From 9ee4f70bf038741c5f341f836ecc3632c9d9655b Mon Sep 17 00:00:00 2001 From: iss Date: Fri, 11 Oct 2019 10:38:40 +0800 Subject: [PATCH] Add Prj-linux and Prj-Win --- Prj-Linux/CMakeLists.txt | 34 + Prj-Linux/LICENSE | 201 + Prj-Linux/LandmarkTracking.h | 358 ++ Prj-Linux/README.md | 31 + Prj-Linux/colotracker.cpp | 336 ++ Prj-Linux/colotracker.h | 60 + Prj-Linux/det1.bin | Bin 0 -> 26548 bytes Prj-Linux/det1.param | 14 + Prj-Linux/det2.bin | Bin 0 -> 400736 bytes Prj-Linux/det2.param | 17 + Prj-Linux/det3.bin | Bin 0 -> 1556192 bytes Prj-Linux/det3.param | 22 + Prj-Linux/main.cpp | 300 ++ Prj-Linux/mtcnn.cpp | 561 ++ Prj-Linux/mtcnn.h | 99 + Prj-Win/.gitignore | 36 + Prj-Win/3rd/ncnn/include/allocator.h | 355 ++ Prj-Win/3rd/ncnn/include/benchmark.h | 36 + Prj-Win/3rd/ncnn/include/blob.h | 43 + Prj-Win/3rd/ncnn/include/command.h | 190 + Prj-Win/3rd/ncnn/include/cpu.h | 51 + Prj-Win/3rd/ncnn/include/gpu.h | 156 + Prj-Win/3rd/ncnn/include/layer.h | 183 + Prj-Win/3rd/ncnn/include/layer_type.h | 30 + Prj-Win/3rd/ncnn/include/layer_type_enum.h | 70 + Prj-Win/3rd/ncnn/include/mat.h | 1580 ++++++ Prj-Win/3rd/ncnn/include/modelbin.h | 81 + Prj-Win/3rd/ncnn/include/net.h | 248 + Prj-Win/3rd/ncnn/include/opencv.h | 266 + Prj-Win/3rd/ncnn/include/paramdict.h | 79 + Prj-Win/3rd/ncnn/include/pipeline.h | 69 + Prj-Win/3rd/ncnn/include/platform.h | 28 + Prj-Win/3rd/ncnn/lib/ncnn.lib | Bin 0 -> 1597712 bytes .../3rd/opencv/include/opencv2/calib3d.hpp | 3323 ++++++++++++ .../include/opencv2/calib3d/calib3d.hpp | 48 + .../include/opencv2/calib3d/calib3d_c.h | 150 + Prj-Win/3rd/opencv/include/opencv2/core.hpp | 3295 ++++++++++++ .../opencv/include/opencv2/core/affine.hpp | 678 +++ .../3rd/opencv/include/opencv2/core/async.hpp | 105 + .../3rd/opencv/include/opencv2/core/base.hpp | 654 +++ .../include/opencv2/core/bindings_utils.hpp | 49 + .../include/opencv2/core/bufferpool.hpp | 40 + .../3rd/opencv/include/opencv2/core/check.hpp | 159 + .../3rd/opencv/include/opencv2/core/core.hpp | 48 + .../3rd/opencv/include/opencv2/core/core_c.h | 3125 +++++++++++ .../3rd/opencv/include/opencv2/core/cuda.hpp | 1049 ++++ .../opencv/include/opencv2/core/cuda.inl.hpp | 631 +++ .../include/opencv2/core/cuda/block.hpp | 211 + .../opencv2/core/cuda/border_interpolate.hpp | 722 +++ .../include/opencv2/core/cuda/color.hpp | 309 ++ .../include/opencv2/core/cuda/common.hpp | 109 + .../opencv2/core/cuda/datamov_utils.hpp | 113 + .../opencv2/core/cuda/detail/color_detail.hpp | 2018 +++++++ .../opencv2/core/cuda/detail/reduce.hpp | 365 ++ .../core/cuda/detail/reduce_key_val.hpp | 502 ++ .../core/cuda/detail/transform_detail.hpp | 392 ++ .../core/cuda/detail/type_traits_detail.hpp | 191 + .../core/cuda/detail/vec_distance_detail.hpp | 121 + .../opencv2/core/cuda/dynamic_smem.hpp | 88 + .../include/opencv2/core/cuda/emulation.hpp | 269 + .../include/opencv2/core/cuda/filters.hpp | 286 + .../include/opencv2/core/cuda/funcattrib.hpp | 79 + .../include/opencv2/core/cuda/functional.hpp | 805 +++ .../include/opencv2/core/cuda/limits.hpp | 128 + .../include/opencv2/core/cuda/reduce.hpp | 209 + .../opencv2/core/cuda/saturate_cast.hpp | 292 + .../opencv/include/opencv2/core/cuda/scan.hpp | 258 + .../opencv2/core/cuda/simd_functions.hpp | 869 +++ .../include/opencv2/core/cuda/transform.hpp | 75 + .../include/opencv2/core/cuda/type_traits.hpp | 90 + .../include/opencv2/core/cuda/utility.hpp | 230 + .../opencv2/core/cuda/vec_distance.hpp | 232 + .../include/opencv2/core/cuda/vec_math.hpp | 923 ++++ .../include/opencv2/core/cuda/vec_traits.hpp | 288 + .../opencv/include/opencv2/core/cuda/warp.hpp | 139 + .../include/opencv2/core/cuda/warp_reduce.hpp | 76 + .../opencv2/core/cuda/warp_shuffle.hpp | 162 + .../opencv2/core/cuda_stream_accessor.hpp | 86 + .../include/opencv2/core/cuda_types.hpp | 144 + .../include/opencv2/core/cv_cpu_dispatch.h | 321 ++ .../include/opencv2/core/cv_cpu_helper.h | 466 ++ .../3rd/opencv/include/opencv2/core/cvdef.h | 881 +++ .../3rd/opencv/include/opencv2/core/cvstd.hpp | 190 + .../opencv/include/opencv2/core/cvstd.inl.hpp | 196 + .../include/opencv2/core/cvstd_wrapper.hpp | 154 + .../opencv2/core/detail/async_promise.hpp | 71 + .../opencv2/core/detail/exception_ptr.hpp | 27 + .../opencv/include/opencv2/core/directx.hpp | 184 + .../3rd/opencv/include/opencv2/core/eigen.hpp | 280 + .../opencv/include/opencv2/core/fast_math.hpp | 261 + .../opencv/include/opencv2/core/hal/hal.hpp | 256 + .../include/opencv2/core/hal/interface.h | 190 + .../include/opencv2/core/hal/intrin.hpp | 471 ++ .../include/opencv2/core/hal/intrin_avx.hpp | 2794 ++++++++++ .../opencv2/core/hal/intrin_avx512.hpp | 2781 ++++++++++ .../include/opencv2/core/hal/intrin_cpp.hpp | 2383 +++++++++ .../opencv2/core/hal/intrin_forward.hpp | 181 + .../include/opencv2/core/hal/intrin_neon.hpp | 1948 +++++++ .../include/opencv2/core/hal/intrin_sse.hpp | 3063 +++++++++++ .../opencv2/core/hal/intrin_sse_em.hpp | 167 + .../include/opencv2/core/hal/intrin_vsx.hpp | 1375 +++++ .../3rd/opencv/include/opencv2/core/mat.hpp | 3726 +++++++++++++ .../opencv/include/opencv2/core/mat.inl.hpp | 3973 ++++++++++++++ .../3rd/opencv/include/opencv2/core/matx.hpp | 1471 +++++ .../include/opencv2/core/neon_utils.hpp | 128 + .../3rd/opencv/include/opencv2/core/ocl.hpp | 710 +++ .../include/opencv2/core/ocl_genbase.hpp | 69 + .../include/opencv2/core/opencl/ocl_defs.hpp | 82 + .../opencv2/core/opencl/opencl_info.hpp | 198 + .../opencv2/core/opencl/opencl_svm.hpp | 81 + .../autogenerated/opencl_clamdblas.hpp | 714 +++ .../runtime/autogenerated/opencl_clamdfft.hpp | 142 + .../runtime/autogenerated/opencl_core.hpp | 371 ++ .../autogenerated/opencl_core_wrappers.hpp | 272 + .../runtime/autogenerated/opencl_gl.hpp | 62 + .../autogenerated/opencl_gl_wrappers.hpp | 42 + .../core/opencl/runtime/opencl_clamdblas.hpp | 53 + .../core/opencl/runtime/opencl_clamdfft.hpp | 53 + .../core/opencl/runtime/opencl_core.hpp | 84 + .../opencl/runtime/opencl_core_wrappers.hpp | 47 + .../opencv2/core/opencl/runtime/opencl_gl.hpp | 53 + .../opencl/runtime/opencl_gl_wrappers.hpp | 47 + .../core/opencl/runtime/opencl_svm_20.hpp | 48 + .../opencl/runtime/opencl_svm_definitions.hpp | 42 + .../runtime/opencl_svm_hsa_extension.hpp | 166 + .../opencv/include/opencv2/core/opengl.hpp | 725 +++ .../include/opencv2/core/operations.hpp | 594 ++ .../3rd/opencv/include/opencv2/core/optim.hpp | 302 ++ .../3rd/opencv/include/opencv2/core/ovx.hpp | 28 + .../include/opencv2/core/persistence.hpp | 1333 +++++ .../opencv/include/opencv2/core/saturate.hpp | 181 + .../opencv/include/opencv2/core/softfloat.hpp | 514 ++ .../opencv/include/opencv2/core/sse_utils.hpp | 652 +++ .../opencv/include/opencv2/core/traits.hpp | 417 ++ .../3rd/opencv/include/opencv2/core/types.hpp | 2476 +++++++++ .../3rd/opencv/include/opencv2/core/types_c.h | 2120 ++++++++ .../opencv/include/opencv2/core/utility.hpp | 1318 +++++ .../opencv2/core/utils/allocator_stats.hpp | 29 + .../core/utils/allocator_stats.impl.hpp | 117 + .../include/opencv2/core/utils/filesystem.hpp | 82 + .../opencv2/core/utils/logger.defines.hpp | 42 + .../include/opencv2/core/utils/logger.hpp | 155 + .../include/opencv2/core/utils/logtag.hpp | 28 + .../include/opencv2/core/utils/trace.hpp | 254 + .../opencv/include/opencv2/core/va_intel.hpp | 78 + .../opencv/include/opencv2/core/version.hpp | 26 + .../opencv/include/opencv2/core/vsx_utils.hpp | 1013 ++++ Prj-Win/3rd/opencv/include/opencv2/cvconfig.h | 167 + Prj-Win/3rd/opencv/include/opencv2/dnn.hpp | 78 + .../opencv/include/opencv2/dnn/all_layers.hpp | 635 +++ .../3rd/opencv/include/opencv2/dnn/dict.hpp | 160 + .../3rd/opencv/include/opencv2/dnn/dnn.hpp | 1006 ++++ .../opencv/include/opencv2/dnn/dnn.inl.hpp | 411 ++ .../include/opencv2/dnn/layer.details.hpp | 78 + .../3rd/opencv/include/opencv2/dnn/layer.hpp | 85 + .../include/opencv2/dnn/shape_utils.hpp | 219 + .../opencv2/dnn/utils/inference_engine.hpp | 43 + .../opencv/include/opencv2/dnn/version.hpp | 21 + .../3rd/opencv/include/opencv2/features2d.hpp | 1451 +++++ .../include/opencv2/features2d/features2d.hpp | 48 + .../opencv2/features2d/hal/interface.h | 33 + Prj-Win/3rd/opencv/include/opencv2/flann.hpp | 596 +++ .../include/opencv2/flann/all_indices.h | 155 + .../opencv/include/opencv2/flann/allocator.h | 192 + .../3rd/opencv/include/opencv2/flann/any.h | 330 ++ .../include/opencv2/flann/autotuned_index.h | 591 ++ .../include/opencv2/flann/composite_index.h | 194 + .../3rd/opencv/include/opencv2/flann/config.h | 38 + .../opencv/include/opencv2/flann/defines.h | 164 + .../3rd/opencv/include/opencv2/flann/dist.h | 904 ++++ .../3rd/opencv/include/opencv2/flann/dummy.h | 13 + .../include/opencv2/flann/dynamic_bitset.h | 159 + .../opencv/include/opencv2/flann/flann.hpp | 48 + .../include/opencv2/flann/flann_base.hpp | 295 + .../opencv/include/opencv2/flann/general.h | 50 + .../include/opencv2/flann/ground_truth.h | 94 + .../3rd/opencv/include/opencv2/flann/heap.h | 165 + .../flann/hierarchical_clustering_index.h | 848 +++ .../include/opencv2/flann/index_testing.h | 318 ++ .../include/opencv2/flann/kdtree_index.h | 626 +++ .../opencv2/flann/kdtree_single_index.h | 635 +++ .../include/opencv2/flann/kmeans_index.h | 1172 ++++ .../include/opencv2/flann/linear_index.h | 132 + .../3rd/opencv/include/opencv2/flann/logger.h | 135 + .../opencv/include/opencv2/flann/lsh_index.h | 392 ++ .../opencv/include/opencv2/flann/lsh_table.h | 513 ++ .../3rd/opencv/include/opencv2/flann/matrix.h | 116 + .../include/opencv2/flann/miniflann.hpp | 177 + .../opencv/include/opencv2/flann/nn_index.h | 177 + .../include/opencv2/flann/object_factory.h | 91 + .../3rd/opencv/include/opencv2/flann/params.h | 99 + .../3rd/opencv/include/opencv2/flann/random.h | 155 + .../opencv/include/opencv2/flann/result_set.h | 543 ++ .../opencv/include/opencv2/flann/sampling.h | 81 + .../3rd/opencv/include/opencv2/flann/saving.h | 187 + .../include/opencv2/flann/simplex_downhill.h | 186 + .../3rd/opencv/include/opencv2/flann/timer.h | 94 + Prj-Win/3rd/opencv/include/opencv2/gapi.hpp | 33 + .../3rd/opencv/include/opencv2/gapi/core.hpp | 1639 ++++++ .../opencv/include/opencv2/gapi/cpu/core.hpp | 27 + .../include/opencv2/gapi/cpu/gcpukernel.hpp | 278 + .../include/opencv2/gapi/cpu/imgproc.hpp | 27 + .../include/opencv2/gapi/fluid/core.hpp | 20 + .../opencv2/gapi/fluid/gfluidbuffer.hpp | 154 + .../opencv2/gapi/fluid/gfluidkernel.hpp | 303 ++ .../include/opencv2/gapi/fluid/imgproc.hpp | 20 + .../3rd/opencv/include/opencv2/gapi/garg.hpp | 126 + .../opencv/include/opencv2/gapi/garray.hpp | 251 + .../include/opencv2/gapi/gasync_context.hpp | 38 + .../3rd/opencv/include/opencv2/gapi/gcall.hpp | 64 + .../opencv/include/opencv2/gapi/gcommon.hpp | 172 + .../opencv/include/opencv2/gapi/gcompiled.hpp | 217 + .../include/opencv2/gapi/gcompiled_async.hpp | 41 + .../include/opencv2/gapi/gcompoundkernel.hpp | 108 + .../include/opencv2/gapi/gcomputation.hpp | 456 ++ .../opencv2/gapi/gcomputation_async.hpp | 43 + .../opencv/include/opencv2/gapi/gkernel.hpp | 557 ++ .../3rd/opencv/include/opencv2/gapi/gmat.hpp | 209 + .../opencv/include/opencv2/gapi/gmetaarg.hpp | 75 + .../opencv/include/opencv2/gapi/gproto.hpp | 129 + .../opencv/include/opencv2/gapi/gpu/core.hpp | 27 + .../include/opencv2/gapi/gpu/ggpukernel.hpp | 18 + .../include/opencv2/gapi/gpu/imgproc.hpp | 28 + .../opencv/include/opencv2/gapi/gscalar.hpp | 83 + .../include/opencv2/gapi/gtransform.hpp | 98 + .../include/opencv2/gapi/gtype_traits.hpp | 163 + .../opencv/include/opencv2/gapi/gtyped.hpp | 187 + .../opencv/include/opencv2/gapi/imgproc.hpp | 919 ++++ .../opencv/include/opencv2/gapi/ocl/core.hpp | 27 + .../include/opencv2/gapi/ocl/goclkernel.hpp | 245 + .../include/opencv2/gapi/ocl/imgproc.hpp | 27 + .../include/opencv2/gapi/opencv_includes.hpp | 21 + .../opencv/include/opencv2/gapi/operators.hpp | 69 + .../include/opencv2/gapi/own/assert.hpp | 43 + .../include/opencv2/gapi/own/convert.hpp | 50 + .../include/opencv2/gapi/own/cvdefs.hpp | 150 + .../include/opencv2/gapi/own/exports.hpp | 28 + .../opencv/include/opencv2/gapi/own/mat.hpp | 291 + .../include/opencv2/gapi/own/saturate.hpp | 90 + .../include/opencv2/gapi/own/scalar.hpp | 47 + .../opencv/include/opencv2/gapi/own/types.hpp | 135 + .../opencv/include/opencv2/gapi/render.hpp | 113 + .../opencv/include/opencv2/gapi/util/any.hpp | 186 + .../opencv2/gapi/util/compiler_hints.hpp | 19 + .../include/opencv2/gapi/util/optional.hpp | 178 + .../include/opencv2/gapi/util/throw.hpp | 36 + .../opencv/include/opencv2/gapi/util/util.hpp | 124 + .../include/opencv2/gapi/util/variant.hpp | 379 ++ .../3rd/opencv/include/opencv2/highgui.hpp | 841 +++ .../include/opencv2/highgui/highgui.hpp | 48 + .../include/opencv2/highgui/highgui_c.h | 256 + .../3rd/opencv/include/opencv2/imgcodecs.hpp | 277 + .../include/opencv2/imgcodecs/imgcodecs.hpp | 48 + .../include/opencv2/imgcodecs/imgcodecs_c.h | 1 + .../opencv/include/opencv2/imgcodecs/ios.h | 57 + .../opencv2/imgcodecs/legacy/constants_c.h | 54 + .../3rd/opencv/include/opencv2/imgproc.hpp | 4758 +++++++++++++++++ .../opencv2/imgproc/detail/gcgraph.hpp | 393 ++ .../include/opencv2/imgproc/hal/hal.hpp | 241 + .../include/opencv2/imgproc/hal/interface.h | 46 + .../include/opencv2/imgproc/imgproc.hpp | 48 + .../include/opencv2/imgproc/imgproc_c.h | 1177 ++++ .../opencv/include/opencv2/imgproc/types_c.h | 659 +++ Prj-Win/3rd/opencv/include/opencv2/ml.hpp | 1947 +++++++ Prj-Win/3rd/opencv/include/opencv2/ml/ml.hpp | 48 + .../3rd/opencv/include/opencv2/ml/ml.inl.hpp | 60 + .../3rd/opencv/include/opencv2/objdetect.hpp | 720 +++ .../objdetect/detection_based_tracker.hpp | 222 + .../include/opencv2/objdetect/objdetect.hpp | 48 + Prj-Win/3rd/opencv/include/opencv2/opencv.hpp | 139 + .../opencv/include/opencv2/opencv_modules.hpp | 30 + Prj-Win/3rd/opencv/include/opencv2/photo.hpp | 856 +++ .../3rd/opencv/include/opencv2/photo/cuda.hpp | 132 + .../opencv2/photo/legacy/constants_c.h | 14 + .../opencv/include/opencv2/photo/photo.hpp | 48 + .../3rd/opencv/include/opencv2/stitching.hpp | 343 ++ .../opencv2/stitching/detail/autocalib.hpp | 86 + .../opencv2/stitching/detail/blenders.hpp | 184 + .../opencv2/stitching/detail/camera.hpp | 78 + .../stitching/detail/exposure_compensate.hpp | 230 + .../opencv2/stitching/detail/matchers.hpp | 253 + .../stitching/detail/motion_estimators.hpp | 363 ++ .../opencv2/stitching/detail/seam_finders.hpp | 291 + .../opencv2/stitching/detail/timelapsers.hpp | 91 + .../include/opencv2/stitching/detail/util.hpp | 121 + .../opencv2/stitching/detail/util_inl.hpp | 131 + .../opencv2/stitching/detail/warpers.hpp | 616 +++ .../opencv2/stitching/detail/warpers_inl.hpp | 774 +++ .../include/opencv2/stitching/warpers.hpp | 261 + Prj-Win/3rd/opencv/include/opencv2/video.hpp | 59 + .../include/opencv2/video/background_segm.hpp | 317 ++ .../opencv2/video/legacy/constants_c.h | 16 + .../opencv/include/opencv2/video/tracking.hpp | 712 +++ .../opencv/include/opencv2/video/video.hpp | 48 + .../3rd/opencv/include/opencv2/videoio.hpp | 958 ++++ .../opencv/include/opencv2/videoio/cap_ios.h | 150 + .../opencv2/videoio/legacy/constants_c.h | 434 ++ .../include/opencv2/videoio/registry.hpp | 47 + .../include/opencv2/videoio/videoio.hpp | 48 + .../include/opencv2/videoio/videoio_c.h | 153 + Prj-Win/3rd/opencv/include/opencv2/world.hpp | 58 + Prj-Win/3rd/opencv/lib/opencv_world411.lib | Bin 0 -> 2451712 bytes Prj-Win/LICENSE | 201 + Prj-Win/LandmarkTracking.h | 346 ++ Prj-Win/Ncnn_FaceTrack.sln | 28 + Prj-Win/Ncnn_FaceTrack.vcxproj | 159 + Prj-Win/Ncnn_FaceTrack.vcxproj.filters | 33 + Prj-Win/Ncnn_FaceTrack.vcxproj.user | 4 + Prj-Win/README.md | 17 + Prj-Win/main.cpp | 299 ++ Prj-Win/models/det1.bin | Bin 0 -> 26548 bytes Prj-Win/models/det1.param | 14 + Prj-Win/models/det2.bin | Bin 0 -> 400736 bytes Prj-Win/models/det2.param | 17 + Prj-Win/models/det3.bin | Bin 0 -> 1556192 bytes Prj-Win/models/det3.param | 22 + Prj-Win/mtcnn.cpp | 561 ++ Prj-Win/mtcnn.h | 99 + 318 files changed, 119085 insertions(+) create mode 100755 Prj-Linux/CMakeLists.txt create mode 100755 Prj-Linux/LICENSE create mode 100755 Prj-Linux/LandmarkTracking.h create mode 100755 Prj-Linux/README.md create mode 100755 Prj-Linux/colotracker.cpp create mode 100755 Prj-Linux/colotracker.h create mode 100755 Prj-Linux/det1.bin create mode 100755 Prj-Linux/det1.param create mode 100755 Prj-Linux/det2.bin create mode 100755 Prj-Linux/det2.param create mode 100755 Prj-Linux/det3.bin create mode 100755 Prj-Linux/det3.param create mode 100755 Prj-Linux/main.cpp create mode 100755 Prj-Linux/mtcnn.cpp create mode 100755 Prj-Linux/mtcnn.h create mode 100755 Prj-Win/.gitignore create mode 100755 Prj-Win/3rd/ncnn/include/allocator.h create mode 100755 Prj-Win/3rd/ncnn/include/benchmark.h create mode 100755 Prj-Win/3rd/ncnn/include/blob.h create mode 100755 Prj-Win/3rd/ncnn/include/command.h create mode 100755 Prj-Win/3rd/ncnn/include/cpu.h create mode 100755 Prj-Win/3rd/ncnn/include/gpu.h create mode 100755 Prj-Win/3rd/ncnn/include/layer.h create mode 100755 Prj-Win/3rd/ncnn/include/layer_type.h create mode 100755 Prj-Win/3rd/ncnn/include/layer_type_enum.h create mode 100755 Prj-Win/3rd/ncnn/include/mat.h create mode 100755 Prj-Win/3rd/ncnn/include/modelbin.h create mode 100755 Prj-Win/3rd/ncnn/include/net.h create mode 100755 Prj-Win/3rd/ncnn/include/opencv.h create mode 100755 Prj-Win/3rd/ncnn/include/paramdict.h create mode 100755 Prj-Win/3rd/ncnn/include/pipeline.h create mode 100755 Prj-Win/3rd/ncnn/include/platform.h create mode 100755 Prj-Win/3rd/ncnn/lib/ncnn.lib create mode 100755 Prj-Win/3rd/opencv/include/opencv2/calib3d.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/affine.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/async.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/base.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/bindings_utils.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/bufferpool.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/check.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/core_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda.inl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/block.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/border_interpolate.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/color.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/common.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/datamov_utils.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/color_detail.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/transform_detail.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/dynamic_smem.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/emulation.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/filters.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/funcattrib.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/functional.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/limits.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/reduce.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/saturate_cast.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/scan.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/simd_functions.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/transform.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/type_traits.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/utility.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_distance.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_math.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_traits.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_reduce.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_shuffle.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda_stream_accessor.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cuda_types.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_dispatch.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_helper.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cvdef.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cvstd.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cvstd.inl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/cvstd_wrapper.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/detail/async_promise.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/detail/exception_ptr.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/directx.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/eigen.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/fast_math.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/hal.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/interface.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx512.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_cpp.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_forward.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_neon.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse_em.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_vsx.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/mat.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/mat.inl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/matx.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/neon_utils.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/ocl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/ocl_genbase.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/ocl_defs.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_info.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_svm.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/opengl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/operations.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/optim.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/ovx.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/persistence.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/saturate.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/softfloat.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/sse_utils.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/traits.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/types.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/types_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utility.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.impl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utils/filesystem.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.defines.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utils/logtag.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/utils/trace.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/va_intel.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/version.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/core/vsx_utils.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/cvconfig.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/all_layers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/dict.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.inl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/layer.details.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/layer.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/shape_utils.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/utils/inference_engine.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/dnn/version.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/features2d.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/features2d/features2d.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/features2d/hal/interface.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/all_indices.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/allocator.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/any.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/autotuned_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/composite_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/config.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/defines.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/dist.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/dummy.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/dynamic_bitset.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/flann.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/flann_base.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/general.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/ground_truth.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/heap.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/hierarchical_clustering_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/index_testing.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/kdtree_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/kdtree_single_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/kmeans_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/linear_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/logger.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/lsh_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/lsh_table.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/matrix.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/miniflann.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/nn_index.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/object_factory.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/params.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/random.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/result_set.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/sampling.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/saving.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/simplex_downhill.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/flann/timer.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/gcpukernel.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/imgproc.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidbuffer.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidkernel.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/imgproc.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/garg.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/garray.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gasync_context.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gcall.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gcommon.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled_async.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gcompoundkernel.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation_async.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gkernel.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gmat.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gmetaarg.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gproto.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/ggpukernel.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/imgproc.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gscalar.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gtransform.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gtype_traits.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/gtyped.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/imgproc.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/core.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/goclkernel.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/imgproc.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/opencv_includes.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/operators.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/assert.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/convert.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/cvdefs.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/exports.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/mat.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/saturate.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/scalar.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/own/types.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/render.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/util/any.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/util/compiler_hints.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/util/optional.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/util/throw.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/util/util.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/gapi/util/variant.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/highgui.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/highgui/highgui.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/highgui/highgui_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgcodecs.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgcodecs/ios.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgcodecs/legacy/constants_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgproc.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgproc/detail/gcgraph.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/hal.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/interface.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/imgproc/types_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/ml.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/ml/ml.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/ml/ml.inl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/objdetect.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/objdetect/detection_based_tracker.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/objdetect/objdetect.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/opencv.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/opencv_modules.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/photo.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/photo/cuda.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/photo/legacy/constants_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/photo/photo.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/autocalib.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/blenders.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/camera.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/exposure_compensate.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/matchers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/motion_estimators.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/seam_finders.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/timelapsers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util_inl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers_inl.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/stitching/warpers.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/video.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/video/background_segm.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/video/legacy/constants_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/video/tracking.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/video/video.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/videoio.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/videoio/cap_ios.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/videoio/legacy/constants_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/videoio/registry.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/videoio/videoio.hpp create mode 100755 Prj-Win/3rd/opencv/include/opencv2/videoio/videoio_c.h create mode 100755 Prj-Win/3rd/opencv/include/opencv2/world.hpp create mode 100755 Prj-Win/3rd/opencv/lib/opencv_world411.lib create mode 100755 Prj-Win/LICENSE create mode 100755 Prj-Win/LandmarkTracking.h create mode 100755 Prj-Win/Ncnn_FaceTrack.sln create mode 100755 Prj-Win/Ncnn_FaceTrack.vcxproj create mode 100755 Prj-Win/Ncnn_FaceTrack.vcxproj.filters create mode 100755 Prj-Win/Ncnn_FaceTrack.vcxproj.user create mode 100755 Prj-Win/README.md create mode 100755 Prj-Win/main.cpp create mode 100755 Prj-Win/models/det1.bin create mode 100755 Prj-Win/models/det1.param create mode 100755 Prj-Win/models/det2.bin create mode 100755 Prj-Win/models/det2.param create mode 100755 Prj-Win/models/det3.bin create mode 100755 Prj-Win/models/det3.param create mode 100755 Prj-Win/mtcnn.cpp create mode 100755 Prj-Win/mtcnn.h diff --git a/Prj-Linux/CMakeLists.txt b/Prj-Linux/CMakeLists.txt new file mode 100755 index 0000000..2bdb2fe --- /dev/null +++ b/Prj-Linux/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 2.8) + +project(tracker) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3") +if(CMAKE_COMPILER_IS_GNUCXX) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wextra -pedantic -Wno-long-long") +endif() + +#寻找OpenCV库 +#修改成捏OpenCV路径即可 +set(OpenCV_DIR "/home/xz/opencv3.4.3/opencv-3.4.3/build") +set(OpenCV_INCLUDE_DIRS "/home/xz/opencv3.4.3/opencv-3.4.3/include") +find_package(OpenCV REQUIRED) + +if (OPENMP_FOUND) + message("OpenMP found!") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +endif() + +include_directories(/home/xz/ncnn/build/install/include/ncnn) +link_directories(/home/xz/ncnn/build/install/lib) + + + +add_executable(MultiFaceTracking main.cpp mtcnn.cpp colotracker.cpp) +target_link_libraries(MultiFaceTracking ncnn ${OpenCV_LIBS} -fopenmp /usr/lib/x86_64-linux-gnu/libsqlite3.so) + + + + + diff --git a/Prj-Linux/LICENSE b/Prj-Linux/LICENSE new file mode 100755 index 0000000..261eeb9 --- /dev/null +++ b/Prj-Linux/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Prj-Linux/LandmarkTracking.h b/Prj-Linux/LandmarkTracking.h new file mode 100755 index 0000000..23f0581 --- /dev/null +++ b/Prj-Linux/LandmarkTracking.h @@ -0,0 +1,358 @@ +#ifndef ZEUSEESFACETRACKING_H +#define ZEUSEESFACETRACKING_H +//#include +//#include +#include "mtcnn.h" +#include "time.h" +#include "colotracker.h" + + +cv::Rect boundingRect(const std::vector& pts) { + if (pts.size() > 1) + { + int xmin = pts[0].x; + int ymin = pts[0].y; + int xmax = pts[0].x; + int ymax = pts[0].y; + for (int i = 1; i < pts.size(); i++) + { + if (pts[i].x < xmin) + xmin = pts[i].x; + if (pts[i].y < ymin) + ymin = pts[i].y; + if (pts[i].x > xmax) + xmax = pts[i].x; + if (pts[i].y > ymax) + ymax = pts[i].y; + } + return cv::Rect(xmin, ymin, xmax - xmin, ymax - ymin); + } +} + + +//typedef int T; +//T i = 1; + + +class Face { +public: + + Face(int instance_id, Shape::Rect rect) { + face_id = instance_id; + + face_location = rect; + isCanShow = false; //追踪一次后待框稳定后即可显示 + + } + + Face() { + + isCanShow = false; //追踪一次后待框稳定后即可显示 + } + + Bbox faceBbox; + + int face_id = -1; + long frameId = 0; + int ptr_num = 0; + + Shape::Rect face_location; + bool isCanShow; + cv::Mat frame_face_prev; + + static cv::Rect SquarePadding(cv::Rect facebox, int margin_rows, int margin_cols, bool max) + { + int c_x = facebox.x + facebox.width / 2; + int c_y = facebox.y + facebox.height / 2; + int large = 0; + if (max) + large = std::max(facebox.height, facebox.width) / 2; + else + large = min(facebox.height, facebox.width) / 2; + cv::Rect rectNot(c_x - large, c_y - large, c_x + large, c_y + large); + rectNot.x = std::max(0, rectNot.x); + rectNot.y = std::max(0, rectNot.y); + rectNot.height = min(rectNot.height, margin_rows - 1); + rectNot.width = min(rectNot.width, margin_cols - 1); + if (rectNot.height - rectNot.y != rectNot.width - rectNot.x) + return SquarePadding(cv::Rect(rectNot.x, rectNot.y, rectNot.width - rectNot.x, rectNot.height - rectNot.y), margin_rows, margin_cols, false); + + return cv::Rect(rectNot.x, rectNot.y, rectNot.width - rectNot.x, rectNot.height - rectNot.y); + } + + static cv::Rect SquarePadding(cv::Rect facebox, int padding) + { + + int c_x = facebox.x - padding; + int c_y = facebox.y - padding; + return cv::Rect(facebox.x - padding, facebox.y - padding, facebox.width + padding * 2, facebox.height + padding * 2);; + } + + static double getDistance(cv::Point x, cv::Point y) + { + return sqrt((x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y)); + } + + + vector > faceSequence; + vector> attitudeSequence; + + +}; + + + +class FaceTracking { +public: + FaceTracking(string modelPath) + { + this->detector = new MTCNN(modelPath); + downSimpilingFactor = 1; + faceMinSize = 70; + this->detector->SetMinFace(faceMinSize); + detection_Time = -1; + + } + + ~FaceTracking() { + delete this->detector; + + } + + void detecting(cv::Mat* image) { + ncnn::Mat ncnn_img = ncnn::Mat::from_pixels(image->data, ncnn::Mat::PIXEL_BGR2RGB, image->cols, image->rows); + std::vector finalBbox; + if(isMaxFace) + detector->detectMaxFace(ncnn_img, finalBbox); + else + detector->detect(ncnn_img, finalBbox); + const int num_box = finalBbox.size(); + std::vector bbox; + bbox.resize(num_box); + candidateFaces_lock = 1; + for (int i = 0; i < num_box; i++) { + bbox[i] = cv::Rect(finalBbox[i].x1, finalBbox[i].y1, finalBbox[i].x2 - finalBbox[i].x1 + 1, + finalBbox[i].y2 - finalBbox[i].y1 + 1); + bbox[i] = Face::SquarePadding(bbox[i], image->rows, image->cols, true); + Shape::Rect f_rect(bbox[i].x / static_cast(image->cols), + bbox[i].y / static_cast(image->rows), + bbox[i].width / static_cast(image->cols), + bbox[i].height / static_cast(image->rows) + ); + std::shared_ptr face(new Face(trackingID, f_rect)); + (*image)(bbox[i]).copyTo(face->frame_face_prev); + + trackingID = trackingID + 1; + candidateFaces.push_back(*face); + } + candidateFaces_lock = 0; + } + + void Init(cv::Mat& image) { + ImageHighDP = image; + cv::Size lowDpSize(ImageHighDP.cols / downSimpilingFactor, ImageHighDP.rows / downSimpilingFactor); + cv::resize(image, ImageLowDP, lowDpSize); + trackingID = 0; + detection_Interval = 200; //detect faces every 200 ms + detecting(&image); + stabilization = false; + UI_height = image.rows; + UI_width = image.cols; + lastImage =image.clone(); + MF_Tracker.init(image); + } + + void doingLandmark_onet(cv::Mat& face, Bbox& faceBbox, int zeroadd_x, int zeroadd_y, int stable_state = 0) { + ncnn::Mat in = ncnn::Mat::from_pixels_resize(face.data, ncnn::Mat::PIXEL_BGR, face.cols, face.rows, 48, 48); + faceBbox = detector->onet(in, zeroadd_x, zeroadd_y, face.cols, face.rows); + + } + + + void tracking_corrfilter(const cv::Mat& frame, const cv::Mat& model, cv::Rect& trackBox, float scale) + { + trackBox.x /= scale; + trackBox.y /= scale; + trackBox.height /= scale; + trackBox.width /= scale; + int zeroadd_x = 0; + int zeroadd_y = 0; + cv::Mat frame_; + cv::Mat model_; + cv::resize(frame, frame_, cv::Size(), 1 / scale, 1 / scale); + cv::resize(model, model_, cv::Size(), 1 / scale, 1 / scale); + cv::Mat gray; + cvtColor(frame_, gray, cv::COLOR_RGB2GRAY); + cv::Mat gray_model; + cvtColor(model_, gray_model, cv::COLOR_RGB2GRAY); + cv::Rect searchWindow; + searchWindow.width = trackBox.width * 3; + searchWindow.height = trackBox.height * 3; + searchWindow.x = trackBox.x + trackBox.width * 0.5 - searchWindow.width * 0.5; + searchWindow.y = trackBox.y + trackBox.height * 0.5 - searchWindow.height * 0.5; + searchWindow &= cv::Rect(0, 0, frame_.cols, frame_.rows); + cv::Mat similarity; + matchTemplate(gray(searchWindow), gray_model, similarity, cv::TM_CCOEFF_NORMED); + double mag_r; + cv::Point point; + minMaxLoc(similarity, 0, &mag_r, 0, &point); + trackBox.x = point.x + searchWindow.x; + trackBox.y = point.y + searchWindow.y; + trackBox.x *= scale; + trackBox.y *= scale; + trackBox.height *= scale; + trackBox.width *= scale; + } + + bool tracking(cv::Mat& image, Face& face) + { + cv::Rect faceROI = face.face_location.convert_cv_rect(image.rows, image.cols); + cv::Mat faceROI_Image; + + double t = (double)getTickCount();//开始时间 + //tracking_corrfilter(image, face.frame_face_prev, faceROI, tpm_scale); + faceROI =MF_Tracker.track(image,lastImage,faceROI.x,faceROI.y,faceROI.x+faceROI.width,faceROI.y+faceROI.height); + t = (double)getTickCount() - t;//代码运行时间=结束时间-开始时间 + + //printf("互相关匹配时间= %gms\n", t*1000. / getTickFrequency());//转换时间单位并输出代码运行时间 + printf("光流时间= %gms\n", t*1000. / getTickFrequency());//转换时间单位并输出代码运行时间 + //lastImage = image; + + image(faceROI).copyTo(faceROI_Image); + + cv::Rect bdbox; + + doingLandmark_onet(faceROI_Image, face.faceBbox, faceROI.x, faceROI.y, face.frameId > 1); + + bdbox.x = face.faceBbox.x1; + bdbox.y = face.faceBbox.y1; + bdbox.width = face.faceBbox.x2 - face.faceBbox.x1; + bdbox.height = face.faceBbox.y2 - face.faceBbox.y1; + + bdbox = Face::SquarePadding(bdbox, static_cast(bdbox.height * -0.05)); + bdbox = Face::SquarePadding(bdbox, image.rows, image.cols, 1); + + Shape::Rect boxfloat(bdbox.x / static_cast(image.cols), + bdbox.y / static_cast(image.rows), + bdbox.width / static_cast(image.cols), + bdbox.height / static_cast(image.rows)); + + face.faceBbox.x1 = bdbox.x; + face.faceBbox.y1 = bdbox.y; + face.faceBbox.x2 = bdbox.x + bdbox.width; + face.faceBbox.y2 = bdbox.y + bdbox.height; + + + face.face_location = boxfloat; + faceROI = face.face_location.convert_cv_rect(image.rows, image.cols); + + image(faceROI).copyTo(face.frame_face_prev); + face.frameId += 1; + ncnn::Mat rnet_data = ncnn::Mat::from_pixels_resize(faceROI_Image.data, ncnn::Mat::PIXEL_BGR2RGB, faceROI_Image.cols, faceROI_Image.rows, 24, 24); + + float sim = detector->rnet(rnet_data); + + face.isCanShow = true; + if (sim > 0.9) { + //stablize + float diff_x = 0; + float diff_y = 0; + return true; + } + return false; + + } + void setMask(cv::Mat& image, cv::Rect& rect_mask) + { + + int height = image.rows; + int width = image.cols; + cv::Mat subImage = image(rect_mask); + subImage.setTo(0); + } + + void update(cv::Mat& image) + { + ImageHighDP = image; + //std::cout << trackingFace.size() << std::endl; + if (candidateFaces.size() > 0 && !candidateFaces_lock) + { + for (int i = 0; i < candidateFaces.size(); i++) + { + trackingFace.push_back(candidateFaces[i]); + } + candidateFaces.clear(); + } + for (vector::iterator iter = trackingFace.begin(); iter != trackingFace.end();) + { + if (!tracking(image, *iter)) + { + iter = trackingFace.erase(iter); //追踪失败 则删除此人脸 + } + else { + iter++; + } + } + + if (trackingFace.size() <= 0) + { + detection_Interval = 200; + } + else + { + detection_Interval = 1000; + } + + if (detection_Time < 0) + { + detection_Time = (double)cv::getTickCount(); + } + else { + double diff = (double)(cv::getTickCount() - detection_Time) * 1000 / cv::getTickFrequency(); + if (diff > detection_Interval) + { + cv::Size lowDpSize(ImageHighDP.cols / downSimpilingFactor, ImageHighDP.rows / downSimpilingFactor); + cv::resize(image, ImageLowDP, lowDpSize); + //set Mask to protect the tracking face not to be detected. + for (auto& face : trackingFace) + { + Shape::Rect rect = face.face_location; + cv::Rect rect1 = rect.convert_cv_rect(ImageLowDP.rows, ImageLowDP.cols); + setMask(ImageLowDP, rect1); + } + detection_Time = (double)cv::getTickCount(); + // do detection in thread + detecting(&ImageLowDP); + } + + } + } + + + + vector trackingFace; //跟踪中的人脸 + int UI_width; + int UI_height; + + +private: + cv::Mat lastImage; + int isLostDetection; + int isTracking; + int isDetection; + cv::Mat ImageHighDP; + cv::Mat ImageLowDP; + int downSimpilingFactor; + int faceMinSize; + MTCNN* detector; + ColorTracker MF_Tracker; + vector candidateFaces; // 将检测到的人脸放入此列队 待跟踪的人脸 + bool candidateFaces_lock; + double detection_Time; + double detection_Interval; + int trackingID; + bool stabilization; + int tpm_scale = 2; + bool isMaxFace = true; +}; +#endif //ZEUSEESFACETRACKING_H diff --git a/Prj-Linux/README.md b/Prj-Linux/README.md new file mode 100755 index 0000000..99c41bb --- /dev/null +++ b/Prj-Linux/README.md @@ -0,0 +1,31 @@ +# HyperFT linux-ncnn版本 +基于mtcnn人脸检测+onet人脸跟踪(光流跟踪) + +#开发环境 +ncnn ubuntu18.04 opencv4.01 + + +#开源框架 ++ [ncnn](https://github.com/Tencent/ncnn) + ++ [opencv](https://github.com/opencv/opencv) + +# 引用 +[HyperFT](https://github.com/zeusees/HyperFT) +https://github.com/qaz734913414/Ncnn_FaceTrack + +编译方步骤: +1、修改CMakeList.txt中的ncnn路径,修改成你自己的路径; +2、mkdir build +3、cd build +4、cmake .. +5、make -j4 + +注意:运行的时候出现错误了,可能是模型路径不对。 + + +Todo: +1、将MTCNN检测换成MSSD相关的检测模型,这样速度不会随着人脸数目增加而增加 +2、使用更快的O网络 +3、人头姿态部分,目前使用的版本速度不是很快,正在优化中 + diff --git a/Prj-Linux/colotracker.cpp b/Prj-Linux/colotracker.cpp new file mode 100755 index 0000000..610a73f --- /dev/null +++ b/Prj-Linux/colotracker.cpp @@ -0,0 +1,336 @@ +#include "colotracker.h" +#include +#include +#include +#include "opencv/cv.h" +#include "opencv/ml.h" +#include "opencv/highgui.h" +#include +#include +#include + +using namespace std; +using namespace cv; + +#define Scale 6 + + +/* -------------------------CODE-----------------------------*/ +double ColorTracker::euclid_dist(const Point2f* point1, const Point2f* point2) +{ + /* + * This function calculates the euclidean distance between 2 points + */ + double distance, xvec, yvec; + xvec = point2->x - point1->x; + yvec = point2->y - point1->y; + distance = sqrt((xvec * xvec) + (yvec * yvec)); + return distance; +} + + + +void ColorTracker::pairwise_dist(const Point2f* features, double *edist, int npoin) +{ + /* + * calculate m x n euclidean pairwise distance matrix. + */ + for (int i = 0; i < npoin; i++) + { + for (int j = 0; j < npoin; j++) + { + int ind = npoin*i + j; + edist[ind] = euclid_dist(&features[i],&features[j]); + } + } +} + + +void ColorTracker::ncc_filter(cv::Mat frame1, cv::Mat frame2, Point2f *prev_feat, Point2f *curr_feat, + int npoin, int method, cv::Mat rec0, cv::Mat rec1, cv::Mat res, int *ncc_pass) +{ + /* + * Normalized Cross Correlation Filter + */ + + int filt = npoin/2; + vector ncc_err (npoin,0.0); + + for (int i = 0; i < npoin; i++) + { + //从原图像中的特征点周围提取一个感兴趣的矩形区域图像 + getRectSubPix( frame1, Size(11,11),prev_feat[i], rec0); + getRectSubPix( frame2, Size(11,11),curr_feat[i], rec1 ); + //模板匹配函数 + //HI_MPI_IVE_NCC + //对获取得到的两个矩形框区域互相关匹配 + matchTemplate( rec0,rec1, res, method ); + ncc_err[i] = res.at(0,0); + } + vectorerr_copy (ncc_err); + sort(ncc_err.begin(), ncc_err.end()); + //使用ncnn计算的互相关进行验证,过滤掉bounding box中质量最差的点的50% + median = (ncc_err[filt]+ncc_err[filt-1])/2.; + cout<<"median"<= median) + { + ncc_pass[i] = 1; + } + else + { + ncc_pass[i] = 0; + } + } +} + +// tracking box mouse callback + +int cmp( const void *a , const void *b ){ + return *(double *)a > *(double *)b ? 1 : -1; +} + + +void ColorTracker::fb_filter(const Point2f* prev_features, const Point2f* backward_features, +const Point2f* curr_feat, int *fb_pass, const int npoin) +{ + /* + * This function implements forward-backward error filtering + */ + //vector euclidean_dist (npoin,0.0); + double euclidean_dist[npoin]; + double err_copy[npoin]; + + memcpy(err_copy,euclidean_dist,sizeof(euclidean_dist)); + + int filt = npoin/2; + for(int i = 0; i < npoin; i++) + { + //比较原始点和反向点之间的欧式距离 + euclidean_dist[i] = euclid_dist(&prev_features[i], &backward_features[i]); + //cout<<"euclidean_dist[i]==="< err_copy (euclidean_dist); + //qsort(in,100,sizeof(in[0]),cmp); + qsort(euclidean_dist,npoin,sizeof(euclidean_dist[0]),cmp); + //use the STL sort algorithm to filter results + //对该欧式距离进行排序,因为理论上如果所有的点没有误差,那么点坐标的欧式距离应该为0 + //sort(euclidean_dist.begin(), euclidean_dist.end()); + double median = (euclidean_dist[filt]+euclidean_dist[filt-1])/2.; + //对点进行排序后,认为大于中值距离的点是坏点,相当于一半的点偏离原始点,说明这些点此时光流跟踪失败 + for(int i = 0; i < npoin; i++) + { + if (err_copy[i] <= median) + { + fb_pass[i] = 1; + } + else + { + fb_pass[i] = 0; + } + } +} + + +void ColorTracker::bbox_move(const Point2f* prev_feat, const Point2f* curr_feat, const int npoin, + double &xmean, double &ymean) + { + /* + * Calculate bounding box motion. + */ + //计算的是x方向和y方向上的平均偏移量 + //vector xvec (npoin,0.0); + //vector yvec (npoin,0.0); + double xvec[npoin]; + double yvec[npoin]; + for (int i = 0; i < npoin; i++) + { + xvec[i] = curr_feat[i].x - prev_feat[i].x; + yvec[i] = curr_feat[i].y - prev_feat[i].y; + } + qsort(xvec,npoin,sizeof(xvec[0]),cmp); + qsort(yvec,npoin,sizeof(yvec[0]),cmp); + //sort(xvec.begin(), xvec.end()); + //sort(yvec.begin(), yvec.end()); + + xmean = xvec[npoin/2]; + ymean = yvec[npoin/2]; //The final mostion is that of the mean of all the points. +} + + +void ColorTracker::init(cv::Mat & img) +{ + //保存第一帧图像 + resize(img,frame1_1C,Size(img.cols/Scale,img.rows/Scale),0,0,1); + cvtColor(frame1_1C,frame1_1C,CV_BGRA2GRAY); +} + + +cv::Rect ColorTracker::track(cv::Mat & img,cv::Mat before,double x1, double y1, double x2, double y2) +{ + bbox_x =x1/Scale; + bbox_y =y1/Scale; + bbox_width =(x2-x1)/Scale; + bbox_height =(y2-y1)/Scale; + + double t = (double)getTickCount();//开始时间 + resize(img,frame2_1C,Size(img.cols/Scale,img.rows/Scale),0,0,1); + cvtColor(frame2_1C,frame2_1C,CV_BGRA2GRAY); + t = (double)getTickCount() - t;//代码运行时间=结束时间-开始时间 + printf("预处理时间= %gms\n", t*1000. / getTickFrequency()); + cv::Mat rec0(winsize,winsize,CV_8UC1); + cv::Mat rec1(winsize,winsize,CV_8UC1); + cv::Mat res(1,1,CV_32FC1); + + /* This array will contain the locations of the points from frame 1 in frame 2. */ + vector frame1_features(npoints); + vector frame2_features(npoints); + vector FB_features(npoints); + + // The i-th element of this array will be non-zero if and only if the i-th feature of + // frame 1 was found in frame 2. + + char optical_flow_found_feature[npoints]; //features in first frame + char optical_flow_found_feature2[npoints]; //features in second frame + float optical_flow_feature_error[npoints]; //error in Optical Flow + vector fb_pass(npoints); //Points that passed fb + vector ncc_pass(npoints); //Points that passed ncc + + for(int i = 0;i<8;i++) + { + for(int j = 0;j<8;j++) + { + int l = i*8 + j; + + frame1_features[l].x = bbox_x + (bbox_width/8)*j + (bbox_width/16); + frame1_features[l].y = bbox_y + (bbox_height/8)*i + (bbox_height/16); + } + } + //金字塔图像 + // Pyr Lucas kanade Optical Flow + TermCriteria termcrit(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 20, 0.03); + //计算金字塔光流点,HI_MPI_IVE_LKOpticalFlow这是海思对应的函数,计算前向和反向光流点 + vector status; + vector err; + + calcOpticalFlowPyrLK(frame1_1C, frame2_1C, frame1_features, frame2_features, status,err,Size(7,7),3, termcrit, 0, 0.001); + //calcOpticalFlowPyrLK(frame2_1C, frame1_1C, frame2_features, FB_features, status,err,Size(7,7),3, termcrit, 0, 0.001); + + + double xmean = 0; + double ymean = 0; + //fb_filter(&frame1_features[0], &FB_features[0], &frame2_features[0], &fb_pass[0], npoints); + + //归一化的相关性系数匹配方法,正值表示匹配的结果较好,负值则表示匹配的效果较差,也是值越大,匹配效果也好。 + //ncc_filter(frame1_1C,frame2_1C,&frame1_features[0],&frame2_features[0],npoints,CV_TM_CCOEFF_NORMED, rec0, rec1, res, &ncc_pass[0]); + + int pcount_prev = 1; + pcount = 0; + + for(int i = 0; ibbox_x) && (frame2_features[i].y>bbox_y) && (frame2_features[i].x < bbox_x + bbox_width ) && (frame2_features[i].y < bbox_y +bbox_height) ) + { + //总的好点数 + pcount++; + } + } +#if 0 + if((median)<0.10 ) + { + lost =true; + cv::Rect track_box; + bbox_x =0; + bbox_y =0; + bbox_width =0; + bbox_height =0; + return Rect(0,0,0,0); + } + +#endif + if(pcount == 0) + { + lost =true; + cv::Rect track_box; + bbox_x =0; + bbox_y =0; + bbox_width =0; + bbox_height =0; + return Rect(0,0,0,0); + } + vector curr_features2(pcount),prev_features2(pcount); + int j = 0; + + for( int i = 0; i< npoints; i++) + { + if( /*fb_pass[i] && ncc_pass[i] &&*/ (frame2_features[i].x>bbox_x) && (frame2_features[i].y>bbox_y) && (frame2_features[i].x < bbox_x + bbox_width ) && (frame2_features[i].y < bbox_y +bbox_height) ) + { + curr_features2[j] = frame2_features[i]; + prev_features2[j] = frame1_features[i]; + j++; + } + } + + int n2 = pcount*pcount; + + vector pdist_prev(n2),pdist_curr(n2),pdiv(n2); + //计算的是原始的点对之间的距离矩阵,相当于这些点之间的拓扑结构一样 + //第二个则是计算的第二个图距离矩阵,相当于第二帧图像上特征点的拓扑结构 + pairwise_dist(&prev_features2[0],&pdist_prev[0],pcount); // Find distance btw all points + pairwise_dist(&curr_features2[0],&pdist_curr[0],pcount); + + //Divide corresponding distances to find the amount of scaling + //计算尺寸 + //(1)对于每一对点,都有一个比例,是当前点和前一阵点的距离比例。 + //(2)边界框的尺寸变化被定义为这些比例的中值。 + for (int i = 0; i < n2; i++) + { + if (pdist_prev[i] > 0.0) + { + pdiv[i] = pdist_curr[i]/pdist_prev[i]; + } + } + sort(pdiv.begin(),pdiv.end()); + + double box_scale; + box_scale = pdiv[n2/2]; // Scaling set to the median of all values + + /* + * Bounding Box is moved using the points that were able to pass FB and NCC + */ + bbox_move(&prev_features2[0],&curr_features2[0],pcount,xmean,ymean); + //跟踪后的矩形框的坐标 + bbox_x = bbox_x + (xmean) - bbox_width*(box_scale - 1.)/2.; + bbox_y = bbox_y + (ymean) - bbox_height*(box_scale - 1.)/2.; + bbox_width = bbox_width * (box_scale); + bbox_height = bbox_height * (box_scale); + + cv::Rect track_box; + track_box.x =bbox_x <=0 ?0:bbox_x; + track_box.y =bbox_y <=0 ?0:bbox_y; + track_box.width =bbox_width; + track_box.height =bbox_height; + + if( track_box.x+track_box.width >=frame1_1C.cols){ + track_box.width =frame1_1C.cols-2-track_box.x; + } + if( track_box.y+track_box.height >=frame1_1C.rows){ + track_box.height =frame1_1C.rows-2-track_box.y; + } + //将当前帧赋值给第一帧图像 + //cvtColor(img,frame1_1C,CV_BGRA2GRAY); + frame1_1C =frame2_1C; + + track_box.x =track_box.x*Scale; + track_box.y =track_box.y*Scale; + track_box.width =track_box.width*Scale; + track_box.height =track_box.height*Scale; + + cout<<"track_box="< + +using namespace std; +using namespace cv; + + +class ColorTracker +{ +private: + + double bbox_x; + double bbox_y; + double bbox_width; + double bbox_height; + + double xmean = 0; + double ymean = 0; + float median; + + int npoints = 64; // Number of feature points + int pcount; // Number of passed points that finally track + + //IplImage *frame; + //IplImage *frame1_1C = NULL,*frame2_1C = NULL; + cv::Mat frame; + cv::Mat frame1_1C,frame2_1C; + + + int winsize = 5; + CvPoint pta,ptb; + + // Init methods + double euclid_dist(const Point2f* point1, const Point2f* point2); + void pairwise_dist(const Point2f* features, double *edist, int npoin); + void ncc_filter(cv::Mat frame1, cv::Mat frame2, Point2f *prev_feat, Point2f *curr_feat, int npoin, int method, cv::Mat rec0, cv::Mat rec1, cv::Mat res, int *ncc_pass); + void fb_filter(const Point2f* prev_features, const Point2f* backward_features, const Point2f* curr_feat, int *fb_pass, const int npoin); + void bbox_move(const Point2f* prev_feat, const Point2f* curr_feat, const int npoin,double &xmean, double &ymean); + +public: + cv::Rect FirstRect; + cv::Mat FirstMat; + void init(cv::Mat & img); + bool lost =false; + //frame-to-frame object tracking + cv::Rect track(cv::Mat & img,cv::Mat before,double x1, double y1, double x2, double y2); + + inline cv::Rect track(cv::Mat & img,cv::Mat before) + { + return track(img,before,bbox_x, bbox_y,bbox_x+bbox_width, bbox_y+bbox_height); + } +}; + +#endif // COLOTRACKER_H diff --git a/Prj-Linux/det1.bin b/Prj-Linux/det1.bin new file mode 100755 index 0000000000000000000000000000000000000000..3290928e05fecd3b0813eed6e6b09ef898d86888 GIT binary patch literal 26548 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 literal 0 HcmV?d00001 diff --git a/Prj-Linux/det1.param b/Prj-Linux/det1.param new file mode 100755 index 0000000..abd7478 --- /dev/null +++ b/Prj-Linux/det1.param @@ -0,0 +1,14 @@ +7767517 +12 13 +Input data 0 1 data 0=3 1=12 2=12 +Convolution conv1 1 1 data conv1 0=10 1=3 2=1 3=1 4=0 5=1 6=270 +PReLU PReLU1 1 1 conv1 conv1_PReLU1 0=10 +Pooling pool1 1 1 conv1_PReLU1 pool1 0=0 1=2 2=2 3=0 4=0 +Convolution conv2 1 1 pool1 conv2 0=16 1=3 2=1 3=1 4=0 5=1 6=1440 +PReLU PReLU2 1 1 conv2 conv2_PReLU2 0=16 +Convolution conv3 1 1 conv2_PReLU2 conv3 0=32 1=3 2=1 3=1 4=0 5=1 6=4608 +PReLU PReLU3 1 1 conv3 conv3_PReLU3 0=32 +Split splitncnn_0 1 2 conv3_PReLU3 conv3_PReLU3_splitncnn_0 conv3_PReLU3_splitncnn_1 +Convolution conv4-1 1 1 conv3_PReLU3_splitncnn_1 conv4-1 0=2 1=1 2=1 3=1 4=0 5=1 6=64 +Convolution conv4-2 1 1 conv3_PReLU3_splitncnn_0 conv4-2 0=4 1=1 2=1 3=1 4=0 5=1 6=128 +Softmax prob1 1 1 conv4-1 prob1 0=0 diff --git a/Prj-Linux/det2.bin b/Prj-Linux/det2.bin new file mode 100755 index 0000000000000000000000000000000000000000..97ffe9f72629a3d6016a80251a80573ff37f45a2 GIT binary patch literal 400736 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%0AYt8U^j;!JAG{iZovXdz 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%0Dg-zC}nM~RF4vz1EFyDSA&+i&ynt4~smokr}T z{IRU+!->4^-79qeKX*k7K+-7~3&*Hvgkbi9a|>nGdAz(cyJJW-r;y56>~; z-RkoB;g()J+*g8e9~>~e+=n;tlVCsYR^h)-&4<{GczAy+9J8i=2P^WJy!s-|Cc9vvQW~bd61gut)*GLDfnG60@n@+=A5P z8suR_`+D@rhQwg<$UYFi7MS6#3InLVp+sIu712+(>d5=Lu{dv@m5_Idq&f9K`%Ig- zky|{e+>!%Sf14CaAD2YM(pqZj=Tl#?RYq)fC6`32Y^0Z*Z*h5nlAK{>Ep0ipl{s`~ zBhhiFqf4bmkll@^XimddIzCGpTGdb0nw)%D?_=Cg9E-Kl?D2Klwa|e)%Gg4U8sbUX zkbGuubrm^#E0g@pYbLt=+DxXb8~0Gg5k^)y(veEN^#`tvgqTCWXxnJuBr5KUP9CbG z`5%0^o`6)Mzf=ixEhoZ`7Bg^6JxkA>;>f(n&*Vy|pExg1OdfZgA|?MZg5PL6y`L}~ z9v6OQI^THF!v&3`(=CjiaqlKCEJQGJPaD}*@Q5k8s6k^}i%G6S9^Lv$6~D|3<8;bW zQ6%@6&hP!ncV+4$_;ThyD`Fge9A~=6`QnF+ z;aGaFiab5wPNm2}y5~X;(Ux(iZ|Av__A5z5)^0Tywc`wV|J0S#94%n@-j$;7Wv9hj zbrIabX)N8M-p^k{4_>U^#iEQ$DAPCp0S#TlQLim? zIKzqp(x$wac!td-z4HrjQn@>K<16blT5bVmuRBAfgdD%lZ(j^Dk-_NUN4OhHc@kZD zlgKSkWz3!wlll`Z@swFj@|AXypDK~$zv;3 z5+dyqMis|uVsNM$T=0*YxN@Y>?a>mPd6#FA9>Z?#bGsA_jhYT`?w2t3+Y>p`^NTq% zm_y>zl9;6IVj33ZK|QJrK$JcfS}unX{q$4h@9Y8?rPM%vY&U}?(VfJ$@*ZV_hKba! zn<06!kQ}O*LQ?9F(X)wKbVS>9Cz+{pajT7xM=uoopjp4@57krR()nGS@B3xsuY(VD z_UoZ37V0!%m?r&qeiq3etHVgf@1yglG%=sbjtMOGi_C?(=Ts_Wr@;12fp%wGF!N1; zuFhoMxcb3nb4_CZT@H(lGUfN%&V?4Oa>8 znejVIQnaj;)Hq!gp8FzLa!d=-=7@>=dQV7v^_=8doDh5VmtqeH&f*GfrfAk9v80Qb zyY{w%bhCZ53^voC8H>qwM|(67ewzh<^Xc(DmSADgMq+kJP<$9jHfisplY$;Fv9p|U zUuX@^UYdyd?my|8_9Sc@h{ENz{d9s)F#4#N<8PY`(mq3qRIJg&%ePN5;Ug`W)BCHb z?D;bKrG(H2d)Ct&-PJI=<232{s|E&q6y0aCNvt(KllWSjh>t#yL$6F-I`#S#vN>1C z3#&RZZv7Xyw&OV>1*c_n>&s61q^68nvpSdArZbK_*7?P~dzemcpOp}ZDH`Gmw|J^M zxr;nFWQ#|3s?fu#FBqRsEPW_DfgV2P$_@BL;;n_}xIezZ6#v=cgP%XS-`6GZb&noB zdRLYnRJzHiEwW&qo79W;H;sj*ye#v&;xZ9h@vvpNBRw)If%bRo!9unI<%i4TdHZZU zQ8gduK8nO`ZuaQw(NU z1wIx>$jmw*PY3RjOHrpp&kYP1SH}c$`h>s`u1&x)P7TKu5L$Wm93y!liw^$WME`D6 zfJ2NL>=w%rqgyFdF=Hp=op4vQL+L*EW#xFXuDgP{;hRUYcQ`Q$#T4#-7y*0BVnIK7 zBAkEgOB_eaLF%n;GE60fTDRBGl{P>wd+3lNy$t%V;x997Y!6v9N1DF(b%6NBZ1TP& zQQTjwgBJfhsak{30SbOa_d7b^e}(4w)-Zv}&s;*oiobEupAG3X)1}gM#??-Ca{?KD;YypnU7=|p!-xK4}Lq|z6Mq{J~BjF>OI?->Uzmh`WQAXA=& z(6$-j@Nj+^=^Lg@nvTpSvsw&+x$Od-CRfRqB}t(5A_itQr4Y@nopgk^HvD*6M5-eD zn2RZ<;5p0?p5_1)j5(I_f#P0_9)`G zQkq-)@UH02kokBm<1k%a-9}0LbGmJh2aHiXTonrI8Nt>;F~|0wD>_DT7>~ltrBt7 z?cUI#q74)8w2^-%|45aI1Sfmn8MYq!OI-Bt;g+kf=zm9siC5p5hWWQfQw^^x%Js*W)ab~OvT-#Sz4QetnqI+Jy*)H+!+mat_aw2AyBhf>csQp8+G6X>Bv`fA3PuO^ zl9TIxkjaN9K>BeRxb6Rho<3|r#T!;(kH`Q|&p})XLIvYlF8S0n9>X`yzyg<6W~aey zlq`QncWqlj?<`CpX5(f+Mc7^9ey*O3eA`L3X^r3_o_r>@F+MP1u`hTiy(AZVe~CV> zU_}MB#k4Xah6#MPm@53dOSBi3!Oy{V=5m7`*XYvB?5N8nCW@|b&nW?Z{&*l>^SX{K zORRz?hIw>l_I>WfI%D+S>4;gcdJ2vH~m%m4jR@1DNis17AP;a1y3^gy`6yiVjEj*zKd6ZNjM%mq0J| zI8rOSVs1!F2$(c_A|q2whXpH9-6e?i>Tii8wHNrS2{a!S z=%uJ5*c&iNv%LbuzKL(RTb8Ik($6KV6=2d#@) zklwckW^4OGb+QBBFK|<&6%_cQc}G!dUN%~68jo+owD7{jvFJEn0>U@vqA0NnzjfI2 ze|F3gA1}{k%Kk~wHx2!yRZ3u(uRKW?4!#B4*$;+=S0P*R5A|%mPYp{dIhVsX#Tisb z;K;Z`^xr)EVaek_Lk%8GS&vOsIXI@y4$n+!$Jv_k=*`O`(b$Yrm+;uU`Xpx88o@TE zp0u8;q_-{i;i7sAl%0GAKX01B{2YFdu26Jkw2JH?)YOq-79J4~dPhOu%?f(z;vlED zXfiIGwI5+mGF6&23#%rTp#I|ZxPLmK&mNq^T&)lI_-iVzGBJX<0uh+*eM1LN+@MuV zKXdDxKi0M93-9ti{JJv?E?rH6Ex*!1yJ|BGybgn>Wm};?hwNw0;}a6ec% ze+bvM<_@>$Fp|M9I`G-gjIOBJ0--;{$k85uk`$HBY%)v6vxAYi>Bco~kDb83Rvw1q zPaLP$0&1w)d4CeEtOjvzeR%w<3|jlEk;c<8*w=3(aGt|Bufxuuo0P~%tVkvb{uY?` zRRp8lf02D?jc1lr)0(Eu`0H>sPFSi+%Oa1^I@BQ5c`upR)LmrWgpA|8nGQms(bw_DHb6h8>ocR_#O`GYC-$$s__hb0N z`~~CT?82CwjG%Qrx0&!>BiOj$1nvLQ&3&8V1e;sr*u1f$;QN;h_-jESyH*|+%g+?v zkGGKKcMI$zc!;)1!bZI${Ly4a*ACOc7ex#4^BouTKC&Ebm!G6D(f#z&z0>&ojSKUi zVjJCTC=EJqrUNA4}zMBA=PvRcA@(6DJE*rWkB7_Cr3&Mmu7B8|3^ z%YOx?o9PU)zG^AiWjsKuhphz|>PZ?#8sf^>ewv+@4ta8jM~e&_es#nq8Ic~dkJ~%J`H+Zeen6iQo7M1igrwi z$5pwt=uvbSHETR^LV74F$(NE9d?;>nF%)a>nS^!Ov#_|{7&14Pl1G*csH?YdpZK)~ z)!qyRqnEzGX%~|h>#{IhcRY@YE8}K-cEFBKYk_@piH=G1gn1dZIJP;L96P~7Prw#Z z>-UtrH+c{DibW)4!wPD%BOad5OJd|NM#JO{I#8&*jU*RtfE)7vk@mT>$R)!_rhor! zuDH?!?@iUFe}5gNThijlqP7ZRe{ zogAH`gI8zH#DKcvG>t2vs|sasq4f;NIFO3s*?D+kSRkGpA4PY{v~%s_MnR3?Mz}I_ zFSLA31he2!s`**CXWOhzo(_{lsi5mlqAm$&Bl+Z?%~9s*_E0k8lMFc6j>NzYC3M|b z%e+jn#IhyVak`L4ktzw~&cAX7RedMw(({OU@!<)Xw#x!w-$c=?9jT!AI|3vZex~<# zI&#}2_TtC<5)_;J;1XFKtoh}R%f}4RV^ZhIyHO>~sa2QAhGD}<+;tadKDr2AshlN? zHg^#7)W?FSH3<_pS7U>WB+gHB!dU{}sX~1-&hNCv&~t0iy>d3@G~1Hzp;cV=n^K@XTp_h69JXu&sFq#)pL9(wzoae{2DLG^YUPEY8O* zg$`&sw~L4u?SPT7v7jxvj{172<51Rwp1YVJzJI!$1k_r?k`2GPn3;!RgPJeM{OF>) z`wx@E&pMbIf13Wz+fT+UPoUoqWHWyjYonLRYp#5199^@1F^*{2O#V%Jr$X;dU|D>?H56sghp7DOED81Rp)RM3llOK+C*x67y~j zP}dQ}&cls1_I+?VJZ}b~@oqvNpCLbnXP`xU4h@isrn9Y9;Imu1@V$F1p3wHg&uE8t zr(B{(4=a-yRrc6&@D=4{b>aAb#pt=TiJUDdq!DUHPd^zAp zGdp6bxg9dr)X@q}eKNoQAZZ`w4VS)7BQx#m8Ft=l(z$9VOiB%*cl<=``cHF+O@SFr z^iyVrG+X1S>H3f|`6;p4<^dZ7mzC||7ovO7x-hWo5Vji1({qV-z(qUaz|U@`+O`@V z2>#Kp3zpE8K?{l4T5$DxWWZ5f7c%#+9;6wahe+utvR^hGreh7Ryh+%km$IoG_E{+Oi+Lwm2!&~W2XU2s*o833%8=w=>{ z@1+V?>xuuAE^%Ov9!aonAxT=xAopiB^&B;UzW#B5C~PxAr^Le(U*3}em5};ZjG_T}(!(De*Ps;mliw$=L3jiMwu$f>U2gn7Ivo7;vG4Q+yhPv)_84LHq}zXqHLt z+z^S+gqXpLA?kSXd@TCxFJvCK&Olec*VHchIhXsam+Li=?yRynk0RKYsy09ILoi3WnWBjM~IMNyrF>k zd-f8j?B=3_5^3=54@8uxg{oCt7S9G~O1|gX+71xK>!i=tN zGEeg}IWg}zcm&TNVFRk-%X_?F`SxORt#~LKoJa7Bbrk*P=>!+ohjIr3MnU7l#cHa z$Q=K*5qPh4FstM=*>h2X-4m4$DjMGiT zrIY^Lm>DtnV)Pzr_;!w{`1TKaSVCaRZX1K)mX}e#;3+NjlE-tSMuWfH2^#o(67IQZ ziAS%>K&mN6CP{wdBC}Jm`t}@ruAl~gw#VUrf*-T)xH(i>m*T&|Q*>Iq7__f{CA}Y( z!}Fi3(f#!~8nAo=+?}g{b7Z!oYp@;7bsLTHeih8z0ab`?S_D&-?$SK_2cqsLJyaZb ziOFwyNW79JaVt9WsmC}WKiJX=KURMd|4AsNmqUGE@i!&0L);>6sJa$=aN=8(J+&XV zJyyUlxj`iVTygDrD_AHB!f{4kf=?_Q?v7hcOg}1dFHbsC*QzlnRr8sV-QPhr`|rkG z^83WG%~y%ETnAQp3EztwKas)?AB>6)5oc%a#Bl>R@j(a+seC_Ox7L7!Oa(9sv7lBi z)94GYJydSTN&2m4Oz?)K7g zmmKj?`!QN0Oi79)$x6<6COsSP>nP&#rDb%4*$Yfr z7lh{(=HrS5@2Sd^GDvR4Def_Q2dDln67)iDPnM$^?E zULZY37IKc9#%p&TF?%Q8Cm+RHs543pQcv$ACYv83_j>`h<&@D$c!fNk=f*`9MUywq z%i-v_Y;d!ikgo!&5x``XaUM$U~Fw=KR~+O8n?u zd-$oMyL`cmVf+M{DwyDN5ENIL@kf^w(k-J0h-9L0Pk!AG4=l-sQNPM;(hPS$o3?0Z8xYN#W@Ta0Ff8$#yA0}zRO5eA{<;7{db#e^E zrM{&jk|S~MkB4y6CyDBh&cUA6JZy-JqxU&oYP&lbS1yu8$@$OFSGyXYe>_Y@zEb@6 zy9@E|V?%r|_*MGbwNaw)C9Z3bEV$&OO-z87}`|=7UIb{EjLp z|Nab1{aesp@O-)5Sjj$4xlS5hOrZ<*jO3d7j?&ncA9RdO3>JBJqUk@tg4v#^lWE3& z-#&!xoo330aH-5VZAbhe@P`|A>O!)>d)^=3%j^_*-u6OXU2lXMaKV`vWOx9zB-i5g z^xHI}$P8L6_QT)9CalYFQ=C5Z5ILOu91;&A#7N1Iu5-Kil|9k4Up|3I7Y*gVPr86_ zCyhgi#+!KJiXJ9ieO_;s)I`^;Y@_#1PY*eym=10%sJS;KT67|Zv3{Yr0+HbXn(J`CI(jhnLf!oJ)-Xs8spiUBI@ zu8dj8J+#O4N7Z1x@fxsS4nRPt9b0~711=f)1GCml;L}nM;HdbAsCje(8h;&!VYUab z{OKV)GuD{hH&%rn(b3?Y^Q&>Yj3#QHbf*`itI&7)5j@j4g|;l)%dSgFV@cd5me=?Q z^Fq9dze*{I=d9V2=>{-gUZ3^sc0)s3J1XC9D>#WQ_?1r<@L}t&V_kVF?{1mFdu=h| zS)9eIk7~p%@09t_Y2Gj-{V~)Rc7WOR#qf3OINb7lBiz@IX0JCAc&OsaPHHB?UKvB8 z6MlgDtW2<*DrElIc#zf4Wm_rKU*9T4(t3s7OrtAyg>3*w-Bqma?oO_zWGEZ>WE$^x zrUTaLB|@p^bII3emkIFhZ}RRgJ3l2Ew+ zFPvp`*#q|~VbzyHgf#^iFQI{7)`NJ& zk3%y@UE=)JiP`f#9~Pgbpr7-Zh>k1=$ImB7qlOGSPU?S(&cvOot_#B@6q(78l9VVk zh;a7WDk(~nG?xY?5zT2*rbHPkDMX48LLt-HYimN$plI$TiAs}7qf+1b{sPzayPUK4 zS?hW3+XW_FZXzG^)u7AxE#xS7fxm|lEFJw868B67v)d`~e!o2=+owQF_i|qGJ%lUn zvEZk6>_xdP?U)m$&5s=p&6JBT$hi4Wa!3ovD_{L-kj`LI@8gnHNrJ@pQor=aE0T*${_6K;$Plxw& zRANmpk74h=1^D!bF?5Yq;OLFPO0rf({1UQuo*TTpFRKjAgY!|~<$5fE}xNpKd6&{IDO@)oIpJO3xKf^I=v+B-77N>vu!B|=u{g5&C`|X#R*P=qf&2nTT2b)4?Mw&IxkF3xW_8v zV)$l#MFzxgX+Adsc zj1JH6NnsJS4(PVG6rC3-Ko<8WuTpkGh+#5nEPsz@hs3eB;(6Tjg!1~a&RD)`HlKbo zf@i%@;I2lBl#R?rX_dnloH;;VC4{h3XO}>3?Q$Vr>l(R{YK@;KS3`ixXE?WQG32+* z!tD*E7e0sW&pyCThxJhDUPT&F^n+%OvGzF;E3LRxGc@r4HTOpCBqV{kKMq;4W4LO zZUXnhoS8zh9Q{$5Ns2xc!I4#5a_+=IeNi;*8=^=Z-;JUZwzWXd`{DS?)dggBJRnJ{ z_fm5w6VS1`EnFSb03KIjXa>6onQ;PbxEc;j!WGi@#Sl|ziB?r#z+=c8GINq9?R{n{ zO${=j#$HQ7+as8bu|~FdTO@#nG0ge(5xN6(g!KcIxwy@o6^xd{@VY$gwY?axCY+R* z9hUO<^01?e5%Lr7%On78l%VuL^4T{|C+ z`9^~IzL&z~7I(7P)Ehp9ZG`u?46$;l3DFxr8kRiQWzx4bSs+(Q*6%MBejXeqZW`xJ zOwU%?Ep-oPat?p(Rvlf1uHP1-aj?``f?!tsMgf-$(GY(CxW))OO8*KuD%PyJR|JgKxy=gZoJJojC1J>aAuy^!55C?W z%zv7V#uHu|=zFxCm5n=05^(gioeH|}41>yWN z?&XJ~H{fQSooFZr?A45`aCdY&9Jb3N9y^R6db<`gk1K}v=Vi&N>W1>FJQb2DowG3y zH<1U&e-iUsrA*~P8tdw|byh^5G!^YuoL18dV*BWAT&toRA zuwb#YRGGw0RDeGb%`m-nD=b(g2bG6zvQoEnR_K~YJXDSolR@!3-YD%wJdWv3@pOk2ntIKVG59NIQNcvLCk#>4iCkn)vJHSnL^>#dJsZ!t^j3 z>HCNb|6?c&mSzpUx>cmNyfr*uJ04#+EM^{ZF>L7X62ZN{ z60^Rf%;xUhC#;g+Uw-G1CDR1gr(4tifMZ-Gb_4`>Q zqvOk9ZS?m9UB(NJ)GG!YyI_>;Bk3dC9MO=98S zB2ti>DE_lbAais#lXx>dK1Jg?=C^TX^6xQ;PnW!<5Bn42ZU3=NA3cRP4);W@gDaR{ z+!$P&8_e9MA0WF9Rh91_HXiG>PcZ$j>L~m&z}OMV)sOMfuAx02gRmiTD(+mfgBGC6}r zG)umPPRoCwn`0V=NAJb@*$ueK>l{m{)rY;88d=k|dALyKB#V3}&s=3(NwdjJ92g&z|y5FM3eWN+L=qGEPaIBqZ$+Yj|d zuK``8>C7%TI(8ZP+Nue%|7EgoO^%WaVJEp53~=*IEUdA+23PtYLe2AvEJkAQZISbb zNt2d?&x#fzm$H#~_#`m%C34{OQJbz$J_!$OcH_-ww}r71+ri&|5Y$*T*sgngfcZTN z5HAg%4#|HyiK{0s&v3p}?y&nPi?42FL*ibST?zUvj2_-B-DfTc%lf8~w|i{aOL=29 zp;?XT|CaiMo|>>KXf_lTO75#a{m4!oCo2fmN--D0#>FlH%eiG?skX{Ukqk$24E83i<;Zj z!5GJZENs;_GHMNyw5^M<$E$SQHE}=YUEju@clndM$F<+c= zVoZ%1dTbtoD`h8Op6N228hVg5b?(A8#V%%PXG%5)C5EMxuOOm` z#P8~5miC*nT_9H$alVi#A3H{Z?fOIWYfU_O&WRh_jo?EkJCN0VC$Wm#6UoShCz;ml zsW`6DorSb3!T|ML_9^T*8-6>8g;$tCf%|LHYTXC>m#AVxlm?FeZiIv8&t&(<`QRJv zpXD|?FO|Q4u1p$wyNjy_Zx-&|asjoH{>aAIi6@8IDmc!J-KIj)Y9>a#!V)2@AJZdbD*|Fv< z?iiq()NkDMbuF2gxQYCCq%SsYmqo{xR6IC&BO@5gPVQ-y{5+QMsfPyo581^$efn_w z72VhbVJL2V#KtCQli9*j;pwLb8+Bw$QQ=Z=-rLL=bt2=iJ>)gXDf&QuQB7)S`~y^;8qtG;e?h79I(o76 zCXLpaL0w}9Lg;ICyT##aY0ct7c(ZP_6~ddhW}ou;u*2W07Any^FF{ z`n=ZxD}MjeH?pQ2*|3#Eu`DBm+7=noWfp^||BBzlXv-aO$0Q0GI)Eb{ewNszJA`2; zcG1W8Z^945aC$l7G+(nbn)lb$#o}ByH2Js%C*G97k`syeCHp+6q5+K>n8ys_7GPD6 zdR8XwcARWZgO|DV-uyk1xz9d?D|L;y@fY8+5o;~Q3)dJMH0d(?*kuU&WV(eNXh~=J z$k4*hh4kcwaB%Ir3K3zeCPQf@GUG!9*^o zMxj!O8-G(;g?;~SKo37pyjUe=HS(OLEZ<#X{qrWq&$q(bQGSq}6^21w7nyD39I9-+4GLx0Q%RZJnuW$M~tZ6P&IlpAQr6VkL2E)y5YIfZ#=%zi5Kmcr+N$Dll}MS z;V#9ERD0hX3d&)0*_IXXgWIA^OBxtk$CVFIJqp>=8rhe|!5H8n@%&p$Aii^tWVJEp z-Zc-|{i7k6alE2@{k4&J)GUKJ{MN#d5v4fADqFBf?@6CdQGxh>PsAw;_4t*Y1S2GC_`fG->zkajSpF_;xnOl(MW#b=Qw^a{2}{7INm9p z1?7_eP;S~en0B-$9VofA&;J`ndVN!Yz}utHPA`_&|Llh^rdne$OCs97zgU!t8MRPI zB$2z<@dLzy7g>1nyI>k#ppF^`RW~8X*0Q-F9 z1j(!mWa~1XUWg?(N(bdxuqFSp6Y>%0$;;A#nyAye9yb^DyU&hP+{K31mdst4lKCZjdj|bIn#^a(Ju1$(1#hRz#Qbsv^DyqR3 zgSX*}_Zlqn#ZwUb|0p*vaK$NSds9cxi?H3GA1$ySjRivznQVS8=~L^5eT}Z;zi(F9 z_fQ_B46nvr@3->jJ(ke+n`iL)mlCAU57Fu!)k1diOwilh2NFh@&?9j&bk0U6I#kVv zMsZ(gk=;T4|Ma51Gm2T?dC?fJqJ!m{9?Z(SgSbD}Cl{(4$xZ1&xYM)(+U=*o%ig1T zpGT2A+5Z849x{yQKZroNzxxnkJ#hK(0r*>y>M9siPV)Ldi zPj4T@Qes7Bbv+c7Zu~(VlNUJR@js09AI&4jG%y?aUi8z#7TcjpG?sO8|iW$kE_^&WF3_k`K2ZsF&GZFm<{Vdt>~c+^va?l8BaC7nI^ zX`9#B$HE!4C9dq1F&FUB-i_G(RFxZKy7J~!PkzAKi~lIJ#fNKqOBtUuRDI=7tj4V* zB&#=iM$F}IhCTSdaEZsSy#l>{d7)N806YHuE%Yoe1*_j8xhxY;clYc?O}8(0*p1-#5N5Ae4R7}Kb?F~KGZQDyT7U8o6)v{o0O#; zmE6c?#4HjrG$un}{d#`Be;;nD8-UyVO9`gR)5a||q}y9n)R_JP=FH4tb7g|q*{*qb zZ21~~O6etBaC!&F&-TXyJKAB^gTd77TQoUXSd9~E_28E88O$5}3d~OShSneLpm{h9 z)>#dpKQ{JY>(VQT%C+lw?Rzj{c2A6)n~Z0e(m^6X1n7fF*KWsMW+wL{n~!?`x;-+ z$n1av?@M5z)mD1_qXzw0vYzCR*atFWs=m#d)KZ!}MF>&Z2I_mixQeEjHfTU2>F7$+4@64yAmk*)R) z?1I82)|ov*aOyh?tNo(zgjOrdT=iM-aeBeVn#nNFiab^rdx{l|9D`X#57~pfUbvJk z$J|UOyd&}U4Ib^lC3^=58U4cW^H6nc4agC0&+!v?4@|`e0g2$Z?J+StuT4%A4Mb&^ zCoE^n4t8Znrg+QivpBt~58hri3jR8bh0s&V5L^G7JsUp)H~q7M3r)nJtZ2bVwh9xed!t}Sfee|Grl-vPFKqcZk9kcRu)OHie7FiYun zA;oWY!kTjj-xj0>_ZG9)nLq?;O`!w|YC4&L`MxmeS z5UhQ+SAzD$ql}c*v2pn!c%JJoEP7r@`c0I0n@V>`(!C!f>qi91id-)2Roh9L+rE;6 zhnd76e@@P?j}Vq`JHx*Ck3gx532kr?dTdT+Gdl+{`$t2`F7GxHJ-!NMu0*rwnng@z zB7py{9$=?@iMXc3lh6CUz{~g7#Xg0_q@wHw>Gdj0ocAyql5f?MX071}z6;n#%~{0m zl{&`W?d_ODzx(8G{f7EZt^ zi&IG2%X;P-+ylQ^6%gmV0G6}rlDMGOM0%Gj7QTNyhC|&iGyjE*Jh}ghB||dgS^p-& z(Q{(q(*D>!Hj}}fz1V--lk!4`7#3hlP+a+xY;<(DYkF)Vaa#1*%K&5Im^p`({p(%O7F(;2kkKY1 zr2LHu`SA4uc{y3iVBd+uLXS#vSIrbo$qB^a%P|Ov{lcn*c?fgI!UUOgFdh;rvHEPt zmm{TcuX_Z@Eoc(kI!!>)U>wM2wi5d=J#4Sb7nQe{uq{)skf|G^goUZ?tZz{;`MFsU zf~A?pyVO4 z6WJ%3r0&By(q^v-AJ@EN59Sa$^%+d)G7f%Uw>JQ?_mJB=~+bJwwBk_ek z8NwM0J<#@y!;KqHu+9@PZ2ynZq~)6%4t^1ZYjlpY80}WFbAle*biRct4crR~nU4VQqiK{w)Ejs=D$1KPD;Vxxw z$+uyKSF|J0qC1pWZP3H2x?&NN+L+E?4VW{oS&W+UL@@tLnBePvCIVDMOX-HxBb8kLIK9EK+nu z9qbe(Zq#yQ1!+B5OivH-L(@WWt6V>vV6DiW_&#TQRs+^m&1TsOtMGiE3Ap4>7g_0I z1pVDo?B*Idkryf2FuUGdxcIR{T)%lYJ3Qr#c&Mg>1*}zs7s|4NePy$7dDlm_c8VgN zTd6>TH}%F?sSA}nu@Ysb?QS9`M*R^R ztxw|mXE#ZFaDw_T-fnfra#h@N&g+xV7P#@LpyClL_~NUpwc5uZ}#} zE;|gK6;FuACm&MyJBoRImHrH-s zIhU3b*X_AH-S0M22rTE%=9}@*^?T5M*6qVxaGr9n1*x$}2d zUJ+Wr$DUJx`Wf>{ty(S0yAQxL&0sFulW{M%;rM5uJioOy86#CYz_-^EJosig4VJBe z|9pbz9ZfI$gh!jX-mRXzeSRP}nWf5Ce^%hrW&4sLJ6f2##IT=ax|IixslYiYZ7@K0 zBlIgUh5EV9Ec$RfrjrFUe2foIZ>z@ErL$;F@q9Sl;2exay^c}OqntJ zG;5v?@f&*)4X+O4*@{XPr=#xh_a0`v*&`LV{b_>@Usuo-Gj52_TH@)N{P|qwgp_kq z3Fi?*=h2K-FWPg13w?ATN$4OWXkjx0tN;8^pIdM{J#`3)cEvaS^D+A);@ta1aA;K( z)qLOr_g@x)?(8i1qcE9vB+tV%9tAk$Ex4Zz<30;s;OMGs@R;ptzsKPowayEsO5evo z>bhcdmOX_@MXvN`#c`OpK3D4JY~i1DeRxR3H{kP5z|FWrcyj7FGFUtS<0eJWqJ$#2 zo?gjEC|u;bCOdM49m}Zqku@~?n=jR@TSqhB4W}C77Cf~gh<N0b2{HX#N+e!T_%My#X5nr-N2i)@&iQBJ0xT?Z!04tPbuk{Wg;;Jp0n$P_Xp zzq1;Q*sBb>N0c$DwU%19M+gqzUAX0>+ss%gf`5fu=wMNZ{mu5V^vBB7c*#k=AW?vG zOAJv(`hBiX>rZdi8es04>3mIH7Vmr;z_<7S|5P}fYaEKfL2p&~lEh>-ZcR0*>6HP- zrSah8s6gL4#dG(l!7y$06~0PhsjOW%lxEgSIe|qHI6=c7t_|t|hgzb!xu=vn>%7Uk znk9~l;EpZ$5|#g4CdpQPsHws@o~bbvQ`XOeN0Z*e6)R=#)7zP?KK(*$=38)oy*hi4 zGYb5d4F;c^Q}D4R$HT39D1TL8*D6%G&rmt|YIjh|%rguf8$r9TkEW`7HE7rZT^@d* zKfi73MXH*i!@{TRsv4;XwOW%n$o5Oiu_Z58g$1wiG z_%Xj6Je?bqPG!#%kMYA@siG7>549owVfXz$B zQ_p@*)YH>|&cJi@Oz>Q)urY-1?jys?_O~*XUY_sWux#lz~0%_!hEcmym z9!BpfqWZ(;(2jkE)brm$rZ(mw-dcJCmWEHG7T@~NE9zZ*@oM>ssmVuh?6rGPJ4c4E z+Sd%?(sA_G#Y%~xq(ChvYmy&F1L)ir*C6|q5qrILY`Ils6f94&pg&Cei0JH!rxkLz zLqrZ|X7{)kRiv02>aTmidfhw>;}0p)4s8QE z_1q~EsG3P;N6YX((&gve$YgB#9ml6Uoq-46U&sCWySUaH1Js@xfg4vMJ}@%o#c_nQ z*Z#>{$f|9a6?q)*> z-`WW0_E2gPYs2GRBe=86cK)~5OqiiZanIE6gn~Fe zo2pNoC+^tL0OQ^Jqq18*sc#=l_x9hK~x;K9PLQevyYP zQDP$o^ui6Y{jpDpI-e+aLkPX7OJAhyhr7$p(7c1jbd=3MRyTe<$XF)R$KT?q$8b%W zCGm%r?fwMo`%dH~N0)P7$Lly*z6#9}oT$#SMB37;8V`HF!&j5%@|KCi?VRd&654IX zpL-hEd&Ca4_y4O;%eB> z5%#;riO*cORQS)l9Lx6HBy3p~4w$Y}o{)Hxq-ssa%LN-4kyI!??wWjxsxosPc$Mf4 zzmG9bhH=Y3=3Fyt2rU0P6_ZAe<*E<7>Fd*Fv|mOYJi9v>>n_OffX`=m)0BbI?!qII~jf3wi%0qw4v|u>So?amCt542H2Z@SC%g%WNlp2_;0F7D%B( zlm1?}o9-(ei(4<~p!}4BaDDYrRyx)Q`VGE}OZS-L$LK*cLn{sfI=``ixiUacALXaj zGiY{GDR`{B%QtL-gjqgqG+zOjf2v75P7t>jS~y%c#0PS?TirY8?5QAN*Ng3a?0-Pg#u6?C*aEkJ3#lr7}TfA{C53UFnJWlU~C{- z%31Ko69@2V6=%>dRFMyBIm-X$_(07DC!+T9Evr}9Lrf+B@AXHZ=EwGN`J>ml{)*qw zVeJhQ?w3i7!&k&G-GX9)3)O$P27JzF!=+wP@Hsh!D^9uwB{m!B<)d!6&ZQ9?7bRn; z?;}{SUz?8c-bvEeCO}Q%PvJ`R2EJiYJmAE=;8GQX7Y~-h?W%UT{O2$93tWijW>})3 zlp{Ko`hmqrd&(&#lI9OK0qRAwxvaC0E zd}1m7t|+C?hYYL;9kGvn|7=DFYG2{+2WCUkfxn;|_krI%ynvpm96)Cr`43B56nJc? z97(lLMw@NbFk70-+2M87sv6| zy_S4;%QuX8Q_XWVud+TbZlhK&AGFYYMJ^^T7psn6g%M7v?AmUh+D<3l?vMgmIuIsO{AwzZJ~XuQpkoOgQ!8wHMn8ii$9rPO|F*IVSzA)`)}?+FX{}% z4~nC4wSF01oAX|Px;i>^vLZC8ET!C|kd8Oo#`7CeK&!lgZn5gi$H@2N-eE3urIsTk zsg0*w3mw>LnOUY2dzl;CrwUTz@~7 z9QJ-hc2O8V{qiqdYb}LwYY)Tc$+{GMR#7>H0o2OuG+p1+Mr8_)(6z;-Xqy*+8y4q+ z$HooVf8-sM{c#mPD5ncMjq+LFweQgB?QYBzB(~DKP`*<3Bz!6Kg4LlXD^7*GDcx&rVTrK0o zr;HiR-+h|E-NV1J3njhzOZm0PwrBCmFZ=k0SPyWv7|UB;2J_mSllUbxk=;I3gztM= z^5WU$u(o6$on<$M-s|B-SISxnP4ccdpG43@YKI|p@^)Ue{0c10NriJ8UxLZVGUl|& zorb3FrQ`oT6$i8>)3(>QsIk^c9{j5r??)7n^6~b(&%6+BX}_FwOejW&O*0`wZ3f-_ zcb2s8ac5WV6f*IIGX>#_m8H)=YA-;LsiPRcgmROLk#eVNZPUMA{$bZzlcgzG3PMOImXIm^iu59`t%P z1D+qM#_yAhcth9{I^3;^to0V4TO$LUZS%$2Yaw)UXuVK*YXo>**5EgdzoNn&Eu7Kp zgw3Uu|p9;aU8yD%>;jQC31ANKK9YB!SBth_?11Eu}Pr< z0xrbz&P5aWyhVpF(DMvmD6^Vp<+;=E(;uVxi3Z&A{t28p3SdXk2f4HR&v!wl0RoJE@9CUinkE!erWI+e)fN%%VSc?4hCd z(|MAv3*Y5wjhkG&_|tz|c+A3+=y%T!=NuS`w(5#}W6dcs@^+lk~DsWX2z3S!Kx`GN+FxSt+Y3Jl)}kJ!Z(U(_ky)#zolO zeV~qCj_bpyZbI&qtU^mYX$QSil?PTvGmAn)%o+6tbM5lVHw_z(9}5%kVv&_NwNSzK zU|1ij@}T=jGSo;puk@2oSlcug^6b|ygkLkTW1=^)9leJvc{r9V zdsf4&T$I_}wt=|Bu?XWWL!easw)n%(1DB-qx4ZMOmh^kAj=GUjZa+)v^k^?4qn-^H z{jM~#UD?2rY95tsQr3a{=1$^s56OWw@gkWbD|rNK3A~M)$Bc$AC33+UjF#n+y=M$z zX8jHE?UD7+yV3#dtjEyEORi$|i?2k>Qwv0uf%x!2Jo~3!N{$}v1Dm&+h<<;&g|un2 zLEr2odAEB!40Tn)e(7GQ;%kM&*O@}{xd5^Mjv;9Fq<~!byq*}JPe5Ip?ZT+sN8+38 zt++sEDr#OZ#ph+|?8G+4JTgZz+&`c7wdsMHoipM0=*_TPFNjTZUC(+v@PG$2Ts-u1 zDt2rLg+T#T?B^3VwoWGy3fVo@!=i(PeK-uy#1+iT)4vmCYO^3DJGEh_XHWK9!JW}s)ctG z#y8OWX*l$#3oQH4E6M zrdY7qV-7`6lpu8RO=gq-Uide^gY5rO!=B<7cEaZ}d3t*Rs*GnWCQ4IG>-(8RD_nxS z;nC!wB7m=P05KgH0ZShBg%^^eEl#dC4SgezY8E5Ki(@7Vl^gR|ziW2luFmzi+_9Uj z@H@q1&)V9)N)KVZl|PYv;qmz7@(ETsXA>EuybYCJAH_={yRpw0i%uz-y*M&-YyY`Nn4fe;uh zXSY(y+RS}9jf8x(l=3ZmV19cXc{V4HJ^t@5l$hR=cIMH5C#KWO<9`bob=!r6=2OH+ za?bU;ev7?Ow7{qhPXrQrn;D*;iw|2D5tlnFnEHk(L^*j$!=^e@ZmSb-CZ z$0I1$;C;Fu{j?9`x>H%$Yn;8v7s`>A{nDOB-Mc*V*Hm$LMyy@kDmkWG6G$dUUluzz z-T|@G0&qnu*{XI(e4851oMe`YVGsV5_ekExrnwA&KWPJLNq!{jP_!eP21eQK{(VJM z8qEdESAgfk7h~GDK-?WBb){{_lA2Gag!zIr?_U0%$#^cqjjN{!$zVQWk0@Ui{|qD933cxkT0ep)qYA%)WXAlfTJ8Y4TL~^m-t>FnUUv zchwhizxxXFtBD5p)HhyNt$Aq7om% z4lh_l&L98Fq~atya;#2z?j=`H>^5xrID=G%sbJdl<+ydLo7npDEbFfP$VR3WLALZdTV?KC|X*zJ&dx;vLQur)p>;YmpXR81-uDr$8hY>Ef@ zwf6`setMpao8Kmc6z8&q1#9u4H!E|VZYlY$j$>EO88%Egjy-wzf#o=PN$%}0u>U|F zDc6`x?s)zbygbdB{I&b#6D)c_Ld+{MYWOm-^k_IJlxGV$yRPALUm5gh83A)nJ|)Y_ zPLq{d)8M=Feqm-Pl`{F#OC-n!tExf&SVIuH$Y+Hl#|RRBN7 zQP661Uw}K?M10+AHQtPjKv`8qI?}r@49p2f zzQP5wpI*e)CtpzyGU0xp4O|PlB!2w^IAP&%y!3>Vnc6*=QIjc^8#J8GYdOv0Q+|^v z6Z? zOwCx4_Zl%>nq{cDP)JOR636V59CTXQNTw}7)yz03Ofv!fsWI@dM-oI_o&`C@@;JvT z0Y0o>3=$L!E-g%lbGP5w#=ba(vO4v|-D(BC=^2Xo=e^hnb2l9GtD32-G$iw0++^Lg zA4o>YF?gm`CS`-8$}65llbBh5$>KfFSmMz^U?@(8C!<4Q&1+M3(j->w%-IfMmjB3f zO#ZEgPk>+rGrSKnKqdNTRIjQGmxlo+$8Cu@esm#mv zIFgO;q<+BTYFu(?Dtt6hfS49p($%UZdC=#A2%lyrvAbaey0`X&&W$z9@pezqy&#!PZ~P}gd!tCI_iNH+0!+PbD;r;Y zzWm9juPlQHL&ENT@U!C|dvC3RA430?U3a|4hDkg5u5)k6t(AE=5^g}ApiN`qOUah9 zAi>@4w0O%?;#SO`PQK=vqPgQ)Vkt3W?5@lw$J!3z8O3<=;`dadUR^9a-Qb38Sw`^n zT0ac`7RDO4soN#=O#;K~@8Lm=ELHq`0)F1x2e*&5lZBB{81yZZ4gPXXY^-=m_{`au zV9;C0%Dl%8Kbwi_7OH5j91Qn;npo!M0kAG76uQRPuw|A9gzIHzh}%nZTv1kw)4P%+ zsY-8{K5roFj7lO`NA!WFrV%7d`8YG{FJ&@~CbGUOFAKe+=dgtpYNB^rBAR!7BNlC! z;ZOQuwsCzwBHHzWlV`d`uDecnc`b){B@M)6qw!>_{dY3BZ7lm+If<}DWw8A?lc-+q z0VUt}3H3YPF{7m^XySbne`>wJd-p#}IhP{1SM&@U`UPQSmnY6>Pr$!!CNM2#6q|i> zKYq#E#qL@U!uUa_(W&Y*jJjlwZ@WV9K<#W8vbcg(m*|mS34dY9gBbX6NSA+{^Fk~M zdc&Okg3)B2JY2FH4)5o4mLIybeD}D|@6GJLqnP(z7wolc+2sEovn1)<%Vx%)!9I z6?k>ZP%@{oH#c>V+?Yd;!TC`lYaZ~8?Y#ApUCOK?!$M~f4EMwD<|J zTJ#4u?eE0Res1`oy_(#((1E>srDDELoA|IGRy?QE&VuiBu|eKSL}te;R+uSAT0hHy z*QdqUx^f>Ls&j_!v#ZIvxyM-Rk`l7@N}}KwmjV|y6{5`f7~C?olO>!gD;_mV7B9&! zM#GAAP!au?j4HWL^19X#`IjE}pJ@&o;lBt~a|7A5)cKOTqZj@ceFUpJWSGBC9H!|G z#{2J^*hy7GkW-hJx>qq`Lz5csSE<2GST1hT5#a4<9kzX?H(r`M1a-1Kk@o1t1L~5{ zWmPyX&F+sjHqjWnyi9!i=&`s(rrs{~QyNRr`OI8DM@l^%3)rq)M=H#ZBdGTle>!Ut zhpq$oeD!%&usv9OqM1)vsy7707U21&Q4sOj1^(u}5oRfigrkN@!VSM+l)3+4sCJCB8z#XpoVVQc6nEj;!pE5i%kp zl{Cmb?^~ioN>*u7X`|BK{qFA%|MU3Zob!IaUe9MIiP)4wx5zhfN^?CpFK>IymREGk9~d3 zq(~@1n$J4$QcPl8qmsd>{to#l^yu{BbHL=XHcanLV-id zfBh+eueB0yn5)qf3RXmCOb{w2%HymXTP#A%OrfkU05cxyquS^*Ovu_WoFSTw>Ti_b z#<=mUY)BrYwl6}_z&Lz(L<++X3$7ulk>u0U`E+k-G1JcqZ`AyJs#dk9MF zfnSS$ljvjJsMs7QyrV{fuI5>RWh2Ai_&Jup8K!{8y#7P0shPMVU?eRYH5W5hBx6TL zxy5Y_2|RSR7ednigQ2)XI4Wx_$+4e{X(KZ5dvqqbiShJRPZ~aBPvXq#D`ci-Ep^*= z83_v!^rw?(v_PBn8Tv#LzopSD{fT(qX*bW&P`)Z_9RK3h zY+SFAO}g#g;h9y(F}pVaR)nXaTj33wI%_qQ^l6Ygp?du04TLw*yM-RFLV1<4{d~0L zD>T?PlRs8|4%;72Q`IWHlz zdL(Ph3lSCTdS0u|D2~MJ!PrLA+oCoe% z?}MqUo^cO-9r?)3I=JwAG-PGOqpegHb_Z=DQR&0z`L&G7UqslK=0w&U3M1~%hajOi z04j2u>-0++$nnvy$%mRFb&v2f#H^i2V(&VzpHEn_%{S)=4mox9yT?tK@}L4m<%Hes z2rYK)*(JFD)M)-B{g3Z{Jc(y-6ywQwIexm*eE!cnSw5n00>9s+2?mbO#{(G-?EBdx z*y?eT{BqODY|k_gINiGfYrgtH$Qn`1skMjj-GAZrbv118RK$m@y6`@|#Js)i1TR9y zvzLb3h=#Hw`jxEX_BTkgE)(y;6vj^{J3Nv@3T1f;^Bx1!c289r)8+Y#_z8nE1r!6i%gz;J0#4Q zLg!QeNzcfiG%>c9eU8LTowm2N!aK!GyeNJWu3Cz--19t0SQ?I3oVN+g#mS`SkP@HS zIRFzjOR%m+#dzQ4Dr~4(g$th!;){@xytUwfZ%?g zIZEkKasGj)7TlH?fToyntcchZjA@r6=jDswyRgf5!2y_DFU?+ZTmoO^wP{M_c=(`T z#?CmYmg(TS>pldehO={Hl|cKtAttZN67n%mp}1WVi{|c<$`jpI=Vcx5U%+IH{INRMF#7Bi?6@TuA)pko^+l!^_2!zTixwm%YKTwOe>4yBbWd&BA=;`TY8LH0M&XgkZTx z+kKRM)Bvp&4X_m+V&F?7c5rSKuWLG!zv6b2imsW*gT)A*ec#X6FZJXNpA?|9eGW(Dq~(%JdnCJmg9q0Z}H5*PvoU!DjswZ<%4-C?s=OAo^oixN$$!x z&uts7y52^wZ_(#9)1Tp_tZ{foUYBnv(&9DpYJ^?lE?&HD52l^ojUwxoVwp}Yu_+10 zHO{+v-}5@W{EPMczMxRPbLDIN_oNh#?L7###yODjy9PF|4XXQ9whkcB4Z?@zSfdkq z>_o#!Y@M|>Hr$@U4uP5xOIiu*rMZl)E87cF+hZZXc|S>as>h|` z*63F}#97-d#7+Oq_@^|SUp9X>)qEhlO<%XsHTkye3$>~ASwl9~w=bsr9W5vwXu}De zBiZZ1JWSJ-$0Nr6bgAJr;Vv}`mqmO>qp}RXd%PxJakG={~XE0&q0WJR^PDe^gS%Fu;MM;Ecmh21s1`L6L`NL+xYsmKWNE_ zQT&yVa9UB&0L7t8h`di6waZ<{=9M_H?GCPNlKD&6rJ%=7c=Vgjvi$&uUAiFjL^t~F z_GOm^l+scAm%yiO&a8yaM6&eRDp=`qoo%p@2X}K#zU5jF+cVrubWfzQMti2PAEus1 z$wy`I$^AKmhMYlH)rH_~f0!L#FUn?R83Xwy#@ZhWf{E9&LAtV#Emz1QuEBy+=1Vdx zkjRH6+m+ev8NP7LqYvh8J`LBDeAo#-8F0dO3w(9hk7lwnd0pF9I3BYb)!%FI?lz+Q zZkf%v`u+=48~Tkyi;T&PHd{L2m%%9d1A5*44~rH|z||hNU>zsCz4YFK<Cv;@zi_?NM6V^%NBY6{45A)AHAk6(+a7=Xy z|NfOcq)80H{GYQ>$Kfn&m1gn6#cQ~VEywlc$8e5w4_27pK`N@vFBQHH>|DyXffs+$ zWHlccGX^KWzfT8uufT+~9%>e=2Io7=!Plz}O)X~PQoWz>YIr6eF{Kmzr+z@O^$l3M zy%xg~C-Om(7xBB2A+H!>!<+3i$NooQSpBmAZHly+IhFJAq^2SsGdqQc?mOV!X@U8{{$q;-|l+LwB>Wf6O#E6L^_vksc$sw$kW4gD6JFa54RM=?WQl zTMjbj1i)Fxd3Z5fholyDGVd*$sjRvm)#g6YzF$Lh>7h}0Ls}eHc~MYTN>^4eCj! z!4_`N&l_j2dWK_CK4N9sN~)FbgH49{I7aaR-6!P1Eq9iayG`wM@yGKx<tW2eE8I@80@{AnYE?{ zHc37st_cBLjNLe9VXG9g-~&P3!Fl*V^(BVsUKDoB?Nq)03C75r!1lK)r2ewNdWamd zyn6MhrM;vVNe`XN9gT8F#of7%NVULQ}10bmf#X9GtFCApb69I|b*o_k5VJ{uCMUq70axGq7=H zINj#80YU{u~k@ zYW%VJI=LkN$Z{yt3=-^@z!Q;bc=G-f9rw=CvLuAMbhSMc(r7S)mHm!0HF zZzl1xX(#UEt`m73JDm9DKl)%@33Xg?9seq)kaGc%___WSS$tp-+`%#$U;BbC{*NU! zi&;GDSb)v36*Tb0EKK6B;2!a*xIQlvX9Rx3xXQQ8xl4oebrFZ#pB*9zf}grVsu?fz zSi}23F>YJcWDKeDz&M>{w6W|lwspCn?NAFqTr_Gl+v zhzBmrz{A0pY02brykoQxSACM8{@i~^QnZ*a)*tBm^n6sw4@dLCL_B&r9S@j1#XVW| zcrfKGsRIbtvKy3`YhZfSXG&EZVz)vsyda za`@h8Tp%#99Ptu2Q{o``lb1+Ogc;(eF9&djii_aCo{PC#DN2vbL(9lMJSP7hHH5o~ zn?n-D%;kja>q~0(&=59!F~V`3Nem{h(ieIe;pA;wE;Raxk+4@Wc)F1XEoKtD5N6jq-X+1a)H7uE zoWr0VQiA5+1JQV~IoUld_@erTnbg$9#9?LxxaD{QmYsv&IY&V1#8Egg#SU5@I)dx- zT5hS%9qg}`KzGv`>h@F=_uMo^vp8?OUQvUZad+ss8GFe6f(xV~Rv*6AZiLd-Xj0Mk zo%$P@(EUArM5a;^i;Z+JaGoqVGA$KDI;40rKLvDLWlgQi+v?UzEWD_E_8)a@K7yhj z&*7u4ZhGO2JV}bWLyjy^!;ljrp2=*1D1)t5bBFlW=eQ(?w6A4^=wLqkM1y zY93+mht@$nWg38s9>vpLb5>H-Y!;uMXr?$cZ`;;52W<;Vk9i;nJ+wp7W z4LrGf3p#$91=f+*h}81MaJb$N4!^odGM_(&6qQ3*`O^n)ExSoSe)K2f^V~V{7bS#U zdLGLM3h1UZQ!uZphQC?^@ZsW2p))P;p_WRp4i~b(v$BoG3TMvJfoPoO|B3W!ISMSP zW`cH_Bt)3~jV^pcJ`B||E{$g3d{NllH)qlnSc(faYjE3KJGe%%>r|t?iEPw*z<6*5 z#BtqtR%dHB?qAW5&lTbrue`D7{^cq?ny5jNf*#bMKq6KQ>I1rHp`$d638|vm$#2jm*oQW`UnLTzY8Xq?X}0B8GV+=Vu9Z~-8OcY) zso9jgvx=n-aldHf`%^@u;tjd}h{^ucTE|=zyd>x0uDkW%>aGfqbS0Hp;BJkVyL!_0lAZPCL$X_|ch?<02CaemF zu;@z8f0{2*Gn-3v8@JGoF=^l@bh?^Fu9CZpoygyhQ!GzR;@}oxnGYVj;{xTj){x$|53(l5!-$1>aJ@|nM3eH#oZD>>7&YAg>MoFEcgL~?+GF22rpGQsCG7rQzVr5g@Zkmu)@x6>_g6u?C%4 zth9$7yJ1KZMkNK%sQsI`%}XX=`OG%dyb_O5MF#vcmwfbpWy;?V6$Pcc3*pI|z3|n% z6^iFZ!RwlXB)a%2Y+hMHn`5+TLu@iy44Tm%t9!&CzK{lO0}}Gc5=OsK;1_ueW3$FO z20jWNqN)m#_c4iA-niA=x4S2*Q0@Xna3x-b6uO>NoChi+fsqjNbuVi}R zqBL$_x{aDjawO$k2=*PD$~rkJu%;&R?6~E&aDU%Z@<&}AOn0VQY85X=C5=Wr&@~#Y z_6Cs)eRs%(elv1>p}?k{69rEM7EQ+YO7z-j!H@Q-#O_U2{K5_npIY8Td5c;+bM-Ka zdsy(-Mpp83cPH|>%bdwMFAMrezn)ul*qf>>n1XvP&%@{(p*QU+Lpx^V(a0mEB>lEN zthw@k&)_+7$5`-lRI#Yx^$ZPiWcfjNYktnd5)u*qlBCa_2v6*5iQkAo&iwT6j{|*! zDuH2>3qM<4S+3uq3ahtwGPOrz$eRXrYNkdY?pz#o3%P{{9?J6CW*j~%yp6jaUc=>g zUXy#S(-^B0zPMoQPOQ&K!RVKpY5Q*@{^nD{zvv3$y|yjKe1$fP%pZm1@#1uNe@6m} zw$DPZbK=Z@X4Uvy?FVJPib26pJ$Zks8`igsg8rk9Agi(;U$lGTubL}ZW%e0oEt5m_ z<0+`a7*NH10eJ1IE|$9~;gSh?cuaRaPP3E|`i~k=aKDO-+9FCyOe8zLUs0 zn~PNJwiz?-?@Z`hyM&LMsKM(Nr(xNM3LNO4iwYM`;om*sto$?)cJwQGR#s7z&)zta zU;h2PFn3oXe}>MIM9DsZLEuW(?~NihHoDN997DFGtz|~cI{lm|BxvGX=WDg7F6-0uS4U1{{tQxJ*~L zVQ_+^ujlcTRw;(4wcv8$UA%kuUHrVT6E9AiA#}yxT7GNZi)W6F#K+z1Foes%FP06Q z+RwXmSWz9~Lw)F&B?r-XYYM&FzKzM%P{pgt%wY5fy+J6E&tv+HSWXpKZmxi-9LF`l2>=LDk$-wL0v4mJ!;?&5k!-H#Zd9MVm7$xj}q_x@VhnD2wcNN(AK#GmsphO+qp3~i@ z%IQFpDqD2l1b)^u!=G3mdavgxQ&F`9I@Z{cI^!x5^4AbPO%P`{>FATq(?_Fht0lMG zG=UWHy1*`ofsc<~Kzo=oluG78h3Xp!J$(SCpNtl|OP@LU_kobvG7Hs(-iF5Kv(!IR z!Ti$LvG||dU*`9>WuW3a0?s~J3`Y+sz+9e?kf8N&YRWh8e*OhQ2gBI^?rK2yvlQBs zJRSlaCPF~BIodz}4|mU)%hsuBvOa&q**}S0oO#n?Ffvae#S@dDdA~k6c3~ki*?v7} zweKZQMot1=L-1xTnTP#HgMnJf!{Z|+Br$6~-d+-hXQ!9r*{fIZnCW4ZUG9f(%*|1I zijX&~@`o#U~@e9Kq?5xV8rKK%o|?xK#~r43~IZ8NeZ zp#pzize78kZcw>|ef00SG%8zi1dT6D;N@$taZ!@?Bt2yp&VKTVA=AFoc|&G+a@~IJ z+?;SUk?_HsmI<(=G?$1yp9f3s&xDr5aYVUN4=Xo_!+(^6#L54`{-zY*LZ1FV0}3zx zi^YyzWB81|G5q(B)!cmHZWP~HfiI_};3n&M-0v>TU6;myTf`w)@B5M=a*+^Ta1buu zje`*HNL*SY^u#7qU`ACjs=U+YSAQ8otwk&7ru$K-UFL!x(h{kw%`obX@4^}5|3gEq z%S5y@3-^zhgV*jT6NM64UeHf-?(?#7lj~o+?K%ZtuJVShj!Ved)zy@95Xa3<(-_BT zuc%aMHL1UA3!m+6dC@>MzROygmxT+oCOU~U$ju@FeM{)Uf-l6Ozn5fuEJo=vX&#>| z@n7ql;Fm-r@*U>5WSkasOfH9C7f(Yr*+!1A`p{&5t8S0~aR_sK2qKbiiMLua=H*R7 z&o7fua_2?rE@L9x^U`?tWNDbARD$Ey>G2KxcXGi_n*4L?pjTo()p^eU%8gNbNAee1 z!Y7ky(7W|KbU!e`OxBbezvMFPc_KwZR?48eMmqksbfp7&vv68}4F0VwtV>AzLf+jv zNH&Zt1*J6%nPXT@rW-vYhqNwRd`+E5Mb}Azh_ft+tgeUCa@nM6SsxW6rL^;77Jiv3 zM#h|@G(T?ucYn>n$7PAw+;s|c%I-ma%vkn`-UV`_atuT*KLpaHZ(whG72tD+bC*jJP`;?i~fn-%mlQtOshm5FDb_t>(fzEs=Wpq|#%H)_ z=Sxdfp+dB^VJqrPilIiwu92kJTc~bS32L)Ou={tKlE{f=jK&5L5;Ne0-L3b@jebXX zq_-00B&vbN^C(a(TELljWE0K54)CM+0H}86gP*?(q*QpIOqM?lir{FRbSD=#WeIBD z35Q+hVo>V27=B*d1l!GS!7s&O5;x%?NWP4P`iDSMx((rO!B1$}D|D6b_QGbp3~WES zA5$w5(P^;+5m~dIaMeP6#(OL%PnuFEqE=>M^RtlL{HYCE<0;&;Iz&&Xv=OhIjUd^k zN~89jWP%bH8dc9*Sw)P*QKawiyin|PPoBC|p zI)4ED?)PB%FK4QIRg~Xz$bf(Fq5-GoB92fp;Qd48c(vJkxUnV&P)=QrH*MZ3oD(xK zK|~YPGPlBtJSnm)rhq=4B4iWelp!x|HY=CTLfr3s`t&6dbN?&c)-WUJTwDk(7wq9~ z+Zf0mJB>9sDaPqN`a<1Iqe;DYG)8&ep?Ak6Sq?Lwp=fO^JpS;Fhz*NCe?%gu@#7@1 zm0SY9|6Z<3^nE}JuBf0}|0(9;h#jz`wU{=GuexYZA4BS!4$?0n?pV5e4*vP{k%Sc< z#!cggxVeotAY!tYv2I&}> z9}ahJsPj{2$?>wQY|%M8jmea2qovPgVDUA5ED2r*CKHAjf2&gFgW)W+mD7arrIir= z%AN*J`%K;4*1~}%1K4*Y16S-)#kF7b@s#ZeP$_!EHS;S-u6;8s+d2j8gk2DALHIQ& z%dQH(N=h|~!CgTP?8cTr&AzY1$3coXADsZ7rWF(2Ra;2WCULO6IS5m(1i^SXOl(%( zrmrT9VAj2LA>$vkQPK5{h~{DBl5;pN{Fy~=#4bRI>))wGNDjpMA0@_T`{+HdP--?9 zOKg->uwS*FmYw;_iK;|WAx%ds%&ZvDq;TtT1&BzDU<3O%z>DV;;%c_S<+?V?^vTs3 z3>Z+Y;LD7Na~sjt86<_Dy&&P>NzP`@Vpx1UO7M_eWrEwUQTK{*u>QUxq;Ee*AFX>0 zJ!jIuc={K(_ot4${dJW7^$~+5Aro1plc&hZ)=tR2_!wHP4dAWB7PP-~mfTt>3D=Tz zcuPYacGO{Q*1ACOCbXRbDKlFVp>z!YPQOA{tmOY^kb4O9`%@P_O z{*ICPJ?eR9defJ%PSu z8_%~5F}Qm5GFPtJ(=g^7Ta>>TEcMizZi^p$b5 z@udx2X5^h`5&ASKLUM4Cz~UvC_*5D!yFBU7CJ_t_QNp`g+EAaHRu}ng9MLr~wk+B@ z9g6l`rT3)rAwtq!_}w+6{m)I|Y_%{C_WeWsbiNYt>$`EoV5DX0K%(WI(lrnz9S-(4 z_j77bCE?ysY~=2+UAs6&ZzGprU|1uHC1KyvdGa2{8QZ%@sKlLn)OnO!dR>XjzbRW-OdR}R4Z zmy4M}GhvTY-A;b?o~GYcir^&CT6!p02|FyK@ZLXvwDEEQH5*w7zP${3PHw`eW;gEW z*-PZEstY$1GM}qxFoKHR*O}DU;wxvMP4pmWFh} zkIH9u(PyoKQ$o$2eEK&T2ik3E;J_Oa{7=Za>&Kwznr%2jEg0Jxt?8^&L1?k!CQUCW zVj8cW<~k1CWR9%bNP?Fit;@BR0;jesoQ#UVM;Eeow?nq0<6}{{Gd_t#?R<;Lk=j^4 z(gihR`h~pD1h%{veK7&UJtZ8kJB#Dkr zA;}WIsAaK`WA2+p*$~{PSiW z?_(s~4YsN<+Jg#IdZZ4f&JL(+6gUKCEltcHbAKo-oj`0x*MsFO8z^^CrvV8HbhooA z4n5_WPbKOwN-n9cMN^8uG+aR<-bpYWTNg8jV#|r+;}EFcE(>PIQ;9=%0%%t)CTqVR z!s+he;Amt7=KjL`TVLoC$6Da1DtqJ}RNzYYd@N6u<%1T*g0A=l;BQ87jQ2u_h<1m< zZ~(iad2EN$N>;=#fVDIS^stwso-xm$s>P4|R}e>AD}~Ir_C0X+tsuXSw7{A}8)?mU zFS4n`1$M?Q<9bKl0I%E0u)Jp%#@%(pPuGQvoBAu-V%WrOJlX>NA?^_ECP#ZtU7)H4 z$DzC@m#j#7O1J)w#OU(<$WQKKxc+ozRQ)=PIrE18vdBiq@B=tz>S*3IO$}E!H!}Hu zk5kiDd7OCLhQ>dz#Uh&m8rk%oF*|&Vj2sNKluSELpIK?a7PC2AY`GI|_;G>m&GCW_ zaFF`y%*K5o;;^Z>1}rL`kX~mga#ThNUj9&mM^Ph5=VS}>fkbsW{;n>#ls_bE?N32q z`Bf@+c^*a&HPfE~EBLR|{rDr<&FI!U8TQ{1hqJ?)K(F`GU)}@6N7)$CE>z;Ih5zv3 zyAF(ydqg!)|D-xU1*TW-8fHZwCFN#I;kJk1xw=}0XP;@3pDD^X&fzp3-(Z37d~)%~ zM{{0t#bKN_QIGc@cYxon?aOZ!_J1Y4LKkmQ8Mtq9#DD6t_`u{GoEvi!?kEb5`_Le0 z-_bzhzHO%~zw4vZED;je7YQ>bye5B-=Aukh7`m(ZfroMwUEAG8n>L;&&i~yIdhID- zfBXR4KcE5rzc10US0enI$YHYa!?asGwu003D4W? zAW^?!h@77$(?1kWRH_$(;j|T`G1Ur=xaLq<;~K`!xtwutH$|B#cQ9yk9o5V=!5x~5 zNbbH)66HLNsuo8<&hajyezKJA+#!j@i~T^~RvCWg$T4QUauD;P3J#1o05Y=-p>5|N zxgp^RJXv8mxa%U36w9P$%C|_~_u7knl4f+PUq9K|+CbAxuhQl#68P|jD*CsDql~&P z=ARRp9C3g@rVP=^~emb)dZ91Cf~*0A@S4aIaL)aiVW*x!t|NI8t(( za6T2{gQ>@Hy2}Q#L9quOc;t`&+or(#TQ`;=b#GnDX_v=oqR8xgeGaf#*IKba^^QmI@Mmn`G(ULJv zAfs2=ap78kI>r_F*Kj6HG&==1ls-~THW#n^Ex<+NRd8gsAx_KtLTxYuVn)n>vI(iA zB2w6y?pO@nwiD?e-$d|U;sakT7LdDP#b_)p!aEC}L7BcMxSTu$m*bltYKA*bydjAa zUgh}ggT2thOW?tQ*Fn<^@gYj+_JK-F5Udn! zOif>2Aa>s}K;i&E$wprcd_2eqR%}RbE~N{5^XSXj9$0vP6Ds$P#qk$rvnRAwAmo_@ zdoOhZu0M1ddmp8d#-LVOKiEnK+oqtwKoGuV$Kyar4NMhg5{m~4aMtl9knC{*ZWh^r z>}|g~YXNn1{_ZODsd7Q(2I;zefqJmbs}G`AZ$-z!3GCCUv)GR*e z0EU3y>;DfRtF@DErmH1;uA!rhmZPW#=;aoB(*hbv+L?m-^Ev8|Kp3`SGOE0zU?4w!uR*&5=+m!J!JyQ9mrwd z#mF5_$1#mf@Me!T=wv3L*0RgspwrF0kF}y(C(VL|#1Xa{akzfL0GRB&2LHUL;ver1DEQ3ib5|0vmHKi794F_p} zQZyV1zC=IG{6^g~^oZC91I%kGCNsBvq5iir&~kecb}3B5t_U8N=Q^P2;Zro#VIqyK zjUsC=>cP$207z564DnT;$k>%50Y)mrm6x-CoxXx_Ay3G^z)>W1lO}w>5Q3-X4db4a zt6bvPo20d0;B~&TqeX7d$i=KF{2AeQdgC@(cxN%p`DKSg<2Xgu!A*n>9n}sGi^sA5 znldo(ND`bsWQX&Mk^J(#1QYg#k);<#!ly50aC_}ndT!bp*nU}&{1KrT7AHkTa>NTO}uQ7K=riJu>I^U8ZbJS_-_{26PGLTleiQ*j}yMP1O{aTwJ_pi zJ~qw^Bbh~NI66Y$fvucK)(yqL`^HExJl0P#t{xy6d)5iQ&XFKK-4%cP-XN+nL^wl5 z(aSTn?yajNjrbmAVf}DCWM4Z1D>543_F|1%Ys ztA3m0?ec=@sn=ma^Ido^CC>U>zeLa7e#l(!SHxdUzVv|hD%u@=mad%NPtLa{H6>2R7w$5LtbSxg4s2dC$D4>!M8%t6fbr^N+xw{vxod9c8KZcrMQS(Ezf$ z*FsC}Ckl@Hpv~ws(OfA`Qe+14RD`f|{bq-9vO>qGHxADioyRwpEo9)yKWd_BjE1QZ z7?WT~d^()Tbe#%v?B_N({9hzd{>l*scN+{eXTX|o*$^?52ft@}!)VV~ zut^Gs^~UNjcS=~P;c_r>x|hyz_XMtZQc<0U&{>_~olGrV1a{oNk*uu2ej?TI10ti3!;TGdxZCd( zDE9uMj*>Zafz1oder!uSU)fR#b#MCR)AX6hr-A_W2v}^IA>xnqJCSTxg|DQb$Ps zqAJ=hcoKU14cL~%R!(Y#Hu1Sq3a2IJP}km6xOL(*a1VYWY4$;n{5Ue~T1$Ubm7M zyDqNy&`lm^xzn}w=V)lWB+7PJqxpy&T9UUH`=`5M|F$EzLfU~(Ucz8sE>Ayf??d-n zuLS;XCjFMV1FM)AoZ)JMr49$U^k7r0*x-cYzt&+u)(~|KcEU8NL!>>_5nbUN-kbFa zH(JesraN2cfcFTTF|dcS{qZC=sFlpwTS4s~{AFezy+iwQm!qe}J+8+mo9N6=#T=_N zy3)aDU-oFStehE(B9f>4AvyL0C3!;bgo-#jPAFXqr5{Pp(Ut#bQ z9d5h052@&jL-DWTP%}#f26i1`wk2q>#be`y{!tebIH?I5oB^J^a3UR1-(gNq8N`IW zVg_U6nYEL~5L?9}dVkXre8|6}qb`Na{v%8eh zXIwJwTJv4V!W_hVyLHe`!2{bSJf~fIs%VXw0XYeP(PQ&1^>;0V(f2b1K932xS=>t2 zGYq*}FEBx-JSTNJ?Z_Ps$G($_I9X{8lvVDfi&ZUPPn$I8&40+WytJbEx%T9`&|7e4 z~zKM~CJ?{Y&Klb}HwK>eaTmH#6H zqwL}!i`oN6J)n;FM`MvZ9A7EIAHCZuuzNP5mu~=;X$ZZ$lP}OEa5kPeAx0Emq!7y+ zf=_YcIdbLdN~&F^O!ub>Zjrz&>Q#D@)_iX#4Xg7&vmp`cH(1e6I|ZL%4c7U#D?mfk zaY|N;TE1&7#g;B7x?r!5`?Z9xDv}y#mKMSEKGj7jo2A9Y-85B5D4z822y_ZM1zMMR>oI%14me zN3QTACx8}x9fjg~-t^tuqgdyf$b=5YSlsWKgLywH;R)D*)a5L6@bH1Vb53(dU#G%Q z>I10zc?N=Ro`Fx}L!ngQjBWdNooFv`0$+tW5Gefz+>91L#42ZY_U3n>oiH6H9r_Ae zrcGguCwYVA%a?Gl&V_1t7U1%rSP);^%ssf?k9_(r{9EKqQc~UV?DFY2fA=MBPBMdk z8DXv(VFMX~;uvOgo@zWgCvYuF=)^cPdLs~+!duUw=RpW7x;+`$>R-$Qt48Q38KPTr zBIt?NyGe=NZ1nh=j*;~$e30KDt{5-Ak7CgK%r0#HpLwV*YH5l$U=I!-jjQ9A(Qc%r^($iKFE->AF0T@ zUv%T845BP1g?d+yaF6{ZNN>PIa@dMz2G3rmlFAB*>wLi9F9CNs+(w!Ap16&;V0KC+ z+Bs~*EBR~D$T}GZzh%=w<2Z&K7dUGA+ql7J0Z1&yg5k0iAiwn-`7PZ;My&V4xY9>( z?RXtbzjc@E_9>#>i;mM{(^K)x_p2o2k2>AlG#Aaz8?zggrjfnZH_?>#PDs&yPCFX~ zm({AD&{5q-Bxe7iWn*R8p@I7_WPTrVg*L9TGA&2-tUbNqem| zt#^s1O6os}i){jQetm9vGS9E}*5xYVdN7YVD<+WYy$rFhGhmlJk0(*b-ZPJKl3{#> zJ9tJ`a(Y*spvkGy(%enx`y5#bV!}BVJYPk~Xr7`wP2-7^S{jLKpA525T)M&R4|YT@LyFR$v}?D&x`iJs41O8!LUS zaC%3&;KBXF+~1Im;XBgkyC6H%xTcG~_G2(dm^=Q8k3{2|9dtmfjuCEy&q;Or66?MP;bF^mC2namWT7{qt>aobfP`?eOES) zT{;RijpZ06ZCEardrUY0+Dyjz@e)n`OShu=x5sun9G^dTkUgMz4e2_-}!iU#oG-+w%v-B ztm?QpBop3Hq0$-OW(YhZD#QgBa$vTJes`4(ZSsaG4PYbc< z%2_O1E$}pYMnZS#Mp|rtm-s!1gX3|XpfAj?lDRNkdvh*1E8dFR9va}tcu_nCd0?kv zS{HJ%7>)+#0tC;eXA++QmB@!FY3WdKP8CFcFZv%v=iyJ~`^Ir(Rf;4Dxs(1jBc6?pEjnzb&H!^&7ARJj%>KC~@eT>M8}?6ct}+{t^&cC?#;PUSz`@v)d@ z$nS=&HXWbuuH~e@p>*__3OI&Y zq5u1X{J-!c{NkHRxM6iJ)oyG;pT!@byMG^M9U)>9{uQw$0^9G0hCP)W|H(y_y4;w|T@1TTuTuV!<^XLbyGaAM{XDbrlVvIHSE+1GI#qu8N~I+R zF;}3s{VNVr5pw)I!j^j>lW$>*OfL~=txICET_M#M@e-GwWMWy z6ns5d2H=$m7d-W0U#5tCdz((T{NCb!O_sRx%3;3iiXr*mI!B&rKqpNa@#Ta%I&JPn zS9hHe9GrJ?#L~qq(k1{(UU)K<(lD5FYYEsD-({jeV|KHxl;hM|aqIrsSbfa?Oq{CveDv1m@P_ z4<36BNb%QaPAB~X(?7Qp_3U$D*&0g<6HkX!eP7U7Str?fd@menkA#l@B(UK}fVjwd zJEEyG{y5?Z#`9v(*7`4-TOb2J>eX>*O)0mtIof{UsRs1zvz87djivPqLExvn$BJ8G zdj7MKId)9J`AtCUr+mY$&iB!nRia9H06SEbC3wJ{pyz!hjFy%{o5?OVH)j}4^zg+C zTB%I6L;#SVi4Z(@i8yB7aOno`FzMN(B&o%~Qpt)HQz(3^KHbi!=hJ6+va^TYiu^a+ z$4gFk=~&haG}*Ha3aoUvqobem$3+t6R5~4+NDOXkXVAgm4lZrLPB!W;k7L(OX9NEY zB=-@yg6E3IIg=l9{cT&Q%{l}prO#u^@0-!aE0E@`Dj@GohcE=k2$^1Gim2N_T2>j< zAnXOwKP?o;xqSd-)0yH4fxRqVI8*KArm?NIDpG#d5lWO7Iu9YAnDzIOaP(dgtS%h~ zeDgv$KJ_M4lvL89S1p7(#jMbc_-Flw!iFnj$>z^-`k1tvMmQ4b8vlU}9!ua@wcrTN zPn8%P)}?MgSMn+lGK6yP*+Pfwm~Fd~_IaPD=(=_6XJ;ofKC8=}PZ~fI>u!*H>ub8z z+(2VnB+NhVHP&$3P-n&^O!}=0rkAzYF(-4#(o6%3M1duI^ftZyL{u0E%+$w{R!Oa> z?3J+7Iy`~YUXQ1F{%g?tbS?IozXk_om9R;3o^oqvWWzJ3VaV00a>q{BvX!HQz+nNf zT~FFrwBkwjQg9HqCLW;wDu#-*)%uglvthK)OM=%M=TpW8vc)HSwF7 zhLk&SKRY;b7m1dRq?j4$WUOK;eXsZvl^2eqThFgza@RDvt=EmOHF{8#IS=$MtDsh9 z3a7Wrp1EBdhbk-bsq?%&TwAXIsfBrL#T^k0etHsC2J{gxe7P5oj~>Zw`I?7ICB@8e zjWwMu+bJ-Eo0*sScJBFx%`Ah@rKjsJ61P@^raF!0O`=|7_Wmc#ZgnQO%smNjKJxHK z$jR*WRzUBnJbcS569yUM$E(k9UvL6cF3Er`@6uuOr4A+^zYL=tCQ-|q6>Q7=#i-a` zEHL+TDadRx9`E~_L|;d;<2T#cnRCiub9)=L1{~q*^cRxB$hGjua0iPO`l;JYjLq4%mPH8pOxe zQhD7~;=YH{zenRxb;dv{-tvKL^*>3jxjw^;yd^ag=NGY$4Xs!z@NUDh#^Bi6_4Ii8 zA-pI2oT;}`@mHZ34&ryv(6K!Gb&&+JA1-6|8wR7nCJn5f=_qO$u0zff^4W+bqnYDd zJ+9pB3@ysoh2I7k(&uy4#Oq5D9dGhiAAQE#O`78FG#|0z!eDV}_f0&J z11Ljt7m?7Z{B_w)s`u4XdOP|YX>V<1SH=tPv6p{xJFkXQs6jd^zu(Cgv{f>x;IAwG zl!DsL!K}XQCs+S#Bk^}{;`xyp=y$UaPyEe+Cn4ETIN=cGT^fw3R*NY^8ialB9Ou7f zDiMEEiu=8f)7t4g4V<%$vhDY=EA<1Zd50Xto;T;Gq;>G0wtmMT#bTz%@#t9F56b;( z;QcyvmXNoCl3EwxsNd%J-YA2TYJza=A644qhjemh1Yf>w58N-k$U34Bqqm-A*Suob ztJq=Wy6ZmHE*wmsw|EMf^{=Sb=mjI(PoeXj7&7+>r8Mu&j2xcevheL~)JgnMWX!A;6P_nu~G_{c8M#n*$d>ZO{ z#!|QcC6=w1j_EOO^zy|X=2|Ri!(KpwhB&R zW9Fqk1LJ-7QQ*HFcyh}&=vk1BR$hzg#(y!`eea9VdDJK4ORb#gU{&$NLw%|C^DNG9 z8gZ)6WOz57$E?Y(iG|y!!0qQ|;BxUGH!5rZt$gK%c?Eha)o2$Ft->_tt-WE`N}Nv zj?jOXKgdKz9iryMl{7E^EA~1X0po<(*!DW+)8hm2TlR6w&flWGHbJ1UVIai#C<<{w zFGyF>gg3|cqgKW{SXI>lt2AaZbMJZ3RA>Q{_#Ad2w;l9OpJcTelVJLM!g(`yxK?f*9Qb44$?D8t0Y6!Lu54;a?J%q}>H$)jjyiNdffp7va>|8zI=y zh2tYNDdJcP`~Ad;%Hl_}RhNZM(T{ulj`S<+_UI7s>zvD6(xX^B|C}E<>LL4RKODDh zU5zUvdH9 z$3^PV$(*;IA^ixyfOi7tW6s-y_%%G0jSqW*hGpYf!=(d!#cNrKr|D8i`8AU!WcMY9 z4W($Atk1uk?t|7E9lTdzG5=xP6Mm+TCOdulEVj$XiqwX5v87}0vQ2y9IL~*AZ1wn= zY}x})xRw2orGEGz>UENVlN(JiC-)$VI+jy!oi&+6+{Y&t`}uW+We{n)449B{f4o}- zQdSKh^&WqEGVCcbVXn7U$b6I+?`1N*qbS}j0{^IIFpH1&^k6|Y_5RGk@UH{#dRi`< z^}t!AEtVza%n`KH*GUp&)ytpyZ9vZD2k7+uja2+7k}hTMCc0nBZ@r&Q`y%#mGqNA@ zi~B4PJ|mf>znIHX9gktSM;pW6D{#BUIgxF;28>W!44%)DXxQS1Y_IVLSe=o|t#j@R zubs7FOyUT^5mdz7j>M7L1q*5(Xb$IX-t$M#Aae7*vVhC+Y(NA@YU31e!#WF;k6uoN z3J&yf>1uxct_A#+`MT5=(v9j?A5hYf%65;N2?p!lQE;0riL-;TB2b?0&Ynk0);ZAG zZZQSWcCyhwL!pBOMz-O9{FXIhXlcyHL0cwJ-&$>$($b%nb@O~lRR*~|+d_V)BiU)I zJQ|u@MDcbKHacw^Et4H5Jjypg--2i87OOyRI`I%TZ40NJSWNRALm|e>nYPtmrnw)j z$RH$>-fh$;lNWDsp=@6&UY>y411(s8*>%EMJ(+dr9%Bae{=CCQ;a%Zj4%1qt0WYrV zuy?aWpe10VVoFqDiCPp@7d3GIbVoBK?1Kec-mt~T%J}?Ahb4at6q)by(`@pNINZA8 zGwL%Azc~BR-#cRZPaMOvWk%7}&YifkL5A6x*iaJAp*g7;(E$w za~IHH>Oq-@$d=^E;-6hKHdRmX61s@Nm=QOMdvur;!S_YA+~C7^Sgi9i=5INadS}|Qaj(`wLr#{c z?#@W68r9B;C%aHr*F>yPs<+?PP{Ss8bm5YBW%$L;795|q3;nunqRg~F4EOwr6CavF za`RgjQ58(BcDpHZ|7ZyA69UO$Y4EmN$fm^(B)zGFL9f>xhYOs`tM_&?^*`#sD|fL) z*`0K`6=3?b%WS}bOLXPh0r0%k#vjx{7^ccIbNdj=rgnUeUrUNP=;gs$3e1cKTtjYhGnn2z)zp|ir?b=oa?zao;Cz) zK#;}=c5uFpRQ`Mf$f}qyLvA81SZDzW{yI2GFCAP5Ph@*)yqNWaeaz;77X@d}fLDFH zaP_J@ZuEU^w$Eh*Y*dJlyfPK?o-&8vU(+z|W)A~@Q5@9IH6dfGMs~tBRs4A+vYf>R zf+w;7+8zZ$>8UE*QJ*LFK30ULzxuOVzl#u9*#g^FZY*34RTX1UJZQ{Z1pB=Q zi>J74gf@K#xaR&EKAG#o{+p`QlrMBm)xx0h;a|);T8aT5^PuaNqDb#y19hyK4MSGX z5w-Tn&=~h*Hmuf+E-&g!WB)tFntz9*v%o-ToPCF0!yfveKAq+bUPl+6I&fV3S^PS1 zoV4)2fs|vu6E__GfQly)n7{UT7-+6bb4=3Ej;muub5odK;8Ye}Jp?N3^Cb=k#z3Uw z7BF~YiI-OP@F_bcfOc1x;HVl3rGDnrRIm=^_xK8Vt$#FPik4`1;zjPhb`Fj2G>1Sp z6L#g?J1p~UWZ#wz1If=gIv*hq!By_?O0$3~pRxsH+L3KNn2NgsBB{Z#LS(zshE_`I zaF0}rYxU{uCWA{B^5bYLsYzc8fO^4cbBNEEk=Y$V*RHAD}4?1=y9u5w+UDFPj1qCw=F}d^!YI4Oa1K zr>gN@?LR(RVj$fSP9$x3%e+jKgxS5|mmVhUBCo#3U6m4idc=@cPdiD<;s3$?u)h38 zLlk^s zfGguET|b7YKF?$;3i?8FeibTh5cC)A^BY^wVnRM5MKZd21C zc9|bD+mXOU-`j=7!vm;U#~P(G#?!8YnPjjf8^3sOqMPR|rQTy(Aqczi@VVDuG}Z(b zPH5xB+G?=!$jDQG36Obvhh3R|}`zdtVGCn54r_Hq_ULz-+f2jg; z9*6KNw>U$2wJ$%YyMoD0Qf8Y%1^b7CJ?To~Z<(hs zCdw0rt}z!_@v*$H)kOUzBbnyc6Ld*Ui~BmB1FiGQP}N{Axou)3zSC|F8OG|cNN+K; zZI1;7A#>m2Y0J!uRpE?<5kyb=2+Iscz!33qz6)+~(;EpDk0y}%#$?Voa|uoBo5c41 z+rfs1O(2n+DP_C~WtL0!kx5H2e!8|FNB-G>77lF^&!!P#|ehfW;tC<%vZhe}X%OGeLN z8PIAP30+lYa5nJ-Co^xI$WC=6?Z4Lu0Ud?h$eKs=D_RWI#~b*Ovea-ly_TCrmTiaePJb8HvhFg3ZONv;&z&LX zRuQnCX4)FIm$|E1iY@UD9~`rlwPzNyhv9qqF{K*pv85F)uX3UMo=`g7_LAyty;#({ zOtjQL!`3c1g&Ak^SgL^`o{y|xnIS4nEk>Rj_e}wE-{-RKd^u_~mg7}QRxq=Ui#RFa z7)AzM#tXSwutN6?jeJ={OgftTJ~@R#Iv!En&2h9Oyp*i^-lF4;1I2~cW0-pEPBui~ z^S=2$on2LWhuKeeQ{cXBFyP%5)~#30uFIsdo5S~EK<9GS|7!xOa@FWFDHfH4dF=40 zr%d#*7<*y|(S)D-L}L%P&@!uk7;$6)B@0TJaxY|-+d0(ls;6&a!Qvevsf! zE1GRuAvxx21NF(S@L8vg`HZ>7<%k`iL?MAvg8ZdLZRaph?eeP9RkzC%-~r#SNO zN&IpkmR{@ZgzQCY@I^)ym*4)Ly#bGJB4Sfmp!b~$zra1-e6>uGKCjeldjf{X%66<2 zm$M%M5nwX<8=7V5;9I*`cB5r9e4DKV3#;NWZ}ML3$QJX-4HvjKq5Wv@v_tH>xfry& zorJlP4Xa|fa98?q{Gu_PKgrpWd#8%D;Hn|~6&U|vuQPGU+X6hI zHiND2h=ontf3dfIyTPAvuzcH5EE5IepB)1z_2dd z1vn^mW8Xe?GrQY|(YvUhL^=1l=<tuyJ)PA_PdQJ;J@$8O(vGJvGD`>1O36VMU5Xm&k%c~65y54b6dG$ zF|-y`W8Zh+@;p;!MOc&T4!{%WzDYuq1n+2Tl-`pl5eXlYdxW#rk|I=B+|%*(Ik(tRq^NTd1}GTNetPeHC{$(^i+iCu71* z@te#ROy7-_a#B9gd^+0s{Y7h+m$>uGBy#U_8eK|wbXJ^7dgtN=x7Knv@?rp8uolsW z_%OlqRmC<7`-x?Ko?LlTHFs#xBX-H|7khM|48zKWvufU2p-ZO%VqIS@C2Sm3`j)d% zm+d4~3brg<`jquanTMy+RA})0*>pE$kgzlDf!uy?aYmdb`OdgN4O`aJsNM*2HF>}) zLu9Cxb4G*IFIXiA$sTNcg2PV)a7S&Y(7JLX9Qq}kKN~*_0uSus4HBoogf@GUxmH5` z-;4Rj1CHRBUUfS8;vs7~uEH*#vZeOY9?|0W)9~D?YW#JifjhWm0^4|d5-jh>v%hPS zc*W7B{7I|PY;R;S?_jo_JZHs_M(#rPs_7zcGxDvSlVG!@JjBP{ zV=HDXB(K`}f@9Q!$!qp!dtX)HHC-z&l7}3b(+LTdgCAr*C0*Mc^AtL-R z^ZM$D0b9c8cUdW}y>$t1{WYYAGZo2JvJf>|p5ltfAJKKkP&)Ed*h@QaV%KL0GkMKu z)K+h#8wKkPsk+5{DFYME1OA=MZu%p2XAmU*L#8eGr&i$)6TkjC)QS;`qf4pLO z`-@rGpd@Az`H?Nx*~LEmn?lwOUfgTf!PFf(fC?;SVB0}WHkAi<`85;yJiQ0Ej&(p? zMGIs#?X3Q_aULoyxF+g3CJRq)=|I2fLqKEaOLjE;FUNW6pnh|7&5{do?5%hTTeQrQ zKRKVHOsg&YrO+x2V{Pcu<%^hYg}aXV@{gup<1|LyW#JD0VK4s}2jOnX>D_jq_;rsc zvo@Q_nEk=ozmBn|b|p-2F7Qp953K*M9`4@W4lSl;;2|e?bk6n#PT*q1nrp#74OMo| zr5}u2tpSruH88>98Qby42nOBMf~$D|u9Z8W?m`@V>pu;?{On<>Lq~E8-H6##52Bv4 zy3)Q{L&@eqJSy*$ftk_%;>PjBCJz5tv)j|M=E1G;OnqeveMve)X`@#N`@(EWd1*~e zcZ%5k^vCR0?JbO25k;EvGTe1#d$fz{LDee3TYBd?d9FH$<0@mhKZ}-Oz|*;$@^3Y^ zrjIT3TFv8&4mC)kf?}9OUJbrgA3~S@?ZSt)t$29*WBeYoAI}HQ!HCz7`5TS?_#sU= z4?dh`;>E^rXU<4cue?S}RTJs8k8rnfF+tW9i|?)P;ONOCBvHZF*~Jm5%ua0(Pj6F1 zr!VX$Qxzw2)Y-@ESDs~dH)hiK2Np0SVGqhq)Tb+w5S$uo2X#6spfuHp9Wm=*UJHi7 zTIE$Jdh5iQOf$y*&gYm+Y9zOKhAsayKb!4*Gl{*_PhhRXwBUA=D>%p=hH)Wwq~EAc z4`u7vX2F^A*XRp+c^k1QS6yM+7lGOF@*r>S{)^9W(u07?IWTUjC#)%wC6~GhP|3<5 zSk8p)s|#UuI~u7up&xTlnu)br2GQv-17U`r27l!az!BF0cVPi};q38=Q3fV2Ebdbl$aR|Q?7?%fhH+%ke3lt-{b0aNI8|4hDX zo-=ft4Fyq|0*t%243kWRdC%}y5iecH%%PP*tR=O@eQAM;Lyx z=?8HNiV&o|4lhOald6x{%e_!gfOM^mw8sB8wSOfVnd(asG=l175AgDPk3iCoa(b~R zj;!mMYrVfecu*x1nu!!yQ9d%|R-@eVfFJkU<68a<1`Di(pgg$4Oq59RGg#WKgb zT`uyn>6xM3vK%CBjwXyP*|bR^>}7Vb}8;?qL%yvXUGe6rpXvLiDO9jqMykAUCp9L?umLB! z*o@C!6xFLJcAC~-ymfjW8X;omp7 zJ98jBIKCbZtDB1-xi>*OKNQbbrg1&8llOq$ z)T1C1R)9~m1?P-+Jv4^dNDGH|e-R&J=||tv*23vgvaqKtjlO?SVg)x!S>7ZeqaJ*g!UdLXtzI403syB4~3xQqXFT12*n#T4``8P)1;(ayXb@IvkyE9`j$--o|~ z&`ZDIXNEIZ{k$E`hxbrud9oNTG{ZC3!?5TQh+RIdXBD@vu$s02@$;$`LT@V+hR-mT zzF(Rv-BLVNdLs26-FJ49ieou&H0r~$p3RmT#xRnLQPd47k*it55GG4 ziAz>Yrym1%k#zGWTzs&VHMtz8VNHkGp3V_WsQ{Suq1%v@z(bJrO)wR`fMwS!M=&!D(RA4-HX^3oF{aeMR{wn_ROJl3m< z^~;GZ@|rB3^r4C>uNg_B%1ot;hKJLZS66x8#u#|FLxQK244_}42b5+V!q7$ObnxUg z2s$F%H6JTUhkQ>VE$vYdtCLHK_OGC`-3WR&7vNQ24RMZP6W27vk16?Bi-%hnQTdui zdKh^X`s-Lp%NwHD-aj#*6#0%S&`Qkj*AkDP_=oNqIEm#}ZV~_IIh>vaEFe84HEFc+ zE85k-!GyR3Ht#_n>BF}kl(S|cbzEZ7Rp^s`rqCU0< z{xHqb5{j9v4X)vt^wjwt{b+Eb3LhP@bb11Wyk7;QTKkE&6gz?PtaD_eH3M7}_TtGS z6Qy60ZN=yQ?Gam_h@kmXhKaZSuowGX7$sHw?+;h;&d z_{&gDTNGP`_j*G}h@S&zzsgFp_ZgAZ(s#6`={EiPr9#RvngTB_R_fpVk9tk^u#w^+ z&dR!t)+w2O-o%>-(RX!RC-TH;A9)n4~yfpXa0qS!&M*QX50BL*&Pwi)3 zvETm&NIkqip=V4dvtIiLK5z>mZRcpQw2wErbP6sbc?p~Ia)|Wvg)CgUIT#kz+{IJ# zMoJ@F^1%K30!moXS85Sg2z8w%ls{5gYBfj%V4#i0A?N6V<~tgZH5BgIHPSV$D>TVU zUivxNUh03hlxEMil*Xw{lbUAU0#AQCDQp-`Pckzg%}kGO7Rib`4;&XC3+SS)um7Rv zJ9qdwXfbX0aSUhCPX7I5Z)xiEA=2EIe&{Rb2cHf((6G=g^mEU9Ua_c#(=+vl_iO6d z+iil1{+JB#0O2*T5Hp1N_2yQh2*bR&4Z2 z4RVv&z1)R?BVdc%Mf0_T>{c&<64P5Et>wcm1UQ@ALoFR%Xv`TotWivM{dA z0a)?^&NulV?;D&6y5~l+ChyBIR3saLXc$!G}is*+WqdpVZSXf+jAH=#m^BRJz5}sp*u!=YUW#=ik=U5&LfX0M&CZ6a9%f2{?`YNj<-)08d zihbChr`Or{)>L-8dk+Q)dwEq`ecshtp1m70l#*L^p>kLTByJYw^Gp1B%WDJSzm4N? z%i{UWc(x5%%u;~0)e@Y$qJg>woq$KSJ?KLjq|$Q+P;dlpaqYssyBlcvrUqg6JRFbN z>yuuj7C9z2vFU%T@uTfI+;!3v#tcdbze+g@& z-C(4-DpSCFOx!C=8%L`NehzOoB2Jd%v#pAVmwi*oj}>8ee1-F_VWDb9ifhX(rn_5~_l9l+AXs(k06 z5OAwH$GnzEF>TF3SZB0|*HMvDcZw4j+jVkfzGtaw!eRKN(w|P8ViX>f2A2n zKQJnjm9E)|{epa%)htWCZ+Z-Tnri~pue;eWfk8c|;s(ETh$B65(7-vDn^@3VO-h(C z2=>nW#;+V)!`B|KfGU+E*id$h%Lp$MX6E;BdB|-3On+^A&3z)8RQVnCc8nrl9b3uA z)^OqMm`FAI2ycb6n=FVd@91cRQ8{RbpDSR^m-vLuK9JBPCVXCd-mB=#>Eo! z+wz@`XE$c*Fuy|#bh{En2|j{D zbpf9|zbt@lkvwknogEZ{g2-?ws}e>lkpvlOHbJ=Ue_>#FfuWFk1gTXEo~> zW(!rt{Gpn(bh`O3S`??FaX{ms=;UL&|^9Xp{RK)NAZAuEbDfudMj2|{Ai|aT#jpet-<4A$M_ENo= zYWAhW^E-8{&Uq+i!yyQpuMB54xe0&!M$Y1fEq>f)!#m44!1qhZ>~oMAzL>rphRxat zse1}h^#})-78kI%4|OQt*@U)>17N1bIyfCNi|^3TVS6IZ@>j=-AYA_kEYLj-5zhud z{{@xILo@?L@%tF0?O;pTcD$dc0&g-D?M#d{C}5`0oO9mWUvxBesGhFJ=o zZ?;GKMXvBW)Q2Y7YSSFFV1eq4PuiM6YME_l+B+Hc_PH;3&otTALPywjJsu{gP2>M$ z=m;6$0kFS!7)>oLru4-EBl(jPb#3yeVKIM^jarE6C3c_`um+VXYD5OxFS4rqFmC53 z7yK+_5?B28WVV8<>xGY!bbS3NwlXM!d;&`;(zlbs*dv<1Ig@sO-9^V%C1RfqzHqS5 zLRR!SjTIb9Vmqf#=2v`V=x85};(K$rgz6}PXZsqH$`gcuvfxyWGNK@5Rq00)U#f0) z5}1A0DCOC3nl6f@%`+|&+)HO41EZ+pQ9gP49p`M$yyM#scf!G{z0hA7*nc0Y;cj^k zTbU(8q93iyJ0uZ9=gZ)yG$WV|Lbku=WjPg(-Z5@)cazQ=)KHtO6gmGr(U1otMXUU37aOSJ1vo|+%OKy4+rCg z-`n_tZ&jkvYZNHz!3bQD^a(@cwE2efmHgtE6iTzKCe<_}Mw8y~Iu1i{_|@_FdP*)c zmltM%zN6{5*$`?7{tShcr)cJIWtxc_j;8u48!9uaNAL6XEiP=Pcv) zVk#{0$H2gHCNo@}z8fX7Q?_?Od+scFW~eWnTzD1?3-5B?rrJ`2v##*?+ISYSc{@EB zFpEF&d;pEgtpdF$9he}>;wpFLv#$m+us-Ms)hCtGhi6LcK+i=so%aFv5r}UJQ zIhI`7);zXLZx^>dVK-mZFO-JL&ZX>cyyW3LCo(_0jNA+D=$M@ixd*$T&*=)*CG<*i zlgA4FY#CCl-UIKwMnQAhYxLic1B&nUp!V)S9INWXO}XxcTr^`-3mhQg;#>YicNz-j zWUz^G=CbZQzr|5gc+YpNF6?|%4WZfi8q8p)0*w=t6_U=_SZ#--&{H}MVTu;P1w*4W@d^k-|9M8&@h?$m<-_>m# z!uOo}%KfxeC&e8uq!W|LZfL#X%5Iv_mTnce+K@oocV~Vn>MRc)R70oU> z(=fL~6yogx-{$vFo9}Uo50MC7;TCdMokxAWYcND`e-Houg8W{ISnb9kQolFV)Gqsv zZG0+Ec0wm4_Fp_L-|!Kqggjv`Z^o1V`5^QQuVS(ZDy%(GN$O*?ol5(EghO9`l6q!7 z2{urGy>Zm6couG5`U;1w&4t``H~gCZ4*ia)Qo8IBP%v67`MoTb+}@5N%Sxna&s5n` zukrZvY6DK+KZPG}*~@-CQ-weCzk|}~1?bkYfgWp*1M2RycPG)czcw_kK#pc-?B{0+!~Ez?^6aO7f8nur6CF3q zhI*GK%sMAR!>Au<@TG%A?uddzBNy`TTL+M@aXfohY{>i)meB3N0t2W<3%>0Nf&`Vb zXwb(JWjd14)^$Gn?3=>(^FG8zzMKZSa)Y@ZO<{gDelNtSKVrp$6hW)(Dw^u%vG*wp zsdZ%~8*?%ZrW}c-6va+_=>C;`JO7tH-CRXCN_+WHm5!3CQ3|*%{yKYfa0A_aosNAo zv|+%UIHvm}A1CZLq<1Q zoVuM|7}|sqRS%3aj7OK75kl@dj|QAw0OeaxNmlFcq@?UBHsH_@-Z@GG!d>RWV4Im# zoSw%fxS7I4hixz;BA@#MwgNMntJqSA#P&5=u(`Q3>^y}Q`FqzamN z{TODvDC5c%=RznS&d>d(PvhLyP`yt+s=m^IryJ`;8>d=Qt;|05wr3Mt?>GZ07ORr> zq>HSt*=NzTJJIY^%wWj4Ex27Y448cIIX>Y(L-f-!<2#K^Y4u=vD&Bn#x6htJW!pvM zArV1ZP$akHxCMJsJD%xPoDsT$@44;e@AN<- z6N(l_a&YbPVYX<|ZA?ha!UrFBz=KFRxYaHTSLREYBW%WKGbtC=+K+B_9A?~}7Ea^K zLwwuui8&>oVX|)9U`pZ&_Q;SVvK7PB{DX}_aVFUcubOcMmzdHQBHtY@93H-}) z*jgw2U)o(|+gAy>kShzop}#epG!j8W?i%d+?Tv5!`eBT~CHGd0=G)^+SbX7KJhFcl zjX#DLq85*#W!Z~P#G zdwBh&ES*|7815_Yq?_|z&=0#j@{4#y=j?%G@8756$`45=Z6|t6H^li<_p`YWM5pU6 z;+kYbYWrpmQ5ip3FTKETa`~`&T`uUnY9oW@5l~vk!OP9cw7P8~SzYZ$rRW0oZIcUb zUu8yHTKAx1zbk0FZ$BxhXp5@;nA59m2~ms!~0cl@JoE|mLL0ah&B zz{-9cqBhHPY+ahc-S2#sMn<pW1Wq z_tOG2NlC)!DGu!7_p?}kWe4pQ@~(zgo$y@kL~>nUk6HRWGyfJ3@=-x7wK<74$Lo`G ztAw5WQiQ&)U+IG5LSm1%V)Xt5x{zf-SCl3&yMel7{!tE&`Eg(>oNJY-b7+6wQJgow z0k3DDAfHTM8nO2%DJNf}bE_|4vxOcQ_6(wgK^`>BRYsguQ9-7q!=xVre?ZNzoA@^G z0vY_-z)zT90RC^z;`5Adn6`2nY%L4n_u7BJgfoX>#^eh2sxX;;rp2)TE~G(z?G^m2 z9Em-$K#n5{X?+9dq@u5MMlz1G*3IaI#$%@Xh%E?{r2NLLNdvh5o z|Cj;GJaYKFBa_)%Wp!~z<91Mco5Skmhd@e#kOjyv#p`;%VDPj>?A1sGsL0fZPadQA z=)X^xamXmVEy)$Qhx3{LL3`M>v4y*`={B8XHD2!C0x9s93U>Bm&J%oLEqaE)#iO~Dtb1oeY=B(29(U_K{;`-8_Kmm4hkTq*QjPrPBx(;st3dQXV1&z8kuo8y?y z?mpr-KeE`}wG-iJtf}~d?NYF^jpF3fG(oQIgU|yGtUe$7mA~xYMfYM>P~AL%LHMhM z^OjSjN{^fP^mqn7x-VprJOp=)S#izIj9YBMKp$?{XJe>O?}hm%1TTAe4-J33jP9%q zmfruG#^sc{*bnd$gG_AY_BZ^JIFJnKm`Cfs)b^8iD>K`ofxGt{Vd>QX2 zq_Bfa8)5b{YpNQuik$1VgXZ-s81c)9`sT+%)m~qIOnfz3EL{ituG_PcK^nBw#zpX@ zWw0Wjo#a}=i7aZfL_hi^(DSer@U}Bda&KP?b_(vKeou1PX&WW5uKvRktYU;a=t;q4 zc@$oT$icAkD%kz^2%BpCjh*x^V*iG^usdq^Sw~VO+vxL~RzKcI$IH#AU2rl?3s;~F ztL->A=oMO)>QQ#P6kl%lBzdy}9J5XnL~gRMu{IO0Z@A7JY8IgL%U103>JY2j+lrQt zR#L@>2Xr=6coXv+PeX?nlX2*Ke(M1%lG76Wrn^k==J2s(T)ds}p0X6Q`rfN>7ttJmERhj0}N#t5dAIBbnR&Oo7iU8^A8*7(mW*4|ZO5BOII`%Fi=N z$Mfm-z5+}s(Sw(lor$uC(;o9{y!6;*>@%Z389gfHzuc82 zOZ#SAHn4%&D&){ri@*3XbPK;n?83T>)aa8v;;okkGvE z&Z|LQ$9X)cBjt63zN4kdcKp0Ta6atW2xe}dxsWZ#IsFHhaIIkupBA$M&+eVVIK!E& zD9Ii)bF}dL5=WN2Xbf~0U*rACCo-p9qrei^QsLP<{BtN`sat1K&I)%-$`}moUw>lN z-4=HB$5S@+W;*HS4CI2x4}dp+1>Tgk5}n%X2JdE##zWB_Sjwi*jK{C}Biugvn~*~T zogXtd%N3L>@u97wS3=0P%^(uyi8k#n(0=hOo8vCb5l8)nrOT#4+QO5TyfczSnX@c%&?MIMBbhB9vWwrntS@#&nPAlIT@uHZeSD6l0uGv!DOsX&iaY8h z0~dDovS}s`Y{~w`^xu#cZdr*66op^GgGX!mO)a}|g~*JiG{w-+bD!|(JyW!F zeiRi2UUu8ddF1t6co*KkfZulT2&$|xq&mTGr?_65lUzu}*N4iutKU=Ers0v?l;=O$ z!iDEKou`JF>pX`Y@n~XMSE^w0gL+P8{x9y$d^vddT$R){Mv`^C0o|Xzni*c{4oYs)HHZc{$FdJ|zHpMRU(9jxE%s*IBGegdM!~6L zQA?76Z(IN3Y6UHRIxphSopY!CrcwMj%cFQ#LFgSltmS(jWn-vZe|#1G9DCOZ?Ciz9 z5WHn7WZPxo%Zb~;ai$zRb~l4Z@8oGjaT4Dhcmm_`}IF;e&@$7n=tqvMQ8p`)z^k$QN~J$h@uQpBt-1>Y>5U9 z)VGqMQZ&+xQW|8)Od*6qD#}nua?W~|N&}TcaJ)VT2(dy&z>4>#h(b!IJ#4Qu4xQ)QV znz6XGVh#9~M?;q>4`hi;TeD301d8lhy$h}R8p_-v_WPI&rvcUeBkc*BHyJx)P zHV-qwGv7LCXtF-7G+&R$l!u{VjRaX(KLmShhhXJ&4n6ezv8MVpcQWuWaSC#W4R%Jb zYv~W7ce@(K^;(1G@;&76`segnlpL;a^T2EQ9LCAnqxKYKH12DoE4CiSOOMx}^skZp zys1Wz6n;~@-*pIo>cAZE_ME`&_q+zp%U6*Bsmq+lIF9QqccHItn}bnC0OSN$a_bMN zLe85TRC~N7y>a#;IsMuJl7~w|cWoSs{k#DF~hYZkbN=+#AVRxRTo98eGs)xL$GoEQCejYK(-&%C1WlguZ&-` zi{x%teffOpC%R{6mUz6?f1scpMC1x~lPA~SliBHvta}hjy;t254JbR4gr6CtaOEa4 z@-={)(EE_M9#0?k+L1;{FPi^O7YD@vd0vxF&PMb2xJEc%zE#7Gn0){Pa?sm#n4~Rs z;T+h&iGOInrQsFE}&*>y(-?K<) z5^@J#mXQsb`Q&`tDN=K01huX>OlljKQJEw~u&5IXkFU~cgx*@19Na>NpOO&Qc1}dU z9U%g{;uGy3>w{q@La6u0{q&J$30`%qrS_?3>HCW(X=bqx)mpiftN5{={1kFd-a@8b zfAv@K2ghhSZ}ALB)=lRW4d&z4!T({S;5_-4dxK8BDoNKa4~LDWess*~jimarr8wsC z8~RP)#XUPdUg&P+h+XF$5l22bj^_J5(DZF<#Vfr}qUHQ3e9+{F$p(LD)fYRojclQ{ zqJ8LKn}ByNZ^h~nzv+f+yUFp3PULMt6v=#{2SW1@9=g5a=DjF}61!dS`oBkHV9q3b zvpW||)kcUX^+e#p)t)dkY8g(P8-ZMAEwPlCgqL?CezY}3r(Qkih^j>X;|cWm9EH!K z$FjhZby%MsBg&vt!NJ21S~ZH%ce@OZ4JIISyaIQQP9{3DM}y=_J=|#ffqGh*(c1m? zI8QU2L!91%_k;;}*D zm_F>F&0Fn29M*pjw+gP((q)dAYZQd_gNNfKVYV4C`GgCGE~oZIO89(e2$^1zjXT{k z@bJe4Hd69s_$;pyU(c(-AJGe_{<#98Nw2|b!(O5$6A7Qo_CuV)aZ$qSUDW3JO*r)5 z2DojyjLdAGMf9JKf||T%wBO2!?3tKF`gBz>(0e-^&I&<$(-&fk)f_%f3luyum1I$y zmf#W+bIp@1X~#T0xYY6nPS<5Z%JeX}_hApGu7uUqZkyM2B0AD@3Rnak1($~}t@TzGiG51F z;lKZu!hwfE7t=Nz3#1*`rCtsEb1aN}ZC`@#kGkWofOAB3fhO3U*(<(YC5^+!IN{kl zHDu?Up?Fk&fczV41y4g(!*b&=(E6#sl)TT-hGR>JUE*NoCN>e6EJZj!q#ma$U%|%l z2eI2X8ER@%sL`P$I&a!>n@5{%>8GjLXcRR9zU|b7b%)mDilau57(WE~H?|Ngyf+4o zS&bU|rb5`(m)19Kug46RD!Qe91>mWFLU*-AG$+~>+D`crRqaVcEEfj43uDMd16i`_ zqi{cYWFfT3$B^4|lptqs6tO4TP?&HX(n_a;X!Ct&5KHoQQygGIya$f>835}V){rIx zRd!*)OE{UMDNbyP!nUE%K9%`m&sR%LCW=`0R3rTweLPH|J?%%ywb_CIT_f&CzNa0@{ao9XX;7Zy#obVB;4BUnLh_a@Dt#lL#3osw;m3LS@lZLp z_nkJFMO_z%>Jr#5L15Ruy<+8QE_gbK$6U4#AB^~qm>rF$LcxOjH2NG(U4N5i-`IjH zR_WkoDL3)z>N3;~h$k8*+wqritXOe_6Qus<3j={0;gnA-_%vLg4Qm$D@zp-!so!pr zWg|8b)53WqU|u%~af%@Mw^GUCy-&n`o_kPZfh)OhvzmGr%V7Qa&o+k*w!6O)WZrV=$y3?ZF>MRB`VmzU?kKJPJ|LFuslaSBjP8==o*te zdaPhPtWZ+oWw{^RRrA%Ah7H+z*t4)0BkEIh9(c6msU|cBXur#ubvz>zVzzMO3Zp?= zBNZmKroylSCWBnH2~ebZE@q{5KP^v%17JO zi0pPX5*s1ApqsWB*InF=Z^rzGPY-Is&A(nG?7}|5=N?HEmGz--)G9FDs)lP1Ct%#E zFbvddfl=?(QDL4o-d&pt4T-Vzi1!Y(B!?kh=Kf!fEK1)3rI!%*F z-4Yct(IOWzrrsxJ$zozV>I7_i{g`$NotPr;U1-K9;L6{}$&{otSm8N9Y-Sh1+!qp_Goj3o=MMc=NA2)5G%xGJINhh%wRSXC8XurFD0E-k z!!UGwDvsPfhDKU!AX@PnczWJco1p#S;t@;j@L@tI#!Mf~6)|Byo~TaaUYw(@|DC3G zCN4DSt`x*BEhJ_eFOm5A9FjYyo!ouGLDaokIyUPACx3Me)Lgnj68cBOpk;3fKZ4ne ze&h)Y%WeRtSx29}v__N0D9-1_d#b#Ali1hfHZhyGnab?2flp{hThsYk91Svz7W9I3fG(!E^|2+b9wh4#H z#}PEw*qqxy`Qt*zfE<81u3a{)gVcN%cbm_ufEg0{!&f%N+0us?P#|F?cLEI(HV z)q!UqCRrXIn>WMPxn{gnM2a|Izq8G@`)5VtlTxW>RtQ-f_L~eEBExTp9*;?VIpi0K z7I);j;q2fC^sk>OIpULvK|1%)xBoIJGnq!!P26$kuYOUSaRcp4$;9@vl{9sY9DQ*< z8b#%&sppVtI%!-c4HwSuXQfw3x&MD;$Z|i@5o1T29x0P65ksk~ixnDrUZFc`Iv|jE zL(@wuX#BgFXs9i~KckP33kS?WV_FUUSXo0p4Wi=R!*9Z+L!@2eBUMgOh31X|C>J?F z_LLkjzo!8U_g>~|4^D$Qr>>FOzLPZP>`JIjt0!i>5@>WDfrpnaK;fjNAU-CIj?K-G z_j3stw#c%{);w{2as=Fys?bZghhqi3qFj0ozfMes()jsg_$wP+XZT0l8eVU6JY*&A zTKj_(FI9m-SdR^PM+FX#8Nf5)e)5{&qh1t5gEc*{`PV~o4J2UZc5{)P(lQz}=Nd`M zh$q%MLFhU79zNXS~=WeC*&LgBQT=-1)0%s1(e+oYWV^BrY0R^2Wvz7ssaoThyam;B`j}S53{3w z!wk-iom=p4hKQ*37*e}+ z8dx=K5{Wex(N)7`_@uISaCMFa17Y8O_P!Y@EP6sm_T{6};$rf3U%l8OSREI&O@xU> zDUf|_E1oxPB`Stb$V7p?`KZa8{xG{m=gm1vCr)gq%e-^NdQa1Ax`z)Via$%a8wV`N zU6B#d6`19p)C2J)e4#DB`>2-lU(RafLDF+-Eh*(2$%eVl>14MzI5Xia?f5P1YEG>c zPw%M575S^g&!<|^n@vhA#8@9MUH(qBS%(<4VM|>yJSi)oZmyc8f|I0 ziXJ?8|C@YLswB3rjuW4&OJP*j7AC8;ZmvW~JThXW?ZZ5AXy7w?ieO1>Go z(bZ65O8Qm30N$M7B%F#l|iK%_r?-(xd?DQ~!uQnCVX9 zif)jM!bnH`9n_WL*@uNot^ zQ1-_3$La8GV;-3t)GTWLc8DZ}9H3)Yy1=yaF~WQv&dn*2hZfmy;$0#klWUhox8w@D zw-OoHTr~`5y2ns8?h2XkJC9nlY$GaX7#MS1qQ9Arh?xh-);?aGxWfy(EH2S&BQ&s} z^9DqkX$#=JC*t!*wm|KEA7FcRC>kB5=k86QyY2Mo?uG)4I2A44InH zqb+dmhq2$+vS4#oIrMPzasO-)s>amf(5PJOcfNwt>KoAWxeAk=bOuN6yM|}x2STc3 zGI_pk3EpcigWHX2q-$+G&Tss`d-V~yE;z*LlSqi06b&gA!}z57E8=G&9;O`(hlMgx zR7au;LTe29W6EbyZ+xXqbp8pl1?Qow3y{qZ@=42OAxAZjgS=iDn3f(4UteD(R-u}7 z+w~Ib=#M|C%i@)^Z+bQ7{G^}64O>O}J_;;`C2921rT^eSQKm>Ly&IqZ(IgdHefY-R zKE!fB3N^-Fg4&5usIldoDB$`+FwM=vaE%Srd-e)i_$LY3kc(uO-+T1(JAgYXWH858 z0#|q|V|?Kgx>My5-Qgn*RtCw$@@^<~y00s0KQKkC;C@5w`-+J@^KD7WYoSvbKNR*q z_ku%b-=OiI^WvKqbgWh97hv*U9dc*CGX48`DAQZ;iktW)iyLN=OFZ+3K*w>O>{!1S zlp3Ol)T=_9%c-+rNUam;9C4l0IqLC?cW(lv2bxGj)OhDHAL+xiSnjLZUVcii4hg!_ zELt-xlWtuy7qe$Y;rxK@I9kmet6T-fobo$x(q%;MN+}sgFhJ|&yV3Ky0cQX8#IK@% zI9K63Rc)QmXTH;64!74~&mReX@QBxNxzGk~U996;C!3MV9Wtzq5zsn8c zlE8Dra5T`oh#Sn7Aycxm;oLN++1#0U&}BYO?Z3=jsUj$Pn2oapCdbI!a`+gn&i_}f zh;J89#NgyO;<)lAOc3zSdR>F~H!5TCQEwY58zI3DKYIyJOjwMwAW+<^)`$_z1SO^l zPMWe?s5vDHd-Fdb3*LskRZGBL?o6MWYB0rO_sW2ML*Z1*T8z*7KyL4wOrl>JlS9SF z>5z(Sa#^o{X2-OX5t~)P=}HOpJR#yDI_`3RbT*22j@1(%wOkDkR$2<2BwsowP8K4@ z#DH?*S&Y=uf?9(yyuI#g5@vh=D)tVA1Df)rV%!Crh|5xR-DwS?H#CV1DjEmV4r~+l z?CC_qUJt(dKSLG2eDd_hG;mWXLAeQcF>v1=vaz|3?D)MND;Jrtym#%S`Tjq$FTsq< z+bjviq>fJfIT9vj3;gr3;Z(j?2M;L=E`yB2aOgxi7-}ex7cBzcQ0PLfvXfwa{#LkX z+hbgm5r+po!*KDr>*(K~O7HDFgs0Ed;dn9&?FBd5l4I$pvqg=pc~cF|^WDMXpF4iF z84V{I?P2z(9{BuB@X?9#K_X-uq)8Y;^1f1%>GuVq%HoLE8%eIpZWvmpJ)@OcU&Yfd z+$Rq=FBgx>&f~UyOBR>55OSgD3wb@s4x3)CNBI;TeCZxdA9$+L>pewq-`)thu36Z3 zWee8Woxx&dAJCsXiQil(Fh1<%@bB-hwDiqb?$w%T9MR+mDUoM6(w%~l1tL5?_zSsh zP=_PUgq@&jAf#wYvz#d($#4A#qMP}LXhgK}o^HJUnJ&4b0b=j_B(5Zquz|k>`~=rcnF3LsI*mNr{g8-c z+)1wo(CwQ{Xq};$It@)FQd?!Ir|t^wrO{rPI)fMbc!S}C!E)e)-CfT0Z}eZB61-`X zMe)_qxZAFg@}k!XPqPg zFKnp!?_B!v!A&Z=@fnUYe2B8^?AdnhQ5ZKgihf?<2!7EX;x$I|>Fg74z<#SUR9A@c z$m8#*FzO-RZ4llQe}6{x?`c$~#8|wAouxKfC&5MZQ~XwP8>n|ZqWk8FsETqlxgu3% zBd0u_bIIKeE!n9UEN} zh<%shtpXwE+<9D_VYdW3FHgj2>gAl@U3K2A^06?VjN;`7_mCNR5#;dnH4xpShW!O` z_;uA#tk!=@9zJa&r}E>Vt*eOq8>Iw?{>lQ@oTbA88bsA+Ux^h~DN;;0f-h%Ch|80_ zV0~;~<-L|Nh@EFg79O*Oll`%9OX#LtJwFC^>>9@pKDm>OXgOsQKO_e#?M@RZzxm|k z?U$go&7ZDXxsuNE-zsp$gK+TD-T3~-GuraxD;;~h1dsRE;H1Y5cuH{#uA3WqkJhdq4za1f$*WmEsJviyrZYiy45ugD_FTu4#$rxBl9XjjDp zc#!jzK9D~}bUh03{Y6QLxn+xY+Rx#jennW+Bd|#G?$K&fO)5G%R-AC7ic08Iki?Of z#nW5NaZ|{4?2`OSH)zhsxF^wMeg7elS|RvnSA3u`I~R(dh-5)w@GH(RYBFaLbdOwq zf7C{n*`SiMklFRoCrf2Lv2V>7o4*QbFtA?{ycY>ORE?KVs(%8f&k}Y^wbnE%)R<1X z@C8jqc2VcXE$Gzo4=)bb!TL+W9@@DMLXJtov^VRaY4dittH7vfeG=Wx=8J*5wnC_9JMf9lbrwB2TU<55atzKQv% zt4ONT1$yhpFS_LTLh;_o->Krr4ywN|ooWvcrCna9MORC6sg*|wwaPj}P9&A#POH;6 z;_i>1x*Eu{){et7fAZBxjOfa%l-hBUQ7oj`PW*>h!Oa)K4)mMA&;1Y!Uo+#V zL_{Lo42yy8wjosuKiRO%+(tHQULK3weiWx>NimBh6H#){0A5xp#0RNg@v_WfP`~dA zt{dl*eR>t}^*?}RD~~{WLpO}InM(Afv}uTHJ(`_Vt=jJOklr1;1Lm2VveV^Z-1uQ* zm`t#Mpz-a;HWR|?@bUOaolY-v&?!)EsT5xL?+`XG~A*bdPNqT)4mkuAp zKi%>gEE8*4he=CKusU_X_B43CD?+BiM@HWtci+8ykB) zmc<^uz}$z&u_5lZY?Qqy8(a4 zdKhnXI1+97GZ?yIw!lJI4DSPPp=;7zcFRc}l1e^d?}j~W_Rth|uJITH4KJp-TZH$G z1K6s!i<$2aPZqE!jlJkJtjZlTmpy(kf;no;X2}{F@U%UG?sIcsvFg^$eY7?+D*OVX zjlpE)pf~gw71%2o`sCz=Xfn($9Ja4<;Hkt?exI+TZQHC!{^7PHzR^E}|J0(-2R%vP zxsAx@snzfymJR#~_{Q3_231A=dC8pmAG2M*b}(E2V{H4(eCD<>a6_tR(ZT?4}=IQ1&3Bkp1$% z!rn)PRi3O|%zjLXWIC#{bj>kGyf=9hGc%pazjRJx?$@N)gJxi=ksQmKWzBY)Nb-uG zy3n8aVwzVUeZ3vX*r$xsT_+ zGE{Uwh&sO#VUXHaqB<^6=)i@tncNxnQbmI;Se(dCisIPbO$(Ujie)VBz8#a9@)bo_ z?_p?ICoRs|fK`j!So)iDFysfvFTWhg+O|fBE2t`SO3Y;^gy)s+-!&{{+YYw$!%Li- z_z2fuozLt9*VFth>uGYt2mBYXiArbg7tj1+#cpamLHAK6NHYZ~*{-Dw&fb8L@$v9? zLJXXCzX3{ZzNDrWc=4C3pfdd=EVBaM_l^uNTOrAYzt~Jx3Z3H(3)D!Ua}*!orN=+d zpU)n5|Aha#9QkmMF8uO9hs@f$f`rU?2WA`FAyV-m8RXu|-F6tm$GBgIgp@X3YCUO8nn__n$7Y*z);UZr^F-#K(i71N1N zp5Wk&>$Jz`BY)071izfVW3rSMEV0Xk#FgogI>VJ!jebFt=PB@BS=D^@zj1&e5P$%#-?yCjQxma%RPs%2(VSX>-QCw^yduoc6hPqn> zfsL@@#$;H0rkD3M%i3G;B*VG)3%yl?vc-LG_B^%qlK16aRU@KWVi zv5<>*P(QvvxNE$O7+r_{iE8Y@=(8-u*@At|GGR}woY`QF(I~k}g6*;vV^i)-{>fMh zQ;d!Hm!cS`ZT8@e235k-E?xMwVk9SR(}(qr57F=EM0RlA2~^(`!W?lJyZ);I9|iqn zGwLt1--9kOKm8GKfW<-b-pgqjtI{v7O!CbFUF18COm!csKl*q^}LcBBcD_#D zw7s2j59&BYkI3^q?AjUD=+#m)&Vs9()I8Wf@!5*^7rv;xIqZ2R9ruhCjc0!2jNPIN;#I=Jvi|<(HkX##fj3 zdfi2gqYe1@+Fh`8rV&3wqekEn_Jdja8FU>Z1%5>~yjzK_}t>FmQfEx$i!r1ynI4&gv_G^{E$u)`W zudXhW+R{R&#%*Jlq;J!{8AF8~%1(AKL4oTn{!Yy{O@!;;V?e7x=yB%yk&1+wD5*LG zpDk74J-VjQyg_H6`jtH978XJJ$RPf^^>eo0d^$@w70#xrr!WK6;k)w33|q}iIRH?bP$vpJaL z9m@aU=kYV;GL zPeN#LbRW6}=fm#85GeX`mdpq*!}axl@#L~*I;D3Kyq~@V_U|i(U>6Ja?&Mh-Bz)Hg z>iu!%Tt*&bgkVm>6^O}7rzYxO=|6*L?AsU%)AUl{>Z}y}_PvH%U9$)Z)Rf7@sh2@t zG@Q?{t0WgXX7D8!>fuH40oHq4*!Sp$VZe^1Y~_%lWZo2c7B_!B^NbnF=0>ICvDKEK z5h{tIUrB-_)fT)uKjVXF4K_C@7_QCLg<(o_A?w_HevOnN9c5OCbN0;Oo7h2YNq)wS z{N%xQg>++Sk`c4ie~qP2i^R{v>gY_la$FS>kCtoF=%za}nEFUlrgOoZg|9k-pX|-q z@qrqAb}IoTMlN9*^Mg?@r-r!flxC&ljM?fL7cjpX?lm7HqT`X=BTpt-kB`VeHB|^D8&v}_u$UGUugB{=_s{v1sfKkhM@)uIOkvy z%4XZ3$rcy!@e9`6pPzF4Zeh0hv!@vQX7%8kfJjVQ=>tpT-O>H@a@;o85wvd(W6MX) zgC*Ct@vY-S@YSved?%p_FJt6UcAGX+3*8TsZ|Jl0%f>U0-SX^2n=~FK+U%5F2$}bL zE^3rYuziQWiyJT8ynFe2y;SKc%!@;c@eEAz){$4^EW*s>KpTCuYde%o& zS`;UDCzD$j(%D{N zE`Ahfj|$5pSzV7Wj*c{iyQ896nD%7WcHup)Sv()u6%7_z-T{xQ?!iK)!^*RC_*&x3 zD{+08K2H*pc3QDlz6z}G;t9&`C`9{SbLqjfp3g^1fa>_<^KE=!$;^PrupmP9=ZAKuL+7j=pD;R9=Pg z!oEU5MTyAwZ$qu}ktpdh6Pu3ff=SSEylDBHy6SuZ2k*-madJO?s;CyLxh2C^_vg?Q z4uYFNA5PZXfzwe-#VQW>_^CT(_;1d#{F4`Q?E3ovj5>B7)*DGMEeA>R^6gQ)Sh_ioKJLie+82m!bdr3vQe2|a2G#>jy|J^&x<>W z6{*F-z7`B?ZRXTe3gC<9DJt3d5I#>0Cz%e>m>Rzn?x$BlzgIg9&tAx@>A!+2!%o6d z&*A))U|q&{M6+Gl#pvPs5?5qTXDfVTV9AO9FfiE*Yqd9mZRjAL6tCvpKF;OOTh8Qt zGa`83+=(QmL7m6KkFa8|7QTu$<%){T>4rA~(^PXV1Qa2?8S;}h$^cm^kxpwq`j7?G ziDIz}JpCR@r2gHf`||ccgup8vGBBE-FC)WSl#Jr@hTCCPu@Qm1Dn>0W3VQdAbS-1eoltZqDSOckv_gz zR}I5A+-fzo8Irlxiggd z=@?+gn}>9pXA{@Hs)R^A-zxOWPC$&j6l68HQHRH^v@mNl&Ry1JQ^x$DqI4V?XFm}? z`00|D-7|61;y64}*(S0(Hx!OHe5SJVIC?9r3Vy$D6HRi|AV;PR7M$1>BG>0T#W5Cr zRKK>I75p&HPZtFw9g@X>`Og0M$yWiH(bKZaAF)fi9C>QB@Yxdq5I(` zFbt2OLy`qv?Wt?roqbA})bo$@Mn{tMJCX$&h6iY=#c`b@Z&Ux5m+0=OBC2xj49(oG z5B7IgVSMRkI->g$s(c;ACV#H3yrlaQJ;pv1n{Mc_u@LTbJnoy)LA?z^Zc7J~h1`PF z)-T+usRE1hh8bCRSh&wFY7;MG-ZlYBq2fvIrWDs&(jCJDmyp02TBsEZ{c$r$m*QpG zHr|U^H5YT2n#zc+c^(nlex{p`DvA1Xo9OUA_GnzEO!#Ii>}mZ;&*mm^<8lOkTFpq& zxkuM=!>9mEonA_In3&W2l!GMi&0L#Lc6F$}u^e0*{0ZAHCSRvGk&&@O@I+DyVaiIl zpg579$(#xjMK9@%k-j)lT7s_sDTDu9qPR5<+pxyOf=oYb1_BTYuZ@;~2iXgWiRM_c zSS^~QCbW{k&nv_mrMB6ySHlSXafoVaU86BZ8YsKwAdcy#;;rIzI()nmI2|sfb|uDm z-eM@G_K#&dv^L_L)|2EFbkf=5p3?eln@D)eZDL>SFH&BSnI2TBd<#`5EF}6z&WUHn-=Kls)uhRPF>QN!lI)q40*2ZunEkkh3|(Oc^8_Bp z$cm>hU#*i)aB&xMQ~8eA2) z*i{cW&j(GkO*k)>OHD`D7wXivqnCJG=-^4!rbs6@ye zx=qs_H`Et%H7~SL#wrz5L^pSC6~Xi7hdHAQ{^ZVT72IkO2s__p(YMz; z#KAMtame{K-1+_=RMtuXXPTY_+Pi>zC*(l`B74ZaZ}-UHw87Zp{0UXJpG9@4P;#i< z04HBI!1+0E!C}CNP1i9(d*L^)kUKy+2Gp%x_r*|gz<4TWAfm0>RpPR>7eveAWpV6t zAMk#DiOgEE6Tive1Y1T zm&l2K3ouN`V(TyTAXju3P(34a8nEx1NUoquH2bR}zT9{OTV_SUNr`KyW0Fo6D1PL; z4xHvdxl#Xm2-qsLAKkZT(o>5|#m zWTr(d87+7_EOr{hVUaan-1d;Ze(4JN4-cXuH-d~?_#7%v9mHM%zj^CFV}5ITrZqO+O0--y4ziteVH!fDZCVsP3E#+tZ-U;H*aU_Kx1qA%m@n6F}G z*Ewv%z%^WTaS?fKFn|xHOeVPlGhp_0dGt&6gS8!wgiYQE##N;dI%5!im}CZOam93t zi4R^IZ;zS>oXE0{!!-Jd4%)wRBC#=h&^oLX!>87XKd>T<{wPB6n962l&=1h5=yiW=+3()WM8G5OmLaqz%%A}9Zy-1K@u{8g4>xkR&dp@BSC z+oOdu=U31}Rl4Ze8i@{p*U4RnH{?gMJv%i*f<5tQqXFMLh3sSoxuT|p=YG`CvZs~Q z*51-uFK-rTjG9T_uWAyXxOR$;I%p0y$D7IO6Gm9xX95fEgh2OaYlxln0Ww|~(NJl1 zm~ZSy`7O$zA|(q$)-?%EuPEZHx)xiTayav;&&6)m@-V%nlGJ8CB}&RXG{@zTcfR9j zc*Pt@x~`6*5-q%xtROx=%pUd5C<*+KIO?O?N41v+lkZK>$!(1vxfIUC`px@C8 zzfa1c^2P1qrU+Xc{q-XaTrcFd&KINoX*GPx6%fB^UTk6YWNfPwxO|mI>3IL&wE5OS zach!~c>QDt`u@{a^2|6Ebow`uOEq2)U8CFsv2LQc0x|iezYCEDs;(%w~pX^YU9ay^>Wfu7X-3t z!^wiR=J;jdRZeS?2?Vv ze*(L;it^kmvMam~svGyyU7i*qhr6v*ODc?dx9`HO{n9whmC@4sm+>T%V2)YCF?Tyq z-G}}3W7I>Ulso~d)AQlT{4eCPVmxYRXtM~>96IhP(ivM4s6%#`jgS6X(%w{0l)p5f zY%r450Yhm0-wBXWd68UKs{qN5Gl=;NHBsyWGtPUI2eJh)lONHfH!skzXLlr)4rrrm)Lswc7grAVavwzJ&cXWZcFwu{U z7;pl+>?`7iQ-7iBmI0sRafMvyIt1;jbx`Gg6LgoVvW4q*V!PZSyc88derv4((V!z> zf5H|b`2#RzMiu#FnZxZH|Cii6>?Xc{zZQ}XAA&bkBM^gpV9&4_Ft+X)H|1_P)G1mB zPMA=d`BWD+X}zMR%V(kM+yLUb*A!wGiAZe9bJ`vk$hk`vka7PyxFD?@o4S?m=%1uW zjH%Tfm@a8(*)@%i5C)5%Bqvo)wR)@fmwfO5?EEhCu3r@dmg4dEY@JwNdz|xMT zRXQP9v0nqU0Gt@y?!O(_0y zkIU)M#_wt2)-8#n;BinZeQ@*7w@bZjL4^SmUMuvEq$ z6N+%sm&fGueb>sEl94#sbTw|ZZAI&$m(VKZJkA#Q4C)_WfcxNl_&4tet&>mXYI6@m z>Z-BOX5&WhY>>eo)e#WvBLye(e~W$HK65v(x6{;?T&~pW48&S}CGKy9vBL9%Sbo$T zm@K?oDD2pTlDDQ2?{7oslilGk)KRJb8?i(l~=SdVhrh^!i58WZnR`M;*k*YuV)9ogoBvY#|5=m^&v#2QKPy1DfN3JsTnpJ)Xl=Ut32rHNENK9(B6M zZ7z2vq;1jOXqz+@+XblqHl6$6Dd zq^65hO;BSI&caL;&_!PgKF}){pTV@`0q)lISm;qqhQUr6;tjc<;im94Lj#=h1%9Drl{jjiG}$9~PrrrDB96`O zFyZi4(0`La!W);tGpz_RJN&M=dERR7-857D;wv~c3Y@q{SH^I9t2V+U$2xBH4hj6e zyoDZ6)TNiM$$2J?&3EY&6HD{1oCY z^PKi+dO^&NTCBg9NJUeY!^`^zsgJ~8oVoHFR=m1Oe*~ry&$D-MEuSocJb&=O&6Jy5dPE?msEq~n`jLVU zcP43!{XnOUD<|b|pTeOf&uBoV5y?(n40C1*9D4mUoK`aow{#c4oor=Vs$>V52~}jl zk|g@!-#hWZ9(C^45<9M^A)1u-YKneeYlQ-pBo%_xrqF z&nK3CKY<4%yztGYSui+0f$a^*NBIqkpm$0hRclAUtfW4&>1CK`z2IAZe5M{^#%=^6 z)`zrpX=KHo$vE=AqfohYv`xA67=m`a_#~v6RIV|B_4hZ3JaTM_&n;IlPEHqlj2mSA z=W-cY{81i@%HES$dtLZ2*$iGDlEB;hCfV2wcfw85`Q-7qg`%G))k$-w29ycRE4PZL zWXCR5v^_b2jT9NfT%T3&pTI_6bJ>w)ym?Qi`HaC}t72^Y6HILVC*tpxcPRc52^$?3 zlBT2exTrG&O0Gteg3~9-NVk(HEt7yxs$Gd~Imff>QgQFUm8Ac`F(Kb~A7dkgJd{oW z77F{-6K4|yFH|V=PdtQP)0@TN&8kGsVi{JR{=t@$`&d@|7?Tq(;L;H(7;z#5|7uBr zM%qh~Z|}F%Fa#U&^FR-33uop|037(CM zY*dy%ZnRp0v*i)~DfYsfY27&VZ5`-oE`bH1<9Lei1<|q%+wrq>F3Q+X1ZUSJFi6kn9bv3A#X*3(!> zG}ot*i{G_q#-UgwTfgIukBKnrp%u>j_mch6^2ciJb7Y6{To`_^A18l!&4wL6ieq2I zAWw`SzxR8Jhh`Rleau&~PwNvoAEQh|7le}4bMyG0(W8mSj?--O3d-dK=1)g`u}w>1ch43QR3y05S8EA730ZttF@f|YzkrN! zqxk!a&FKEKg;-B{F5J_E;LMoq;JsoKMxE5hwRS0ZDo}|(UeLz2UAzNUJ91DrwuhV% z+yP#WOK|fo9l@C_MRTf0@;HGD^2aL{s-84q*O8MDrTUfR{y2%&mYZOC>Lt+WE+nVi zcZu7Ex-z;9p%d!C;K8~b70>%S3%WT}dBloRlxg&5@v6392Dakx_8(&j8E zBa%*f-r2@qVIR9%rAurg zmlA`1TWl?kf?3Z!NbUql6yUKUg$Du5m)t^ohgNd$LN0R|vI9qL8IL(r%wU*~JQ_My zumatc5I9+eO8YZ5arQLMBDX`yzCfJy`xEXk9SNPY|FGVkR9tRuK&?}1YTlb1M5(<) zVZ4eY2u?wyy<5OMI0Up-rQuEO^Gy9vD3)A|6@A&DFY>QY!`dNN1YXl;_NIL*dj494 zJFXpIzJ+4eGkLbafYcQ0&3(%JcRQkj(S9uK*n*GF$Dv1g2J29y)wxSstVffJhI?Gm-gM@d+=v!z{w$8Nx#pY-qBs|6L_YLbCA2l3uOc`!>m z0fzt5@c8E`plDSF^K-A`4%g& zvDvPPXf!<+EdEOs`zvUQU5m7#%T^2TUz!O9l^!@~;T18Blcdrmon)Dm5yIqrjEYf0 zn6j1`=dZ;1Sw93{)JNQUzZngwa0e)L1UiSx;DXXWV7zN7`Pr3--l?vzX^jl?F?%oa zR-9N9=*BQCWeonf3*dGz934DO@pF&R3*M;7x0ib2z3eU=4~h8Rpo$E0J&KE)jq$p- zK4fk&N7G-1ta4)yE8XRb5+3@P=%fh?W_#j4iD&FXcM;THs39`;P8e|MJ&DG695P}T zep@2&dv_kd{ciE(%V30kas%*X@(_4v-3vJ$GkNu}@2D$y4C>_OlGfv<809lrn2my2 z^IeWoE9KGk%`n(qT}>Ws&JpWoFx>0SZjm7U`o5sp_}zO@K4ml zE&ZdopRGEKC<;L#ijLGGj_qAH9Bm{b@y@AI2;D1znKPux+GoiytKbt0*C}BSZ);CLn3 zptT$8X`tXVCllkFYEb*sBSu#0!p*={;!81?n9RU5(Rp%MRB^kWz4GWL6EaP})>jpe zNo(zt=?@T)v5nUq7fF-DiafdA`_b=mIVmCSk9FEQv6$0aE%FWoom)KxQ|{ zJbZv(rvO`a)e`fzuYiSmw`~5dxJ%T&M#H_*HB5bT29OOkpqV_9O8k+c)nQVcJN|>$ zrLp3lp)D(3EiBl_ zAEBcAv($tfMiKtm_?eihCL(rc;P$u_u|n~1{?NS__w-H#B_U59BA0>1LR-9;F+J`KQueLpR*< zd??CWzLS@Z6)64z_aQ0xAh~#9C#e(e%0Cy?vtzQ6^k7mP{I`55JZ{&gmczWEVakHWZ zfAs2(u%GVY1}`pP-iWI;@8ZTXI-sZdUhqqB};$OHsAz z!|dPXL+pY`g`SC#1NDJVY{scyhni{9uryVc&W&$?r+;ox`NaZef6p~?ac3upbX}oH zF@g`M_2nz>tVGM4Ql9OZhm(dJ#2=2Q(Wkx!WM^vApP7dA6YjDV0Z&Mv@;=;m zrIVSs=5VE1iTuxvK}_0b5qGgFt+Lx@)0QMT#l0Q~%YIdq?Iq)KbI(rYV+!FC5}nj&Njy|v~M zo6es$eoNfAlFm5Z@M0>2S(<88~eAa(?S_f{nqdkK(3?E_6F1c+54- zYRc11p)tD-toA6q9D!%*1n1()R(2^y4chg_pt2&?mWQk1r60z)e#$76u}XvA z$~HLWEak&m4s%n_v9&G_wXkZPz>Hm|N3QIA4N-0ZwDtpspTWlTaNm3QfDR&sb~$>= zeldQvEW}xHVPailEz%Yu%Lb>)!kyzbRI|(%%D1G0OsxggefAzEF8c&`+NEfuO(1Kj zoIxf2x#OQx%lWLUNAbPCB!8G~3G*~G;Qq&XbX@&?Skyj3F8Amyro6ezrH4(y?b9y7b0TD`_GrNCwu#hy z(<;b)GL&w;|B(zoG7}>vsM4h~bSV2d1)sQALFDJZFoa2PgQ1fAwD}}_xMd`Ny|{~O zSsmhE5<*Zneg)P4{R3(i2jjQN6R7CmbbjpHJ52Rh!!JJ?T6ax7M#wZ)uoFA);M$Wv zNWg&_IIviauRFR0HA2SmDjRqHH$9JfGiw@msT(#=ZKTs%oyDRz;cV3Cwe*!jGBDZ= zd*g~wZju}3wr zb&nS`h5yHnRc&D#pB`k_CJXNQ7Bjm2?q#Zd^Tx1K+FWLBCo= z)38Pn*Z)_5^DgcKg*&gIY5q-6Fma?6&z{2kND*nMAlEGZDB8%_be-I7Q1rC9Op;%{2mEf*U1v{NJ^m!N3PTd34TkaBQ{~beL z=StGHHWNPVmkfVdeSoj){D~(<$&elpX7FtHNt(jS#UbhAx`Dnm%cdK;>%}@S^7`dQkTf>GeBDN4rPRg!O01yQa~$ z8x3yI9>FcCKUEX0k`nSRXP~oN5l5CvQBh5wxap}0-}GoQpD?=|<%0CN z`LGV&uCRo!`;$mVPaK1PhE74L|7_^7Mq_$4Djlmn3tqlu%V}_M0m%3TQsdUKv{fY= z-+b?b_-13)BIM=TUS%_P^%@*}%!%k_^oo_FU%=1ML@Hl=5z?30@?m-D*t1Vyu7>_V zsRlzHFz5g^@eQY|i?hHkU7h;wn#?|38_A=l??zM~&+p7w&Uc?lgGmNU>C(ZAuvV{= z2+w_L;x9pu%Bj*1X%4i?N1m>{_8Z{rl*s-rZVu)EXo7O#%=N5nlL%jf9`M-NgQ#w}JoW8*mf*W8!;5Bl+{=&h+zn6?#5uCtaQ7gM}lmvCl=RY=DIV z5BV0wrD_iI-2>Wi!^%NuWV#ElZ=Ay`FCBo*_Xp9t_lvox`5BQf+Xw+J(zf0m_B46q z2dI|~fbUg9@y0j7As_i%w9=H|B+Eql-;>oax6_Gsbe@DEZyb1Y-*F+YF2P3(T*v3YjxC=i|zla7|qj>DleQ!GzI!qb5y=F{sq zoYtC8KsBL1_}{eEI5qs6^(l`qn3f-damwp?@sn7-x3I!z2pFoRSUz0-aHucUouP*?)Z0nvBBqgfmp?VgR24TR8qjzr;FLs=aT^?)Sq1%WL#bs317^PzR~z|bxbt1+)#3@dhpl;E zjWwB>mkrZ4RSImuGw}L*9KOoyL;I&neE8sjR6pn{E(cw1E}Z%HFMBLLxhI%E*EZ(& zN_S9OKRs%Gay;~Y8ISiIGT3>6%e8Po3Ceuiz=mHkrrpCHKtq-i4^F;<#$S?oUQ#0N zk(t6e>&*DUiGJL9Qz%~)oyGf4=fTKh4B~C|sE(@z{8atLN@AYXN}7(MfvutB$paNS zXUI~Lde)IoY&*lZ+OOe9CT!ww*Ozk3+4lS*J;f_t$MNM=xpZDgJbiU4ht9Wgq`TD; z1!k-wowvZ1YR=vS3Xa16o!fg@lsgbi-iE{Bh9>;@R*BUoSK-bH@m!-%0ewC_!72ZF zanbGT_)udt|C>;YA8kaUIq!UU`K9AH!q%FZ4xYjH^{Lk_i57w2 zu%n6V_lfqsl_k&HT~H@!GhOaiM(?GDQ@?99tm$zgJoGbxSs#qqx_1LGbn$M~S5?O7 z;vVuh!;Xqqe}#FCcW|M{Ply<%M}5*2C^b)|8|rWKu9hl(=t3k{Nr>Qg8bsE#AEua>E!9=ulQK_&I&iVQ@64!u+HukdFroUdvS0vs#RBk!v3*L zI#-2W7xL`yr5>?k60fm%Ru0BGC9`?OW<2u9Q~0Pnj;^x20`DZ-q2nDk=Z1)Q|NBAYHnrE9s{DsDg?w9U_-Sn4s>gf-$B+dRwD5KDIDT)RKb>);3sqfx zYR8-E(>XZH-YO~LmI}L)!9Vep)<96ydq7pI zWpTue*>rjRLwph%%F6R^fL8BhdVaYKefB|te;$!nJ9Tg$Hbno1A-#jB`qfm?JgP(2 zfh=~$VA|_7l$wuqrt`n#&?Sraau}V7G*Jp$nJrvA z{)aR+Avt2O9*&Bw@x5y<9NVK$f89O~E#*t-uOda-=dciW4p*g-MkJI)R!p7Bxbf1|M+)189f7EIbaxNY|L{&03gE`n1l+L}}Ci1o+bNJb$`TUfA zI+|;R@l84Md`sju^lrDMsnNEe{ksabO{^vTT830JVm+O19)xJA2qQOH6L5NqXxs=R z*0o}BPAH2rnoJcs`LP=-A0a)OH z&u^>JuLtJRPXngX0hX^>_;MTiEN%czjPHc4Z-&!;jhn(wub=eY=?6Y_C^bEw!Y=)= zpu4~L)A$d<`&zHSt>p(G?Fglca|2=Ev?zXStPaFRZ-al+Qc(JLDp&;hv599>nMXn# zxpL72QALcIFJIw*YsT=c3xtkVlQ~aGRl)78F8pJD2sVqi;y=6JZ13uW7$*3X_XT+K ziN6lQ{1g{>A6-P({WQQP^JtuZNKxRi-eP|RhU>#mEg+LRiZ+BFC;J=*(OfeTj@dVd z2PUrNX4)ovt#2rw_;x;O`ef4-p?w&_?!jt1fno8~57WmlfwWuxqTAWsOk z2i1d<;0~^7D}+xy>*$xF9rW}o6MA=~Gd#TE&)L~qaBfo^_x!8NMWTEd>bZgTg!=M! zn{cWjoHwp-T18re=F#?{65L345kInIfFMb+rQrj9iJhid(lo4s4O2a-f5A}tOfesZ z^jku6Kn8Q#n?S*DJv|#}PP4mb(JB6~;pzT^^!?M7aDJ*Qw7!mkR@D&t(F38Y%$qLJ zDdO(@828#9$Co8`p|r+MK5?Aj(fc4ToS|a)cd0Ng3QFQV)(YG#BaBZNdme4#I*5VL z3o!Z|!p{sY6_{nAysGON|GY?&%dK+dV=iq(^^QJq*?&X1-=hd#*&a_8J&WTC$|eG; zu!`Wpg>)hhXYRXp;9l2aq3fB0)uAu(;!j=Py~2mbjr@nBo}5NImsxzScM*Q?AJ5Ok zujB>J|Ij+xlNYa@Kto)|QQtSC=#=`i)IM=5Xh19&v|pk2Mmh9AH>ce{w(#Mz^Ld|s zHP7q{;C^>X`M}RLJo9NTpE{wck&+FndO?FZtkl669VPDGz7Z^${MERL*0}A!qhu`qeB7G<^xnmdr%1CD6?wk%nsKy%#p4x-y5!rOA)3pa@f0}M1f2SLR9aqw>lJ)$Ct`40QA0l$| zEoD0`9}_o!cdi~J%jf9tgUacbNm_*qEfaTwld<4DuUJf>r-V713*5nGfkRWMjU$U) z_~@yAeEWd+bjPYqFgQ4qtJ)po;fvqn2h}WCVq^yAa%Dx;kcS=q08hWBQ9s|C7@d9t2id98wxQL6@AEgg_|J)EdAic>%^eWG^C(EgJpve; zCt?H7gHFRJ{Bg#ChtBY(k1j{@jD%EvH)9L^Ty+}$Yrn|L)DuMS$`!a%L#yCK3Zh$I z7hso#B3P8Xq63pGAx19>cQi%9YroN4H8>LS)dx_UIE+}HRHqHXIYRB}ZpeAO!*=G> zP24#=2E@68xvY0P%xLce!>}*lvFH;>t~yD(mgLg+zVBG_(ZO)Hd9rOl%vwAhdjd*K zpMZ-72(#-NynS~9jh>(&@F$1TxZu^`u9iv4w1qpxEmm02=}!-xzlf8b-36^vHO$i^ z4z(YtaDDG`deCtIx0{v>X7aMOyM_L?Wv~`U4>4G}c=4H^7SSWe27rO53C-V~Dmra> zg=>0GBx~d}H=J1}V`TOvyEJv=OI+Dj5+llZ>1TMbY zgb(*wLZ&c38%=fM?;qFlYgb)(ncGSr9gh5W#W1S5uM+x`mtm{IKiK-*lwSIq0rEM$ zw7ldYd}x=Zxb`m8kK0Z^&rakc+ICRWDX#D#JR4;W2#v)zTXXQukqmx8 z;!^G9>$?2mi#*<-mIGDMmzdOyvD|D@o4~x3Be1+@~a;wdq5B)I_ zDpRWQuY)YN6#VF3CH**8z8!xpBRqKRY^)2_r}6R|#VuDN`IHuKsJ%acpXnP=*FAkM z-*h^QYZa|P(;i)1fc|g;CPIbRF;;TvFlMEu5KYrxxWVc>HxY8JSN1A{|G$%1RIiLF zHo>&jD+XK5EqEI>!c~FGL<(6-*xM_{87t%|q{U;~j$`om^dej((~H4BJ8}QFi%_## z#rElibHwvjKEzMk3D-KRdB0o|5BzR{-_u6(m+JBCD2Ki*f~3r$f{(~m{&Wf+){zb5xtAAb$AA^G>_0ja2bXkya}0~8mXC! z4`g4y2eFA+bpHbxUOS=&)vi9HZs}HNG*f{uHjxBz%wf9V@*#3kO_fV7il^(ND_GI< ze8x^c!{J8jFm#g@Y@2qAj(aLYv*kniq#L%@Y5xkS4Q$~~3N2_c`3zo^SxzrZ{|gNt zcEKE-CNOMULedpd=()2-wr`qC>DUE@w7ESTRT58dyQK3q>1IE1C7sJVHa7BZ&3&-Z zJb>Rcx{nKNGQic+Sm1}2@}Ii@z)5l@{WfDDy*o#NkJB#%%eo9~@y=y0e4n%PyMBx8 z59!mLp^FT2n%ls4KrKH`ex|?q%vBa5ZgH z1eQpw4t>>dl>EK@1r|Ty_+;d5>UZ!J&FLRT>(=?u@4~)*ZNqT-W^V}9m+GkScdT|!my7QDG-P*$ci2r{lKi!SDm}G-diNw$}RuKTw)Z6&9G#?E6OW5p3aoTR&tZ#bH|de%#qG zfxmasfq>mge9o%PpvPQj^eCAZ(`tL*wns+Xp7tQeI9v=i(QTZs^_bCC_EeOEx8n0oJZa)83a*KU-3#G+l zl0~!PZ0V>aYJ8lqpDW_w(BmIM)b<^LxvMY1ASp+f_Ep5^j6I5fiY~+9mJs+-xqzOl zpGC#H>^Tm5i7J7y)GFjLtQ**lX?as2X1zKu=`!XnPp84!o*!`j-)wM__reBw8<=n4 zhc7C$=;lvp(B7s=FNT>@1sKX#^y<+wAv>wq_avSF-I`7~-pzxJ4~VK8C3vV}3a^X) z1s#vc|6 z_#(XK|Lkk_@rg1jdy6r zy*0(^qP?VH#aw*sB4iE>wMc~49QN0!o2kwjhu^2M_>(8ATH^;&ukC`UhQrlFFwh=o!^Vp*Yr>B$v%QC|^E*V>@O*Lv1* zsD~Wndq7WZJNyY-D;hD>7q&QzCUQ@Taj>5P5j`Tf_)i1o|5b&jart66EbQuIBtR#x zo!Ga@K{iqa|?y$GHJ;jt6*VyB_7k}`@%}O|aVLyB3-h^dl z?;vNX11wOOum#3hSA-^Y%v%ndkS|x$)gyzSA~230ptV~ zF<1HDB%3KgdC43$e)JfjljuYSWT@k|YZr*d_6k^dNkm@PM`3{AruPDPCP>ZffgNg-VC-sFDkt6uhv$rhpnhXu-wxwQ z4M%LVj3V-n?J;Qn+v*AG)r1C~LK~OC#J}sL_zcb_POheG;<|&2vZ3ruTDREN*Mx2U`-g2fd;~5kuECRAmO}lmR8qGmk44EIhL;BW z*@}r2MfF2qmsJ)(FR^ZB7a6lSRdm93Ec6<` z6aDbIN!j}C{q-~b+XWN`K60OpeI zNUCaP!6J_+=$fI9Z)ZIvUaceHYw}CBf7uac)F*<8Yd4Axk1~gd5fky|ksoZpvJ#k{ z-iwGz+~eV^no3ATMP0qG{=3l96d5mW#PB3fMTDBrMSY1r1-QzE_Ub zhpvf>q$Fs4!GFjPNTR)_A<9je3YKzbL9WmfPK3P#uOAygr%9TAx-A2FGv_nyJ4g}7zlc+oo-8Pwr@qTfHhh!Y>|Wz({x*{=K=rcl`{N(EV%Sf+wD zM#b2sUkpioLLYfmzTiF>M4POip}b>zt$N;a7`rGRorP?2eL^)^T-r!nDR3-$0ViF&@QJ59WSVmb88Q>iSZ}UOmhJVv-uL19v(o(kKaYg$!qv;dK8mvIASyOjTiX)O~tB#J4pM19x_-m zjhsFC0Dejf_p+6LMRRoG$egb?SpTjO?B-fq4AgeQG=q3Dtsxl(-bjGK?pKJMVjFpX zCBQm_2@L-c5zHSJG5!0dP%`!wXngU+#yU&Ppts5Mh3bUuJ0?-S6a(i9#h)L`MfpLoOn zENOp}i3XDI#~F|~76u!)>A*qV`>?e%oosO%!whL7 z_|s?NFURM?^WWJtv22L-=JBt|+pmYAW6U9_`a)4N-;b48mDOIj{hW-iwZy=ihieDA zq_QW5q3o)u5iGo(M}oDj@#VfG2#=3s2j>v<_$uTKO5$MT>`+L*vkh(+-vBl>0JOpj z#pCPzM1LknkaJ0+anXPn(zzmo?V0U^4eGma|KkTN;l)%I?=?`oxAKnlpg_5@($xfoJ)2iF>GRK8z<@Rq)w2y6~>85$}Fhy$Yy(kDO9pAR7Lklo_Aviy4Y|H2gbB$2k@b)1qKc*s zq*&XL_)NNq0V5-E;ff4Z zgmlLqWU$K+=#_qQ*?9>%UHc>&7w&{nY5&;qP7S>BOckw^op8f2J&auPkBtzz%^SMB z@a+^?_Wi_S)LSleG(Sb)f({!rP*%p(-3quqAP*I{$D;M9_joy45+}2C_PGC)=tB1w zaYOJMrqQqujdl+}Z7F%IX+1#P95+MH?il!HKNKd<5S|NC?jUYY!aH6vSg_jxzSwy| z>e2*I`7#w!G;KkP8^P5qX)rCC1s{%S0IT^MN{Oq!MI$obN>QJ%Ues40}jq-*ed)OQ0 zokC}z1bdWhAo7P2*)qiw6*c;5^l~G_H-=Xdzf}h0w4)B33OX%Pa62QqBKU6$BcntL zwaPFd_9(25IE6*At5}L;6RX4`wAo{biFwgjV0wauO&yOV77pl9Di7B89ta)6!_2t+ zBtxNJQ|ao9@wJo5ql1n(s(mhwjB~-=78dZ=b0wIsy3U5yj)#E{iuWv8(PdRKEL@*(yegFU?oR?;p)D?1UeV7~w#y7rL`RaW398 zy2m_(EW_r1Q-yVL2rE;1NHz_$q>pn)k}DHuvg~i25U}dBI8%0&cm>d6_md~x-{6-4rL7`tuO$ZTaOByAoA zAw`lnX<{Y|Qkx8|*OlSyuG6A(N;05l76`vCSBRCO>&P#`^IB`sWmBLNK$g5PA?7ES zit8rdVg(yyaP;B|QThD?WZ`-{*6cn(Z1&NQ8D3Dv3C?JJecny>pe`HVE6U;apkrdQ zfJLNZ%n%5(2}4z>3S#cR5F+~y;h3fbR_tT}zYeV?XWmtkXO^L&j;3>>!^pz3qOh!O6H0Zi(ZhFwRg#E*JefvD+v33h#b9o zgVhT8p?!-)XeQi|AHRN;g;={Yt!eS>`M2|=HEO<4)-_`%LS#^M$^g*LkNN)%fkAh# z5Ti`Nt=z9IbY~*TmQns>`|4QSCwGr1o>hTI7gO1;Z~Bn+T{v&e$|o}g-h^Z0Z=qLs zT6F2{be5(voV*k|2PV=IctmCt6jxqg(u>>KOd*3S|6A}_x+aM?%SABTP2OaNV=}Y- zL)jBIf)5(!3EaSGC|&=XxSTs7E-9D^G8+})QPM!roI4plt~gEXH&lo`Oj}qhD8h)X zFKnK6++%a9Lc!VB3i=ESMKceLhXVT#Fcbq}+i_!ZzV{MKlYB}pl_rspQ^_`w>b$n6 z%aI5He3CkeZwGL{t1E3mnfkHl@nSYnxSoSh1q#&*1SW8UzKM8E4}MN1uFL%kN($90iOE+gQ8 za)!V;0P*kL2gGre(xiE#BguX~9G%`ri7ZErL1(YgVnxqr)-LqCU}u_Wmq!MZ%#y${ z5?1Va}pF}S=Yrz=bYb14`LhaX^RNOHmiaDPej8jyV*d6cb_~C00yMCtGMp--sJtkC& znp|A)k#;72+Z!lq9Il7a`UWhzI<8iAz&fVo7fGJd-Jozg3B?aila%OB;`{&YuI=g` z%howbVYc=bM;>f0V55)r7`f z=TUyu9VDI-2Vjr zz9*@BwhdIWS!7D#%CWfm)^nr2I9?R|HY+!rcWNt6);-2pA#j)OYDl3!IX8MM5zY8Xt2)^d3_+emlw<&B$o2^Gm^1yyCS?CP>Z1t6AfkCO*rg0sk3WZM8f|qz^ufQuDScYLoq`1$x->5xwBh2?g zh_Fl$<_9G>zUU&jy8eX|w>4qPu_6J~_ylSP#B#MOQ9MolAZA`#$MqEl@|+Db(R8;Q zR~WMc-&~xJ_345mZihZN?mr?#DpKZ+JH4 zGm<(jyf`EkjTiOey}*O`XLc|1IpD&2T+`W**O?G~M3VbysAG|*kTRaShpp8qAdSx( z*$E{%jMi-=du?>V!}l6G_FLh*OkGS+3WuBPE#Q0fd(tQD%q*;$$jd47;BQ+Z%r^{R zLpGI=naNymm1U5yjGZ+re@>#+iub^DU>FgPQJ_=an}CYXNZivYqAl8atZ%~B@f|m|hO^}EZYH{N30uV>Oru^O z!mi2U&#)X~_~SOI(3}R>_n#n&4%dj<_5Up_`JNT}jO>HEiT#30>@gW@{~2DT9R+t1jQ6%G;d|o? z%uLr3ZycG3D{QUN%4w;{W2HY#>&PZXP6Zf#s2rEqbuh=P%Q0inJiMy=jXW5wLA=Mf zlRZH%iP9Gb`hGy1;7si&9|nJb?ibluKC}nb+a^%G{Q?7K?Hl~DcRan>_zDu=RzdS{ z4?2I1CWWRTSXrY)10NN_p9N8neLbDL+_e#kiw&W0X$wg`X91F*!ilW<8unRi1Ia?} zX{uQ{SmY!@?tQ^&T(JUjy*+IPzMRWC>h$47-5Ek|%_ohMheL8`B+=wnSg+Sgro`PN zZbE0g;Nw`h`9=agP9G6(JhFv+C$BJ8eiOdDFhTIA+uJyzAU1%32LS^S! z*k3Bom&k@Adt;6#K829eTQ0%{oi8N+&PiCZP=gxVm;iZn1ad7W5akUatmyU$x_A6` zTCuqn)P01G&BQ^}&-?}X7_16=_m71NpWmR>R)ovcB{)xBja@%ttT&urfEGnV@YbDi zY+>&Vf%D^u$vhm#UQOWFe!RvdvJPB*^iND_4<%Dy8}f&*9%J4IQ(X0l(0?n`K;r!c zvZ?eT{BCK4_PE>ZNyThY-JN7CS82vmHR`Zae?B^>pT#{whqyXVU{u|7W$!1PA|rNB z!4HZ-t!$lyCObW%1WXO8(5JD7SUs=8 z7sa6%<9?boJU&J`x0aDxqImJ4XUp*Y$`9;K!8I~sRG#?9;}HBlCJIO1hz zO!{ku=dLV37=N2(<=nw^^@~_^;R7B^NW&(H+iZi>Qd}209q-22fM4)=GI--`dc{wh zJ|ERCc!DXsslNaj5sh$F;U6*f848Vm#^bTkNl^T1J#Gz_5m=yBxTEkRCWYK!H-@gk zg=Ov-HuEfKCEfs~tZI1D6)k)o#h@6qhMYUwLS{(_Y|U*9CY(!w1*SU zm8TA2V>>4?sqk-XVRtq*&Mn8!eJXfmM+M6n>_-l6yFxxpuOOfEa-j3!utq&8G>|Ra+1}L$^ z{XS3>mQ1?l9IrX*o>?2&|55DX*k5ZI+(-E<3zrh9ZRM+!N{4QqCuf(dd^-)LMqA>r7}yV$koiD71EP?SL=uG}Gw*qS=nv@mJkL3MuXSJ7O`K}xleMu|$c4gXw6{`l55$YX z&cr$@61;0`Ua4c#yqRRcB#VUp5?rFkj&mlD zX0d+3<;pXK337OLt~j?~S}Y9SzebXm1d}8A6~NA%g>x1^qN4R`P=Cc4F1^Q` zs+|oI8?TV5ZakH*YT&k&Nf7Jh)5(mHBZcR{b*S!$P`0n#dnk{sq*5tgVKc2kf z$kp|rxZf2TuW1u+l87rt7Snszzmg%N8|0Rv4zMr%;H2I`%$y!3utDyO-reK0!r~u& zwMzqC?zJ)Fx9Tz#>pqcdGpBM%Khmg;(=*a3rA}sCGlaBZCB%I9Sg>8hvSpCB3gOt4Pqe-C2>N3>r&n~5 z+VP13Z3Ae|&n z_;c6DsnC6JD0%|<+@Ob>m0n?(^>N~-97Nl`8Bo=l62d8d;^Kp!5pytxqho4`)*+#j zyEc=N&_2Xftk_5!gO-qE5nH(L#}l~dmlZT`|625v&%-+XC-j2*0a`Ut9F-vedBb|r z5l*>32~ITTNi_MmJBQwk)8|4RRp7;I54a*7NZQpG!+`rph}2(EHoty47~Iz*16h*X zaD{86*-f0b9gQJZMv0XvY`3Rzw6bjN3Z0UarzPa=oK3=Pvz)B)Zsgc2qj6oj1n#!B z#8Lht^u3crCz{#7BQ}$}p6Lh`4%I|;j4Q0wxC-%ldqIA`u+JTM#U0ssgZ^=>258f0(k*Hl$jZlZ|S*N4_u(48Ld(tvojyR-2z-Dpwbi)^|oQK7SIbHcrNK=O5yy zIqy(0c#m*z%0>Q|kZZeilZose#=B16fL5FgRyNHizgO;r<0~%V>SOXmRci@)?d%bH zNh68Iv8kBRbdN~n#X-yWa&pBlhFF>^LriZob<*2MCrlGOkvY4V6)9FY>!%C`W*o)Z zc4-XT-^P?!{UzDQzAmd!>=;3>vT*mr4bXR*Jw|7X7 zSZiEjUjJJ`e?A?_sNM4*o@5r7=qRGks^=JbeiXLu-NqbWw~%;Md?2ezUNa5d*-YKP zEQ~z-it2w3p$0qek{ZCG!4P*PB$n>5*PN0wqW$M z5LCne(ZB{{oEMf$P7Sdzxc@Xa?Q<5{aaas{eKPS_buc1bfG>=cz%(qJ1l;bXCRRRV zS*p+>_Qe~H$-Ls8{mdp2#dl$U#tb4EHJcphki;A#FQCiP;0+E zFmZJo8KpLtD*8Lqk(bix@xje_bp3R=S{_cX?-&k|v!6q|cMt{NEljV)NH|~NN)u~t zb4mv-xu>heP;$!|dhPm1d?!AVcx3%Y9WE%ssT*3P;Fmk6G-5N@-if14&-dZ%J;NZ! z*BbwHmD5*_1tO)0oH8*5O$_3rxbp5aX4|CU)NSK5)U;3LitVq`Crd_Pn#FH!wQd@> zDm{;R7g|K#*Is0L?g;bvX#~c9eNW^aa$#cB31Ts^mdNp4%=_NG#8_zq^bfmB?(~g= za?JpMNs74PZ4HJM))L#(+2~s+aD)=_Bxx{5PQWIyg+xYU5g1#l;H8)goTaP@Xk;G4Te~Z$#yB0a@zpUn@6<#lZk|XV8%Drf zN?^+^7v!#FQ|S+@X+e$y`Tb@XJUQ%*wi(mmTv8CoADM(!-TR<2Cym$~ZUe2UQ}~tI z=OIyS7j)0LNV8}5mc8zM#n=_UWip1sFz2Q+b(K1ebz9}o*vW-!T{9j1Rhv+Ep}#3T`)VfmZM8rhkNfo7 zt#C{kR!9}ZXTda+`B=!5VQ`EC>M~n#wdp+mz#@I#ckm1vX1_zXvthW+YZ-=|*nm+m zK#%Vnfik}eA#`5|cx*fcAERDy7vp9CY7P)Db#1I3VNT1IK7}p)l6==zReHd(kzNha z=Wow4!0jmmc%Z8oH>RCHx1w-7y;_xx-}VLz)n)jB!U?b{VI1$$mr2|9nv>QOqxmZ* z>*y)nU$7wBLCA^Sg~WsLB>u)Hvc1U=*GW9ZEvFx#@#O$iDKEq{4_VwF@(R^VHqned zpJ~Q^8O)fVjyHlNXkbMQ%@Z;NZhafzZl@9@WAv!2SO$%C(}r7W(YR6~h0b}pK**b@ z@VlR%##dGk@N#bf{%~m|595!5lvFLAD2xE>eS@%gQ3@V(yiF%xk`!EIV)S+57tU2< z5+t|=k=T>Zsn`AQRPAyKJAC6p_TX$)R{gIsJ0Nh8sSh&9z5W<@y-k@^>?oqa9yWaM zu^BjBE{5!Nlt&2*F~Kd{MEgTy>6aVDG$1sR6x=^YHZCuMcE{)N=TI0tekF7tHwet| zQx~X@R%9piU4zEUh4^{06^ieON4C}-H~)*^*lRO^FSt*G)~_Ze`Sx&cQIfD54aeE0 zpXt*FyTNtm99ZOboD%f{CQv1ZJN;V*+i!kE8Q%-IwjdKN9uHy1JRjWFCNJPUKQJQn zC-u*6=3asXz?7?asq6{*=aj&vL(atA#{x{PZh?NZ0n9$x$0#YP;CT7<#BIqosMT_( z!N)d%>5>LGm* zxMw0syytKlQbxQcI+_ZM_Qq4Fng5$QT*`&TD{GjS1-bOv{s+WkP9hZVE{5eQFUhRQ zf6&}P3_tJBB1__hox(|uM88iWYj#>-t>CTpQ>(z8dsE89^A@0SmmG6%`)ORRq5*AD zvCwhqI$5S=0H!SyKz}HL33~8fnPkH0oY84dFa(mTlp%Z=V?cX1AgFJy)zcFhusbS;N0C zahSGb6mC|rg%*<>9DV;YDT{tdwv*GiU1Jm+EDXmxKP319i+yeu!UOm*XTy zHQGMmDs+q!m}E)8x2QH6ETi&>#5@;RdP~F`KKP2h-l1gi&Z&IlS2rd@vj%LPC{Dj( zjg5C&!PhbwZ>tp$D2XK}JJ!LEf6tin=Ic>aa9Z|@Pr&h`yYPM6d$@f!5RTWZ7pPP( z`gMLfeONPt#xB(&N)CzS%%2t-&>bymme#lE{xy+&SRDj^R}^tIrfGOvI+9yf?uj)f z1=wtu47|YSa^LpAecz|lKr#ZY?p&pbkwcus>QMS2bq-_2RFS~#JZ#%1!RDWjM&ujdrwSY4dAop$AHNQ-wUS}a%KOAE%>ueAe$ng4 zouP4zBRUV4;t$|!CzRNxXlm*BY#_Y2px zOvlBO_JK+pPl^;SVu$HCe0CA=zG*QkE$PSHz*+SARV~!YJR$7)O6Wjw3!ZTt1IF1m zz)bMm=H-5bN|zQg11S-Bs7sDDi#7fII7MH`oW zn1=(&<5g>R*2r&ATS>KUbWFc^{==r^8QTzT_;Z-Isv* zW@@b5zBcre{DWh){OFqPB}8ldR?0W6gwD|CbbON|EdE*vGiG1KW&0zkttzeU6r?Qhq?!fzUr^tkj1`v@j0^)0KL90nJ z#OLPVn3-?!bN^#}eKwBnips@*BZZ#h$0y)?r!;@=<`Dktev2=q!f-&ciUtqX;_j8t zarnC7Se!1wJEWzd$+V@A8kSFn$*K!IidwWPC=@0i)B{WR2W9mnkX|u!fytS%8077M+QRYs;S(l#!k9D!X0DpuEnXr6&SexDmAfg5a#F!w99)0cW9q1 z}j zp8x)%IaU|(MPejTpz)zVj&8M&QN2?zibdpyyj=HW3Q*teYPQBB( zG_=n`y;t!1#9S?VWHKI>jML?Rek;as!Ku_JQvnG<;oRIsbHVce3!u~^e9WVh{ENj_ zICJN2(DYu!TTd$?)?35)+%qcWQ=S~dhCRkYhhjGCZ`F!bnR+l{wmExy<6$!59uMtB z=B$2nJidRR#5S(Vz{g?V>BO=rtm!^OzDj%wmQOE$Pr)B7ir@46w9qpCNwR$T*8ULQ zu~V0~{dkbycsw3tmFB?K10zuGbOG<{a1`E5zC(O=>GB=X6|j5dD70P0urg`4v3;Kf ze!RVqpR1O|1>~;aQ~v4m?Nwof)x3{;b0%Zh`3bzVmpCtOIRwGC1pmtEdyLa68Fno_ zMI*Gd`G!lsVUnaZ-r9~}UB8IE6LFB$_@6jCIsAU-}`xC&AsvqJFT(bC6y$a_OAkKn?He|{ z%8b3GyNtE7?S@XVXzZ;RPj{Vr!)A-@Fk3DGPNrUmq}LQ4EWZe|Ll2U#>PfJm{5Tk$ zTa3NyH?Yp}32aPUi~tcj!%zQpXzW}EAC@P>FcUQ*S`Z;Pk=%%Ta4c$^XUko_Y4Ig{ z+ZngmH2%N!I&59?0g&^|S zrQd7eYrYd*sp7zo8xPce>vmp;?B|!BH{wsV?BdPS;wa`eL3i1gCE^*|UWs zdFFgPnyoj2q%b>pAlU=&Y7*IVJ$~$r6nl2d%LMjJg%R7(6%5grHnAU>WY*#5TX1^t ziPhgep7*}DpWo80fdP7f@X2TvZ=#E_-B*iboB6*~v#d|p$zAk7I|9Zg@epO>P z?6|oCESzGv@#`CjyITOSS$B;8yT1+F{nzt}Ll*qdN^|U0e2%pjN3mwrvV56IADmNW z*bhRlQPAT!x_0+p2p^kH(>?{GXV-S#>B|;2>)T6s|M4{(eZ7s(@SVps>%4$<@gm|o zUV`-;J&)Zha)Hj_*8HczRPdS}12#{G@kJU{uqZf2=yLo=FJDgQFTD0-nXnaX{2W{U z-@sP(Zt*wRU3|3kix&!`|sT%x5#t`K>2g zc}E2m{$Io-extxAK3QJRt1i3457*Ty&)HjzwYy#Tz{x>;&I5BAFx-wUx~Iqf8B+@G zU1BiSYdins%|mwn$Vm1;*addR*c?>faTwWq%iyuA1zq=hA3S>%g((F#VCc@1`)kkQ zrItIOBXw4I8(f2e;#m-!UB~6NO#wTLI@aplCH9rVS5`e^5Zs>6M^q3x@ftLsacv(- zuKf&eUH7xr#)n|c+BmTA5+}E0Ghm$8CU#=JDjPLu$-hp_U~2>hd_-O^@s}%ydx9J8 zf@Cx;d0Y;gLUxh|=L9xPRL=el`~g0jk8#T?C%}{qwwy(+7vHS7n&08j!PYG*f&4Q+ zFzsp}Y>J%Ee!QQ>uB|BsXTh7~FB8J%O#cAgqO%aBS;`uGHYktvzQAw!Q^4oGj_3DG z%jAP)INo2zg-<`l@GFXkmxm;O5;FHDWY^zpF#Y+E+N9Os>RbBk*xpl+v|A1A1*aMt zUq&tDzJb@&23}T6mgkzpsfzdw{cV`Q%S{lhY zWi31(Y}u-(+XZ$Y3QLpi_+QuJ`AmT!eK~bMpCggMcetM7cU8CXv61rSbH^%|4_^E$ zbT0f9dL!@Q__n`r`rrd}EYxE27b`)axfs;MM6$Q_SMm*KP74m67G9&HgAZNU&RhIa zC_k|~haWbxhTr+$AKp9SG;Fyxo7Z^1i!><7eKZNT zsg+QT3B%}+x)|-*`-e(@yi2d!on*FG)L4Xu4Kcp$e^9wM9JAJ{!n?{ix-GwkK3Uex ztWS}K`mi6gS7ZsD!u|2_MI(~NPld31$FaB18oiumk*dudRCkI2UEKYEd$Fb+2Os!T zkNFE=p_nWdZf++rHNK?ADU!n6=}iCHd1%+N7JGX#@V(noY-N@4HO-+L&=Uv0mD9Ua zkC7XBf}VL2&P^JtfQJ2LG}&to)=WKt>SjRpbqOy+ozTKD3%bu)-!8 z4SOD8cw{C9R0~{@Mm%oYl!DtdRbj^K;q+P1NOr?l;Y@nE1zR2Oi@yJmfs^*hxVtJ0 zs?Tho>DRwd(QHjf=bs`kio&Xv;dFshI`?;`HhdYL2DYQ5VAF)l%)QbmjNTDQ+W30& z**S%D)comq$oMw3)l`O(z%7hPuO%FUGxWNshzm*7fLU1vAUUUou63FYD=S*bBiRvn z)H{heWA7|@;;e{KV*p4Mi~`dDfhY9ohCuIlknsx|Hq(HN-+J7j<8(j z5OqH}2CfeD5SMH7;qn3%a-=&Hx7B|jqhoF8-nKcYJT9B=kZh$N-yNfI!C|=BPZrY} zWrZ{NJha$sidACg$_^z5G9%e}w9_yEPCEUehx{+Xyx38!jAk+usI?D{bM?^N^_0YA zMu20-8RE7$6S|&vQn5~DKA~uL=^VeMAj+S^JgxPB(}NbkoPW(6|K>qbHsn*On&Fr^ zaE_S1a071g3~=4N1BlRJBtB;wm*%C;zgbD~{^a9y_O=BWu_TlBsr@Ctvh47iLKJlh z4y6&ZgYe zstuJ3t0uh{WQk2j5xn}Djpocrytgv~W1a-i5ueh@xH~@xeIpJp1HLn#Qo@Occsk9? zodL1`A=Dg{z#~i!IWr~={3e&t&JU`zUnZ1hn@9@Y-@|n9(N?frB1SE)PGBqr$9`^X z0L_lQ&NY{ep?ke$U|~=MGp95T&-O3IiS83^^L$s6nwz7@5~Gp$MW>iv zdOQ<6Yb?mg71fO2v45nzOAc*efE+)fOO6@4l)XE=SUCGjkZW7yKuciU)+@iHQqlX! zvLz+dGbHsb#hq=*`({iX+ZbaDf6p(M{B3)DpCDZ^(ni4*U`--@GfN&P7dF6sdB1$!U|k3)ok zKD;P6IsB0sDY?(PxAitPT*%Fqpssz+O)WuBnTOu&8f2N5H*Fj zV?TrWk7UxJ)JbcP>oMy(E6HJ>AUc@891i|+qLY(vb03^j3Da|orfgH9Gr!!XA!EB~ zb73S#PqAhG9X(78J6>QMtHLMM5S){Hp8iU5!s~i7aqDOhwZz%cpZQ_r!jTyuzVIB3 z`naEt6PSzPa|_7D9xoV^7XbTj=5UUds`%FCI4w(*^^<^?o8f(&x#vxbNiiIH8Y1Es%UJo`OMkYpCMY&#+zBhYm`paWj_A zp?>ifFu8LTU9tNH?mlrCH&`~4^p`b^P2U`BQ+Z47&8a1Ii|VPmL^DZonhOhWe5PSH zz7UT(2aJ02mZqB%NIP>KPhG9UXu)sZkaq%e*L&igA8PpDtrB_wn`w=SFZ=}xBMkCs zy!9@!XYXoquJ;heeY%EXCo;k6jX3^Wt;FwNCQBz@9!H-z?FKWmAJ++X7N;U=`M+e34D|8UhA z)#T{EiHy2M1*yNdoA_5LL-Ddpu+Ph%s85*yjur`IoP1-M?&C=EujDf~CUOZ%X6{1Y zH(QyZ+QXzQa0&*-a7^&DlT5{K37XiKOLYYnY?JtO^lZ3F7a1|IPGUX%72!(?^7@J2 z5_#C@rw&qD3&Gn{j_mW9js8=$aZ=9_+V)OIV3@9oR=JF!x5~?io(>`Ek62D^@>&{w z=Oq5;txKHdJ}TQA{+Ql8ciFuCKXG(6du)f=YhnYhEGfvBUP{*X|6>k_m7q-RbK%Us0)O0mg-4Bh z@EYewZ|AN9c=&>}T~WoJpVR4Mt2pw$OqP7uoJ&J&tfinSRX8fqsMcFe#-CQaQmHu(O^C zXI63VCftRKRX6FFBdhVWOagq#6D&n8cR*o61WZ43jH@{uLI)zwaw2gM{al`a1RacO!v|Z;e8M=FdY5l-*BPD10;C3!1t=WCKER`;@R+KG~>i!DTblH$P;_& z$1q*r?CHnFKS~F7%fZ0Qd=N8!3m<0L5_9GA^xUssq<4WAyf`OoZu|QzCZ~_W{WV+B zJGBsJo&Q2Eu4(7^W&81~x4R&yw+l3{AN+3BlopjCc!y&gTkgu^GF7=%jyzhf# zhe{^3uzrCP27<3W=1YausbO#_XS_6GyaMy{=BKK^w0fsO+2=kUpmcOECWj5;3SlCA-a ze&9lyH0*`m$as8ebp#DAN8$5jt4q5q+{)aZ{o~@gB9QJASmDcN$nF^V31VU5MZtRS@S5uNqShugxPq}rud0DV`o^^4uu zbMy7^u$%#u-x&jqu0p0#V;#PE8&2MQ_9UsBvd~aW4#%9n%XQp-je1s38H=##^x*7| zsM#0=^0O59iz|6LM)=*#>l5-ZE9t1Kdjdi_q=az7Y@wPbidX~K6>f6TXwKwk&M zG=X7xATUA)=FdQbt4BavbeBG?lOZo&%43M{6f$&v6x3>@(65qiWwPIE$xewn`e}(a zXeXPJaTo8!a?y7SUfHfjSk-=btmO{UE1T$t5zC3ktWl`{MxE80RY&!l zC-M;k%GBL!EGej;MlKYj;?x6SM9Qd=;00%xe04W%SW<(nSET82D~y<_H(_rP0z#674hnL1JAhl>WyNW~Btn zgxA8{rMV|)7Y|1%%MdJI zcpbh)^Cb69F^PLBgJ~Nz=yLDP*cNaa)5h$fhT%J~soaM8oUx+Aw%#nIVU%)563M15 zs^C1aRdbhQGSDnkhL2gCKz|Nx zCtETW;W!M$lC6(Le~!IpnD{^Rex?GLSYsjZL#<3w=Vs8p!O$wL^*E7hqLtN%&T=dHk=`P{VPZJ065NAt z4o>Ck3ZKw-^Rn^u{*ySR<{-@YW&?|D3aQM~NA%j)8p3U=;0mHb!F!Gj6nV%p>;9Ob z>f%1o&Au(YxUf^e@zrTqL_cLmXQhc96coZ#U#Zkz|QL%pp;nBH#88xsJjvM z(YiR}^Db2SYl`{*SUmD%2BVsK6AmnuhsLMkWSrg)a^PnJthl`kdRMN1Ww-8A-NhsD zzWQ<$^Gb#47Ypc%vnr^zxC7)`tzlMnJKX)8|?4H^h9g8 zn6?VuHu|ByY6IPswWf6YTm#%I;X`_5jEG!XI@lTnz}533u;;~1;uN2WpFis1#qTH3 zU{nNcY5q(9epkUz4GWm)Sjp^HxrGy|%>eiKfI^Z2+^AUved`5|y~`i>oC$(_#S+HV za4)qw6i?qd{$lR@_+>8h;W%m)3%;D!lku=oB5E#mhPIdX!aOGt13VX@pLHzbJmntN z@-F1^<7sfM<~fE4jLBxf(H!=D56X9s$C|1m1kLYED&Op5v~K`$~POJFSv*VZvM`NuJsT>V9tp6fy+1Ub~EmXHF39&1s~w z{{%e!% zAJLB?b@ZO;3zJt1bN)jd&9G{qU&L3CxPvMXeZvcEPN|Y(8q>J%&kLBT`;xelHXYp~Iufr7FGh7!wRbylOm{!&jr&NxKEGq(Hdz}^zfXnbW0c|5jvxs0 zFvpJCSaK?*lB%)qIeYlP$wrA`URxwsR7c`r0}=M6h(sN~?ozgD9DKa%4cb4{ac|>T zoU$%P@OUkNb`>eek(~s3I-96mQ3knn?iAH|Xo(xF#Bk@Y3q-!nnI`f1bm#E<&^^Wj zzJ?pZ%CDNBR~$`0OxQ#kER!K>z>KW0`az^$#M6T-9t!i;t!0Usv81(9gypaG=!s%k z^o@N><;zORReNzP*;^xO6f*{mD{i=Fcdo!1KP!7->_yVjOX;|(H&kZTC2~CU3VD@& z8Ts<}blm3`-0{c&$oV*$Zv1PDJ7pXg-_c%BdB6&cM@|CepRKsiBZIk~bX>G?b1^>3 zn}yE{*AbUvrC`|cn$*1Tga4SVErf3#j9^Ol@~@=Io%+v~4%=g}+h#y(Bx)oMn$ z{loEEqZ*%)D8~o-_2A#APxyXB2<+Rc4o#x5f`eKNUgjL3gTdYq$ZNvyd`+y{+YHUa zjmQVvA&ApeCLd(AxUaguA#C(hVjmYkf}SM6$MuTDV~iMt7nBjBr(5V#iAeGx=OQT* zdVe2Xn1Tsu(J=F<0lJ*`LCMYswfj|$i54%3{jVUL_@fG$jS;ARaXOeems2_^ z13eV#sEX-MdTgmX$#NZ_3+~9nrJd0ZYA7Vqr+3%szI7Z9R(+4M}Iql`xhR!%AI6BnukHhUK6;oX{hWFrv{65 z$O^gpw{(kr9j(6ijII&3D$@A{bhhAm@ZT)S?wi?40^Wb*bPaC8v*(XRvQ3UmrNlNk zbWoDnROUeEMjeHSM@7VBs|&1AF``yKAE4)O1yX*el2b7d?%Rw9=~asY=_B^^iIOD* z|FlHk8`ab~hVOT)c_KbzF%x|JX zo%NhT_A$5|eT`dLtc^Yem&t?^I(T7G6=Ygbavsb#r6<<9E^e|8aZQ#7V>GZw?t;X0xf&E9m_re0dD zzgyt&q%eE#BPRTxJoLApVm?1Th4=S-p(}+m;N%S{_)X|EUYPS8e=n=S=0I0$@+rmF zC)9Ykg`;`C@fkH6b%kCRTZvohhrxZ_d)#V=6?nF86r9k{=NR>sAb;-c+D$Ab}2FF3!`)(&S!I2f^+b?tCIe;j|{rwKl4@JCkxxPG@j z4@358^!SNyIbEayTu#liul%!VjW5#I-sWFU5tRLwc;h+Wtmv zekc>>rFv3PjO+3qJR@5BQ${59;Tn0On@HmD~iu zvGs>YkN!+{33Dbb^^aJPz8-EbR)faX_N4n_9{K3F6dJ1^J6CSPTR9#mD^R= zVenb-;H5H6rn0#6j2iT9uOQybQc0+$Jlyc~2A$rq=zVxCZ2UG;bk4H|s>g76;Z~X5jUHH-yF#)m0@F7+7ctfunp8@Z;0x#b5h)y#| zAfFBj5bC7c^yFttyjZ>qsbLfD>03klt~Qi%+14~?$zPFvekQZ{T^AJ}tw8c;oGAOS zCz3ir8hO@ZhnJKtQ1jc9$;Dn5aD20iJX_vHKldcMMEermAnSU6qi@{S&f$)t+gQ((k`mmp_U4u4d2*h;rx zD($-+x9DWzShG^{uyYY7KGz9nF4+Sb4l?kcgf?E0?WI$)oN)W!jbzsE|9e8@iH-I* zf~yRuy^}5W2+z1TQkUs8Q8-cM93Xz{cx1#9siWcz8ZE|CYex+dvLTM{iI9L*lSV_; zA$4$1X(yf8(jfhODV$8w;nz98$Ei*_{K-vDG(=2`pQ4>2nm(atYNhA034n)39{;RVRfE3tax`9Zk;Zo3yi~1d+upe zdNGUA6f+F}6NWofw_@P^2e{rSg-Y9O#ko~~se4WmT3*nk-n|=W)xuWXQD%fyhGD2> zc1{#@_bd*5=;b=2pTRg$Bz@a*kj#D1OS|VL!)5OZfU0${dT0h(oMdQN_6R5sO~Rjh z@6g4cyqUW-HaJ)E1-T)9oBIaV?5*F&1=o)(JX+&YM?>S+l=ltdOVv9wp7U+!3ehT8DAyeIECs<}6t^Tb}R!-AfbV zUvgK>B=|euo%sveeN_3~3T(I1;;m#8>5&j%;BV~*qLeWFw)hRy*4uGowI^WbnrrmX zdlkN1c06x;HVG9j=itAcb@)DLGTM%6#%Cv``I(LCXm)|%aydg7yqynouP|iKlApMH z?m(HQt*|;dHW4ItX^=dZNaAfSgZGUiq0m>BeWwSwU+I;zN5Hiw5)LabqE_w*^}+c-Ii&M;_%YSi`)R81y^81GG6zZpFHXA= z6pymUy5&Zgk?cl9+o z-jz7F^E!OA@TDpCx2Yh9h2GUyNtUiXBuw7KD)%np6jM&Z7TF$fJhL3URg+7n^|zA; zhsU#*{xIw$-I?shT?_Ecf?G7+RsnxW0N%Dwr3(ahetn=L8h$>3pPQoSA0xqKYCQ{^ zx)tzU#x-g)B*i_h(!ssq({Ni+HyIN0&L(^GL4J`YtbMBukF>_%hTGQ70lmUw$O2#;N};`d~%!7kidxK z_R*lD8%G14n@CKKtp;b=4thRyBJ}kX;)$9PTvaK>k5;V4@m~b@?lUuVNRB284EMoG z!3+Gi-Ij)sY3R>SN4dqGq;&RM8h%CrUM4(*lm}DT6R%&wF!j6GkUf$=kY~u(%8KaX zff>x;*GjZvqOo=ORy?|3Kb+ow9jXoVfVG(cbGo#^?bkfe+E|G%)@+8+XFMVCMn9HG z#X)m#5`8$Wp5)5yfR+>5}DBG^Y^{U#+I`ipQ`&pg1g+jzBLIGFYaz+2lwa@FNL zHfRbiSu-u%ZuOD7eX0YZa!!eAq&V{WkRGdErr5~P4zJy87zCwJ^e{`+!O>*OjKC4idiqDn{cdpB~ zvF2qNT67oT=*k49uO*abxxU8Vc5-ye;a-O9a|Q3Kl|sL}JY1iv0IzG#kim`f@yKL% zeAqFOEgN+UGt;$Er~4~Tj2#I!ug)ngBt?+-h?!z_TB5BCvLpb%X z1TGi$7B5$>#K~(@IainYcyi?i@R~6Z|Fr^SUAG|;AA^{Yx{|DDXAm4ptc48&GugP< zlTf>~gS5MN(;wRkDXZN?{I6WL*r0fm&bK=WHs4=RgV7y$yu=e`y}JjF)1zTy)HQIt zs>4crJIDNq$cE)>q*;-JGqPHha8OAMOr9q*=eh)*TGNx>wv56RqKWwGh-+Z#@%Qp>}Qx% z4Z%Tp8{2|)VEU)Y{PUZ7kan>T_&8~H*ujx-?z#j#T42lEnHCJg-i{zc&X>sW5mN9x zHHuD|l}Bpi8fdtmBrhA&g}0p_lj?2BIDB*{f8zZM)c605yRMAlZ}on|`3+Hcblot1 zi;!*BOdQA8De3avFEv;Vr6I6dZ9?4^=71cPW;Z5OTk`1{72IWwGo)Mb2HsvR zi9hlIqPLs?k}LFB3QW6u-e2hXJOwN|i(#qcd~&2&aCQgXWfu01fsBN2@Wi{CBy&f> ze&j21U2hvqSa%5arDc)QC2io~oX|d(dge9G`}x{pFC9I{3TVq5Fy3tZ88U=g$WR_ z_9dwphzGk>Kba$HF?6`LHa_2Hi4S|!adX&d>_s)+e5q1dY-tvD(t zqrIIp-;RfqjqlO#4oJ3MRwD6rqIH+GCF2+Gq^5{WS};uqCXdRY1f3c9zPSv_rfnmm z_*h(+Y>&aOiA(Ob0^j6uaH~219z4+&cYHksfqxINYhI7R{+7H%DL0S?RSbj$CRbqS zxkTtwmlYct$kWSKVLP0o4jaSD=|P{N*p#WmC`Uc<=sa_Az=b$aib)5@2pRFFqsJgF zWSzJ{^9eT2ZKhEpRK%-g-|>_0SCGbgUFdy}G)x>PaVYCy6Ysl0(Fu+#%W38&wS~a# zT^;}yQP82gg2i+khL@wxfTGYG$cwCm{>-+Yas<>9nW^%4FSDO0I#Pr;lSE?pzpSaUU`<%o#AU} zwNx!Vh*(cMq@&SfyflsIES8v=E|Xld+d-$BEXl0FAM_U_k>&?QT4r<fnuC23F9%Ka*~mH`Ap;F+6Zih3uTk;`GB)#6Lzo0FNF7#k9-Nx$X?i z8o2_FC8fZR?dsx2iv%!;JPw<#jU!4U&MBk;f3i!wSywrJi#bS(@&^F>=tDEKA|-*> z+i2NaM`~d!;7)oLHAw(VUkG{U{nqF^XA6{uZWhaZY^8$_g|2lkRY|zRMH>G4IMS4t z^q<^QW=cw8-m;Wj&TnPoTbrrs(lL4!UBm*5lQF@z17kxH*dNtZl8+*JN#e?Tl>U5> zB*tA`GUvIur2lspNzB#-64gbsC8uYdku+&)O7fo7(BFb63RI~h$NDU?)fBObN~u)d z5W|$Mav?|6ip_7#p*3AyWb&IRz-KwdZM!dMGJj~#)Jc*Y_XU#f^*Yw2h>E7an z-?YRHuWe|gun$>jhk;r9KuDEI!g!C(@cj_rAvI#p?2kKK8!bZ{V+`qXpE=d|M{{## zJV2+wwf6oBXK?rk%~~zrGA{7?Ov(ziq~8l$&^~w@zTnhICC!0u$X-DuL7(orznE<+ z?Z<3N-=9@^b_EN~Wx&YE5jx&Ba4CZvSm@YT_P%cj6ouHKujXv_+@9fdWwc*2B!k^F zP)DuGF}Uz-9H;EWF@O7U$XzXB<=dSht2>@$56tJ*%s_Q&Wlio&;H(W}MG@pL5L7dj0;b9v0lY6JJlR^WB4 z8plj+hVjqzqOeiXo-0cg_^$;%%xLg!T)tuif7wUiqJA5Nts5uc2on_=pfCW(B=^I* zg+o|HizdW>(S!G$@$CDU-Pm|_F#j&=p@YKijp%KE41bo1YxS%Ch-SqUi%!K&!F^|Z zm|IyU3~5MUNxN-C2}c}g@x)r(t+yK6CJdkqWz@7iBroqgvpTa+`@*>?iC%6MIo^sEJMC0w=yPT<6KHG8NBIo3Ni2HS> zoo{rE=L54}vrT6H^z*R+6$Qvsh2~OxtZ@dfJ=0+rn}F%|zHDgXDRwYX85~!t!`UH9 z`1gy5-8#VY{>RJlP|79F?-zLWL%_T?7(6!0!@RFkFyVJ9nxr-Jx`A(b9mhTFL`E~Fe0_;K^Fn2rI zsAtjK45^u-Mb5c=&x@a2_-9w#*>{FbzU<2`8#aiB{AUhddKB1kOYC4K=R}%acDV z!0Gda+4}8%EDh0{bt{Pmx=D02A)o%@_Cxb%q%=12U(^JE#UpH}CUj+{B-t)}I zRRMn8&E=9jOqkP;7H0J}099{mz_H^d%<4`VYRs%_P|Eo*U!JGIR0LkZ z{gwT&Ej9+1ydTOc+CHJYR1+@xwUDh)+{lJ}Eavuo+{ga;U*N*3qBwEQMNFO*&CKg9 zSnL=jwpTQQ)!H9M;bX9UdJ(9sCxhp@<%Dy_7?M^4obbaE4`oc_)(z_7YHA;{b8pme zJ11!2`fZ}+Z655sW(%%Ati-zvGQ(TebNGjjm28`b8$Hqs#^}fbrrZB7ZV75bH$_dB z``wo+&DF@J>H+&V+=e>0jiE+qeYzx)M%Lm@&wuBlk!lRH*(Hr*tX1LIq-@r>Yyix@ z%JZQoMq*FU1>WENu}<EU8~Q*Pktv;9>nu6#Rs{JZh&Q19bjU_08p8s$Ua@eEc9^A6w<1zW+ z7~K9(15ccKfU=K%aOZ+mm}~fb-hJ*NuJh>!?Gt8kQ z+mT6bl{0UzEZ(ts2VL2$MgNu_WM@nj@zx9j7WwKi$6T)9!8`Nm_=-~IXD0aTvMSgg ztuS`6wTIL1Lcyak2^~x0*}N@Eko$B3&51aTs;f=dE>$@^Gf0Pa_9>!wZ#=gn_y*dI z+ki4VXR^(iiEQM5i+I*^iPQS{i<4hE29p(2xksPf+5QPKT8MHPYAk5GfVX4;YQ-?o5Pr6u7&cMXQ?D`A#E5oicV}4c=L-DX@#jA<(9^Q z=9ZhaPaFQQ=bm!(Lw+w6+*trm?Hpl&&^MGeXRG}*K_e4v%Ajy1mCG#|gKm+DZ26gI z^sBm@UM-$OHYal9albV%#Z#hgn5x^Qu4DqS^ObGFtM~e>R(1PKb zbpFIb9KSUNrwOcqRmnnsM!*F&`(_MTPwvC!v|l(`Y6==_2_CBwce?s(C_H{t$17L+ zqv-dNTCK81Cga@66zv^Zy#91Z8a)RVEc8L`#mC6{`y1N)=M@WbR>OXClGql_P?j)$ zKVM_S=+~0Ltl*?PH%Mz0Bx%?4^{3`h=H>qc{-p~v-O2;+O`*`070tGb9I5&CcW&9X za(2nT02LleQ_2NF!;?CJ1KgBx@R{*Y^)eloJ?C~TT@)CWnXkkmm9o}BZfXmr0hV1>(Fz8JJ8M#lDbd7sT zhZKY8_j4!7>e+v3(U$epa|Ea^a$;CWevFT-E^wMpuqz`1FPL{qOSw6P6Dty3Fn*J^d~ zt8VGx)p6bYz@JF^?GDUTX9axD*$mSPhlt}WJK#ib6keSaOhShrO-;$gY5A|v=d&%T z+&Ikt&@*HqqYdcq`q5-pBPJW8Xd0K`MWwF=wR_i8V$Duees(-lS1QJHE{&`hmIEec zvXEJZ+&n%O{RhZl>Hs^6J7C7pa6HXAF@^S4?5c?!{f9fT{V6}HVi|9oXw1Gi3jVH~ z`>ge70qd>q<=po5u!842oAX%=Ti$rVt$uUaoN5(_9TrAeakcd09`OdY&q!_E7)g9% zJnLLrg3nUA@lx&`Rv0xKPLvOWmvxG8*j?ae@vRX0pDIda{LD`E4ytt+^&Q6^ z(i0JaWIocHobw$vhvl{qKF51kxb;i69aIb+fDz(K63 zs)@ynspFjP9KaCu&5-iuBt8$cgPUw9H!$84zFb=bJ6h)p-d82`9j}QJ|6;OTW=_6t zZkQf_65gA-p=)~xU4JZit&i;I>Yr$m(moFC)P~`JB7bNUd^bvN(Gc9JLj&!m;nzWg zNB)Lj(DGEgUoyV-oSF!vz07OX-#+G(^WSl6AIHPTJx4itLlf9F#{nw(PNHzIa3Q-T}YO*FwRk!QzGyGZ{f8R}`x1XX=FTVoER?GpNMW{l_rMbErNM9bLcQ|%OPBA@)3{z zapzrH9&jz2IhgpsfSCvRb6z(mz@+&ptS;jeyU^5MV1cQDtmjBj5c1p&As(WZut)qk zgJ@P2EKflZ&S)Dt7H+JOhm*Z>aPL|Od;7!|Dp?s@C^3N<^&#*hG!k t^uku3+sl1sv2@FD(9u4gxQhM|H|9zXt> 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�@E7C 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

  1. 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

    `Lh+IOW;jpxjzt2kGN$wM1 zZJi_~{`O*^JGU>LQ3?Q)QA3PrbmaVz;ac3_*b={vP7f$0_{tr76 zydP(J5_v~b4EotR@%6=O{Hu8hANXtlf4;I1&&*lHa|;gQf|ZA%U16T+lVvVwIju$2 zjy&#bE6slpAwxHySm4hlqP9#YeyF$z>6tckSeQ4pIk$^8ZL*|kf@9jPHWh5$QsC}i zY5ukA8BR8ryamE*IG!a}+E~D4tnu(h*`==~-I`kILwddf_)%nE3{{nfX z@_~d@%peJStB8toHgSl)L+Vs_lD!wBNbA<2)c<`M9!t^Wv{{O-adCst!LGP*VJ~Q` z4B~+g{P~enL9DrJA|H3q9YbP%k(MGZ$e7StEF06B)o#yZdDB=s?W8uneT~lLWuF2FN89iq7o10YBeM zK}@2oI8ex4InCD;g#~svg6=NyI)_fD%jQ{ifwd3oinI2LH)?gj(n*^1jQdT{Eed1L zZ!QtKTHl#jY6?17J;uFS195QpYPix|1B$CBgQaXXv^E$Ke}glqP*M(~ie^LplIKFV zy#jxX4@CNVI@_djAFG~qqG9I_B)y+8TW-7Pkxc>gjkMzu77e&GJpk4oUxz7IT*dZs z`=FrHjQQS8Wv3QJ!kHIS*!9cbAnl$qse8~!&Y$i92m5T1PW*6uGrNTBP71*mJHdN% zp#it9{SQ}WEAg*3gSobl*A9}N$|D5VpH}B;X1u|WYF|BqvRPSt;L=JM(q@D=F2f*+KPaac>lxvUVvv*gO_}C&{AEl4WF4 zcno;4#_2BDO8(KZf!b#z& zB0U})OvTGaqTR&ZIP^j#x+bTx+rwPglK-}|j96Fkz%@;xUlaC-54Wel4S~s7^R0li zJDwt1!uf5;TOEg$^InM~vr5=N^LV!L;svrdFhk%v$J0+vU+~q=vzXhI!HkXLv99(U zON$Rc>h=O}w;X4s=hx6@0~CNgdM&E8Go@a~oayntQaEImL`VAQ@VtPFXm~z_4wbjy zr}sa>r|n%Zy<`{P*t-GO##6eZLIVb^_hYLrj~3t7_7zKCmBB@O7)!P(W|ffvXgp$| z;7(adqJzD0n(;;c^{yH0x-$V?1`p!)ljLbwSOv6)w~`}E{^9iM(OhI6#|K0$=63=F z)_s{QZ!Y?(A2pXmZ^K= z?cf)fH7b_LT8eR6S|B_9Sc``4&BJX;# zrI531{JsDr0z+s|nit=gorCt)A8^>Aqk>=F5Y1zcVrO#}_Ae#ewmlb<4z9w32N(0T zdmM3Nkq4f1T#i+4b?iX35-F3uEPAx(qUdjO97vp-fwn2{N$op%+A+*W=$)HTxi6_S zICBx)3nk(c$(JCgTAfxsSVg7AoTV{)fn^GN1B*f9>6&Y;kataodW{=HRhxF=w&&%f zd|Vrdgx<`mF$L&yJpebDUuJ=^mr19E3^i~XN!m@aVf}=9NU^oXvXk*R`R)Y%wQnm9 zh!Tpm9Y678$7+F_B*R_&8+m8<#JbaJC2;5I9J=PKJ|Dkf6fWQY9p>yeo4KCA$(7M0Xj(9v@?0CGymn*bqB$tJtPFP~bhDd=1>hRBhy@Iv&!Zy8)m1OC zM3quie#`W%Q&d|zMEe`kbrB}~OkNUJl2@48SuVESoCq^66_Tg3tdZ1YvF7wQBtce- z+T`m{SKaw^ul9NIucb4pt+p?3tyIey<)fDKp{5;$#T28+=da?O)7Vu;L#`4r@wfwh(RQ<7|etemR0k_CA z=6xS+_>}zye9X30e4Xz|RQTG#5_SpmP)B>V;`tn*7yVAWN_d`)2+9>5o~KPbiu37% z0SUx1YAT;|+>icixk-#4RpODa$3fiwka@S|vIPwaT>8K)kZ}@ty*97s&gTK0Mp4^r99kM>XGn%2I2aMWC`{ZyOZ%F*Q{ zlW?amR$QS%g)crI0$ob6^uZQ29(G3p240e(A9DBCZm^GUGEb_AG?yel~Z)a~R!PYUE7E48i8|JXUW~O=Yx#`OSj|aH&rRJnT9{0`^zo0JUS7 zc3qZ+wr7YkrCP-gpSaRNC%1twJR=_SebHTJ3=Z{{rAqT}lZ}ox?A;G3Dl69uviX5z zSiTH>c-vfddy zecqU5%p5?yv@H3|4mm#KngrZ>;)Pk|t zj-oYa=&wQ3wuSg+U@#y3)R3E2|0i@Se0fhYS4L4MQ+c>A{n zmO6Dq(h)5>OX4>?JtITq^5fxONxpc$z^8BAn&Xt!AsJ>TMw#kcqFCWTIO?<>AetE(kWH^AqHxVfm zX4R=1QpDLYhcWxJ1fSM-AIE7Waan<1@KAdskBglJ1J1Uwn}LWo6FfmaKp#tEU*g}3 zMqoQR(dpSUQ{28zpI?nXj;DVGlc}b$s50FfA{L~HTU%WC?U=Jr+=-az`5FJ@|77xy z#^Cz&T`0G851Y~>W-I0^*BuXNBF|o?lk2AXv^l7nrvJW1{WWdyP~LYk;vu2mORlr< zM_QOsI*bNe2GD^oTxsK1Df(CLKH!1tkbL(&oLcb&Hkb~F0)aQ-dscAIOiX2lr`Ofp zNxmcMN%MtiYkrXUr9=71>2LAurJE@0=L#DPXR)p!18MHn>umZ}Dc-ibp_V38>U*1f^WIvNt+zP#&hOl0>h)j64llDHGNS)$L=zzM( zI5FZ9vps%^Y|qHypg)bbPaVK*ckjXdkB#{hi3U9Pf~i<2L&q^6 z2+q>w2gan~;-1qm#c)5KvT?+cZEi4QYz{d-aTBSBg|K%vxn^+9VmHFSh!W$6g6q{PvU%hm zRPj^bnHKV}!s;7F?|q6VqDDbm<4A6GpapwhenCwcEnef+h_^MothG%xr zP|H`iButC4_x~y2#%60{__1pRP2d|aXWfMa#7hwo*eLj)(wYgjr`xC`mE}-;K8Sd&akN+;v z<0+Gl;iX!A{=x99VCcR_?xt#zHnY<#(>9+4jjX{x9#grbFcX+!uOaHyEJ6AX;FQWG z(fVP%?6QU>?%YT4e8F&XcW?@Owm+1$>sR7Z&C6`g&|Mf58N}lT2cuKYf1rE+F)?3~ zgC656q2bg_SiV9QmvwE$=m%Yhr%Lgzy*YeWOrp0}*W)Hhb2weIiiRI_FE7q|rtYxbd%(Q5u7(TN`y`0>A!3faV~10awBEjhRyJ*8vN zaC;ey-CvE@DjjgLZX3BI@N%Lp)o{og0jLH?;E9w05mJJCeQC~d>$(dUJkg*vzTuZa{3eF}+1 z?licz6*b3A$0JRBVv+h(9&-8?dRgi5fQLh&eBg4{KCX%!%o>JSBYra8?+h}}*5kol zz3krGtK{-4Px>mKLdzm|QY$@y?T!c&zZujob}vuG-iTS4zFrMel^)>R%rzL2G7wfT zc!-xS)}f^^Kk6(VK)Nq&!H>-!@$SNQ6o^;&^Q|&}STqdmPt1qRNykKJP>Ncg{)&qB zu7KILV^MRvz*j0)q8kjBWA@1+k>S!9GUtm1uR19>HpXtn-*camvbpcc*2*68CFd8R zqlJuvmMM%LV+L?;9E=wt=Mp;GsH1%>HH;TBZZ&i8=!;=Y^T2r$yeo_EU$m4DI6siD z+cT9OfA$O-?(0#FIh&D;3&;8Tk4TK-jk?C5{ba}ZEb)rSCwTX=9ANR3p@Ocbm+d>}fe)^iqN=zK z=jQ$;Ewhq{yGJoH>s#csLjnA`QHZCS^zf_Y2uPgzi|r_$jFopLfXU(_w%j^_^|aq$ zLHa`0?t##8OW%b4_j_Q|m~!CKmE_C*cJe0nljB&sg=FKDI)+)^=-Xb8X4c*Ca)3Tn zu^2=(cNvhx`J0H(2P=V1KbDzW*s}DIQldErRN(xkZn7}*KB?^;4N`{&fL4eBIQfPH z5sd+}1B>C8uB)Tz69q$%JgPrOU`c@~EjM!EM-NG4Q zX_o`9Sg;OzKL`#>rELDRavpyb=fdy#d+;zJN9qzgg2oR5er#hf?AUEeYkmFr7P~Y& ze7zXb0n>;gDVUb(&AXdXkG*Z=5yrUt`$^7GX zk>8)bI{lFJy7*zrBFj(PMK3OYKUW?ngPTs+@aT^N_)14Lt|YC(<3E^yt-A}qQ<%id z8*_QWT^*{M`IA(oj^I~=oT%KeLa^U&&lQdK(P09A`0A@zQM~RGs^6xCx2MJPZvvm~ zSeYXClK0^zuctV_Ek&65s1cu>bYWL5?L_0IN<-JIPG%A+(*g5Ejin3wzjOB|U1qhJQUFVzN1*v`c*`JuG~COgs7(y6kT8`2Xa{^??E}`E3op9#c}A zCES0W>3w{tdj%#X?uD_JOCi{AC)71d@zZG*bdtab`u7m{-XKCJUCe->6g**h;778#XV6q0WaZ2gBkcH_y_fO0xPz@*ZAF`g|AX~e zDm40pBd=^MW4aw$B&5KU@6pL+_Rp@c?~Cs-o0n2t?YW`QV+y3(@+A3b)zSQ(RU34s z>G1;zv-#|)KOr60;`L;$dH;)ZH$N}N zQ&;EkLyA|S?64sT?#U_UfAU|n4J&U zOD>0pqrXloyFV?RNTMbs<%PJt^dVcY>IL|n4Pr%^I&{PUfv4j)n-^zaKo`RcaH0Dt z+f?_oA>Qw1u%?85T? ziA?sDF5S@e4A}fLctX>hG*whHsy7P!oe4MpV#wb<9R)YW_=wY|{$NRwH_+xig|u%5 zG)~eNzAe1ZPCl`s`ew!Oy8Q}!|HgtIZ@1u){40BNr;EfL61wOu67Z>YCI)w(=c7hW z68NN9@H1SlevVZJZZ+gf zvJP;E$zJ^PzWt)dz9zi)brFOqxzm*~lq~;q25%iXhZ_!#20XV0+kAcLe9J6)`ZaGU1MXQTX+>_=9KTqVoBi^Cz z)5L_#EvvU#A^o5r!T`ey-g>tGPI&1)snYElBj9D)5o3_y#h9$6Rn=Osn z_!MlL)vf#vQqTl>UbaQ+jS(@~qt}F4QNO$WgqJ4ZRIp}y6vyX)e&r&rS(38xi zg3aOXLqEDG^ei8^u8rw0T}9VMShJH;=HTSjI=pYtQkWn+gYY9aSe^G=n(1?i9CMGx zaXaq7`;TU9$G|civ~(EV=cG;(^JCfJ`JAhMy~xk5eZ|E>24&u-7b1O$0`ck+Q}(Z+ zK;Q!p!sV?e_>Tcwc*Ll`Y|xVeRQ8v}=1qPm`gvKj?vNq4tWRNi2jbw5dIlN2M;2!l zd9yv=L3Y@)u#Cm#xVa03x(NsIav`B2Ul;Ngh#Fc)UVhd*3(k4o!?;aeyl;gX6VrG^eH5E zsIa?7*J6d$Zss%il33~GR&ng31>zp}XvgQ1%tTh=1hHm7vZ!22EQ&pHx9){}5vKl~ z#yvN0;*~QEv1HH~h?JD%11Iex5z4XH7e1UXk~HTU-!<`vqzQDH5Z)JSg6&?bF=BQO zq`yrD`-TpY>Iox$bb#QAoR=e# z+M>?8cXVR$!+E%*2Uu)=d2i?&nX zKct7iz1@3Y{Ec>2b-@shjQ_~&R$B93bmR}*ikabvX1us#E|*=XCcZ1YCx?ro*rJy+ z=+qfU!M(W|$E=m3M=NharkV#DY}pOzMPo_$eRn)tQjftNo@lXBmPcuF6VPdSK7KMa<*Ur@V&{q3 zyf)=4u05#FkKC2Qc8eCAM3XUjb|QooKZkM6!=P#EMF{@W4v9J*tofk1;2Vg?46|Gs ztE@v0XFmm5I7s~B6+vsc1Gjp%9ggj-hm!+}V0GL+cs?(PDm{~>iynOyIV)B`+1MZ$ zzQUNV67ny(F^1sd_>twUiDDb(XF_3d7-U3G5{JEO5NC`N=FH(H{NRjSoOOWk+3l}z zuFEgco{TxLDfb;LiQh+Kt9QY^8UK+HM2Ti36oBf#7IGwYBNXS!qyLEc-LZbPz(%d|@f&i3d{`XR2$lrFLQ2z{}Wpyf>g48D;H(~ZO=a}#Ag#(^-(I2)WV z%F!%WTRJFV6m}?#baJs1Ts=Vp`I?Gd*gL(EY3M4#_d(OS$xM0fzpkGhXqM;CRfPTK z#C-9&dKn%V^NI`-c0L*HBOp^?xHr#T#Tzr}NchNXT;A4#+!R=~ng$%n4*WD|} zY5q|DN&f+EeO5!SJqV-H3MZ(2_&|E}X$TY+ZKBsw^WoXFr;sE#BX-_s5r4BiPw1aC z@%Ml0k&szOg8Z|SA=0)z4y2KIczRS$)XdG`c-{x1bX zUK`W3!cOS4vI=(yFav>#1DY#l@E^b8Sg^GXY?NpstwxkI*$#nr7iUsXqKGGNOv26d z1(9#O2g+v;K;M*bu%0@RzutHYD_$(*r$4PE*RUAm;`GoxB7y$3E(86ZV@!R$7MF_A z<5!oKkXXlaDDwP^izbz!#Ah2C-!Ysfuh9hOdyQyXT#Cj=o$7YC?I0^d4xxJAP1qZ) z28!bn$%)uhc(pbNX8-*Nb4D$snX=dL^JjNZ*)*9Z+a+_iNI%^C^%Pi?55Z9*<1nm# z2g+wOfT+d;Y*!bFAAd7J&odFA<2{S6?yAOr-tv5;g|Op!l1F|9WrEaA!b4K7ppm5+ z_P^SvkN7*K{MTz+Damzr=56h39YL+>rYys-Ks#Ms|t zR=ei#(uMN4XL=@TD+{^xnajxbSxAzmc932xQ`RyrKx`1>;uO(+xGw)qV{J<2GtuKu zt3lWiP`$(ZX_;da3kffFN-#2{r$j1z%WvRyD%s?#wKHi>8VV~NrE$$J13J=F5}(bH zzy^b1^wK05{$tE7yqWFev}WFUvU;F044<1W-s)#cG%L+WaPyVAVm6kHkSroEv<+zE zO@Asbv8S1^yx6je^6u-GM{Ag+9>`p$mA%iP9r(l>L=w4kAO`wqPJ@m@tSp zdRuXSmwv1pT1aN){~@3}L|{;?W^&J0iWC!Pia$NqC(ncC5y_@XQC?ak|DHF5A000^ zg_au#ZnhmPZIu^zwiLnHZlN=5t3<0!Rp^bxM7X1T7Y*mO!h!DwFj$xi^H6u{CDNfP zzk@)2@(CX2u$|Yt>T_eik2u-blWW+n<@0Ck$4zSw!(XkRPDK>;nF`nW#mny~A zHt37B-2b4P>o?Y=B+1jxjKO(|W|*SU!!$1TKtA^b`&VV+bW1J%Bsqs^;(CcBK(jW4bH>D0mnx&mx|dKlfRhs_vDcO0=jYP=OIjcNIRK4SDF9UcNfYpvLVe^94|27lzocv^q(v^*>j8K^C3K-<{#Q$ZNZOS zid@Mw4c{Krgd>@AAZ$)19Nj9pg^3R*(+9WagXxF8u~%e{#(wQINN>iA5wTcu20Zq(ygQ9gGQc=*@mipirY1DNAqCUe6bE{Wj-dAtja4M9=%h=+g+7x6(yXhgpYkydIH{GJ%0(t`-shRdQ z@P8`9Bisv7?wme97B>whT-BsYuZ@TL4L@L+t}LB0KO2G^r0}iB0@(J=jQTDr<1Z`L z^SE?@4SBwW9e0U?U-f@rXwTLEQFI>eSpHueC!<1SC$fvEh^*&6pC_fMC>1SIG!#wk zP)4%JRuL&PDZVMseU7$vQc|>$O3~2L{M|qQ0GI1}?)yCFyx*^vaNo=kW{`R=H@c8N zv~eP)*w~UaS#qmZRP)B0uVIR+(6`l^0+vaE_~PG5{`T28%qcIx?2u)+MWqDgua=;t z;$9Rdd*JG8lW@DieBNAmUoXC&?BsLcEO@3Si{=+(^49W`*`lH!B8T!%*mVbS=GsZ9 zm9d34+x!?GnA!6fdV&jB-2)0U@59JjW7$KIKfW8352LrYg3HK7D7|72oIWed8sC+O z&YnoZrz_X<13Qh#<>Pr=t*XQCD{IE-2lFtdeI^c>bO`+$0&$p082XPc6Xlm&#FcAu zNMr9)F7Q!$L5cY0t{^RNzl&J?=DB zW$`NtB%zi@^u}ud1yx7Vh+iA1e1ZY$T6iKe{fS$aw{hAYS~zBq3q5L>4!PVx#zJLPzRV!&WGmoPZjK9>Z_>bD&x&BV^SzSc*wJ zc0(QN9bd{an$@^ramn1}AYGO@_X8MTP-9l>c^|MvxBmgHfkP8V)VU&3pMl-anmtKfi&8YTLNpg~5f!2R_^^RuxilfDTz zHIHDE;xo9u0!zN{XCLJF$AU~rgXojBgnwo87XzB_V0_R-itR6CsQfhP`yLBynIOl_ zyQPHdc05E=kNz}k({t=TC=XiIZ?N6+23m!8aDflvBx@}X;;gHT%{*Jof=<~php6pb zsC6d%wJ!wAzrZ$?$+Q0=1%L6^Ggw)v3rkwI!h?Ym=*D(`A~y$$ZTuM%r7UrCB4ll}W@mh6a<;#uN%!?h@9-wPzN%H|ylA1Sk|HSOOckwuFc^;n>(Kmd`uO5rGTh}H zuxh#~?#VsR>;5Qb1^xFi{U_bEiisgy(2KbumE&#P!>y&<*7r-0+5wNRMmdRB)u=jH(z)8Hshnu)j>mw8X*^9IMZ4ZG-)b7CiM2>9L zbD;wqPy>h3_G0{eWx6L$g=fNkS2FWF*RjotZPGJg-*VhpSRse2HLvhqF^=@laHc4t zwh&VGYVg@Z6!-@z^5E4|j>|Utp-Z$m$*pmvUf<%#-* zH0VG|8NL;A{_WM;q|wxfWl`60-@5xK_jV>`KbPSA=}r>IwacMO$UVq@TqJ1^5XrktPuO+f15iMhBvtJrN>)u^cKZz3y4VVs)-Z;R3F^lnG8TqMyRhT3YRtq< z;No05jfo3ZVbiZHzWj?3{YweM*~QcFTj?rHzL4o;-_H*Rz1<2y)3w;8e&=~j^=_{H z$tf5RbqQWg>4lVhHMVJLA?h(tc$j+%?#+G84;v=|dyfVv{3!Su{~B=H$OTn3^tdl$ zWm)g_2ADOe1lIZ?)LjUG^5-!y&@P<92innpPdZ59kuK{OG>%RAu^3!0PhtkH+05Sb zBOF%H7ude9G3%uS3Qp~o=;t+^?c28!{%FNQ{pmPp>iNf2EK(=$d|#RnYKK`_rku&p zS5DOzb1^=}5`2XYsH&G9w}tP;pkynYWv&lz)28#@DGwn$;W{Kn<_bLcOVGD929gDa zfmEp+Gd#VJ={}i34jX=B+XNveVlse?-{s*lEmJJ(DW~>Qn z;$`>^qw9NF^Svn6Ga-hBJ=zV{^AcdrD1k}2Obsu6-v*~wk3#*=F*wmB zO4Jx~maopek9uD=;@XkZVRy?*)O&bQ=yCRA+XN1H6ln=8kXGsucK_X>(kwE^5VO17 z*oM>za_wM%x$G4X;=5ilSdappGYrkS@qAFcdY-2^?l4%D?+lk{^*T zc~>FJZ`~XNi)8KLjAAZGp6o+zrI2~Eh(YZ=3%I_Wcesh?n)v?j68Txbf5J7}XZZSP zJ*0;|g6C)NVN|9rr_eP3V(TkV*;|g3`sR>qbRYeUHwQzFoS-Hk0kfF z>$ofa68cLm<(A@iiFVX3?tRrM{!i&Kkxh?~KYTF<TVyR1P5BR$%-ujuB=Cj0 zT+ppg2_g(cC|&{lifnUc@n<`et5wB%DZoiz<01Q>6g2&<<<=z*WMh@}aJIS){aW)* z;5aA3>zV`bi&SW{hYLIN^Ev4LT!tarF7qedjp?U)1$~>i#c5yeLkK)S0gH>i@@&Dm zvxVjAWU%xq7Pw-!uBLOTHG|_Rd-Z_q%HGGaUX9S2LRq0Hq=3XU)lf#$RY%=gu3s?}f4yQ;b}9nWd>;`>#EiPs7Oe zuoh)UdC;=%$@r;xFKmx$!Ly$g(f4Ns$Ui#{{LZWBt33!a)~mvmQJu*Bl_9T1CsEJb zofgLkjL)PgLdJX)Id`g1-$i+f8TJexf))jFa`bbsaEFLE!gY*32uJb<0V$b6f4QZw ze|dkXtlA2lk|LPmA>t?JB};0~DvHb^tR;^fV2+7M3MX1Tz0ZX!Fv7ex}%SF#?PcX77Lh?#kThf(MSbIlFMRMi0tYmrU)mr}N3yIakuG*Uw zwvvlQHz3I7E4Z{9vcE@zVQBghzB#w=+TsTv=KP8WBu3B*;iTg{a!3NMJZ9sQ8kjjEJv|{O4KX(eGWOb zV%U}e6z!RgB|bujd}}Fx?z$8;Usj=8WBQ}}(tmuDSjlOQnF@FOnHdgQI16;G_L5`J zDfBq@5rzv)EPn?jI{3Vqn?Egqd=B5mC-;sB9tcI+vL+Az{w>3$%gVU5ouz25aah>% z90AjeQM9MA9fPCHXy;RR(onsN&BOY!oHfJf-o+%4%znatCynM`9!)`ydxEca{ta%u z;~0pFtpgMLF>u#Q6`tw_Guhp;!fhsk)F;N1&O%>Gd8|#ZXV}w&SJtG-kH+AGJE-Gq zJcfq}Y~Vq%U>>!O?tDw6AA%dT=Tt&v-<_-dQyS+|1lTR7R&+ZwFY!!Z#Xg4GqhoE3Jwry2U77I}W@)g{pFl*awhzX^uJ61hap=eXh59e7{X z>y+ymCF-6{FkxaAR1Vt%-dAn;U~U>%>3)WV>xYBEwN4nj>jA{K7I2zHt6{ipB>4J- zaP=q5p;&OjNy2Y)J_?UG)lsIrgMkceZp!92-WrVt77sZyA6vYpmW`fomH6-H!ugJx zZhpOq1w=Sp#3lVjBIIIk z9`{gTD~^z)a_z0kP`@t<4C)+Vu<8K`4Bu5wZ%h zJIY@=fyPsRaM50o_`n2F@v$df+aJv;iuB?0lO+CP$Vj?)$CS2Aw4jwUln#I#Tj7pcf@f{}@O+pUl` z;XR!rxXi$kmS+0nOQR6fvCE{woF{yClQbJLNZX9(xaW%r+@GWy8t$4WypElP) z`z}*z_wB;aky&s%)d;|@4~KZ%#Gx|l85>doj#njILG^iV{0)C@+b0FCbL?Jjc%T_q zUdD?IcJJjLS#RftCvlv()tx$0;&7b*HPj9)f;+FDbAC?-if;JqXWcFJu-oedcOmOO zrTw~0YBO`F&tWU|HO`@*_rBn*5>N8$2&X4~_Qbvog$1iVaY-S`+~8Tyx$}FDa1PIp ziWV9l;k2L6<7VGcu*aq^M=IPBzZSo!K6K9n1aEguF!Nc&J|e$j?E^|G*^>wf|p zAgoGZRt5h)4Zlp`h;}qoTf-?f(Ou!%_9v;+sO!IkSz8T<-aW`)>zIaxt3BY)3m>?=Dw%Iz_J~s& z*$mkUidg@CIrQzH%J%J@1Gdo;K5yqK`0u$VKT}3cm?J77^894{@=6L4ZB{bptE1u0 zpMzY)<$N@`lSR+2Dlo%;BBuP;mgOvtLuJ*g+`Ut)MhMZB;sg6b?kGpXz<`g8j$RgDp`pW6o1l{w0aC4Tx)lyQJw zHg%AA%4K1fn+<0Fr3(JbvEpG5@6so;?JTKUk=^-f#C~)Q5$oJUrar(GWmX5WqxVbr zmob&tC~$Oh>oe&4WEbk|{*H^8DSK2lK&*4T1@hM%{0+!{>&|3{m5|<;Os2Kw2YMLVh<}EK)*W3g65s6|BEJ2?N4!@# zRQ$p!UEG_ZDK_?v=k$N6h^M$cVV<*MS+pau)IHK--+*Rzd{|E1#-J|TGdWQ_Ws{+} z*V#?1karRmKB^JsL7E<)1LQ>4G;9I?4 z;+Xw^@Wa}EH2+OUt=-UBIQ(RvljvqPPFNTSa>?OTvEw85-+NJF(dUVi`U_c%*s-j5 zdm1!myuygN%Ro;p9CmqE++A zW2`sR?AnK}Ps*wH^Ly-i5WsO2rO;jI{@*N20hhTwe1h*OnAjXg%EJ#*gO3($ zX*kQjw%EgGKO6x|VxIBb5i@*$;1HAgTgQ(78O5+`GTVAPi#v5(7H=HUVhP^y$nuZi zVN*jPUnWf*Qx2irJ+rzVzXY1*tpp-4!+%H5GxPmJ!Bry>5@9j!O4Nc?4=uqc#1s0| zyy>^ZgtU0D`I{r+vG$pgQkgMvK%h%;w(OX4w$>41M!sldOHaGVw8jem=Q9iypq!aMHB5MSO+&Vk*^vtSbqD%hy* z5_Z3F08b8n`B}JD|2M zfwixernX8|_AqA-X_@=d!@F(#;Tytxq@N`j?HWfd?MwLB-}_N2Ef~fuOJ{S2N7tIh z1;C{@g{X9Mv`BB{aY@AEv3%To1===q4Ey1pK&CB9_~cj_73T!;jzYHkcpie={s_{$ z)XtZyokppP?|Fr$Bj~m2Jw|R4G0nqH%-m5;3|)crVHo2!Q0xDjz4^Y z(-Rxuzl9+v@B9vY{u<-kDMg@{WQM{zkS_e>VZ6H(i`gN^L_#koqAwShd5&Q(d%oaT z=?ILU-~?}r{n;43`E1n0aZLB+4}5E3$Q|@fruxmk0>=k%KX-}WU13ctlg#mGp)$(F zq{E5Wp?GrVE#9ZZh`KptQrmDJ-`!lv#Vx7;+sbIHH8o_%W^aMAfnz|sQs7xjf>68EJd`;^dtrO8 zL^Lljop-!8ja{4{K_8E;?ybl(>vs`RO6K-ZpSibEU zXeEP(ssxaYE~C!{1?ZA)&vkCRhuX5wAau(f^e7JIW-m_0^r3t3$NUz!^RH+kp=`5;$P-M#$vhdfp7}hf4fMj~UCCM3=kz1@EF5&9=dAqEb<9abJS(^dtcMgNf zhxb^*`+QIdxx!x^-Oh>FOs-~{KfDUC!tpK_Fjzm5n^CWYiYI^J56fS0K`ojXKx?(bFKw_XmjJ2 zie|GJ1E%AnQVZPCaSv`h9!!CPBl%13ZW^d@5KU&i#_txxDQk5pZP$~5N%@EP2Uh*S z;n+J-u2x`eW3ndfxHS}Gtk2+@JRkN|YXP@*%s|%OS1sf<6`^OqDAqI5AF6$=X?|}k z?8-{uwyO&{1j!^E`+F9IzHHzePYchwi(>ZgwUFhIYJ`($g0{_Q+0ra3C3Vw!W9#j~@jZC1TF^Y&H(>wU&7IE@RK%F{s}^5z{wqqb1{|D05yk z?!4ecGFlZ}@yfS+PTMpZzTgftWwvp3!W|^jP6CF<-td@P>=bl78%%|nYrF^Xv+j6e z&(vjt=Sa3Lmt92NH#Ssx{U5w@{EPbCyIH@Hli|ZRdzvxg9#)nl;gFZV_*^*&o3OZv z^(1-Hm`C-{Im?`NJo08TPd)et$2P&(fDIshxe*dC7jp*&3HjlT>!DRj_sp zeEC&57SnfvX|`P9_WWJJ_Vv?YyLC>1Y?C1tj%&buQ~ltkyET@tS_@Zph?%L>A*}u# zEZo|C&@Ffagrx3^7-@&9S)snv_2eXxCuemGV7hvyI zQ?%-H75bribh7vub9LCmd{sU0Hakh%W?$sr=5}zOh6#>>=fl~gTUp#`aS~2d+sPK( z(`7eHr*a|P{aMW2c8q9PLd8+W+`%Ja@-I$AuiK2OT%x$7S;F)EN33K@%0T2cYLI@C zBFSXe(7Cu@8w2g45L&w^Vx2_hI>@6BkXF1N2b!x+1H*X~Hx_(K_f#+ar1Cys~iEp?=E27`;z&w25nsK`CE`@_7CpY=FrI% zQy|=W0q=Tkvt-?CTehM4EX?9YlAn+%*=t$?9~~1}vi<;2&-u$Vn+o9Kl`KkqlF9A{ zn)B81vgF@)TQaSD6&L9^j*P|rO!`3^IBZv9KSpT_zJWA6enk}(C*9%eHd=CitM5X` zYG=;+LM+`8p0y*@PC(GG;Y>!(gvFfP$s%nC`=q3q_|O^(D^{V3J9bQ-&Om>*dr3slmJe>AG8aakR_K2QOYf zMSVBo=yYrmNvfv7n8lkwW`+|bUh*fGvX!L%&w$>T4guGKP%a@U66Dw1gmZrw(@7f& z+Xu$8?Tb?|QEn;ya1J6J%VBik#W|e*U@$8&yUgB(oe?P~Ol1!Q#^kztsWgu@aBGKq ziniYKXJJ1R*fHTo8(f@=hPFy{-@TZE^>kQ|IE%j*%EMM=HEyh15?mZz$0sE}qiW|( zbu*GR>OScj)@|CC4&Rrgai+4jz~+6b#87q_d)8IWjWS7qrWrTk#jp@uHr<|rUO&S2 z33`Yb5BRPI9a{3n1ni9t;;)uDBvWU=X6taG#=Zm4>pqnKcGZMwEq>0$N1ulJ=OWm$ z&Vbaa6#13$17Lh!G7CwwVLDaYS-|mQ5T)~;pHV)atJ3<98-DXQR6n|j@8$zmsfjq{ zq#t`ab}cagrz7Md+H2`2BlDP)3=;f1)tWbnrb2ai*Q1*^Y;L(6zJY^Wg?x#nWOw4s7I z{UsN2%8+>1KRBgSL=nceG{V=M$z?o;B?B(QhsB4m*0+T>zwgYBOt=M)GquF8j0UpU zfTR4Vm$L9zm}93+tLF9H)3Go21eYUm;wKL729>Z+-0<_C`44Ho@a2-T*ph#NZ#le+ z&kXLAC|Nhb9w^5^KSM})rAm(;=+gw4#N7>fE%{J5jSV)q4D;IlAiaAC(IflQgrwWt z<@@na;24CWztSXjJq8ObE!p5#OPGp~AN7{s3oNanjTeQ!Ve`XuRG6vbx{iH2ud*w3j+NeSS#__mkz)?=wDM_UH`wWi0*(1!= zv2dig9zLseOWb;iSIb++9jN?$|_4`$qmaEyr--a&<~E_-S^^lvSP#M?8d@pB2?TU3de zBV?(0Xf~Yu+Qa|4sfGDVZgAYJQKT^X8}hHp(LlWd3kTVAHg|5|*egT$PH#&n{++=u zzUfRy0-_-Azj%~;nvUw<%lY;DK1lA5Ovcrpjo9iAAN;J=07;V)IT)!3Im=_PZGJlc z$zVOVbE?qYRb7Vu6K1fn4_xWyFdx=v@g6U3mu8vEbD;eC9Ef@}loI!=fM~uAdORM^ zyHpgRS=bYJcVYy+zxxn}2CC8dgih3+?Sz@e4}`;;68(Pu19HFgKzRSbQ2s9ugs~1z zPG|zNCFfbf$c1S0;5jRQGmwjYHWlJl4QAGEQ}OxWBmBZ?mvLQI3|faov+oTlaA}yp zbZ|GLwS`h_o5>9NyzeR&wnUR+zF2OiqXJn+mpOQp_sd(H;x|#Y8`;`Ww^muj2 z`)Cg4J&lL72%(1_^cZH(y#oauZ&AOkAN`VDk7qZPqkE-<(;7V+_sQ;L1_U@Y!iH9+ zMM`dEMA3yZS9T}vKAxzHgs32aYqWDd$<;o?blpvmB0S&SZ1&^mxt7qV2wE|y0D;~V-jU|b}6eMiO#;UcY zkZN)f?3RSGu#N!S;&&hCZp?#g9;Gl|_Jd^GrTsWa){TxSt;Wmg>KGJ1h<eTJa!g4vs+hkap?I@O#gI* zKa3Y};I0>NzfqGFeUK%;H8JdQ>?^#jIhBo!HDzZ~rm&{yZOqeJ9*2Hkjf>3&z*%i! zA02xLrW$QR{WuLs_!5H#0ow)Ey)-)&HV(J!b7GtHouDYJPU6|Sf^}?FVxKMK>EU!K z>UVz*l@?|QB>z2l21IsL?c!WpwoP6r5f< zogy#VlCaGMM}Hn)XqfU++ZcC-Ibd*jE$8)5la`q*;ygxoip-YIV(Eoq%sCX!#VuLG z`Un2Tf*(gQt?vX_S;t}18BM0YV-DNhGm7oWT*#Z1r;=NXG5)#o8iVTlVX43;nla=P zDm*skbd)t%p{3v#u=zkUU%kh`FBTM)K8RCu)Pbr&>g?ZnVE)InK`k>3H?;o6?n8H| z>|7alEbc3eyJrqp>=js<;~6$JJdxHN7!3oLwbrJO$ig>)MfkYhoo19fk*jDOse5i^ z!;dau&5hd3??4khZ#{@Z)mE`D16x_RPcZ#mF^D=9o8a#FMwWllj7nZsOOn)uzLD)A zDyx`8Pmjur%RajZ3`#pvwq3_Y%;33p=L4uu4h7>$i8$p(BuNava*kv` z7W3T1DZeJthWz35mbv2g3@@gZYeGXUui@~uhq3O!O#aykX^NY!DCDqr;-2JGe16G* z47HBJ-+aNw9UVhUem&(fR+mCU;u&rpcME!R)$y>}WOO_K0DM*7NUXPpz>~@S z*jL*PSW;t6?d=GEZa;xjJu=XEdK`N!mjd%!zY7`Ik(`^&Z~jx%XPmcJ30#Cb*VGNV z%tGk4v>Cs~qe?5$NnM)C{3@AT*Jf5TWh;j^h9I>?cvlOVii7_=Nuh8Ai`|d_bu#C8 zFO__<*(X)^_*D;^W3E6;w_DROw{VJHKZC0s7DzQ+YbE!-mN32L*KziU@f34;6@*1d zIenJAM7eW`xMss}kSZyKLAU3So%2AfdX`U%ytO($?io9RcSn4iY-`nwYI!(T(1j)-dJ2>Z9Gx1m$G3C=gl7u(b%o2zIK;aaInP^&C!A@y%ObbkL44KO?jCbjaurSKy&5ZgW~Qzq&X}e9bE-pUX%ul zI=X`HKCD5T8hOg^8%inf|8aXK4G~ym-qdq$Ia>SLasA(9!`3YkbkOw^cW!(l8?W!i z-QFBU_f3|ARMB3l53b?tq!QurZX;UxeF?FTBiM;Ms!Z2=5~UhTu@%Da80#NSI=6%I zj`K|Mh4j@J#OitHA^E)L-v8KTO~6VMQ{3C>Lx+D3Ve#_?f05itw09MD5tEGg!OaPj zc`-^-yfh4)^~S;3yd)~>Y=upRf$Z>xG3Cf$a(7)Q9{!|ntgjH&QrFhWw&GD zdTlVbV%u6iYM?gzygZEE^|FS0Us}PiY6kPWC?h;qTm&v(16UsoVRMf0V0U~pJ!mtd z!Y2-FN7q~iTUf#UCE@ECx`?;T!m5 zOVj1LgQ|Ply{EZIJwo`GOGhX?83(XBTQFme(6_k{a%^4$l`SLnk`M8bmuCphz&NHa; z(-dBP6M7ln_7gwP6t@nxWVO9_c(du|q&j{z2Hd&JFFS3GPXuO6?TJ|Kg}?|~nP-9# zatY9rI*6v;+ew1w6kmEsu>ARZ3~&#|6A~MC?)^|K&o*VXe=kGPPZ_pgWg{nj&WlrB zYy>hwPGX4iUEakm5kr(>>7KqK&ir|b^PTC1nL&&3h0=N6pi==Yre?#TCE^W%ShcU1V%6Iz{y>ENNQ*n4gM`p30q^>8SBk_`#T4gASz;Q?y)RL zdlOrazu>2EM{m%yVH(kg1qWI>HhE1&lgCXwZ+jSByt{bwHNPMw>mC2<&LM2`N+1g% z6Y{0CnEhN{4^J+RXLp^8;llO#!v1NYXzi}Y{OC(d@xk&Mv>PAEO;~+{a~Y)$L07UM z$TJ4M@+a7eZJ*#+=@52I=md20Zj}E02wR!)0OCGIQOX}ndhsp;hP?0l8}g*HAn(*TXjv@=uiu9p)YHV|S~-T97;R)@ zD>`9vhXRZlaR6RzZ+mqW^Owp5=ahj=E_DG*Sx}GK*%oB7 zzZ4HG^I@7k?yzguXI2pbzoyt;1O5uso)1Wvui%T7;%!22=!L_xa zn4kV0cYoiG|5Y4i8V*|#bKL;GtfD)&cZ+VXE2p+!iD#2aq-VT?U@bH95X;l9 z>nF)blEH$4+K^7miE&*in)S1zH6D|wqoD_NgT(?za5LIZRu!c!*g=bjY~=#$-op4> zfdfyYQ*dMkZ=d<_fy-D&f5Ihr-+ z7616m32;{$#R9#XVanA`FpEy4JGv^&{UzJ3D>k4R3UunpbE zKI0CLRHY}b`|(71GA(};PK}Mb={&oQ;@@Q`{d+E!v@nQQc#9*FY&icQ7jSg!@nFp2y60PY0cAM&>Na5!d3QgVyFaneh22;?t%%c1+Js(W)fIp zI4tuDKWS1Dc(wh7jVDJlkDW&Bg82!keJD*gA{21x136?EOu?=^3nq`LY)PHAVg zX#Bvza40tl<}G^19nK!Zt_qBxX}$<6Z?bJjj?Wz1EyJ<*?C4N&J#b@?$ZU3+?7 zZp=q-H(|He9YQCKD}1NSXsGlUgQee>3Qmz0#M$v^`$O1Qmak+}(garuz9iL&)pYlH z9$6<=(%}LtzRYSOc-ROM*{SN_;c8BcX61+sEv3oV;u0z>9s^Id#&U5Ho7h6N>+t(g zDLP)Trx$qx=;-ld=;C|>#vZA~%rkMq?*9j`TJJ(j7yGj4QHN1_$sIV-(#t*gcMncC z?57&ZS$Hh4k01MN6Dg+6U{`O;vQfKr+5Xkn@tgM|TGnYpj$z+tu-;-f;#2)VcB?T6JY!6e~l8VoKaz&RO#bMsDk7y^KKw~YmX@^23SlOtv zj>kUCZ6uQt@_My(Px*rSl~^?LCKg@@fot;C z`1NxJd$2VWCmQRsmK1HO6Mx1na!a7uG79!MDT4hoU*<9+nc~A|Q=-E$Dqd?s6GIHS z#j`VD`M)=uwkFWAhlXr-?0=}=;D$r3BI%ar4Zdq~LG9Q76d)p2aKCQ4gERiWYaVwQ z-7uY3D}Mq%Gc9SQ|4Mo&mCHsgJ-{YjKF4&`Z!n{^1L~Adr<3yReRV79v#BThG*r7Q zu?8zMYSo0I^kM7r|cISb*of#R4KBIH>Jhs-P3@<3e zvY*b=S>F49U|zg|W(ypSh`m8rFv17kh60Tb)8Lm3wZsiCz1VowV;Cp!(TaXVL-G)lAk9(XWVRO}c;mN)k%uCUQ zj>nvqjCmcwR^3RVxh&c!S|lMtrN=0P;FHfSi3NqNVave)P=A zR1o-5qEe>B+(x_eSNB$fuk1{6kLXV~^)1PPn*lAGX0RIjyG%tQi&ypLGF97H=6!oF zqsM!3xArAUmSc2IO9gUs5IKtctR%_Z;zP4D*W)v{EiB}IspNX5EF1l$0hEq@=MAHui*DqY z(&PVPz;dZK+fk&*+c~em&bB>li{lFD`Ik!jESCa)+3#xF0T@yHH`J%(_F6>kRk+YT4ENi_%Ff;E^>&q#9GssY0UhvT(0;9WJ)= z=2mn@;Ro6i4vmX2H7)g2^tH?Jmfc4t^2IGI3 zaHu+s_c4-VE6l6ui+wNNsc1sQ4#J&}pU^PFbC7S{g)g7h!q+k*GF&->Nm>9sgoE?=NzD4Ke7BO!_W473;5tgxq^!3{bTxpxZ zDLuQ)2VFYF7Ihz_`oe2C#C{Z6JG&8GvSz_{3%Iv4R9M-^SoU(qKyl2jF@!U=W9mb1 zF!Yxd7w>B1MHhZyXrhqq8JCUE?UdLuX?bqc;WylbdJ`BK=Iz7h=ZCP_F|}~q;T`{R*EPQ8?sNXd5+zAN(JeS)83~Uc{N;X2 znLyu>eth%NYDv_T2P|1_7+sY_2%X8y+KH4Y>}#Xgv=0@mV8a`j#&4$5Zo%dK@f%E2 z`VKfyn1>Z*K>Jr1n(rD*Q#V(MF7N&%(m#<262FPKKfMrQ&kHx1OWmkGcnU~29)+`V z&6t|YL+zkI$!e({yHU|VhC9RQ>rTzO?&c>nt857=mK-IGWZ?#tuYn3h z8dNQKy2p%^V#ZH8VdTsk{ED?QO#Af%zWx4IhzwSs+NE2-Vx@#-%4~!WnZmvL{Ss(< zYz_{W4~k^=YM}Q5WhPFXi*FTD;Yq(VusCoW7YST^NpA-)$y9%$;@I$3$|Euy}7WYHuoJ3YQYu++B>u`@djY?>z$LIyLb>*LqHUeTCp8 zx`Q{)OlM}1Z}D|V8Lla41eIwg$lym5v;7}M=i!gl`^Is}mJyjLMMRT^@to_{6e*D+ zD)mj;O0*-{vLZx^Btk}+mFHZSqEb;tO4>!Fy|h!m^ZO5;*Lhy&-1jv;@3+Px2#|Oy zdgo)y8E%e&q8a%x=*A(K=H7s!E0dsHKMph|{{xhhrO{@!{H&SBL{(2cpjOXC;3$S- zQ|f0d>5)XszGAv;mCp^Cx*aO&?LmIXEjTUg#M;PDWtIQJSn_3UQeCOZ^zb$mZCuHD z^#8{S1vYi6;tVcDu?kc-N-_1FF?6)=F+TYg0RQeBgdx&nxiR%qXj*4C-`^>?7b~T3 zynmQjCG#I-oUey@+VU(b)0oAducLdV*Qv~`3r{-SPC_oZ)Pxe=o16IG#efo+9p_29+yLg6?uJQvca0I;A%OMmxG;^zChE z8eV`>uZOV>g9f3FvJqqdt%iuRcAR%+GR(=Y$FEyl*_Wn5xFRXZ>fIwiE-45WXzhY+ zeudO9buf%(k~DK)20xwIVL_cSG(AqsH`B$W&Kx$z4@CH*}dbp#fvYxumi&o&?b65G58ui$x;)IQU!_d$BDfAn~ zLraJ{rVPshnUU*Y^1~RmRO&3J>$C{|J{-YXx?=HgTZw4S_)LDdl{vd=ZccB%ricnW z$D!TqSdNY9G3yRKKm8S+{b~d8l9fy^ zc_Y`_^#hy6ETH=nrs9IDV^H#?Ctr|S2h#HgqHlWzSa>hun-76{d*u8{oT#~mfb=DCLnxUZ$PuHEjt%d3Q9}Hi%Mpu!nYw_?7U?aP8706 z9$q|`w&xD+1i`tmRD&2($IcQVi!%QtY_TWF71^#bi-n5Daqtdez?w$U#P|w z?^q$Q*=KV{=F}m-t_Le5QYdGd8lEzXL&;sUDQf>4T$^8yd%jyRts}!h!*HGGci|8I zWA8l1`$ba8kxbm_r$jS^yR-LIDYAY)lTK8`gT*Ul(wY}4P7>;^f!p-ytJGN9%%8wM zSx>gZSrJ|hf5e@yvg4OelB7YmK7q@VF_gY^4pzvkvE6P9C|=+xe^uH{54V2e+Yda) zR;j@>pm7M@$OuQfPmAg5u_&Hyk7s7n_pps4Yq$!P2$p-j5@WI_^A;)@;2&s5wc(Yb z0;T0_{?z$+E9wqhFwN(lnHHmgZ#t*qOZ;!RWCR& zX`x^EW9@SkX*}gVEDJ%0<1ze3jYgOdavne5HsU-oCSqPu0%$+{$i1FCgIzeUArcGU z9YrCd{r9ab4Rc5&tEkbmzfBrfycfLMeZ$!NzDd;D^BC02ev0L{9~FHHNu>`9qdAGH zdYp2)7$W-4!0k>;{)|Nc^OdS+3w9X6*8}q8a`g)AH1l9)>3#5Dx;}nWjAbhh9zjpL zLu}H|fjFf&9~NJk$yBERdPeS|ZrgKsZPaOKIjx0D3j}vLK<# zoKzQQ@O`^HvGcPLg^ex2Si2Zl96ONGjk6#m>j}5h%aG|>MWCVVC9$ddaCUO!L)IkB z9M&!}WruVlY0r!-dN8#RmER7+MJjEuEqyAhZ)hcdjeXg<>DkL zg+1HMxi)Dvw$|fO^&uZ6X5Hxpqj%Qg)s`V-v-K&Sn>vqmBC@Snh$taJtKb{g}B2lD_7GlFG~) zkCy$S>fKfJAjb@6s~?6vjzh%N7lx7VXbU*4Bk-bY28w?vXL0_m8JHMjM?nrHa9Y0= zcHcdL3(F+f`gT9AC~+x!7c>scrwpW?@9tRgz>6NN9!V9ePjj7qArwArEtxF!rj^dC z$->BRn)ygU0^$p!{aL7@anQ} z;&_|an40enuRly@!5fpox8E05q+Wo4)F+&x`b5f5-_E}r#^L7|X{;eN3@*=p%(=~; z3!;f5p>X_t5I37qVvPsgsWGJ{8FxtStHGcqH+G~ch#ULRmH&P13cs-O;)Q|n)hKR> zuy*d72IoBAiY8bDU~srRjX$Kud~|IfBTC>6VFJpoipJu?QFO$<2W~YBbJo2VAhB>5 z)s5Xs7LuLRb@~;Cj?RYT>F;5&!$>}E?KF&bF`&CGj?8MqTz;_CIi}yThkbeZ9V9P4 zs(#ZX&-CBuL&wOu)IR1EXdiUP7tJ!1X54{^uP;>J7<x-W8O6~IAz#xmrFw792#8AlhC`BU82UJ1z? z)xp=x34`*dVCL%rn)6zc|L!kC&NHXu^*}Q;8>3Gd0{iXUkVm{kx*B*En?k2WDH^I8 z)ARjxuxsN6&T@DH99iDSX?=YODXf*%wws`q%pn%JB8&a=2!)NVn#^mF706o%tUckr z9K9hF3kox+Kl~TB)b&0r)SC=>&QI~%Km$O8Xfe9Gb-SjGjkoG8v%mx|Q!RR))HuNV2r>#3{fZS z75}8A<_oxJ96>kqq)@-7j+6dV#@|Rd!f(7YneCpO$mL%gNh$+Enao-p2y2?fHm|u0 zl5`R>)8n9U_;kV3c$)n@HV91ZeBfMP4yS%^7^bZq$i%ZRVECX)JQQk*5A9UZFZmjd zIOxg;=3j%l%2y~}8_K_H%)|5vPes}fqbW3bE|tHi1b69n_$#H0KG)vjzMFycy`dGx zIM(wXy$0YndLZ}?^~eqy|Gh6l;3Kz!>wg(I{KGl! zLVYF399oWQ7dAoXiX80pzJn}rHu~5*p_$J$PRF0;7s?vItzEqsuJQ$~6BnVzhw*&# zlQLeVBaF97iWEQlJB-u$umL*{tDwjC?Krt13fF{YR__k|$^Fw($9W6%_#FH1IC0ZN zoRE`*TeOa#sktfGJnY14pC9qfr5ZF>qmwUq-t|wS`x&lQ$Ja-%jXTLYV|JI znPFMI^?oe3&0LY37hlDrdG~;+y9&w;b6_FA`mm<e|ZZhUmnWKX9|4qVF3tVFJVEo;K>S3;U<}6f{WKqO#bo!CvFb4ex6*1hLg0Y z;m0|yK*pQ%*ZRPJ3zoA!`ECqWTJ3^fHE)5Vc8<%wkOAu_z2g-VB5}IFZL|3_4@)Lg za!t$4>3cyd95dO&|9RbEHDX%~e%3w3kJMIR8IG&q_Ci;v+ZiF;&x27ZNMLuBt5Dl= zCGMu3G0rS@;f!uK@Sa{MPF>oBO(*Y*-F=*~=JZF9cr*?yFQ?*;dpw9sBB0}p7vKM5 z3&d;cQ>o@A%$~9jHxJjRnAd~Rz|{b)lDP9dI;Z%#Dd}K8N&%BYtgR!?6vF(A3E~yc zj-f_EI7jw*;`W0{a4h)|ueeB<>s9EHdHq1DlQ1A1r5@aT3D74;ggy_Xft!@VYmZ3f zM}@8B||&8@~Wlj}2xog?n6cJ|U+HPgWB^E%P#({NB+ zvIbw!cf^Z_X|J?0i`#k|*G`GRbsUeSzZ9t5T8+NUos7|!vzU%qMRh=;Cs!|*fb}PM zrrxPTCIidi;Ok}3_R{g|hBPI_lR^ZCca5bAIUOs6=K<4cn9pi-QPtqj z^(65lwD*$CI$@4uBzQTzFLI&Dt6}NzT`X{J1{{*HM!j97;J8Tw3KoRGk{vJk)@dQQ zVu=^OdEQj4x{!-=_npPFiLwwBr9p{04aj+pBhB16DhSlA$!bl+ym-RLuRe1p*AK;_ zKgV$~T}D534U#N)fQtiT;NalZ+{pd9Xg*DieC`%=qP%45Ytt)5g=Sg&yYv+N*xi8P zh3&9ZayuNCe9V3OHViGF27~?J&7$d1N^C<&1(#=LN4q@ZY5a&1d#*H1=~ z$JcUhxH-VGNk|)tC?`MK5Dq83tG+r3rUj*tSHbZyL8g?`^9Lo1s?w zJl)AF6cnQ3;%Hpse;JpX7GdtaHFRF^w;LMjlCAc_a%p%w1u}ZT<*eMq~h$ z2T$_yt7h_p^Dpr~4i1G+Eupl8knGah{U#%5rlCYQjdyO+cf4~h$yBNk#^$6$JUx~rpmhzxpD}~DOV_5iq|FEpA zoRTkfz`CkJusEfUsotmA9EBQM-8zh28)U|23K`@p4}!_mu88;8^$ho(HKtQ;p3FjT zGpjWGO83)*xoy)S=2#ZOI@XP6Eh}Qsv_OxI-RjBNr)Sbvu{%llw?NRja#&TLPviU^ zBe$-bow?Kt6PY6Wb0A4{e_sw?dB%`LZ{ERB{lU~`a|u6sDpFviG`mwbms#s8QJc90 z>gw3RgxGty!+bjV=qXUl+BrV=us)CHvXtH`Z+NE>(6zu>{}0mxt3fVL0y%V+;GP z@b3p1l6G2hb#9$DExTBbqp}Kdn*SG0L;gFCY5#)nS`A@`Ngb**^uh_jLtXBKbkH%&B-_dt z_(FC(#f5%^(ILU)R=bfJ=PFW8rwM63uw;sH@~pG+Jd^e{VN<^Y7yUXHSE;?j{DJ+L zC9CHj-a7s*@{rAHavZ3}*T3?sEyX)2rilN>lAfAy4s5j?G&f#<*BBdbH~v z+*ThCvQGrQEq@%!b)3Yr*g-lx?iE-4q5u~aJp<`S1K701zU=Iy-PDbzadY`bwtrk0 zOZn$R3dg3*cl2(K7!>*4SZRGEp{A}0}J?% znGFp^b!&I}+R_ED{?kNbO?5hb`Wyz{%Axk|1oYaLOsl&u;jhxU{Nwt%9e@D+Z!qiQeXu$!u;#_N!gEUJJ|EZ(wH6!c_xbPKxXH=j)ttnXt|%}A zLt&-$L9u9fWFmV7&TL%bF@B|~JoK#4#n*i(qinoAQUrqgU8UsoNS#8>Sqh9Z+F!qbp1oQDP?VVL#bHi{Lyf&6b@ z*7`C63KaL@O1099o_!7%eV@dCj!Hu9L3-?l*9EeJ&bUF6H{Kjm{pI6bY%s9l4rtg>sq#tu@7rbW^=An>)!qrtNvqL#&?&HMPr%{z zGwE~E1X@)!iMk&hgdIaiu$Ww7XYo)rr<1h?XLosXY0h`Kyh}RlSDfHw6#6U^Uw=gB zuO3jX{|)n5D(F6Q!Uy8L!h63H*A7#Msq5bH0_Tl)t_}x_HHP@Ey8<38n819&6{e*9 z=DCr_t*50Wu}qU$FmcZ@?$r71VA)>Dxy@P#8C7dAzkLF)eaQkgHtoZ!Wj;8?c^ZGJ zzzaNlM$wk_9bnaT1=qx$#7jdN-!I9yse5eLcmoAyquE*Ab48P6ZkUr_$y6K~IgSQc zFs7l`41&B6)=H*8-V?-GwsPDUN4ozu2&q^G(;U|_ zkAG6Ie^nh`sBpuyuhwkzdL6cBp&6K8QK#QRF4fk58`|z}=59*lVv?*Yv{?@m_iR`| zpR%rUcXRz&^|TC@6*d({P5y!6y{hcMLSfe-I)RDNc~t&Kq0Kqvd0l(nqKFs7l(b*>60H>(gbk zU(aHT4d$}h$(oc-(x5SW78|**2@?Y#%cK&{YOU)iGpgC}KP8 z1~OfVZFF=j!-=`Opk6|k$(`LyA(wuk3Z~JyfqGDEk;(OJ)}~=@*_3y75{)W~#bt(n zae&k&{3!6n22FGz zimDgj^~yt}c)H5^$-d!~Dz1QE-b3hCRt(*r^#&cTRpJ?sr|@XiGWM}sl_{*M;tax; zGE3pSX#X9GH(T>@!OdYXLroF;pN)nwJ7sBdiZfTBcLg3N`3Sf0EWCTa3?CkfVFw=> zGPT;F!nq~lAA<>b4&Msb%{#cbjr;kShQBzX_B=K_3jTdX^m`|JZ8S`^E>u6{oSS$81?snlx*%34_+gVN@cMii309IDd&k zym-SK<%~|?zS9%gzE#q6SjmhQr-*o)At(8g^0$~TyOa7A1?I@C9}x63jaFZqz^uw| zfmh>v2tJt2&p$r{b?WpuXTM`Kk3Qm9S4%L0Z2G=rIvcxZ2ibkssn$Gr zly|Zl9vBzk@Fyi8cPS5w<^RI^3LA>t5D$koC{RkmdaRlvupq}8(uIZz6rX(?jO^6; z1#^yahirYV&0X9udu0sz_g{kum6zh&(HY>QbPi1Q^y!#e3%6mEwDtNmW8lZhb5Jz> zH?%n>ifcz3VB$Uob~B4{{k<<@oxD&QHPns2=o`-FRc7Mc;iFhg(iPehbr`gJZ{xP4 zD_ot73k5e^&lf>(eRV zbcpzew<_0hp%EXK2@cH~fxYAQ6@%Z)@ZKXDVQc?9T-SI3He`Lo!6zF*Nog!Qnd(3y z<7|vvGze`R9`JH^nz%&?I`H)O2nz5%hym}kNmMzW)cR#eW=}ds9`408eR{M@N+187 z7J6OxqTrcOe@qraCF?c+RuAp02dA`rY?${8j<42YMeW6~a@{Gh&Vo=(T{)4KpOZwN znIHJT-ifp;HHU3f4Hu_8ljQDf-U5$y48^9)Yw>eKFung<&uKm^W!pTP;k)%-iqV?| znq@|KLnQ@$g>2PdwpaLujAq(j2ea8>D~0#D2xNY?foQiCYrHMXIM84=8#P%`QVPDy z38K{6a(pP2%};;Y1%t<(!!(U=aCWU7>3oS~AGTSdlBpcE4IBUoBfIcXkSEFBQ3DG7 zi$ClnaGU1_>UjK#A8H){QOh*hxWgH2R%Sncao&oY`xOU@$4)N;={o>^pt~rly~Vl(Z&fBYj2h{!PQW>%Z~f;+eEAeJRyl z(4{Gne(XYE0B`qVIDKDThZ1qe1rL-3`?e|$wbBK?Q_w25FwKwjetM%SrlG#10(&H> z46SQ_@eVh>qWib~XtaMJ*t?eDvafFRHpQ3em2HE?;^U$XRc?`FIMqpAQA|5A*qr-xz&bQ$U5ca))w{}h&v_riRZBy0 zi&qtN%RInkm5%r&zz7N+t%O=3`=#UdhL3o3i2Xk9fR%$jvO$3+So&WQOu3^)UjLc% zF7JCF=h-^ZXXO~Cq+^de8h&$st8;k&(XxVLDI8`vIYG9{St#D)0^aM=dG!hhxK76KE6IGt%foz~&=0u!IUG+U zMzU}I2T()LiU?{%E=iIh~t7$u!&EpQXX*PE!UX^^3zu@@y zie&b8@sx%KJHdIKFBcNs%a?pTfm${qc0}_wj@q%&YLT-Py+7bdQ$P3OG95A1`me;p zwq@9Hb2PdvHl-;ymh!HvYoWhOm0%BtO64c9{?rLkO5r>F>ZK;IAx-%^Sq|1qj!y%x zW9PXA{*J;tZNAthV-GH{_{o17Za}`H){9by9HFO5Z@7!oeX;Ms8k#h;9S{9eCW&!V zS#)^?ym~sG?ecvFc9*6KJBatci6Iu>Ud;8&DU_ba2>(JqPNoqT# zM(@6?q+_*y-1B-hzQK1QU!$~~My=b7f(QvF3iD{WqleksqiOJ|_8gi$+lsTQB=2NAQ3209pK!P1b#Qy*eUVgb8VoBpXYMag zaO_P9#2Qayk#bXE^@AZ4uc6E<6t8FX_-uRn?YKJS3-;}gLocQP|FlVXGXE@DkyB2LyCN4q^tDfC(W z|2>jiZ$mVcw#{daYnEfT!$4YNp@`!LP7%v>+2hyp1eCuM0;9(E!7c~E>ta5Z{(f6S z&Y|95c>OJRKUtDK_*${j^(FAiUC8=P|BAP_8^8kT3%GsZAspUgjb^TXT!))3?KBPG zHoqu?1D%E3JEflh+a$Q-D8UAGPQg4yQ_ASe!E=*^_g|>ZKQ6tD!K%)nI3N?21`3>5 z8+rC*TDs`dt40j0x{j@%r{T68!8|SXzyjc5nCT@>Wz}15MBO>;x;}vV!i9m+XAeHs zPjE54S;~?HFNx(LP5jod&)WL18ckF_F8=yf1U}vAaQERMu;WgF#jbGfT~sVqY?#6R zJ-1|i?-DqZ`NN>{b~kVD=>l@u!8j7M_!Su*FlOda$g^z|X9hQmcdtLo&#$QA#9gu6 z^&3ybh2Aefal;(g|9T|3n5`i_L9_Jh^<7B&QGhH=lQWBm6#uFGSzU6dl-uX-gq=){ zo4x)We_A*X69SwB_Pr@Td3`*0Y3WhOI_3hko$oN z?^#IG)2tKXVSx&?BXKB{FHxc1Um2pDman)>bA;%Yn+#+Aqd?}45@bnf!=|SW{7kui zcsOPrckxLg_$in%ug}JiH`xoiT+YL`Elc>gMa6vRE?>yZpHFMY6ruX{pDcFWA-J2H zi+X-f|XYKrBTACy5p&|Bbak7YwkkHCC?Z!T;4ZMd>} z2pS(4i4w1T_)SY@!|wLQD2|Y%tO=)}wcr9DawnLb5@(@roeUQKOTj5_-jsIt4OaNH z<3TG43VfXal_8fP>G56MyXFn=uN8&8aYbTrKrc=>?Fd(EB-yvNJ-Fqe6Y8q2K>bJ6 z;Bwkc$PNr9@$cV!l9$ko8!{3%E5GG3`)WA5%fM8nlt7|)IZPTgfLC-hpaUMiQJPOd zJ(Yp@seCGbzGFDPTDB8T{@w{&l6d~o_H^VwtAnZeBVo3`iGQvqu<~o|p`tR97k3LY z;CrTQr>mN%(?5(e$@WDPo9}pRs0*91y;zv<&SHJpFEKS$6LLNkQ`{Rz_N}Xo83)Zr zJGn*R_h<)y>5va7Ye-O%_DnvYVk_s>I2xwC3qquVQ^_cp35nAR%Q{9TY;=8f#I56H; zG)r8AMgHHhGGZ`kj^Bu3>v^=k*9S*@RoH$@wa-c;Hl4NN_&TLm+dWR zeC$6gx|o4?B`cuwMjguReg%U!O=p=}AF#J!1TK(?hhJIIuwl$wF3nM>qrHo;=iDBg z+?@}%=6QnZip_}SvH~A=0J>S*(xH{B*{FA#v^1`ZKPIr1x4pbflD|ix^QUkc@idd9 zQ{^yLcPbUX8p!qsog|0*53y83$njU5!0^b6WO;w1D9~tb%kCy=?GgYt%3=}0VIL_VGN@RC4J)t2plU>9J8vQF= z#7!xn_tPY4#8fFXerZl;3ntO@3+3GS+jVHvZ9uDjjN#=s?kD#FnxN$7#H`JX*m2)> zXv_0qj+&o%i|66&xO6-`HG54#hKKp!tM7$5`4zS!`vDysn?&);)=`C39BoK1hZJWm z++22$4?XgRukkcuu2To#mtW&>)E*NSWA=ytwrv>B^o-+fzKMil$yS;cphY{aXOdU2 z5?2)+#bUVGoTg_K&X0@3<68utY}`?<+hHY=wH?#EJ=?~>>N;LgspWnJ|HSVfMv%36 zI$+oYb}3Rsfulb1347GQ;pGjGo09>lTR74Tc>_}F8q9v32QKc)W3S!`{FcYjpueF4 z7Uim8{=Q@==uUu}SKonIU^$J5%*SLO2jYTk_@bwC=uFIP-UFXvz@HNIDdfoJa0?%C zXDLRzRzc#G<4hsl1f{+6Ap7Y67BaP*cX)Azf3Yrz&6r`&G7Ao~qn0(0dT$JT{J4lp zrLrmPZHD-n?Mu*mV2I)B)~u~y0j-yLB|0OWAb2swoWzn&_IKn^8g!0JkvO<%zj(E0{T4}ckXjxlP83+9Vw}zk-MugwkV$-nzrKI zBEjDzbAaz0GLHf}Hjq)cD#Z_o#Z%_ako4*wG|nsFo1{a~Qu8?|YW;!|`+nZpYYHfo z#PM%NXE2A5y{P9|1-*9f@X}4;8)=`;_t~nE?{)=x(=(WkE1p56Y9pL`GoE`U9|Ibf zH^FS(ZSa<)ag=_t^^}}QI%7GJ){kq%y6`ii;9D|G`H%3tgzRzr2Z1{#)Nr~NL;0|~ zKKS&F6+AMJ$C){9G^EiIFMUv<76)lIHFPk!bw<*g*bekDZ4hSQMzrDlIlz-4?0dL5 z-hQ}6@YX%X(OqLn)3A!Sx4FQ5ldp$j-i=cpzmt#Xc!b5n#;~9{uc3e7d92G7oIb6l z%rnPA$X9=W@rpt=8S^1oL~Qq`qg<`G9Bll1l?&W<7j_Nrf`9%>{QDkd1oA~p z@IrTCz7R6+7GlS1!J$j2=_NrnipuojpDb2bz2{HbF63g01g=n+H}^v?i90jB0sRxB z(Nji|Zhy6d@$*WsDSJHmWt`^DJEcTC}P8hBHJ)?Bdto z{MfhN*yv&i#yd4w(4$)*&}J}N?PkLXWetGrrZ zskV1jOdyi!0 zx6-iB5@MCbh4^EWCOcj}h&uksvw##=X1-p5S$b(e=84B}+&TltuNHiX!FSk_(OYom z_pexUqJ-ZRAjMqWT)E}01QTr#hFm=&?k$^3&CAS0uiokKS1#vZq~{J?D-v7@GDBgj zu>$L_-NFwYeitvR{GYD_m?r<3d;j?W9(vir`#OFA5tP891Lw$TeGbJHF2M;`h563L z<PwuL)@uX^y$GqD7@tepG@+_wR4mye8>`%U!cRmv2&EYFMxcrlSp>#V5;ow zfdBrMa6cVm&_P@bT;ezQwMHGgnuyn~jlhij1*9eP#+4TYQo-grvJvKgO%*L-T>-mTAoQU0sAR`+rI%aW-S;yQ~t zuoyfoSqSICq{u1p3OMLbMD& zOpO}J#G3~&%Mt#3>Ck4-o3{-{9Dd9HE>$AKx65!(_*dT6N{OlM6EUriWnAm>Fz#>1 zR&j1|8u!j=A*&Y{ztOiuP`vy#204aNNUuJ7n4J!DPO7kx150t%?0sy`rw2IfPa;gI zH)IQgKEs}`)mZub1E0Th3zX={3T~YPaIa-JWay8@iUZp?bv-jMo?{I4+lR3&%UXCU z>k4P+V1em;SEY7pb9V{VGN)59RL${uRRUgDfp z8bPNr5eMvg4i^QkMv~cUK8ibt$7u&&YjYe5f3%{FTnM)`SBd$X-((9Cn{eigBiLfw zgvv)Wg*w@bwH?dnt%8P;MAkbFZFsD-c#Vde*0DG%SJr>zEKa`}4#p!7;J;tPX<~i{ z{1~YK58UH8i?qGsiyvzEK*N!A!Q%kxc$~qW+yac*`~ss?H=uS!I`?aD2PF1?!{(Xt zHIeTZ)r`?stGV&luqMY+nUxkPu?v59gW16pgrw_uA~_nX->I{4icjIpgKQxS1*B{9 z5qhqvvQZ;XLB*53%<8kiqMy-lqxVb5`w{Uc`-)lcH*Ed7huW!MEovm z%;q)QK$_NOT75Aak4;o!2XDk-QB^NCY|8<;`DvWDODN})Zw`Oq3QApP@M z6wM3cGS&+2&j1}w1jCHhDq;3~0Qb4al5@gt z=xyPU-ep2+Y9f2s@)YzMwXlEv7aX`42 zVVHW+0%lJT`a8>i@#p&Hv)jAl&~|G#Kg&>_MOco2`zDdJTdfyZfWfAV$a+3;!n{5KZ@N8C;WeV2xvj2tu*M){3s> zt)zYJZFne6omld8I{&&F57~3VtXP>sSL~qS_d@8r`(&ydaSu$F1mb12^>EiIQ|L|9 z@*lM;u<*hyZkMGIyHFCw8WfA!vl0!a@b4q%Qfy4`-}vMDXMOyo!7-G3?In1qU&aT! zT|n><;p}-w!T04XkR0a7epNhy%8xcoP1u36kvPoCreEPEYRuxI-&+aJy``eICC#{c z^<&&+CCp2gA^h3a4XgbW$(+*$^@ss1zt@R!JCa$~EJND!MA-Lf34<9AFLS4I8-C%N##8fXUQZ%qe^XL`X#8rTQ-T z8Ji*6mbnsV4O2ky$>%$Vy0f%V%lNOSMlqd=yS(R`t1u&f4?>Uw_MXka*4R*5T}ilS zuQoNRq|+X`C49-V2cowZ{2=m4Dt)pOYReZnaA|KWoqj90>3$AkLI{A9{$hzY-Irly z*GE3<_#IFmqCl&^%))?YN+c2(s0WHeX@S}^z*~{*x|A^M&Hf6vKaFLpor7`l`3E5R zUl)2bW#FC!Hw@A{WIZc-1ZfwZ6FElea&j#P$o=>%nD?v$HEp}W_LUXp{rn52$1m}& zhk9}Mq`55ZeGn~-9}T{{EJ)&qC7tLPLd|*0__#|sWFr>_=Oj(gZx64dR7@%$3{ak12Du`nad`51tO1}e16WGOnw zSMY^el60zL6suKoXY~d9xGP(ah?@7R(#(-MG(1_ErYHELuKpCV;V!^6=)%u!8PqZP zAU2Pj30-%QS)?F)AI4Ui5RZ9%*c*R~mX%&w++mj=Z`mF}^E|b=;bX zQ>2Amkas`Pr^cRgzdykjTBG>gIyLZcsSi_xD=6MLi|Vz_>6H3wOsLq1K@VjK`;+)C zErKdLTU@e7pL0>p#mHM#{NL6jE_dZv_#DBpeGdI#V3Gqqxq8g5e=&`9GN6h#vuTv< zP+B}N7(J}wA);4ATU}PME4u{uM&O(`q))0jmpO&o-w_U1!t<%e@$CHQ_97D77X_%J~EowB2h6f(P?)d(plp7F*sn`E; zYVIGQV8=kb`#uOXH^zfb%1z$w%^uOL4RL&yTr_XutczjY|M0E5IS`$ zz%l(loH(a~FEvR()5C@WZ+j!RZ%HRk2)!$ks`KFvpUuM!8EMcdtIY|h9X4ayDem3* zEcoaX1p6+0hM4aA{5^SXv2>g-QeH7KLn3v z&V$3zK{)8ib)35U39KHT%?ctl>4wd6tj*dW&e?DS5@t1Vvu>)<$7h!Tj?RJ?)@zv2 z8)X)*Kbf_qw!qKTh1hshnPS5x;m-k`s6M?9&&ABa2hpQpT<#!R@Q|auzT2tbzs9y%H_4If6kwIba`C3(dF9 z!ET`udpv0vyLI%i^*zszApRDM9aoI$$YdWBr`*DJGr?Ji`{`*;41!Y=p1ArCTlQY( ze+#Ylh4+7*Gc9+Dz^H<`_v3{W67y(l)OVG@0Dw-^)g`KYr zu{}|O1%K$Gt3FFy{~4l27_+xItKoJ0 zX|`f#EWN0R6swGoWqSqob@`+rEW`7E9G!_@jo;UX8#PKwMJbgMMG{fxSvyh@iU?&$ zL>dsvEJ~566s3tYQ$&-JZs|{f$)*$@r;5PaIO|;adQ$hyRW4F*Ls#X$B zoBa^>HiU|}LnI{!S;P{+xHT>aDBMNyBtSEE=MQz2IvfL z#GuMFnz}L+SMJuJl@C&(H$I2m&-ln9ZFx@LFOE*-y+WH5dAjN1fTs4^bX@WxTXt(S z8>Cf&*1<*m*6cty+84P@BHrs_|EkQ@4rP5V|5e@fBu9mDU)&KLRFmp{s4NG9}%T57v9cl>)E@Fn{mK= zTb$11*{!QJ9QQDdz6$Q!U7m5&vO!9quU!y^NSC`<*|{}FhR)SP7}kT$C2nU-izb~$L@>Os_eIeHkf(jgSqKB*f&do z2DM3I@}VU#?b0A=qB6YuQZ#`b7xV$^y+ni+Z<7oN#S z$(JK&m*q~rDf$GMJeP!LQt{-PRRE_rCFXNvIoom&o zeeY67)n(r>@<9sAaXo ztvJVD_)iz*e@>v|3#I6T14F|^MRw@7K4Y^1HVSU!Ro0GdgW62sejBq|^AWIpsvMT~ z9bz|H$FQnNDipEqAhirifx(0Apv^M|60%?7_FHq=o}Gtq;?x-S=4Ak6PR!xgm#eY- zgjH^J0W=LRlWg_XpPx zR3+QfYf(6e1g1b1HQP+WWjs%x+g@-VV{%2l-8-18TnN*;^hKEC*-*=s0yOG=iuuP+ z@@`vI>H4xTzT$~CjxQDShZ+ZiMsyeEys5Tf(@Wa9aCiIBjqb7t^I> ztSPk$Mq0mu*)q*=^7lu97i7zN4-cimy6?G)upnHp<}keX48mZ6$uld)0;TOdn4EbX zj#H@wSGh=9^xlT#zb}Tq+gi+E@-wKN-iud-zqPGyiZn_8EO@NHiJt?J>+f=8-#%_b ziyS$)wAz8KeISLh$7(<{dMg;<<~&=5Qoia^QW&s@5`S4UrMXh%usR7`#3ImpW`=`Q6%{RXL*Dm!@;3LQj5R?I<|@ZycmQdJkX5z2L$ZBx8q8IDd1$ zG5=d*BKcM(kXq_KRFl`H8TO-ShVxuXJ8sXOdK?3@0lztu4Ivd@bkuRfqG0;Za10F- zc>3obIP!<58-vp9Y-l_#%VryCkhacuOx1Uy?$?4JPyYyRviQJ_4qDD;ZC7BbPA)Xe z-JTL}*5DkM?bLcr#b&N-7M4t&#bjP3z;*o|a1U`{7gxC9rsi~UXwYuXyXG}Nbh8rX z=Dq>njdH^0y`AK5{T7A@D)eA&G}mBR!|Uiuf!;PhXpJ7gDh^xYFh^@XEvd0$ilR0d zIy^!BbRjQ!-Icu^w4ZKCKSQaPOKGE)Eb}juA=3?C(7r>+{`*Sfu#L{xmp+S*Zr+OG zj4EC_OK?yu=;P0>DB;8ZTO|Ik{Q%B7GKKxqS;pb$-*DyM1QsOu5|%G9q@^cEpyNba zwqW-p_U5e_3;Q&d?dt4@MZ0Vuw~E1lb1nEmD(`dSG(-dGtDN@c;LeMGIeZ`DJ1u ztEbBSu-(P(9OhxZnIW5|z5regnamd4ogxkx?8!b&E#h~*zJi;p1XP*)QMhd)flkWS zT#Ae*-3)()?2t4xD~P|*s=n3Gj{3fJ$PXE94{A6CcYqC ztP$PH=@&;}vyvAcopuAK_#MOQb=5oRdudcCQGJ$xqc zSu?C`Ls1N}8@uS8j59O7I+6D8Q5EUsWxy)&4R&DgQkZfr9bQaR#DD#&EaJl;I@SLK z&veAIjAQl`dPJY)%<}<_^L|uKMl7f?PMF)SrB=0ZP@vS#ZMc~T1G9Wd;-EhNx;mZO zs_)y3o6*Y4*KsuT<4io+5JQhNy0GkS3M=WK$UYpNY#a2wj4SMvqWKwX$$P<0mbTgh z#Py$1dBp%~A1uwJzTC$}&#N$7+k%uoSkcBy=i%(Gue?jRH@Mv{Cg%q)IFrCwdV_jM zA8YaB`bc`Kb&6*6G=pmBbguKUE0a31nO>-dvl^3^f1)R%B|_$2!Ic^hkfVnTUPg;GT}v~=-sd@=8y*!yoZG|CQVk8@VS z`0=YSuB8OjuA8$TmNw`qyNT|9AHv!WePn&9g5SxZ7H$b$l;M3+#Fhkbx7Ov+4$5Zz zebNKg^r`t?WwTD@)F;B@EoU}EoHl?M3*8|EAc?ieI_|35?!whqdll4+>5=K zd9N}1yD$`&n0r%NQ3UzlT>}2u0f^rlSgy@y>zmoBG;oFz^Yb}LNs|e?w5xfmPz5K8(n`z&9H&*^zh2hyUbcqhf(RMZH9Ni1+&qlEIg)@XuKGp{bv#Vu&(^uq^LMUnmXM!IFjf#}xp`9Lzdg9A>o`5=I?i%t z`jPpJdbawGqr?8=%StzJ3ga0qaXb!@{rNb? z?>dwyRDt)&VtnZ$bp8?(`3aXSSb+3fSdhG&DY^UygO-^v6Hb%mKqC$m_`2Tr|HCtb zvtZ|FV|rbE8Fb2Ya989m*0*Dv$p7piQNQkd*nMIMH*ZlXpJnI8W=N;dFIg}4^Z8+c zm0JyMFJie_->vzgDp|@t*3H{}*-evtTk!S8rR>q;QS9NZ9DaLQIe+uEF!QROf|Cp0 z3I4k*bl1KHQqKh*(j5sh8n6=<*j#{=k+M+p%7c=lyzw`C19ScjqX+zKwwj$_hPqGS zL8=E+RINeJ!SmSgj0p7mc#6M&qyT%4#ImZWDdO8FP02931pBE9_tY#!yL4STw>gV{ zHuyZqxBJ8JXSb-aP~BH03^JP#kq7?WVCK3E)+O9nWibQrMViW3=LzK zheW?DGc3cLbYF-fo9Zkc@FX7{nF)pa&|v%9@iya zIzO8A`UlWvy&K>w@Ky(|Q)Ul#m1Aux2Os8|Q~cX;7^Hni{6RO0o02?5yhP$9=kGEM zDt(l>>uaaNLz{1W<7;(x?1vFsKJq)Vb*^Dpz|HFOue{p!(e7;G46pi4+ z@!?OQ-5=b_eJh$vCdJ`+Yq>jFyZO@3#i^qH97CEbnoq?A8f^4t86quxzE^%Ro4n^2 z?l`Om_g#~rS9LEts`gye`eh`&v#)~S1tD;6+Gto6Cn-392f$qC>)hnaC*hl!0@I(u zM5!J%ymE3P^>k%X{Na6I@5Qm=)k?^I2u^pOflTS=cZeDy^zgcj#cP%iW)eBmn6<+v z+?%n4&f1ouse&=KmWN?M);#{u;Ol5<`37`$F=`q=8rnS0Vr_he&A}}TanAR#M4Nx} znF7!B*sIt4p+Gw}vmqIF-$L%3btl$b+`?V>XG6<7A7Wll1)Oq@;C#cJNXv5|IW!I- z(c3~;V<1U^lAE|D8bpKJy;x_e8hmr$SpGGEtD)BiCDO-mtI0riZ`fBpSbimnhdzYf ztI^z*Q#VnlVo`>K1`Sz_D2T$jnR$0Gcu|n}hLi@qTGNN7LyO>gXA>MO-@#Oi_i?=7 zV_f>`2^0@E7rryPC~aJTzxCqAv`-ub4Xa=!|V&>6=+xbP0u zRR0s0<&Sa1^4Fr)XhW_*;U92!jac|U1$_Nr5g$J!3OC)fhQb%Op>^ySTr;geba?6; z(KB;19AEby7DT^?k`x_gDXI`Tj~c^fhs?xN#x)q1kbs#RE@N0&DSSH?jTe1BV2<20 z2s*oy8n=bRfFqU|qGbV<){*F}77yoSjY_8}7m${wrd*39{ z_GJO+Z#j;{b-uLt%`=`?10TZFmb4$9hCR8fK-;BXe_LsRJzpf3flQWT@P=`NahB7U~SN!?zdXRqgmzPgK z97%0=O3+hcC+R=P!1G$WalM)>iA3^DVofZ{RZpPVk*?G+sTRMlT}%7&i_uze>KJfc zIFAC*@Ou$FvQcF3qvx>OH8M=5>H+NZGiH%z-eP@x9KWh5k^3Yi&6Ph_WPQ!GaLuoo z3tc?|Bd(QUSXwgw?5_d4yTpV=gdRlcM|-e_bLRihNHmWt6S@(5aE3xUhOgaBd1LPL z4O5%&$B{VvJR<`Z#0mSG!<*UJ)^IFZy_Rp(IDnax{$fCjK1;^GaG+ZS_DULY^NL1L zcm8OWG*^*2hSYPbj+_RWUFpnE_>5ff0+$ym$4=xm!-$b~Y;-_4oPM|prZi3=SJQRu z-^IyztG^v9oVRfDrh0Vc#TwXbyPm<`r!E|ziGM@jZ#bkuHnUvr+H|SjpuJ8a%=V_B- z=?>aZY{wE+q!??uh!=<^ZDb_V4XGx86!7=rNKB>5iG-5>90T;mmJudyc^GF=0WG@qfj6< z46`dnvJ;COSmO3SAmy73fiGTT`?=5jQK7qO9ygiJM5VA8VV-K>V9E9j2txUj^<4g# zsgOE;Dtml-18nrM!9D%aP*(m26FQ~XgRVSLz1;@U;QY%ht??s7o!U%)-sHhIBMbOz zeFSUaoK_DC9+y$#snu^IO7$oS_XnFU)a{jpE==U?e`;@d<89jKjD4hj3LVJfZt-H?Mj^ z2IsiuKvBX?&U@4*%zmRn<$eaNNb(#6^-JQT`BTZbO%nV%Qut)^FA(x=49ojvI)INUVlR1@ZClD>WwR<&cBAcvreHxZwH)umIYR&rM&F4 zw;11(is8pc(3B~S;)4m3+4_$CG~Ba**O(<-c~U1)@7>Q>CY(`)szggWI&i{+Tl}3* zs?1?qF{;1Q$9F=`e$|ZMAa804CJU9}&mmh@tsu!hkKE4^X1wKl4Bun-mo}`lFyl=F z6L4?ta)hrbDD$JXd`D{s==sK?-SjY+zxXn4i%|n{*FliZ9E0n3u40DQoWMS5Al{s+ zf>Q4wPxLfjkTlX0x$qz)XFeg=i}3&o{c{xE%E zB5YS|h8^w7v@G%*PFP&Z_iHEM__8W2m_LzOlq?jP9`}NxcbatOpDbOePsi1hoaqG@ zfy!e_MK{C}Sfkkq$xHUY*N|4+QJ^Apkz1knax=JG8OvG>{h8eu30kpyCeA6}0;+>A z!|zLv;CjF*@Vc;%y_j(i{i~PPC zb+*W%ooTPVfZapKz)pedp)f#jS`WH_&to#VZOyju3kIeGZ=o>|-Wx zr!e!m8QkZUi4`4l4~Uv3=+VRL@?c+}&sL{}gO*ndJ`ujlW8P+9?2)x}H}?)oX`11} zG#RcxDj7P?E8?Ts{~$O&4cmMcQ2dk*e$%t_xMtI@ihkc{yyoo!w^S4bM&$JtCKEYZYSn-?_9>LnQQs~Oj5b1;-T1) zv(WxaNU8T#Jn(pPSb~vQJr1kE*{jkztK;k0%Q_hb7K44Y+v|8hFG-$NMu_@&3L z<*Kt6w`a5dz;E2a-n-a!P&fwy7DB+jWO34IZRTBUjXideq-H3~*RMAu<7Mt_iQ;MU zyu2Bt92Ho%mZ|OL`(~AED&DcCd#CA7pMkBVXeh*s+XzgPd(!d)6JLxRzR4AZ3thRjV-YqbE@$&NQIa@zIon?dre$HG#gCh3P@VzpX$;m+iDNSmh^PC zCZ1lchU-4H@ni2^p@9Ab{+DGewmBK%0egT+9*4;C=1a6FKFi*%w1&#PRqU;EG=1c? zNH5QZw#YV!oK#CW>k-e$XuUi8&o7)Q`|48v)_AbJGXmafHACSJXYzP)jB#5oFctYX zXet*^ALnd=m%|Q2>YN+slI;!>gDW{np&xL5v=z*i@RDonqG4g?zx;O=J)^n9Onu zDEL+q8!)Mo;wJ~Nuf2b`ZTtRWz4rhX@wtGw;%ZP2TFQUCGn?J@RHV%pFT6vN*oP1OVE9f??9{%3hUqEVHm2~jW0Jrlc@|8wb~<6I{4!MAo6WTD>61i{ zGj!xT(1GwYHvDce={;?M{`vP%?MovRrf2f|KPpu=jGt@EHcX^PyB(?Y(SFYLbd=x) zSOPT-y4-y8Z(O9kd}Ulv5KhaHB*}=uw5&yumAhV`VG5Hd{LUy$9e$SLU+=@MHpaH1 zr#u+-yr)o?`=t2xJ~LXO%|_I`g%E>U?p4Mymb){OrfSBr_V2lP`{+$<7?=yQ51bLa zW2vzH@(J3xpp^Z{J1caBKZt@wEh3xSjAfmjjtd61iUtLElf16bDYjfiS>w7fDdz^1 z++D^D8a|@`v6JMMp+n9dlA;%;Htc6-0Dapgk4laSc<*foCY{_yE+vD(|NJA|;rN#l zZyjM)nV;DI`px!BzKAr=$}@wE<+S3puwOa$f({HA20M4A(!rM}==tEQqTZngZ9XR4 z;`-)I2B*+eT-&JwvZB1_T>zwg|di2!O zg&Si+prmmE|I7FtoE*~3y|z6KzZAz|V;>yYv zhEdq|aL#SMITvEM4m4Dj;JA_!V3U>DKoa`A3BDNe^dtm~ih`}lCcNOSfPBM0mcBF`cTzng`9Y;ARaDI6$ z{L`Ki{9Ad6H>{n6++Ixdm8f_X@(=R$;AF65KCyr1fL91dpw$s99hreR(q+ zOOHu|N$VuI7q%N>hYsMTZ(aonGIt?9t_O~AU9e-s12lLy44iJCv$t#Lm$M5<40*%{O!-fAXm&SWuWD?G=KO6S1PEgw$3ZGe)dA=ohI z3V-jk2Anuq3O_cgu~f&4u=}5|5Api~&iqZt%=TtmI+o&{6ICqc(JwxF-BEC|xXe2T zU4`(X^IVY6ZS21g&qP|PXuCNCqx^&ERFD#`Y7lzLG5N4NUW0A;RmlZPC2@XI4d`iL zPflGixI85eXF2C%MHPqjO%vIsTd}+oKajGeDq+9jRZ(2rB^(|%hJu&GR}6k-0Ea5W zKw|zy=+hK>d*33Vf94XdjzwTkY8@VUZV&f@RG9e>Nmj8nRy-%V1-1o9&>rO^3&MMP0XTsM1Wj1ATc_II3_EH75*)(mPwAAf^JooJ?Zv!$#BHrhJ6{ z0eETnd6XMtiNB*Yslqb^kDk7T2@k(;=8sfZnXCyr7`}=5^7)*sW(&_NO4H_3g?#Gg z9dJ4G66?Bg70XS%*?3Gt^QGr8yXF^X?);nI+M9*R*CT{Gp%`xVi@D3%jX0|9Cg@}Z zF#oibIOKx~XX5+_c2@s`%Nsg`9hKmNbRP?Mx3}TU;YqO7W*Hedr)}uvtBmnMKzp@OeHT zf|LX<>w;r274{(iBNsj7SHt~NMG*8snF@^^D7e0r+x$6~o8O_pbT>`s@*f=o2}Kk7 zH?$fzdO6{@{kiD2){7Pn>%=#f#TaJvUer8j8gil?Sp826Mvt6{?Wd!`#@Y?~RHMN2 zh7)OOny{tkrK##vGe4laxnhmsKDw`Q(8hQEKQtDy(6jspP>_Q?I?77$^ImSCZq^0t zXdC9|9ENJ)ef6r#h&4IKV^ftEc4YL5Z0lWl^<(e(vG4xlQ+Kf;pIY?O%-nE3oRPOAO{ zZF_Id7Pxo7#1}g7SUL@oB!iiq;(9Jou;6mj*WuiJFVxbD14H=8-Rc}qUTNo`)$tZ~ z4+!C^1@018yqh&XQf6IQ(HOBrkGNenq*SWOnnc6dg|4&zV=S=RuiwErR-4ZoQH;%9 zSJ=z?2Ni#ANWsbVL+Ys7`9^&Eq~&TQU;^N^Lsma1^+P^9BYcEsme4iDoQ+bWgFV7M6rC94tZ*p zV$GGI*ggCx`YU;qS33Ow_hsKXgSg!oT$h8gP7-u#+!VNIyp$ZSoW^~D9cXaoIY{5n z;Ma!uvx!>{KHNq<_;r+S_6=rx*q*)jj{Q{Vfwms zEM>GuaD}(iaHUlZKP>eccC7h~EvL@I8s(v)pXwF-jV}miHr)WFiwIVk_AG4lVzNJH zfuq(%;M2vs#NHpbV$Qt5v|V`)t?sfSZr&J@iE)I9iSt;tS`3R*8Nj?e+HhBs932eI z$Bwi-QQYMtsM3HmZFvm7;ydv1i-E8+

    =xVzS&Aljl@RZfDt4n` z_Vws}u`%n}Ys5QojbNdXKR$l+Fp`beV{x^o@Ve+AawYdC%p0A6CmvkE_BKSZHC!g4 zR>>siILAAILP){4E`d)&51Cgpy?EB|PrPIOCl}N`g)EwT63b+9SY17yyeXbd)@NSC z1AlbU(@E<1MD%n#ATpPoDP6&oZA9=Bb!lpO&w@aZ81pqT2Xj7aSyJ*59s9hQ>^8eX zcB~B|V$(BOv(rp=n7S}=Z$I`yZ3UEmc?jwM_l>>%1Q8R8>dwUJ7k& z-Wx=o%}gVidP7)j72@*A$Op%>*^#<*}9| z@4bhf?)1U8v&(QO?@Ndr20TIyz{<^ntjTOAf2PhRvO1et)qzkJH@vFkm5~_UM^dnb zs6Bc2`ZFg!HHvJiNG6kIRZD`mhBLp6X!a>rk!>nygwx$?*}tdNxX#cQF1hLAWxr&} zu&XRPcS()hdKJ%Ziq^3qgAgc`m;yfwE!f$$DNHciiFUYe=e9cWbJ|IjI3`}1%>SxI zQUr&nO(D9&7NMk$gDRC zF>goAq|dsumo5GRGxd7(T(5`(F8PO?R|jDM&-v({!Ow;UIDzBV1DuJ7E_^t%gL>w4 zAO$;Zz9TP2yihk+ZZ{K|4`7a-bx`q!_#Vu&Z;m;776%Dxu=0LyQSKMA0%}ovM$I&`l$e~JWBHT8QERrvPf6j<){pW+; z2F}5;ok2XW;Q~?6iXbOWXA+egUx?m!3*)%0s>I{EANGbD_#BZTZ!a;TuqTjw*Li_Y zsQe-%>L!T|T7#F8SW;}(N)DTtk+Yi5NTTcuV*9g$4k$f=jNTng|MhBC@x*{BI{t)1 zJ$y#d$rXRyF^NH4K9=mzz~`3-Vx_~LF#UTWT3$Aa{&rj@^&5^5ALVdTWMqo0w&${I zhTGVU%z4-_W+GE>62j*WPF=h{-yO8BI}4UOM`M?BchS_BPN=~xpCB}rWh?2^k8m-Z=oCTOKpllX0w5{TExi z_9v|qnoW+dS)}&^?@}`zL%xm*$e`C#bmR3F^8VRv$gk+eWmiQ}E#G5EI4a6+65f;h z;|i1>Za{@;>shrV$NK&*p|SE?*o=#bOm0;L2;Qi%83qaLEIr6lGSa|cD2tV;7~nT| zH-Uh^t87mxg}F+?tYLWuEYmy4o+@2rBioO`(K$KP^j|T4x-t(R`nQ4gS%1bCdo@_; z%?5ZHSkLr34ltLu`-r;pbK)l(L#!?H=ohq=Jb2WPl~ca5;rc}OVnZ1FMNZ>O31_gy zo1;AYkKZTgMRPg>&tT+HB^YU$QK7pg>l|kdr)B1$DN)afT*);;3?*=1_;1+n zcam5;YZKkedaStd2}&EW10&5vQ08es(ncil&!P;n|3VCW`=CLbf2NZ`i#POkpS|`?ViP9&;mhJiWc;+Nm{}G>Ynu`FS(HLAC2ePO6vbGU z*DUaGyNWGGmw?S5Pkb|f1G%`n3jZA2fQ>soAgROg*sW2QP?Z&+(#pH3q{7k2hg|w6 zvKzm&b0SqcY{_+qBeoiqcuV9Wc1f_8ZArfd_jHt*WKA5~vy*2jyH00{Y%a@tco(Qe zHo7(?TUHKYV^{Xhb|7uCc^)>p%j%0AGn znLyUnOELFU6Sn2x9tJjfP^lil+IWYIy5cPS%xMWZHro>ojBBS(^3u%jo(7q)VgT|+ zq&Vqy6?ka71}?q44&K#uao;`V$bNbOKX|T~DLZ9tn}e8Iymjv&$e0RK|Djhb%pZpIVNXoXBZ3Hwn8^+i6c z>i%x_boOcXbZs1K<1VptE&fEeem5~2qeA}j8L^Mi;pnL0N)oLmTrw@Pjp;<(W3Qe` zu;Y*7Sl#?#nCz1Xvj>HVr8eNIQz~p>|1YfHcZ3vtasdggne5Y-YTVlY2-}WY;I*SN z;`6T(}%@AZldM06dA3UNj9C@NA}%vfGY0| z?9jy&hW?&n+~M=gW3n#OowJ`lvR21}WhddMmkH^NYQ%#&qgeBd7h7xi7P90ou;EA{ z67!@Q&neU;3igdCB+(2Qq9HqkVlRP3^G6OnFv zjrY4uggKIPQOvz_c(H6Sd_RzicZ(R2$Tzm><`vXvs;blG(CXTo|b=LUG zoQaqzuxr9e%-LR+ZA$aQ6H->ti2M7&?)4Pbbw3lI5c`hST~h}vT|q2^#~8m{cZs-{ z@Z6wJRXF&TB2KvO$I@I{ncwb->{VbCl-_y_N9>H~W>ZzP{z^1fRX4$1`)gsek2gKp;66vNQP|EzYGm2@ ztdC&%V*^u)H$_u?a`}8ZVz*BYV&BvbT2QzLG{ToLwnT7Jr+~#zt$_F+DR{~vp6`?82=`1* za3CLtn`I)1g473`mlVM6Z$88PLnhhlh7A$89y^nCX%TP}E=)5l+NkV0&s3_-wv6+p**#%@U3@^4xHat~@>) za<&PR;wPse-bfyb{r18kuQF!juPV4yxfQ?GD1?r)$=Fgh5lc-|!wzdU(7Z$QSe~Ih zYt&GK@1KIf*l`j2_C=dX>^TT2k^P_)HJcr^zsj~$tCn<~=J%t4(!}&hCa5Ofz*8Pt z;`%8)c!v5#_DJF){`L1D@s`$MD&PEhuI3#!!{PyaeIiRHwvLCIwXx)7GbZCV=b)QN z5}Q5m;-o4b!s(D)c<#b;OpJHK!ns21ylx18j_678PCpy4ZxUB0@}_VP^23V zzJIi!Qg;gbeqk(|f6^9;|J~w5+Xhj2n;O}rX~phy)@-NP2cm2^(fHfmg~nMAUPGUG z4CX>5Sx}=jE?=@7?^;)iFFjul_wP<-l3kxc$~Oz;u9---1gf*>*-yZI|4%SjUBHev zCF6H{Is%jVPT$Vl z^KhQ$5zI0Qz|)JXVT@H9n6>?-{oc2+chf?+oHv8ri+>H=OD7gBc8m$#{R-clE8!PT zfjMrg;ggjQoBLgj1sGr$vR}ZyyjjHl&Qrs`3Lm1W=FdpWk!@r&oo9{PX)?*;dytp& z0G~3|gE?!2*x0k-sO&!(lG9dCH#hP;y@dyOh|}4}Hwl zuO8T4WmKbml&U_o60A5APP)aWldbRa@XxbtaC3Pm^Uiq7f(>=?g|s3ZZ|sBHwP&%e zBo9~}9LXw+lJT4Gx%kJq=}00v3;*hHAWh0gN*-)R2pdoOcFbCSyY;obdTg;_!9IjTK&Z@5EgW}*Aay4@itN)96 zSBVCi}lULyDFEBqcZ z0gGoMtS|X09FO4p_%4^A*S!g?s&>Z@r%hv(c21B;H?TP|TkuJp9Q<)aoSC#@b|-Wp z-EN#go0mqSaw}c@rj&PC_C8{ckt)P0T$Gt@Z5R9=cueJ=d}O0%_OgE~f8qSP5@Pd4 znOsZgq-3}NckGx(E-O#KXK!xBVI#rV==%$-+oMe?ujk@O!^uoDEt@sCPGn&-Gf0_v z7}=evNp5XT#p61?S#S}6#+nzz{?~luezOc%hb_)l9L19 zv$UAO$}nbpvlX9q@FOjQibQNuGXGAH#(`CbNa+wEan?g<;;|&Q=GtCjm!wCORtG}x zEFJvEcsdK1Axw@~Rb#30P|~$MusF3x6&bgRk^8sL!R%lwyoP5W=Fa;MK1i*?iyJ@T zXGd~budZm&R}^&YiY30hqs3iq4oTVk5sT$p78PaK;a-^_ zJWDAB&2OHKu75tn%LEKb;o_Ib^+Opk7}g{eg^#h>9L7AW82_!GT9T?}MKn}&;K$<_ z>^O~QI`pUFRLwcWLxgwitzJe7-cBTS!&F)GSn?uYF`1|U1`GRhq-gAd!NJ2iXNl*Z>mghf-PI# ze1yo|dP&%rnPkR6lahP#@+B5C{;@!(7C7km4ErivA=7?Hz@<}bn7pF^AI(x`3DrjA z@3ToXcUlfiuABg)XeWKUBMhvr#tL4_sN=~UgQ!@i5P}{Y!mDDcQRGE2YPn8`g&&*? zkGDp%k;#PRUMZ$RVY*DjGmU;%s)jmI3YGy20eFU{>awNqMzjVd#FWCoi+a2^xQ-Ry6NFZFN^2!%#CSDclc55bvRdb4s_$C@F9)6;P)vL-%B}* zJEn}sbK^vq{PYaaOb(!(5#k`HZHXhdDhclFL`b*cHnwq?_&{J=kK+w(6{$oe zB}7&O-Sa-T?AbsW8A)YJAuCDRyC_OS(V#-1(mn5UmFx;3TLU3kkuQ?+`~3cc9=H2B zpL1XD*ZcXz@ydXXZpCCvY!=*C=u4yeD~K|$6+?#a2$p*C0)FyRVD|-2;J|xtq5k9_ z5Wj!G4r>j9PZ^D%yUQ6>s^anUcUiRBbsZ0}9VGO^G&nxckiK{k!2a|IJ%HT|!fM0t zj`~8FXq`je3BP|eOO5!R;L-d;u?gKWI#tp!uM+*+8nI&1WeoZ}9iQcoQrN4Zia&P^Crdqi$aybS8eQVU?A8c#>yabr z{Ec~7(((~Tk})FN`_XJyNDEjOzmfQ_j;P2zQ7Vb`bptCIUzCa_qKoZSwDOxGNnTe* zWK5D_uF^;H(bfpfR_#R3w?P%-h6GE#3GCkjOII)s8BAw9Jpcj1nK*KuGWb`I;>X*r zq3`xjIDYJC$|^JQr1wbPGP@48?p5INJ|1_-I~Efk@XNz+JOfqn}g`S2^6f`j`*rgaz(huS!pFf@MlG+IW9%|?mvm0 zRyk9csDVvqt*DRLV~jv|P*2xj54nATBUMIqn^*zwg9D@QsgIrKHB~~}W(7-+p9Oay_ zd?tdof(t1Kjl!j??!mLy`@zpaMMEqBkady^p4c!-^_%ryq`R7SnZA1j3?sl-fnRByoKFaX>7q2gdMGl z*w?@aug%^kxSM*&q(wqbBd{TRHp;P~dGmO9@mGB7sl^u_p2lALen#`w!F2olI!x9CwH6;@wagi^_e(%0!q*&aarwlK> z+`%MfBba=D#_WfQ@#^t7h<jScGP7n40&WIFq$$TN$&uRH;jZ9Pi64YP7+*Y=b3!1F`qv?5)Ta(xC_GEdT9G2 zRH{CLpC?wr~xZs;4E3QvHcll^uNi&kP&tLzu}2W1@H974w^(fMchr^EvH=FBozh ze7&8~)hSl+TuuSoUR|Ew^$oWMz9Y$3CgU`dcW7|r6O^3qC)&8a1NxIhcA+wZb!wi5 z?67Fi_P;~M5;e~@!-f44S;d1YvL#oCN6~xucf5hH zUs{2N(WfzacN`n*Tm`00^8BP>9j?jvDk)8h$1xKcQF+o7!S_;(npvBmE%5>DdO4m> zU;dED{5oMH02UxuEt1K{%3$%<<@Dl4U-~oP5xQ9xGrMR8V@h?Ag}T6+6>Fh!vJ<{| z-UoUcQ{ir1JSdEvjFDEs@!~i(AAKyEt=|QmjViQMnAOOt z2%WU3Ac(80CEd4LC%4Xd2*0%QvHN-zvTI3fNTs~!u+Ld&Ug81C=}N+0{$6@|)(Oei zk&%-7%GRuJW4h>dL5n0nQ{dLTHKr5DIS7!MPJ4Cs)1={<;49>$9+QJ{aCb7(lUoVz zj)*a0<`F!g_!9W>^Q<8262=($vWKg?aip^h1aEl2)Zbd-s$JT=rTHTM`<#bKDTe4U z@S()_wVq`AlTO6eUZ!|2jJ?~7xY?;rGGonAm>qkSrE znBt*KO)ZY2b@420@UaI&Lpw|;Xk__wP5J4uhhY2t&lp&}i6y1ilVi0q*k|rfj2q}A z(fSa}(yj@N7p*-+e#sGb@~<95Tp9+t^RJN_=L|f;t!TI99-7^I2gW)qW5X2(VdP&m zJTd^=|-k-BeCQ9%}$pA&jAH%)Nt8wFlCXEnI%Xyd3KHu%D*1!P)E zShkHf=uXk4sz>TYs=lj0F6IgZm1^5W4;+f&k)e2V*+cA%6}%S%En(fAl_>9%gkBE! zaf^B%On5BtiT1r<5B?RRM0Op2xL1cJoDs4)w|Y1=bsn9)awhezD@HZH-E?|qD&|kg z!COKfG0tcU-dHySdm@C{_ticu`@N>k#b1-~>*~IcQfZA(QvBd#$|(~0TaByM%*U#g zA{H{dj*aw9gXdAn?Bt&5AYT*>uUf;QbiG@fNSyfKwC6lzx5a-CAWhlx4cD0|R)g#?>+5f$%r_~|$Wcx(@2+L_GGb}GK_lZ`6prFhNmGO2p&LD%mz zM2$(2WPooj>`P1`@kX97ZGAMJ{}u)#3=YHE*imHjy>OWN;uLQ5ZGimBO4elk3NuV~ z$cST4&}?iR+Rm(G2K}Q!N9e(p=gwpmeRiU6@Jf=Nr2u<94IyBOHaty;0PT*QaIfMXxzwL9^G`M7f3{%Kj0*O9{a%s0Nvq_@{8MD@>OzsvMq^Bn zW@DXsI$FpZqmrlyhj#^$*|G;=h1M1@Tj>Cf>KV{=po#I5axf@bLR+@z&_Q+g(C2s} zpR_m>-@Mg>k2->rph%Njc6buYs;d>vFV3;p{3OY~u4bG#)ff*hH{!!JBDw9B4stK& zH^fXGfumdjssx|&f_^L55cgGh$w!Qj731*7W{MkYdNHJPh$uQTmFe4QWACMPa6=Ra zviP%{44u=CvYy7#;Htk7cYnDA71MvS zroaP|ayw1F>G=!Nr%a2liIwAhG?68H^#Qub1j{|AvT1kJssHC~IQqOJsSAGy`VX{3 zFAY6Orp`=!u#;fZjXW?+?1ASw=Jfp65A4O<=Ni&~!wqPhRv%bhc?PC!=nKQQM@ps~+epsTZzPr> z+c5FTKytJ+l#H9OgqHP~z~sJy57m6O&<7Yn^p^L*U%CP_b%ZY8sg+N>%2FVIj3X!v zEktJn8+x`tj+1BBT+Vqa|CKu$00>vT?f8a zydzN=YXmcF%h7L^A%FX96dzL>$V*Bl5z7Qm7;yZA=ykF=%|5D3mRTUwFTM+Vj&xK^ zO4O%nlPy?@%|BGP8IP|eDa4H)u6R&=3KlFXXLC>G;AZze)aSxPQRTR0==*m#gb3ZH zxz2wu;iMYbcI+@dk17>8B_eLSc&1`bTn4J2t73Wf?db8}P*hl-FZ!Y3hShV0ygB*+ zsBg|j)1DPLY9YZZ-V0F=HDHBtE?oI*guYwsP-B}WmEZl5Xb1GgLU}`B4Zk1mKYWly zS}D`Du|wI=fONsa6TSdCtB4?%uP zF|1e?2;FId<0xSs49*L+i4-!x@{xJ4Y3B`c>3|QH&3XbpF(crjVlxgIcL_H87m^I; zE3E5)h2R;zO+0P;@ESicZxZG+yXFDvzG{+8d2*cHUoJdrKWnir;uG<@bf0XR*G5Xe z9mAUrf>Sb}5-hu?lBuDaG4H=%+)_1(EF8RuH^w)j`bKq-i!WqzWp1!@pC?GdKn8WT z9R`O3P2@sq3+xyUWTHip;hY9cSm)b|klArx}vc9Uw{X;m^O-g|r`b@Yp30K~x zsnE3WCDYq2gGC+B(OzKft$Cb@?KcYXLYOSaqd(Xa;U1*9cr)0Yt;H|$Lfkte1iZAw zD6vjO`=Cg8T0a_&j3{B5|K(I<*&35&Wy?kV_a`t1b5mhgEgAaQY{b2AkA=+&0{!C` zNzkqWRGF3XFb&%~KWEp6Nt_e0{DJoNJ&029Bsvw6|k*!F7^ zE`K9seLi$yTlG=q#e}T#b3f4gBKQMs3Nh(NBQ|8;fb(h(@Z+6Sa<*nOPVsj_Wnmwq z=eQxAc>WQb_B;V8CjIcG$}q_D{S9t+N}=ZDZ20M?#*>F#;O^ss;PCE+ETBZ2+jyi% z4z+in3E6-%Cd|TH*I%N;D|42=`#PBH-p|V4#lhAol%$^ZWR5G&i+snWV!_v0@SoFc z4CvnvFU`!N!Bx7HMq9vo5upxqq-ZoQ0ji2p*#0cRQRkZk|GA!*B8Bd9U?H+mSaI=ARR@;0TX6c&JDA-!3!dKlg!h%oNaMeIZ2$ESq#dsy*ocU#5B_1VNy-wk#bC%}z$V<9m41tcnzpu4g<_!uWb(Jvhy+E4^<)(xW0 zAH8sucM1$seM0U%vd5oR+L(Ue65IVQ3S}lOW@8U`!^(m*R$eg#eg7GWY&8b)4KE+y zp|kE-vM>d|kFbWMZYB7UoMXrmkV6r5M$M=3GH-=n* zG_U7)H00+crB$)GJ1`VuW1=wH%mZ(&8jF`#U&M@GZ@{SZIHu=r#`SKtu0rvNDjebe0cU>d#CZP>d}m?6 zS8WCU`eF?1Dvg7dfpTos?g`+Pup8TQ7V^i-SHp+u0sO3DsDtgr;wr#2i6hRKjz;a*Vo zp@Hmf5<1;Gl0~;#{h?w}CJtK`4c})qG5^~mFn^XC=AFrce3wl)Su#hf)A|RRR)hF*G2zQKC&*kP}0vmfuuVbK#bQ}F!-BBR-M@*-0cf7a;z?tTRNip z($Qpr(=Bp!oi=1!4x?*pf5Ds!hanA8afX8$;X&hQ`<1`Mr~U%;ds+)VX6aZER3Ylw zP=goktw{Ufx++} z*^OuP%|#>g6}bA$h1e3QfqM17S$;}VU$@n&tJ?%}7DJ8+g z8EbIJVilNus2-M!d)aE&>tvgM7);$U7c{Jvk)#!aXlKq?dj6U-J2G!8=*CO~85I}M z`BKMP=)Bd^G+aE{d%ava}(jD8LxY_Q~BvRxVXw&Sd!n6DI*V`4N7k_Cv$p8zsF5 zcSF(*R+pZ#VWY9Ewv$C8MTiCVLp&jQ0m5 z^JwAz@us%fM&s%-P)aZn4cfOHBmEdD9Q}Y@_m`E--1>yMS|pH1EwLodAs1@fRLJe( zc{r?nFEmRQ5t~(F>QGk!pDxJI;M4k8{BP3u)e@QnBXn zAv~_>0L8~m+4{lq{7gayo|?4{r&zb4@rbz)ZX3m?-7aVSpB^C2K_}3M9L2>Aa`bDx zpX9By9oN>~fu0Bb@yWictW>leyP2ejT#8->FU$d``i{dw)pA)nNGb zA{4$EzXbDXgQ2_C2y2x!dCt8Sw&~zKQKNwt*Y94%TI-&%Jv;;sm)Y^4nyI|`!49eZ3Y zI|eNZH$zFUCVM!|5{t8(KyvQ|tQy~Fv(K#w?|&(WA42 zQQ&e_st|8nMb3X#07b`sU^J|NncGZ)qlwR%`54*B>d(ZZ&wdrUtpV}Jv!ndos2nhCXd`Dx z7ZNRZSUty-*R|im+tYGUUZn$5_6S^IZEYTWQI~6;Dm-Jln zqUj-ejM)hOOpCo;9|{n@6Rcj8Numcufs48fH~Tz@mjy%<|MQPXz1BDKu<VE-pNPVq{BZX7Ni`oU)#EQj0M!pj~tVbjc3WNBaXTfatr%9ss zzf;N1tTM^n5i8MVb~mg28$|m2&a}CAelS`umO{h785NVO3USNK6zUgJOt!u?r&pEs zkh5}9{H)Z4f~XjZ!8k)Zjkrn`!a-#s4}cz?x2ogd`b-U*~%wxUF?@;9tmVuH1! zH6eYDELBRfBd7f;DyT^;^QZtlwt7I{gLb0S;21DYn!|sW?ZjDfjgo?40*AAH z3q&ZHV$dx;AP$?@KfI3Xe}%GutrsdbN%l<~*K3>CHGS`~=L=utKFpgZZ2lY3O@V zmOiKuya1p6N}kVCr6~!`Wb@<`RA>HWY~DJ6HjG+|Y^RnaG^!j-s+IV*IZD)(r$O1D z46GbC5EnfNBnKi-60PVoawI^GXf+37!2D!*tN2`0FgTfPC_wf^{wR58o=zrQlDV|3 zA)M^-oellS_%}1}%Ey z@@USkX2I9&RrIxwJfHh2kopeEqxtvk;PLJ&Fzu%;_EWeknzU6G?9?woo$WF5>}xih z3Oi4#a`t1^sz$VoUPyZfIH8UwV4C3Huue|G3APuYjeY^~=F8l~;1aqR{)JkP6Z|cX z=DF@t=+;Jly5aNY{}@5kAqCHHFLXvrN{e2S_!4bQRd|IvW@f=U?^wbArNGULGU@GyosxeY z?_sfC1+|j4(}%Nv6Q%Ec__YBG@YL`i78i3ANSixSGFfw?< zPE`A{3@bP4(GlZ^(2SIF@@P>Z%Dzm(^&MT9ZV-bTT#w+l-xGLxpE-PYU^8rziJ~c2 zH*n)gP4M66GzfMc$_FpJjDg0gcG}p58drkB+a5yY z=^yaQ|2b}|F%mf85jgmRH;AXbgZMeUXukS2v3k9U1|)9c%QM2c^{+Jg@p>hf#7S`C z34v=IzX-L?dx5993R;YK0P{}R;Mh@ju>DUb1YRwI&rcWfixC58;#XPv{8$9brHb63 z-&s&=>(77e+l9UY`0J=J6Smj-i_6y6u-E@y!tEuo@Xu=#?W)UWF2fAzyUEw! z^Q2p_zTyfD*l`;E2u$zzFPRX2)q+_LQRbVi1&8&7^`v0ME^z&u%@b@tGP@_~;O_nf zk2~e!iB1u<%t_;cjnBC1_vP?@Zwoi6(dGx^7x7P#!oIovdtqm18mD}-&Cq~mRAfJi zj$IcV&r}dt%&KH>m=VnC66OmdZ$ewjHkRl2g-p;F7^}g(Y}TCLLFtsfFZA8tlq=SBxnzjfyHZUP6}rg^M*S~D1}C?~^q zPK21=I9hkzp5LE3m^bblPBn@{1-HOTKIq#6;x)_w^>2Cc{R56uIzyKh#15sGb%dw5 z!wn*yUT69#AHd_#E(%F2$T+=i@UY#A*(}`(qaO(!`oIU|@41=u??S<0{U(O8@E;_# zs}3zs)Y6-`HN@N~(#Ahi4Mx2!5Py5phS#+35n`}T{N|A{+>M@3Lkx2H$+Owq-%*3E z)j!9l_08f}-dgjaixjY6&qt`xPk{EPrHD>c*Exg8GdQxo+V92!OCy_xheT1O z0~6^oM=3-ew4>&F#Zc2z4KoE6(pR^W&}l8aqj&cs)|L|R$RB~zOG>bPpE_@t*@xqh z-kL)lU5x0~|CZCyhd$6><#)K_^6z-B|8r5Q zas)UUy};$#o_Jaz5>SCAf@ogrECp^+ z2CpiMSkH@mI)0)W#1HJ{2d90bcaJI1o_KeDxpg3D3{a(Swp2o$$9Gh%&H`QcR4AD_ z7cH+0!lHGqeD9+Ydb)A}7VKDxi6MGaDMpUUZ`;J=H5bszh$DzMBhfMT9jQ=0jHhj; z2zSd!%$OQU?Is=MQw%Qf#hR1obm=N?d{du%?pQ+udrEOYrx{F~pNi)e6|%*O)39~r z6N&5)c|rptMSJ@_Vml|!WJzzbQO_b1g;?Wxy!IufpB(yd=Ybs%)IS{Z{2jQR?RhZw(4d-Q z2k>d@*TI;s1^n!>O0F_<6f7Cu$!9e9No@+36Ic0iuJHUVpK>6PZ$EySo2}UamsW<* zrHdZ14KwuFo{>{PYe6^uQB=fT-5R|21L0xYVz}Ikv#=?23GWH6L8M;X4}VJ3od^;$n<)8%3;gT5-~0!R;xh1&7CfA{G{-dGalR)lnV~yQ}v=MQ8wq zb%jBatS3)BeGCsyx&$AbPm!)km%+Ef0<-oDvrSh`@$a;D__}W@ogbz^F{N5?L9e9l zp<@12rjS^SI77VxJaEXmC3K{M;Pu&EOCtfVqc*gDb)h>Ge3DekbLPFAEZaLJkD4uLIu5pNE#=EDa*0man|un526B!df} zr_+Gr9(Ld$-$S_K*l>ag$1v)PGL3!c#8Yt!?SFY7wcp;3<1AC5x^W+7Se)nYew@ZV zbEadIhBEZ8I7{b;|3}P94$@WeSvc3Ti73ynhP0Md@aXOv+!bBQbw+RDx3WAXu1!to zydWP>pKX;)O-{zr6A5TMKc8=Y~hQ^P9F5W7Kd$+ft)2nLGdDB<(xlc(cFB!=wqukNB|P1uVd0uk^3L;rw+|1&d?v;$|5`T3H`R zn>URiV;iT?WOXy~E5n&IRC5CD7kQip&X`00QyoIzI%l$gaqC&I=Vba!QE?-WjA-Y*n(t@`paZobrIY!j;1&fr^Ts&Ke{2d4^5uc~dS_-fNLd?D;>C=6DI zbX9f!vvWH-``Qrmgw zdBK}Bn-Y->_lk|-A9p+x=GIoERo)KvS-a6M_7ix62}(YtZKu;aR>H>TVdS3A178FGsP}Oanr1)XO_pK&MMes35X%ZKIxW7Ze}r%!F@z#HB}{(zlvEcG zj1SbNxf>oq>8edMEpGyU>T1NTVuR_;_EzkSiRD)PLuj}>gKvk%qVd2q9&@}u4Hwu% z(c01c=5!6Hj!}a{r!@Gly7642UJY-xCt*LOGW^avu{qzJo94}d;dhnbV@WnH+q4}X z$galyg6i1%=~N!yIF9FJi==V*nZG#ufT#WY!2_3W=LY5%Sa0Y){%7q|)HoeZSI-l& zWZPagzlqT8YiIK-B@9(2ETU^v1vbp~BzDQu8NVDE%6FJFqGEb6De_v6b~c2raW4XUqrG^cbUl{g9jusX zO=9vH+uBEl%x=2_r7Z)=p5^E9M(8TyzP=A#IrSN2u6qqX*?w9P^Nn9Iyicta&w+w? z2n?%?rm49*@%MlrIy^H<^zOgSC{91d+wMm4QLQ#S{EIy|IN{HW*(`LH^`qKqD!k(J zH>^nT zF1w?Jcij=%_Q{jGW^Jw*x@Z@qETm;lxRCq!?qMytZ7FJe&oUwqgQyogV3w;BC2?2Kh+5R38&2M=*2Os zAaU6zzGbOCKJtHwcH#f=C`SJxwTyqK6yE{{tzq{byxOx0oeAL1eI5^-k$(~gv`JKO*dZy`6 zGWb23JEy||lP-~)UpZEj4E#Dk24VF%{G7ZJ-50DOi-H9wUE@1MvKZ=)hvACS6HGDr z1TI-9!ycH#vMzy_l360p<(`hmq7mbGx0x|MOneNwdw(&nf-s?%V1iCHk^IxFqtLb{ zRkF-88neR{ggbpP4EUMD|32+cBhL#ysfE2F-9bUP=wmePEz5@H*GY7uVF*fvZjbnB zGF@b(%#Ajr)A1vIqj0L>>7(c9!>`lDC!6)?V2@Wc$T5`WH$+i~k*zq_;T`F@oM#jL zd_A21=Rj4@L%yJ6Fbo z-!)tAefS15%sPzcV)Q9jcmjtKR`5RIf^WNhtaK;+BRR9~5FpKFs}IfPRew*y6uJ3S z?c*ph`>=-&-P24b2_B=9`X88M(J-Mqvm5Pwmhxx+R)dbqcs{yWS(^KMIchFG!<+pV zO9!tUEZwr#OZr-^Lh3L*RqB06@O&;CNBr*IrZO!TXtGfXEpdHJw``zd3-M1{7db`j z_)JT1sQ2aWol5+4;C}FM5cWGmbm7?JGqiZ6C6(&v^1a4O#f@>hY22Cbq_N;S{WU8K zXuUdb={h8yoKu4Xf3M}Uw)xV%*>^U1;A?X1 zz$yBy&7XfWd4TG#jkwN$A>!m8w`kYrI{M{zA|0#vnT4m!pue5QW1p&H=vtRdHS5A? zO@IddF``l6#;4MOYYZU8=^OXy{YR5F>F}_OU%XoVCI2aSoKg$E@`BJ_{65ctz0td+?K9&QgQHdAy+N7Ee5+E1fj^8n<3~Ovr5BB$igV6((D+VU>GJPmq=mvhbM+EEsqWzZ(s*IV{JH2AZ)?59vj<+nxq;t^_BM6O z^E0UW{8{w#yA60`aS{I6?Lu2lD{{Ml23}@Z%a0Xhf#hN(NIDnuuCuwA)S|+^xfzJJ ze)&mZb1hxSJ*2f>m3(P_D+I~j<>fc?c%pGN3>xwT-c8ty9aBeBV+Ut(yTpu6*>w`E zb?muUl&n-?aTNET7QuB@R`OJDC1{UXMrV%`oCi(D;uq!5K=U@D-JwHN_Jj|0+qs7p zl$_*+R}b-J$4q#e><9kwYdU`%^cALc3jL?~H#jjKR&i~}cU^?*xz*Gq z{8b-;=kx6;H?6QR&-nf*)-(HvSTP2p#s@NA8cTP>Zw0(m#Cv6XZaD1ec7Dh_D zHt32?eA}stLO$&&ilBY>mC`*0XXq+{#Xq-JQ9O3sbn(6??zCuNCA{`Cqc49grLwVQ z5Y|(IZC~1X__hjAHaX54lYa_a#tn4f7d@&X?3qM|nZqGl3HOfC6`Or7V~4`h`Q>xN zq{YE~=(*JA^sDwUelAm;&U!bGYAy8Swu{{PvVY5YS!G|Tm!+!IJxR**zI#az?$4H< z6TVM9&&{MnX`S?Zo0>E(r1U&M6}52sU4iFwEBg`z79SF!E;t>Db1G-|(jFb#2DNa0@( z?YqC3`ade8KJj|uh@?ciqEtmZCC*B$eIkH&_0;0ufuHEsb&6E|(s25qs+oQ^Tg4B9 z3od(AjYno~rPo&EvT<_VczbP@_>}{pE)A}9$HH{(udFClp4`ow3noZQOV>!Zy`L!k zH|8eSvnNvP5317Qt$peK=R!AbYbouHdr1>r6X~?R?}&O~2u0FtPdVm84-+^<+&yn4n^ad=S&Es`3FFBIj_ zdA?G*>ZmboemGGON8d*Ax*KRwyo1^&=J0(P6Q!f?_|o5#O!??W!8`kc@KH&hCEHFm z(&nxgyzX`;M)v?4x6fEQIVFW}IuL@+pq?&OD)L7~k+Yf(_H_ zz*GOvHP(+3`}7+{{|P0B;S=VQLj5_+U{4Y^oO2Ycayz;9npM*B&&5==j?izSTeNf8 zGTt^LU-WS^P^EiIdBw66Ze@RvPv&CUGE_}^Enu>AU3n63?!Ci(3exyXQx#b6Z$~T6 zj-Y~BX8cGuC#T6OeJ_)!|L zE`(=39wYs$`Im#Ez&)FnD>$50q@L|#=!*iV$P1jo&lPW!k}oHCi}MqH+^fHIzhxaS z8~Tv%T(2bUoc@w;DKe7&NE{_Kbo<4>?LN)D?(UMl3|b)lW9KA=n*P#t-VV~Q5P`=+b4`_nTKx$+HA{>EKrySMDI}ES2Mv@o}_$ z)Ddw_|Ni0_lZ9e~!F|PN1&&$GgB;qs@idJiv#9d6W3=L66Ysy}EHBXwmDFUpLf1Avt7ka+?Osa1(5JA{Wg(4h`$Gr2 z*7Gq_l|cK#WzmB-g4>KPp{FEr;xCpBDA}F^dL^g9zs5kUaMXiJ=Ou%cXf%APOXdaL z)#&|jsCdE&U+@roBD$e&+`D5aKPmqKQ{{sA+2R>|<@;Dz-TND~O0S^Yid^aydX=7B zsx1B?oh^3wiqvD?F`B8OEuOkTQ|u()M!y}?6H5lmi?`3!qn1&pX^X&YaVptHoo_N~ zlW8ipjJQCvVwz~bWvb#mRxZ@B(T&2+A!Bu2`IJ<|_7?mrXat-J)vs=HekSPif%s zI$F9%Rcta%Px_!f+-?_3*aGk&ezABUxqT23n)uz^R}{ZkkceYdzQFA-CgH@zO^+bHx$y_yBc? zEnh~Z`%6GP=PW$1D`7(>ub}!1e&7iGHjGc&z(<8QK=Laas&u$7-#>C9{UKJTtJ@dS zozvp@u<%J>FzW?PiJL(8n@omZdmJe))fQjWG8GryNE5Hj-NNpCI74-x^%Z-_Me?5Z zNS^S=2x~$U=%4qQc&Iv=Hpz_^+q|D5&dDpI)7CKRY#d47FAD_3P1Z?)pbmK#W-8?3?Vvm%}TB8N&1hR|ipZc)qgi^ZGWB)HY+H9IeN zjI#BQX-v&(>bm$fJ#uWc^lzxHboRBId|t;7ZuOP()jwWhu+tx|vX${4<)iSu!vh$d z8%w|Y?V!0wyCloqOJHwR7f6om;u)T5{MqTZJo9J|P2X)R?s2sj7ryxqp6zI*B_F@i zIgK*3V%b5O_xL&WKH$wKC+G6ojBdec|A#Mn-A@`ayMTY+Uc(!_i1fmBRcU2e2z%$A z2Lp!Rp&xTklUL0_^nVnccRZEv8^=*m$c&Oz5>lb4oaeqyA(9cA-%61-rKPD-*{gwy zLa9hXD#CfL>!2m0R7Ob}8XBb1rty1z|9ic>oZ~#_zOU=^dB1fMmVl|bl5}pruk>j7 zBEd=4%dCu$DOae9|E1o+MB_dD=RJ?vpf*Mi^)(<~xF4&Y)Q~Q^V=cWKHdtzqrY_b0 zVkxZ>p25HW4U|3?pCxafLlkH=R+_Nz7_As`PSW1#C{0?JLH3J;y;}58=^|+s&3YMu zM;9naN8au$?VCGIy2oj~wB_P<>5bbPrP(X=rH59VN;7k(OQT)X#XpBd!{Cs!&_3WN z_^MxmA3N5;mc3iVe+KHa zLQ11A^jRMT={??{x({LWpcbfJwNP4;p(@>c=Qs;KyN6abtCNOYBC{(fgZ|Y8>|aR^ z3obPf|6P|w2iroW`Fk&bn_C#qj--%P%~J?U{>+Y-M?tV&KJ&`&W)=>rFjr3u_g~br zphK3#qBBLwW*2aPYb?!qkwx0t-BeLNUfMM=2M7BdqnsN$Qu_(BiOD3Q+MeCC?wkRA zcU?lcGaR9~VlP^aFrb^i6d<~3ytuWr2R>!a6AyY=0mnQ|;I_0B&PK+9(qqDb1#0k9 zYZxr@h+->tF_vgl3@KgfVB`6E&hf1!?CDj3KaE{nc|#@5&a;qOl%ALV2pGg1Q~JS` znJLUiV>E3~Uq;g1>NxQ0meSf_WjOTeDJ+g&N|W!l(KGFL?;S*cX|WAwZa^2 zx?p52onx?1sx*AObVgwr1uIq4v5}?3wMCJ}4}n)^d4&?+ltN`fDU673WJ{a$#2p@~iY);0bQedvP0}Rj(h0$A1!=#oVw7t0&UOqBs`@i0% zDOz92w%0;>#S3Zj$Yv`0VI|$F^_gyY=hFthgcklCN(QpBOby&1#W@U4-)i8WRbIlQ z6YZeQVlPPbSD_h}z`cy$v}TQ_w7_TxZb%6wrNMJ?@(oX{JXeX=R}F$kp$4q!IVb%$ z?>OzT8X^6(Hj6nnl)$uA$C-_83LR3>1LX}TsO4Zbp7=9R;LRq1gZofvYR_r*JH-KV zR|@WNK91hll(EPgy5htYCgL3pZsNii3-QQwW#P`NCLa6JLM*$(LcC?al{oiT9m`0~ zWy*81=weMWY8{jpXfo=s?50GC%Akn`PaL6a!JwS&K6-pw|3 z<(0;+sAA-Mm)Q^4!nwM*^L^y($g$=Qu32hMC&o@<6Wt7Ggi#$|cV`b=&{5^mg8cZ7 zZcTn}Vl7j05cbN$HnV(-`|Pu5G-?li&lU`-#zp7vAvtJcY95C?)G=p0S<0NKVmr&? zH$P2xJH{%6a9S(Ru}J|j?9V&K&is?7Cy{CtWU0tj4_m_`{jUl8$f@k>{sWk>VgmZk zQfAia%Q1^*6rleTcl_9ktY<#A`H%x!^0JXPd9{WH&N;>uN9$nYbUog;*A2_V$HB8X zVQjI=WVkO-5K>~lvdtSFAya8Uhsi-W-eCx5r<=t$HfBn;1pF15HC@K@56<&*tcPNq z+By8*FO(~bif4T{3VhM)1?a!b92c(Lhjz=|QGdi^&c3<|^K4@Iw4y`;g)OYu zErFfyD+8mywK4HKFPg)JW1GGXt*U#%P8Hj-Ve@CR%Di)Y_{kn-o?!x~x!El6-$hRD z*%H2EWE@Hg` z{}f`Gfm|WCPVW-gvuxBhRm9Z#{_r+t6APVe%4bc`fln=eSmEk)cCq~uy!bGU-H(1< zI^@h@5GC(oPVb37y<-zM(0n96On)TSx7=dajAr9zw{T|PKZx%VC*XgHO}Ht?h1^Pv z!QSH~zpJo~Wv3oyzhq^Y()$oNv+g)Mdu|eY{mBF3|C!*TDI@XoeK6!{1t7;C*!*9dy2pZypMtlK^%8P{%XowQn(Rc2k|#e4)pAjx6Nb zSH2Prn!1NiHnSk3{z9+rRyb4MlFat>+`&ti2hu>Lt!!(M0_ZLtz~ar-X`abb-v8hu zcCz3g&M`3ObN(H~)-#Pv+ro{z`C8x>X^Nq6#8j@IrwP_>W@z3Wk(8Y zSc46*GY<{mglryacP82%(9&Z2=P0AKQ3ExX_0Xr!txWFpWHgKU!R0j%z>$l#p<&BN z{?mVP5L9N*@_)9VUuG8*S&YHjf8Q~1!AkJ2F=2hUr4*{IAZ~V8w1;ixbVFy5U4$a}$8P1d!i8;$)+63}%XOTp@edQ%HsQsTM6Ujz zCtI&RgZC{dmwH11&tP(Y>e2x1ntT1ou zE=(8lb+e}U@zXzRf%1MWCSCLrD@WaBOTz2;u2)Y49@GzfvwH+B86;07nH|_UN`mcy zO?W!y1R0J#!nU={EFE(&p56L#ge&fm!%1EX@%z9kEch{-WKGA=*fBzmaGO7dyw(Am z4uNO1VFK?g%K=t|!EGvr!(*0!-Gwb!mvWt(Cu9*D1(s6Gd>vS4xrG%umkRv_S#qg3 z&-dkpIiK7smNvGYg#@`^LvtFoS@`43qbG1c!f?1$Rl)iktVW9$y0B!76sx|vvyg9Z z*`TbYZ2FTxR&^S?jt$LyF)Ze%e-n(zj#M)|O?1<7p5%6Dk*7L8xmjl((pe(-_uvNWs;Xwfch z`t;%;)(<{F^2L+M?|LgLwN9Y(ksr8kt5jfZVFHdxc4B^4X3{{?fB|dg!WF;qWO`;P zJD8X&(l!#a%@NU(ag8~6%7xJ^ehg;(jD|seeW`6pG1q;}if!t7D4Ki2i&-X_A9RHV+o&nNLD_g)XaLzpq;gRjiMLa|L_y#r(ebLkBy=)3p#QB z)ducosSk_0sDz8x&)~~#e3)XP59jIb&aAa0?E2Hm7=77*`?*||J9(dHou7n$^y?

    bfZOld)rW?p$J3&;D@c><=esATWNU55M=oNZR;%4lS6moo_i44nw-NU|p_|g)*H8 zBS%P?to>4E82^ba+;oGT?t0Hg9DBwJ&lqqmaW>#|Vka}$;>A4672tk(hLG>{VX;rF zXz9onb||-*39B^L*}RNx%lgAFekaw5_u_s`JU1HD{Lk<=7EFMhXGg+pUnjn~EnVV0HJNGY2=}sv zZ%pg{EG{+8fDZTtaXmS40{d$+?z%x}|MUuKR`el9kHwAH1ux z#_6g;^Y#kCsWX&4{nM9~Yj(2~_vPriUWcZ93&v+3wMgUg3am;kV0t;dEL6Um`Tj_S zf)Vzhv|u@H6@6pL8p6-5xrZu_g8LzQEjwG5!2k4J2>R($p=7iMoxEm--#vvK{fIuI z<$u*^_yc`v@UeufcUI&#z?@W0-DR;EErL@I(EXPyn#Bh&WmSJ3(oZsDgDTv7BZq%| zq7eJftj5}s@4T#CKEK4wfHbP2S-GEsFiTmAWoPEWzZX$p)@PaIcinyNuw^ex*Af^` zI~&n1$_xT5l3@Fw+2~!J%eJn_!II1k_%tRNm%NU{TW9z4`=<5fF6{0v8W{GEwVldl zn-cZ$fW;0_Q96&ct*an&rz6-s%;3VwiWT*Vq^@B;v~%5ZzGdcPj2>BnJyr@Jx@Sin zXZCYz64a^at{jb5Th6)$xZw*$A~<9Mf_yP(QJE+8u>py$j#SdY|;Y@sPQ_* z3QyEB!Q&igbSL!jHK6cpkSkI{_>IzQ!R6Rwx}k zoSU^vmPHFW&yTNU$mC=TPAax$B>s(WCGR-#_!;!^q795+z%zvr!|>|CZQzpkAI!e4 z1g1td@W9&w>c&BBDgdM=QVO2Ha%X4bn7DR~_KjlJ zRwDdx^N>W@>Lv3K*x8HAo4Ao>ZkTa*1UyDvTum6|Nc zO!$Vweig9~c>}0h!;W)$57;+A9d~&zftz(B$bZr=Ojsa>yq-)&3iAm3S8Ybyr^(a9t7bGkKv%jnTTyysO*n=hn#SZ^QRw*p zmfY?kEIT%Y?tGZXHd~Ko2iKLN;Zse@pFV`{ZCEDoX$Ai8!;#dsvkl=%553=Ces{!1{ssDShGvXJPk=;1H*R{@!q2PIqHhU4o% zVb8o)jNvt_G4rr4Dc;ILrGH}uj-C}JI6qvy`3{3I>wl5pI4181`4FH`U#iUF909y z4dfG?!`X!CW691r9>=XxXXIwz?W>mWQK#= zZ{mQPyIA;pBe-)T5UZw+r{$@^d`b3UoT5;OP9~diaKU&=${$8LN}E`9l|IG``6-q3 ztC;GW!j8sHp~uo~G*?d!jP9;sm*1@8hkQA})*q?lyr#)uMV1P;KU~OF_SWO%(P9*Y zKR0GNhn=ag4?Y&;?A|VP|x1jw#{xoAGXvKhS{kR=lzJg8(YH)K7Qbn z%=6giKUNg*^d9ElX`_*S^hi#)_dl6A6sJz@2LXlSIKRhMTu4R~Q`b#|;eSl2AS?xo zRtD0ZpfgycG*^<|wuRfLs*GI15V+ZsO78D%(XZnv8)kYCBXp~A$j4EX+akiNEm^p- z`Xbw?YDRO-qe!@z(|DoV@nX+4wzJlWzxdr;U^I*cEpH(+*{~QTdW&F>xi!RQZeYfF zNz8lqGG;aUIZD+haVcvJ`I8wDIOKeyD1T==^Ll%ety({mTPtMOCKu(3Zk->G2L!%X z*NEp>6|@YeJP+q|2U)N$JJ+J#x_4aPj%n=Ssi%_G;~eXC9|J3eF}z`I7#&?Rm^EGE z(0BAN-f>6<@AXE5%D0Fx#$!8+d!$Bd%KNf0y{Jg& z<$Mo@VwB@k(eNvyXjbGDb}F-+rT8y`;-;Y(vhoW1wt|7#XdieWv1J|~9`NajLHN-r zkMFnRFFwnbrJth@;njP$5e7w2=#)Ra?en?(@w2vUPSO|N>Z1~RdhuNO)7c{B@gZnD z&jF9SeG-j{D#x)A_9SZk%&uuTkP_F32O{bOZjK+-Kl;tz4P3x1%j9T6$8&b*^<;K> z-4(_hrtrEsXW7iGqDf&3!g1C6H2h{ikiEV(0i~r8Y-o%cJ6t%9dHJ1TE)D*Yq>DlZ zG&LLi_43$-U0!_G%6!hEa0P$Bv6mfL)yZZQsqqOLXR|rq4xx(oI$UWk>_8W3;R@sV zBq22vxhdSVd(3t|noZu*g0bY|WHL{Ahp$x6 zF}+zlrvLH7>0ADCL#!jX0mn_m4_)(k%m37*XOAYprmsaH4vvG>MGqyO-)DpT+KbG( zqkwC2T}^e$Lxe+N9U49s_O2z1Xo+4O1{^)Yws4mzR%SK@F3x5kN62f^3umuNp@59P#bLdf78c)BkJ@+!}Qr+Yu~2K6ck(mls5y&edb_FrI*<KP zzl?wOg6M;SBRy}kBkAUo)TNb4kRUi5=U5T!R-ocM6=*-DE*6EXr-8-aS*)-lvJkza zuJA;<`_~Hs!i%Z$TVHyqm`Oughf@AJfmnHR=XLZUPJbilr`W<*E_$#$&^VeFcF`G@{Umf7h zJ4;y4^>Am#o`lzKZZP!YUnnZs%IMfZ_TjP#x!lvEMtqK+A4U^Bt>w?1Yh!!TeVC=Q zDP@hGL(_ksqZE0O?Mj+P`BwtSBBLG`zEh(?XMSShnX_=~v<^I4TEc#5w}VqN4_Uve zp{(Q~&iBlsN!GRGLW-&;)ZAZ|B-0gW za^)#<{pN)I6IJL}j5C=8CP0JgJe@f(Om=3R-<=Mh$4&1jKf~@O<_@sG*_(LIOfM*}#g1t5r-O`Vq z?+XHx_q}Y`r7vtBRj>=Oz^UoUiX4uo!pEzH%=qI9nr|=$j8FYwO~b!qU27^^cTWp9 zc}LQmun8=@dNV8fH;NW+uVd@?2SLh^ozSs<3~nt?VfQDe;PE_J{NAAt`!DND+so4- z+GI3L5l%v4_sx}U1SeRnYadJsvQo?gJt z1;(J@z6_FemVu`oirlXJ!ZBG!IArZ!Joj`7y*yG&5$QYGLzLk5U1wNzgDpk{Rbklz zO=|n{3U?HHv8MCs=&XH^F5lN7hq;LqdoH?ESZT5wCvuq5-wFKIgqbv=!2*{&YG;Qw zD$x8vc6fPu9`smz7wsstf>XO{;pFvUp#Q=fvJB5cuTZ?W-QXhb`58)2P8`Nz)CJ)c zbu_!{0ZA{J!!BLnb2@)Fy`SYp9(f_O{6IL(7`TakR!HbkP7w`kDW)T`uP}j<$R(nd zTGbYV^_Ov2>+L}!<{Sk__oHmLi!NN+atdcOD$}Fn?9=3pFsbAnOPCrZxc4sdWd)bWv$Kn{Tyh>`YW7j*5sp;OSMzR) z;ezw|9rlJgkoacYeIL5Kq=6NU zwO|V_#L($&Q6kGz;cT~o56L{0ebnpJ_jpeou2HQPvpjJpIqM zX_FDwo%wcyMnn`0yZxhgt~O$t`SJ*&lgeB*NfzS`!vn`cz_yL zujMa-BlaKujF;JBLbLvKVbI*us5;#P=U%pf2H$Nk(P}K+7%MoiWD{8UcL$I^w;P6q z?0~yfVX#0a8B(5Ih2?Wx*``%dlO${&xCYhX%}IguW#==bbYl#S9LewB5y{j<^T_kd zIlORh3}?7o4oVx{p{`m23pbu(&$q0H?U9*qXuTJG92-o&>Loa9U>6oYTuY;qGbv+& z9$%jrFSx2tfbO(7KUdO1-1-li5JgrEkpfktGz%eP&y{7DAg}6T4hAi=UFb zhmC5KFg>lgnD-+QMvmGB$EWlMr)v_J>bVVU-tC1T?W3YA>-$Kjxje+4Y(t2DC1idN z7UA>AgZyHPaAvf641dUOHU&HD(!RcnDKsmMd_3OKqE(m4#@LJ8j!r>;{yK(kcBZcK ziSXB36BZ|5zyP&v@TK4-+)qv5Qnsy!LH;R_?Q@l>G_K>LJ6^%3?`f=H@C5LkcpY}! zJ;J?I7(&fbj$2ov!Q^89NQ(Pwz|oX?QQLhhx_>K-mT!)MFLnbUevho!?3yk?Oe~A8 zImC;{4rcvMPJ+`%PqHD~&p?HJELhnOhrb=>wCZ;h?M)@xvPhfCUbvypsXRJ3N}U2M zbNRRX$5EKq2hyw+m={}fC}pG>&HC<3a+80P)N(Y;RNcV3SG&^g(=oK{=2g!B@Lh7U zX%gH{dvVU5!L)IMqVP3vAe@hM0Xvhn=Cuh|*tRr{gvll?7a2m+26syB ze;fx+@SyAsJ8Y-=421ud%_sF)ztI2nN*Mny0+Mez(|VcyRIqa>ll#+6i-mposHsCK zu=70cxVS%84FRR{30|&kwAmUKV21es%&M z3|mF#|6539N!qCSb__Y5&_{(6I&kUx1b&FREW7qcg7f9)QF>E9xD>2N&whqbcSQ;_ z-xAHdLlY=vP6t=f=N`@qAc`BTPS0!I!6vl>mj#{!uNNVcW%$1K6xbKJ)cVHTX46qTeHIgtq#&r+{ZWE9}At% z3ewigL2%w$jkEU*C*#|S(Cicoy=gn4Dq}8&4XVPd@=;`|Jp$L9b7BKWO`uf;^MtO( ze{9vFkNCOgD$^46gRg4w_{sl{MEUwX!5ws)vZXVz_01KwRJDK~mhc(nGj72UWn=Eo zXKUtYvg}(5P_7jBhsndx-51!>i3+eZqZ75y&44YQN^HRCt)f!DSeR$9 zh<*1=7rJTfpdBP+9DepnLU=t&=-vy?fhuq@xJdA>$%+*%GST;LDQUXKiq>3-V@8J) z$bM-nwl}2mo@XmjW86xLoL2*iqgSyP)jHt%c0ND0+=?4Nsf?;DUXpWK1^Fbs=8yEu zL`wl&Sku_emcW0clh{he$A>Ye{3MR+{D$KvE~4_}BHE|hLVN9;Auw_>6izt8a%cWw zp?DhZ$3{Y6%xlqV=MK&y$*DK2x!~#ODoL#x?A{!QSdw?nekx02XR&u@GiAoJEiCgUq?`4hwcVsYJ7+=LD7hi-?rFS9Q&5;$9N5d^)x8LW@ zSn{yX;M--c!EXyCvDdp?$X*r7Ov}o^V7N1Edik71$os(LQTnju?+c0Mi#8ZbcVM;A zQg{@78s<({5eHsYrNn^;@MKsy+uW>5v*#+3hI|6teCh*Vub3fR{x-s^{_$+| z#mzV(>jL;h+yIvff11|vkUPH&~bWx zuMdrVmQIuy%6}5_#NmqZ6w?^Pztyy)sW;59Ci6G9N9qA8*IwY`|0;3KT}!YEJv0U+(o7^?EJ}_B+GmIJ$4(f-a!Dp@vtToVv>gAa*JF#VS8~?_A5ciTF|8fYEs1|!2Tw|xU_|v5$UZ(2?rTRwt5p-!DYx!=M_8vuI!!-N0%hB8^Z1z&ManucS~SM zc_CM~!JJQ1xW&D3IE~LAOhwOQ2Wjrf{g|)BDkTOWEYiFWm7 zV{wB^ ztQI!^@@DpZ(oU{j6iwlpo2bYlKtL}d;U(siu#zoQGhrop zAK6p8Iq+9M8uBx?vnJ_ydOBwiK1w+XWqk!N!samKL_Qc05lSzNwa}+bkL-qCW7#b) zZOb;E=hDr}L7~S4s_u!wZF4f~7P?1#Uk_MoxPZ1z)wH2juaRF;I1@k(DFm^xNLnX)0a%; zw^gcuiuD80P^&xqg8@clv{~>wobAR(u_I_)zbyP})`=~yoj6@n_+6*fImpu|>o-H$ zee3(&_P^iI{MkVqHav};x?oAy?4!VqT@&tU%Ayf1cUb$H=iGWp8E^tyu>WBPlB*so zzP9HBbKTXzJ$3uVFS)S+U)<`$I`g8?UQW2b@DoUCD37P6^(AThPn^M9!4LOf>Z?%9 zvj47SOXb=)H|sqD*K7u=>HJ5sKN9H5Xcx(l`t|g|Q-_8H2S7_}Ddq3=qk_q@;wfvQ z>9nsU(ik<2?Jt7w;A=v6MKW% z?3w*=O06C2uh65)7pXY-xC^(fBIdL>@y3}dO9k??$cHrkXf0?jjrAa_=%=-t+{Y}G?ws(x}qU@aQJS0@cNH+34# zo_Lep?@}f4pJe)`oHi zx}SLY`aa@Ti+9ZWQ5bl14}?%U!`H~6W{>XmBEWWQpX}pkmidB((>ljHp?<(={ zPMd>vrz7o)d4ZKDwZ$DfV&H_~eDYcr1;+P`dE44#7Bgx;MNRVrQ=uPk{7G=lZghe5 zCyglaP#x_QoC)nkb+x%dkXWosHJ zJDF028REQ@9K0H(EZw-~EoXbzlnm6f=&R*=K1TT<+-XncCoGrc`fE+WIayt7p~Ej) z;}8w{L+0@&b316!3MmW|?oXz<-}t}_N8!zK9$!jNQv;U=CBlr^BI+2MsS`uynlbdG zFDqUh!JzPP9I5lc0DhHhPh>AA;1GMzG5+&0-C!p!sFL5;Jh$1{Wbv@Qe+VqM_w z-0@=89R<(*zj1?mL%~2NgB?D53EN^0pmew?o;13{O{={uaMZ4|U!BG5-st_zbXbUO z-KqEJ>$Zet7}TNMJPCJiRvMH$JVCR>rC{<;hyP=+Eg(m|In?m=J+72_N4B4?;r1mK_`6WT#n(5oIm>>) z!>PKER2hV=M#;>qOXxK{vK0sE97FX-y5xOS6BTN7;cwtsbkI15tLvpSt#!S|??R#b?r(5-t>nixlbjo|V z?&c7%*;vku7xsm_k$I5RXoJ0MGKGGd!Jed)Fx4Zzls9Doc|N;@OMm6C*N@!5LdY_A zbiaf7r5VhzC>(!#pXJ_uIZjJfB2=A^TrT1GJ;nUr{%6qo$z)_= zj=3~8a6u=;@bmq4mcHQ-%ketI$(YV%6AGQ+b$2Z%s_Ei?tT+JfPe)M4OI^CWyC3~E zj-Y<$_R=c*MUt0$yK!7w3m<&Rkowo2W5+*!!hm;baI~*7Egv6&JL|u)(-MJ|{UDmY z*#*#HA)}$S={APXyo%O)9@5>-yXmaL7wYqXBSof1OZ%phQtcS(F-KCJ^GD#7a8#4? z4bL|Vdyk$l3h$VK6LsICv&%V*>TO_2KNpbZohW>lrcE=0Gr7sqH>{#T^e7;^lPy^|o~4`(qtqYC z0t@8}AKQBr4!=Asc!}2X3Tq=JL#}M$lwafu4umka#x;Z8P_DxRr;;QeXN;o$hS6YC zJP!`QOqOE}Ak!xl4&JXpE7J^U3@T({YfQ;`_hVFQ_<`MuxqL@t3^yY(jH>P=!MKtR z<`@&fqS!Ym9e(`9{m@m z2WWw|vN1mKIK{hv+6vQW-D3W)NAkH7=P`Gg7JQWWfJJDnWD_4Y^ShqK^4I;|icYGC zInRJl3SPkj2-AcS{)Jq+!aZo6HAXz@DNk|NDCo_3 z5h(BEN{d}qO`3o1BkPjC%SK%*V7YY**>jCsm~QS(vg7;F?P&ot-}eaa((4m-cu4#^a5K@OZ&L&U2*^<>?(_yH(b*m?9Hy@%>G- zvZP+fM#s{X(ubTWQxrGdJOcac3ieJkh;*X*Vf^kY+!Sg@yL_|IJwpf1d-y@yxQVpPVXNSMZh+ZV6PZou zOw60Li3Mt;V4|lF_@)Q5<6{gd^HTwa)el0$oBi?9Cq zmu+(LVYl~p;a9uEtozDy+@f&xkoevw}!x%J$r;dY^X@CL+^3QvrX{7ZJ*eMM+dGRXFnpO;h-Hgz~s}XO<{=x~1 zo(nUXw^Vv_w=~z?mgKf;2=Boea$lm$_wOj9$mCaiceW+9j{iV!Rve*x`M%N>f01VF zHG#t$0zgB@NpQ6kq06T%SbwPsGyD?hh2X=IHGKyML!!YmaU8_Gu!o?pQ{bGjE`(e*sMCS>Jyf8UBzZp)F}ojYW!E3ob!tVV6;W-R?`!EM;@ zPRR|&DOs~GIS2QZ@@MU&-0owPQhA%~_w>_kp*q?V9p9uWIxL+h$i^qoBmCuyNiFcHx9K-Kec%7mn?Rck*p)nt2Rw zqhG|fH~wZ31-Wo}{a~@WX(L4H?q*J&y6_}0RrJVL8%`~#U_KW_09V|(^RlOCuD30u z=DNbG0nKnqeGO=?I>7z$@h7WQZgf9e$}RSu52qt~Fe0>r^ZM@_^XgM1`XZA8e_EZv z`sXb0axR2^&jyKA?>jKRJ4hqcXHcNwEx!F*b&e2Q4Ok=Eq9;lNJ|AhGua_8M}~{2{9}$>1MTiI1Uq z(ax}Iy$!tB{!Pft&46#6lUV4VAvEE59)`So4Rehaaks-BFN7)2Iv>5qrO z9=|wBwHMQ&XZFxINFSch%Eq#z$*g9yD!k1-4f(RcEKcC2jkPU?d2)K7vnyuOxrg?` z8EOS=)SCpCUUcyFmnyl;`es=0@CMg%OojDq$YvjQ-D0EWq`~l3pa=RHZ0m*9{B_M! zjFslGEgvVchExAIbaiB^u$8l_e2e-WKTxA?8LgX$pYIrOI^G@D^ z?`C@Zy#b53luaW@Lttjf?6HN$eJ8-=Lml+b9}8t;GMSmH6Li;Pqu;Z7j*~quFcbXf zVdiSGeDI5jC+%U%N&C^$LW$~h3^8{~JAK;O2X1e)#^8Iq=xWVY&{8#o-SJsOZhkbX z|6_hogfG?4(j;xEA;qn8hWO#rD6P*oBA1P{)!GqLp5>rlS0#%HOQCQXXG)#b0OvnG zq||5MX}OXi_NIy0yqwmxlD1!haqqI9cNu&XVpuISt|=TNxBLzJNF2@4l`zL zZx2Jw=5BuNf`?39nEsrSFc+ zJGYBh&@AUZ{+hz}q{OqO3xFvvn29>cv#F^e2#(%OhKTxA`~t~6+$wPCncyQ{8}L#h zQ?E?@MR*J;9`#|rP8yQWXL~xc?Ij;koQob) z=7LeWz~(#Vp+;ySf zDvzpDo=6myO=RA3m)XA2v)H!Z)o8g_iK`D?%Z|V42g6DO;9}+xh&ktqJ4DOasb5+w zaIpo1UbBJo4YSFh;2@{5Is|k3{vt<5mSk{Sf@3+8(eto( zxhxg^E5@)lD?zR73j8cM%IO{!-fNRRAh~sbty{s-%uF@9D)fLg8w95P(R>WmO=n{x zw4rA8X2Q@2idIdc$4cL5^!-$JBXG*H5nBwkCWRnGfLw^(=h)8GNhog}o{fJg_=L zz}@*1bD1cM+l_MB`F=K-wP8HnuCGCVZ6&(5RB)W{^QPPD$8t6ap>%tz@Z4m|Z0@ZH zRwLwC8dvoZ+bXPOzp_T5^!P;Z4@%+JM0&&a=?~b&S{>Xv(3MST8O%$XBdFxWT|Bx% zU^cay@D<7vKu`S=V1-f$R7Zk9vgB-_OJ7*mZ4KvdNo`(T^uBh5qPxX#$mH z>eK%yIuCy;-#3mMA(cdt>^+jKjPqQ#RY^msR5tB|6s1WSky0X}B?_gf$T-h+p=2Z> zN+oH2+q<;a@A>@$=VhF8pXa`=&*%MqF656@e=Mc)eZaqXyb#=NiujT%N_ak~3j232GxW9zx^~+S&SvtN7!^NSt@oe!%@{j-+FZdZOKibMDN8kw85S< z1V)nlU~PK#aRM`6cZ!YnF5wM%u&K*an2&ut_?)|lgA+%? zt)@mMJyH%Fiod}1q=~DD)T0ZqpPk_rdQRufojV7*A7nOJI<-(^(&|If_uoRweclInL^HteGuizm2 za_|N0``rue1?A)P9oV>gJ4j#~z=A4$T^u0-DVV+#4p)Z@h=>oKU=kz`VauuY4Wi0()hgT{?i zrXnh5O_A+jSd_ucUOO`v;P=K3%Ir%fJK-1I({@tpBd()SQ^K5M~W`rKu zik364&1I~aRM>}EwZfSzFupdLQqo-~DmpGjvVI3Rqp}A)?b=OCH8|D~8i4QjkAh-} znas3%E%(o34$Lhr$HT+KxXfn&`COb1;d_UX-JnRST-^qHG=|cm`?+-c%3L^c)t05b zT18rYdoe9G0Q%Jw1;&6rZX9bbs`z~vCqFI1rHvEOf;O-lNtW5s`x)$WINl8m^dsz$Lnm?9hwuex|>UjdotqGm%>*(Bz z26Ww}N)WHY)I)yqAvS?*i71Kwty`Z&4829 z2bjP6M#e@2GL@u1EH*%xb6I!8NQaB8>8vN)bgf!!Ki`cWdw;-y*d(s8{sLZIsmKg% zD{;li9~i$nMs!Ilk?_(WJlC=gw?qrPLbplm-9a~I>RKc!Tl|B|aOL?`2HD_|SHa8g z(T3$h_CCbn3&&n4g4Fyw%%oqFRW?O}#qZnjJ?ja7qG_7AL!}w-Xz#<8`$;tNm;u{S zT7?I!xAD7-d@w6M0bt2CH~kE5jXVM#BUhmN-$!Ve zEo2-IzNt*?#-dY zzQ*)AYygSRDUiqI?c6`tf$YfmK`ggHjCwzVp=9+?SS*u4XN!`dG%10-AG8gg>m1;x z)g7R)^@AyVXf{@SFGpCULSIMN^6xcI(7T8GNqujH!0`Ein$|5i|7t9G2k)f1?@!6u zvM;tH+mBBte$=lGWX;~v$2tDbPWjG_eI`-t*;*rFfBN(!`{u8sT1#>w@v zsw>)5F=i!wFD2^NlBYSksW9!@7G~7*4jaAA*!IXS7H-1PkCHR=(fk?h*}RnwJ<6xa z7L_>hp#~KWR-+-;K0@NvSgh$t=Bg)t6Z(uVaMrcsNTY4QN^vVj2|v3}lMAl#70xo} z6qcjAmDw*Eh_isG$n%$bnXg!xw!C@3yIgrLzA;LYm0CHYgOfB<4e;e0$cP#*f`j9#I;U`YD;L4GZ{VKj&k1=WcrI zzMkEk-3=ZiR5*_zbJ*vE{OSWAqUmD01TK9X4Y7x&lVg!Btb1CG3l$CF=_NB%%`Ip8 z_aoT1=sdiYcmX~e+VEZ@WN_R42XJzp5tF*H81FP%k&9?71Z(zz{X;W$P)d^@x9$#? za4rCgA8&yw7Ekk3WT;&722HdL5{vu8#Qzna!Men`)Tveg3I%S=V~itqS}C&73U%h_ zlTQhkODJhg2<;}J`25QgAB5D=t%k#N&2KTKJw8CqUvHpX$Q91|*J?^hDyB96Jry!; z9&r6+Jl&bwmXY$q6XQRsZ-j$sQIv@k(1 z03n;!@ndGDFkfcNO3#{$0vrI`)CnEh^vGJ%n4Rmd21~!WjEmjNj?FS-rRt-Y%s@v9 z-eyBywymI7Btu6`!Z|}b!N(nrq$+%l9$(gHhmF#y*6TR8YAlJCoh@bK3E1vo)A0NI zl{D+|02*GJhI{5_)1y_jWOVf?cI=!^cLxne)LVz;nP1Uh*lrw@zJ)Dt&|?{uia1j1 z1lw>lPuzOq8f1*R%5|UX#*!y;jLkg3)?Wd3=8{|7{IwE2Dmj`_bRTnE z=W@Z*qFLDO9guuL#D}T5vLlZ-V?_6UEIg!)X;pXmk*|cD*e6M7_lw8wWgYNA*f+V4 zRb#i7e!wFMm*HN5@S4Zcn5^n^$bXT*6bd^*DQ!2VE$l(vPvv~=%`~oZ?qVu3Qlv%M ze)R2e0sXfolN^qA!uVb9z|QM2CeUo?x>-b`Ak<)2i!X=9MecftY8g`J4{n5;(*EZsM+feM4 zoyZi&SyQi52bS)0CI5%gHJ`5n6CXOjGLARH;5J>djC_apvhRw=>~m)dVar+m#|Wl& z#SIU=`v}^G$;>=Q8MXF~V&hNmXE#^QAS;iJ$cuC+;^7K7ui?vO$vV-VI~!THsxN8HmdH4|<&ZZ0J z{Q*=}i^p+eRq=t)@iyD(2;&TXbDz|%iv6xda6bfo|ERa%IOrI${E?ejSjRch%=$of z(YlUhM3k@(lM}F9@hpsRn!=tA%ccRVhEw;sabRZtov)HzMC12|P}yiT@>q~gZ`CcS zW9S8b(e@@B=(C@1@lvKomI52O;xUF!H{oLT{{pt+7pfWCvY&}B@y^_f{Ois(nCjro z)<*7+kst+LZ#v6R?V2wj8^2OCZE!j&pfHnCRv#cK> z?D(r3-n!45rL1sgWy3hOM_ZHJJ$HeYQ4*yXYoSr`5?EGoTy*@iBhiRcsQN4!GKGwZ zyJaK>2JA-HRkMWb%~rNyh9)aEKg4e`F5}uBOs7YSkBX;0+kjf~CCvWD8m@PN1HCaE z4YThKalEU5(C={yC*;h4vKy_O*C-?UUU^2~YC1T$7{yVRMhe-jm1Zex71^+Z>p`f( zvfj4cEG+&7_rbo6ofZCHdplJ4a}6zQLB2dQlPkq^&k})Sy8?U7uZmoq7eHic4_qwR zhPS6C;jel%W}>qbw~W4lyM%klDW^sBR{ILK`)mfklB-9_KMf+Ut$}Rgr!bbG8jt7S z#-do~1UCK}$>!BgVo6)w`NDc{w%Dw?W#f)YXM8)H!DapZXy~X;A0z}{lE*wew^ra{bgMFxC!1OJpD31-yNXNadhp=b zKTJ2~6DYQ|3AraT`sS5MmNF60?e+uWlI>8*X&;tM*-1*9uW~w^FAW%(OddUFuuIf} zGoR=2)lcWs&z?5;_OTz77ym?mUYO*6Xo5cn{Ym3PCLb}c1e~+DIm*Y6CbgSV)&-jH5x zTS&~^o(|6*NVz%g6t5NyuBVo8#u7PH8gQMf@$y7hcT)_NmS&3Y@AEr)^LU}AEt=K$ zUhKRmm8~$Jjh@wMZ1dtc$lmjhgdq{ExE_LO*Y@)v7v6Dphvss}O}k*;=S=48y9d2p zIo6V`&MdmJ;hpj-GH{we+|XZmPgxF!OD=*-w^!iWC$X?0A(vO2BM+{h7+h(zr2Z}K zXu0wfo9g)u_D;KorawB_!^?jms6n!3z@w2+t}wvy(X+RZ(Y*=dY-4HQw^MvW!E%U| zGozIArTA8(6=kPhqCA&@^fShZX}vLFsrox%^*TcqU3doEtD?Exexu>RoHWcoy&QZW z&lFQ^Eo}M`j?P8_&^L7_ted038uX*+u~rUkm$jvN!b~FTnutP%34WBP3i#!D0qyMi z28aI3gnz+1#Puq*pc6ld8C|Z0EhB0`=d2Z!@!_B>u7G$xn^v^wQ|q!^n)u@oyn8Vd zPIcZ#%j?1(Phdmpg_`X)7xfKnoWoQ~ zN$f}G+?{aX#URw^HK4HGhj`EFG0qn56D4ZCEbn*(#Z1@^MoQW6;KxhM9ypgYF5g0v z>j-X5x1dzYl-xz(v~|-F_E7uSH_`5^ z_4H$P95d@r#PUMovRHvc1w|&B}y~yW(v4Z@I&$E5|~yl_oUHmRx-I2G|D>l0e5O+r z(wczZFKwk+-t*zCiW%IwsEl3fhq8u^>+p-gK}sG_Mz*WFP$_C7`O7Bb>0hmmJ&X6? z+rzS?V15ajnp)B`yhzxb?S|DaB45ler)fPJYF!{1zYmbCgc^ZzfB4UN43 z0p~)Q|DH4KTKE_4?Vkb&dEm({e48Zr#h!EbQq!3B%nH_&V9P?sn^8!&CAnuV1izSG ztW0d8RePtCu7Z#g46eo6{I%Fx@fGH*7w#iZd3<{54~{yhM2>v}k+Vq`YfE-;hEYM{ zb2GQ{f2@|#nu?*cMz03%27V-|J=fuzoht-33OSi-CA#c2Qt;fg;^-9%q55?w>85R> zE82_5SgsON|C45mOfJIn_eOjloUL9VXDCWO+J#RQzoLAZ3cA+_yQAL+;nvV|m~O03 zUgI~hLXT1myub(jh1~CC3)s`wKnwvUJQio=!M8@c#FbK(RKTH+fr* zU$$3cMBh1FsJDo?vMhWSaGf7_{u|2W^nq2<9X4w7G%oz`9+uHoTwTfqlftPJe0<3a zs*dWx;Xfzx+K%_|Z-EzX8CAr-)cl5&caG$_a{!yCx1WD}bR5MLN{Wg$Ou-Fm!{Phs z9W*WZ0PW40N#A5egaKoy{;~wjNIOZNhg8v_RjDxg>t(o{+6-Hd#(~{0Ns6wy1Fz=C zu@YqmY*QM{9*jB0w9728pyw*~{a8m;Yld;}Ok4Q@e}uCpUEp>Hq}M+-1r^mw8f7pgFliGRF$$E+*Kc<`6l80?wgDC<9cAW&`DmEpiVv4Cc%IE z28$=EK;4SEKIST>hWq4&HfE8pY=8(q)0K+OnY-mfPu3qQ4u~ZwMs$=w4j- zMp@`Qb~*Mt{S-|+JDfH=ItP~=WyJdP!}(N;54hIKhM*u5pSs_Ii>f*-;?hVOzWOlO z&JIDnG8aBSI}i#i3+cIcKPIUKv4K)aB5m={Y85wS8r`Wuc|S_9{&^r>dG?f=D+9>rm~UV=93@58YbQ^2EInys)n24516<71bFq&(Au zHELDjjol?!^u&`?GH20eA-d$MnL_D8KcsEi9E4tHR^qyb-Cm={j%NOX?|I6sqG}17 zaQis~9Tz-}!81Xx`#AeT|_JIR_T|sT$N?S7_Og}auZ#RnPO`1c=(vQ|>-pJ?Va#FkEu=>i*N zNm_5em~y4RLxIIo+9Nn=JcjYqOnBoTsdTz9aSS8};aLl(e_%}wl5l!oKf!=FL2PnLacj%H6M zr@)rrB04iJlo^K)rCpY#WO==u8$VG@7O_G$AZs_9lm8wpH(zEN2WKy_O3ufc+U zqJkMno`s-@3}&4aLnX^aqr!%aVE${SMaqX7SKIOdrUv5j(hrVP*d4D zdOum71_)f414qWP1IpzPK02LgO+CpT9Pneqe|hks8`|*aN=0;@(}rvt;(Q+nSX&)bq7d6=?kp5tr>ZolZU*P3PU_ zP+F&0nDb3!ud3Iw2)75^yK!&W=C(?vVOq>K9~(-m6O(ZMMq_q7#)OS+(Zaff3E+{T zf;K|lNb5lX>c)?t?{dnR8E;PI(SyLPKa_eR&BWo+ip(*5AG1~6#5xmF*{YLgalzY} zlzwA2O#I8k>of68LT<9t=%|a#eVnG#pqx`|&G2<(Z}iFW&7gfuX0RScq|+IorBocv8)OsXbR*psZzu4JX}HJ!fM`LkAb-m!ak6vPgiO8(~} z@P1?lH9j25e0jlzQuvOUryH`PD!cLPr&&xk&zW61oCBM@9hg9Rhq6C~O!ve+CaRTW z({Gluv%cwYX?GRQNN$JLS2C>Ba6LV1pF>{NJLtbH>Cmw&4nCmZ=<{0w-%8{_uUuf# zNFd9bEyIRQHRhfjcrLauJWB3H!koD24{nRdCMUgma#1I4Y{FLDxx$!o2YjUDeBGLw z2T#b%U!o@I*FU-hQZ=t?9}qw31Kl}oR+BwD6uOlTvY4@r%-G;H=-H;ju@AYhahsSm z#szZfdL1yka5#uQp6A2Y41jtKGxkp2lC{)oi)^!`Xs7yRD$RON(uXkP@zNidU6cWKqOr{IZz{Y# zGy>+lc*Q?7-Ue4@A7pK}w1qoDDl;`rWXE1^32vTTYEdaX^o-?l3m)RCgl>%3+mD}0 zGueF$cQ!t39@FWV$JPhzX7e`-TqN(^@ZQp&%+H319c0#m+zbW$lQsYqho$k#otn@u z_+>YItwq}sTbe#SizaLYwom*MLVw8#&+9!np`Z*c%8&CZ+IF=5b_%~`X&j!O1#Hu+ zA#BVTSN1%6DqTu$!W%y;i21IdM}uW*_CB?)dAVNb`0AH4ok7>xcGUvTUwjiR(l0^m z?2*tf>n<9cY{|OZ1sPFmsm$%y01()L3(yx^%0UY2R(oku;$(woMw79%`~~g1bXm@ThMb*-Yy9G1@~yYjSy(}K zX(#Ac<4elEJX45w&ZW6yuF>+5k0`wGCLFkKLKBnK>E#6za&Hn-z}m;8(cwago^SEe z48h4#Q^xL=w==~}!O&u7M!XQ6w4I9W;|npfX$S48 z`^jaON-%?!WAVZ7L)=F$9si|#CeCX%ZMDk5VIf|mnRFi|G%C}{wEyE0grRXs|D+Lb=2GHf{u-B$+dLT6y{gBZ4m zKZmP+DAD&7!rnJt8k#)D(SXyXXmD|yXm*vp(7lSr)T%80cKBM9R&2mqx3x$tFm#8_ zw?i50T{!AS0lqfZVEg10*!WFlY_v`>JM3A=mImTE~LE5~OFBXCjtb=tIZ5+2={#jMumVZw-^boQSl`>CDF z6+iSrzwV3RqdL^7Q#XsPwHI7f4c^?=TAmy6!w{`!hA?dJ<79V8u%g@1BwZ>j-mV?N z#Hx>c?+aBdh*ZI?H*dnzZgb{!X9^p)Y$p??WI^qeW^U7?x$Hex%=X=0&lDHcVSz*v z7zYVXit$^V24`40nMa>zmC~Nja(@K+#Mn~x7IU!onNIaDE4e>UuCXP>D(sKnIkszB z1vuMivj-HM8=ZjQs$RtgA#x0_lYg6b^r#(A6V>JDIo`csk zTG&6sCH!4|3I2KaR^Dk7uTD*@3UYF7k&m3x1-492NtZ>i% z9i%yF4*T>Vh^_RLqIrowan(2rws*yB7Vu&l^*8U}n{OURiAT=(!6*rS<=lqBHjbF? zERTl_9%Hw`eg^;L@?vaJ5$YEO1%x)OFx}ttY(YR5O~MTq$0p zJCzOCSPJ8(+G1zcwBFl9j z%idqihJvX^^inw=2mjI~5qh$%<2U1%Kk;zkobXI$dtS&xIKb!VFzP>Q%laJ!?!~KQ z=$A=iuV<&TWoPejC!KFQ`YLO(@24MNqUj|l`)LeQ23LULEI-%|_psepm+sG;&gFp- zTRH0kd1hDSVrJ%G2RNEN^K)d zXv4%#&LQX|{_UvePM!Av$J zjKIQu=OFH1P|1bwzrk%DtHq29BiX8DohUKjH5R$+fXzy2L8Y`C&z(I6w`+yKpXe|b zU+)I$Q_O|?v^Ts=i(^)ul|p~#G}rz*5Q5z%u(FV)EUt7bx0ydq6BgRkJYHc~6I-~7 zu1;v6;|Uk&iNzhfZ;_A28L!bsZZYe;+5-_!b?J_;1`B&5!L7E~%{FW}hdC?L@agTt zZ1u)W=BeVrK7Nn|^^i4W)ay((2`cpa-wTwlkE2l%f6;f$JofEWKTHOWExsqgmO5W& znigXALgzdjs%Sv}!=_aEwx0B6ZzJiMsq|0gCG`7lVSg0Qvq;yMsF65~*_bvmr{AtM zXMb(1iJw(cV>jNqX4)j>8t+(_npNFHX?OE=sLDJ{1v@_BvJKAcK$a!D|5iopyQvP| z9@JsywRLD~dk1>`P-2FkdO6Bi!D!Y_b}M5in)Qmfbv@hIuDxnx&*@S3sCV3rpg^WI zNFUDnC2=1&+R^=&m-)l4`Vi)8%GRAUr|)TNG3m|&_U_LyR3p0bV7$EY~vN8EvHz6N7VaCIvi z5#9=qRfm!5Dm6B`rj-0XZ6FKaD9Avb+t#y$oANxJ4>~-T1<7=AumAIc#MbTA(PBN~ zT6RKFrxi}KO?X#zEK8fRg`GGpWE6Iu5g2qiY}tB4W-%g{eeYCYPkK+`%Ea?b zZ}KV3-L#q6Fo#3r1Hsjfc`(W{KGm?); zW;LVJxoz&lP_8e58y;VXw?4*$SGQhGN7@2%3;GV3SLA4y-&?l2Ud}1;ksaIBWWRshh`Z~CGDzo za@3kn^M;v{@o0Ife$`GZmwS`<=jkLfGz+Kylcx?|iH!>@LTS1CD0{V0m|cFr)V;YV zHj|`D?N7Ktn+u^o&!3&2wMm?_+>)Cj?BCA~)DXv8R$|$xVKhU9;hf;z!e^+Sf(=Jd z|I1_K;!sCj-@bAeHiWY&s^i$?HJ0p_$r#~tE63K=*}~n^*`T=~fh~J@QSh~np`gsI zY=mSIYx7iM_H{S#aZDK$=bT4{*M-=y{1a|nzE@QEK8Af0cs$b$SHs1NO3YOuL+EE+ zhbv3u*fpt}sQ))hxYK;WHNylq$`CzLaaxI*(}HN8mn9YICF2YkMQ+=>9A5V&k6NKy z#2@^PDRNN>O;|aKu6+IIIBlYcqD@AMcZEAZ?v0C%t#7T-(=!OXf2rdz{bo=-s7}H6 z&1p_#JvU8K8Jxz>$L+(~B$ona@i9$&!)Wgl$nd@l0+u1+5hMBr-S zt~I7=4>~_Tj(4vNrUwTlY9x~{VC1}FEOwJ3&*UN8go|c8ooNA+mq%f!f*L&k-VQ~I zyV2&aEK0RaM(4Rh=x65`oZxqr|GfM=?j5%qvQ8khp}>c}as!r`sjv~wbK%+uIf$NT z!;b$h0IpD$eGV#w!FS7q8rfdBy~P3phMBW2le=6sE1`o`P5dF5H+bj!MY^0am^BS} z3d=4HU?ZkkvExzWSg6|ocGNS7e>g%D$62aSSj+)`q@k z+mv-1WZ&p>gV(4qNg)?e*SViAs@=r9YqV)1$y0yTC_K=A0_~d;DSY%-Z1S#ml%814 z-9C9#93e9kPS1%EEl`cb#+t-aD#p6_VD`Pw{L?-2 zc+XKsVNu>jEUSEor*)>X{IW%$;cSL^=dME;O9a0iYIsO5n*~p5g015OUgOZEAokW^ zgUlpZAMogV^bRVnnZmxVSd1o{Cg8zieUMBunBS2`X4SolQ_g-5Yg3-WNTgy|B{&zcU zwVTVX$2NlfKQ&g~AV)#ZGb!@&c~Cj(4f+37!`$*LxGlK5Dx){T=8tkTv2zM*y)3xL z-rT@RXHIad2VRCnFE5I}Uzj00myM*|%N0;p@Ru$Ae_5_O;4_Y;XD`eKXC%nPN$GoJJ8VKf|tf^8eOTHNxDL> z^nmG2QG7-lp0d+}n;rK>4|1R4%Jfk2iKt+ZHBIC@cXV?blZL?9@LT*Q$D0t6pMYvb z$9V5ao^YgF(a~k7&rpo!|CYmV*cjGISD5pmZtX+R56Dex&0OPM(Z;t_jEk|0_b0LEa*SDuL z^sP4uo9#RBLWwQfo=JU2wcl@?f`wgl*bN!)k%BN{A+!p=tp;W)BoD=w$3#e`0h8?D!&U& zcVtuDGjB8u--fzJjJVxThLDv{77Y(L1x4@Y&{v0bboJkTn5861yNfMIe5n?6Z+kJx z>FJm#WsmLahQf=@o~R)|gTyf}(x z8;a}2{Al}#gSu443^tGH~xH2s}=l$RGNk%H7x(9#6%@{dexpApFw#yaBKL!V4^%TWJt?FAYEpiF;{;p2#Bo&+P!Ys@?ej3bT!ryM|9)HC zepLUiO=Xe-*Ltuq?-x5^~T{q%ToN)Hyu_b=;E*&)%*}4 z)20^png6;!6p!34;A59Y@YCXBxi@tVLLO5V_6fV>?`L|@Xs<5p`p*bgY3mAH>Fbbv z%bY1YE74P>-~5ybPjI05R^c^N@WRb?_*E;1vmB~M1O82?{fq0d(YYOy-z?=HY5m4Q zbq!FPIT=?z*5scq|G;M~D?z>0-Yh*u9wn?3A;|kGWYj01SHeNmOP8mI>$G6-6kn12 zba7Rl!~oXzF_E3<+YgpcT6rneWl&%D8i#G3j&E26uCKa=nUimdU+*Zvzo!3T+f+5~ zYl z{6~S#EjokRosy*3IfNQMB$K8xhf4P@aD_>uY3zzLOkA~B^vZQ9=9c+$Qo#dgP2oV) ztIOx#*9cjb4Uc%sWFAxMWw_@b7`xoK4fvH>#Fx1IKYxSDGletdU;>mb9*ocXJ~}j< zRiVUPI;1@JAjat>QSm}wy87xgzS!qa_r9*6r~)yT2Mht1rWeqvsl=B5tAumi!ED*0 z<*?}OL-9seE1`p`Ov{-wne-{(w<|xy|0Nkw8Mxy7Sy{OMt3S$Hw}Y(nKWsRdk6|Mx z;oU#Ucu3Wn&z&<_{K~{m)HJV;_qfx}XSg@R#Vxu}`neR3-)e+&QfKg;z!YS%Z~04J z5l}bKh3m{Z3Z-shu03}Pd0PC2_tQUs$uNO4-nM}Y6=n#V;~rwu<&PjY*^KJPEvE4; z0r0C*id3z}P`mCjTw5JU$`>x9nwbw=Tzn93EZI*7>N>bvYN;@;INyK|)=b?1NG$$9Fo@h%ALo>Q)f@U@rSO zz*7j5RPpl;SP9Ik;Y?eyP8{#H4#kQp^kPg2CLQs{$S0GK4sYbWSFOUa*2Agh+CID@ z8bJ0xZD{lK6wcJ$2h{Z*fyS&W@bZQu-7^oQ!qd7n=@axhJFOHnTU3PmkMQE_Qu}ab zo}FmE!g)T7Pe9MSi}>zpmf)T`#x->x#bkdII&gD7g;eBIh_^Obyf?>=fA-{IZYFk~ zpvywCg)HbJQ|{32b!d4$2M&d~h~p-9VXttHi$C88kD|-?zyIyfCu8PWMM)p)c+5)>Xa za6KJ=_>lW1_}P6FbQKw4uj6h$K=mf}eT{<=W;-A+RD+3kJi&bv&O^-)hR!Ov7&y(I zZp;s$u?Y>_kf>R@%wLT>N0IW)G^1N5Vk@yjMxoTLAV z|8s6PI!yZj`5T+~)+G)2L)$?7bGf8=$x}agv%wL&of1jC@)HJ4X+(pL>C|%44x_&4 zaIf7P@l#4BEz6upK_^tGbH;YDv70dSXbs1`n#XX%7&ZERzz17OGhuRIAp9*q%&*wf z%r9__gmNJl6F5npEjuui#ZLbLq7}EG(@%wI`LBolZwF%JnFEk)bbvp0Dce!P=qoJl z?SUCrf??q@D{y)}g+AP_hP}glSn@h)lpB8pY&+tZEt)Z2U@=VdDB->hh-cDYzFF6!MyI;mZ^QI}3ai$W!-F(fb#@mQ;b-!|ZA6$VE7tQcuR|W>=7K--l3&z!V8sOn- z5}h@7g;%BDxW#kJd70jA=#(Qvh5H2e_0xV-R$0b+?>!QE43$NP|19Y5{YexO^a-h1 zg&s*vqzl`I(2PN?-1h9paBE~O{!5R+xbe@i$xWWR`Bt31>NiRV8N3mB9Jl^X2jq7) zfxgT{oSNDR)55Y??NbiFsJ;etxz198y7>76rE&SN4&i(`0D2*D*iztvcPeC9+sZvy zEnZ2N#wJ!zbQ#Q2_AX<4RoX>+??|!dYk0UBV}M(#bjZzEjB|#1)4x|?Bg9WhWqz897;wYOC)x&SIw8OeL1L*S9)7ZA= zGvBM3CUhbXaLZoDgD!W00#r&MAT5OBeT1A7K{+Sc;@edl&xK|nGY&xA~msa?hBlxt%Th1R$f{~a5=wOBfilr zg(FfnQO%81F6L=D7yHeQ*11Tt+D9>PNZORz6btxbjb0qpEzBk)=c7*X3A~dr3R`}E zz=1}=l=n7;`nfllu-1X%RMx=l+3Ij=Lx#B7eJ+Ac4BInKh9CFTnyybapfMk9$hzEXFRSuN`6R zn{zvVaAy%V&1j;OW#8%PCHb07nnF(FyEEy&@)f+VdHm!~X|DW{9NoD$hiO$G;>4}7 z2P#m9*=VkYhbm*PMQ>`LJLma#9QtD z)ZP69%Qp|DBUff)%?1f3o^uzXh8jUt#1XtK^vn32vIu{zQK+FalN}i}Zt@Na{d5K! z#})C?8w7sJ5(~Czu>$|GPQaV&G^Lx@>+pXJorgb_Z5YS1N48|OP*Fx!ah~fYC8LCT zld?)gqAd-jWQ$~!k&0}hkZ_*smQYfWhLV<|DQRmMz0W^zKF4^@x$o=x{l4Fy+wO7M z-+209-X)TJQIBql-HA6=Y=zdf;;cevJtoJ<@OGT~j&kbB?EaB*rp@dW8Rnin;jP!$ zPB#k8i5Z~cT@A7e4Pc}&nn)bvV}5TT>0i)D!al9QmwE>DnQ1I`JrSe9%FQ^GN!aqG zz3@X#f$M7skrhR+apR_482axt<1NHJ8?NJc^7a<`G;A6%w&RS`a)lgj`6{u27w z=3_(MNjhvENx$^F(rnirnyA@KEnYU#Kd<%4)Fr>cs+Qxoy}tn@PM$RC$&&|eLFoO* zj1=CTPtz_Qq5Fr!SO?Qe)Y{w3>O3(=XOR`p!3`BCv%NrAVV)=^W76p@RuIQebhC zGJ+l+#OrD{vAr;Yp&l$7aA_8)d-52skGQhxL)q}MRn* z&7qahDs>(g{;k_ypjU>LLBF~IJ91D%Lph=9Alf0$%0tr1ZvtDLLH}ygS4PEZk!uVJ&HKL z!{m7lP6}HZB2>fKzRO;SJ7&|8`BUkXiDz*2ofo*?CWB6GSVRpc*3#K|ci0UcP9t&apJC$oIy&$-hR8{Bv%bM)I3n*%wgh<*`&YZ^R?#=CiI59<$L+GExXhXA z)YoWoO9H>=xG{x?tHCcIuVhnR+EkuTdm6TOlmVw#@_CbzlowSRH!#-r9K za72#oFI+^eD*n)2=Y$(#N4Z&FU=POpe9hELS1_0V3DcByHOPMA;Zosf(qY?AuDEX@ zcby6t4f|d=U)Iap^?owJHTfjyX(b3nTp|&A(<~l5Jx^@MO0oS)B{Sadf*)2}lb2(+ zSkuu?Y`IfGE-!sdewh>!TYf61!itA7t6C77DNQeRY=v{hQIHcm3##tQ5mmVs@HjV% z>OMM5)%yKtvPUku>HkKFO$({V#_P;#t^;x4xepx9;T+5M-%;Y@JUUV8F56-J4>k6C zgOt7?y}o@H4GR+@u5p~tfdiv;P(#jmqCmh@t7xBl`RwT!*T zZg5H^XXSNC+FMbw{Ow0j`yN5eRF{!P-^H+ery}vpoJey1ErL7f_a{kI^m&xU!WRmdWJ%-yjHTeALqpXWo%ocI-vHOW#qq4^cWwmiqgeX;cQ`YY&Va2}fevmtRC3?SkBTF~1q zk2$-_;84E-Df=^rfys6s+Y`b_q)%0D?dYbT@<7yhbBQ~7ndn{ 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 z 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 z

    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

    >xkC5)85< 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 gYJ)HQz0oN8jivmo)LD?2EP`bY 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 z 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%0D>W3Zg?{mV`!npTyqYjyh^N*% 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

    iDej#-vau1`{zbsKxtXx>Z6-Vnd?e*?YT@=& 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
    uoW}?%RFCPAY?qgf@)|W8?VM# z^S(-`@ZZ9U4y3Z_scG!Lc^S-W`Wqo1TMK_jnZO|KK89ah%}n~)vuKr4Sof}w*neLs z*+@|`Io*ezygG#z1_HY&c^G?pUr;}8_`{YZf2Zx9ex$Q~D!J$n6BuVlDNE`UJzjqv z>gKo!nZZN6jp#pC1aFvEVhzik6GET1C)0s*uW5bPHoiA?9=baT>`EDLIzHdCAh&5R zDt@~_Ri6gK^|TCDw)Tj?9$HBWo21$Jq!#*FC9I#Qc@j06LiHYVsm&mXQ`;QPUL~Jr z8OOUoyy**kIN`#&WpeQR>e=wyX$lQ0+JvVYRx`Dg>o_YnTguM?-2n=i(M&FtGw90531n}YO-njnpj(wHyt54#+>o+1!I!h)sMB8N zA#Zu4x2|t^RpI*u#2O*k)#EVsl_Si z7#}HgJ@uJEeG2C>J%G0edBwPsTe-GgP3HbH5uXk$!Li0)V5!dFmAnr4iBggZV@apVd7~XS| zQJG5q>I=xx=LhP%>BOWd&!DbGnRQJ3g?KrejI%D$D6gM%{pb_C zZ)8cezdO+MY(>jr_VoLAc=Sf->GgTy zgeL(o=w1<9^k%Hh4#npb{N^Mz`F$eWu}Z8pJQn{B&?JjFsy2Q}QLMaWJifDePrkYW zSK8n&ZJq6mp(hqIt*A)iWTk8rXYXM;qf%(!?Go4=E@Hj*N1%Gn6;4_9me_Yx06#3- zl_hLkC+dDwi^G;^kdoqbn*4SXeN=R3bCxIz-m~wpyua|gtc@#_Aaf;KV&mh-^C{X@Kl=vdEu;9&5X@7tYXpO zrQE6i>_}$zD~xtM53SRdGL0F&?34OBR&rzotA3%(qLK|EC&`c{oGf5J$Id0G=T@{_ zUvN@%$=WP&)n|A83UE&98<<gTOLgW5h=5N74HXjy+yA*5%o(O&M=t^S;~K=6Cik$~;H-Fop;l4OLcTR_SwwO{< zTM+8HKI1$>*U^z2Wm@atLd!1Cp)W~OsmOC4gV*{XizWq9nyqPZtS$ zr3@8>32egM^YJ_HLlx;+c%<+Uy>tITPyP<#C&eFy;wwc=^P;iMK*b1w|58c&4D-qQ z^<5hK;uU%4ou<_lFX@3r9{m$~g}vKbN!sQVEz63d;T<<<{nPIh{`Cr-ST%q)nNA@Y zy%50}a)G8q>xzob$g*Cp7+>nzv%}H}%;dhXZq{oGp4mNAqy)5ReIoY18iiNnc$leY z1j~1gA%AyCyrQ2wp=|YoUe0efzviRGa-$BP2WHR1B2Lr zy^-vWQx3oMb3Akk=i^Iv2XpcXx3FknBAZzp1R8nTHg>}Q>Fw<#+-Y^=#JEYY)N>&` z3!e%1P7Jjv9y!EDZ(jo&(GbEX{kIm54=v@LD+KS?ggj27AH}X)&Z46wVs)PAy&>=e#bm;Flcp5s|Gt7?Es^Lx;D z;uA<04zp3;p2;jjm$F$eOj|IP{2w|aERp9Et_?toLS1I!-2kP#RLH@t zN_@`2Q1DMKr;ned*ejE@`10H-_>;JZZJ$9{7vGOo)o74(v?-O%JWN``>}Z^h9Vu_H zWZ~luVVF+~X-GeWh3li4cDXB)eVjqj6D_E^c?~ueDA4WA`{>uEg=BqDhg#C|UU?sS8=s#ix`h6N0JD*paL-iY8_M!a|ouwtxSARMki7PyFt<{ zqHHxwZ%c$L|ko1Vd}>!1z> zDJPSh+clOcR%KbUV^Qf}+Hb14gRKW(GD)N4>|paNfP6*;dyMF<-)omR#PIiV?eaI(@L zIIni#w_D=Qy3_cmV+4IaAUL!yttE9PqOvkwjOmG_JEw!V<|R^m(Ww=@SJOl2*9b)a z>gm(aFnZ)y&es~w=f-$>pzeG(x~+YepLR8(;BMP{mf0}C=8aAR8?6<_;-|l4NxA>w z*a|r&J;8>>Z61gJvTST(Mrha++fB8Z>9P#|N70#vWA$}$n9Ng#q>wTtgecRq*QO{c zrAQ)ajt0$|2jP#*Q^^oT5lJJ(bJj*lr6SFVL?uO`6s5#_-jA-!7mw#UXYaLszxy^k zCdv};wBo&kCBg-pRM{oNT+H0(jY_gX?8;wCv&|<^xqvFr4PH%6IVbw2E0$(H%%}aW zrBr<8Wx8HNi_T~U7N@s`&8#zFr*Oj!yEpnc_+*T*ZdDgIHb;Szdm7H^K3Xc6veAip zoOh+=R^!NygAzb}jQHn7EJmiUW3FRE5hk_@_W!kqj=eR)WnlxbIyD$p?$V}fSHDKN zgjb~LQyKj6Nf&O^8jbt)LW>;T)!R+C!`2FDu+{dn9kCeWk=w%Sq8ec+a z{91&hddS;#kUT$fmCPJ8K|lSs==Wzi`25#|-d7t0cCur#1h|hT@tih$tKf- z#h6lVH0W4MP~Dacuuh8P{1Pls&U+S(=nY0&&pbm=r5+*NLY={fB>Nm;oja%gB;yQg2tE;)HErRWX+!@?D?XH{VR`Q+>%$e;duqN2WNleYF>B4IhciB zYV+yMSrb`$n=ZQz(d?XU228wILDu}24Z)LcfM8BNIp!NrO5Ng_%cz^!y`~-2ABT`R zHbPY85o(t{tc9b=iMrT@7BN;KJ;YcAK9^? z4oAlL?0)<6+f4oDFI-)t$&$A$CJP@(!wXSMp4V(nKi;1}sZlfhkawqPNiDX4Zwm0d zj=1d^w^MAR*-_Tqe3D7%5_&rQAa1p5O!vP88z4;aQx`?qNLVdLPcN zwuForAHhC5zDvuyeB0N>LBiaRAX1@W8^7=rSQ*;UzrUY?t#<{PGHZadFO!3mtpC_c zu_Tfv{ID8TT60;qb6Cv7dIQ2VXuo-XC4Wq zUltSHXCCzE3v(1%W`vW}oFPc}1z4@lg&&6|!!vs?Ztc}Kq|hT77I|HO{wKzy_r)|^ z@G644ND85=Mil}YUyxsZTk-riX^8FF1v?g812Xp(GXE=rk;;Wo$h|@J8_G0wCJ|`% z|A3{-=hE&q2x-9^pq(?sZL+~V1=r4+0T8FbfK{klRrFx1-H4-Z-F0)#8p@Bx5fxK!He9Lf2y$1Hb0vEIh+Rg zUV%;LykRT-2l)=qVfdCa$P4C!+R7&A4tR^RHm0!#u_$(1XNVkDyNN>+KA?!tN5O=v zM!%B=; z^?|tB$*}t4i;+0XaHCB5@0oWmME`k*Nlx3zJ>3dUchxAc%jAE4yquXO^Xz<|>0D8c z9v00XjomIzq_sl_o!Dj2e!B}=^d^&#jk?^b*Upd_xDJIXy&z__5%xQaLT4851#ueB z8SC@?rO{E4K)vv&v^v$RRD?a*xwv}jS^TCXMOQz00;LOwh~fUV7%|Tk_i|6s`|NEz zsHQ>m9_)mvfjnR4;%GtlCsmd)`wdETgejF-HnF}eyWf<3a6jT?R;i$LIL8~pQ>{tilnAqQ3+QKSwOIekc zt4s#>?s2r*D;$nENU>vI7GPh-6gce|N_sr{NszArK1`nrZLMpu@K2tw#k_$#U8at| zU!H*7Uz3Q{wg0#U-X}0jZ9N$4?SPzNQzq)%A?*5@4ZqKs(SevY5VkO=h};N{FA}-M z?zM2;R0eGC@$Xn;{`p&P0_ndmaCNgH;DO0=tQ)5amn1lpl8~S-O5(I%c9p=e?kRfS z<=;moG3=*k71;juqyD?hX&mq8xx3z(9X)KvE|!jFdp7X<40OVEk*}dyCkN-fm4z?* zA_7IFD*Su(7pXp;g#~sxxPG7zmFPTnhx^6JR^EZQhoVfyrwKcahPXt_0sh_Z$NY9U zvf;K$WLuS3lU**nuhGV_KgFrq_)WHz6V+{Ze0<7v2@>$@iz#r8@3FY3deMiURO#ji z+v#^xY1(zLT5vUYFL>-aE_nL#5s^M3%Py2yQrq?8soFU;nli_a8r>YT`B575V`~EJb&e)m zC0256BEQk!*@`yyq)?yNO|VMLnN3amD_k;g45#idMgQ({R%qqLT=hnDDiLj~i1lje-kUH`E`i1&2H~h-`VdH`@bk3TI z?I&#U7TXO^L=TWD#1kGIiszokZG}f-?**B;Rtz45;_pq0z z%>E~kdHxZ1ylgY;O*6$pZv(hCa1~E_zay)z1)y-56|rp=1?fc>a8LC&lvR->myTsosT7WxN)vqgNS*_HJXZ-% z2B%}?oq3q_Z9Gax{UV)jFOjYBFJW}MW)#f<=uuYJaRtPx-x4~2VoZvvq3!&hDEI&c;`(k`F7g^=%Nd{wL7T(y>CEn&LtR3lYXA^4Eb&B&)wr2Y2Cd}mT5$;BTsL)U-N$_7gX)kfl8i-Gf+5^H5AU|&ZIlQp#lD! zH1#sB-nD`MoVT#9wbvP!a)F&W^%utszZC>oo6)TSv3N60o*vRv;3UXX@*&XOMvO91E9d)zmE!b3H3@$pgWeQXUAQ$3HRA?jS-(FzRqjYU!-T$Urd+^lF}%yqM7k!4qFLW+bo-fw26wB7 zUbX>I-JHU8dyMDy>S)qso=dd1pl3RPykCjTUP3uZFyB%ZhU1?R8p(LYJ%xa^J`KHG8*_Rs5rlV8MP>zYW;bs^6O z>OBYFGEa~=$x_?G;gBOQq=%lX{JQ7`;F)E&_*uY;4R~}=mgm4Ikm7N} zT-lz<_+X|5TYmWjH*tzB_8ptSz9}`AKF$n-L1h6hxUmd}(p*?wf(FaG!+SG(MDV)I zJK|WcjN39~*do4Tc_FF}Q0@}S~p^YFs(r;_xtaDZ{VHY%{&V`81;9`Fs(CQLbuDVf(HiH_*eTn98ch2{_{?*iObyuU%c|_V@dP$n$qy9Gcfx?q9qKZB9IUrg!sP7r zR3}>vHO&m^=7WlMRw|B^#@Es@E@t%h=L869GK1cRSh~W)hdvk~Lt}UR#aZ=wtbX7p zOFNyxeVuX+#kzmPt)E&jp~3(zbS1$Ki%!_t=tYyxP9$IW*~pQFr>S4m8#-!JA`UE? zibo!=fOh`8UQ#N9$E9rP$s$9#coWYxihcvR{Yzd zxSZ3mcqr`%J9{XCHI7Z>dWt2ejOI9K=tyEy>O9!;&Sh+A?m0%vOIW-GW17YV%=4i< zyBMri{>MfW5`K@R2TufYipjidppNgYiR7_;;n8$Q>w6 z7RVCrTNu%t)I&~+D=@{cd$D7@8>W<(($z~nsrcMMDs4EMMo3%Z_5j}hcp{Q_2_-?{ zI#mqyFrlu;ML@kOl{v!-`X+1zm3}#bL1{W%QxeedQY|*Nq#LhoQU)`b5oA+#rcfll z9`4p1piRGv@vPk|VQj22%@bT9MO1=nuZ*F`P1fUl%?3!9T1IvFRCB=`2OP8-L1tz5 zL(D>T7#f_6&zo2AOlDQ|idAMW9MxEZayf3&%Oa7*W68wCIB=TI=dItUV)&gwyztSO z?H6$+(xMjx){n(db8@#JO7$B4T7DlN&Xb4KW4_?V=YnH~3-QzCLekFrB&<%41-$+W z2I>|<-NOi5;c|XdtGo@=BW}TWiShKchzXVJ&W31ZiXSx|a(??cIF$W_$mYtyvw%}* z`c9lJ`aKtm6Z2u!er391Y8-8=zXTI!iLpgR;w(VPl`8R^mVx_#V}|nZa7Zz+?U+Z0 zbpPTja*op}Un>}WVIkA^|Ax6E9$`hVDf`wUU}g=wxsC`vMjn%<0&dV)z^x+&2CR_h4o@=nNc3W6Rm- z@|!~*oXIS$>%b@N6*%sl%D%o4WfDiKkeE1AwH#+!YsRxcch97efo+hxqzrC;@uLkV z55XM&RosfSv4X>Y9zoKg8|cze2eT{gajNELiO!C2u&{0t6jvG0-)ElTW9Pe&eME*H zI`Em3R_3?Fm*wfb6mi@CN@dtASHhHy)LF$Tai-+)kZb>Ji!<{5n5(=5`*NxqTSvFR z{v#{lwc;##@-NROf8b4&SDG@hj>&MyYX-L4__AFQEzpp$l?G-eQSHXJpj^%0V=p(u z+U2?U-|Sxk;F;fU92xd!;)Ejz)zfeyo&GSh_O*G*PxXC8~n~YKGrB%u$Z1C_EP;c z`{}LDR;k!AIbXiumb!%|PB}zhNhVTr#SR!Hl}woP2gpnx4=u?7WCtgW?TX%K_w zcSVC%(+?cq$)D5t?;c#tz=YY?iSeRN^7FqmeEXvxPGve1yYkD>ox2rsZi52FZP90T=U^LC}wMVZ_iJDkF!S$oR<&xYK5E~`-8vZJ4mZ>1xO`zzyh~f+_AY!U~}XsRIe_Dlc7_{k7c45eI*x$ zYl}g%Xg<`6t|wFG2xwDWC#mC^=;~j8L!+)c{q$UgX8n5)?z0$FZTgQIZcHJuovDKO z@ta}Ss;5NK)Qg^_^3>x*Dh5ce=N%Ep*t-oQ@p%P-g?|z;6}~u*ZgJo(N_E>86T^2KqjzO<_FX&p> zigpHn(P)kW77BGSe(WB0#>pUe4S%4c0iW30Ogz5K}^yt7QGxyv(9^^5?;vI8*xTqqpg zKMP6@sbR$Nvt+8TJQZ{&(USa0RGiQJ9IxT~yH1hJX6hu?&P*AeTg{UFwJa!5c7;EKki`Bx%yQ`;cJe45KGT zfc!gox=d?2d2Jy=ovy{x_-1X|AkAly9ux^?wC*8yg$S_Kh5fL$VcDJk5%Y!fiI|KJ zd!cK>VqWrnf>+Y;d3!hBiOoR|wcpsP9tty)K4Ng_F(~OjL9OK# zX}KezW^b;*>c8eJ&O?({Tn>TMJML&4CP6l)W(i8&MzWfP?_j{C6KtB-(WD)UkXGHx zNl5zOJqal~XC}|Kx>^i3^!`IX#R!rvVa0phzj5P=PZEV}Gx#x}M7uJw=o5Y?+_pE6 zrN{4J9a6Wk(BU!;4J+c=&HD71r6+%0UImYrM$xj1@-$X+8Yeg_FPuFs2<0U5F!bIP z3@}ll)oype?|}%ci#texeutD-7wJGkI2_(J7Kgj{U|U`nM!%g1IZ`8-Y=|KmdWoOj2BBNh0dATY?^)b@0L)F~m{4*d`4`~AZZ3b0 z77kT{t(x}CKh7D}%q48@P65?B`W<^5j)y|z zU&Jo(=AEY?VjDw)y1i(te>q%QKA%Raouu!!Pp8_`EU4oYlTOb;E&u zhea{zpnBvWb{5Bw!F5lC$6gV<*`JG&RR{3ko(WKupC^dVzDWePyy4V9I2O6%C&mjemA1qtWLW zelKi?@-HKVcOq1&OqdT_tdPSVg`8xOgNKQyiZ2|$$M12q@g}hkAUo$C1pPV&pVa3(T$1$Ird&jd~hCpMAx3 zBqhK^jTjjIeFo1siPJ^5#>4x4=C??kbzVBQIT@8jtkglqpi!X0idN_sFqKEprxnjL$^oHVbByBk_;fjO{blf$@WX#9p<6tUmA_ zS_Vq6-zFbzQnrJd^$mEiK8F35&37>eCv#Fh-|#5k&$IhpjMt;w{K{!7NbSqqp z6TJEJec&gQ-}n)SB-db1#Rym;Qj7I6J$Syd16MXX@~(PmoW44kY8Rano(yoM_c=}K z`O=6QhE1l9&Ud&5y>gN?%7_&;-NnVLpJAy6VburYxT)U1;L6f-EPK5ye;yhp9e?tv z-M}p%`#hj~br=+X_)D$?h2i1LPl=hjDH5^M@p;FB*Yy zf4#Zp+if`evn~4@b{H#H@!qFk!X7s2vC26q%=Y>RoPMMQ^4`b6h!Orcq2o0v+LA@C zlyt$vDGg{-#4zl}WY)Dm8zW~-EC1|2gv%tuVDbKbcI0s(`_Ekqw0TnRxWtw0?w^UU zG1Q*rcuf>Uo{d1K;q6%QBT=|`dX?bt!xC2O>%~O)es;xEZ|3f4#?lA3F-nX&N(w_Sbmrg#+s8iqKxqY1q~Jh)Xv)0|$5x?=9CJa{s9~9c3m#H?7OZV#gqw zd-o5_ertq@p)u&*X+qi-)uP_5Z|IbDgRF80q=OS}D1U09pJzv5dA0 zDmd-RW?c21_XMS0MCq<-{CB+w9B-MkaVCejai6R4^Y&8CUhFmIHeE+4sfSqesEhli zD+ZS)U*@XMX$z%sEF2%DKy3uCz-*j6b|raGIm2sY)Q)3h;(xyMil#L>-d_iGJpV^8 zGK-B$kPue;WU=@ahdGgAS=xNS0%ja~f$#l3l^*uYU@!b-nbkcr*rRry->G^+>k|I& zv=qT{iC?%cT7KNI17dX5%ox`A=mvUiOl1A~Cor;*cV$&)qvDZ8D4tf23U33M(FbXA zJ#Yq<+&PQteF+!J-WoxZdB5uLQv+b{&cg{War$@70kBOe=3WFR&{+-Yv^l4iME{D0 z6YH;Vow57bn){<+Kywr4@U;OllAqC-z>%f#C$ERd?u{yEd`Lx0H1J$rEd)eB%8Cm@-D75IzvVUL+V zmIN-wDX%$vTzwIz-VOr^u^8^u&D=5tr+1jTKo4vdSiyGr1w?!JI(UV-VMU)Dbf0_& zzjj67h+D3#D5?gxU3X?;q3NvcP8Y7!=Q~;}uAtILKh8be7U|lvGVg+HYIoi z-d^&FXpFm!C7aG*-SYuFYrhUucm~GC>O|i2Ai}$~{Wi+-y6^npth!y?Qe3sMzhL*xPl8dUw`r2$ zbqJc$$K5DaunV}`X!~;Z1;O6sGIZ11TyQqzGm|@c2STY3ECt(y4%tJ3re(=sC{0+c z&rY!V9YZ$MJQChTj`aH-BL|+i&()CEj#wnlttuyXKLEHbVk%6j@z>ow~J`e_}{a+x06SMOy35) zIPEiz6RRQLQmZiK=RAy9ehE*UufQ!2Qjj~P$I_Z7&~aUS7TIDiC#vuaVs|#7i+DV0 z-14NiH$_3&hs6+BaS$a3YdOV=b@=_CztCm$L8|K|&Hnt5=kF};uMz| z+e?gTHH5P4Pg7Xt7-hQ3;S&2`a0<=c_TqBSPVVyxAvMz;<|6sd>AuTGRQ%I_g025V zSjdA>a4W$9=Ew->ulKX5lc0$+_%ndLd=Itq@EH^jo`gPiuGlNL4R^#!V7163wC$+I z^Z7Tp>ikq#$!_C_vJ$)%+K1=DTk*VSD(k81#j)lLCxtlU(%ornkHkA{k2GQHy3|<2 zh)785N+A=))G_?ZLT;FsWH!82q_eJ1N2QMwpq9TKWQ0tjYS~pV_aA_w$9;}1x&u2W zKSzgAqHL_YBKP=U8kA4?42@Sk+3xmz)ZyL`cx-8fPM;xmWWrO>{kVz5=_!>+T<}|iC%7i|ic!0K?+(yLwi$P~Nmj2g$6rP1ulG*}uI%~`>x_hq}o2R^)y?NjP z-(7Ct%947%yIF@RgY$5AaW%_(_!Wm!AMsqeBH@X$1{%)qu7mWLe`pgN>Dql26s*2=X?J=x%Db(crW%S9v_?rrm+TCE76XU zzZB^DKlfokw-Ynca$&c5nxOYr6E>DiVAm{GafXw^nWBv(^)FF`G1d7n(DD}EO$`)^ z{YyuKrgAdk!yRs}(P5C!swN&?P55*J&$F>81%oZgI4-o8WUMl#*L$p4`RaAJG^GZt zGsOivvJTMiBA@X3CoLMd-x{m+PGa>bMf4_T**mXIkoLd;zR$|zJdLNYPs@mK=fz31 z;_p??^283NYk7_L4=rcYbdEvF277j@IG)dSYhj0_C;s`%vu60QT2$2&d|f>Sts9Qg zyQvN|d^i?rHkE@y>_=Ftbp`}Y8gv?aMB`5EgAp4?(W-4ZWzxkX$r=bEC!M;%HlNQ) zdn&QaMg4g%Z@xvK*IhcW>&v+P|FM*f8 z0yj@{kV_onj-T@W!wcWhrk~G&&bsJEHx%=X%>J?50TvA!yz}DC&N+OZ=O8EKe=p2x z2?XY;Q;nsg$>||o_P)Isv}acf?9bJcMaPS=fzPtPaNf^mZ&jtTt&ges0ZsPb^=mLN z(tv)PmBdVB+;L?=EL^E<$F&{ZFePLbsq=61`_E)J^=3R=^|z)2xvhyyYg^*Z=B6tUxh4d44Pw^jMXiqMJ`g>BA_Mjx?#p4c#3@(Yf{Z6m>fg@Z_l_r zI>{JaJsFp(9Aq!FMIrZq0Md2KS=iGScog;peb%1irf#BaZue~bo*YQ8XRHMqj~(cG zX8|?j^S$4l%*X}nNZMWS1Ver&faInpP^V$d>|P~s7JBcwJG^uI)yV)@IYSI=v_lDmsr&uAaABkv)fe=`!EI7_^pzzP2Oei@WcIVcO=h_BjRt0=MN`MtEm+A) zxo0oLX?tNa{QTg+CJPZ8YsIMc$Yor5)G(QK?G|2ddXLGm)0rsgkvL; znupa{U0N-BcKsal9W@C7J9{%0d{JbfA^|8-_Z9aE0+{zW6`Eh;MdikpF}@#w3)cDY zchg|@G$ae(KDxpkX^BGRm5=a3@dIvo^gkTI@64Y#Nw5<8*^J&2BN-D;5@)^VI6u{^ zO#IIy67(Pu^S@Z)!h~R^J2VDH_KUEewkgoM%bvFQS8=^uC6vVR&(*D(bm@r6v?g}} zzM5JIThiHcDuYaY0*X?Alyd?;?vE*9Hll!c^GB zQ9~r;)sQ7Rt?s1Xn|rtJlc%Uism;_wsP#b1akUPv@Fu?xTVH-evaR z6m0VuO}Ah8$Tb>YCO;qL!${Gqcv)HurXJ$IFh==F!?K4}lC*%>e?sVlImb^h1 z(QVK-Gmlib&4sA9Ga#f~04siV3*R4m&MCcd$JTaD__5Roa%o@Do6!3XT?6QHQ8tex}eqr~*xW%%=25tz$$GC^}X{kb)e zj&5|sBl{hw%d$E2_tHejsC){$j$DQFOD}>&zbHoO=3wWOjc`5v1njR&z+KMEa9mR; zmwYTACtd%7TK7uPQ+xn|wya}s&5J=ScLvqSabtQ>C&{5$W855_NxmnA3%oPFl6?v5 zF*bY~DhE9yWA;~&uVck|XP+gw`cz`5^G2u{(xqjeu9C!AVPGJggT<qgnpkQm#Dy5Z86C0?neg2pZ*{z@<6oQRPJ+`4X82 z-;=(e>WLBb?DQ89r|^Wht7pUTD8kE_mawZAg=AuW1U*sm5npOuB6`96p+I~c%DWoF zIi8{YXyQY#`MCnVKW*j23$5Xw)EU^OY(dv`@_eg>>cYg>`IuQb1641DvKdPx%S9!T z&Du4AW~Q99^9~+u_oreJ8r*0np7I*R$!a{CSg6jlTGFu0cb1@_q*|cgmcyMb2*aPp z190`5QFPna3_LFWh@APj148fbE&I4L2^;MB9)RU3E^A^esKo?wh6dsILSqob_`JY2 z7bTYGZj0}ZJw`DSjv1L(an)wtV`Kgkuk(3Je|v3g3;z#4_zno>7%5_l2mf4bu>{5N z&CvNJoU8S{#|<9fxcyTA&3?7wt*l+p-O_-!cu%{x3BP9^+JY-)-rz(>i__gEJWs^V zk4~#vK#kUGGg$TqS#Tvc`gg4`KqVa2(yU-$qd6?&xm^i5OE94~9gh?oMHha@X52T0 zO&>{F*iZg_Z0^K541(EinIn*zriqRP3YclK8odvT;DdFaNX)1fEYo>H?(EHg^YUzUssLJvD;pL2Y!OQ-FW7Mld~bWpd`n6|VQoI5uclOST=C1>^QJ+>?NZSUn|& z&w1o>Xv*iN%g<4n|8~=`&}4uoPX!`5(qz4BpHMHslZ&kn#=e~epwBhHh2>M}tS@`m zdM8u7#d+eUmqX~#l*YZ-^NRNns6jBLN)}n~BH@aXPlfg}#UrV%;wW5u2+(Zts3hVbwbH|6IV7&c&C7-P?h69T7P9 zS}W|lxPlbCkRz!%vRt@1hr-bzH2&T&;q+X=V*lEAU*E|D42M8=j^f~;;D4t=WUGE640K#ilEG0)PH6~D>Z zX)Hw}UlE42zqkO&LFl+%1HHZkjk6EqJT6AqtGx`euFhc#%0qGGibveUKgsm5|9|i} z*bj3ZhB#No53O2$*JMlF5_U6zd(B zRAV+bFC0zhy`RV)IVP}s zp*LZ9n>u^nX%Ag)2K=+m9yC|ELFZy|`r?ivUB0dejwG+JooA=R625$geebS8TW1Kl zkgP@b-ns-MpL%lRRxP&u^6vxLoHq_uTydv=Iz{2h$nC@j8P~n{H&@~5$lqP&($%K` zBQEf+oaIR*ckya8OY-5Ke>A17GtWc7+83B~yH_CUyca@drQn&S$1o@RGPl{vnc3|S zFH>t+g(K(n;r7~bY`g4eHfY&IQhL|W>cRssXJ>?9!F?}sY*QD0k2Ate*{ituQRa9s z{{~ZGJd5;&CozoZv6X)CvP>&=AD8w#k@GvV1G^HMQN(i|oN)=o@jhd~?TCW#WnTbj z89wBmOH0vDkH?Z+by4PXYaCj+MN+Hl7r2B^i*QaV&(QsT0i4E4vlMfl=&>HRVRrOe2}UpQL6?^@tVW}NlM}OKjbU3cbRFYLrXzG{jHE)+B{z?^`IPXP<{`qmWWcNz(siIWjosIUSuL$ z>TsyC5AqZ~j>Q<;}UY$$sGH>ITW<4l|{?2;v;D7FEn=z>EVj zuxIT8bebf|e70Z0C;IjjOgOr?(U_L#&xH40*<72tE^Iv0z&#yw#-CkhNpgi8r2UG* ztqMV1bMdOo;W|x48zU4d${!pifpxi3Ms2{f#Vw@pnI7s z^MAHNIJc-DfBiCN;^`ylRh@<8P-z}_>)Q)K<3UwWt5Sp9)ruHe<0llp3&Kexk$X9} zh1@f|4_fv*kl;(9U*OA$Tn=X{8}^a1?c$6LO3~ky7h&SbRJ?w^1=C!`xo0{TgoO|9 zDlc!0r7e28(ul5UxWRXVkDZ4ikxJ}6ElnyKmcVLfL;6u;BHYWk zh$^S~PN&a2mV0Ftrq@?9lO#t@<>VKVUXw_^Twg&7iXUc3uw4h1q3`|)SbxMG8&CWu?kkUR@L^C8Q=HBDPNLd zcs%!a>vK*GEBFpq0r!2OJG0?49=&`fZq1w5KoP&tv$yo!`k^yg
    0V?e(z&hJ6oSCo&5{etCzoQW}InAN-jx1$G+dP@W$6i74Rv$R-Y!5SKy2xIQ zEtq+$3nlqZ^&n9zGajGA17b@s;L-=KM5a^_Z{EkX=NRDw{Q@9nOY!2RU)Y$vfgN2c z&po)D1@=|v@xQDB&g9-*&ik1g@ej^Lw_-EAMTt=$DE4{{l%xSl2`Gtvqyot2}dyX^>OUHVD+!LD(f!9^o- z$X|vPsTwe&7u{rl@33i3ZG+^tHuSruN&l{^!83eMzc%Is_awoVh-8`L0rr3!9=Q`8 ze{C+68djro7kn$IZM%y|e0#v77a&B?^7t`onspCZ}Ew&Tt{ z_Vkw7SE2Q-S|TdfE?B#BCw5G6gsePCx?PUJzZv%Ea7Puk)YgM{e;hPEu%_i_35FQR zVAg77RBIeT)uy%J9`MJxR;TcY>=VJ*pTu@({%we{e}%e74f)xZ3rfwtOP(zsCfeVY z5!VT!!b|TJSe5Fq3-8@IBURm5g+gc z7Lq+euH6Z4Dr?Zw8*@QEGk|{2(}!WZnt*(^1;csI@r|Z4tO)EPQ(ND&{ULXW%E2g@ z{AUsD8Kg)<1V8kb4te-b(OSqf#dGhYEkxYefzETTvd=v+L_=02dL()U_3ze#mB8#T zP?kqOi%oX<(}wc#2}Ag+s4ck8?=)c>3GETpz~1_U7-v$%oBrx^_1zNqSL&|a^}rw! z>aZ8D`6lvWl~w%f!6@$DG=X$X3hL{COKi=@U3GW(?0|#NDBRDN30iE)oOyUm zrB#&V@mK6yGmiYHuE;BWBl);kF<%iINT(Y_QbQ(f-`9N!O#+sqXK5PlbMOMqQEGf| zVlP-1Wul(ZGd#4WUhtMAlVq<$*z*Uf23|@9)ynnoNn^XfrM039=J-M3u-oAHLPxyl zfskR^--&kwy=cyt0sM_a4BAc1!U?jDe3qOQ%;@fg{C{rf_9PK?v_8Q#JsZ0EKY6h0 z{tNm_3;4j96L{*2Xe(rtj ztD746 zNDvM2prOvATe;ydIrO=u3uipWqwA6!7$o?QbTfi^yz4B~Iq{gAq?`bS zv2x<}wh$=PNWmNa&9HIZThy6-1?&9Ii5?uAMR#qEp{bdd!K;8lWtA5^^?MH$gHFQg zFHv>}rVSP8UbqCGY-hn!CTPi#51`^SqUyO}sB5hQJrNohcV{NQGD&PrPG zLkfb5%9+ZYdaQV@%gf(u^SfmT3l)oL?yXt$qn;*p-JwRNnVc18=~akt{BtIMn=A2= z*nxyrjH(fRxX2x)qVZ3!BI>I}vL8~l)!Wx}fuX-W*_ZnpGLFO(9m_j#K=Al1Pw#|~ zt|d^jromZ!u z4=d3)8#NmKSqggX@}W>~JXp&6!}XVj;F-7=qF-KuY~38_eEnYRFlHvce>ym(I%hyv~9v=B5M(kY?Bdp zHJ-&o%%<`y&&#oQEr=BRjqvn`ST^*1BwlD7!;Rk@=j%1&`13nE$?PXCm>n<^yDa6n zbCz)TSAGobd$-_*BYC*XBN0!(QX+@jJ4k!B5hyl)Vz+iav70>YfXKhs2ORulxc2$C zxSyEQSMPjir|&4ctE-wzxHR+J&dVs#_8!aFjDn;8?*F$~h5_(eBoEL<6 zz#BPzI!K(#m4nLhgI*5w|5Am^P6i+)x&>QC8gsF!8W6{?@Kb9CSIo2KL0j8#-Lq5Z zeM*V`9ej{>$9VFXnx)Kt-B&nmX;3ru$tM23pc@NZ;#r%tA(TD(ZP(@*j#4p0>6)Y@ z$~RZwlu3HjAh?F+g(>h$^dZ`o?T ztE45H?63)jZ|NbM%|F5#nISwwv5IMh$FhWqFF5I79E_ahL+37@4qNt5fSP%4AgJ{q z7!2^nu=grd&22W_;gAZ87j9u@azBOpm_3-Dy3I7V4aa~Df?q1-FJ4Wb%Vt?^r}tJ} z#Mc{ZswyYv;0H$~Xcy9OlmF`S-SYX^cXh6Kd=tS@SH6*qm=>}t?jVj})l96i0dCbL z3ETm5p$Fm=sGh$C%G(Fwp3|mi^4~w4qE2~W_F&%kFo5rDdq%ELoxw-_zK#+{2Gg9Q zEqExr9veeGvY4yeuyvsyd$V&mt8GibUu$~BJaTmPf@|gMdZw_H)M~)XA9DF^%|qB9 zGnf@xm7?u57aSRo2nvoL$-gms`QMs!9zITZem!r6IeQ!r&Pc=l`>nROo8UVY}p3T(NNgz;uu={`GOE*@=3Do2l_mxqqT2~&$Pdbtl? zH+m_0+qRL0oS6ph)gMF&#|F|sl_Su5f~s7lB81Tl2XG z4uJZ6#Lzi6$fKB8Y%7cb_ZQQlUv{1N(2QQ#_ez0Ii_U>RiXY)kX$&^Dj}j+O?S!7p zR=7EGAD1ee4!y2>QCId9B)FGDaQ+W6D&Q6io$drYrG&VZ?iJNe?n67XQZ#6p!%t4@ zK$|7kFy6q7AMa4-jdNbHmF>Mmr(_ZjTelB=gbua5dDD1K_Cg-{aSvacJe_A|J{0FZ z-$*_jiXmq2glGKA4MVqUVOQfT(L7~uu=?f$J4|Y)tJ6R&b2~5ANK28U22JL<1|r|C4CI3l|@X?*B69 zZwIO2kb*qX@g3L2<`?(yAdxq>@Giy+yQTQ3pH@6@%mb9wHs`K=t{7Xp0kf7Z!@_S~ zJo)z=X1-++7th$m&n+_Har%W^d9D!+u1^y9dO`LnlMX6?}I^l=|T?qIqDn?u(P_o8Mei>qFL@Y{9!Q} zyhh0Lf=`R_)XTdVw!#``Jo;Dt;bAW;cyoe{E&EH%yCksOwhH_cpF`luCNL@e03(Lk z(@@!Y!oHT!TSsiDRdQ(*aa``)##6@>*<3LiFhV%I6JMm z01F?V0*$3sbm_K{^t+xl|2*O(XbO5s(9v96H|{sMZ$C#3uV-=3t6eztMK;V2ZQ@R! zIsRC^9xwRZ1(V3lAT^$l&W4RNcXEm7VoDA3%il~>pQOOv=+XRrvO0|)sw3W!rw@KcnksDhyVx|m`C>M`_TUn^`*}VeIBh9Z zFHVNzZ$|Ue#ZlC=Gn%eY98Qbtx59^C%jwax`{=pOf6!um8-8~kf>twS{=RJ=lt%bK zpp6npn+5UuKQHm`KQ-!>Gajs8Y4W+hKErOshtR%zKRpyH2JK^}Xd09V14M^`&P7|_ z5o$1eS}B}RKOy8wXW$T3Jv>`(!e93u~;>L7uHoUi&epR^x-5r0MEkXm}a=$+zKWl zciwiigZcg*PIt@2!8b!m@zd4b)aIHgrc@YVa?CH-AY?i{x2TcAYirT);Y08ieEun( z=V8s+3donPgTfXIy1u1~wv3UZ|4sb~gYOT=g@+z6pVzI>6&F{n9rqgpCkjy3^R+PP zu>tl?9gpRzmGDe-*6zsk$#mTsH&idE$Cb7xpn9q-KlRZQq6Y&V8NPsjXwG2`PE+Y9 z0|h?f^hcuaAV)QJf9H?1^m)EB1*gJ1O!{>KG`=`f`JxvXp)?P&7mTJ~kIm+;rHiXg zSCj4?(*?8j=D@?v$Fabn7#s1Mc=dK^h%-+{_?(I9?{m=l(PZv9C4h=N z4B@A(E$^~3rI{Xn&|9uc&yV)vK?5_{y^%S5q$k}W__PqeDBaWj%jV4zioP7+$v?#vdDZ!m8|pMCx-1 zTDA6}_gDuyK4mQ)7WhN`>GkyNBr!da|5wPgsNwFv0;BBtQf5{kz}t16ko!^rLcT4Y zFM2qgizJrvgG!ItKRbEekk=p{5RgLNkBt`pNWTinLCT^(OJdokdL@k5AZ7neX(HXc zco?0y){?r42Ec-??nM4eF8yQL2nybQ5I5mIJ`%ckW=ap@W30Sj`LCU*(+k{W-wtXx zT$*O)htUEz6O@z|;mPN3U{A*$_WX(%{rpOVuJ|r^l_7K~7A*tkDW*_hGLp*pX;bep zbNKM`UUErnNB8UXVCzZYjy-Naq}u1<#S#<2?^O<;1ud?){3i^E5rd`wXl_YLK;F!Y zRy>xZdHZg_>Pw6HCQWyIes3tY~tHs?J5t)#$k2mcMZI;$Ll2z+lTWyepH< zL1`y#|JEvU{&-l7Cv5of=bB)drbUDL(s=nO3H~GQ1!`Ic@^>v_EXyv$z0SL-x9B7c z7VdiYe0@=EaT;z3?*Y#jmzjlB9S&_?j-M|4#I&m_e1x#aPS)Pf^23|a=aUL|8~+Kk z&OBk!1Eu->H+eWwq=@NCaxtY!X8B)d~i7G9~sLJJeh=Anq8PWC5*c$kLE#k34Gqs zi=1ynT%;v1p8r|##v~*D@cmFQ=y(FRZ4|*^jc|tbFQICuR=}n4687e=qiFW}@63K+ z6iHl?Nhg{&z{KrEFk^==Jz(+=POnK~|K2`=H_L^coZ=6`lQf8b`S6ja4{63Dm-pgf zb5Ab0Fb-G!w&6$XqPR&+GBarGfznV9;TsSQNz?3L!>PBZd!U63t=|lFpUvsO?x)=A zc@r;L6v-F748VR3!uxE4(Y<^$?J!s2d2zzKZ9I}PNl7l9){2wE7t`ow0~oT#8~Zb7 zqt8?w+TyQ4p3mLOXPPbL=aNUm)Mul4-;Lq?x8Hf}|B=X7Khfdm6pkZbt_{r(W%zeL zW4`)(9)P2=@E?-l9D}sk_+kN(<09Gh1G(GD=R%BcvA&#?nHMr zI$rRb+UXDAu1@F1r0oh!)r|-H*_FPGqw>;IGcwZ2GJzdJDAu_yNZ_A2MB#R z!VWYc16&@iAyzLZ(VEb5i1y1Bk4vA0&ShCx@>LBkkGfB6UQQSM>gP~m;~4&9a0wKB zUkkSf>cGs`92@)>u$Ff&Xf*dJHyY{0r9PbyGM*uP;?ws?<7N41YtAYY2Z52n5u7?@ z9E>WdgMGJ6z_+^tlcS!puWP-i_L&&m={JkT8lQwy(>$rdoR6@r*NlF1&%#8(FQK-^ zjt)9}jf^grp@utR;Y!I=o+^o0BlaE9$X;wZFCJO`j>Io`4auQRqFrl;pz_d(^zu4^!=oophZ~-vBh`1) z{S)hHh^ac==%x*RW21QUmM8GRQBypkRf4Zq$fd^$oanZ(g7?UBBrd8oAv*?dhj&Zm zxU%u?>Z>O^;hR=A2H6O#^O8ccaY7$#E_f=k;nwtfZ#~Ei-v>HdEvWmd!?wo5^09W= zT9zPkf~lWwiK6$5sHc{KI5E1Go%H)alC3R)k1Zx|n81a(eS;lxvxBbmG@_nZ2M44)C@jCkB<%`Cj$s9?^5PP5>e2CPV^zZX_UqGK5s{=| znI2@1*iAzJB$CBX)yda;Z<(2IeD!N#ezthDkC7gqYKs{LV00}D>blZc=+S(#f9FG1 zdv72~_}z?QODukE-4W9-7PDta2 zJN1N(S0<6~X5qx|$3Xt|M`rSMEZR-Jgexl#!a4^{h)(}TUPY;bWu^jAqrr&vhd~_f zLgZW)v6-Gz+1UStXJ90Yj>Wr}-q(RxEc1z(NZn?7RMgBAvW|YBewDb`ORSA?$&*liz)&+(D3nsI#B!gVt zH(Xrg<;+e*1u`vvU2#bG2Bvn|31>8&tLls4Z1a=d5V2q|e(ugE{~jBX%^!kc-aSD_ zUmL~j+qYo1#1}Sjh$(AuJtZ3B(M4PwHsZ|J-niwLA-Pgs$W9y)v5BMW$(KdI+YV%5 zaH~8iKKYKQl-rZv5h<+n+8$E4QXTBaSm1i2tAusjhq`&2&Yvw+Sb7Ve|^@U-_B&@ zr;ztQMNDOOGb(v3z-e^_c(Hi~1`Mue5$97O@1-P!S=Y0DtE$MNSzlOl(@o}hG>*CD zMPu7aDbPD$&QwFkvYJ~$Z$RohVyrO)=yFfe6Ey?QSap-P|2gy95kpzUqI8k&X2Byp zdkReJ5{p&*uG=}!*;rjPCJ9G}>0nK0fpErnfaUlYa=cv{-tJF;87B8&b7(fR?l!@~ zPEEWT`V^hKH=?epl927m#0#$iIa!j8iyNG9W70+JSD#E47^Jb!#e#;Q8H?{mjY7v( zRrJhP!;QCu9FS5Fszj}X)9*r|;LJWz{JX;#^=~4qX!M54lP4-SN9DlEkKahFNKNe7 zaSR*+4AJAv0yZoxR#fry7ut=uCFGiXnfu*2C_Vo=^C{c{W^dbIYTX(nxl>@W6Nh(~ zQ_#dYR-}4jD~T$%#AQZPShwK{(H_&IY{x!VOi>rZs`5JceJ!oJ!6cojG*3a*JgmD zW{PqWkCQ8t97PTujO~4VnQh&!0b|VKgpR^(BxT(~B6H?G*<~eJ6<+wTdi0?(cI2NO zPx2|o8M*SrYfOZ2h9ANFk+b3X_j&M5vl2T-ZNa-Qb_+0@Vs==e6qb7&gYdt~0HzjX z+3QPUE5%Zh5+tg&>b@zSlGI&&V)OOtUptoJipBn-h{$6Myz+_WmlCL2Bn$oq1+2D2 zx%$85uS6eQRp{BERiZ)T?}}1wLO^b=Cfkv3EP5ZP&zJ2zNk%^(NtRZX;;hyb_)k7Y z;M{&h!=$gwEA_Xy=(9V{4I7FQIohI=zT2_Vt(R5IyAOkh>Co5Kr`Yj9!kOtaov$%m z2PaB5qD;pEsEPE1V8IhHryvl&UI@ZHWffR<)S9mz{um30Fv|!mu5puwaim^Q& z*SFJNyAVdox0Be`FPIp68aova=syNUX;V&~#7%rMF6GWKc-< zUDiiKm;aD^wy^NIL+IJAE$qUjY&QMQD_CEAnpBUk#`gl#;K!c(Q2zKN8}hZ6nP(iu zhX>xVUCy!SbmkWRQEg-**$9?crvfWVJRl^>1@v75S>+H#)L3yHKJ=?Xfc<#%7^w*D zmd()CC_~!E`-sP@H4!I6CFnAmjoHe=-mP{Ob1+_vnR$k=dDbH~#dbAOYJW^(c6nAi zAIt~4IT7GKDVr@TmLnU}>cQ0|TJ-CpJu~s*5wGu+p~sU|855r{f>BN{u@^KVmS%Q?Ig4R zx+hQRk2{>Vz~t?*#Vm$k+H4JqL18C~6fmVmTZu4qkW3yT}=Pre7P#qJ-uV%shq zw#PyaD-R}-nay7KV%He(YP&=9CjJ#|ID=w|u${!beFzGo3h$TM20sm7kjbmvMDd*k z0tp}18knXWK(Vr7Q5GFKyvd@{HOkuC{zeu zp)2LMvh5uvYg_WO=IP|R$`t1NpjsT$ERDg8iCmKhK)$OY%+r!(QC*2FuC|gKdOMiA ziCRSFTZJr!>v_<88(pY4X&X0J{C8<|mqu>1De4K_MW;k`Qmjc5tWQsaI zicP?!8oRLdhB8?@*bZC;znH;YKjQf16LDjHG`aT@cKtCUMS^E;_S+;lX6IoSaPFJP zXVzb6gM9J!U2CW8sO;!&cxDkmR0oR!0 zGc}OWh{Pa`g%EM77smuCinG_p;G(7^uJGQ8JSmqEEwi2qb$`oH+bWsFd*;J`2gYO6 zdJ!7)4PvWxWoUOP#LmLr%66E(5mSv!fRkoP zBJp`gzSyIHOo`ATWeW|koj=1NNf}tN#hhQZdBk2QMdPfwd`1o9-@kORAm;QXe{ReB8j6?>Si3!$G@g)(VrEjZv8i*~JAczAFk zQJM1-B!`U0x9d*esyV$_dQ=K`wjAMIE3S%W6kcIomvmu^(n;3;VJpu36b7v!FIkwW z2_|>FVgFY7;kr$}kZRy5^p`f`h5M7B`9&$r*dI);dhQc_m0brtDUNu!X&$pVkR#UX z%3=mjitu0cXmY{S99p)S;zQTV_^tIA&JG+QzW7mv<*=#HX0jfhSmzLj>BB_LwI9H9 zk}_0f%EDryJ9T~ZLRzu<5!q4FBes7b2^z%$^hqraQ(Y3+J)eO*j&Bri3y348>&`Lt zI%WFhpCd0A&0DM|1>X#~Et-FB2|RZhNc|KNVds$vxF_`w+vs%(656bA ze~Aux^ZF0y7W@)bt#E{4T9T;y=q1y)nT+{LVWcy!Q8fJ86mrsKFmZZZBR-{mooNd^ z+h{F+V&L*ql+x2kCNCKVdz#jgTgrAqN5Fl&-c-UWYSP%d?T4A(9v7&z>cV@Kp-}!w z;70|067D%+!s<{S&VRf@W*vVfma@7BZ=5Q~3DsO35L zEehQ}OY+2eZPtGAFFQHw9jZ2*!NGTTqsb)))~Wc8Nk867UR+Iqdf!2$GkY;4w}un2 zP~ZXnrgUM~0P5Qw1%bN$=(+g>Z*#8%`K5J`y&P!eHD8=_atM9R-JyTU3Tj{{5&DSc57dO?iw5x7P5bDA^A9cx9D1U>8?;6w|E-6zQ2#C z&ez3zxg$`ntr8T^o8!;bgP5YaB4~skBObAX`GD?0bjhnUI(*>gqbxk9l||PJe51_$n0`^2ci08;S2kZE z?BQs7rNxyd1|ML{7tVpqLuPQMr4pAdSk0!%dt=Y}82Uc=GxXNAih3;UK=#@cY??WU z$ySbll~I{gs$(mhyUp>Q>^Ra8^;+D~P=dBgVsLr$F?M@l16Yr`CN7s81dfLGFl)*$ zrnE^BKK@v3XAu}BR`)vsx-tLo_>_8l;`dpkq^}OXo8H6i)U7l;|0GVzK1=58HlTw- zGKC)5Vp#3=A6S`IL+;m5NbgdnJ7%cyZ-UNzQv8IF{RLPRc^EfE3%L$SH&`?L3TrP* zude>~7~985(1;SDKf~ZQz6pOuUEjTMMGxcGGS|Q3R+{U{*qM+iKkPrQ; z#q)BFk?nT@zpSlzZY2RQM{^E!I`fa$RRsod z0p4Gy%ZnDz<$vY%g}!QiOwwA)oV-HubW{|UYMsHw*4n&ZAp_ILt;eb#M!2RqpMAY? z2DEbXL}x9R$_L18f=$I1EXK3;6P$G#NS$sZF4q4n*KO6E-OdRh&_1sXd640nJdbc zF+i^pO+HGxm6*v}@hR)m_{YB|ac+Y-UfbLP>KDsk?Xz{{tDrS5o^_mUvWlmx4itbm z=qOI|{VZB0`wV_Q@Dj1MUOeA22@}P((A7Vjj}Y{)G>fSqrQL{@i%i%6&nJZc%O(8} z2I0?r|FM~4FXB(<6#nMEGLMkmhqYa2K~mn9dVMx0Ba~EWrKKhn%ib3=TT3{y)el~D zW`WjL1+F@&lXz!JZ5zp&-R|N6PWg*Wvg}+Y1gg-bQaa zoM%av;2pJ(SaH*Uhc7P>&C{yKPzht9XZE}3$Gcu;5}FUvBf6N{ERF-U%2DRwY81`- z2ltgm(-m1|Sghj)US(sb!NxB1@DlbPvY&89F@x{7!ih+B4ZKquN{>!WfWj$Cyr8TW zqi!jH@{t78-R{Cmxe1O_H03rzAN$U3UECjDCK?;1$G2M!qdTYMVCuM4c*y)f_34gG z95`kon%tPc19o`upm&AX#)f0G-7EGjHvu%Yy-?D30@ZLe1BI7g*Au^O%L@8zVul2UK>DfFKHnMjMc&RUI_GGI?7hX3GCY?4lwGPJfyEtfUVjB z-^c73@$s!=4^x`)OWIp>f0autQ?$7+7qRMHIktaT>Fd815mw?;d=-YfL%toQ|69jf8s^1C?X zqdPahIzcDOGQmqiJEj8<-Z>`8w}Se;4cPmrbO zjb94AmWR=2!7!*?`xnCc+Q4mQ1#}8|4C_%7Xioh`kSbdMZ_J0$=sSI+-faNnv}w`d zTRP$G+^s-n1k#(vTC`Owg7!JDLzZTXyY}8-IsqwoEqp(^p0FUjQ>3Z;$Qrnr@B@-( z+$A}c_7FVs5nEC;mMuQ=RfI+P7@Z^VGF`;DdV?35Y}|yobI;)yyK#JNLo+kWl;v;N zPA6rr3s8S@9afn}!`Oa-ce!>bX2uw?+ns4_QTPG4AhKiue{At%m_4~H8poZ}`$V4| z#)>qbPvk3Be!|GJ_i?I5JNkK)z+k)s%|C8JY=8wuHY&m@cLVHPTg7hNeJWld6$>jX zol)W0Yg}jH#S?_H?TPCKK4AEKUc6&I-xwszbLL&a{j2SvYQQSm@;rvtWNm_NGtBT@ zn>n0_iJ%WAx#P=`fJQ-$C7rPh@(&DebcyBxGg_*jBlre3*nM=1diMeT{?ZHmU_A^FQbq z(Li96Hon>E0b8ESQ2(!T@ZHl}bi#fK_}!d`FYjI_{|!&Z%d?A6xp4_9?oYs5HX7V< zLq67p3-j6p#%@cFCB@q%!L(Z&U(}f5w}Uw_CoK-12DZY)QdxLm`Wz%Dm9j%J7a_={ z7-E0^B&AFKVm8kZc(p@O^^2XT`gj~PN4dgctN(~}#cmWAc@oKx)A+by13x@Wf@c=Y z;lBi)lt{^)N0qPTEzN$ocFGLsbKOZzGYVMO`eI!BpiyLLAHpXUU*~Gk1T&WPGyf!a zJeMZuncBtZC-^^tgO5SuwLJWDvI^%ZZ=t7;E8*e&HJMYCVG2ZTeuG({7XyJb|mK#zU}n1q5g8hg+GlRby-S+nM$(g_q&4phH|i zXRSI!tMYRpnM?3>J^tj}lRD7qe#<6S$#IK4qE98nqH z0&>SF?HA^cIWr64fs-O$&OahpH1bihYY^Y`+7Pv>XR_UYpWv8W88qo}#4(=Z8A_I- za)~^y?$zN(P8=aU!aaNV8cFVR=nCpAG2xasmHDT;>TFbZ8hFGA`6^clI((EZZOuIj z8Ag90(SHS~++4w|o}Yp!8DExoI}2TBABHnZ_PnmkfImH3jH~BzSQ9#v`}#}q4bfis z&rFQM7K_h1n1qHOKH@{L!PU;^;0qfyU&WWCt?G*Ms>pX3?GOZk_Z=-(jY)H1hyXx1&8S-nPEV;W>P*7i3K_nC=P|*Lcpm3(_)5-O%YfgAt1M~b9Nf9( z9@KTr6W@r~$f`3o;?1jn$o`R4P=3sqnik$9>YkR6^sNP6?O?dJR*q}Q9>Rkcl=!!* z<5+Zd91NTAlWprchdb*wio%ACVt1`WQTs;%-=6rFEEq9?OS(kzq3>?9@*gX!^*-67 zq$mZHA3Bmx*X&@^Atk=~XF~PU^hw}VlZN)whw)E;FX8quJ)$OISkxy*ECovYD+7Eix`Rt_Ud{&e5QGEUG z7u=g65BYmDz{KV#Fu}`a;d2N6jAAfrWC#4QF2tAa2jS%6MfA)SH6k5643ZKi;dr~* zW zqQ^f)(~g2kJjHtuf3bTkO1SjmVx2EIYey-O$&aS-b9vh6R$qphOEsW zf1cFk(;F}2#SAS}@cKWy^8>VAlLSQ{;k)u~8C^0m1!VjiFzkZR7m;PaQ;jRcKdjEP zsDI~B{izE*lQvZ3>5#`<0-G@N$sXjwF8fvVQ_ z_gW(SFw1}*+5LD;dKnZL&tYkEfL|Rlmrp6WgD+chK~*6NFKp{X+xM-cb&t?Pd)lYNo4WQAmjSI1VRwn7CRF0}OJ_*i#dy50YXkSDlnNT$ZE;6b2dCeSeTv)HS01ux6a zg;&@2iMBnu!j{V&;Nznt`RQOs`sjuWJv-$OQ{5_u_Gy;HJ=l%wH4a1fThH)bNI7Sb z8vK2@h{_Jz1n;+K!=V8RwBiY)>FU$z7q?ZkbZH9x7$ncrZnY4X6M8hnJDuz9i{J(> zPtogODv$eVPajSAMYbMqfk@c|;k&K`pMvDDI_5I2&^aTj-eQ5ob19!vXUa!~i?FkA z4O(08flry=pyHbvFCP-cnp7{-c`C!{m;*DZ#S35($I)+N9y~86hXX%A2I@H6a45rUn2gkm;@sz?6QN%b|f%EOpB~^Fu zHWOVuJiwoa3mSaKav{@`((dj;2(Rq;D+<(hG+)nVciSoQH)Cb<=J!Tc>u0!$83Yzrv0;Ig@ z!+few<_3O5o5TOXhb8-Io5x(Pr=Y=O#y29|Izal;OV)!C~pLpB^WSufu;HhYM zxb7}Bou^2R4p-5zlDJQdz-*$TVbtysr*AxlWp@J+)dxYC~vMn(lN zJ*os{l_crsC(p!Bh1|mPLw3w(q8IwsiCC=i4IF)v;U^)3*rgv&W)y^gRnRxQwq!My zum2-@_%aZun|b3uc{6VKGLh#t4nZe@nfC6+2mW@4D~uX@ks6#^$g`>lmEC`jdVN_8 zY_}d-(QMK4Z7RIoZwL6ax}e&X5LkKn8cK!i7V_v5`4OJaK0H22b}WeIx2ONZJpwaq zldJ>0yCPz@pEZi^y@`dzm(PfMjMZr8hPizCx$Ah?+86%S+whh5>O|?O*Tu@tvv_!I zCXAZnLpSsbT&ovH$+tWLTgRC4V{w%vYC|r#K!%SN`=UW^dJZ2UC+5H0g=L++a+GxC4cSm$7 zO5jz#YzN(Or|B}6<+OapE}E=UZP&K~(JVodj&$7vi;pRRz2Y_ac4;V&l}IHGEA08o z^R@iG-(0Z%;*Vo{o|1nG-s1G_MzrYgbc}Ed0j&wr_6@@t$*lSoND;Vi{+frO?w2)P z_Qe=Kl`Fw}jdIb-ma8zMY$ddYp2enw1vE(|1agWe(Twa?+A5ZXi?WmXR+}GmKxz&o z$olh?PcqOn`zkC`kAs0i-;?5%(`?YzI&p1QIGS#J4TECF^PdwFxcTMhy!fO-&A#Qe zXts8E%?j#Y<6i8^^^U03(onW*&yzg|;9r`VV9?MEzEuMy$6#S?f_g%qz4nbKW< zZjr4i@;v@PJe(7H;Lm+s!^g}v<>&8Dravwn#?&r|C4W`ah`eHhShDgkzV#4vwEZfy z`(YB^+}FYn40y>c>SR^MF$BJv55Quet`ahjua9Y0@+xHlDuP zBrpiY1sJd_3{;Kp;tG9be(~o9u6r|+$^`7?WoC2XE^CB4LXOJtkqmVJH!64O32fYA z1BZ&6$cecEAI|O$pHD8Ki>)DVZt>>}&PR}*D>tyPCx`#sY0KxHe1wC>+~tmg>v^M| zGYt3YLnr^C{Lz>M@ET~bR z7@GGdi|%V^fE!k+aPmeDL~cBbo0lY_$q-rU;rE=yniBr3uNtay-;rx8-c?UrdWK%@ z$VIy#Eh?AtKaS2ktj4bk!_pv;QmLrWh(ww=XRjTV5Go{v2oZ%+2oaJ>(nLxnQ7Wk@ zC3W`NrObsim_?M#LqtOTeDC%B*VSLWbAVf3+GFdC*e(48-?!14%9 z?rH?I%{G%9`>+#z-lm8SW*)>bcS3RKu@Q8+^=R?2KY_3&QINuf;{9=aOe78sNS#LVRea&^MC4A5|)mjnoULcBL0V ze@HP^kz~?j#|1P)N${C95nAu%PU+(@q)|BtA|F13$)|^bam0AMJ2#QOZ|%nIed(a{ zY9(F?k*-u9YD<56-KO=A!l6Z3oBo*PK%L$gLD(P(SnX&9`do?XMcGcXNE}Z^Uf{XHDk@80n%QaG``x5#xY8otG_>StHR;2!V zHn9HPAuRbBEKw}8Mfu7L*zRphi$|@4hT5z6urLYtx5O~2>qy^dkE7Q~8ZI3bO7|o= z!dSBq-hKBCOrI9O+jLIw<1!_9=*SH)zcn7#HAT|!_0HUDvl*Y3Jcjz(0{(d-^bj2q zJnJb3F}C*~OID5MvmQtB&yR-l(+XFZ-atPtedGxXY462|l|eXfqBW_QCBoC&2^}uv zUDA9qsK(BNRO8w?a!({j-}{WAUy|;EW0W){pB?DU;yC!7yO}nQ8cp?gr_(gaNeG!Z z6?~6~=#Jk8xTP4;)8i0Myn6)q1z4foQ%(9lKNIAIyM3tqK$?V(OFpS9ZA&EO33-{Blu7IC~WI#p^~qAY0`N)`rAd3 zN*(Y3C3%FKhNr2QjwWT9!9=R1lH4=2qOu7T_oZ7=YbSO5W^2eDpRM4tLpH&($1mab z&a>c{8UzbPhpA7_GJZ?>E}k`CLykMNQaZ4^~Q|u^)KY^8=h3e zJ8AF?cWeGw+7$+#Si?^~9L9Gm_s1`@b6AUoG=Cvo1v?6#fw${l2tGTA7e4W(ex~=p zL^XmMADYLnm2RiO9X8Z|*)~3OydixXQjO`^i}9V{s`xj8Qt6Y4!fR6jCufeN@BdNi z`e*~re;th1{O^+SQzvqrKM6GMTtE6>+)oTF)4)kF#^T|7GT}msGTk-$1srxf1xo}! zc)?g>jH`FX8^^|jokJmaax#GDmYEE_g!}H#(R`k73);_dB##wC;gY}KL-rB!(QCKb-ms&#-Vo0_d+BgiF>|lj|vSP<25H&eCfs|N5twc^M#}wKK{lzetFS1jMt0e4LKKh zYj81nUAl#u4oaXN^QKYT8-{RJ@P>QNESD^_y3d{NHSu!CB3`}ShiLm2Li5s0?ra)J zrG{@{Ej5+UQ`|>JnOaeu&Du0&mzqCMBcejvzp9_Z{DbOkJ#?T87M?rw!8L)AlNO!N(r27-E zu>ZaR)x9=|t*aV{c@wPh(ZO1_c~~L-kaeIZUaRq=J_0 z9L{F01nFaw^s{f4yn*}Nrb=mm*?A>`q-Zz#XRxbLL$jp%Pns% z;|5!%@lUa>n7q}DM;H5p?np~o(GtlugYxKwzJqk;S;~8T7LugU5g3-FOf7Do0)G<^ zT0L?L{aLyS+~!zOw|jy|VP7H)n%p1u%^X1UYzOf7XryWI^c`BvPO!f-VBvpe^xCTo_O7Xn?{cl;cg9!anyqC#Kl&5eTiEa!N4H_X z{)cR)@pgKxZ8G-}y}+GQ!f?x(_c%e#fd7h^aRJ zbsNIYiMb?uu^Q~S9swC`bLpRi+bAbfOKPp9=nAa}sisS5Wha0!05`I+3vu=KzKr6Nq{67B$`0Ty|C7FM4kxDjxyx4^Mb94E> z!e5-7i|1b()u4M%GykF)F1P?Uv5Bkp;P?TL(Ph&<*r=||)zU_B5BDrcj84YK?=o>| z<74>tFA9o&41$u=J8<%xKR7?ki90>m2+BPZd8~X0H}TE}-GCK1c~1sWo85pLinGzB z-c(&v?$HtF&J8IVXoyPMSl2sXr&rPdUJQ%Q`mO zz8htXG9fi}3-50jOJ^-RM4hgOaL?rj@TH|9SbP*ZlA0AEc%cpdCtrdmj(RZl(Hr@{ zM&1=Odqu?3E-+ zcL!Z8sV8&Z?8kl2kJI6^uRw9oTY7cdbn1813b&|iq&w>h=qWu5n(4od?r<*@oU%O_ z9p5BM9}~wToX+Fo`cv#k-%YTacZ7bc%wh|?mgCpqp9BYOA-*WvNfL&ZfTw9I1RNZL zqd&hQ>qeI`xg+!7(;E#qu(uN4yfEhrhLrJ)la-?6Qh}%2ew2@#nGcVy2a@*wmh|D` zvjUg70S-tGLidLf+}7^`D6gIbW1R}2-^F+sCuC8!M(!gW248XIre*B)&W*Twy*eGX z)QSf_Q{|t6!dTd_P4sc)8CAF_W+tI@c&h!r({XN!AeCDPJv=-Y4>Jhu0V z&!=jUTjA2o_tP{?*xg9dcVtTH_x498!MpTy{th%(elGra&<&M$5xC)!4^QO|V|}@z zB=p}+_G6$M+}rvc9xYOaBcA`no3pl%*`)y$?-w@XBGad0S>KbGnYI|_t1iL5G1K^y zAF*V(+!a>Ghe<|e6%+r%Lr9;Ii%2xqTr$*12_{($s7MJ`sCev}hLfY=|4!!mfh(c* zqax&O39+ggG#@;?itzQ36%s|4bF6vY<0&t^|4K%8Uc^U=_e7%1r{rVkE-Y-gEnXn% zCLb)S*u1HG!A|`u{4zZOM>n2@_P`X$s-mI%+h#jlyXH2F91)8NG9SpA?g3~V>?CQj z(1K@+n%N9j6S!a`MzwKXY=-z4%)5~a=dZkB|Lqwp`b~C8!K@Wa@V{%v#7pa)i0x!;vgGmrXmMWz z>r?b_d3mp7f0Yb;(KyM*8Z?mGilyw1o;OR9Ph|^U?5OYy)FMBB&1Q+uQ%QK+8%h2o zbG+g<04`tABnFX5ELnFK>1V6KjIB?QQzVFOLuITQ>kZbqMeJaq8;&U$g`b|3LZ;
    At@ny_)V7J2xXQrGT1}WNKa=&zoF%>k_mIdmB~s|H0E-g^Hgv^oToED# zPN#|F#2975*SDZTywD>(;u*OS6o)E5J4xGxBoeh=4i)__V@vk|w#$AsEUUKX_wSy; zw{~eLs>mWCwl_g?XF96)CF7{tapGOqeW1_u9GF;0*s$7f41f6I^l~|P`F$e^){n;d zdor-rq@|*~LYIm69450BSC?O^^#m7#skm^i8jkSaLF5A#qHdol#67-(rv``s``I>B7WF-Erv4C7PT1zrN?tyW|D&%bQYcgTvcGe!) zO%}P3VmdjEW~=eiCols3kPIS;|)@OrpsnIP$$aEv%TSSY-Q z4Pf9EXE@fo0Q7fHWfNqApkqNc=`z$}zbD9`TY(!>c%d!cy=W!=oVf}MJ5zCwV;N4u zB}{9{bqsPf;Ctj}2u$@@p5!Bq_oYVi|IDx9BS$N6=njR`CsV;?tO}N?_&`y_JkYr^ zg4=&Ph6S2OB)@Dgv%fOO+4_NjBAdDAN$!j};z_6eBh8ogf$6=Q;@N@a7!!O4hcvy% zAelgN_|X%bCmW47%*MlLpYM2MLKqGc9A~q=m5A)wV{l+}1l)Ff!>WZO2S(cw@Udp<@xB(Ol!i$lG;y?APA!^zl(4LZvd53|c&G9VR-QXV-0gSa zP1`Z>(ZK*Lw@qd)wueEX?*R#}t%awDe8ej+$kC%sdF1&h6MWWsnC$kCAP;ktU~Y66 z&`-;lwfzb9!R-N4d{(u^E~NWx;22ecU0Jh(EKc@JCJ*=A>xDuPx{C z&*MOT>)Jq}(^JHjBn||@v zbO;RChe_o+?EWQ3+_7pVcFsOX+~#PrC4Mz{cg|eNOFOZU%dp4GlfJMz&3mLX<{(TH zTqA$Z9~FmJsFHDRgC#yIy1+v;3;u;Uk*qPEP<8z*>^Zd>0^;pp{Wx!7*78i!^TiZ( zvTDfewa4JO$vTwr(geMVr{r5zCP}*2!DcnhgGZ~2Nbrpbk|#NzSkdR}68~NM@IR|6 zQsHl0v3AcGw#NSmvv6yWl!n@iMtL`peUZ4s*l6 zc-{r#)ixbgS5y+)uo>`(27&t3F>pc66W*7GOYXhzVuRNxfqSCh2tAuXTsu@r_}n{0 zMy;6bRQF}u<4ww?oZpK4y*EkvjkqdlTsMr3dNUe#&&$PgbuqZHLxp_UI7F;6jEiIj zHPuE z#tvh3=SNVzyTWTjc@yMS&V_rMZjc8P)q%WzLk=jK&_dS)ddD#myF@zZu62hPJ&oq@FPQ^4Ox=xA{K1#9p3 zNF1(s(aRN-7%P5fjXfn~#}rv)!g*zV&??e@V;I^GB^c4~r)06?dc0(^23CKXD<1d8 z6lGV-ks1$k==Nx2GG2X_Hn+12rfXS7b-mS(v$@csonPU5WiWjg{!tRyISyh= z2GbL&DR9qFQ?7ewGW@oQ5{C@D!f>XLnG0yd>;EEACsz%*+e2LNrHCxsI3C#d0w{zF z6+>q}#ehwpVEL6+STSlooR5lQR*Q$TZKIU&^^zatsZ=}3(#wr)chT)42C zTs%-*v0=Lcq(tRF=DS3aT(+8gSalZlFI*AVM>mT$45t#KrWwoBVMWbUD7`vDpl$1 z#W+LET6r2nJY>NAsWYCwdYk>%a}pMwipCPx80@kdipN6tu-RAlz@q+_h_7@UzT!n_ z5c-%b|7=3cEgHyIpDp74)DD~0EMV=UC9LT6E@*$`Pygl@V1sNDc4vl@KWF>Fw$}pJ z5LO`xS5FZuYYZis4w=yDFa`3=VsOi!FlZY&S@>tx&IbIs$aX9?;PdD0#BlpMQS4?Vu41%?ImS=GjoaY8&C_q+5c!(~LBy)Uuv!B^deN2AD0SjhDkUFm}grcCcN(LMTKNIBr|q zsN;_Hmh*4~n}>m^&&kw`9#XPrAl5M9IS*;^ta+oz`yY+CaCtbMRCo#&Bb8yUofV$l ztAh6wx^UO?O#B>~%oGL2UwvFy#gUm32$&KL*(=8K&*!3G<*mQ)WQ)+?)m?)*DrwMV z5Dh9ulc9A@D{II)E&4S51UtNb4_h^`TQbCA9{UooPkeK5FIg}mfJNk0fd1q)&^btt zX-%tOv-1|>*F`J9@z`jp6r%;6(gYS7-5^)yKqxyMB^!*&*Vn)`4i_8P3*zQAhh3&)5QD zOiaElMrvb-T7OOno|HWHNmIT1-@i z_QFMo7i-(fL1xk;*mEZa$89ynt!pB{o8@EqQhhd*jKIfrKFsa3D$F^!l|H<)gayp8NWPry0cj*-0P01o1eRteH zWe58e?u%1EBLM76<)E3&+ z%f;&p?lZfl6?js%KtgamehUoXWBv%|@S*DkF4cf9czc;nHDn(CHV74JMJ^^J~SI^Cd(k zAP}{eJYw1RGT5yPZdkH&IUC#%hn@;1sJL=6NxG8{J9}@6rJl%=(fxzbc}X=YyKP2) zZN}1522(A)R+t|5Q1De}k))_ga7?3;J?a(lQ6o;_<3U65^M-7^_upaMZv7G)T{prZ z!QYZyv7fz^7os}uzw!6qkCi07L+qWc_`{xR zTiwO7#L2y(5Vy>+ThweJXIKPEBYpsY{%y2B7S{Q{hybbzjTJXhckLTKd= z1&a1Zv2V$GY(6;w{dyLmKpoB~10*cQ$$ZQQW2~%g!9y z0O1~k`0stWlcyS=0jF^*F|^DJ?oY17qjkq2MDPL*8I=bUo@>(*!GjV%QXigogwr&+ zyD(6TQvdoGdiJInd~(;PrcW6$Pw!=@@{P1Rwc$RQSuo|Jyx6K6*r6+WIP;%A+8rFr z7bg30WADX$bo&sr2&u=v+1D|2X9Fxr+J`Uw9#-u5%J6DRDL;F9I)+(^#Zx|a(x zg&u?AU@$p}4(@6^q11+~n1^uD^a2jbkmDDBtzdrEEm$^0j!W(HC3bbHTqkE3AJM9T z2M;BXq~G-w4vzIyWrJibN7tE)g~h;Epg<2bKXF#%tf$s971!Be!Kovm-A6@_c@0)y*tt7VgYm8x(lY7MxvUE8H_vd zk-S?xo(`UU0Uus}28FW6;7{}<-0yo8qUS}xuyzYxTq%)|wRsrVjV<2JG)LEgR*j8gZ+fRw4eMcS^UD*M)BPHngWj>d50aUh|3uo=_>I}SnTftW zy#S@Z%&GVLI=EV_!-Km^@c1-_|HhU>%*t{I{(2aeG*ywSv*fs8ofLnsVu$5N52MS` z+0fZAh))`2$&UmTi#=T?qE5{~cBJ2Bh#&YI-ss1WVs9JNNRNg)cTB+%%E`-xt4Q1U zab)^f7iv6yp};uZg8T8;V5LbjyPy0XYhIlNd*4V&)8=}fCfxNuoeF{><6WTe?O>jB z<|h1*oq;RVKQXCM1vGiFH2<(Aow4Bq=m3c`>O35S%S2vCb2CWkfGc3UCyMR=7!I#) zTTu5UMtti$5S(@q(7t3U$O#;WZ^K*hn#imvUuKQumn6fmD=`em>6ePD59CQkO&y2< zW2+=NCstr*Z7KC0LCMlhJJBhpn>hzQBU@tQK+~*;e14)yi!aIJAE!?Ew`pdDxxyk| zpH+mG&S7nl_D6?EmxEK(q3>&M9Kq|Zw)u&Tfr~a|CZ@+MZxm zc6t+7j(!Wh``2*)oV#pAj*z`=mBX1y)%e?dAMV?th1o}B_)r})?w;1iaKtqHaNvj7 zV&o&3)Rido>%AfR`llej;yc?js1)~E{v)}eKj7;S9ZVZ00|zcOi$v1%@NoYdnEQ2z zICYGxBw>;zh=$xC+d7t&_uU=OPk#J|Hcx9XZ;l(^es4S1maoNbhjaMmunzdn*a!A+ z%E5Mp9Ba!f0M~Q-$hn+ovA4d6e{DN~(|=6B_cu!L{`hm~zHb~Kc}2)R?#V{OthwAV zW*1&MriMnF-(bH(<8YJ=;>VWXLblhO*lmo3zt^02mQOBt8>f*eG3vNYMh*TduH=h% z_ygD%5@(_RtYTj(eKq_6J+pcw5WD?!p{cNA4$;Tjp9|>G4T`kjnkUYWDwLcL%YyU2 z&XT!)4^Zb_Ak-Aiquq&z;dD?lWPaD9T9ql4*P?p4W7}tFoG-&dDz*8|`L6s|{Ws9+ zX5{YlLR`Ap7^5TwIM-|xSJMi^foDv>e}9D7p?nJle4oneKBcqUo;M|#Ew@1}CXZCb z??!b$S^DPcOHgo|%+tXE68b*^%k{^F8mSok_F({}qpBdrVlEC?egqF#21E1IBpe(u z0t~tqz%GR{wlwpPz>znKZ{rBO`rs)_GDh;ItKR%qW=6SFp+417?<6ap%wUK7h6~=$ z2-fbJPWqjSL4!$kOm=ZA8x>ZFQ&wicgZ`Zmv+XNx*T{yUp8B{*b|1Ugc^$oOMd9YX zmDsp)EgfBH1+IfHV&;D;gn!kCUplLK!Bks3`Gh0fk>>Bi2k@5hDm=JJlO-vc@*!F! zI4bXHdE2on6z{fyq(e7hNX|rlt5cO8?2E>|p3YzRh3_`Onlt+$uFMe1_D-aq>*HucU@{s;{y;;sXr8|_ zgwLK|ifuz0@uFJ|A7G+T84=!y+$EH`Rf`#BHKUQ|J6K@bEZ*kuQL^pc2i6&K7={F= z;DMA%)}UGoLql${CFYs5%Q=f)8ZsKEnt!J8RW{Z>4)b_oPZ6eHlSh{&tMN_vXr6Ll z50f4_1{$NsQnjqBkhyI*-FmA5l5iY*vTrdiI~D^Ms@G%H_k*}zA0q7w$H=Vpmheevg;L{+=PNsdJ={JcN1rl9%Mx7>37p z_Myo78@uvX*e}?r;GS_El7%-yai-Nh@o6nno^Nl3dq1~<_f!{tzdnl>+?tJ|i4Dwp z+Y;z*i$TS&OY!!J**sg&MELfGLx^M>KNp^f>ZK>~l(i0XK6plKe02aW)yo!%UTO=y zVne_su?(+X8bBJ}-vK2dZ&i{e#Z!%S!Oz*4&3K-H<~2QdF0GU8do`Nh2(sjh)Hi_E zE>qatnT-bBE6A#&-*8TIDv|zdjb*J~>$*HVOy2jj&T zEI0G(Cv3Q6s+YviK=}LJorAM4nQ#}c9pd(Op|@Oc3)D_kmn2j~V3W27b)oABNaM{26I(QFR(Ox#-iL4r_M7EDxh*4W~AT>&TLFVtk4uI4yF*VL)g#PVj>xjvot@acEgK(x zmB(wB`_W?GZMb#eWELyrI;{PN(PEW{a5TuD)l62xwKHo)E%#NpivK1tdThXjCuPO` zmtP|a4YyglLMfj7!~_LXdquU1E`;6`yt{S96}H|9q)7h^8r`?z&5^xirE3M+S1soq zcAa4O!Id9>;egJfiE!CF2y&yo;QsPFXpXuC+0&;&RYVc_Gnu>434>Gf_xJ-2d@k{U#YL)K<; z7d(k?{ne?@<&#h}U5DzK4WpZOmqPfle)w!+0PQ;Z97gEn!ex0cAs43&e!t$~$}v%- z;ai4~NxcgC7u)bx%^70)eG>1f4ZBF4b;?mgc?bDq?0is(_|k@B_^6=@Kh9ppSD#DcGy6`#s~_X| zjnw|QPOS?=CVUsoxT(Yo*NND5^?O80X(L2h3LY%;Q@Hd$8DvgEM^mjKHM#Cb!+w8- znxXP|^7C~XBJA1Z2NdG6gN2a#CK65#I)>I`+{tSXWw5e*$-E+SaLF-6e0yKWOHR+L zNL4kaymJ;Ev11plI_)hndmlt^?m9xZh7A-rttY51+zF&^7lUc%0v@`xAFE1lh0jOk zR4NBnp;CAP4xhUn6?T*mSK;{*_D1ua-qL((b`Kh`I-LGGir&1SMh7MxgP@C6^nvh< zHNllE*?vLAyPLwCM(PN?^zQ@M?=B}*UlES3j)mJd50hZ+e5l%z0ixu?;1`@tU(g1~ zKXI*Gd6zdl2)YWjnpIdR+_zgr1L%t@-aPK~LCjtA0bcidgF#U$WUh!L3*MDNo$NIB zM?IKECA68FD!5*zr{A2bAmA+?z?O9b)@b)R* zh^ocG<XSV)|t#?zNZUUb%wN=Ui261u#1 zgUw%oF*un73ubCEzX{>+dR_$WH&2Z=XN`m0Z>QktYjccLqjXUm(5Eh{-14s~d#3vp zAHOZb;G#iTyVZh!|C@p2lrO0Yt&~jOQB9OZOX1b{gDBlSkP8?kzDPp$Xn#A7yLARW z-xBiktNSo?#}v4&I1p~T&4KZPD}0^GR}A!eh#L!1aoOSt*gvKa)1uz7_?7$N$IhLw zOxQuUFHeNcX({Zg2jLxOG^t*28;nCEsJMBVI1j7@Zo-7(hv@uoCbraR@FBx`G4N{%vDss0{ldEym7e+Xo+vfyu|k{Q6Ayum#T#k( z6ARM4IfLz6D{D=cmqV?YHhukO8ODD$$5*y`yh-pIS8TOMwSQXNSB{|daeLl+DFSon z_G0zM+qmqT1`o=6C-fH`#i|}#aM&No15TS`v@@`~IT%@>BTG@(Yv9 zO3@|M1D?E?Eg7>#n)9DJ^( z%4A@sG(X!If+p`v*|Eo^xYgSar)o0%W#P$nZ@n>6G) zlH+$2@oAv~I@eSI8LKJ&?2-c}yU(Ch(`?)kp93oE|6%hCIbxDW;GAkE?j2x7ij6AJ zqE!>`F8nPSfhTcY%wd#zQOKCXEOx!y1wRE|z+JLJEViUyGlRc&-o4H$lBkSS{}moj-AMz8ua)Vi)A_?od4Tiew;Xt2|^|v}Mv7D3#Qa24S zuC@z&Hs6OK(m7brEKQdrW`RO*9C1QlTw;`g_J>ys9&uyQm+*d)xP?WaG1C)=Ubb#Y_(lBwY+ zD!W2X7*6D2yW4U7x8b~fmNb7%NAkoi>+$OHUjn!J8K$MSFuBqS98M*W?D+uNq}E{B5;uva<5w1P>Idj;&Lwd!m)Y}TIj$gW#h0XM^U&EI7&g>| z|B)RlnZ281hQP=0u+L;+cN_P!$lb`Gxn(9!tkdvW{svV=6oc7UJHE2w1;ru>tKQ1D?-nyf)`+O z4XgUYu*T;*T-vz_nte_1#?#1(&V(9f+P@nYtZT;bI)Xdi4WQGN1wY-u!8EWr7YY@& zfN9}6h&l2B&z7DevptuSk+oOgrIJ2Pt4x!;n*5LWozEdM{YS#FyEasPe+CvU(!&4F z)G{lnOWVIl983@6iwG&$xpp6LnHfa>KrA%59w7N& z3*q7~KQbXukB*HT$dW%H72A=il$Ki3urd47T(&$VK?#}{C_Qj27OFClvetp@3_ zlkjQN4M_f|3R%8FpO;-KoR~3^PI$FWtm!{ce0;|wyjpt-*GBKgNv~Gm!hOxmy}}M# z1ET45?PKi9dS4Jb?_+T;2l2t5+h7;eU&!IC6Au)J(d1wizA4sF`t8m-0bjf-(%tO9>lTqF6ZlMN?!9f9~<8In7#8|zPgf-fUvuxgqI-{>%s`{XF| zTw7_VQ~L;03L~)M*gddR_2&~eM)Uc)JHhHgJoM@PM?d$CpqIafLP1q4S#G4tUEY{N z-+O(rw)r7C=Eqic*U*=p^6?Z8S9~w2a7`nZcfG{Rmnum>MSm)#dIrK}Cll>aS4gI> zk>sv$7dO6>hJI?TusYNel*he??_q_Y_@t7IcI;1@g}g0jUIeev3nVwcEC81H6U-i^ z<2gAg8Wb!Gt#|8j)}({P$kez)TH7Exdqj}fSm=jOePjVkzYDqU`voxMTq3oXdk9Jp?ZT6pJ}-t;@N)GXsr?4lG<2KrjiANE113gH?g*~1pUtS=Q%?O@d?+)$9+u_ z{Zc!!J4@ixP9(tn>)F_z^#dP`=kTh@6x2>Hf)U?#;j9Z~Q1U&1eKnkn%VsBF%(DdC zA+sJ9$yDQ#iYQ#Vvp@VU*vtZqF5=m58r1*#5ls6VhIQxtB#BbTVc)Z6_Ul1CHdUsO zTZ*Y9cV)fA@ZfjY^Y8&2nA#t{R=Tp^!hLkg3t<*D-wIZqO&6KI@*`hrCqwG}FrsRt z%Wuh?#f4fFJ{3=*^@qQ*Auolqqkk9Z9=HR2MU1)o>Y>kw3SOvml=l|TMD!4x1@6l1 zc=#af_3Fo6BL>2$%8r%my`+Y)F^m_}DAM1bptK~%P~mt;;JL|x(|P(6MGI6ZxZpC0u`%ePHX;%^Aq zoljWXzHDB5tbp67hQZApZrC(y9Y!p@2b&%);cY@!;!Ww-;_=Ut@xIp{Y*XKW(@a)wUlf}p?E2nIJHyAfgiLiF$zOa|=hZ_F z@a>nMSA5KUjDa(ngwDl07-jaJNjCfvd*>d5uy_q>PfBrk?K*m=AHl<01xIw)MUs*6 zo18XM;m0!{f|k^MaCaSnA~h{YSyKZ0btj_1D0R|Zx=nbkCa_yVKUT!HGXh^ciZ9-B z5B*SzoZoB$(?a85TR(((9|H+4pA4P1CQ>bS34Q)M4sxasU{lv%TyZr7w5(pj%4ES) zFlRnKn9zs`h0;9g&^&55c_Mw7(~1M)Rj5`9C%viR_@y+KipLM2_Y&(sSG$U32|eTS zVkH_j@wpR!?H&wX@odxw5UeXt-R9?#4AV(2P4X49a`A|utgr(_0bmI}F*{hwiCnju1m zC4ZY)j}>;|tZvCM3|N)`*S?9sdmCRiB&n-GI{*XomtVbd@%V=d~vXeX^g&(&(5 z<1ld5JLW4bf&!s0Zt$`((EK<84=hRK1-AuXbCxdFi#PDzx^&>L5};Dnzv4DP$e6mpN^^=JF}4fS}|y*pTvpY~}=|NQ$Y zZ;j1tm@A6Qg!8=9oy+hou!BunYL6YGABwKlSHsoyThZS-fqOqO#Q`5~V{>jRik-%> zX0_|Y+q(tVoGSo-wH#C&FL>^wE#N=je|Y=144!MdTVc|(o7C18umU$PNvnJ%`*hh< zxQ~A(2f|-S)_%`pj>A3J=;sx1X)wW}@phO$@ie{+x&cNTb4j7L;0?Mb!W@$>%)Ymn ztv31rYqAx^wbO3nKk-YvHti_$%ksnnYsT^;<9DOX_+yYA)D5=+#?kMZMXYR}K3Lb+ zz`5h;`14VW#ICSEkDX&hVw*Q(n`k9_xqk>9j3VraIm@af{-mnV1mzB&#xspaV53So zdd8SS%R|CF=O*!IAz{3Wno%pwTH057l1AHYgl#DzE;>1cE&n|gvT_VC_VGo0sCW#o zwA^4P@2$mKDOK3iK8W0b?O6U}7O`N}Fnn|sjCy?#JC%+hOg_ny^WNgGwg=*bb_t2- zFM~?cN^#vS;ddS?0~G>~pLb(D-6+~Z)|VvX6{B@5d44Z5lo#>D6i;3dp@B`Vh2m1{ zRWN2u0Zz3Zz*R1OWOqgvfLpg3HBqm|wH7}3dcZ35HJr=dv1?G&*-U~qE7PM3jLFeu z3-H5vSw7|PUCcTEgI%NxX~*qJmA^}9x1{Mw2(7N0me07ozA3iae z9|GXHlb!jzrNy{+f)#2G+|3G#-iU{l+$M%rCQxP;1;4Wf(}%7_;2mT_7hA7@tirtanXtE%oD&R2r1E`S{4u*qO`L_K9;`zU~;eVCcu(>c? z==vIpVIw4DVprXiSLH&lrOI9Lc41N1w_Z47+p#*RR&)33}HtVZ>cDS-l8#cUeF{UlgcM%p*$TD9ABS zB^tpN*e~P}cnZ0X($goI!{)QoA<(+QQD)gBRK)i_A1js6kQNPT zNt?D`OOaWKhApL%O3BFgK1YL;mduux5*pG{RO)~KAA9A2?)5q6{k|@0{3%;;ZcR0R zA!0vFJ2M*h>wd${0+*u0Q1GMoZsacey1=G8tI6biKJ4VvgdFu1R{uH});r#W(Zkf3 zZdm}?=N=^SXAO2FwVID{^TS!fUVosH5#FU3veR*<{kQ)UrS=^|(AwP>L23mvs zKQGAIl*A09Wm#dn75BoER2u4xxrx(+=kOctXSD89Axu9i2h($J@!J~zLBmrc_9J5ym*UT{v?0d8 zj-TLv%C%$f@+DkP(g+&<#19|7u)$A3kr2OeJobkSWfkA5`B~Eyu&dmLqHAuTtB)gz z4%WlA?agp)*&%+)i&~aB^Ad9i@a2|7RRb5}z+E!BE4uvm2>eRV6@SrNhXEPMxa>?k z3U56y_BQ19Su5awa}!~!aDUreTmuWgZ^cKtDinABEp%}r))cD2r?NS8@Y-}t?DwFl z!+zuAY1W`#K7~}1viTFM;#vQ#*`l!l@6qPW85Z}|fqkx%U}N^$(&eCF4Efds*K>q( zbmvPbyt5kr;~qov8*{|$k2RvC+C3CE_#VtxuYw)Fq}U%H9rmr~0IPd@fhm`}P`p<#^}h(F z0mARqHyFY8PPoi+s@&Q8U%@Q*(GpsG(2k}r3ZwuBS<*C=!Pg&t^GDOp_if>4pq;>N{4gY zEQ<>47+8T~ozEQfJ>{&{?Ze>dzs2|ZzGHQsBdv*6CgtZn{G749XnD$(%=~82IHx%J zWYx>1xa{TS=6?d;m#%DDaXJK9Pvvs&-iD0aY+kbC5MBJ2$A#6^V@Pius{b$pwSC%H z%ao~k@F2>H_>UB<7LnoKWcai6ppbc+&XjgN{)~IRnT}j3=4~BH{Q{}3#X<&o6dxJDv`c47owyVSYtxjx-(@B)M z_yx_+MRUF<-a&%$Ip|G(zyVQJiC}wNW3B%+K`1F;UY_f42dl!-lmODZ~^UE40`fR{t6PK{B7v0&{z@Nf5(Q!z# zmSr8I0`dG6Yg(1yM(^i(;1Z3Yr2p6wE^U@~ni|u>Wb)LVel!D}jyXVS;q&Qf5+bj1 zi)Kqj&~w2-u`(c;Vh^QJj?P1Lx*kK<0%qXo{3+C(A58J<)`PRe6ksR(ncZ_Erw_;4 z(Bjx{yk@(T9Qsx1RHGEFdA^TImi|I#kpi0||6J$=$C1YM1U_8x3q1Vc$P(-NxrQbu z_HBzUw_~U+O*@cJYTMlT|E?CHYrT;Fx^Ws0&Ai9=ZTk+=A)_cu!kGVRlFRtrdwJ(^ zTT#R5I~KgW>lpL1K;Qw&(#(i_I=W4d&?K71`~T$DJSh}1^;{!5tt)SFVz*+aih^-62hp=ilLXfpONqGL!t%))Vthm(`QX483Y>AZn7Vr~p|r}|Rpn$7%_sxJP0bP*gk^JU{M z=s~}=2{6*9K|;>LJgGzn>eyNt3*Giwc*LD2k}7o3OJP$2d_U^ zP^CpK%2%rJjy?yezH&STU3y4fZL#c0;1zCR;|lKOc~w?%b}G%^*N)>}Ou_}Ho^#sk zcEHGW8<>}}KFgV$!4BkYfR37jIDJJaE?+T`mQ?GbZ2JWCEVrZK>5-zbNw+xdPGzQ@ zbyn1JJ(${luVO2gJ;ihXT1fQc8S2h{j60)`V35~2>M>QUFnr%e69=WxfQ&&ER#vhV z0fO6Aovi6+L<3gTS<`KSvo&adJ-`rocv7FwE$prVrEMQLysFOJr(MIy8R_Dd!QZi6 z(uBqja)MOd-4tqXPaYwLY%;IMu zQ!05BLc=Eaa^_Qhz>)ncal;2^JgMxCr}IWLm9EY7Ahjdp@{ywZXnAOZX_CwPJ_GFSx;m2JBFe z71iksk#~KrR zTfTFc#4%vkqgwIP@13wY*S9?BkAsj6$mh=7Gln(r62|U72J@A&AvD7iehN;Twf-0Q zkwdS8Q^_;d+aJ#o1jdmlGK@W3s|S52=RicnTFR*zK_K~rBlQ?q{>lNq=A^Nz!UR0H zZ#kyie9xzxOr$QiyR_*>BIRBDz(vU3LMiQU_}h3N%XPiZA{L!sHGS6X#(-vc_0#@!3>FlGrhjn$wyO(7E<^a-RxWm)PSId-B| zjkzY-uzvMxFh;r!H1@`V?$IGw@FE8#g&szJ<2G9KbQfndr%_TVcp1KL5j-q!rn!_GxUdIGruWg(&}7jxEyu1%pFs z`TiLaV3#z8Uv2&kef?&@iK}m5eTX{vXxoARITsk-uncBtl;Oq{d6I7#z%JkFN2~MC z`NyUmoWZeJbotoMKgrt1jHM1SeGhr30aiT!EXEzhIbFQQT07XbMh{;YJMnu&32g9^ zBWzRjR~EXao2$~7qM0L1(YU%0X6KKGL+;D4uhWQqP5MvN&FOPS8RN*mWaM#_ZsD8@Ph5P`AyM1&*A> zOhX$*+bbg2nXzeXNQ5@6UOEVwuM)bpt|o=2J%R&6f_cu~4GDh~MLqw9^T|S1##rdA z&yaS4SuvI1?Z1!Ng*UT1yTXJw#w2pnawTJUcVaFf~8paQ%8Eaxmw&Em3 zk9|k45*zW-*TGbc5;UqR1J}w3tSZAQh|*J`0@GOnV`d};-V24KToGjKY3H7l76Z54 zi_32v$kNNUQ_{dq)S-MDRi;MrZw3q88X0-^+;cmNkvYjSrU=)dp*6{a4mw{Kyc2=b zAhGtZsB)Vh4Jq9R52Z)4^@(;&eUl-?-Rl#LmUn}pm(}^YM_0LKA^Q>-mPMyS50X<* zJC!aUi0}6-!C_yo!3EEH&P8_)uAgudHk^uK=|A1sdAq|P60!+a&E{;l{eNu#rz(N7 zrGf)KSpl;*rounk6tGy49KP(M|6X6i7@L^{U`<)$N@1kHH;Mf`jGnwO!>W-d@TtTk z%F&f2COlN7dZNp+%I<>Bnb&;sN5;wy*fOJ;xAEh=Mt;m>C)}K}m{*;Ah=L~u(4o(R z=u<`+AFK|n{mgM@-Q|v-U+?8T3(ENsvnz1RX`s(HC9%EmApMaQ&c1I3(&^`=q<_qk zu1z%|r#V)%c9$h!n+z3+f%V#2vK2Q?Q2Xl!@(&Iq<#T@YK~oZoC)r)wjVdb_%P{ zaKM?vJGo=-QEar<53X_T_425OVJvc>4R?CI@NfSOBvXAkQdU*MV(Ie`-#dwdvLoqx zVmi*y-9g6L3AFWyG;Qe>zJ=8UhQ2^iF-n1J=sdN3quJ#`##WiS3cgKzy2 zT!c+E_rpzspKn+tUT80P?;A=m)Eoup`cuBDy$lN#TX9{a1bR6A5jT!Z#;JZ)ysXkO zKC>jBk4;V!eNZ)pkNuV4ninN_WtPx5#UQ$~q=P#yFl(fQ?9QnC0c`D}ccAxgF6(N} zWgZ>tS>!M&=25no^?sbs%7b6Rx{)IAe!Yl3{aQf{qc$;oF%svS5EtHa9s56+(aJVM zni?U;mN{#)CmZ)WX5T%^w%`(0@?|Ys9TN^_3E`}NWF-4|p`={&<0(8})h;R?63DLU zo1lX3%tTVcG}&ZRk5Z_gzo828S}`TZa6h)n9P? zStGP)?7@{)BXG);>C`dlF?zr)Arq3!tlC$wc-+s_D-{Ip(^S@1^N{`6m4v>vdoe}L z6IL1Y<9V$q)Kp_aWyX`ha_e<07%M?duC}zhz=2MGccUv_k6~dGXLzGpt4hf z!VeVSo}U7H-fTa`$!L*u4vQ`e*hs`=b<>*4-!r!;ya_!yhd^+M14tSUMJ0&+cO3_hTcrZaR5x+XUCVW z)n|HD?l{;jhIZ*qgm|!EdT)AgPU2n|K4vm|tGEHa3$D5?GYY}Saz3YV^Cw;t{{P$0 z&%*I{UgNQ~V<`Em8>NnGz)5+p1ipqC6K2IZ-Znl0@^X1t@b3a-?w`r2wu~f=Z>BIX zp^lsXypr>H@KdCHa53|edBEoGwt|9BC*kkzR5n0T$XbX`L!tU6CjOX#MO9uRr>nzp zYyLQBdNT;#i8CFabCEbg)gFaqHL91j;Fcv)DBYigd0S?1J0_)zwo3GiM@*^*V|jOQ zG#m=M2K?df{}J|*vSWA;wQN2_EsoQh5rlR2=g@z956*mKN-OHk&}zt4O!U4iuz3p5 z{M85=+V=`yrVIQnZ$tPobRkR>NAhP6P9@d9+o;+19DKU1$R2Fn&2|17fg9H${&L?+ z+d8$GL6{2LS7*&!t`x(=no>AFT%SdyeSp%knQUwLR+gS@LDrs{G`!D-YS;ZiJ;hS& zy>){>^FkNb&Pc~AH=gsx17^d_GnSB4=EWPxX_C3(2fVL7jjoQ-B59EaM!&A%4JFLD zylK{aU#A~jxZc854co*|ToD8s4hk%0&1nF^Y1Hzg0vD{Zr!Msp?5++$dFLS7voelS zeGX#kw0Pcosu8`7Oa>3TbZ+BeF&5Q6;B`9>!X?)tE_TLw?%=v${*bkg=%u4A)f}2YPsXmG*m)1Z(OVP6HIrde_+u!E z{f>(aEND{Fd$G#q6;!-DjepcQiL06M9sa6~XWMnALAZ|^^9otPp0A#c{iR27fx8a- zrK`H&dzN@fy1JW;*T6oJWCuMc7;*hyP6! z!;qQM43dsRy>NDP%MM_7@1EkSKD`H0KfpXg6!|G`SNQs-7x0C94YJD5#Dh#2v`>zL z^q|2o;$OV@{ftGp()kTuc&0>dfwf>h@fKJbD6%WN*Ru2Oaco2IHWpwsAGpq&xJCX; znRZ(v?g`4pt79_p{@tS(FH$0nbZ68I)ZxbVJcXT7OPPyGyJ%9uRZ*I?8f(95gG-cR zFs~xS(zWs)io64|ymau~|dWFNs_|WrRQ8-)3DsT8INqVOB zaQ&|lxSw2uVehZEG%j2*@f%TDI(Rw%Od&Yt{$X_e?NFoHL}mf+V_{KBT`yvRJw1gHIo#`W8`naFzNj_^~Q;HI`uKAE+`@*Rzmdp~*cu{14jw@0J;J*MDUZY?J7a}#0 zo2MKKJ2D?|{yEmL`nxW>Qhg1)K8hfJ)9udxE9D2d&j8b8@QV-ypCn>0r`&?w-$wA{pJ*Ly0 z2K^5P^L*tdCV4u7RamWuqc4=1?^kE|e>U;zljEWoRbPH*Kr8eV7_b9H-7wR6K345W zgyiH5OuLZ@CygTDPUt2+-o*$;w9mu?i-xi-r86K`HWDJA3})e#Dj>>^#R;4ov5F4 zpXE5{v$_S>xK|A-Ox!Q9hGzHjFUMK3x+@!@ko|V?k*RTvxtb zR&g|n32yB2(_`0A1J69NS_jkMpkvJIr;s@gLxM0|}xlr&G zTyh9qT9)hBfQk|9uERYD%t>V%{;9H<03MgWpTzz2Q)3EE zRbZyz&Cc&?07LsSyzp%yK9$y>`d~X|`5~Pp2~CrA7y99V-4D2Z>@rgtko&QsF5i%!-Lf1SSmV5Xx+tjOpKJ~;~F3)9(I(D?F`~c0fF{8gm>X7ui z92akU%zrJI!;UVjhXExYAyD2Am%9AHmW4}DHu@YswNXZs)$UMtRRX*$oSE*ITd@1e zA$+p%6n9#AuaJrJ#PXH{B2)8D;UGI2m;LvWUw)#Ln;PZAM^9sHZ0-cM+vXl5t4@JU z>*he)0tMLpR*i~P70Eei8uaZS&87>p^Y>Gtpr}%r-5n##Brlp{V8l#N*eb!k>D|OP zL%rx_=}F{I7USY)^|;{PVYJ&g3*VN@!>s-1;BT5WZ}KUMe-|e(5q~J5ymvC}m^=-? ztn$T4nM2rjt&y;AkB~Ljl%={v8JxeSn2&9fW4!&yIu=f*($hGP?Tq2WsjDoItOTWf^b;KBiPaA5)J|L4fdM}GjoGyId?4P0jC zN7y(jP&_f=GxuoMc}9jinc16q7!^Gb2G8u`7Qdeaf8Sn&>GuD@;<^*?tl>30add|Z zHj8op)q%9UuN*UVmHEsKJ5j>>6#n{p6AipX?A%M?9QxXgU6~(3JJN-n$;@QI39}52 zJheiVdp~%UVpVpj)SR7AEP|)KFL5c0=3|AKrNo}=<%?W8aAs^NgdNkw9*0PL?7R-@ zMe||9vU>5v0q*qfZ!4ECWKF;AD}>E<$Ix@wQW&WJ4ALIi5EJrD>fiQ4)|n*C-@6-2 zj-{iZ5XJHzo6+o49q0Ne7&o6&5%|~^q-5y=2{uaPIYW`ks>XoYm0Vmn*p%uwInY|? z-9k6TkHP~bD8Qf3J?ZA`YzCqBm5*-++rj+72XY_!Z(g2&XA%T|5|YT%?0A6FQc*h zGID$7srZ6WFbOwCT)vC?E3g@|_L;Fs-j2)3QTx^2`j!0LMmg z+lXR>oJOv$#0f(~6v(?)1FlHYQ8xNQAS69cfo^^f!=EMG9d|Rnd}j~nt{g(T zPE+Vc&@+s3(W2f(D%7j-0_`##_=$#j<^E1*x$~1O>FBA~*m~?GH}uUC+{d}`UpxHZ z#-2U6z`+CLKXig&TMu8^@|UY!s=zLMS&rPr^ZeLDqnU*qkFLWD#Zubw@U?m@-}v|v zFR|tw+J`uz=G-Q1u96gdFVUE;b`Mw7wqkzHaJEzUHeWK(j(IoTLi5&36D|-T4+&3CB>{Xdt&^$J&Hw2!ACGp7_GAumg8*l7048(&^!YNf9NMS8# zmd+s6!av?TUfdvkY=9V5T#Lb5K^s_(@7AEe3>2D%oyIKS~-IC|# z{#=T;u8X<5sbwOo2Rv7Gb{QVHqek3iZ5kLr{MoFPICX>?jr6WV7p=dTv1TYWk2=nK zoLq_XKbe#7r80h@-3v6_yMaE)9zq}1$>ol@!fGDdv$-+?v!kb)P34uLPCkwgpgoM2 zJWH)!5is6aV4yp0rV~jgF!Nge<+D*s>0d++Uf5rO&9Bb!r%ePuMdSu%Ra1hF!cH$s zZ#dUAwhOMGvt#_xB4OWQ%lu?xvC`Rr()5zqZQX2m{k;j&w|{~CF9r$swJ9T?Iq+U4 zgzZufVYX)v(X{19;N{FW{D`7F_I1=mUfOXmQA@>&>q2Y-ZbV=<1!zM#24EII%;z#gTrX5p@gjv1LGk8b2P!kh?3wAst zJ&UEBxzs#iJg)+SYX9T?j_3>5*#sIixC|bgDdx766ryZJJ@&=hVE71Q=A$%@_5N4G z``r}_9Q32`d1o^W>oj59xku>Um5#37o-9asFLurU0gL;5=-Pb=IvjZk=gPS;Be5{A zPgWrLbyjS;tPVIO-bB~ct?(mH1)DEIalyZZPVK((%mT zCfve^SG#ONyp|Y5T4_vn!Z`eQ={$Eqc{r;Ra%%>+QlW2E3O2v-At{X{@V9rt1ttRt zJ<`N2hX3)Ol)j-xL?3EC6~3DdrD1DVA#R`d1ZC{Ah3?NutXO^-_jX8<>GEqB75E)X ze0#9$mN4@OilNs>IGQ};H2?SB9V|OM1vQTJ@hx+{GAV5nyx6yc@^_V>WwHtz(7Z-; zxu}Z|^;to)pRHj^hkV(ngF@bCM=NgqXbtgEXW@&*0bJ~%L@PV@bCCx_@G7$$Z|alHaDZ-s(~V@~Sn~)uP@LiwXFNk8Jx}#aGcQkimqtJt%qd`tSuKc!fvG{uL zNLJe~$4<{%i(574vhM#@mG6I-1!ui~F}=S>@#ly?kR8vn1>484t$U|2gYnjwyx|E% zy2x=+`8w?Awq&>#dlyD&Pv)~6uW-!)v)GpTTY1~6B`Dt^Xo?oK!Tz)EOy|{cIB@SE zS|)0Nc~cP_E&7JbyaT9AHGv)K{sXrL2gBZRxtJMjK>cnjN!q%A4IdWC{G<2K>-ncC zUo(}~9X~?XCN9Psor)Ec-`Q69`n7@GNFLiv{*she8a93~U}f_*^T~n}BXmy=^r-Hj zaLwOX&@l!!heUzo#W}+M&xqAMVQlEE6wD8J1CE<|AcV`JYpq8?@og=3H6BHiwdGiq zuLnz8hOovEeabQ~!NUqSuv~8nZ4i3DiD|xMb?&S9^;H`hJXiyL_lKw?I z4&@%Vbc56Y(+Zd1BC@=5hF)Fjp$iGaDpCXw$F2v7l%M{MQdZW|u-EHYDcK0&)A#&L zk0aQ4VGGk97{{uXXRxqusjS*IiluoPLgS1NV5k!bQ`+IuznKG{=CS zV`+PP2!TAp_uGgs4!Vww=d*9$0%@vd2lq%yLTc=D;LL+LRdI+TXGq?BKOn%{BYJAt<8U~$fjY+Nhs;j z3JzZSY}pcfcDde`jPmcJc<&TG`12#N+nL3*_=5~y_07g|;n`}i{w;Q95}wkI5mn!K z&rN_weD6eOG#bzdb9}$?Cff6Hv)^jgUAlv@R$)e6+AZ2uHXl0tN?`B5&mwvL5o%8_ zgXUf<_A2ZPTi?2#rH+@O+n>r=%A;loUbUZPr%hss3tG9rjnhCyq=@kv!JLrtX4&c6 zM77D6!Pz?;QuB90@>6wo<7C|-G< zfO;!l!KnE@u&UjOX*^4ZMWzwr9dkayfYN&cUv7dp_}_8(_q>JAAN2_WR9|CwUl14O zQwXCM?`C<~u}sy*1EX|-)i@+meMAh2=M2CzZY13*7JMMiYN-!JDOel-KCRy?iUhzGS?BiI$_;${&qnXt$Ko8}5*SvILu6 zGa9spM?v616(0Jnz@zkteIB}a9v#&k^et*2#FoCa|;i}69 zHH%@Mq&(~RV9QnxHy~yIQ#kbuL)8n>pmkoJRlN`5`RAJ$|0@8GHdta8Z$VFVlDVBH z209*^{SN*Kj=;>{8o0|!5xZ^O*zbsQ+~T%%5ci=B7n$5g?>RBtcDcQzvD=7-NgLAM zgaPCD5eVinzeiQ+A$)=Wvha={|kQC z%wM2ed=rNzA4e&nL$mE;I5{R4;^zx{`O>HB_}2RxpUFHPWXNR&qg=F%~gVd zvxFSe)f+f6XcaVl@^_RQlE_qh^7u|+PP==~Vy@Xf01J*afp@|Xsxuh^dA%kOcP5lQ zP4!}hM{mPh|L-{d;8Pf(s>u8{C&QMomDvBE64k{hI2~AJ3waN=i^hwI^;~`lYrFO7 z@mO1|QB$D#RnY>6;0YFSN8r_w^?b*H36SKWfT{KIaNXVl?`It3Y>nO6Z2x;WDb5BW zXFlU~{Ec`PI1Jo>nTp29^`VPlqbU30S7`CPT)xo6fR+o{C2wKxHiAkdr5`NWXUR&os7IK8w$G>CzJhn+ zvp&wB^cfy^3!S)ov)Ns(4h%Ke$5tl2W>-T8QNKk1{+2z;Do#Xl4F}hQr1D=3iwa;P zKh0$6)kB&3*^zW;Rx`wAmy_zQbgKCB3M3aEq|pW!Y4(3wWHWIyv4j+sxFiCsLsZ!H z(q2#&?c*Qxz2fR>&cV#Cz5Lbdqn#pSwAsgGbFyq5>?GkYq-m!ru>2k~*!tuHZ2J|) zET*_(h>!=F?C_ggwR0)^9of#SM~ozWgSVWhMZ_2HBKYw{nJk)D@!`GWSaa}ieD5EM zqvaytS@dMq=yH}%(q|C!O`fYceg#IY$YY<~SHP%*NbHC^$rAG;NKq!6yJ&cdZyk^T zZ|9e?&|_(Az@lfkSytE!n9t?DpRDJfZaU9$FXh70l4@)&F{Yr5(=_3e2R0TNV{42H z-F_tSvwSbY>QRq*Sg+_LcT{k&%}B!VfofE=Y&JXNY5@12UI9y0YcSjLUT^?TXVOZO z$>PT?#J@G7BNl`oeO0)slBF<6*I8iAU*^a&v>G)P+EQTKP@0;snf7IkW$C>G zSccjJdUNA1^wq_KXY(;^HLr#vA3um@&T(c&2DSXaZ?({@V9Da=w!=o_7A|B&Bu1>C z3~NlfAxw26-Bh|j(z`N9R%MgOuoim zXqCg)Y<>1RC9FS6O_<{Ji~ia?r$bHZP7P_+6}r8>WbySItNwWkKVIT-g^L^u zkqIRArSqwNbrL^P>LE8JX&FR6u3(w93FLTYKX=aUBNsY0R5*(ZOwi)v{M<29xUzMJhjv}E&MDunFh$4(|IAwq$`}+ z8b*EL?FOhYgUjhmqiR3&E^CJwb~6}+3E8Iy-Q2KY$#m~|46V|3Vm8aR($u!ClrH}f zj*cuvDP^K-gFY}>)iHFoZ8t4-_h+-bu5nG#0+Z_3AwKtuz^HpD^o7+f;6cLytmcj` zd!N06v`@F9)QbR&8WzXhw?B-5qlxE zh$Jq&gvOgbOhzIT1}T-|sMWsg_@o+eUOf}y1kS(Yn;;fAy^pqZ*U*+{bE&F0f)tjI zuaFvQQIVCINC!=%E9R@)R(RXoM=jsKQ16z3^Q4sFhrSxDU6IOJ{{iNHAshxwiNv4W zbDDmmj55+~=s?yjT6smQqG8Qt`q^j3dF2-J=QIszkFbkb(b_^k{>ZZpA?Ml6uf1Gs zNB}z<;Dq+_HDK+28n+jw;F>39ga>TtKpwDymH@HT=)2r8)d2g*_jyxtEgW z-U0uVhfuq3Iyr5Z!NTlRSTc1yeu@pHI0qhQ%T=;50>>!GA_Dq8Jfx&=)-=;lnP1%; zB=o*{QnnaQ%Rc|+>V zO@(?V>E>90+aPebey({12}6g#mhVg0B!OG=(=?ohKe!Fi@pDMWdla2;P2>Dt3+~f~ zF?4xpEPpTK9XcPC#Ea5h8wxJKQE%>kOpGfS2&Y$BR1bk zzT!bbqVNrFjPvxyGshJdvAlLO6LPI+zV-vIaxtU6b3yc>b}V_mmBKfC5|juXj9j@m zs8*Vf2W~i^LD+Hhb5P|A<7TkcJJQ&dyf;9>z_iY)!pj9Qe0Iw(?&6hIWIw-N+|(F@ z8F3nvHZvJRBj177%s-%5cND63>4Ve9Bf{Bq8f{39B_o-B)M@geO%)Y1^kXJD9J66l ze#Su5i2F>@hT}%;nN6D}j;H&c!}*Za^T_O^8IGKm2qpKQL*{HV3_tXPi!Lx?yTk8t z@4cKzp{G#nH_Ct(T+D{m2Xx4E&;vT7Y>A>f{pkHcv*LSk8|vOzhHZl-X}!KGF0B2H z-W83!W#vQBl`u=ZyF?AG4SLI3`v)+|$PCyxXDHVcrpRntgszyzDYV_Xl`nRQLGN-u z(#SZ7U(QGJ7R3s*b7_l%N`fX_O!UVeU!-u(bQQWje*t}I`;OfY+R*F79@KlifnPph z7`+m>qu1+qk%!S~Qt`;3f$}Ld+sBDwbUEHd?g0G#Fp@T<3d}d1Z}9%#7QD7o;JWp1 zfeGPDdASardnNggJFRd@fb`rG5I8HLvnYj>e%-s5JTlrcB+z4;gt2)!cPR^fGU$Y*x^IRZs zz%P-M3Zth(v$+$BC-CT=1loI{67ugoU?(m*J2}_6zf0rB7Vp8AmfLZ%!(o9jt%Eu5qIt_{<5|Cc0597oxF;UTQM|k!DE&}@ zkEQY0H@BWU>vD>FGmXRjBg64ba~&_X)~9BxxBSxGn$S3g$Cbk~q0)jJ2U^d@4TJod zOmL3=PZ#|5|%-1nd*giO3bCU<3oA5T_2*zIdg42a8frsN@Ch=f6HHJLp zh7Lq>YEq@p|Aw<$6GSAAR1-bvmLut#BKq&=ec|Um@H%k`%v+XRR#RXq%xTJ5^sRD?9GExm!y=W65e2eL_o4`%9rR$5TnRU} ztQYfc+$6nWdE(ofRKV0Y5<=_}v3;v7+q(WCSC?+V?iI_j_!;Ijc~KX39BJX_!ga1O zK$wZdMnFAhz|1E!imNXk7iG;k!HOSGgQd$ve0P`?JQ>;ugXGJx$+Z*r%rocB-JhUq zuO4;(7Fg5*!~bvl9=N(wlkRv~lmC@NZ1nPC!!{uw#nANA9XtpDPJNfA%KlAP}?q|*=h&?<9 z0`_HqWYj&l8)wVq`X1*Wxvt?=&3bv>`7EkldV*dNGilAtGH%<7L@*j5!=~-Zhvbe6 z@a3x|?8;$9Jp-65PEa;w20WfhmUSCZz4G->xDd3xxk&eHsi!M}1Q{>=Qs z#~ACL6qa&9J*(3N(ZFflsCfyBy#SM^gM) z10G}UcTd2rrTvzhVtxQdhp6p!K979A@X zW+3eT6a=4DbsJPZ*aSxmrelun3A|TRK)D}xk`4D7H!T)Zmgh2v^pv4Fg`cn{MhPUA z#^QsU9dN0)6%!K@d2!S6aw*T}aC@EwOj=_KCtAOQYDowGD$5R5bZ2k_T(05E_2t+R zA;Dg1Xu&r%5zp71;*HM-fpNY+Y^fRGB#xPnR-2S5*#9PI)*ckN{P}1-$_*SWBk=NI zMSl0XD3%g?23!a0!MI)X$#qH@KP;#ML+5D;>eUvPIbth=wmK2AOj!wipd{lRm&cl$dav)7n;#{NOy zGYcucN*%&Pn^A4LCglvw=bL;-G}txMa61mdty=KgynqYwjE1qvQa7dW;#%k?)6%jmj+G z_jueEd5O~_3H{e3$NqlF!8mY$$J-sLYxKC%(nd68Hbp1&@W!1@2_2W1?{dWV| z-*%*qnewz?j5(NHegFQ&7|hmdw4>Q0Pxh&GBQrYk32#SThx^-WVUkKYXZN-kYZl+9nBGL1utAvd4+)_s zVdKdAnI}orhLZW^qZIeB1yA=Sfm+!@2-O?aIo8gg>1>`f*t5I9)J`lRV<`zdTp z$%Eq#tC(MPIy}#_oY-L0ye?kZOZ{3U7mWd9`^p_q+yWWInJ(KXmigtMY z{2Q0qosVO8-NiPoUeR}>N?1C!1r#d;e}Q5On$P^ey*al8uaDHC;y?|&G{cljF&_>$ zssv8Gfakw+ZUnr}9Y#6#3iwq4T2Kv|xIK0a_Pk2x_UBzkr3Eu_)4oHH6s$xuPI)rk zqFVge^ETEijYFs0F?72N4F5!@@kI>>D$1T4#1yu{8vG~tPTsuL|>4r&*sJHYvwO7sD+>GaVu)M40|RQyP;u&MIy1c!o4wVk?3On@ zuo}W1R$s?O#!77Df>~_5>}9NJYT*w#uV9^8%b3l#Rv38i0PdbOkB7fAIK#@hn03EH z#Du+QfNuen4|U?xgnrAOcl{Xq)r`CC`G?QGFjdIENP|b9;M2U6ht_vx=$Yb1O4;2D zI}Vu%Jk9$w{QX$ANLLmY{~d?LtD>Q<_98xoZzw4@6sFJ8Vt;B)nAev3@MM?~7h!x^ zbUCSkOKtiIFZzY7n^O}G{us`eKQpAp0lB!~&K@k?w_DiLo#M9&x&5~_1|0{r$PD6or6w6%w!(m{) zBt>)xE`d`&IQ#erXghowzML^-|F+4%nW4_8aw3g89-jj{hc9H7YecN-k3XoYdoxRo zI}jvfdGDRv4>7glKwrrpVQWPS#SyyS#?M!sMJgpyb6DqntL@js=7|FtzYCezH8;~sU3!#UAG}O z*nm4WU5-t?Zo+B?jKhd_S(q^_7-N*4b4N6?`H79${6X0}`1FZ2trYS(uU@KBVW|R) zsZGMLGgpMOuLS(rB}uVUC(*BWAH@rn_<@$VobTFIgoeYd@Pl?abS_)~MooW2cO@@! zVWXV*uXSnkJ^2FGAGv^~jV8G7iY@E-|2sk8O0=iR)9>Zp(A}JgMWs(bCd8UOHy+0N z&xNo{dWtN>^DXPODZ}0^>hwQ`&ch$eFAU>Z*)t=OQADzm^`3J?(Nsx^LOUrVmC9(@ zSs@vTA~ej5#Cz@|MZ*j!ZS_k-C6ac@@A(IOKJUl#Jm)^weO=${(sTuKU&b1R+(G!p zxp{0-)*cWkJwY{7R4ZlrI*=)fimS-SDTApkqw>Le+&-5#C+9eGlaN3r< zoOlvlfgk+gWIE4QA_zM@T{7^eD}A(yw$fMzxfZ? z1kGk&M9kQCnGE{de--swQ4J@*{Gkh1sbZyo`MA+*1I7~%l0|~)cvtXNl2H~*W}bWv z#@zqJwnmC$1FwjIf!6S$m+?)n_@2Dk4vi2tgBXd{=S_+ z0*tXiyAozRmp<-AWuGxPt8h%1x&T(Z(QNx;b9pT+1ZTGr6vM*OGg>W@g(>AQ*wNN9<}pM z=Z}j#H(kEc&PDKEbxEF z!w` zYtlHvdL~Z9Nj56DzDAfFIPwpRajd4_|1m84{2_Kz%fboe@t|vkSn8GrsJ?rjY5WE8v`F-f-^gXydMjCdz6{7I`Ap9*RjhU#~lZ3DX#Cu0B{`E{Bb`)uIyZ_}Z z$h5I8|B*fH5xxe7+&5#!ZV_a2aD?48vnFD{zTq|9N62}H30Nae7ZR6Eqh5BLpHAf> z{-^K2ZbU1>wriU}cegcpappX}g6~Us!kPfZ!yPqX#I?vg=1OUmzP+@ScUj6n}9`z9q`vPYIW`d3WVDBz*})O9J*#D znc)5%dBn)DF0l+ad^45uMpvP}--hJy<%giGqz_W_DgY0k0MVL9aP;;7((;#w`3cX_ zc|AQgD`Po+$n8c#{V;BQD~{uT9-;ZYan$8QCf?qxPyQ8Vab09)Y~xrm)Js<5md8n; zckdkEZ=XL=ocSAsJ5I9;T`NeLjt_H5kARq?W<=-ZHyHK{gYKFBxHO>)N6*)Qke%6N zQQ{2VM{idu-M1W)-aLn!PBQF2Pgge9zmezY>V##E-e3|D$-IU?!X!&K37=j-NN9~a zF&R6+%>F#Wlj}v{^n#zTXPrI&aGeT?)VYLJo|-~@n=jtzYKMDOGRg0dyXeK}5|({I zo_zG?I#&iWh=sONZS_bzzOp8U1^h{1p$qr2yDJ~Tm4t8XctHawT#_R_r{*wMi#YgU z@QVHx~f_rg@!x(Xx4UkYsFV=wU5NQ6Y? zd@`A+aUNMevRhy|Yrmh#gskMS+ogJ3{yC9!DOi)OMrZK)>_2qth%~O*sLXb5NyLi= zpP}E0?YL%TEvwws!KykF2^X$|n>nZOzwQ0-Dtj0mAHRSHJL1SGuG6DwTO|JIbQT`2 zY=Z&=dn{((hz1f<*__@B5E+zAdTok`k1W>%gG7miw*-64@s2*6c}91y5@d&3Cy=OM z6&nSf4;kzUAnT$5)pXy5y@|c}>FM3%;*|`t-sJ{SQ^{x6N9F2|>AqxBc3r>=A}-^K z1r=Dos2aC5l;9=2=MWV7ofuUpkoT{R*tB9>?)UiNkKcN6HY{T{KEiC_r@8QBxCdSP zCP$=PWANqqjRZZrffw4Fk(B1!SY`ejJP`GRiXFYj(%LUV@`WKza)|=6^#$w=oW^_= z)}Rdqm$AJR*P(c<06SegkNU?tkj{NuCb=aQ6t40xpWXqvfl>TAe;9TeF97AzgOGE$ z5cZoy;ZTnUAlizUyr3hS|7|DBE}zdPTS>C?*kb7XB+bUXDfP5u-0Y7I}5m!4K+kH{1f(^5r3QDYAznymcyz}pP*mkGNH-YgS-k|juYP< zfv=A@F$cAUTz*!Pbj@cRxA7GAo#%ps&X$v@p5kQ9>ImZhsDSGZh$MK6EtZs8$1hi` z0gc@)aA%D^ss8UX@3Zhje8u5E{!14gTBxBwUKva!&zqLRhi)~vn4`@Crz+L21tBo_ z1!S;+V={@ju*eC-y+M=4)L`xPc)S3@BIzc7lrXa za|JCwVGDm|I$~XgL|#jqC9@7nqbVG7Ts5Q>$4;!q?|+2x2I?a)@A7meAsm92=Kto+ zvO=7%FpgX_8^lOF4HsV);#>WWXnwPn*$LF+s@U8VllX39>cAB}=7uB@{KEmA{Yp_Uk zFiD+ZK?3=K!_%}bzOXx>A%YT5}%y+43c zM@#X2$(uO#>`^LB-$-C!~ zv{F2oy?r^^VChCy8#&>7(`Z=(2{Jjm=|nj0CaLWk<;6RgQthchShHRqzu?X? z>whX_ncoHGI$e*2oHZb8kA)LIHIBEOvj@A(%wmt@bkVP|>$S4GA7g{)x#U^DAdKBL zB##f}!HPXRrk|+CgfEsdgQRdaL(iSH)Bo7)s6wVS@(SWsB9?xsnDwqoB?6jjSVM6= zeKSdt%lDOF`c#zV8zqvTT#mH+sRbJx5GHrsbkTmN6WClB`Gi5N{$%^Zq1Jr`8bi_;wUA9lD2k zy?p#ZeIZ;*;<^N9%w{^SCM=f6bzc5?1gRjb6ox&M^tCm&$Pr(eU*i>E;C z`eQ6sJOk?|ezP8moy=Bp+}CvXkGT5pZip?rfb~W)aG%5%l==DrY%(;1T=90Ct}I4` zXW7`;Jyo_jmA@P1ah~=V`%GqNcn9P!$gz;(+sypea<(5=9ir~Hpp*B?TaF4$@)pmT3rn1U1(ssIi74R{tUxwq?p|PY&J_QlsWu* z13pR#Ol12tj^SC(IwLWtp0i*-ZyC}rmrvrDdky%R<_Y|r+b!xoeF5i?4t(N#ylqpy zut)Om*^W3)R}vb-E317u-4K!V4KXA(Zz~RVn2)Eth$fr4UCG}F5BPTN5k3$cL%Qxb zVr7AgNM%7LE}nZ7BAfNGPgy)}`I=9BN^-#Ylovh8kHTGvPD~KKpf}ZZSk^&?MTi-J zz>-_wsKwp0E^s|sQ?lW9SvYndTgM(<@+Wdv!bpg44s(8e50~cp+1zFu zj$a~yXV<+&o3Bk}0%w(xe0VE9J~NqAW(kp0JtOk{NE@m$@`f0Y#~Fg;RKQH488(ScIuZyD<|pxwHEXb6UpCnt9!nBp7`zO|~`dBrhG>d5QNlSg&U?_j339`5k3n5Bw68o|J z8{xk%Cg0X*u{)&-Y>mA&{_;YI9bfYoLQ~dZFX>-6QgJ=Z=~+%Dj(V^doD6c2KXKgm zQ#jsSl3e745h3p0eKov*`LA}vJER|R`uI$=W`hZoOnZ%g4edfwUWee<#)%~RkR#hF z{}&7YRVDZ3Mag1+QFgkv97oBW#k$p3SzbjUd*ZBGe>}>Et+6}cq zJIqiq!RzO!k$De};jc{zT&~3epEV07nJcWwp=n$O&iN7vJ4M=w}tMy*&>iz;|S`f!XrG!X?=OODBDQS|zG4lprYJvRT zeXz*QiY3gu%2W*F$+%B1`%mjOo4e191%}7t!;Pl0)nbGWpatIUswX9zD=34TjSCi}- zzD0scoUoO~R^q^E=`5rJa*l?B??zc>|8pk`=tyA&f?>@5LmrzotC|@Gw8L;^IXe`5 zsNPFmqyE(=Wl%q`gdA_-#YW!0 zWwyCohgIxZ79pMstIS8i<&6aC+^fzsWoyttQ#AbfyPip`T|kDVY#>`i2|bQGjc2d_ ziue7kz^bEru-@k{c$?QxXzR;_D<9Y4oUvtO&fWw(x_Ja5W)!hmdo$R~E&E~KK4bRg z$U@d>ag<)vh-5*-5m0Ut3Crt`lG%Ssu=rY0vZTBnf69_3N?+rM_Zmsu@OT+WwuNKK zu$$0w`#R2SlwixRZN&HEwdlUnmc;bLApAP{itg&sBMT?3#1oh)=)y9b9T;RWbvsJoEbZ8B^m4nIFi!$thi!b~3Ethsj+(8R>E@D;D{un+ZNSj-Q5Btdw zJ&of;e|#rdx#2dsxIP9K7VIb2-Irny+fMrHodVf)Z3PoGk>RC^&SuRw-r=tIwj^nN zGv2pejI^)j-q}!ZMmL=!#sQP?dRK~=l;ceJ-9%zgBL%FFV?Hd3Wf{C< z@OO133h>16-DC?>jvs&%b;-=9(E+P{&SOIY0`;DgebJf@J9cm2DGYx}Lr;E-z&%?N zrpx`!S%>Br*T7W5*RE%Kia$bA-#z$Yrc9r8{)KvzKJW^2SNK``a@~8#82Y@2@N|&N?VnvzsERSqFw;>9RCLN{ZI}>!k@OvMtk;37vNl?r zoJ=J)>eAF@A$4_au~a2uZtcs20=(c+9hF{hhSRDh6U`0_s-z$aZR=#82Ls!Gd*zp%(qu3zdnOBgoUBm)|*~FI+J}rBEr5#+p%ZQZbO^f`~E|dOg^E? z$tHBNo+nlsug5awHrREw0sqrbCzZea9z49gp(pSaU9LPrd*@6Br}?kx%70Nv@X#{g z%2a6Mv<1*Gb0s>XABZ=LKj!?=8>pe(W!^-W#}K~H@iwusV%-wR}qGXPmZCX%in*cVv)rwxfkF~xeB8Da;Xv2cH{k*mhkE}x9&!GM% z@@R^A90dKh9^2+-({Jgk;eymG{v;0>{Cw*v>^AinoS_a>(YTfBJWYnhzi!Z|^Sh`^ z>?nOJ_=*Fun2%gXX_pu+V zKr-(3k>z&@Nb`%cAEJ2OQ#46>fY#2hMQQ5a_&YuT-4mUJzhr2Ehs!}IM`y7~eL4+v zeavtAqYOnW@A2Ff6RgjV6!0&-_ykoMgH*jr6S@Td!P0lzV6Zuk_IEF)C1R_9h@({@b_{$sU2Nc6wg^qRi_+MrA7qEfi5+LYz^xvC4;=sUxIn>DR(wQL3v zMI|=$JdbAQe&xyA+~yf%&ZWi;uBhj_0#EK*IzL`J3jJ`1h1p3mV9--af2YY(XCWCZ zyGn@NQlR`1Yh`}?QEq?wa~ddJQHN253pm@%89m!HLf1I9p|baP5h~25Vl%HGKi?bZ zuk;UUd?FN<6yKmXkEHYeO^fFrTqFt;X6o~VD_0`xW8dh{`tv;T>jkL$7Y~Lchpfc=$%kURfSv*F1!M6FI>l0y|a$yMQn!rmVVIbybXUV8`d6>#2=4$ z!Llcu$9bweZYrF@Kh;o6A4L7GTWdR!mzdoE!V4;S>-=@$Q(rNd)!V_thdppUk4IMq z4bY8yXQ0#)M}BFuDwt3F!yiewK_7kQ3OtVNz||pD*1xWgq008P@ZRnu)pCwtNA7Rr z_CyJMMQ0`6&9(isJwgJKn-tJYZZH1u=W5V*kzw;-F$DXy;T-vRxS4DV?n_nSlVl$K z{I(Eoozs97g3bKuNLg6;{4eCK7>BxQS6Vo6C2ZX8j;1?arYc$~6c4UL%PVS7r>G+n z{x?kRxm>63VmG><%fPPm3V^D8leiJVoT*P*3@HCET9SfD+UBkF7n{nvm81<8_f*-* z$6TM0E1+HTgqYw=8OYd~#p`A1q%_2geq} zmTDEaTUJ5uWS7CQ)w=LxnI-*}``)@<@E09?EDP^9ZG%&}{nV=b2sm-f#r=30qwJ$sglTVx0-eY1TNcVL60aH9|pH8Zsf( z{J^{0(Syizy7jaUHP<|df*mHqYc|R+tt&%`Q*Y2Vc*UP(G6|A)Ie_25Tx2omjeTEn zd5^{O*sZ2w^yo%Ay)$e>_uQ3-Q?JAL4~YgvDu?mKS zF@!xoH{v;SML_bL2GUK_fiISs^tX37d`OW7jlJ6NHL#K%HeHR4!X-f0G!~hvhVX{I z)o^Ek5ga!t0l6Akx^L$m2-aT3=}R1M=eIj82xv#GPtI7kggYVYxPv%GCx!;PxLfb5 ztHnEVERdIvI%M2KP3?WwmZ_Df22CSCyw}ThqDhjBIV_{iC2hy_RR$ zUP4_QW9gTVr_q85OF;e2cf`9t7Z*9(;Kg%P!Suj82z7+%Oyqo?S(A^S_RBQ|&TP>RN z$&aB%iJ9Ohcb{&cA80Q3KS&t%$JeLMqp__TFsEe+&3o5^?(G~yo| zzUaq6j1r%wEVzp%m!{C}28xQ)&(aQ!8oI*tk=2G3Vzk{}lHC(41IKBUF4@^)v19LQ zXj{jlK5A8T>GCAdsn`X~KGoWdyB~MkY(rYF<*{n(GcqESSLL=5%^{{zF_A?G2G9E}(Beve96jE<7D~tDSB*g&*+b z6bf8JV3QWdI{AH`9{fH7^vAwq^}<8YebbNHrz=2jm@wPO`L2(N#o{9uUqN@AFXV5% zgx|ciM-Ec&Y2gY+bC)#I&J%|qL*^@$lv;p<;S$w;RY#@#Z{Ui~augk`ft3nk@oI+? z{QS*%P^I5RfA4*cXUv$xbVDCmTj{)}4a!@oj)EBz+Eq-&Hua&LbbV&IxDGV;so>go zTC^@+2E+`W@V<6WrPGaGL+esu`1TF2{eW&yJCtnEApPHU@N%RqDiL!;J55*Ae zIG;wgXJ8Aw;d=rN5<-f3p#7yeh*w^t4!{d|Kzq;LvQiHPn!4*gZT-2G zI$?PLb+v7F3%Tctsj zKh2~|_MD@$mx$q=?xNUtT?N|bScjZk32YcUifad>(D~cR@WA#2+Lv(*^;=e<3>y&; zP%1*ng9>my#+f#}5ypc)rVyL`1o@}v^7nFlzw{<0=viKb!wYI5MSMPNS?7YTY~i@} zGkqY0R($AaWsndNlX*$>Ma$pX( zVpO1wQubHOH}1#2%}#G;7YPA3XrvhVO|AYaa4f(a(~9J@MIhZ zu8$Y1C;%&xCV*4pU;5EQ1rPek$H~F z{aY=_^+Oy7@olYi!IPWT-?O>G@%ntoed?KxL#S!a3+k+4 zh~KX2L9U7`aY@w`?prLuN+Wt$n(}&RpL>p`nBL-Rr9@DP+U=Z=aELE(s**;GaNfvB zf4-&NKYHKM3mQYU!Pq&B-mR9zUZ39bkBG&AyVNu~dv+_lRc9C$pU4IMEDKtpj_-2%;c*fkF`kq&8om*F$MeR&Dk&Eq^V z5n*ua(RFlastTPHR0i93yyM$&IR&jL>a73#8kUkRLtTr{(KWHBVaE)4s)QL`z4RL0 z8g~o=GZm11yCbdo+{yD_@t1clLJih5Z3T_sV^~(!jC=N+c#q$3YzL2e>i)-p|1CL% zFEvukD=!zq*@--GcQ2_93ms zgLF^)K^k_af*KwP<1LPzLY4m9psP2u(})9iVUzD;^rA+RZD|(*U*(BpLZ~H_#2O)= zj%U13oj0&xECN5T`9Tj(QN|Irap-hqFG?{Jg#5CDyo!v3S|cIuS(Ub9sJMwK_$af#f>U7gdBFcNzv73BW#CRy3OxTyIUb%p zZcDUb@14V0;BX76&U*t-nqRqu< z)5@zj?D0q7jJI(4gb=#f5(hGsT_EmS17~y!Atj-XU$4-DU*>E>-cK)p+w%pa7qT_Mw{NbmgmY`|9s-SyzJ<1#vpT^~EI3 zVjP>@Oruxi)nGzH4PF#)OcdS+^MBvYhTp#@<99Yo*~EbPb*tPKLaTZt`^=uehDFuz zOI4N3(P^WzM%F@YU_DM><&Tx#i&2-L6y*Pt^Pzch{)yfSdfea}q+Jt76S$66i2!ft z+nYi6r%r?EQ`X~6U(DF6JN9&=pB`JVKalevKI0hHcc_6yJT~X65|z0#$hG}U<5?w`c>&ST=4IsFA$^V~eu+xXmSC2rd#S;cTx@q;0lTknz=iMb z)8uj=`28mbX>+`UkEV}MU9=WyK68PXMZe{FZ?GZLciIwj`4ZN2t`qmn<$M99kzjYI z75v2S;PXq=K(JkvO$!ynmq`};yKx3{y*-1~O`S`5f&O3Z9j&zIUe`AN1MTV{sxfU;tS3{dLgPk3zA=F z;;(smZ1aKrEcwn1x>?DC8B|YZLH1cNdQzG+C|#ts2gK3x&>#4H_HEq%1d-9^k65(+ z7aZ$N#!~T1al3{e(&}FbU%UQ;h=_JrGg+TGoo%4^?v2C7{o1VikT`U1S`GOzYw6*C z_V7LFHkLJ>NLKFqP_t@d6VCq=M!H6fNbAO##CVbn`G#xo<$eLut>27VMKsydC_d~h znFfX@%GlorYB0X(FPh)~75?%0a43B)5OZ6WBVG+ILO$?h#d((d-!AsJEtB<|II)QK zZ_t##gUx-sishMJ@bnZO; zG1^Gi`y!_5KAF8wE zmRh4Y;@4aJ2yekc8^bvcQ~`AV_W;-2&g7rovJ-1M=HtU;kZ0nYiC4amB3`$5!H#`| zDIzs;-7pcAP00lG?LDujC7OS%U=0Z0n2KXw&cX+V^yqe%rO0*WVh@U znkuEq&L(|Fd9IiF;#n?iZqQbiZ1asj=SwM<`7Fir*NTxqQzhiFY2=)4w&);7f2{G*`yV0D%XGd`RZc!>Q5Hnt7R%} ztHaJl6ZT8Hkfxvhjy&VSSy)d2map(7qZwPcp6UPaY`HpIlqXB$osy`9mn4(ZjKxCx zmvUU3N8skT3j9wt&{FrsBx#KS)9UM|hOcdixV9p*7g~?EM=FwMGi>O?$qBe^%_^d1 z?1A(236qk`g%9T>NZ7DElQMaU40idDt)AP-mWny#p}Gt_GfseATyMk8@G{o>DjIaW zVu*#fBHOTDl4biu!;CovIDOoR zq|r2iZ}|oB&SuMynRd}cph2DaOK5>w)enB7iz1kwR7clW{^18ay@_`pn1R*Ar14#~ z18i!4FeWZxL|*kAn=kj1mX#?It!cV!+qg2j5%U>4yxztpeRu`Ox*SQ~w7+1^7lxG= zZbR+wWG3UKiz|{=k|gDJ{7Pj#y_qh-3lCIg5|2aZslqaFwVlk0X$+ZoU?QHgb_mRW z`{83Rm-G5eMmfHFn$_N+BIq65iQ_me(%;vVo!Qun0}cV1Ytaeo)@DHLqFy{9-Ixq1 zNDZwO61PBY}NdFXQp}QS7!j z8=l^KiYo>>u|Vft0InU&+(i_7hFpb4eP8S|bP3KB2cv+HK=LSdh^IWT2rN$opkumw zL2c|jm}zZhxrG+Y^+_R2uaRJyfBYatYYMSYC2WoSdRSw86<_XE!~V03sD+#wL1M;y zKg$v@xW#cU;}_r&2{#xhy@Oi+BK+;mLpmg$2zQ*m(_Mc%aMxmGTH3xBr=5R`Wdq;B z&3*$iq0$4-IP)6UnbcyXi<>|qD;&+5Bu+0~(P9yUH=w^ym8?#Ez-t#R0ppKT(V=4) znz^2iB(5Jee~mLwfn!{5EH{NYnq%leLJ_Wwn#DR=345^3mIc_HrmDe-xap8RHl2Qy zCGa);B7y@n25N$Fhof*kr{3 zq?F&~yrC87WMvPGJE?;~Wf`yAHrEkr4$1Y`t2^VS8kIU%u)E9V@L>{5aPWX|T7kPbr73o;Cj#P|=6U7sw z$WeU=&NJBAxrl5rx?2(RD!g8)Yxt_ExfAC3@_Vrg&vB@ zB?dpk$uU0@s2$WHAL=`4%QF)kx8^ad`rQw+)>`B7y*A{6-Wbf4oy%r%-P8AfoP&D> z17IGxi#+2;fivF_jvSvu-wAq=@iUTmw|FvJCpgBdtT_RvMehOgH|M{MtHzU;$dZ44 z&p}$q^&P*17d^O$3=-mKq+uDpr?(0YJzGso z+w6%?g%eAAt3wC8PJli44XiC&iF0iou-xn>7?QQbF&V`;Xv$G0?P$)d`@X^Q{=;n1 z;eT+F%e!1^3}Di3+2Hdim18|`V|7@XY5&v&fpwc$Kp2-5`;v>oE2dyo$0|5zwT<u&F=N$I>Nuv&Br`__|1QWtMxcAc5<@mDly z&aQ=29YTse*^;S)F%WIlfuG&bqeX`*sp{+jyiw{gwiEWnPJgc9rAuO{uH*;wr2RHz zylX?ryJK;2oC14t^)wWlZo?l_E!b0siEKnN8LNec!K_h5c55rwQ#W&*3O0tY?W-t> z%UO*6thRz-tw7Q(Gll%hQiVOAbBIZNJnqcP0x!{fxN`a*8ntgbnanZGf@V&GL)T2` z$$ba$#2O)za#4q54^1RhiSrq_USw^BS$KP0FZj9`vgHMfq0{>lT#V#)+CNfQh|qf0 z)9lFZ-`&l$ZrHI)vx{JfjwDl&GzQstMSP{G15TJ5lX>RnNV#VmyUO*h8Z}trVE>13 z`&=fJbj9=J&j+$)H@?8hUE5IEi62ni^$F(JEhHyBk|4{{6S}h<$cmkl$id=uq}m`F z`~G`_wVoA_lZG+`#cP7Jo(RtM*CF@U#4f&j=GB)~SJH^K(Hm zeK(hlo!N}_31Drtb0AB_vaqDXI?}broA5?1Lz7+#Zhd@?h`3E4eR40*pLwguNcm?t zJu->OT;9SKRG8x3-1(6AX$xG_1peE;pP;<>5Vh9gH0b6;ICQX!R-OpQH+O%c(NS0F ziZgw<;K(kxVY3?2%0DvUOf9x?(1~=1&tv_uB53`M4P@VH9?KYWW+(0QvEz>#7?)ds zw(aVm_;Vt5c`pQoAEu+6!}D-vh%u2dU5r2PFN4AOSP~I&mINgSW23UOxI^k2z7}?v zXr*1l4{;A(PDr85dSbX9d1R1sXvJ0|3YpLg~61;811JG(AFuM2_`V_blP7NAsU89b*Hp2_bf%?00y&Ea0Km-+ypx*A(Qw1JC1T50bS5$1i1 zvX`eRtIZkX;)jb#D-lbP+wKR8t`4aPYRw7=kEI38)mp5Ne9R%?#8 z{%R|jOjiJjN4MbmS3z8AFaxg19l-C@-of9k(a>^V9jU*Jh{kZxb^fA z+M3&JUC?k5ot&iz*Z-cwt*@q&(Ur<9Xz3Al$g}2ZdDuQ$|LHH@FQfn!!{=b9S1oed znT&QguE4cTQe>xG2_U0${LM%M`!}BA4Lz*J+c+-9gY11MYucfn+{#03zF;M z&#vzf;TeP%7JY!Dd4;TCZyDS3^CWb|n=`-apRh?y9vuzjv@|A5<=mo}LarHc9-oNu z$70yEdn>Gxa3z|R(^-ztPFTNv2GKP8fOm>NrZqx!@Sy#NHBFihZn3NByB5l_b$5Wt zj6QrxmJk846ueu%jtxehMkIMD922+>ONLFs`{-WkJ>n0>*B@AJ8Qu<|QsXRp;WF3~ zB+bro3}wYR_u;~sQ{ZYTi(Sf2(Fw~HNzor?yt3F0*YR`cNAm_~(DcBrBla+r^OSBq zbs2)Rk286hqfG8~JDk(H#FC!nv#XW!Y30d0c4jTd#oIAXOQV-S<&hwcYjqyKOBTY8 zElXJciC7Z<$^;B;uc54tLQI6EIn7}@!%Q^ z*^E?(m)bPaXxEK4qhJV=cI^65-m2No27=1hF~biQLaFgINlXaJ+0BsaY7s(l+XH8H^yX zlHt0dt_q__y=;DUp9vXn$;3%}Gx28EOVqG`z5Tc!1^qTiU^Y;ol}t*Y2b z+Yq+%iAw#x7s*6!S0HgqwxB+VvDT6&3Pa*D+EVDF-XZ~0ehVR?3)!dxyc5f2dv&RQ+ zkL2LtEKE8%eu%^L4R!yH`jD$#`>}S_Gqm+u4VjtThILN=wVqNR!it4T!PoE`DyFXN z6a5Jv$DZSu?>E?_PdjMPt9#5(#F#zcs}pCvEjaOJGh7?-#@#~U&^B9;H5^@so6l|_ zabs;LwbvRJ#r>eBBR}}UC;FkoJD!~(>p0(k0vVcLMYdO+CMV~Zl4$o!T=$R-m|9ii z?tgXUDyZQDwUKOggeDV}oXsu>uH<}u=@3||j#dqCfhWe8S&tI7YvvOy%6R~1++Br_ zgi8_m-;3CI#(&tgun7A;&jY<;W9HVp4gKV1_Tgz6RI{Q0xJU?0oMKFLe)pnO?ISR} zxP*Rk%LM01-1|Gd5=WgCM@t%ZZxn@39CO&r_B7`G z*TXNoVa0WizQQBRe`EipC-G|q9*)fmrK=yv6NPJ>=dX?HewNS&aFYeEOQyVRv76{c zbpWim^#O00C&2Ok#-SnLA1z+_)@u0=Cwj$IiF`2Rbg0hDpxQZ&o9ANjeU9<6IOH(V zmskSl?GtIu=wJLsBZ}1OMUdI2FXE5_GbTNUus#1xXVs2(AyA=)RUgx17dma2VP`Yz zA1X(xg%a$p)mJN(YkkOjaENAD2hybzoY?o}t@!G3XOcgZNo>-mvwumF90w?xo%MHO zj~s5Xk2j}6>a6+fMfy}&*!P5goSR*1ub#uIa+^3#<2ssFZNqMK*}_=gS-g6F1Cf}y zgzQkYV_9dfpl;LOFe@aN?b9$|YxH(Z>oCxz3au?^prv>kE7dI80tQ`v~$Xm`Q{VNKY*&72IV zCqh_iHyBCkvsoHf@MzQ%6w>h+F2$Z=ozTu)I=q=|`y)2a(_p4?@?76|3R4Xn2bV-0 zp7>jHyyJ>K);W5cN-h~k2^tz~z)g)wuCIf{As)-sPk?2Jl8p$wtXPiCPj1=Pa?q_b^hUc z?mfI|$glA{h#h}FqBrju<7T^a^ofWDY4JB9MQ%6gTJD~Ask@ZOe#O~ZHoNc8{V0$gT_O6!ad!F-tEPnAnMd#tp)%(VAAu}UecG;_B ze$M@%p)_P`Xcy|6LTF1yk)53isgR_l@HzJ*t3*R3BTbT|Qb|+8@BID&m&@gx^E~(c ze!pIDyouxEkC%huz)5zeiUggarAgP`Fh`9`ui@)AZSqqqg?T5Fz`T9+52iNTp!dpN zyg9WI9sd2qz`5n1F@tk-tmDy54WF1Z12Xi}^66yvMmrLj{2Y6I3}89)31SO#@xhZO zrZ`_6)+^6rLd{}{s;?f2jtk%z@zo#|Sc(&x0y!Z?9JEIZ!>l=ziC?J&?H`Y(F1JOg z6KjqWe4`-Spav{BuG}f11z_ELmub%@gco_1tlwZmv;9jPfR^Zt(voF=F1{lv#*E-E=!;ruT)SG%ky+f zQ8&kFR-@s!86v@D@$UV&fkAS)(EZ{kCS)Y-#2j%$L(6cO0jaj+G7I_|k&>pX1Rkc?Tce&xDAI zLJ&&i+%VkU=*dz~5O^mK5sj*3sKOdjBNWKt4=Qxt=@&R=)Pn<4=F{^$Eqd(iZ0adh zjkjza=!~-;(N|(JiQ)V=4tbYI*C`82Uw1JuH(+;TihK zQK3e4XwW?j+qIMNru8;nV$g2>_Bt85$gd8KyVg>xU@59?R>&-om8Q(WG?4$M3~M!S zvwLsUvK2ov$;UO9c={6h;Bc*({j+EuFz?ebf$JKq-nS17T8_Y@=zFO9_5mzOz6g2D zA|k1k1oATfLGFhmWafTVNO-2M|A_UZ+k>x@7fzd}YwQ-Z{8GK9Sj zDTs%ZX>Ku(*YQD&zPaE|bAuG^=EQK^e~k_>y1tXVsOp4y^@{XZ@JT4GIS$2F zj?*m(lWF$aFE~&XP91SM<3B-%{m=IXs7Kj=V%#az+;x&#FWW~4{_2yC_jhr39@j~Y zZb65dVcb+LPkU{r(ze`G8a6A6u8{G860t+jbhL!kOARNUyDxz5rcjs@R0v6R=b8EP z(l|8q7p7Vk(0#{s>45D*7&U!Ni&Iz8{@sgl*M504|FwvEOBT`ztBw%8k{jT=-~wJz zK0|gtvLMCBCt~Qw0NSx=D{UT1z|_)aG}4r%D<$}-mphSZQ!Rk2^^Rn8^-)r6Do*_``P@sY%Ns^z=<~)oeL$OY=j!J9`R2W%(YQ zF)5sFj`X4e`l_UJjXIgCc@{evapYgS%YUA_h5FlNa_klv(xh6AvO$)htaTn@G!rmz zT@wTh%toTEOL;;gD5u|}{W;fDM-aPzuI*R_fcm!>S@-TcB=KvQJN9%n<_>%j^ z4*&i^(ymP<^pz{ou8kozt38N`_$tuy6u0*`R3w?FL3;S+dUR4Or2dK<;x=2NryTI4CEv4y@jP;2{K z;t?uL5_4T>``1dc=ip9~J4b}BwT>iUc^M^ppHOA*1XQ(4rlWqlsrbSPc(Fr?Cd(Y+ zMv#4M^s+6(B)6-{= zgPG^?#EXltw%nJ-oiT%{@c~diX$53E<-pxbE-?A;N1T;3%paZ0IdhkK*8U4NtIeA= zt2T4ulv>HRj`Yroqttj;Dwf@Fp?~TJkP;?d``fQ+k?RT>oq$<)Vyc?z&XX@DFAm z&Z9bAP1JPG3%aUvBi(&3gf6-shl?c+(fuil>6;S*^vB$zRK?;w74^DHv+Xa#J^%Nx zx+?{qdDXDB`4+@rx_H&VcSn|bOeUYD(x6MxiG-ASlkp36;I)4iS#sb4sWmPoUFoUx zdgvDVvZIl)RDX?00ke5I%IYv~eF_AsPvYA64wxQ%o;AIA5T-=Olf~WT< zyS@Jl#3lY?t{2(Dn-!06&Hh!?VuliSS_`3R&pT|oSc{*Jict4nLAq`EPt5mTMK-2e zf_AeOv3zzMc%%#tO#i@&MGV6O5Cuu&9q3kb3~x+w!7qm=*!%zegpw(i)TVnTIlE4W z&OD*RTKFD&}NpAV7FS`&L)>Sh9u`a~4$%D)i$O3tvd!(y6kFm2eL5bgm z;F)wCohJ2R!CrIF*__4lmrkVy@`-r%XBI5hDxZ%U0{5~4eHYx;Q9PvCVk-m zHXRk9jgxod%6LIC!RG`?pKgbC+e*Q+*@sxotb$E9<%!b!F=)+-re;>sWP+e8)k>A2 zl2P-iiRnYMFi%1I3Ll!Zco=opWRmRV74Z7WO9+lHhBpm5z^JUiYVQ=_&k7*b^b$HL z_u%mFHXOR+%d2WqCMWzv7)`+tynXxyzlel za2yKuEoEJIz6{~jg6#Cg&61|XcsHmEbonIQkt@|5!IIt5AB?!}&jS19Q zqL#lmU5(teRbjn`gqXRWy{P{8XpN<}C~mXfhb?DiYyDoO&|8uHn6x_#->(n{KW?69 z{p1^FTC9SM)%PIof*8@Ayctz~8$q{d3$sA_94qDYgq<{9faJ_SNU|D^kfn1S>4i<& z)Us|CP1kS0H316vW@8PTKRC`fnh0W0-!zDd?_=`k*Dyb4D%t5IuA*^&z4$NsIL4Jf zqS$nb$u~SPp!+N>SnWp_^G_n`+GEL2!p!iH!z+0nv@1RvODmOujV`1zX%6(~f=1fo zG?%{qOtD(G8x*G=!F0V7tW$Lo9F+|wP6wRH!;$aMz~zYY4i}N~a6?jS{tcGB@F1eg zrjn`uRuG>qA6#Lf2q%?`h{?J%C^&GA?Nw|BSG*ht4rZfA>4^oT!bFesD zn*0==KsDn{L66%(_kDkZJLb;C+NV8eG0~OgUfzLieRXWb_Ma%XaT(4wn}sVqIYz{- zNL+aM76xG;&FN7`p?%Y+v0M!uIex@0=7|iJcTA*8--94tYcn<&*yCl@-HfwZ9kZF| z$G(UP#)1{x`SrUWeeFNa-{}>{Rz~Dt>~uOe3kQI2fjjqhuKqpoH z!qWHKaauttlwZ2cXgaOtr-mNF^2VcZIAjwZT=It>(Ub%eVy1vB+sMRgORxvuZo>1% z{-~TTjK@!}h2Goh)HW*wKYvQZWxNq;w@I2dA1MSklUMkBM+!R@HwkXFrZWF53{j&p z1eGJ#=yX*A9`d^n zGvSK0s4Tsc*~K|jmmGc%Qe9na_IgUSdBA=?FU~amQbp^{(_y9CKfdAn0d|M1 zDQMXdCO4;>F?G(xJn<|{ZheX}4#n7bI1cp}?Z(0vt<0&6Hs-hCZ>FH6mJQVU${1|0 zr(I)t;GeLSjdwqV3#&A7>X-;hSlOe;;18x#Ji12n_!9P^#!pF@KV`Lz{yKj>}olg7S^4$H$p|DEGy*9^n zfUZ~z`0{f>ad8{#s;SF7STG6R?1^JunVi6$@GH=kDnOKOO{TA3XTxZC3urwk=O3M$ z24^BJp`o<_nYt|i*6?-t`(M|E z&G5*~cD{SGJUwvy9OwN+TvV-1pZZr|;^-u}8LLIqW~g9(gaMeT9^kUY4>?|0AX}3@ zTD^bGS=Q{rQajZ@33%vSHEd~o4A=SuaJhX1={xoaWH!dIQ@&4uzw_O|F1W!?wILQv z4}=1{PmZja`-nLse~dXC(#960%w(kA{ebdXTTG3Sfzt}9aN(pOn-X9JuekTCX6;Lq z-75g^&efpKhC%eVNrXivlW4f-XZ)+Wly$wJjf*E5(fdONuxDWk_ME?h8*)CtWQSzz zp8E!Sr@v-TEtSC|zsE7yBm~<9wduO8ov7o~1(_}1Q1QDH&W&}1cSprZ=f>4!iK!OZ zqpd?NJp}09tc#>`&unbpYDM?1YhqGD)hKSZrzb-MX>`zM?%f{>u~W!FO+>RO0N3Yfr3^P zK9+g~&rXSvY};uhaNRMOVuV~@e-&A@o*b)Xm+QNNf52*5db)}lY+T1KQ`MvMWP6b3m&E9sSuy{8Pk`v7QgCcm zIy1j}GVOZA$M6%P?83LH%29Uw&?YX&D*9{_ee4k`aeHXgij5pN7vV7g*<1L$cRl z4E8)L!r6E4qQ+)X@?T&vL_dB40zWcf_04$Z@5OXh@O>PMhdx2@)B+fIoq$1e=i}^D zVRAM1Gm{^F5x2%nAOQha;g*3bxC?L|wO>BSOFM;!?3ZJ5<~4TY+E?6cl5e-8^Bmsx zQ{%kr@9|GZ20a}80N>RK)3Ty#sGe7WNBSqw#9#a9wV5(BbjB-Oc~2jOPwHWmv@qQz z7>+(RL1@R#!eT{FVesP~Jf|0hKc;*_J*j^<@K23|er{npi$~bf)h#$lq!q;rzF1n3jJcd5$NWidF*O)=hS(M_xh_QU7 zK+Js=z^dUed+dGz<8$^L825c-Uq?uzUxEw?byp_cKM3rcBT9sNq>0@=Tl{IJO8ZzX zTKwh~n_t9Y3CD$*NNjQNnjlm4A`lM}XwB=ws z&NaUQZ~ZdtCdO`LwV$exdsFX#o^lVk+)Ba^?;}xB=pk>WULtIJw*%b;>wp<<$F~vg zw7F1$R+e94Ust=)vhZ=#ee{KWu2BX*jQOY>kch$ys@bFs520d$9&>liG;%9*K8)lMEe-rDOSj|oBlvR^MF+5+Fg-g&t`1`PcX)s4?*>T91K1Zr4!Fzhsyi^*r$Eh@b{^YC!`Q`pOS+&k>u&@}osF1?%%p0_gLm-cJ+ zS#uJ9bkbQoz;(17mnGobpdj2h-Ve`D)bb~vLYy{hA6w}524}u1!tvZr6!+gmji26T zN{7wS(QX|(Fd#<1=4awC&kZ%~&vQJplWg9Q7cOt;;)nIC)8fA()H=@u2W0M`$Swu^ z*QyE2N>zx{90fMML>IaE$^Hs*LhBT%B1p_($KTYl)r8gNHol1r1RI~ZTWE! zbDe;HgShWm*E3KTy$vd#dZ7Lr*EhDf%}V{)51Hz^Q1aFnf99#9ft@?lzjA?~yc=xr z{5*EOz;QIBTvlLz3(T?>CPh`2uvxYYu6|!&*B7uBpN(ZP!Mk3t=H5|=ekYk_9Q#8( z?icjgzXsb2MQAQp$ljIpU@ql*;Gsnm(eRrtPTskZL=Sf|SO4q73+azo*Bxu%+xcdG zSd%c`BV*X3yO%fX$~jClxy+a;jbK229xG+&fRFd^sM?Vm_+L^o^8Dl2p!=HOUwsi$ zJr(&!w#^62@{9agSIcYew8!F`Ig&WI(ul0;F9h`^v!J`x81@?|lM6CjCyZmqN|l_( zuP$8IzB-PXW+O}+-E2X4Lo(a?8{;dcOiup_h5l;-WZLx-Xvld3 zf(31i&#*4-9qdQ(T3y`PVg^w%Ymr#)WQV5)Q4MbPHt(ej6?=N0?WmqWPZS-4t^Pb> z{pKfpl51sx{%j_^*IMMilt&P67f<$VwIbDvl=0uOeth?8jLko{1$BGgpxyk_%qOZx zVmMy6s?$nF^7Ae@U~R&)4bFvsJN!ZP*dL}kBne#ZXp-x`>tV=57}gZef|K&4%;|rJ zA^QG8bU7W4_D!dG1yf6LOS}LzC=un@mLhoP!!%mF^(`-Xa|3qmnoR%xnuY^A#HnH9 z5%@Q!4&>$T;F&{lm~<+E{5$;_pY$cMLMFPz%~XUtLnqt$J1C*f?JQ>XivZXjxs|SQ zl%!*;O4tKjrqjNsgI}flgn8rQjep*jK=?=nyI1Nc#+PyVqvLsOz|1Z*`=LhFEtP21 z(gkd&iyFC*l!*EzmEfvB0L{BBvHiCu*nWS-tf`fr)giJpgGOWH-@RzLv=c{qv)Gm0Z@9auEqiO?R9qgJ z3CWzp&TyK9Z>i=wU7bJoP11bl2rdV>a0xUmzogPWjvcM;S%*75t_R3e$^%cNS&fKS0$cu`)SF>2E% zZzRj$lglmGJ8HlfA2q^?d#Ut(!A<6K$0dBXd_5iBB}~T1OWy6NYIJX9DO}@boqIX{ zS&9B!SSZ`YvyPKw9!7s;EwvLMYRne+*DDykZzoV__atKccpVuxkiwPv@oXCV87?Ms zd8??|DA8C!YOXqxf2N-7=y6%1u%CNpB-F!`of&NB(nN@|kB2=*(?Pj54W1jP;z1z=lKAi;iPksh_GEI?bjN-IM=cMpaQ3PufaFR7{+=tC_ z#o%(q8uvIy!tkr(xOK8SCdFNZn_S+@_+uoqXpTMEx(wK+?i(;m;0(&BJz`Z7rqi=a zL-};v6xXdt2DhE@+-_wG2-Uk1k;r29OGh*I9~y=1*W(cDTVm&!s7*2tJ;6)=B-piI z9^;ga!))xgGg$NGJez&sB%IMu#24jFaB=$)=&3e@u{cT6*e^n~cDTWYTXWFWYAsvn zVSrm+2BZIqAE45s$kFWk(W~e*9E=dc?seN~S<)SzOyw1nxnf5TKh>qSOU9T7Ay!Np z_nqrJAVsD)%|YXz{dBEP9~Q|LV&97qEZ-wYT5FOR6D?~R^z|6!ZTBRm*_}kOFpWMd znhM>S_c5MuJ^vO_I(kf-UjK2C-g;d|A2#LDBS&TE`zP0^hgAq&;@=EI=|bdqTs{42 z*NZdOZO7shGPP@G|Da)!9`wXx8)oY-O&qkV z=tfO~)3{4itOD#B*Tgw7ad7-4pPjAJ4J*?Ua9XbntN5%6;y36MS=R|<@kT}VY1RU; zyQ)Iwa=XZH2U#Za?_F%Mb7S7wN|IH%x!Cr{pJ|IdOhye$(KqQDc1<`+K2Ci?cCAh& z??m!ptK2dod0dXXOnC{NlNPdtz3oJ!pUVO{sA7b<0drq#F&g}^;z!T7$6Vtmp3;v{ zvMqEr@w^(3)j_jqjzTFTc4Ia*8qB4QUqo=G^+Y=TF^{GhPqi2O<3J0UOKgzTH}>1M z23EU)^Qj6ZP&+t+Qn?JxPuWK!XLI?}u!S@>IgAMKIOllSP1yK0mbAs?u`_~;@e+wA zQQWihm+MAt*&W5aTk8(uTkDzRLlI<;tuD_y2f=hWmS_a}lHEB)Fmy?c-Wym*^N)Jb zp0B$=M^J;EnpcUI;g7*9@CW4W@8nMoQDe_`oCM*!cVK0O7di$lL-FA7ZqAa4PMAl zrG-N{?Zq<2;=nND5Wj=A@pjSUxsr7JeGyI6DaR;|&AmG1DWa?^S`oC%2L_7_9YbM^_=TWFCP+~085BX6QSZ$5-hoj6k4EFyS5W>9V@v}W}!TAqZ+O-sBTdklA(+<;>84c8HUknYMUIw+F z3SrbEhqgq85LM$$Xdc^6b4*tdtJ|`;S@|#(Fk44IuU4Uw6%yp4RSV{OC{n4Bde$p7 zgp$}%)7@An1%CK@xr<1&Gx<-hLz{ApUHW?XQw7?O3H#)8qu&R z;UDIA%E9_j6AW_*#30S9?A`P2@KjqBZ?(Ng^HZ)^d?*#41ep`D%TbJyh$u}rHl>Z> zC2*qk1biJn2Qve!;FR}VlD1Kb3je%;KKCvYfgio}*HbZiV^1boaL0_?ji4}j@jJW6 z+RJf?U=>f}%V+k+rL%Nss}Tx6_{6iY7lwb?$Jl)92D-Aa{-^8_NCy^=lEy%Q_`_Q%M zIKzLWN9HX|V2$6-Bm<4R$N}dJxU?k<{@{7gc>EPi+FZeV^&dEJ(Adt~d^(C=@gb`w z-vU~<2c1KmNlqizMXj7j%gaL{Z!nrMdX`PacxS0q>;I9ba-!`GJ)h4|yhv`&?yqyJUI@~wJ2;`S14=6N$3 z4YH{3sY$*@jpNT_>3G!B0KcAJ3^~^8=u7icSg)dteWhMt^rs$tw`Pz?(=PPbEk&P# zHcYOygGXHUaY3sD|1IHPrQ5m z1bgADA6@_IJ2+kS1byjFeBls_Wl`rCwaS^8G}nt7cslwU=rk`*}LGLdX`G$$7L2i}}H27-+f zh+gM?kWTRhn)()WH*g7Z2MeO(X-A|C&oToKdf1!NOCa~qC+3-;COm00p+Ctf=69(A zId+K9-ViyA8_flo)P7ce!9nKsM_0`5xdgUC*GWkDWYU}D26+q3sJm|g-d}YNeOE~{ zNn!rr#dS-^v*l@hz$Bt(@D)B<1(Qj!A5ri21*{e6ftmwtD4fU%6PHJ6@j%pWB{cS$XUN4B*^x$X{@bU)L})cw!p8DlbaHJ=W5P zeRbe>%o?uwv-qvxEZ#AkPGvc!nDMvOSh{WsPMCZc1s6@HmN^5MR1}4E-ZN<4({lup ze^*D02~x{lazy520a+6LnK^tukvN|&L&=&Q;650KLqa>SyOPU&8unnR_z>&#RD#OA z`it)OcjCiN0lH~j4}6hai}_cJVg2s{##MY59Ous`Qx z+6!dE(ZMW?Jn|mp^o8i2&pQab15}vv4)@dtk|EJo%;@HE&du?Ily!ZDbEY9gT5TGr zd4{m_XZumya1k>2g0LX79d~RIv9G^iK-5nkC!dBjKu0MS*3_y}i?8B@lN7^iD@AfA z^*!+p7A7j!`~X_cvqDxy>=y@nlKNU3zdfwPD4kM9Z*vUUw@3vC>mS0~k6N@|Xc$!+ zJJ9gJQBb+&LAPWHQ1y7#+V4qoYBO8o=!F8#;SN1)Q1NSAy4RZqtgS;ceilFG`%b!# z*Tt$mS%OoHQ{ny^7Pc>*!8WDZ;*)i2V7-a0XkD;H9dt=S;!SV?EP0b(HRozAK_q=JG@1cNgPc@;p>#gbAG68C0 zG!@=7KjFD^4()EBU?O$}|2nl`R^|h8W&b12{c?>Qk8g!(G0$MOeHJW;{K(D_`vzGy zR#;$s4aR*rUqcM%Zjawb7;mmqvonLH+>s<}4}N5HY8KFWX6E)1)-9y@M>HK=;6gUb zwZZSs9P)S|iQN6{N>*6SB)j`uxc9|-Sdjb=hJ|w2@2lpK4V#;@gr}B`s|MMNQ zd%53N`xs9)Sev$HTVnJ`HhlV1OICIbvHGq?*~(-xZ-;XGw<&)oXzL z?+;9liWkZ(bj8%*`xy7vorug9B2QaPiRI63Fnf^3b1-ONQ>jvCFU$;n5-q4Yd-{j+6N%Lc*nt{TW(IE=Rz&ZV7M z0x-$$4_5d)Q1R(UiRH#qB%R~Tm8<@Od+REBq0@ZWSCtmjVM{%|F-e&0b5^0ekr=w5 z)095BZ4IAZpTmj+f!ID?jP=$6IMN|NH`r8Rpx_{gf2+r&gSPmdaQs^J&$w@BEom#z zr)$4_r;-X1IKTBedzjlf!}6JQ^koy?AM8Wn51*h!L6h8>Q-E?c)5-b_3HJGj7MbSC zorB#D!$B*CoQ{!zIS%5~V_y}#S~e3xR-VQW{2az~H$&w23^F(C-_{tVjYHYE4I9n% zYXt1KVq@75wyldpClN;?{q#PZOs~YCBk80&DhVT{wLp)Ekj-~$ajVZkd{j2bn;5M? zze)?@B!xs;@~4>o`V_@BTm8c|tCv!f-aJw{BY|1YWk(#(OWLnKGls{V?dbk9srLtKCu*EOAysnZz=v@K|z;*nGSy<8< z1OCwq=y6gERtA%Z&wn#Hzf3l!IDclE0z!%G=m&fg^?=vj^8`#z$}#AkOLI@X#bsL_ zv*im`gZG61y3oUxbVw`$epLzXRh~; zOw`{-`9@;@Sc%2@G+*QbK7QNkhyKy?WW7jr>evFIadQ*os__$ zLylxP9Dsl2LgZjk5`=8bW}e+ih7H?7vF^k^i2S*YTwUEF*F&T}~^KTVC=`bS(w zqsxW}vzctHiw5{>yoX7zC(w@Xbxe8V1E#-V0yS!yP2Whl(wtICf2v)k#fCL#pBzVP zZeOMk-^x%AvtD>5Jr1{s z$9h4!-LVx;y3Zj;)l*?OI-bc_P$MgsjzjC@P3-yXlSHlJ49|_X4NO+>NZTovZFw&U zkK59T?F>B>6Rv{yF8`5fQ;KkhSP(inpJoEWw$S!s4Ha+c;i(+4dYe`N9;sy0@6F`NFw}A}7(ktxwqB5AOpF_o7?A3((*-=5%V_ zeCpDaMU6`tT5<-38_P? zQRey;3<)WOo84RKhVyo`&E*-p_NOmfyZIWVB}amD|970bxEx#CgV3u1VdJ(D$XO}K zPK{P4E1sW+#qtF>JmO8mUT89PnWre!bTKpL48qdVIP4zo#KkS50SH z;Dz4+Qc<|;p)|z(n1%-CoL_D84cI*Eu3gie@tTPEukdhZ8?4$Sk1zaJu<9zD`-C4t z%D!#HuRdGR!_}FJtqY{mC+ktdO#lM~1mQm^0d|*x4yqUJC6eLe{QI8TWQ^mrh?Lop z-F}ZCM}7(L#|W92kU%W9<-yl4^XTu+b+D+e4D55J!LGQ2yqw3jbc#h8*={_K?2T=O zmbzcqceIz?_~aMwW#wt6LbL>qY>h&LttqtAXbn2Nj)c5RS-cg04v|?(O^j*BO6pd) zj_S@kglCE>n17XJcq?E6>+$;)OHhm2aJ$kgvOCD(kARml%TU8xoG#ICW7=llv9qbq zzz=cTS=@-c(i`1Zd0lpOM0p90hFe}iJ2-+_Mw-{9-|0{;1BwgW68OX*5V{!Cv<8(OUd>&Mc zGnw5&d|pyQ7n7hl75`SapvRp|(9q3dOVtm-vD94nFx#9Rk!c0pEK`(DFQ)!xNywX4 zOd_MR*rJYc=D(_B629AxtlN6I#$(wja`M{-BG(uQ2ZB?WzQdZ3YIYEJey#)Y7e}$I zMv??Ct*0L=+E7j>hKAHUCMG^c#LuA}k6PY_-iQ6{B2hu=EFwic&C5|^=L0@I+J(>i z67Wb+7R06;1I1BSI==fP$Zj;j?gP%CFgYAvzj+T4Pq^p#y$3eGJ;3X8&1MXTIREIX zDqPd)j^#hMVC~g?bg-SOj#&8j7PimVAshD(!x$AHLH=h*#z}_0>-vT5t)(EDmdsY( z)+gVE2C=|Wl?`~+${d=vonLxoDx=JtWki)f0~hpT-{eeZogK>U#yCf9dtM(}4SnbF zd`i$iON!r#68A!A9H zThqp-+c@JdgN&NlJF=y~32#ilm}DUxJ!mjp5k#%aAMdGr8iYP_NC1UOOZU9U1@NMX@85dsNKc zRNO@ep2jns3hjvV8);R?KgR3rMktatqRw9r;Wyb2crJ~l;uls@rFRRU_~jflz4@Lk z$rB)ve59MUJ*G9-%zbm^Xr*yGtt--_S-r18?CKcm%}ip1hZ`UQH1Te(5Aj@g23l-v z3DYM}7XLa$Bn@-Pp&or=WHyy_8g0duCkhrC3oT3(@7+?vkzJ_UotsABuK7)0p_(x zv!UMU#Ql#K(R(Tj_QuoT_kb}-KD@;9FjFVQAree`!*O1`DQ}f^7Fcm*|95_GnQZGk z{48fc^|#DtbXTRLvy>5D>@p;ITlsMN;zeF$h#-l1xF1agUFi4u?QHvDYpR|9ogK)Y z&yGg0xa7h+44(FjIcoQbyN_l;Nk#|$XYGZG9Cyxi(;lj~flu9alW6*Q0kQf|pKNK% zM*fnYU*ldNiE^#X^psp;7@}66tV#vN`p7u@NgPKci3L6rzA`wKa4EP=eiJTW>25we$ zB~KoW(r4$wX@`#%P5);{SG3yUSBp~Ycjg>0>-C8f$28tO;|+cZw8jM*4w&xH3&*D& zgG|E%kejs>tY^<DUHjKZo4^E&{;zhGB?ww11A_CPeU3VE>D-o&8N@* z6ytRnmRLvok%9U&`t@8JZceFY_q2DzH~V2w2%AU1xe@-#t1x>qMj^w`8l7&RhTP0Z zNRD`ghNFEL_p+E>J?cq>!}W3Ooh($P?V~HEaXZt*a8S4qj3Wa5EbzWD=JV38zZZ~8841bJWxp39b#M)nZ9oA-@1Gz`Wc2~n`qP7BN8HR0;d zV^HTipLq2#bVt;4THuyUPZ|}%TgRt#@M|Ob8f{{HGn2>`i$(B6+6?Xvc|p|tOIX|{ zk6-3A!^*B^=J`QHFJ*{h;YEz_(>AQ~egzWA}7E;P>i1KS7PsdlO!F_ z^l-)uRoY@uZg=^6H%wb9&EG1k%-5VZi=+@$=3IIVx>YE$IbEIXy6y?^wErAd#_i)x zHQNI}Cv9eC-43C@Et25TT1V`@e*wyipF?GYF5cAOaYy=DmehCErNZp4A#b9#Y-lQpkxyc{^>I?;NLu`xKo8SyJl0Bk#D$YwG*9b zpMhO3b+~s~J=Hc)qDwARLfoM$=F^S^oQ7P7w@H0k@#s>s?9 z?2);OIoqZXJxMFFU7{R+%ka3rfie;OWK9yA1jz9N>0t9P8^n61llCUg$0%42+~5`h ze2ZZEvY(70x1XN=buBu2rDB-JLc%0Whslkc&yw4R#T9KL{G*Fmua`@x|6z6Z^6cAK zaU=#}x2ckRNpX0mlLJX%H*lKwDcrzy0ow*Q(SeHH=%3k*uKv@=_od!Af1NAlS`Q#Mp`r&`@o2|Sv=rgk`Rq8`8uBeMBt6jSl-$`tnf~$W-4XbvGF<-}w&$!u;6@$2zc1CzhgsDQ!_Y%s=v{2R?B# zX_d&mVEOMGIG*8=NjdTSV@o7ykkDiz6q-Z)3XQ>a?G-RA_hLONlbHh&l0^RdS-a#9 zE}$@P8?6n>qF)6k(0z#saO-&%{Ta4|YWhZ@?A$`MyDv%4ySI{pya2LH#va~j_0wb$ z2XdRY5(|YLBx=kZHjcc3)QJ-qyVxoAZ&s$0kE2OsVv;n>F79QV_NmZkmkz>W;Vtav zy|JJ(vYyO*qYc}Za~zoUefVu@4&zWAL+JxaJl|f&szr;D3+mUnu7WG|PYooFPjtDQ zd@!8(@C-MR$JlyiHmbk>ZCm>D2cAv5$aoqo!v80rGYsV3 zC+f!v$QLs)ES(j_-g);AMm_U+UU@Pk=Y>5MhdSb5$QWE7)+0UKd z(oAN2q9D=R%Q-mOWhaKeuxoGVMIHb{CW zC1Ml~fFKbG6remKIT|!+K2e%Djf{&n@w%f{)1xYuIEEF>qw|!x-&>2KU(&(JHxnG+ z`eEQpW1=qYNopQ!AUBtfa9NxZHs*i>F7VN$cXx}iuI`ISo(qqx?=8YlcRk6K;GM7{ zxQA6s_GH{vmf^(9X}C;mGSOYTh2`}maBP?T#OC{Ln5JWmB1}GbZu-h>mQurm4z=(n zrxvd56sG3kvQ$4+glZg!Kx?-NL^vP}8f94OaJ3U>yo`q}e_BAqnq^x*I`CV}jL}8* z4D;`c8+HHr8q?f1gEwYy`Pj=?)@THx)d)7L?^2D}12F#Oh+UZTTk`(8COP4d4yRVO zVEn~4-U*2fxK;5K3S5~7Cq_%LefJlf{UwuDFIK^TeRp6N_Y9ogX3NGp>5=uvw&0CD ztxR2oHstq=ze^0&U-8{EXHdsmvGjzF8I7K;$9C3_VqV5R zx@U$vQQDaW4r2bKlXElL%>Kr4Y7f)bHighND$fi1-NOIy&4`MucB7#j`*d2?da^i7 z5Ted@W5~;WkS-_%N80^iqW5bI+hRmL+}^{?FG5r`WH~y2S7A1-m7)I2TA*yoKXz;t zLhH3D?Dn_e;E+;D+CB;rNB(no_RgJp-LaNjNY#G^tBJngD0riX77Vj7!>(^MZ~LCq3!W3Di1{L;c~7m+8$0>-E-dzj4;s>4Cc zy~sE@kzWte@OaI8D3e)EL_B`ufs$9u#w&bm$P=Jf0`-WOwI$j6T#nYv+`@?S=b+<| zFofLMkNsx8sBzPc{*~g>AeVcXb@&XO9~MLv53ZssaWQ!qcaFSlxx~ZrOz0Af!OHK+ zOm=`G9ef$V?pQ8DX8g>B7wHq|Z>qVw~WXOeOGJkixW#`bsUQl*PC=r3j=c5OGKi>KzI??f($uI__=HevWzfR9gn&52XT z9lN(86KH5M$3p0sM9?G+yeH=1oQ2Vtcv6w16;EVE9=bA0YF@k_A>~;2bQ+fz@0j;HsPI3E&cvU}t_#D)5Rx)0rGZd}6wY3oiWG^^q);hJ6D1W%5t%Zi zMBd0yB8gJTdDhNQWGJa55elVAqh_V=`ThducMiw1*1GTOdVCPXmtF*wl{X+(^#>P~ zl}q>T(*}J$`zaMy07g`t!s0$bQjCF?TE!P03K7!8&}@ZwFx zWr-ZoonQ;ECFF?r&=lfX{Lx%QT837+ABQzLy~H4HJ)V#V;KEki#o6Wdu&}<53{GMA zvnT-dYaxC#!F2Uje8Kzfz9(E)v(V8*#L|J_g=!GVMRj3ziXqKauY5a3x zt1<@g9Iur;qhT>=MuBDtm+-m`R4bgQ@+VdHd}$09bV7-R6}01Z({E_Ge{*#g-p=Now-x=kNO~jdNc@Oy+cVL|dkDLN{$X8LvC!lmk`7Zv<{`S8mabE@aEmX3 z(7YB1`Q{>2EZ4+2rs{N$O$vxCw7~BrqS!8)j(*RK@!f$&{O|4&VP_QI?J2s-e#?ol zrBjZhq1Pc+I;)8#xD>FzU9SaQORnLbguSI0(D*#L-(#~pxWyn zqfY%VE;}?ER_cqe{PZK7PtRpI9UM&M3L@#2{NwaykOpWw?dRqiULz)DYSbqu3slaw z!nf(;=mXi;0<=+QHDBvM@l73E`TPphXH*kXeU_UXqsq=ad%}*sZV~KD%qt zDGg$<^mj2Rub&N%k2(pq#+lGHkI#eG7(Rb*UIS7m`1!`(7)*6v07`6tiVh`ykADRm z_glj9fi??xnl0Gd5eg5VwPM<5YaA1&g=Lo=@$;<;e7Zu&X?-xK5mhN{OOpe6#j}D# z@;pfK2~~1ZY$Uy%83ym-&Jm$h3tXSJjJEoH;CwU`@l0Ymd^E^|T7wQErXa)Kjy4uf zc^-h13O~T#R#VR7s}CID=TPBDCHm-sGI0?9f{_!3VOOXE-dHdXcPBrA$U_$RE?b4Z zJeQ9vqa@hKpg*Mi0iRVG-hv8gi*WO$Oc3=yz-r7~nCd81ZdB(L^r&RaORiFI&-5im za z$lg>t6u*+dPHpUhtNfhZ6T1^8cgcflNEPlGlZ7gxVlZ^D7){<>1-D!aP+rXH1b{KNF+y&bJ5P_9cKN zkDJOAi)XWaOU^U5E3x=e#1;1mDYHwm#J-3xc$;S~Z<><{Q~P3}?2|j@Jzqh`DExs7 zV=e&O{z{lS#SK4aX&52zGpEgzcGiu-eU*o05GIj*YqqMJ|LI zeB?PLZu3wF+dzA(Hpu_na1P`n{W;7q_7&eWa-kzT;lz^^l2Llc~7)R^nH5AAa1( z0sX*Ja4N%e!crt09D{DBH!tX2hF_9P1EV*zY zvoCyvWuaS{=}If+v{;YT+}6U&c7<5ndmkrz9AHhWk}%TK8rj}yEcLxD6dhAx8hls& zAwNIk(|6=EpZQohumw+4wR5Mh&tap?JK@&QA2@#YI+vxm0r!;@TgYG`o;}dP1z5-8 zC#PIyzS7K;W|$1(kB6q*cLqW$#~=vTHF-KGv%{OI{9*!lhg zl$|glHYwo{v>F5n`xEf+m~Z%Zku_b-Gft`SJnhMq#1UDx=(BbtQ8Jo>-=&qAn%T%YQQ>57v+(&*mCeyxoHPCzi7N7rng*LAwS!JX$-6Nw3dT~ZH zIB+f)Eh^vy{AV4TG<{M|X60Pv?#KTj zK6M#o3KH%3?cXA{^UNi3s_6xm?2QCl^U-7k&l9cGm=5*#y;!@s5qtXKG<430<8Qdr zgmWItVpG)&>g{s}j$A)Y2xmYqUq4Rd-5ZE*moW{v)(Y;IjKCpPl$v~-%Xf#am>*xC z3Jq0Hp;^#HQW717U+%g>@sl&;Xzn3+o-&#q@H`M#7&TY8Y)ff^6;&#z+6+nB|I5?42g>ssDd>;L!uv?i__LChkUkP7a@%Ud3!- z8>#3o1*{CGxzhXT+FB)Q?Q|8oANGUO)GRp3^IdirA4i`$OERkD3woU`Mq!CG2(#w# z-t$km`|2I?=)W8k?9IooH$~Wm@NrD!Kr&m#dmq?}C~oQBU9j>~I4r$Z4Le@TQ6py| zIsP#X54>2y>Unmoe&9`Xb-RRCGkO1I17W`$y)iXf62(4bz|4w6u`9eeYhe-^$xG5n_chqHZ`L5jmeRzeU&LqbYwq($SD1Yw4Quj7(v2@QgjMgO zg`>>wTJ)sq(2uLLL8bgYwCt3o*Gj8Mn}Q0RFxUjE#j;4-hk6{YI6o#OLl)AUiyhvwP}@DhHJ5iDDlbQoa^c z2Xi=w|K@<|a6XakpG3cXQl{!=mQ>ku2fy#1OoN7+Nnk`n`AeIH_-yN=yiRN=U<(|=EP*qMJ@)5y>?*4 zsAoj)*)i_6m5PB zz|#a48~Ct0Te}4fvqxjw+?{OOHgOi+x|QiI3T7fQC0ui^50%S2hW*FpqQ!18s(7QH zYuHeP@e!UxqFS3<=<*gl$2F2~y6&*4S_98{*>hu}I8N1jEXwiSw0>EjVP8TyDI=aw zmlw;;luiPJtEB>XEyHYiC!4r!jSFmq& zkMLxOHrun}3_DzL1bzHE$&$co^Sv??n4`gMO!pl^`r#D5Zjfg+bM9F9{$X6mkP)?t z)+74fJZs!xCfOP>l_<;k;ga0LAbPbjQgZ3MG_tmaztHJRA+3qm7B zandNZ2oG&ZWCPF_F;zpIEk8Jwl$ej8n#u||l+*=l>||-$#s6?-=o{|8 zogX>VjE&%&JHRcvyNkrHGbd~Qw9=tbC+LYs<<$MJ8C~R%LNDu_qUl-f)bLw5-5l_O zcGlI9v^gBahlla9k1H14!C9nm-4jmvTOkaJDwCskk~yx&og7c*yN}yC;qlHCobVu0 zFm194%aIpjnv+McZi_@_A+n10lvaUWmIb|N*#;p8PJ)TcF-X^YM1D?FgcohHIQQZ) zbT&=lWKM{%V8sgl4s6Rt9j)e4iY9SaCJy4nU^BMfsuX%QZlmu53#dWD81_d`5>w2x zaD~>g>8o zGRrfL0-up4?914b7XWe2HVvo%_>W~1>XyJC#KRgc7)Br#LqG; zy|N3f3zfM4HmL!IN6-xi7J$-==g@QG8LcSlBWXfMKrR@39!!E`I>%AXP>EhW;Xsy6 ziozK;+PV9;$I$A<4ixGuK&)jJo1d)A+Kg8)@eUCv+IvsX+WgGyaH$m5OWonzTJGY_ zH$0C(b|>E<&_r)BZ{}28h$3I~as7rm92#$r&xa48e$;MuJx`p81S1*Rn~9QAA*6VF z5}v$WK$Jf=a4JfAxZBAXZrL`%8)Ip9$Kwxob7%}Z8MB+cWBlG@!VLELvw(G$w*V@N zQfG(rT;&>P{L_DxOxL$()5rKg$I2%Dem|ETSWpI;es$!T)-%FFwK%DRc1Ra=SfI)# zwviaU#KaAyCFT)~{YJz>wy&nWT8li3ZKF;Tl57I40g1+;BpZY#Q3=gkZJ zZGRKnd1wobw3Woam(H{A+pC~&)i1LCiwhO6+)0il=K{r=)`zOp78))k4m-{C zn8^<*X0f7-`x~qQ*-djnO(TN8Ifu{zbye!(XiPmMvT$I@ES7AC@aoi4;o1ci!k|kf zxbUs6&^4_b3$tsuSw5H1sQoklEOA>9!m|LRk2=#^;@+5RHjb#eFQW;-frOYG_GWo7 zjZ@iR@|y1q3qIrEg583(BU1!9fsy3ynX{l4JOCG#of9he7t_nDHE8SYT$q`aKzq=I zCS4p46I9E|%io4rt}9Ppqz1s|)@v*+ZVhy=ox$YZzhFLnyz^eNij#kH25pX7vW~H( zB(3%mTAVUK<0bPUVS)(`9jqr*M~1fO*kHi^Y`iU4L7!(F1PS>*9Eu9!gjb5p>o3}1 z!R1t#zP$jH2F6m2F-hd&;0w;J*_OU+9mgEI!eILB>9pa;2snIIKo?oP#xu4;%>K{; zRhx>yNq7|J#+cFRkE4ie&tJGd;KTkIlr!0^88ByH7N*Y^VeXaJNmGP04Q=0ob<&$) z^{St6g5SS-eR>R%)t`vn`*n~tvXR6`M}kGQ4;ztSfU<#?FtTx~pZu6032^%%o zO#jKe%OwVu8;j9j!&RX6Mv66!<2}{)f5TDUJ+|eh4ZC#G4DU~uypbJtnC*M;iSD$v zrqfzusmL8C+8D}r)1OIE(;iovF1Yba(yoG&!Y@WENn5)nCUO(- z%yf!%ZPy4>;~?fu8FAaM1<$vC1gJiWuFv{#i$@@r9JG-}h>UpY!eC$SRs1Ao7Lx`2e@)raRXhWKRXxrO zoX39jZpNTp7EE`lDZbw@g*v~DW?nnnF*T>3sOsFJPfr<8$B07Vd8=lgwQ0bXiH9+% zxf5ta`%TsmasX$XoyV5@oMHp>J~R6ko*8UP*uVJS>`1g64liAaIckToeQqNLkRlwr zIUny#)nMv5IxK17Baqsu4#y%?*tCZ0?6GMn&9qm>>8qx5-V+@epR5Prx?FHHC=(X& zw+G)5G8T1HhcQ4QnHf#-gCjHCFkz$uPRS~Rkc=U)mYvFTfPm@t{Y6pPFo-NDBTGK& zvqotnT#{IgGDV5F^t}?ata=Jczb7-3yDQlUKQ*>OWGryQBB9Tk;NWGLq&#WFI3EOGMzswuPvswfiJsdS?7mB_^P%Jox4?8*~kbEK0X)5*`{;ucfy$LigR2_?kqZ8{1UyC zz8prqDW!+*8gcS}VyPhf0!>n!PbK$Wpm&2t(<=#KWS&$FY@L<`p2hJX{p1gPcP>JA zePkHY}%{2C+rjrKsz2o@0P&NVSV zC(EOpS%gay@yXl5%0KzR+yPlCaF~W3BW=m*t?TKexcA(atizDEUX1O8(Zh6h|yiLEbL`E_!(#HwQ2C@ay<-cFQ$)_4^#I#{*G@l7kWUfO}u;WhB8-w}W21l_e?01wj)v;ED2RG}XCnbPQ zI3mY()cDb^2OTIrZ3TomjiuRj3+cION@S1LezH~S1mK&A^j7{Tbc~4so%lGiSk5}?^`Mv-wm~Ds& z%}WGDGY28})-j6|9Sf=&vkohgBvRDeWa|vIpoPe#awJ-HcbaijzyWIo$BF(X8ZgA7{TJg)^R)&&&@Nvd(Uv zCE(Wv9__1G_nQgWoIV9aUdmCYleyUI;4a)ZYb{N<^$-#l9HZ|u_?}>WGW+@DD4sj> z45MGkv&(V2c+X@SJ%4*5#0QjcX1s%N!yHFYJGck)vY!x_W;xhA{|-oOu?ON}2vwyL z+=_i`(eryMn{*(8=TFsw-jZl`@1l^Z#y3Oc1Ku~ECIrS}we!X4q|cRHn#McmXdj8jt%+Evp22nOyoBO;oPc`D)9*)*P_S$P zczm>lQ??gadE!zwN!1zJitgeg?@v(Vz6V`XSF*zA1Kbr!C#s;o9w@D2JwuNan^5iBo5o(;5d4s0@3-4TntxtFR-G9&aajF=`&wX2SN>;x+Ya45#PyG@0I}F*L5`3M@TTi%_;S1~Wq?xiT2t#TpK26n9Ciwo>334oX92=mvMVbtOsX}#M^UMF0G87r$n zXm%EqJ7QUXTO4o-Gtf0>fYY`5kFg_loL|x>?DN>n?oBS_q*m+VOV?9GW=NYFiRIwV zoI$X9=fL`svRHek8r3X)#(MZ1Z}zS$m^u25P#RW&A-3=mYykcp+}WR_o?ar?=JM>7B@i&>OUQ zrmS{>1E;nv4t>X@4j3TSnP2ock*a+@ zeIe-Rc(NFS1e~ob2gM5?viMPV$(6M_RDjD^or)q(4z{P^ec7<5p%xbAIKlxNj`RN` z%M!fyQSb42%)<{c*Fc_y$)#dNpDO(`v;dx+z6sCgCGalDsno~FfNC!0d*Y8CfroM} z`*)^-9et8RDpbsw;qNy5!ry+g7izJHRXgG8V@LW?)0Cc^6G`8xXQ1abO}Z>v3%9u3 zMKf7dx-Wh#ouE^I?+2$^?s_$h-}&+JwWSL?Jo*ba*=Y%#wDlVC)N#XtZUGyqtV7q_ zm7zrsmZPsjDuzDWgA$v*lk;CoxV3jDa9IhFR9DxXN)PMMYrJ>#eu^4ogdh(8o=o33 z{YS0j*V4#UCUmf`0u_2sab6iIXmW$^kEwmbe*+hp*gzsY9(ur(W=60v3xt?@WF0za zav1x@NuV147H*IGi8nW@Fo|;~$(8Zatg(M7_^?tq=V5~rtGB`R`vz41dKx~H%ZIc7 z7IO=<+hFG#Nl0)UM~e^Jz#{Jg9Fjc?F5_y*4Tl`gt@kIEyyrPf?=PZD^;jlxwi)!z z7C`l~acE?!0rPPm726X*cg#}fOHq%Dh4yH8@M zTr?STNd)R^#h&Zs2MJcc>SzM|lB=3nfuS+W{}Go(!wi z8K^xw3F%*3$gF%#ykDG*x~ZQmVtgdH!(Gzcj9(|X3vKmKIgandl^*AAz&1L#W(!-i zFNWvnE3v#!=@?`q!J>M9W74^|BzNr|e5>~xpH*2>ac>c3s?FaRm*ZOFa_H9&ajWHA4# zh8CjZz+6rQ9$s#PdF@BR_QF>5xG{ov+D0TZDk!8^Z6x6B>x zq39!vOqcoSYsOH0hB`HfJq&Sgoj_YL5EOejSfD?dTcgkC9tQMikIYz><8~BhI}6yS z4eCf3L#uuHz}Xa=KJ?0Ja{#2^AMJ;EYt z6o_s=igns~-1NCw#PXyf{;<{u_HQTjPYOf1_@^*8=pB9;@fee#2ukYYS=$>^D$i$# z(ocn9)M{(k98rr;iqg?IJAvyMDGKQiCg8q$El|))!NmH#(0OhNl`v7HZ#AB9(?U{# ztCOZC!QWw#YZnBydtufKSw4rBiW7A|z^x`fNLT0clmAA+(*|Ei+<686_De&)-3A&P zX~IctoyA?5-ayTqyHPNxNKJ%baIY zB+Jh(BR8IT!|kiF=>Ptu87v558O9ORO?Ls?G?V9QG!C2u z!*ffRJ>Sop`?{GN`~AbB#l@3OeOAoXd>F|J_wAt96vi>d6`PsPZGBMgG67jmNY=ev zNH2_&=Q2i(p?33z!JGGu?BMQiT*<|cxcW!FQ1$#6OS!F{G%Xe2Q>Y#tDo8Hht$G)Z$R*I* zi%)=i-)OY(Sp(lxBG%n#Dmfrl%1$Eqpw1r`y^>j7_xc|Zh z565E3wRCP!{VVj&d_xXaZ6`+Z2cbK_2riCr!tGm2@X_WUkUJ?GcQ*50(%p)9@6-a2 zmCM1{n^TzXxGSi+G7gL8Sip|`eFFVTb2jC2Ebiu6kcZs<62)8cxPE^k`fe?-h?4yx zcpp|kF1TESucKp#R%Q;~du{}WW>$lKrU3msl6Zer5sVFPL50{ji%#`ez4sK8Y!gL^(%DpWQ#8(WzYAm2Bys&uApSiWK*Z88e?%di`<_G^ z-Qw`DwJ7zvDT~gnxwtLXoV)$32M^Ef5#EoA19_!0cvu*YS6A^l*Nt`LN_f4X%c%nW zIxjJIk$1d*E*%qgo?*J5q=->zH_!U}z{<@nh*fQ{F!!nuW*fOc#?QATsj&h5*KQGt z`ak6|BGkDlyhF-vBk$nVOGWKn;)tuBW5!vTv6-<%u5!3Cf-D=IKd1e&ISj zyXw2J%C>`i8;%7N!-wFaB0{h8JjWN?^=S>e1=||NGuMDH;f^?G!Jez{VAkJxu!dX( z$6XPy$p51td-`fP<|ZoWeB?`;3y}B9adIk*XO->w?_aW@}3y$@)6whhsv)C^C2n01!Ll`a(Y2y z>DGQ#R`cs2jL_UquN`;{Yxu6&q=W0IDHh|!wghhM0PnY{Uqc&ft8hxID)%XT1nn@E z1l^S(5b-QcIO5xBG=Dxw#`r4`-Cqwd-CmmgISb7zlnzT`(n;5& zO)$S@Hz$0ih)+LFr-H(dxN3@5`JVAs2buvlz$~%IZeJt+fKE(EW$rgG*SVemg$-6ao@* z2k>3A8#mZ1gPFrixYX?TG=26dcADDIOWR+W?FMJ}pG;>S>&B z{aj?VRgl=QpsVs%^tOinBy9?{aO@`vrx?maHMArWsfpKei zr{Nr3i$8t*XQBQEt(x0FW;g)Kx9XxxpbPpocf)2&CH!}P3mz>yK0xYOE;!1iRwq04*NJiMIG{&id0=(w6K@UFwqQj(r|v-kAM# z_4;!(DW{q!}tIiE|$G+jfz5OF?xyAQ61hT=9k3+8K{59aY_xz1~&VL)^RsNsJoYb;KG zcuH}z_#4bGt7Z~M=Rr_lG2Ti`$LQvxXf`W>Bu@^5b1YtP{fY$pRBuETEtJ^ek{#@o zzZI;%s!7M#JmnS{^b)n4G>lsoFMO>XjB>j!;q+6ND7Jac-IU}n-2?1UH4 z*SwT9swQybwO6scp~F~hp8(cVW5{UvdO>xUGOh8R$KMttnPnscmXd&(vgdGXeFfU* z-sJY0Oy>;sq^YUnRPJ5w1Gr&W1g|dl<2=pZz>~(HLuM7=Asu$Yb_Ltw*#v`Wwd^c^ zLw?+`0lcHuuPHkzH8R1R+* zHj^@q5j3T6A{Ae~lijht3GpJ{bo7W|T-_uCeRJG!aT?FQ+~aF8)1{tSn;9{A(!+JM zRCxVb#ci8*z2JoFy0uA%2%3Df6YYp|0%HwX$8I8K1&cWIJ z1>E8wo>!}Skj@Bt4%u_Q!&*TF9!q&wZjtp8o7fbMHTzebUxql*SIquI?i^&60xH= zTE!IB@R|6&nfGA6Ulu!XTMmN!OkmDVXRL{~M}OZa2(?QmvyXOi9+?W%v#*ESbe_Lu zwO{AE00AK4uZ^lNL&>tq1sE1Qi<)$;VNH&vP_ws%2uh+^|8Iml0V5#KEdqmsqUfj< z+UQZVoUM!&rGsS(V5ezDtPID4dA$kCKlPl?+)?H)s|_}`8aGOf2spwVHds56owaSi z(>LV=X}6N#?^UVm3q>chQU^Y08$OIJQ)D>$+!Ac-9tuC+^@0RR7pnIXu>OUC}0koHm{w(k5<5iGBKRiJ%fvBi=^WF&yZyKSXgy=9{j1-q$K8< zV1eRpE@mFXJ?EZsfzuyB{k?jj*^z9))MGgyYP%T+&uhbW3u}tope!yU=(QUWQ8CaC7mYy_bKZrRSI%pJmm!jTa+uc##QAs&y13Mpxs~ ze%=Z2>J=xWYbLB~8pG7YB*4hvA{V`7H$9S;Y|(Jm2v1z!Al$O6mc(|R0jcU!WY_j; zP!j~gOMx7_^H87s9UTrLF6%kRZ>_M+Yb=Ib$cLB%^7Qg(HJBa#7}O7#(AI}jN%)>4 zu=27lQ@YJ}gGTIT=fiK|((z&3gNsw}vDSR}aENDZXate*#(!|ZzzbBUx(xBPNw_gA z1;^xDpyR5Scy`M)Qew4~Yrb$7XF1*%dPf9fblXX|u6Y$RwtYk6LK(d8tAJ5=6okw4 z3ou8N|NlE-wqT889n1=0+`aO5Tx8918rA86(j)IscY8HX=2)>{*|^#FBAx`n%TIyH>>tFnHvp`rg;1X#Hc0#8(OA}=8uByvaFGbpOi}{_Z4vx!l32dl z-7B=V=!pUw+*4||bW^Erh!7)CUWVaKfjCXKWQp)7*cnA1< z;SKLVj)9*6ohbkLI`ooPoIn3Pv{pimvbxVuXmg5`@a!&+Nh7G<@8{U~q7ppRj|c=4 zDslOfe#~E9P;PrL1$_To0hTuFz%Swtm&9itBhN48XVPi-HPsy}9qsVs9d*tl$&3|d zzd@U#cQ}6kdo=BHWu}EmEM|c<{jt3ne5L;4n|lku-v1@!q&^pT4eo@AL3hFNu^Ewh zcZ--#AHj28e7MciSL2VRF2aThTj1^ENDve3hEP8<)@`zvp4%Nl!jp{QyxkHgOPh{| zzUW}bo}W0$tQXz*USdIoCihGD14b+T2OT~AL_a;cJoxJ;&_3D^FJt)~eb+Iti^>M+ z#{#r}^p`u8?L}+CC(xVcHj}9($6@9UIXoVJ8q{{C!);|C)}gPlNpCCO6n(_)arGwM zpn|=Fb1hc;?;VG!nUVkhDi%7id!g*($a-0sbVTB zIf|~zDJN52ABUa%964Te1-bAvforHrCJG-{2p=hJgmCE@I51}(UR)7MCCW#$qW#C2 z$UqA|FwAG!OUAJ z<@w;R-3g%q+ratDUf9?5OpxfINX}e$1*KW<;b)B#7xaDu+<%})P1OHG59zsZtGEgd zNOvQxxPhr!MZzaq{601Q3RRHErbRLOnCx6Aa1h^sXBw69^VV&wx@SP}VQM^=L@r*LpW5h#$J^2{u2>pgJ&?oi{EUZ&3V$-sOwPK54?izjWd~_%*exg8^y^Fxg z@{f?DSr3VPR=;HUF7Z#i4i7D^!iPWG$hB1nr})>~?h}GKffh9XWj1Wi_{A+T`Nloy z-$!%*tS7<#VX$@2E~=357vBGJrAt1y!SjQv+>gCl6qV#z?;mYicV!hmUtvT$zBfSU zO5R2KIG=nHJr2v}_9& zlQb?o-T*G{>)0jjR@m@+JnfIvX1@Mk;Me@&^1H>~asCY{+~j%|tUFxMeO3d?Hm+hT zR@$)7>w9rdNHa!lWK1seB-`{kh3#J`$2yW0LF`s}ki9;gUh7HVY)Y50JrcRpiSH_I zxVsfk*vf!*)ne9oly~Y~%3-cQ3s~dkcWh+*TC@o`#}or!u_oKtKe|tMZu2?HR!Frnr^Lk&eR%Ya9s2Vwr2h=_BFPOw8uAqyOA1A zHtvQyPsVaxKexc`@E*9|zLx~734&K|R?*05>eRD5gQOO{LRumUgB#Cr{d{O@kTh~z z{>>FkPp*c1{(g0Tf(L%}oy&ZPB)e$F=ag%XvSoFR+>`9xg1*;BnN-(ku2FY7JDE9} z&i%R_BFByp5W}r>bLnNyXvb(W{kA6GvoC>VR%7VtL7uau*aUe`H-cEoUo_DEPmtY%T6|;ggdrD9Vo6S^p zv@30kNru@wvf$C-owQzT4=gBK2H@Z%l%mgIv5qnE+UCneuT123X6bCGXgwxhIE1UK zBXF_pIk<431Uhz_k+Nht7`K(-%Wt}P?AU(p_8wIf4UocDJC(2})D%LvE-0Z>=(Vso zJkX^^7f&;%ProdNth^9NkRHoy#nZWI9}S57;~J1v4dXWZb>Jk?`#AAC-`P8DLT|j~ z8MH5**cN>oj6R~q8uI_qF~g~pqk*i!D3j`pw?aevWOnQ4Ji7aLC3(ls3zip8VTHg6 zmJ1c&ym=aF9a}>7d#(Y6b$^M^B}I#_ZWEkpaGJ~cd7ijW;W_;LbLHc7XLfa}G%j{- zz(w~|Smy5}Ow{s#*>BX@MWqtxTdc(*pE#pIyg%^iML50SK4hEc;+KCZur03$WW z#&=DCke9l&=0gEDrCx%iT=fIZ3mXJ6t8$65+H>$1^g-VPoOVE2h^Xw;x{Ov0&=eGA+zPQV!JM_j)@-$x7F0y{nY(UDE2fkp=S;P)Q5@3?}h zutap56vJ+P$%K&4#?<{`9y~fB%9YgBalilBl9;I7oXXRG9BED!eo%Q0$}(x(fm}b_ zQ6Zp{j{FfgZ@aj_DC%mJRZ{mfl|t_zY1Rl@5|-Yns}av_~MEoVbJ^I%{$?+_FUVRv;9?QE$NPCj@E-5!siCIR#C%)MLO zI!>3KyI%`lpXKQ`%WQs+Vo&tSAApzP3zB$k4iTx1CC4o8VC2Zjtp89c&YNt;GdM=m zx2Ifb(d8SQkL*vuwaI0Wv>q)6m>+HI%Yqqabm@rJIjkgu@5Lyeg}7I}+~!?1oTlpp z6c{z4r9>;*C-|XiVJdz<&Vjme3LR5jj9R;jIN81KV0NYpZ+K0o(ZvH~nL!}yuR6f8 zG-a9djfrdxJtZ9XN|tSXrH)>KGg0NzD3;jqk!v}uMwRZrMdyp=6e|=U`O0xpd9aon zT6BhNbI3yb$4{B4)MfU!)&Wz3X0hvI8_Bs@zBrcV;#R+@+`(mm%*r_f-z)jCNxCL% z^OjoBxjGfgUDWBw|GvOkCofJfU^cCiuEZ;2d@=3cNv>h^8}caf8K+ZNQagMtROPlfk$_woY04=b3Cn`e;v!v82b&v-1~HjdkpGRjsVB1DC7U&kp*WHc!4 zrL>3YpOBE0twCl+LPH^y;=Yc9q@f|A5T$4+?V+LhT+cf%yz%+m?(;m4{d)K(p(`x6aDNOQLf9J!g!vH0)wY;bve3H{vGauMEHpmuJF;CU#bD*>uh zCA>!+ydAOH#fbG6$8f2Cogu1YJr_{(1undphCff-6rYOS4Q}4|#M#9yG;5L*w{68# z^!fEseA52|tT#WzIhanxq!S%N4qTh=kMHK+78_BTg%*3A^9<}4PJ&x@yT!p_Vt)AH zO^_rLN$Do@sMc4F&1qXm`sbgbWRe57%v_E6orvcyc}!t86NjVRzW~bF7A7uQ^9mP* zUFEWCJ3-u72Rf#e(Cs#d;pa36yFVQG*(z+o@=?$z`5%T{Nro$I5@N?}fsHnew@q}X zGS}gxy3UrX`xQ-YviTI+(l0KEyoEG;FezCD+b{N2VA+PVard(W*j^(;vKF_wvwtF> z{O@BJAGMJkKQ)iPvL}OvU?=bS$P?oheFy181K8CO3lkTakm6%oJTvYe_dRVd`zkO2 z;7ul1HS`@yj`t<=d8SZZAIZ!IX|X;(Tkf22PWGwT!P1TuoTQu))BN_5TX%3jhL)M& zEQgPn=U)Tzol9urj|Lj|bSwXGWDRW!`$(UZ$5Pkf300piLY4X`f#=d7VjMP#FNFUA ziCaRS8T78Pd36y#%}+bdb!y523FE_M+;JXtcE&Lf=X=c{7!0_$T!c zqn9^;j!YFNGTVs;O4o4Gfl{uzT${yPcp@)(Q<#Yq@}uij*>A}f{_>P75Td-BTkdzB zZ#`QKKTbYFmG7%j;aLp2`X%6jPHV1ux-1>YD(4%6XJSRcFBrAuE1v9BspRj~Nt27i>B`P$xU zaorVDE~h;ar?f=ljikfqo@H_`}x-98{ zF~xkzqbMUsUP1W)O<49%C%b!K=#94CmqjM&1ERScq^hUADIC)NeYYwZ+Uj>Or zf1vl+B-S{|44tPdvmCWUP>_zG8<%cBG-nu_k{Sz&*X!`qZ$lRQ?;MTv0?Wf(TwWZVn;oKgpae)-9gN?{5lPF`7dF;lsc2>DTT{dRN1c^$$0hXRbw7Hu$S*a?Ybmt7+F_A_y6>R%iItLPY;uK{M$&lq`;gY=bcrxON@gb05ksg-xzHDdfl_m2KGx zKLzp5FTEI4bCEr4t6(xx_aLZT*CEBH^CMl4U@QeMd7B|lxP zPW{G5J(&chW_chv!=GtcNVD7@WniS3B|fl00=-+ZU`$^&v(5MpNz)qPYkB}{^{~d( zja#sCl)#$RiWiyZkHs+0zqodc8~Z-hmIBS2Kq)4csW{n^&(y`JYnMxAAy;Tu%wTqL zBjeN=WR)@Gcr;oo$X{eV{z#gf{qOo`YIiK#r zL)Q{%OG+_~8nA(KEY?(A9m!SI{(Xa!1y0Xpty<14`aKHw=dFQ=o3_m6VJ7cC`5jJps|A~FFR*{3 zSBXw*4x;#DvaEAiEe<U76@H!Qu8!zHil6}=3UfXM$6`NJzuFjd`SR@){Pi47=N_^0&p-L`=PW7KZ4|s+(?{`oQ^|RM8@{MNLDMbWX=IoY z1S-yfxmmxs#83N#e9=_WE?pvOa7*Mr4!?ri+zR;o=aXoK(pH+o_ESJlC);4Ojy*o` z8o#en6SADMA#%%J)|%kN4la#?gOW>NN6Sjq{NG?29#Tv(O;}9zX%i{d_^^ae zj9Yl_2wwcXhW5qy!OY7&yZ~RJN!fB_Wqgtf^nX>J6pf-9|JNeJ?@uu=XEodoQi9AP z1C+86_+rJq{M}Dev3p$yc6udq-rM(Lf|LxYh8(8}R(e=^tsQb+WznA6i!f02G3S3g z2PYRsvEZf0piSclRePng7gE_+J-UMa2DHQc{zBN;)P{q6C&D1hZD{-WE5E-`A6Der zi2sJT!iUp8`N0vDFn7^p{?Hz6wsgfoSn=W$bkscOO&5=6sh8hCpT{vM^~qq(H%H>p zU&ieHbx+n+62qz!2eKPEyI8E+9yY*Z7L(9SV&nRsvNPfboJ-hwme!z0o`c%Bz@j~1 zua}8`{{F)WitFv4k6i_yE&vSsq(UX3QS_`}4{Unlk6}Xx!nTnwxswOZ@NwO;+ z5(E$MVlIp=kq~lF4;7g1=@rcRQ406zSug4ej z#fphs+jd7*^`sPE51q@j0*oA{n!B*~HHHqAm*+9@Yk3xY$Ie00b&x~eZUcP2BOEO+ zP33p~5IBXSE{TH7H{r--W9e!~7P|d-!_O$s<~CWnvhs;DsqRHC<=cqFhOzOuX~;p6 zdoYi!J7CGOoKtw8jXaZ2dndjvA-Kfieb~(!2{grX;Qr_iw|96eW<&`O#iAatUAI@9 zGsYM$_nrd@*@-NBiYxDPK3o(#stT6R68cF~%fZ3z)WzlngPGy#N&LDcv#HBxD=Y~R zxK7g2beYM6UXB;oj*N#7o0eh6PZb=u(p+2?ssUdAx^c@8Wf*Z(=&OwNVTtie$Ys(D zT65zLb_7Xa-TgRTY~sX*L|lT4?Z%L3H;95-H0k(Nb1X~eX_qN-)}xouaP23Uy`U0K z8gD^vK3r4IL^O1Y9P+?6v+#36{GFvT{B4!N%1;1>#k$aFYgn`sPD^_&vZ5llf z5`5z%_^Gr#__Ky(T;r8{+?c6atmf=9e*4*C?#sOnxX354uek-(-aZK?6jXxo1mXNU z*Tr%3K~!6^luhz` zD;_s)81^dW@u8;jsQ$zSw$%;ByVrN|T#paLJ`m2+)O4noBF~&hdf*HF6Er08IhS>; zna}wsFqG@YKz;HKe)wb$j8ZDbz?F+wLhfF6b-Ol8t@UDc6JIf3t$(mU;~%LNb7GJ@HUO#$>g&Kbn%vhCB4!RXi1*~+=m;I%gwHMFO*HNT8u zg6m{VuJ{0|YtD#*ub∈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 +#include +#include +#endif + + +#ifdef CV_CXX11 +template +class QueueFPS : public std::queue +{ +public: + QueueFPS() : counter(0) {} + + void push(const T& entry) + { + std::lock_guard lock(mutex); + + std::queue::push(entry); + counter += 1; + if (counter == 1) + { + // Start counting from a second frame (warmup). + tm.reset(); + tm.start(); + } + } + + T get() + { + std::lock_guard lock(mutex); + T entry = this->front(); + this->pop(); + return entry; + } + + float getFPS() + { + tm.stop(); + double fps = counter / tm.getTimeSec(); + tm.start(); + return static_cast(fps); + } + + void clear() + { + std::lock_guard lock(mutex); + while (!this->empty()) + this->pop(); + } + + unsigned int counter; + +private: + cv::TickMeter tm; + std::mutex mutex; +}; + +template +class Queue : public std::queue +{ +public: + Queue(){} + + void push(const T& entry) + { + std::lock_guard lock(mutex); + std::queue::push(entry); + + } + + T get() + { + std::lock_guard lock(mutex); + T entry = this->front(); + this->pop(); + return entry; + } + + void clear() + { + std::lock_guard lock(mutex); + while (!this->empty()) + this->pop(); + } + +private: + + std::mutex mutex; +}; +#endif // CV_CXX11 + +int main() +{ + + string model_path = "./models"; + FaceTracking faceTrack(model_path); + cv::Mat frame; + cv::VideoCapture cap(0); + if (!cap.isOpened()) + { + return -1; + } + + int frameIndex = 0; + vector IDs; + vector Colors; + cv::Scalar color; + srand((unsigned int)time(0));//��ʼ������Ϊ���ֵ + Queue framesQueue; + std::vector faces; + +#ifdef CV_CXX11 + bool process = true; + + Queue > predictionsQueue; + std::thread processingThread([&]() { + //std::queue futureOutputs; + cv::Mat blob; + for (;process;) + { + // Get a next frame + cv::Mat frame; + { + if (!framesQueue.empty()) + { + frame = framesQueue.get(); + framesQueue.clear(); // Skip the rest of frames + } + } + + // Process the frame + if (!frame.empty()) + { + double t1 = (double)cv::getTickCount(); + if (frameIndex == 0) + { + faceTrack.Init(frame); + frameIndex = 1; + } + else { + faceTrack.update(frame); + } + printf("total %gms\n", ((double)cv::getTickCount() - t1) * 1000 / cv::getTickFrequency()); + printf("------------------\n"); + //Sleep(200); + predictionsQueue.push(faceTrack.trackingFace); + } + + + } + }); + for (;;) { + + if (!cap.read(frame)) + { + break; + } + + //cv::transpose(frame, frame); + //cv::flip(frame, frame, -1); + //cv::flip(frame, frame, 1); + + framesQueue.push(frame.clone()); + + if (!predictionsQueue.empty()) + { + + faces.clear(); + faces = predictionsQueue.get(); + + + + for (int i = 0; i < faces.size(); i++) + { + const Face &info = faces[i]; + cv::Rect rect; + rect.x = info.faceBbox.x1; + rect.y = info.faceBbox.y1; + rect.width = info.faceBbox.x2 - info.faceBbox.x1; + rect.height = info.faceBbox.y2 - info.faceBbox.y1; + + bool isExist = false; + for (int j = 0; j < IDs.size(); j++) + { + if (IDs[j] == info.face_id) + { + color = Colors[j]; + isExist = true; + break; + } + } + + if (!isExist) + { + IDs.push_back(info.face_id); + int r = rand() % 255 + 1; + int g = rand() % 255 + 1; + int b = rand() % 255 + 1; + color = cv::Scalar(r, g, b); + Colors.push_back(color); + } + + cv::rectangle(frame, rect, color, 2); + cv::putText(frame,to_string(info.face_id),Point(rect.x,rect.y-20),FONT_HERSHEY_SIMPLEX,2,Scalar(0,0,255),1,8,false); + for (int j = 0; j < 5; j++) + { + cv::Point p = cv::Point(info.faceBbox.ppoint[j], info.faceBbox.ppoint[j + 5]); + cv::circle(frame, p, 2, color,2); + } + } + + } + + + imshow("frame", frame); + + int q = cv::waitKey(30); + if (q == 27) break; + } + + process = false; + processingThread.join(); + +#else // CV_CXX11 + for (;;) { + if (!cap.read(frame)) + { + break; + } + int q = cv::waitKey(1); + if (q == 27) break; + + + //cv::transpose(frame, frame); + //cv::flip(frame, frame, -1); + //cv::flip(frame, frame, 1); + double t1 = (double)cv::getTickCount(); + + if (frameIndex == 0) + { + faceTrack.Init(frame); + frameIndex = 1; + } + else { + faceTrack.update(frame); + } + printf("total %gms\n", ((double)cv::getTickCount() - t1) * 1000 / cv::getTickFrequency()); + printf("------------------\n"); + + std::vector faceActions = faceTrack.trackingFace; + for (int i = 0; i < faceActions.size(); i++) + { + const Face &info = faceActions[i]; + cv::Rect rect; + rect.x = info.faceBbox.x1; + rect.y = info.faceBbox.y1; + rect.width = info.faceBbox.x2 - info.faceBbox.x1; + rect.height = info.faceBbox.y2 - info.faceBbox.y1; + + bool isExist = false; + for (int j = 0; j < IDs.size(); j++) + { + if (IDs[j] == info.face_id) + { + color = Colors[j]; + isExist = true; + break; + } + } + + if (!isExist) + { + IDs.push_back(info.face_id); + int r = rand() % 255 + 1; + int g = rand() % 255 + 1; + int b = rand() % 255 + 1; + color = cv::Scalar(r, g, b); + Colors.push_back(color); + } + + rectangle(frame, rect, color, 2); + for (int j = 0; j < 5; j++) + { + cv::Point p = cv::Point(info.faceBbox.ppoint[j], info.faceBbox.ppoint[j + 5]); + cv::circle(frame, p, 2, color, 2); + } + } + imshow("frame", frame); + } +#endif // CV_CXX11 + IDs.clear(); + Colors.clear(); + cap.release(); + cv::destroyAllWindows(); + return 0; +} \ No newline at end of file diff --git a/Prj-Linux/mtcnn.cpp b/Prj-Linux/mtcnn.cpp new file mode 100755 index 0000000..73b1761 --- /dev/null +++ b/Prj-Linux/mtcnn.cpp @@ -0,0 +1,561 @@ +#include +#include "mtcnn.h" + +bool cmpScore(Bbox lsh, Bbox rsh) { + if (lsh.score < rsh.score) + return true; + else + return false; +} + +bool cmpArea(Bbox lsh, Bbox rsh) { + if (lsh.area < rsh.area) + return false; + else + return true; +} + +//MTCNN::MTCNN(){} +MTCNN::MTCNN(const string &model_path) { + + vector param_files = { + model_path+"/det1.param", + model_path+"/det2.param", + model_path+"/det3.param" + }; + + vector bin_files = { + model_path+"/det1.bin", + model_path+"/det2.bin", + model_path+"/det3.bin" + }; + + Pnet.load_param(param_files[0].data()); + Pnet.load_model(bin_files[0].data()); + Rnet.load_param(param_files[1].data()); + Rnet.load_model(bin_files[1].data()); + Onet.load_param(param_files[2].data()); + Onet.load_model(bin_files[2].data()); +} + +MTCNN::MTCNN(const vector param_files, const vector bin_files){ + Pnet.load_param(param_files[0].data()); + Pnet.load_model(bin_files[0].data()); + Rnet.load_param(param_files[1].data()); + Rnet.load_model(bin_files[1].data()); + Onet.load_param(param_files[2].data()); + Onet.load_model(bin_files[2].data()); +} + + +MTCNN::~MTCNN(){ + Pnet.clear(); + Rnet.clear(); + Onet.clear(); +} +void MTCNN::SetMinFace(int minSize){ + minsize = minSize; +} +void MTCNN::generateBbox(ncnn::Mat score, ncnn::Mat location, vector& boundingBox_, float scale){ + const int stride = 2; + const int cellsize = 12; + //score p + float *p = score.channel(1);//score.data + score.cstep; + //float *plocal = location.data; + Bbox bbox; + float inv_scale = 1.0f/scale; + for(int row=0;rowthreshold[0]){ + bbox.score = *p; + bbox.x1 = round((stride*col+1)*inv_scale); + bbox.y1 = round((stride*row+1)*inv_scale); + bbox.x2 = round((stride*col+1+cellsize)*inv_scale); + bbox.y2 = round((stride*row+1+cellsize)*inv_scale); + bbox.area = (bbox.x2 - bbox.x1) * (bbox.y2 - bbox.y1); + const int index = row * score.w + col; + for(int channel=0;channel<4;channel++){ + bbox.regreCoord[channel]=location.channel(channel)[index]; + } + boundingBox_.push_back(bbox); + } + p++; + //plocal++; + } + } +} + +void MTCNN::nmsTwoBoxs(vector& boundingBox_, vector& previousBox_, const float overlap_threshold, string modelname) +{ + if (boundingBox_.empty()) { + return; + } + sort(boundingBox_.begin(), boundingBox_.end(), cmpScore); + float IOU = 0; + float maxX = 0; + float maxY = 0; + float minX = 0; + float minY = 0; + //cout << boundingBox_.size() << " "; + for (vector::iterator ity = previousBox_.begin(); ity != previousBox_.end(); ity++) { + for (vector::iterator itx = boundingBox_.begin(); itx != boundingBox_.end();) { + int i = itx - boundingBox_.begin(); + int j = ity - previousBox_.begin(); + maxX = max(boundingBox_.at(i).x1, previousBox_.at(j).x1); + maxY = max(boundingBox_.at(i).y1, previousBox_.at(j).y1); + minX = min(boundingBox_.at(i).x2, previousBox_.at(j).x2); + minY = min(boundingBox_.at(i).y2, previousBox_.at(j).y2); + //maxX1 and maxY1 reuse + maxX = ((minX - maxX + 1)>0) ? (minX - maxX + 1) : 0; + maxY = ((minY - maxY + 1)>0) ? (minY - maxY + 1) : 0; + //IOU reuse for the area of two bbox + IOU = maxX * maxY; + if (!modelname.compare("Union")) + IOU = IOU / (boundingBox_.at(i).area + previousBox_.at(j).area - IOU); + else if (!modelname.compare("Min")) { + IOU = IOU / ((boundingBox_.at(i).area < previousBox_.at(j).area) ? boundingBox_.at(i).area : previousBox_.at(j).area); + } + if (IOU > overlap_threshold&&boundingBox_.at(i).score>previousBox_.at(j).score) { + //if (IOU > overlap_threshold) { + itx = boundingBox_.erase(itx); + } + else { + itx++; + } + } + } + //cout << boundingBox_.size() << endl; +} + +void MTCNN::nms(vector &boundingBox_, const float overlap_threshold, string modelname){ + if(boundingBox_.empty()){ + return; + } + sort(boundingBox_.begin(), boundingBox_.end(), cmpScore); + float IOU = 0; + float maxX = 0; + float maxY = 0; + float minX = 0; + float minY = 0; + vector vPick; + int nPick = 0; + multimap vScores; + const int num_boxes = boundingBox_.size(); + vPick.resize(num_boxes); + for (int i = 0; i < num_boxes; ++i){ + vScores.insert(pair(boundingBox_[i].score, i)); + } + while(vScores.size() > 0){ + int last = vScores.rbegin()->second; + vPick[nPick] = last; + nPick += 1; + for (multimap::iterator it = vScores.begin(); it != vScores.end();){ + int it_idx = it->second; + maxX = max(boundingBox_.at(it_idx).x1, boundingBox_.at(last).x1); + maxY = max(boundingBox_.at(it_idx).y1, boundingBox_.at(last).y1); + minX = min(boundingBox_.at(it_idx).x2, boundingBox_.at(last).x2); + minY = min(boundingBox_.at(it_idx).y2, boundingBox_.at(last).y2); + //maxX1 and maxY1 reuse + maxX = ((minX-maxX+1)>0)? (minX-maxX+1) : 0; + maxY = ((minY-maxY+1)>0)? (minY-maxY+1) : 0; + //IOU reuse for the area of two bbox + IOU = maxX * maxY; + if(!modelname.compare("Union")) + IOU = IOU/(boundingBox_.at(it_idx).area + boundingBox_.at(last).area - IOU); + else if(!modelname.compare("Min")){ + IOU = IOU/((boundingBox_.at(it_idx).area < boundingBox_.at(last).area)? boundingBox_.at(it_idx).area : boundingBox_.at(last).area); + } + if(IOU > overlap_threshold){ + it = vScores.erase(it); + }else{ + it++; + } + } + } + + vPick.resize(nPick); + vector tmp_; + tmp_.resize(nPick); + for(int i = 0; i < nPick; i++){ + tmp_[i] = boundingBox_[vPick[i]]; + } + boundingBox_ = tmp_; +} +void MTCNN::refine(vector &vecBbox, const int &height, const int &width, bool square){ + if(vecBbox.empty()){ + cout<<"Bbox is empty!!"<::iterator it=vecBbox.begin(); it!=vecBbox.end();it++){ + bbw = (*it).x2 - (*it).x1 + 1; + bbh = (*it).y2 - (*it).y1 + 1; + x1 = (*it).x1 + (*it).regreCoord[0]*bbw; + y1 = (*it).y1 + (*it).regreCoord[1]*bbh; + x2 = (*it).x2 + (*it).regreCoord[2]*bbw; + y2 = (*it).y2 + (*it).regreCoord[3]*bbh; + + + + if(square){ + w = x2 - x1 + 1; + h = y2 - y1 + 1; + maxSide = (h>w)?h:w; + x1 = x1 + w*0.5 - maxSide*0.5; + y1 = y1 + h*0.5 - maxSide*0.5; + (*it).x2 = round(x1 + maxSide - 1); + (*it).y2 = round(y1 + maxSide - 1); + (*it).x1 = round(x1); + (*it).y1 = round(y1); + } + + //boundary check + if((*it).x1<0)(*it).x1=0; + if((*it).y1<0)(*it).y1=0; + if((*it).x2>width)(*it).x2 = width - 1; + if((*it).y2>height)(*it).y2 = height - 1; + + it->area = (it->x2 - it->x1)*(it->y2 - it->y1); + } +} + +void MTCNN::extractMaxFace(vector& boundingBox_) +{ + if (boundingBox_.empty()) { + return; + } + sort(boundingBox_.begin(), boundingBox_.end(), cmpArea); + for (vector::iterator itx = boundingBox_.begin() + 1; itx != boundingBox_.end();) { + itx = boundingBox_.erase(itx); + } +} + +void MTCNN::PNet(float scale) +{ + //first stage + int hs = (int)ceil(img_h*scale); + int ws = (int)ceil(img_w*scale); + ncnn::Mat in; + resize_bilinear(img, in, ws, hs); + ncnn::Extractor ex = Pnet.create_extractor(); + ex.set_light_mode(true); + //sex.set_num_threads(4); + ex.input("data", in); + ncnn::Mat score_, location_; + ex.extract("prob1", score_); + ex.extract("conv4-2", location_); + vector boundingBox_; + + generateBbox(score_, location_, boundingBox_, scale); + nms(boundingBox_, nms_threshold[0]); + + firstBbox_.insert(firstBbox_.end(), boundingBox_.begin(), boundingBox_.end()); + boundingBox_.clear(); +} + +void MTCNN::PNet(){ + firstBbox_.clear(); + float minl = img_w < img_h? img_w: img_h; + float m = (float)MIN_DET_SIZE/minsize; + minl *= m; + float factor = pre_facetor; + vector scales_; + while(minl>MIN_DET_SIZE){ + scales_.push_back(m); + minl *= factor; + m = m*factor; + } + for (size_t i = 0; i < scales_.size(); i++) { + int hs = (int)ceil(img_h*scales_[i]); + int ws = (int)ceil(img_w*scales_[i]); + ncnn::Mat in; + resize_bilinear(img, in, ws, hs); + ncnn::Extractor ex = Pnet.create_extractor(); + //ex.set_num_threads(2); + ex.set_light_mode(true); + ex.input("data", in); + ncnn::Mat score_, location_; + ex.extract("prob1", score_); + ex.extract("conv4-2", location_); + vector boundingBox_; + generateBbox(score_, location_, boundingBox_, scales_[i]); + nms(boundingBox_, nms_threshold[0]); + firstBbox_.insert(firstBbox_.end(), boundingBox_.begin(), boundingBox_.end()); + boundingBox_.clear(); + } +} +void MTCNN::RNet(){ + secondBbox_.clear(); + int count = 0; + for(vector::iterator it=firstBbox_.begin(); it!=firstBbox_.end();it++){ + ncnn::Mat tempIm; + copy_cut_border(img, tempIm, (*it).y1, img_h-(*it).y2, (*it).x1, img_w-(*it).x2); + ncnn::Mat in; + resize_bilinear(tempIm, in, 24, 24); + ncnn::Extractor ex = Rnet.create_extractor(); + //ex.set_num_threads(2); + ex.set_light_mode(true); + ex.input("data", in); + ncnn::Mat score, bbox; + ex.extract("prob1", score); + ex.extract("conv5-2", bbox); + if ((float)score[1] > threshold[1]) { + for (int channel = 0; channel<4; channel++) { + it->regreCoord[channel] = (float)bbox[channel];//*(bbox.data+channel*bbox.cstep); + } + it->area = (it->x2 - it->x1)*(it->y2 - it->y1); + it->score = score.channel(1)[0];//*(score.data+score.cstep); + secondBbox_.push_back(*it); + } + } +} + + +float MTCNN::rnet(ncnn::Mat& img) { + + ncnn::Extractor ex = Rnet.create_extractor(); + const float mean_vals[3] = { 127.5f, 127.5f, 127.5f }; + const float norm_vals[3] = { 1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5 }; + img.substract_mean_normalize(mean_vals, norm_vals); + ex.set_light_mode(true); + ex.input("data", img); + ncnn::Mat score; + ex.extract("prob1", score); + return (float)score[1]; +} + + +void MTCNN::ONet(){ + thirdBbox_.clear(); + for(vector::iterator it=secondBbox_.begin(); it!=secondBbox_.end();it++){ + ncnn::Mat tempIm; + copy_cut_border(img, tempIm, (*it).y1, img_h-(*it).y2, (*it).x1, img_w-(*it).x2); + ncnn::Mat in; + resize_bilinear(tempIm, in, 48, 48); + ncnn::Extractor ex = Onet.create_extractor(); + //ex.set_num_threads(2); + ex.set_light_mode(true); + ex.input("data", in); + ncnn::Mat score, bbox, keyPoint; + ex.extract("prob1", score); + ex.extract("conv6-2", bbox); + ex.extract("conv6-3", keyPoint); + if ((float)score[1] > threshold[2]) { + for (int channel = 0; channel < 4; channel++) { + it->regreCoord[channel] = (float)bbox[channel]; + } + it->area = (it->x2 - it->x1) * (it->y2 - it->y1); + it->score = score.channel(1)[0]; + for (int num = 0; num<5; num++) { + (it->ppoint)[num] = it->x1 + (it->x2 - it->x1) * keyPoint[num]; + (it->ppoint)[num + 5] = it->y1 + (it->y2 - it->y1) * keyPoint[num + 5]; + } + + thirdBbox_.push_back(*it); + } + } +} + +Bbox MTCNN::onet(ncnn::Mat& img, int x, int y, int w, int h) { + + Bbox faceBbox; + const float mean_vals[3] = { 127.5f, 127.5f, 127.5f }; + const float norm_vals[3] = { 1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5 }; + img.substract_mean_normalize(mean_vals, norm_vals); + ncnn::Extractor ex = Onet.create_extractor(); + + ex.set_light_mode(true); + ex.input("data", img); + ncnn::Mat score, bbox, keyPoint; + ex.extract("prob1", score); + ex.extract("conv6-2", bbox); + ex.extract("conv6-3", keyPoint); + faceBbox.score = score.channel(1)[0]; + faceBbox.x1 = static_cast(bbox[0] * w) + x; + faceBbox.y1 = static_cast(bbox[1] * h) + y; + faceBbox.x2 = static_cast(bbox[2] * w) + h + x; + faceBbox.y2 = static_cast(bbox[3] * h) + h + y; + for (int num = 0; num<5; num++) { + (faceBbox.ppoint)[num] = x + w * keyPoint[num]; + (faceBbox.ppoint)[num + 5] = y + h * keyPoint[num + 5]; + } + + return faceBbox; + +} + + +void MTCNN::detect(ncnn::Mat& img_, vector& finalBbox_){ + img = img_; + img_w = img.w; + img_h = img.h; + img.substract_mean_normalize(mean_vals, norm_vals); + + PNet(); + //the first stage's nms + if(firstBbox_.size() < 1) return; + nms(firstBbox_, nms_threshold[0]); + refine(firstBbox_, img_h, img_w, true); + //printf("firstBbox_.size()=%d\n", firstBbox_.size()); + + + //second stage + RNet(); + //printf("secondBbox_.size()=%d\n", secondBbox_.size()); + if(secondBbox_.size() < 1) return; + nms(secondBbox_, nms_threshold[1]); + refine(secondBbox_, img_h, img_w, true); + + //third stage + ONet(); + //printf("thirdBbox_.size()=%d\n", thirdBbox_.size()); + if(thirdBbox_.size() < 1) return; + refine(thirdBbox_, img_h, img_w, true); + nms(thirdBbox_, nms_threshold[2], "Min"); + finalBbox_ = thirdBbox_; + if (smooth) + SmoothBbox(finalBbox_); +} + + +void MTCNN::detectMaxFace(ncnn::Mat& img_, vector& finalBbox) { + firstPreviousBbox_.clear(); + secondPreviousBbox_.clear(); + thirdPrevioussBbox_.clear(); + firstBbox_.clear(); + secondBbox_.clear(); + thirdBbox_.clear(); + + //norm + img = img_; + img_w = img.w; + img_h = img.h; + img.substract_mean_normalize(mean_vals, norm_vals); + + //pyramid size + float minl = img_w < img_h ? img_w : img_h; + float m = (float)MIN_DET_SIZE / minsize; + minl *= m; + float factor = pre_facetor; + vector scales_; + while (minl>MIN_DET_SIZE) { + scales_.push_back(m); + minl *= factor; + m = m*factor; + } + sort(scales_.begin(), scales_.end()); + //printf("scales_.size()=%d\n", scales_.size()); + + //Change the sampling process. + for (size_t i = 0; i < scales_.size(); i++) + { + //first stage + PNet(scales_[i]); + nms(firstBbox_, nms_threshold[0]); + nmsTwoBoxs(firstBbox_, firstPreviousBbox_, nms_threshold[0]); + if (firstBbox_.size() < 1) { + firstBbox_.clear(); + continue; + } + firstPreviousBbox_.insert(firstPreviousBbox_.end(), firstBbox_.begin(), firstBbox_.end()); + refine(firstBbox_, img_h, img_w, true); + //printf("firstBbox_.size()=%d\n", firstBbox_.size()); + + //second stage + RNet(); + nms(secondBbox_, nms_threshold[1]); + nmsTwoBoxs(secondBbox_, secondPreviousBbox_, nms_threshold[0]); + secondPreviousBbox_.insert(secondPreviousBbox_.end(), secondBbox_.begin(), secondBbox_.end()); + if (secondBbox_.size() < 1) { + firstBbox_.clear(); + secondBbox_.clear(); + continue; + } + refine(secondBbox_, img_h, img_w, true); + + //third stage + ONet(); + + if (thirdBbox_.size() < 1) { + firstBbox_.clear(); + secondBbox_.clear(); + thirdBbox_.clear(); + continue; + } + refine(thirdBbox_, img_h, img_w, true); + nms(thirdBbox_, nms_threshold[2], "Min"); + + if (thirdBbox_.size() > 0) { + extractMaxFace(thirdBbox_); + finalBbox = thirdBbox_;//if largest face size is similar,. + if (smooth) + SmoothBbox(finalBbox); + break; + } + } + +} + +float MTCNN::iou(Bbox & b1, Bbox & b2, string modelname) +{ + float IOU = 0; + float maxX = 0; + float maxY = 0; + float minX = 0; + float minY = 0; + maxX = max(b1.x1, b2.x1); + maxY = max(b1.y1, b2.y1); + minX = min(b1.x2, b2.x2); + minY = min(b1.y2, b2.y2); + //maxX1 and maxY1 reuse + maxX = ((minX - maxX + 1)>0) ? (minX - maxX + 1) : 0; + maxY = ((minY - maxY + 1)>0) ? (minY - maxY + 1) : 0; + IOU = maxX * maxY; + + if (!modelname.compare("Union")) + IOU = IOU / (b1.area + b2.area - IOU); + else if (!modelname.compare("Min")) { + IOU = IOU / ((b1.area < b2.area) ? b1.area : b2.area); + } + return IOU; +} + +void MTCNN::SmoothBbox(std::vector& finalBbox) +{ + static std::vector preBbox_; + for (int i = 0; i < finalBbox.size(); i++) { + for (int j = 0; j < preBbox_.size(); j++) { + if (iou(finalBbox[i], preBbox_[j]) > 0.90) + { + finalBbox[i] = preBbox_[j]; + } + else if (iou(finalBbox[i], preBbox_[j]) > 0.6) { + finalBbox[i].x1 = (finalBbox[i].x1 + preBbox_[j].x1) / 2; + finalBbox[i].y1 = (finalBbox[i].y1 + preBbox_[j].y1) / 2; + finalBbox[i].x2 = (finalBbox[i].x2 + preBbox_[j].x2) / 2; + finalBbox[i].y2 = (finalBbox[i].y2 + preBbox_[j].y2) / 2; + //finalBbox[i].area = (finalBbox[i].x2 - finalBbox[i].x1)*(finalBbox[i].y2 - finalBbox[i].y1); + for (int k = 0; k < 10; k++) + { + finalBbox[i].ppoint[k] = (finalBbox[i].ppoint[k] + preBbox_[j].ppoint[k]) / 2; + } + } + } + } + preBbox_ = finalBbox; + +} + + +//void MTCNN::detection(const cv::Mat& img, vector& rectangles){ +// ncnn::Mat ncnn_img = ncnn::Mat::from_pixels(img.data, ncnn::Mat::PIXEL_BGR2RGB, img.cols, img.rows); +// vector finalBbox; +// detect(ncnn_img, finalBbox); +// const int num_box = finalBbox.size(); +// rectangles.resize(num_box); +// for(int i = 0; i < num_box; i++){ +// rectangles[i] = cv::Rect(finalBbox[i].x1, finalBbox[i].y1, finalBbox[i].x2 - finalBbox[i].x1 + 1, finalBbox[i].y2 - finalBbox[i].y1 + 1); +// } +//} diff --git a/Prj-Linux/mtcnn.h b/Prj-Linux/mtcnn.h new file mode 100755 index 0000000..9cd2043 --- /dev/null +++ b/Prj-Linux/mtcnn.h @@ -0,0 +1,99 @@ +#ifndef __MTCNN_NCNN_H__ +#define __MTCNN_NCNN_H__ +#include "net.h" + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +struct Bbox +{ + float score; + int x1; + int y1; + int x2; + int y2; + float area; + float ppoint[10]; + float regreCoord[4]; +}; + +namespace Shape { + + template class Rect { + public: + Rect() {} + Rect(T x, T y, T w, T h) { + this->x = x; + this->y = y; + this->width = w; + height = h; + + } + T x; + T y; + T width; + T height; + + cv::Rect convert_cv_rect(int _height, int _width) + { + cv::Rect Rect_(static_cast(x*_width), static_cast(y*_height), + static_cast(width*_width), static_cast(height*_height)); + return Rect_; + } + }; +} + +class MTCNN { + +public: + MTCNN(const string &model_path); + MTCNN(const std::vector param_files, const std::vector bin_files); + ~MTCNN(); + + void SetMinFace(int minSize); + void detect(ncnn::Mat& img_, std::vector& finalBbox); + void detectMaxFace(ncnn::Mat& img_, std::vector& finalBbox); + float rnet(ncnn::Mat& img); + Bbox onet(ncnn::Mat& img,int x, int y,int w,int h); + ncnn::Net Pnet, Rnet, Onet; + + + //void detection(const cv::Mat& img, std::vector& rectangles); +private: + void generateBbox(ncnn::Mat score, ncnn::Mat location, vector& boundingBox_, float scale); + void nmsTwoBoxs(vector &boundingBox_, vector &previousBox_, const float overlap_threshold, string modelname = "Union"); + void nms(vector &boundingBox_, const float overlap_threshold, string modelname = "Union"); + void refine(vector &vecBbox, const int &height, const int &width, bool square); + void extractMaxFace(vector &boundingBox_); + float iou(Bbox & b1, Bbox & b2, string modelname = "Union"); + void SmoothBbox(std::vector& winList); + void PNet(float scale); + void PNet(); + void RNet(); + void ONet(); + + ncnn::Mat img; + + const float nms_threshold[3] = { 0.5f, 0.7f, 0.7f }; + const float mean_vals[3] = { 127.5, 127.5, 127.5 }; + const float norm_vals[3] = { 0.0078125, 0.0078125, 0.0078125 }; + const int MIN_DET_SIZE = 12; + std::vector firstPreviousBbox_, secondPreviousBbox_, thirdPrevioussBbox_; + std::vector firstBbox_, secondBbox_, thirdBbox_; + int img_w, img_h; + +private: + const float threshold[3] = { 0.8f, 0.8f, 0.9f }; + int minsize = 30; + const float pre_facetor = 0.7090f; + bool smooth = true;//ȶ +}; + + +#endif //__MTCNN_NCNN_H__ diff --git a/Prj-Win/.gitignore b/Prj-Win/.gitignore new file mode 100755 index 0000000..c870a29 --- /dev/null +++ b/Prj-Win/.gitignore @@ -0,0 +1,36 @@ +Release + +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch +*.opendb +*.db + +# Compiled Dynamic libraries +*.so +*.dylib +!*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +!*.lib + +# Executables +!*.exe +*.out +*.app diff --git a/Prj-Win/3rd/ncnn/include/allocator.h b/Prj-Win/3rd/ncnn/include/allocator.h new file mode 100755 index 0000000..61a03c7 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/allocator.h @@ -0,0 +1,355 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_ALLOCATOR_H +#define NCNN_ALLOCATOR_H + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else +#include +#endif + +#include +#include +#include +#include "platform.h" + +#if NCNN_VULKAN +#include +#include "gpu.h" +#endif // NCNN_VULKAN + +namespace ncnn { + +// the alignment of all the allocated buffers +#define MALLOC_ALIGN 16 + +// Aligns a pointer to the specified number of bytes +// ptr Aligned pointer +// n Alignment size that must be a power of two +template static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp)) +{ + return (_Tp*)(((size_t)ptr + n-1) & -n); +} + +// Aligns a buffer size to the specified number of bytes +// The function returns the minimum number that is greater or equal to sz and is divisible by n +// sz Buffer size to align +// n Alignment size that must be a power of two +static inline size_t alignSize(size_t sz, int n) +{ + return (sz + n-1) & -n; +} + +static inline void* fastMalloc(size_t size) +{ + unsigned char* udata = (unsigned char*)malloc(size + sizeof(void*) + MALLOC_ALIGN); + if (!udata) + return 0; + unsigned char** adata = alignPtr((unsigned char**)udata + 1, MALLOC_ALIGN); + adata[-1] = udata; + return adata; +} + +static inline void fastFree(void* ptr) +{ + if (ptr) + { + unsigned char* udata = ((unsigned char**)ptr)[-1]; + free(udata); + } +} + +// exchange-add operation for atomic operations on reference counters +#if defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32) +// atomic increment on the linux version of the Intel(tm) compiler +# define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd(const_cast(reinterpret_cast(addr)), delta) +#elif defined __GNUC__ +# if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__) +# ifdef __ATOMIC_ACQ_REL +# define NCNN_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL) +# else +# define NCNN_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4) +# endif +# else +# if defined __ATOMIC_ACQ_REL && !defined __clang__ +// version for gcc >= 4.7 +# define NCNN_XADD(addr, delta) (int)__atomic_fetch_add((unsigned*)(addr), (unsigned)(delta), __ATOMIC_ACQ_REL) +# else +# define NCNN_XADD(addr, delta) (int)__sync_fetch_and_add((unsigned*)(addr), (unsigned)(delta)) +# endif +# endif +#elif defined _MSC_VER && !defined RC_INVOKED +# include +# define NCNN_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta) +#else +// thread-unsafe branch +static inline int NCNN_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; } +#endif + +#ifdef _WIN32 +class Mutex +{ +public: + Mutex() { InitializeSRWLock(&srwlock); } + ~Mutex() {} + void lock() { AcquireSRWLockExclusive(&srwlock); } + void unlock() { ReleaseSRWLockExclusive(&srwlock); } +private: + // NOTE SRWLock is available from windows vista + SRWLOCK srwlock; +}; +#else // _WIN32 +class Mutex +{ +public: + Mutex() { pthread_mutex_init(&mutex, 0); } + ~Mutex() { pthread_mutex_destroy(&mutex); } + void lock() { pthread_mutex_lock(&mutex); } + void unlock() { pthread_mutex_unlock(&mutex); } +private: + pthread_mutex_t mutex; +}; +#endif // _WIN32 + +class MutexLockGuard +{ +public: + MutexLockGuard(Mutex& _mutex) : mutex(_mutex) { mutex.lock(); } + ~MutexLockGuard() { mutex.unlock(); } +private: + Mutex& mutex; +}; + +class Allocator +{ +public: + virtual ~Allocator() = 0; + virtual void* fastMalloc(size_t size) = 0; + virtual void fastFree(void* ptr) = 0; +}; + +class PoolAllocator : public Allocator +{ +public: + PoolAllocator(); + ~PoolAllocator(); + + // ratio range 0 ~ 1 + // default cr = 0.75 + void set_size_compare_ratio(float scr); + + // release all budgets immediately + void clear(); + + virtual void* fastMalloc(size_t size); + virtual void fastFree(void* ptr); + +private: + Mutex budgets_lock; + Mutex payouts_lock; + unsigned int size_compare_ratio;// 0~256 + std::list< std::pair > budgets; + std::list< std::pair > payouts; +}; + +class UnlockedPoolAllocator : public Allocator +{ +public: + UnlockedPoolAllocator(); + ~UnlockedPoolAllocator(); + + // ratio range 0 ~ 1 + // default cr = 0.75 + void set_size_compare_ratio(float scr); + + // release all budgets immediately + void clear(); + + virtual void* fastMalloc(size_t size); + virtual void fastFree(void* ptr); + +private: + unsigned int size_compare_ratio;// 0~256 + std::list< std::pair > budgets; + std::list< std::pair > payouts; +}; + +#if NCNN_VULKAN + +class VkBufferMemory +{ +public: + VkBuffer buffer; + + // the base offset assigned by allocator + size_t offset; + size_t capacity; + + VkDeviceMemory memory; + void* mapped_ptr; + + // buffer state, modified by command functions internally + // 0=null + // 1=created + // 2=transfer + // 3=compute + // 4=readonly + mutable int state; + + // initialize and modified by mat + int refcount; +}; + +class VkAllocator +{ +public: + VkAllocator(const VulkanDevice* _vkdev); + virtual ~VkAllocator() { clear(); } + virtual void clear() {} + virtual VkBufferMemory* fastMalloc(size_t size) = 0; + virtual void fastFree(VkBufferMemory* ptr) = 0; + +public: + const VulkanDevice* vkdev; + bool mappable; + +protected: + VkBuffer create_buffer(size_t size, VkBufferUsageFlags usage); + VkDeviceMemory allocate_memory(size_t size, uint32_t memory_type_index); + VkDeviceMemory allocate_dedicated_memory(size_t size, uint32_t memory_type_index, VkBuffer buffer); +}; + +class VkUnlockedBlobBufferAllocator : public VkAllocator +{ +public: + VkUnlockedBlobBufferAllocator(const VulkanDevice* vkdev); + virtual ~VkUnlockedBlobBufferAllocator(); + +public: + // buffer block size, default=16M + void set_block_size(size_t size); + + // release all budgets immediately + virtual void clear(); + + virtual VkBufferMemory* fastMalloc(size_t size); + virtual void fastFree(VkBufferMemory* ptr); + +private: + size_t block_size; + size_t buffer_offset_alignment; + std::vector< std::list< std::pair > > budgets; + std::vector buffer_blocks; +}; + +class VkBlobBufferAllocator : public VkUnlockedBlobBufferAllocator +{ +public: + VkBlobBufferAllocator(const VulkanDevice* vkdev); + virtual ~VkBlobBufferAllocator(); + +public: + virtual void clear(); + virtual VkBufferMemory* fastMalloc(size_t size); + virtual void fastFree(VkBufferMemory* ptr); + +private: + Mutex budgets_lock; +}; + +class VkWeightBufferAllocator : public VkAllocator +{ +public: + VkWeightBufferAllocator(const VulkanDevice* vkdev); + virtual ~VkWeightBufferAllocator(); + +public: + // buffer block size, default=8M + void set_block_size(size_t block_size); + + // release all blocks immediately + virtual void clear(); + +public: + virtual VkBufferMemory* fastMalloc(size_t size); + virtual void fastFree(VkBufferMemory* ptr); + +private: + size_t block_size; + size_t buffer_offset_alignment; + std::vector buffer_block_free_spaces; + std::vector buffer_blocks; + std::vector dedicated_buffer_blocks; +}; + +class VkUnlockedStagingBufferAllocator : public VkAllocator +{ +public: + VkUnlockedStagingBufferAllocator(const VulkanDevice* vkdev); + virtual ~VkUnlockedStagingBufferAllocator(); + +public: + // ratio range 0 ~ 1 + // default cr = 0.75 + void set_size_compare_ratio(float scr); + + // release all budgets immediately + virtual void clear(); + + virtual VkBufferMemory* fastMalloc(size_t size); + virtual void fastFree(VkBufferMemory* ptr); + +private: + uint32_t memory_type_index; + unsigned int size_compare_ratio;// 0~256 + std::list budgets; +}; + +class VkStagingBufferAllocator : public VkUnlockedStagingBufferAllocator +{ +public: + VkStagingBufferAllocator(const VulkanDevice* vkdev); + virtual ~VkStagingBufferAllocator(); + +public: + virtual void clear(); + virtual VkBufferMemory* fastMalloc(size_t size); + virtual void fastFree(VkBufferMemory* ptr); + +private: + Mutex budgets_lock; +}; + +class VkWeightStagingBufferAllocator : public VkAllocator +{ +public: + VkWeightStagingBufferAllocator(const VulkanDevice* vkdev); + virtual ~VkWeightStagingBufferAllocator(); + +public: + virtual VkBufferMemory* fastMalloc(size_t size); + virtual void fastFree(VkBufferMemory* ptr); + +private: + uint32_t memory_type_index; +}; + +#endif // NCNN_VULKAN + +} // namespace ncnn + +#endif // NCNN_ALLOCATOR_H diff --git a/Prj-Win/3rd/ncnn/include/benchmark.h b/Prj-Win/3rd/ncnn/include/benchmark.h new file mode 100755 index 0000000..63de7cd --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/benchmark.h @@ -0,0 +1,36 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_BENCHMARK_H +#define NCNN_BENCHMARK_H + +#include "platform.h" +#include "mat.h" +#include "layer.h" + +namespace ncnn { + +// get now timestamp in ms +double get_current_time(); + +#if NCNN_BENCHMARK + +void benchmark(const Layer* layer, double start, double end); +void benchmark(const Layer* layer, const Mat& bottom_blob, Mat& top_blob, double start, double end); + +#endif // NCNN_BENCHMARK + +} // namespace ncnn + +#endif // NCNN_BENCHMARK_H diff --git a/Prj-Win/3rd/ncnn/include/blob.h b/Prj-Win/3rd/ncnn/include/blob.h new file mode 100755 index 0000000..31f2c1d --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/blob.h @@ -0,0 +1,43 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_BLOB_H +#define NCNN_BLOB_H + +#include +#include +#include "platform.h" + +namespace ncnn { + +class Blob +{ +public: + // empty + Blob(); + +public: +#if NCNN_STRING + // blob name + std::string name; +#endif // NCNN_STRING + // layer index which produce this blob as output + int producer; + // layer index which need this blob as input + std::vector consumers; +}; + +} // namespace ncnn + +#endif // NCNN_BLOB_H diff --git a/Prj-Win/3rd/ncnn/include/command.h b/Prj-Win/3rd/ncnn/include/command.h new file mode 100755 index 0000000..d6cdcb0 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/command.h @@ -0,0 +1,190 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_COMMAND_H +#define NCNN_COMMAND_H + +#include "platform.h" + +#if NCNN_VULKAN + +#include +#include +#include "mat.h" +#include "pipeline.h" + +namespace ncnn { + +class Command +{ +public: + Command(const VulkanDevice* vkdev, uint32_t queue_index); + ~Command(); + +protected: + int create_command_pool(); + int create_command_buffer(); + + // record issue + int begin_command_buffer(); + int end_command_buffer(); + int queue_submit(); + int wait_fence(); + +protected: + const VulkanDevice* vkdev; + uint32_t queue_index; + + VkQueue queue; + + VkCommandPool command_pool; + VkCommandBuffer command_buffer; + + VkFence fence; +}; + +class VkCompute : public Command +{ +public: + VkCompute(const VulkanDevice* vkdev); + ~VkCompute(); + + void record_upload(const VkMat& m); + + void record_download(const VkMat& m); + + void record_clone(const VkMat& src, const VkMat& dst); + + void record_copy_region(const VkMat& src, const VkMat& dst, const VkBufferCopy& region); + + void record_copy_regions(const VkMat& src, const VkMat& dst, const std::vector& regions); + + void record_pipeline(const Pipeline* pipeline, const std::vector& bindings, const std::vector& constants, const VkMat& m); + + int submit(); + + int wait(); + + int reset(); + +protected: + // record pipeline things + void record_bind_pipeline(VkPipeline pipeline); + void record_update_bindings(VkPipelineLayout pipeline_layout, VkDescriptorSetLayout descriptorset_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const std::vector& bindings); + void record_push_constants(VkPipelineLayout pipeline_layout, const std::vector& constants); + void record_dispatch(const uint32_t* group_count_xyz); + + // record barrier things + void record_transfer_compute_barrier(const VkMat& m); + void record_compute_transfer_barrier(const VkMat& m); + void record_compute_compute_barrier(const VkMat& m); + void record_transfer_transfer_barrier(const VkMat& m); + + // record prepare things + void record_prepare_transfer_barrier(const VkMat& m); + void record_prepare_compute_barrier(const VkMat& m); + +protected: + // recording issue + void copy_buffer(VkBuffer src, size_t src_offset, VkBuffer dst, size_t dst_offset, size_t size); + void copy_buffer_regions(VkBuffer src, VkBuffer dst, const std::vector& regions); + void bind_pipeline(VkPipeline pipeline); + void bind_descriptorset(VkPipelineLayout pipeline_layout, VkDescriptorSet descriptorset); + void update_bindings(VkPipelineLayout pipeline_layout, VkDescriptorUpdateTemplateKHR descriptor_update_template, const std::vector& descriptorBufferInfos); + void push_constants(VkPipelineLayout pipeline_layout, const std::vector& constants); + void dispatch(const uint32_t* group_count_xyz); + void transfer_compute_barrier(VkBuffer buffer, size_t offset, size_t size); + void compute_transfer_barrier(VkBuffer buffer, size_t offset, size_t size); + void compute_compute_barrier(VkBuffer buffer, size_t offset, size_t size); + void transfer_transfer_barrier(VkBuffer buffer, size_t offset, size_t size); + +protected: + // delayed record + // the good-old path for device without VK_KHR_push_descriptor + std::vector descriptor_pools; + std::vector descriptorsets; + struct record_type + { + // 0=copy + // 1=copy regions + // 2=bind pipeline + // 3=bind descriptorset + // 4=push constants + // 5=dispatch + // 6=transfer-compute barrier + // 7=compute-transfer barrier + // 8=compute-compute barrier + // 9=transfer-transfer barrier + int type; + + union + { + struct { VkBuffer src; size_t src_offset; VkBuffer dst; size_t dst_offset; size_t size; } copy; + struct { VkBuffer src; VkBuffer dst; } copy_regions; + struct { VkPipeline pipeline; } bind_pipeline; + struct { VkPipelineLayout pipeline_layout; VkDescriptorSet descriptorset; } bind_descriptorset; + struct { VkPipelineLayout pipeline_layout; } push_constants; + struct { uint32_t group_count_xyz[3]; } dispatch; + struct { VkBuffer buffer; size_t offset; size_t size; } transfer_compute_barrier; + struct { VkBuffer buffer; size_t offset; size_t size; } compute_transfer_barrier; + struct { VkBuffer buffer; size_t offset; size_t size; } compute_compute_barrier; + struct { VkBuffer buffer; size_t offset; size_t size; } transfer_transfer_barrier; + }; + + std::vector regions; + std::vector constants; + }; + std::vector delayed_records; +}; + +class VkTransfer : public Command +{ +public: + VkTransfer(const VulkanDevice* vkdev); + ~VkTransfer(); + + void record_upload(const Mat& src, VkMat& dst); + + int submit(); + + int wait(); + +public: + VkAllocator* weight_vkallocator; + VkAllocator* staging_vkallocator; + +protected: + // recording issue + void copy_buffer(VkBuffer src, size_t src_offset, VkBuffer dst, size_t dst_offset, size_t size); + void copy_buffer_regions(VkBuffer src, VkBuffer dst, const std::vector& regions); + +protected: + size_t buffer_offset_alignment; + VkBufferMemory* staging_data; + + // delayed record + struct record_type + { + size_t size; + Mat mat; + VkMat vkmat; + }; + std::vector delayed_records; +}; + +} // namespace ncnn + +#endif // NCNN_VULKAN + +#endif // NCNN_COMMAND_H diff --git a/Prj-Win/3rd/ncnn/include/cpu.h b/Prj-Win/3rd/ncnn/include/cpu.h new file mode 100755 index 0000000..9209cec --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/cpu.h @@ -0,0 +1,51 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_CPU_H +#define NCNN_CPU_H + +namespace ncnn { + +// test optional cpu features +// neon = armv7 neon or aarch64 asimd +int cpu_support_arm_neon(); +// vfpv4 = armv7 fp16 + fma +int cpu_support_arm_vfpv4(); +// asimdhp = aarch64 asimd half precision +int cpu_support_arm_asimdhp(); + +// cpu info +int get_cpu_count(); + +// bind all threads on little clusters if powersave enabled +// affacts HMP arch cpu like ARM big.LITTLE +// only implemented on android at the moment +// switching powersave is expensive and not thread-safe +// 0 = all cores enabled(default) +// 1 = only little clusters enabled +// 2 = only big clusters enabled +// return 0 if success for setter function +int get_cpu_powersave(); +int set_cpu_powersave(int powersave); + +// misc function wrapper for openmp routines +int get_omp_num_threads(); +void set_omp_num_threads(int num_threads); + +int get_omp_dynamic(); +void set_omp_dynamic(int dynamic); + +} // namespace ncnn + +#endif // NCNN_CPU_H diff --git a/Prj-Win/3rd/ncnn/include/gpu.h b/Prj-Win/3rd/ncnn/include/gpu.h new file mode 100755 index 0000000..7d786d5 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/gpu.h @@ -0,0 +1,156 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_GPU_H +#define NCNN_GPU_H + +#include "platform.h" + +#if NCNN_VULKAN + +#include +#include + +namespace ncnn { + +// instance +int create_gpu_instance(); +void destroy_gpu_instance(); + +// instance extension capability +extern int support_VK_KHR_get_physical_device_properties2; +extern int support_VK_EXT_debug_utils; + +// VK_KHR_get_physical_device_properties2 +extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; +extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; +extern PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR; +extern PFN_vkGetPhysicalDeviceImageFormatProperties2KHR vkGetPhysicalDeviceImageFormatProperties2KHR; +extern PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR; +extern PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR; +extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR vkGetPhysicalDeviceSparseImageFormatProperties2KHR; + +// get info +int get_gpu_count(); +int get_default_gpu_index(); + +class GpuInfo +{ +public: + // vulkan physical device + VkPhysicalDevice physical_device; + + // info + uint32_t api_version; + uint32_t driver_version; + uint32_t vendor_id; + uint32_t device_id; + uint8_t pipeline_cache_uuid[VK_UUID_SIZE]; + + // 0 = discrete gpu + // 1 = integrated gpu + // 2 = virtual gpu + // 3 = cpu + int type; + + // hardware capability + uint32_t max_shared_memory_size; + uint32_t max_workgroup_count[3]; + uint32_t max_workgroup_invocations; + uint32_t max_workgroup_size[3]; + size_t memory_map_alignment; + size_t buffer_offset_alignment; + + // runtime + uint32_t compute_queue_index; + uint32_t transfer_queue_index; + + uint32_t unified_memory_index; + uint32_t device_local_memory_index; + uint32_t host_visible_memory_index; + + // fp16 and int8 feature + bool support_fp16_storage; + bool support_fp16_arithmetic; + bool support_int8_storage; + bool support_int8_arithmetic; + + // extension capability + int support_VK_KHR_8bit_storage; + int support_VK_KHR_16bit_storage; + int support_VK_KHR_bind_memory2; + int support_VK_KHR_dedicated_allocation; + int support_VK_KHR_descriptor_update_template; + int support_VK_KHR_get_memory_requirements2; + int support_VK_KHR_push_descriptor; + int support_VK_KHR_shader_float16_int8; + int support_VK_KHR_shader_float_controls; + int support_VK_KHR_storage_buffer_storage_class; +}; + +const GpuInfo& get_gpu_info(int device_index = get_default_gpu_index()); + +class VkAllocator; +class VulkanDevice +{ +public: + VulkanDevice(int device_index = get_default_gpu_index()); + ~VulkanDevice(); + + const GpuInfo& info; + + VkDevice vkdevice() const { return device; } + + VkShaderModule get_shader_module(const char* name) const; + + // create allocator on this device + VkAllocator* allocator() const; + VkAllocator* staging_allocator() const; + + // VK_KHR_descriptor_update_template + PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR; + PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR; + PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR; + + // VK_KHR_get_memory_requirements2 + PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR; + PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR; + PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR; + + // VK_KHR_push_descriptor + PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR; + PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR; + +protected: + // shader management + int create_shader_module(); + void destroy_shader_module(); + + // device extension + int init_device_extension(); + +private: + VkDevice device; + std::vector shader_modules; + + // default locked allocator + VkAllocator* blob_buffer_allocator; + VkAllocator* staging_buffer_allocator; +}; + +} // namespace ncnn + +#endif // NCNN_VULKAN + +#endif // NCNN_GPU_H diff --git a/Prj-Win/3rd/ncnn/include/layer.h b/Prj-Win/3rd/ncnn/include/layer.h new file mode 100755 index 0000000..dc9c950 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/layer.h @@ -0,0 +1,183 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_LAYER_H +#define NCNN_LAYER_H + +#include +#include +#include +#include "mat.h" +#include "modelbin.h" +#include "paramdict.h" +#include "platform.h" + +#if NCNN_VULKAN +#include +#include "command.h" +#include "pipeline.h" +#endif // NCNN_VULKAN + +namespace ncnn { + +#if NCNN_VULKAN +class VkAllocator; +#endif // NCNN_VULKAN + +class Allocator; +class Option +{ +public: + // default option + Option(); + +public: + // light mode + // intermediate blob will be recycled when enabled + // enabled by default + bool lightmode; + + // thread count + // default value is the one returned by get_cpu_count() + int num_threads; + + // blob memory allocator + Allocator* blob_allocator; + + // workspace memory allocator + Allocator* workspace_allocator; + +#if NCNN_VULKAN + // enable vulkan compute + bool vulkan_compute; + + // blob memory allocator + VkAllocator* blob_vkallocator; + + // workspace memory allocator + VkAllocator* workspace_vkallocator; + + // staging memory allocator + VkAllocator* staging_vkallocator; +#endif // NCNN_VULKAN +}; + +// the global default option +const Option& get_default_option(); +int set_default_option(const Option& opt); + +class Layer +{ +public: + // empty + Layer(); + // virtual destructor + virtual ~Layer(); + + // load layer specific parameter from parsed dict + // return 0 if success + virtual int load_param(const ParamDict& pd); + + // load layer specific weight data from model binary + // return 0 if success + virtual int load_model(const ModelBin& mb); + +public: + // one input and one output blob + bool one_blob_only; + + // support inplace inference + bool support_inplace; + + // support vulkan compute + bool support_vulkan; + +public: + // implement inference + // return 0 if success + virtual int forward(const std::vector& bottom_blobs, std::vector& top_blobs, const Option& opt = get_default_option()) const; + virtual int forward(const Mat& bottom_blob, Mat& top_blob, const Option& opt = get_default_option()) const; + + // implement inplace inference + // return 0 if success + virtual int forward_inplace(std::vector& bottom_top_blobs, const Option& opt = get_default_option()) const; + virtual int forward_inplace(Mat& bottom_top_blob, const Option& opt = get_default_option()) const; + +#if NCNN_VULKAN +public: + // upload weight blob from host to device + virtual int upload_model(VkTransfer& cmd); + + virtual int create_pipeline(); + virtual int destroy_pipeline(); + +public: + // implement inference + // return 0 if success + virtual int forward(const std::vector& bottom_blobs, std::vector& top_blobs, VkCompute& cmd, const Option& opt = get_default_option()) const; + virtual int forward(const VkMat& bottom_blob, VkMat& top_blob, VkCompute& cmd, const Option& opt = get_default_option()) const; + + // implement inplace inference + // return 0 if success + virtual int forward_inplace(std::vector& bottom_top_blobs, VkCompute& cmd, const Option& opt = get_default_option()) const; + virtual int forward_inplace(VkMat& bottom_top_blob, VkCompute& cmd, const Option& opt = get_default_option()) const; + +public: + // assigned immediately after creating this layer + const VulkanDevice* vkdev; +#endif // NCNN_VULKAN + +public: + // layer type index + int typeindex; +#if NCNN_STRING + // layer type name + std::string type; + // layer name + std::string name; +#endif // NCNN_STRING + // blob index which this layer needs as input + std::vector bottoms; + // blob index which this layer produces as output + std::vector tops; +}; + +// layer factory function +typedef Layer* (*layer_creator_func)(); + +struct layer_registry_entry +{ +#if NCNN_STRING + // layer type name + const char* name; +#endif // NCNN_STRING + // layer factory entry + layer_creator_func creator; +}; + +#if NCNN_STRING +// get layer type from type name +int layer_to_index(const char* type); +// create layer from type name +Layer* create_layer(const char* type); +#endif // NCNN_STRING +// create layer from layer type +Layer* create_layer(int index); + +#define DEFINE_LAYER_CREATOR(name) \ + ::ncnn::Layer* name##_layer_creator() { return new name; } + +} // namespace ncnn + +#endif // NCNN_LAYER_H diff --git a/Prj-Win/3rd/ncnn/include/layer_type.h b/Prj-Win/3rd/ncnn/include/layer_type.h new file mode 100755 index 0000000..91da743 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/layer_type.h @@ -0,0 +1,30 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_LAYER_TYPE_H +#define NCNN_LAYER_TYPE_H + +namespace ncnn { + +namespace LayerType { +enum +{ +#include "layer_type_enum.h" + CustomBit = (1<<8), +}; +} // namespace LayerType + +} // namespace ncnn + +#endif // NCNN_LAYER_TYPE_H diff --git a/Prj-Win/3rd/ncnn/include/layer_type_enum.h b/Prj-Win/3rd/ncnn/include/layer_type_enum.h new file mode 100755 index 0000000..7977765 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/layer_type_enum.h @@ -0,0 +1,70 @@ +// Layer Type Enum header +// +// This file is auto-generated by cmake, don't edit it. + +AbsVal = 0, +ArgMax = 1, +BatchNorm = 2, +Bias = 3, +BNLL = 4, +Concat = 5, +Convolution = 6, +Crop = 7, +Deconvolution = 8, +Dropout = 9, +Eltwise = 10, +ELU = 11, +Embed = 12, +Exp = 13, +Flatten = 14, +InnerProduct = 15, +Input = 16, +Log = 17, +LRN = 18, +MemoryData = 19, +MVN = 20, +Pooling = 21, +Power = 22, +PReLU = 23, +Proposal = 24, +Reduction = 25, +ReLU = 26, +Reshape = 27, +ROIPooling = 28, +Scale = 29, +Sigmoid = 30, +Slice = 31, +Softmax = 32, +Split = 33, +SPP = 34, +TanH = 35, +Threshold = 36, +Tile = 37, +RNN = 38, +LSTM = 39, +BinaryOp = 40, +UnaryOp = 41, +ConvolutionDepthWise = 42, +Padding = 43, +Squeeze = 44, +ExpandDims = 45, +Normalize = 46, +Permute = 47, +PriorBox = 48, +DetectionOutput = 49, +Interp = 50, +DeconvolutionDepthWise = 51, +ShuffleChannel = 52, +InstanceNorm = 53, +Clip = 54, +Reorg = 55, +YoloDetectionOutput = 56, +Quantize = 57, +Dequantize = 58, +Yolov3DetectionOutput = 59, +PSROIPooling = 60, +ROIAlign = 61, +Packing = 62, +Requantize = 63, +Cast = 64, + diff --git a/Prj-Win/3rd/ncnn/include/mat.h b/Prj-Win/3rd/ncnn/include/mat.h new file mode 100755 index 0000000..fae02c7 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/mat.h @@ -0,0 +1,1580 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_MAT_H +#define NCNN_MAT_H + +#include +#include +#include +#if __ARM_NEON +#include +#endif +#include "platform.h" +#include "allocator.h" +#include "gpu.h" + +#if NCNN_VULKAN +#include +#endif // NCNN_VULKAN + +namespace ncnn { + +#if NCNN_VULKAN +class VkMat; +#endif // NCNN_VULKAN + +// the three dimension matrix +class Mat +{ +public: + // empty + Mat(); + // vec + Mat(int w, size_t elemsize = 4u, Allocator* allocator = 0); + // image + Mat(int w, int h, size_t elemsize = 4u, Allocator* allocator = 0); + // dim + Mat(int w, int h, int c, size_t elemsize = 4u, Allocator* allocator = 0); + // packed vec + Mat(int w, size_t elemsize, int packing, Allocator* allocator = 0); + // packed image + Mat(int w, int h, size_t elemsize, int packing, Allocator* allocator = 0); + // packed dim + Mat(int w, int h, int c, size_t elemsize, int packing, Allocator* allocator = 0); + // copy + Mat(const Mat& m); + // external vec + Mat(int w, void* data, size_t elemsize = 4u, Allocator* allocator = 0); + // external image + Mat(int w, int h, void* data, size_t elemsize = 4u, Allocator* allocator = 0); + // external dim + Mat(int w, int h, int c, void* data, size_t elemsize = 4u, Allocator* allocator = 0); + // external packed vec + Mat(int w, void* data, size_t elemsize, int packing, Allocator* allocator = 0); + // external packed image + Mat(int w, int h, void* data, size_t elemsize, int packing, Allocator* allocator = 0); + // external packed dim + Mat(int w, int h, int c, void* data, size_t elemsize, int packing, Allocator* allocator = 0); + // release + ~Mat(); + // assign + Mat& operator=(const Mat& m); + // set all + void fill(float v); + void fill(int v); + template void fill(T v); + // deep copy + Mat clone(Allocator* allocator = 0) const; + // reshape vec + Mat reshape(int w, Allocator* allocator = 0) const; + // reshape image + Mat reshape(int w, int h, Allocator* allocator = 0) const; + // reshape dim + Mat reshape(int w, int h, int c, Allocator* allocator = 0) const; + // allocate vec + void create(int w, size_t elemsize = 4u, Allocator* allocator = 0); + // allocate image + void create(int w, int h, size_t elemsize = 4u, Allocator* allocator = 0); + // allocate dim + void create(int w, int h, int c, size_t elemsize = 4u, Allocator* allocator = 0); + // allocate packed vec + void create(int w, size_t elemsize, int packing, Allocator* allocator = 0); + // allocate packed image + void create(int w, int h, size_t elemsize, int packing, Allocator* allocator = 0); + // allocate packed dim + void create(int w, int h, int c, size_t elemsize, int packing, Allocator* allocator = 0); + // allocate like + void create_like(const Mat& m, Allocator* allocator = 0); +#if NCNN_VULKAN + // allocate like + void create_like(const VkMat& m, Allocator* allocator = 0); +#endif // NCNN_VULKAN + // refcount++ + void addref(); + // refcount-- + void release(); + + bool empty() const; + size_t total() const; + + // data reference + Mat channel(int c); + const Mat channel(int c) const; + float* row(int y); + const float* row(int y) const; + template T* row(int y); + template const T* row(int y) const; + + // range reference + Mat channel_range(int c, int channels); + const Mat channel_range(int c, int channels) const; + Mat row_range(int y, int rows); + const Mat row_range(int y, int rows) const; + Mat range(int x, int n); + const Mat range(int x, int n) const; + + // access raw data + template operator T*(); + template operator const T*() const; + + // convenient access float vec element + float& operator[](int i); + const float& operator[](int i) const; + +#if NCNN_PIXEL + enum + { + PIXEL_CONVERT_SHIFT = 16, + PIXEL_FORMAT_MASK = 0x0000ffff, + PIXEL_CONVERT_MASK = 0xffff0000, + + PIXEL_RGB = 1, + PIXEL_BGR = (1 << 1), + PIXEL_GRAY = (1 << 2), + PIXEL_RGBA = (1 << 3), + + PIXEL_RGB2BGR = PIXEL_RGB | (PIXEL_BGR << PIXEL_CONVERT_SHIFT), + PIXEL_RGB2GRAY = PIXEL_RGB | (PIXEL_GRAY << PIXEL_CONVERT_SHIFT), + + PIXEL_BGR2RGB = PIXEL_BGR | (PIXEL_RGB << PIXEL_CONVERT_SHIFT), + PIXEL_BGR2GRAY = PIXEL_BGR | (PIXEL_GRAY << PIXEL_CONVERT_SHIFT), + + PIXEL_GRAY2RGB = PIXEL_GRAY | (PIXEL_RGB << PIXEL_CONVERT_SHIFT), + PIXEL_GRAY2BGR = PIXEL_GRAY | (PIXEL_BGR << PIXEL_CONVERT_SHIFT), + + PIXEL_RGBA2RGB = PIXEL_RGBA | (PIXEL_RGB << PIXEL_CONVERT_SHIFT), + PIXEL_RGBA2BGR = PIXEL_RGBA | (PIXEL_BGR << PIXEL_CONVERT_SHIFT), + PIXEL_RGBA2GRAY = PIXEL_RGBA | (PIXEL_GRAY << PIXEL_CONVERT_SHIFT), + }; + // convenient construct from pixel data + static Mat from_pixels(const unsigned char* pixels, int type, int w, int h, Allocator* allocator = 0); + // convenient construct from pixel data and resize to specific size + static Mat from_pixels_resize(const unsigned char* pixels, int type, int w, int h, int target_width, int target_height, Allocator* allocator = 0); + + // convenient export to pixel data + void to_pixels(unsigned char* pixels, int type) const; + // convenient export to pixel data and resize to specific size + void to_pixels_resize(unsigned char* pixels, int type, int target_width, int target_height) const; +#endif // NCNN_PIXEL + + // substract channel-wise mean values, then multiply by normalize values, pass 0 to skip + void substract_mean_normalize(const float* mean_vals, const float* norm_vals); + + // convenient construct from half precisoin floating point data + static Mat from_float16(const unsigned short* data, int size); + + // pointer to the data + void* data; + + // pointer to the reference counter + // when points to user-allocated data, the pointer is NULL + int* refcount; + + // element size in bytes + // 4 = float32/int32 + // 2 = float16 + // 1 = int8/uint8 + // 0 = empty + size_t elemsize; + + // packed count inside element + // c/1-h-w-1 h/1-w-1 w/1-1 scalar + // c/4-h-w-4 h/4-w-4 w/4-4 sse/neon + // c/8-h-w-8 h/8-w-8 w/8-8 avx/fp16 + int packing; + + // the allocator + Allocator* allocator; + + // the dimensionality + int dims; + + int w; + int h; + int c; + + size_t cstep; +}; + +#if NCNN_VULKAN + +// the three dimension matrix, vulkan version +class VkMat +{ +public: + // empty + VkMat(); + // vec + VkMat(int w, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // image + VkMat(int w, int h, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // dim + VkMat(int w, int h, int c, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // packed vec + VkMat(int w, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // packed image + VkMat(int w, int h, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // packed dim + VkMat(int w, int h, int c, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // copy + VkMat(const VkMat& m); + // external vec + VkMat(int w, VkBufferMemory* data, size_t offset, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // external image + VkMat(int w, int h, VkBufferMemory* data, size_t offset, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // external dim + VkMat(int w, int h, int c, VkBufferMemory* data, size_t offset, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // external packed vec + VkMat(int w, VkBufferMemory* data, size_t offset, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // external packed image + VkMat(int w, int h, VkBufferMemory* data, size_t offset, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // external packed dim + VkMat(int w, int h, int c, VkBufferMemory* data, size_t offset, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // release + ~VkMat(); + // assign + VkMat& operator=(const VkMat& m); + // allocate vec + void create(int w, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // allocate image + void create(int w, int h, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // allocate dim + void create(int w, int h, int c, size_t elemsize, VkAllocator* allocator, VkAllocator* staging_allocator); + // allocate packed vec + void create(int w, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // allocate packed image + void create(int w, int h, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // allocate packed dim + void create(int w, int h, int c, size_t elemsize, int packing, VkAllocator* allocator, VkAllocator* staging_allocator); + // allocate like + void create_like(const Mat& m, VkAllocator* allocator, VkAllocator* staging_allocator); + // allocate like + void create_like(const VkMat& m, VkAllocator* allocator, VkAllocator* staging_allocator); + + // staging buffer + void prepare_staging_buffer(); + void discard_staging_buffer(); + + // copy + void upload(const Mat& m); + void download(Mat& m) const; + + // mapped + Mat mapped() const; + void* mapped_ptr() const; + + // refcount++ + void addref(); + // refcount-- + void release(); + + bool empty() const; + size_t total() const; + + // data reference + VkMat channel(int c); + const VkMat channel(int c) const; + + // range reference + VkMat channel_range(int c, int channels); + const VkMat channel_range(int c, int channels) const; + VkMat row_range(int y, int rows); + const VkMat row_range(int y, int rows) const; + VkMat range(int x, int n); + const VkMat range(int x, int n) const; + + // low-level reference + VkBuffer buffer() const; + size_t buffer_offset() const; + VkBuffer staging_buffer() const; + size_t staging_buffer_offset() const; + + // device buffer + VkBufferMemory* data; + // subrange offset + size_t offset; + + // staging buffer + VkBufferMemory* staging_data; + + // pointer to the reference counter + // when points to user-allocated data, the pointer is NULL + int* refcount; + int* staging_refcount; + + // element size in bytes + // 4 = float32/int32 + // 2 = float16 + // 1 = int8/uint8 + // 0 = empty + size_t elemsize; + + // packed count inside element + // c/1-h-w-1 h/1-w-1 w/1-1 scalar + // c/4-h-w-4 h/4-w-4 w/4-4 sse/neon + // c/8-h-w-8 h/8-w-8 w/8-8 avx/fp16 + int packing; + + // the allocator + VkAllocator* allocator; + VkAllocator* staging_allocator; + + // the dimensionality + int dims; + + int w; + int h; + int c; + + size_t cstep; +}; + +// type for vulkan specialization constant and push constant +union vk_specialization_type { int i; float f; uint32_t u32; }; +union vk_constant_type { int i; float f; }; +#endif // NCNN_VULKAN + +// misc function +#if NCNN_PIXEL +// convert yuv420sp(nv21) to rgb, the fast approximate version +void yuv420sp2rgb(const unsigned char* yuv420sp, int w, int h, unsigned char* rgb); +// image pixel bilinear resize +void resize_bilinear_c1(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h); +void resize_bilinear_c2(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h); +void resize_bilinear_c3(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h); +void resize_bilinear_c4(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h); +// image pixel bilinear resize, convenient wrapper for yuv420sp(nv21) +void resize_bilinear_yuv420sp(const unsigned char* src, int srcw, int srch, unsigned char* dst, int w, int h); +#endif // NCNN_PIXEL + +// mat process +enum +{ + BORDER_CONSTANT = 0, + BORDER_REPLICATE = 1, +}; +void copy_make_border(const Mat& src, Mat& dst, int top, int bottom, int left, int right, int type, float v, Allocator* allocator = 0, int num_threads = 1); +void copy_cut_border(const Mat& src, Mat& dst, int top, int bottom, int left, int right, Allocator* allocator = 0, int num_threads = 1); +void resize_bilinear(const Mat& src, Mat& dst, int w, int h, Allocator* allocator = 0, int num_threads = 1); +void convert_packing(const Mat& src, Mat& dst, int packing, Allocator* allocator = 0, int num_threads = 1); +void cast_float32_to_float16(const Mat& src, Mat& dst, Allocator* allocator = 0, int num_threads = 1); +void cast_float16_to_float32(const Mat& src, Mat& dst, Allocator* allocator = 0, int num_threads = 1); + +inline Mat::Mat() + : data(0), refcount(0), elemsize(0), packing(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0) +{ +} + +inline Mat::Mat(int _w, size_t _elemsize, Allocator* _allocator) + : data(0), refcount(0), dims(0) +{ + create(_w, _elemsize, _allocator); +} + +inline Mat::Mat(int _w, int _h, size_t _elemsize, Allocator* _allocator) + : data(0), refcount(0), dims(0) +{ + create(_w, _h, _elemsize, _allocator); +} + +inline Mat::Mat(int _w, int _h, int _c, size_t _elemsize, Allocator* _allocator) + : data(0), refcount(0), dims(0) +{ + create(_w, _h, _c, _elemsize, _allocator); +} + +inline Mat::Mat(int _w, size_t _elemsize, int _packing, Allocator* _allocator) + : data(0), refcount(0), dims(0) +{ + create(_w, _elemsize, _packing, _allocator); +} + +inline Mat::Mat(int _w, int _h, size_t _elemsize, int _packing, Allocator* _allocator) + : data(0), refcount(0), dims(0) +{ + create(_w, _h, _elemsize, _packing, _allocator); +} + +inline Mat::Mat(int _w, int _h, int _c, size_t _elemsize, int _packing, Allocator* _allocator) + : data(0), refcount(0), dims(0) +{ + create(_w, _h, _c, _elemsize, _packing, _allocator); +} + +inline Mat::Mat(const Mat& m) + : data(m.data), refcount(m.refcount), elemsize(m.elemsize), packing(m.packing), allocator(m.allocator), dims(m.dims), w(m.w), h(m.h), c(m.c), cstep(m.cstep) +{ + if (refcount) + NCNN_XADD(refcount, 1); +} + +inline Mat::Mat(int _w, void* _data, size_t _elemsize, Allocator* _allocator) + : data(_data), refcount(0), elemsize(_elemsize), packing(1), allocator(_allocator), dims(1), w(_w), h(1), c(1) +{ + cstep = w; +} + +inline Mat::Mat(int _w, int _h, void* _data, size_t _elemsize, Allocator* _allocator) + : data(_data), refcount(0), elemsize(_elemsize), packing(1), allocator(_allocator), dims(2), w(_w), h(_h), c(1) +{ + cstep = w * h; +} + +inline Mat::Mat(int _w, int _h, int _c, void* _data, size_t _elemsize, Allocator* _allocator) + : data(_data), refcount(0), elemsize(_elemsize), packing(1), allocator(_allocator), dims(3), w(_w), h(_h), c(_c) +{ + cstep = alignSize(w * h * elemsize, 16) / elemsize; +} + +inline Mat::Mat(int _w, void* _data, size_t _elemsize, int _packing, Allocator* _allocator) + : data(_data), refcount(0), elemsize(_elemsize), packing(_packing), allocator(_allocator), dims(1), w(_w), h(1), c(1) +{ + cstep = w; +} + +inline Mat::Mat(int _w, int _h, void* _data, size_t _elemsize, int _packing, Allocator* _allocator) + : data(_data), refcount(0), elemsize(_elemsize), packing(_packing), allocator(_allocator), dims(2), w(_w), h(_h), c(1) +{ + cstep = w * h; +} + +inline Mat::Mat(int _w, int _h, int _c, void* _data, size_t _elemsize, int _packing, Allocator* _allocator) + : data(_data), refcount(0), elemsize(_elemsize), packing(_packing), allocator(_allocator), dims(3), w(_w), h(_h), c(_c) +{ + cstep = alignSize(w * h * elemsize, 16) / elemsize; +} + +inline Mat::~Mat() +{ + release(); +} + +inline Mat& Mat::operator=(const Mat& m) +{ + if (this == &m) + return *this; + + if (m.refcount) + NCNN_XADD(m.refcount, 1); + + release(); + + data = m.data; + refcount = m.refcount; + elemsize = m.elemsize; + packing = m.packing; + allocator = m.allocator; + + dims = m.dims; + w = m.w; + h = m.h; + c = m.c; + + cstep = m.cstep; + + return *this; +} + +inline void Mat::fill(float _v) +{ + int size = total(); + float* ptr = (float*)data; + +#if __ARM_NEON + int nn = size >> 2; + int remain = size - (nn << 2); +#else + int remain = size; +#endif // __ARM_NEON + +#if __ARM_NEON + float32x4_t _c = vdupq_n_f32(_v); +#if __aarch64__ + if (nn > 0) + { + asm volatile ( + "0: \n" + "subs %w0, %w0, #1 \n" + "st1 {%4.4s}, [%1], #16 \n" + "bne 0b \n" + : "=r"(nn), // %0 + "=r"(ptr) // %1 + : "0"(nn), + "1"(ptr), + "w"(_c) // %4 + : "cc", "memory" + ); + } +#else + if (nn > 0) + { + asm volatile( + "0: \n" + "subs %0, #1 \n" + "vst1.f32 {%e4-%f4}, [%1 :128]!\n" + "bne 0b \n" + : "=r"(nn), // %0 + "=r"(ptr) // %1 + : "0"(nn), + "1"(ptr), + "w"(_c) // %4 + : "cc", "memory" + ); + } +#endif // __aarch64__ +#endif // __ARM_NEON + for (; remain>0; remain--) + { + *ptr++ = _v; + } +} + +inline void Mat::fill(int _v) +{ + int size = total(); + int* ptr = (int*)data; + +#if __ARM_NEON + int nn = size >> 2; + int remain = size - (nn << 2); +#else + int remain = size; +#endif // __ARM_NEON + +#if __ARM_NEON + int32x4_t _c = vdupq_n_s32(_v); +#if __aarch64__ + if (nn > 0) + { + asm volatile ( + "0: \n" + "subs %w0, %w0, #1 \n" + "st1 {%4.4s}, [%1], #16 \n" + "bne 0b \n" + : "=r"(nn), // %0 + "=r"(ptr) // %1 + : "0"(nn), + "1"(ptr), + "w"(_c) // %4 + : "cc", "memory" + ); + } +#else + if (nn > 0) + { + asm volatile( + "0: \n" + "subs %0, #1 \n" + "vst1.s32 {%e4-%f4}, [%1 :128]!\n" + "bne 0b \n" + : "=r"(nn), // %0 + "=r"(ptr) // %1 + : "0"(nn), + "1"(ptr), + "w"(_c) // %4 + : "cc", "memory" + ); + } +#endif // __aarch64__ +#endif // __ARM_NEON + for (; remain>0; remain--) + { + *ptr++ = _v; + } +} + +template +inline void Mat::fill(T _v) +{ + int size = total(); + T* ptr = (T*)data; + for (int i=0; i 0) + { + memcpy(m.data, data, total() * elemsize); + } + + return m; +} + +inline Mat Mat::reshape(int _w, Allocator* _allocator) const +{ + if (w * h * c != _w) + return Mat(); + + if (dims == 3 && cstep != (size_t)w * h) + { + Mat m; + m.create(_w, elemsize, packing, _allocator); + + // flatten + for (int i=0; i 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + if (allocator) + data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount)); + else + data = fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(((unsigned char*)data) + totalsize); + *refcount = 1; + } +} + +inline void Mat::create(int _w, int _h, size_t _elemsize, Allocator* _allocator) +{ + if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && packing == 1 && allocator == _allocator) + return; + + release(); + + elemsize = _elemsize; + packing = 1; + allocator = _allocator; + + dims = 2; + w = _w; + h = _h; + c = 1; + + cstep = w * h; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + if (allocator) + data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount)); + else + data = fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(((unsigned char*)data) + totalsize); + *refcount = 1; + } +} + +inline void Mat::create(int _w, int _h, int _c, size_t _elemsize, Allocator* _allocator) +{ + if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && packing == 1 && allocator == _allocator) + return; + + release(); + + elemsize = _elemsize; + packing = 1; + allocator = _allocator; + + dims = 3; + w = _w; + h = _h; + c = _c; + + cstep = alignSize(w * h * elemsize, 16) / elemsize; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + if (allocator) + data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount)); + else + data = fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(((unsigned char*)data) + totalsize); + *refcount = 1; + } +} + +inline void Mat::create(int _w, size_t _elemsize, int _packing, Allocator* _allocator) +{ + if (dims == 1 && w == _w && elemsize == _elemsize && packing == _packing && allocator == _allocator) + return; + + release(); + + elemsize = _elemsize; + packing = _packing; + allocator = _allocator; + + dims = 1; + w = _w; + h = 1; + c = 1; + + cstep = w; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + if (allocator) + data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount)); + else + data = fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(((unsigned char*)data) + totalsize); + *refcount = 1; + } +} + +inline void Mat::create(int _w, int _h, size_t _elemsize, int _packing, Allocator* _allocator) +{ + if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && packing == _packing && allocator == _allocator) + return; + + release(); + + elemsize = _elemsize; + packing = _packing; + allocator = _allocator; + + dims = 2; + w = _w; + h = _h; + c = 1; + + cstep = w * h; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + if (allocator) + data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount)); + else + data = fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(((unsigned char*)data) + totalsize); + *refcount = 1; + } +} + +inline void Mat::create(int _w, int _h, int _c, size_t _elemsize, int _packing, Allocator* _allocator) +{ + if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && packing == _packing && allocator == _allocator) + return; + + release(); + + elemsize = _elemsize; + packing = _packing; + allocator = _allocator; + + dims = 3; + w = _w; + h = _h; + c = _c; + + cstep = alignSize(w * h * elemsize, 16) / elemsize; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + if (allocator) + data = allocator->fastMalloc(totalsize + (int)sizeof(*refcount)); + else + data = fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(((unsigned char*)data) + totalsize); + *refcount = 1; + } +} + +inline void Mat::create_like(const Mat& m, Allocator* _allocator) +{ + if (m.dims == 1) + create(m.w, m.elemsize, m.packing, _allocator); + else if (m.dims == 2) + create(m.w, m.h, m.elemsize, m.packing, _allocator); + else if (m.dims == 3) + create(m.w, m.h, m.c, m.elemsize, m.packing, _allocator); +} + +#if NCNN_VULKAN +inline void Mat::create_like(const VkMat& m, Allocator* _allocator) +{ + if (m.dims == 1) + create(m.w, m.elemsize, m.packing, _allocator); + else if (m.dims == 2) + create(m.w, m.h, m.elemsize, m.packing, _allocator); + else if (m.dims == 3) + create(m.w, m.h, m.c, m.elemsize, m.packing, _allocator); +} +#endif // NCNN_VULKAN + +inline void Mat::addref() +{ + if (refcount) + NCNN_XADD(refcount, 1); +} + +inline void Mat::release() +{ + if (refcount && NCNN_XADD(refcount, -1) == 1) + { + if (allocator) + allocator->fastFree(data); + else + fastFree(data); + } + + data = 0; + + elemsize = 0; + packing = 0; + + dims = 0; + w = 0; + h = 0; + c = 0; + + cstep = 0; + + refcount = 0; +} + +inline bool Mat::empty() const +{ + return data == 0 || total() == 0; +} + +inline size_t Mat::total() const +{ + return cstep * c; +} + +inline Mat Mat::channel(int _c) +{ + return Mat(w, h, (unsigned char*)data + cstep * _c * elemsize, elemsize, packing, allocator); +} + +inline const Mat Mat::channel(int _c) const +{ + return Mat(w, h, (unsigned char*)data + cstep * _c * elemsize, elemsize, packing, allocator); +} + +inline float* Mat::row(int y) +{ + return (float*)data + w * y; +} + +inline const float* Mat::row(int y) const +{ + return (const float*)data + w * y; +} + +template +inline T* Mat::row(int y) +{ + return (T*)data + w * y; +} + +template +inline const T* Mat::row(int y) const +{ + return (const T*)data + w * y; +} + +inline Mat Mat::channel_range(int _c, int channels) +{ + return Mat(w, h, channels, (unsigned char*)data + cstep * _c * elemsize, elemsize, packing, allocator); +} + +inline const Mat Mat::channel_range(int _c, int channels) const +{ + return Mat(w, h, channels, (unsigned char*)data + cstep * _c * elemsize, elemsize, packing, allocator); +} + +inline Mat Mat::row_range(int y, int rows) +{ + return Mat(w, rows, (unsigned char*)data + w * y * elemsize, elemsize, packing, allocator); +} + +inline const Mat Mat::row_range(int y, int rows) const +{ + return Mat(w, rows, (unsigned char*)data + w * y * elemsize, elemsize, packing, allocator); +} + +inline Mat Mat::range(int x, int n) +{ + return Mat(n, (unsigned char*)data + x * elemsize, elemsize, packing, allocator); +} + +inline const Mat Mat::range(int x, int n) const +{ + return Mat(n, (unsigned char*)data + x * elemsize, elemsize, packing, allocator); +} + +template +inline Mat::operator T*() +{ + return (T*)data; +} + +template +inline Mat::operator const T*() const +{ + return (const T*)data; +} + +inline float& Mat::operator[](int i) +{ + return ((float*)data)[i]; +} + +inline const float& Mat::operator[](int i) const +{ + return ((const float*)data)[i]; +} + +#if NCNN_VULKAN + +inline VkMat::VkMat() + : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0), elemsize(0), packing(0), allocator(0), dims(0), w(0), h(0), c(0), cstep(0) +{ +} + +inline VkMat::VkMat(int _w, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0) +{ + create(_w, _elemsize, _allocator, _staging_allocator); +} + +inline VkMat::VkMat(int _w, int _h, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0) +{ + create(_w, _h, _elemsize, _allocator, _staging_allocator); +} + +inline VkMat::VkMat(int _w, int _h, int _c, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0) +{ + create(_w, _h, _c, _elemsize, _allocator, _staging_allocator); +} + +inline VkMat::VkMat(int _w, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0) +{ + create(_w, _elemsize, _packing, _allocator, _staging_allocator); +} + +inline VkMat::VkMat(int _w, int _h, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0) +{ + create(_w, _h, _elemsize, _packing, _allocator, _staging_allocator); +} + +inline VkMat::VkMat(int _w, int _h, int _c, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(0), offset(0), staging_data(0), refcount(0), staging_refcount(0) +{ + create(_w, _h, _c, _elemsize, _packing, _allocator, _staging_allocator); +} + +inline VkMat::VkMat(const VkMat& m) + : data(m.data), offset(m.offset), staging_data(m.staging_data), refcount(m.refcount), staging_refcount(m.staging_refcount), elemsize(m.elemsize), packing(m.packing), allocator(m.allocator), staging_allocator(m.staging_allocator), dims(m.dims), w(m.w), h(m.h), c(m.c) +{ + if (refcount) + NCNN_XADD(refcount, 1); + + if (staging_refcount) + NCNN_XADD(staging_refcount, 1); + + cstep = m.cstep; +} + +inline VkMat::VkMat(int _w, VkBufferMemory* _data, size_t _offset, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), packing(1), allocator(_allocator), staging_allocator(_staging_allocator), dims(1), w(_w), h(1), c(1) +{ + cstep = w; +} + +inline VkMat::VkMat(int _w, int _h, VkBufferMemory* _data, size_t _offset, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), packing(1), allocator(_allocator), staging_allocator(_staging_allocator), dims(2), w(_w), h(_h), c(1) +{ + cstep = w * h; +} + +inline VkMat::VkMat(int _w, int _h, int _c, VkBufferMemory* _data, size_t _offset, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), packing(1), allocator(_allocator), staging_allocator(_staging_allocator), dims(3), w(_w), h(_h), c(_c) +{ + cstep = alignSize(w * h * elemsize, 16) / elemsize; +} + +inline VkMat::VkMat(int _w, VkBufferMemory* _data, size_t _offset, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), packing(_packing), allocator(_allocator), staging_allocator(_staging_allocator), dims(1), w(_w), h(1), c(1) +{ + cstep = w; +} + +inline VkMat::VkMat(int _w, int _h, VkBufferMemory* _data, size_t _offset, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), packing(_packing), allocator(_allocator), staging_allocator(_staging_allocator), dims(2), w(_w), h(_h), c(1) +{ + cstep = w * h; +} + +inline VkMat::VkMat(int _w, int _h, int _c, VkBufferMemory* _data, size_t _offset, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) + : data(_data), offset(_offset), staging_data(0), refcount(0), staging_refcount(0), elemsize(_elemsize), packing(_packing), allocator(_allocator), staging_allocator(_staging_allocator), dims(3), w(_w), h(_h), c(_c) +{ + cstep = alignSize(w * h * elemsize, 16) / elemsize; +} + +inline VkMat::~VkMat() +{ + release(); +} + +inline VkMat& VkMat::operator=(const VkMat& m) +{ + if (this == &m) + return *this; + + if (m.refcount) + NCNN_XADD(m.refcount, 1); + + if (m.staging_refcount) + NCNN_XADD(m.staging_refcount, 1); + + release(); + + data = m.data; + offset = m.offset; + staging_data = m.staging_data; + refcount = m.refcount; + staging_refcount = m.staging_refcount; + elemsize = m.elemsize; + packing = m.packing; + allocator = m.allocator; + staging_allocator = m.staging_allocator; + + dims = m.dims; + w = m.w; + h = m.h; + c = m.c; + + cstep = m.cstep; + + return *this; +} + +inline void VkMat::create(int _w, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (dims == 1 && w == _w && elemsize == _elemsize && packing == 1 && allocator == _allocator && staging_allocator == _staging_allocator) + return; + + release(); + + elemsize = _elemsize; + packing = 1; + allocator = _allocator; + staging_allocator = _staging_allocator; + + dims = 1; + w = _w; + h = 1; + c = 1; + + cstep = w; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + + data = allocator->fastMalloc(totalsize); + offset = 0; + + refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount)); + *refcount = 1; + } +} + +inline void VkMat::create(int _w, int _h, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && packing == 1 && allocator == _allocator && staging_allocator == _staging_allocator) + return; + + release(); + + elemsize = _elemsize; + packing = 1; + allocator = _allocator; + staging_allocator = _staging_allocator; + + dims = 2; + w = _w; + h = _h; + c = 1; + + cstep = w * h; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + + data = allocator->fastMalloc(totalsize); + offset = 0; + + refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount)); + *refcount = 1; + } +} + +inline void VkMat::create(int _w, int _h, int _c, size_t _elemsize, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && packing == 1 && allocator == _allocator && staging_allocator == _staging_allocator) + return; + + release(); + + elemsize = _elemsize; + packing = 1; + allocator = _allocator; + staging_allocator = _staging_allocator; + + dims = 3; + w = _w; + h = _h; + c = _c; + + cstep = alignSize(w * h * elemsize, 16) / elemsize; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + + data = allocator->fastMalloc(totalsize); + offset = 0; + + refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount)); + *refcount = 1; + } +} + +inline void VkMat::create(int _w, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (dims == 1 && w == _w && elemsize == _elemsize && packing == _packing && allocator == _allocator && staging_allocator == _staging_allocator) + return; + + release(); + + elemsize = _elemsize; + packing = _packing; + allocator = _allocator; + staging_allocator = _staging_allocator; + + dims = 1; + w = _w; + h = 1; + c = 1; + + cstep = w; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + + data = allocator->fastMalloc(totalsize); + offset = 0; + + refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount)); + *refcount = 1; + } +} + +inline void VkMat::create(int _w, int _h, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (dims == 2 && w == _w && h == _h && elemsize == _elemsize && packing == _packing && allocator == _allocator && staging_allocator == _staging_allocator) + return; + + release(); + + elemsize = _elemsize; + packing = _packing; + allocator = _allocator; + staging_allocator = _staging_allocator; + + dims = 2; + w = _w; + h = _h; + c = 1; + + cstep = w * h; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + + data = allocator->fastMalloc(totalsize); + offset = 0; + + refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount)); + *refcount = 1; + } +} + +inline void VkMat::create(int _w, int _h, int _c, size_t _elemsize, int _packing, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (dims == 3 && w == _w && h == _h && c == _c && elemsize == _elemsize && packing == _packing && allocator == _allocator && staging_allocator == _staging_allocator) + return; + + release(); + + elemsize = _elemsize; + packing = _packing; + allocator = _allocator; + staging_allocator = _staging_allocator; + + dims = 3; + w = _w; + h = _h; + c = _c; + + cstep = alignSize(w * h * elemsize, 16) / elemsize; + + if (total() > 0) + { + size_t totalsize = alignSize(total() * elemsize, 4); + + data = allocator->fastMalloc(totalsize); + offset = 0; + + refcount = (int*)((unsigned char*)data + offsetof(VkBufferMemory, refcount)); + *refcount = 1; + } +} + +inline void VkMat::create_like(const Mat& m, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (m.dims == 1) + create(m.w, m.elemsize, m.packing, _allocator, _staging_allocator); + else if (m.dims == 2) + create(m.w, m.h, m.elemsize, m.packing, _allocator, _staging_allocator); + else if (m.dims == 3) + create(m.w, m.h, m.c, m.elemsize, m.packing, _allocator, _staging_allocator); +} + +inline void VkMat::create_like(const VkMat& m, VkAllocator* _allocator, VkAllocator* _staging_allocator) +{ + if (m.dims == 1) + create(m.w, m.elemsize, m.packing, _allocator, _staging_allocator); + else if (m.dims == 2) + create(m.w, m.h, m.elemsize, m.packing, _allocator, _staging_allocator); + else if (m.dims == 3) + create(m.w, m.h, m.c, m.elemsize, m.packing, _allocator, _staging_allocator); +} + +inline void VkMat::prepare_staging_buffer() +{ + if (allocator->mappable) + return; + + if (staging_allocator && staging_data) + return; + + size_t totalsize = alignSize(total() * elemsize, 4); + staging_data = staging_allocator->fastMalloc(totalsize); + + staging_refcount = (int*)((unsigned char*)staging_data + offsetof(VkBufferMemory, refcount)); + *staging_refcount = 1; +} + +inline void VkMat::discard_staging_buffer() +{ + if (allocator->mappable) + return; + + if (staging_refcount && NCNN_XADD(staging_refcount, -1) == 1) + { + if (staging_allocator && staging_data) + { + staging_allocator->fastFree(staging_data); + } + } + + staging_data = 0; + staging_refcount = 0; +} + +inline void VkMat::upload(const Mat& m) +{ + memcpy(mapped_ptr(), m.data, m.total() * m.elemsize); +} + +inline void VkMat::download(Mat& m) const +{ + memcpy(m.data, mapped_ptr(), total() * elemsize); +} + +inline Mat VkMat::mapped() const +{ + if (dims == 1) + return Mat(w, mapped_ptr(), elemsize, packing, 0); + + if (dims == 2) + return Mat(w, h, mapped_ptr(), elemsize, packing, 0); + + if (dims == 3) + return Mat(w, h, c, mapped_ptr(), elemsize, packing, 0); + + return Mat(); +} + +inline void* VkMat::mapped_ptr() const +{ + VkBufferMemory* mappable_data = allocator->mappable ? data : staging_data; + return (unsigned char*)mappable_data->mapped_ptr + mappable_data->offset + offset; +} + +inline void VkMat::addref() +{ + if (refcount) + NCNN_XADD(refcount, 1); + + if (staging_refcount) + NCNN_XADD(staging_refcount, 1); +} + +inline void VkMat::release() +{ + if (refcount && NCNN_XADD(refcount, -1) == 1) + { + if (allocator && data) + { + allocator->fastFree(data); + } + } + + if (staging_refcount && NCNN_XADD(staging_refcount, -1) == 1) + { + if (staging_allocator && staging_data) + { + staging_allocator->fastFree(staging_data); + } + } + + data = 0; + offset = 0; + staging_data = 0; + + elemsize = 0; + packing = 0; + + dims = 0; + w = 0; + h = 0; + c = 0; + + cstep = 0; + + refcount = 0; + staging_refcount = 0; +} + +inline bool VkMat::empty() const +{ + return data == 0 || total() == 0; +} + +inline size_t VkMat::total() const +{ + return cstep * c; +} + +inline VkMat VkMat::channel(int _c) +{ + return VkMat(w, h, data, cstep * _c * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline const VkMat VkMat::channel(int _c) const +{ + return VkMat(w, h, data, cstep * _c * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline VkMat VkMat::channel_range(int _c, int channels) +{ + return VkMat(w, h, channels, data, cstep * _c * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline const VkMat VkMat::channel_range(int _c, int channels) const +{ + return VkMat(w, h, channels, data, cstep * _c * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline VkMat VkMat::row_range(int y, int rows) +{ + return VkMat(w, rows, data, w * y * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline const VkMat VkMat::row_range(int y, int rows) const +{ + return VkMat(w, rows, data, w * y * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline VkMat VkMat::range(int x, int n) +{ + return VkMat(n, data, x * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline const VkMat VkMat::range(int x, int n) const +{ + return VkMat(n, data, x * elemsize, elemsize, packing, allocator, staging_allocator); +} + +inline VkBuffer VkMat::buffer() const +{ + return data->buffer; +} + +inline size_t VkMat::buffer_offset() const +{ + return data->offset + offset; +} + +inline VkBuffer VkMat::staging_buffer() const +{ + return staging_data->buffer; +} + +inline size_t VkMat::staging_buffer_offset() const +{ + return staging_data->offset; +} +#endif // NCNN_VULKAN + +} // namespace ncnn + +#endif // NCNN_MAT_H diff --git a/Prj-Win/3rd/ncnn/include/modelbin.h b/Prj-Win/3rd/ncnn/include/modelbin.h new file mode 100755 index 0000000..3237bee --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/modelbin.h @@ -0,0 +1,81 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_MODELBIN_H +#define NCNN_MODELBIN_H + +#include +#include "mat.h" +#include "platform.h" + +namespace ncnn { + +class Net; +class ModelBin +{ +public: + // element type + // 0 = auto + // 1 = float32 + // 2 = float16 + // 3 = int8 + // load vec + virtual Mat load(int w, int type) const = 0; + // load image + virtual Mat load(int w, int h, int type) const; + // load dim + virtual Mat load(int w, int h, int c, int type) const; +}; + +#if NCNN_STDIO +class ModelBinFromStdio : public ModelBin +{ +public: + // construct from file + ModelBinFromStdio(FILE* binfp); + + virtual Mat load(int w, int type) const; + +protected: + FILE* binfp; +}; +#endif // NCNN_STDIO + +class ModelBinFromMemory : public ModelBin +{ +public: + // construct from external memory + ModelBinFromMemory(const unsigned char*& mem); + + virtual Mat load(int w, int type) const; + +protected: + const unsigned char*& mem; +}; + +class ModelBinFromMatArray : public ModelBin +{ +public: + // construct from weight blob array + ModelBinFromMatArray(const Mat* weights); + + virtual Mat load(int w, int type) const; + +protected: + mutable const Mat* weights; +}; + +} // namespace ncnn + +#endif // NCNN_MODELBIN_H diff --git a/Prj-Win/3rd/ncnn/include/net.h b/Prj-Win/3rd/ncnn/include/net.h new file mode 100755 index 0000000..fb29bb0 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/net.h @@ -0,0 +1,248 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_NET_H +#define NCNN_NET_H + +#include +#include +#include "blob.h" +#include "layer.h" +#include "mat.h" +#include "platform.h" + +namespace ncnn { + +#if NCNN_VULKAN +class VkCompute; +#endif // NCNN_VULKAN +class Extractor; +class Net +{ +public: + // empty init + Net(); + // clear and destroy + ~Net(); + +#if NCNN_STRING + // register custom layer by layer type name + // return 0 if success + int register_custom_layer(const char* type, layer_creator_func creator); +#endif // NCNN_STRING + // register custom layer by layer type + // return 0 if success + int register_custom_layer(int index, layer_creator_func creator); + +#if NCNN_STDIO +#if NCNN_STRING + // load network structure from plain param file + // return 0 if success + int load_param(FILE* fp); + int load_param(const char* protopath); + int load_param_mem(const char* mem); +#endif // NCNN_STRING + // load network structure from binary param file + // return 0 if success + int load_param_bin(FILE* fp); + int load_param_bin(const char* protopath); + + // load network weight data from model file + // return 0 if success + int load_model(FILE* fp); + int load_model(const char* modelpath); +#endif // NCNN_STDIO + + // load network structure from external memory + // memory pointer must be 32-bit aligned + // return bytes consumed + int load_param(const unsigned char* mem); + + // reference network weight data from external memory + // weight data is not copied but referenced + // so external memory should be retained when used + // memory pointer must be 32-bit aligned + // return bytes consumed + int load_model(const unsigned char* mem); + + // unload network structure and weight data + void clear(); + + // construct an Extractor from network + Extractor create_extractor() const; + +public: + // enable winograd convolution optimization + // improve convolution 3x3 stride1 performace, may consume more memory + // changes should be applied before loading network structure and weight + // enabled by default + int use_winograd_convolution; + + // enable sgemm convolution optimization + // improve convolution 1x1 stride1 performace, may consume more memory + // changes should be applied before loading network structure and weight + // enabled by default + int use_sgemm_convolution; + + // enable quantized int8 inference + // use low-precision int8 path for quantized model + // changes should be applied before loading network structure and weight + // enabled by default + int use_int8_inference; + + // enable vulkan compute + int use_vulkan_compute; + +#if NCNN_VULKAN + + void set_vulkan_device(const VulkanDevice* vkdev); + +#endif // NCNN_VULKAN + +protected: + // parse the structure of network + // fuse int8 op dequantize and quantize by requantize + void fuse_network(); + +#if NCNN_VULKAN + + int upload_model(); + + int create_pipeline(); + + int destroy_pipeline(); + +#endif // NCNN_VULKAN + + friend class Extractor; +#if NCNN_STRING + int find_blob_index_by_name(const char* name) const; + int find_layer_index_by_name(const char* name) const; + int custom_layer_to_index(const char* type); + Layer* create_custom_layer(const char* type); +#endif // NCNN_STRING + Layer* create_custom_layer(int index); + int forward_layer(int layer_index, std::vector& blob_mats, Option& opt) const; + +#if NCNN_VULKAN + int forward_layer(int layer_index, std::vector& blob_mats, std::vector& blob_mats_gpu, std::vector& wait_barrier_counts, VkCompute& cmd, Option& opt) const; +#endif // NCNN_VULKAN + +protected: + std::vector blobs; + std::vector layers; + + std::vector custom_layer_registry; + +#if NCNN_VULKAN + const VulkanDevice* vkdev; + const VulkanDevice* vkdev_local; + + VkAllocator* weight_vkallocator; + VkAllocator* weight_staging_vkallocator; + + ncnn::Layer* cast_float32_to_float16; + ncnn::Layer* cast_float16_to_float32; + ncnn::Layer* packing_pack1; + ncnn::Layer* packing_pack4; +#endif // NCNN_VULKAN +}; + +class Extractor +{ +public: + // enable light mode + // intermediate blob will be recycled when enabled + // enabled by default + void set_light_mode(bool enable); + + // set thread count for this extractor + // this will overwrite the global setting + // default count is system depended + void set_num_threads(int num_threads); + + // set blob memory allocator + void set_blob_allocator(Allocator* allocator); + + // set workspace memory allocator + void set_workspace_allocator(Allocator* allocator); + +#if NCNN_VULKAN + void set_vulkan_compute(bool enable); + + void set_blob_vkallocator(VkAllocator* allocator); + + void set_workspace_vkallocator(VkAllocator* allocator); + + void set_staging_vkallocator(VkAllocator* allocator); +#endif // NCNN_VULKAN + +#if NCNN_STRING + // set input by blob name + // return 0 if success + int input(const char* blob_name, const Mat& in); + + // get result by blob name + // return 0 if success + int extract(const char* blob_name, Mat& feat); +#endif // NCNN_STRING + + // set input by blob index + // return 0 if success + int input(int blob_index, const Mat& in); + + // get result by blob index + // return 0 if success + int extract(int blob_index, Mat& feat); + +#if NCNN_VULKAN +#if NCNN_STRING + // set input by blob name + // return 0 if success + int input(const char* blob_name, const VkMat& in); + + // get result by blob name + // return 0 if success + int extract(const char* blob_name, VkMat& feat, VkCompute& cmd); +#endif // NCNN_STRING + + // set input by blob index + // return 0 if success + int input(int blob_index, const VkMat& in); + + // get result by blob index + // return 0 if success + int extract(int blob_index, VkMat& feat, VkCompute& cmd); +#endif // NCNN_VULKAN + +protected: + friend Extractor Net::create_extractor() const; + Extractor(const Net* net, int blob_count); + +private: + const Net* net; + std::vector blob_mats; + Option opt; + +#if NCNN_VULKAN + std::vector blob_mats_gpu; + + // the barrier count must be hit before reclaiming buffer memory alias-able + std::vector wait_barrier_counts; +#endif // NCNN_VULKAN +}; + +} // namespace ncnn + +#endif // NCNN_NET_H diff --git a/Prj-Win/3rd/ncnn/include/opencv.h b/Prj-Win/3rd/ncnn/include/opencv.h new file mode 100755 index 0000000..463b0af --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/opencv.h @@ -0,0 +1,266 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_OPENCV_H +#define NCNN_OPENCV_H + +#include "platform.h" + +#if NCNN_OPENCV + +#include +#include +#include "mat.h" + +// minimal opencv style data structure implementation +namespace cv +{ + +struct Size +{ + Size() : width(0), height(0) {} + Size(int _w, int _h) : width(_w), height(_h) {} + + int width; + int height; +}; + +template +struct Rect_ +{ + Rect_() : x(0), y(0), width(0), height(0) {} + Rect_(_Tp _x, _Tp _y, _Tp _w, _Tp _h) : x(_x), y(_y), width(_w), height(_h) {} + + _Tp x; + _Tp y; + _Tp width; + _Tp height; + + // area + _Tp area() const + { + return width * height; + } +}; + +template static inline Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) +{ + _Tp x1 = std::max(a.x, b.x), y1 = std::max(a.y, b.y); + a.width = std::min(a.x + a.width, b.x + b.width) - x1; + a.height = std::min(a.y + a.height, b.y + b.height) - y1; + a.x = x1; a.y = y1; + if( a.width <= 0 || a.height <= 0 ) + a = Rect_<_Tp>(); + return a; +} + +template static inline Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) +{ + _Tp x1 = std::min(a.x, b.x), y1 = std::min(a.y, b.y); + a.width = std::max(a.x + a.width, b.x + b.width) - x1; + a.height = std::max(a.y + a.height, b.y + b.height) - y1; + a.x = x1; a.y = y1; + return a; +} + +template static inline Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + Rect_<_Tp> c = a; + return c &= b; +} + +template static inline Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + Rect_<_Tp> c = a; + return c |= b; +} + +typedef Rect_ Rect; +typedef Rect_ Rect2f; + +template +struct Point_ +{ + Point_() : x(0), y(0) {} + Point_(_Tp _x, _Tp _y) : x(_x), y(_y) {} + + _Tp x; + _Tp y; +}; + +typedef Point_ Point; +typedef Point_ Point2f; + +#define CV_8UC1 1 +#define CV_8UC3 3 +#define CV_8UC4 4 +#define CV_32FC1 4 + +struct Mat +{ + Mat() : data(0), refcount(0), rows(0), cols(0), c(0) {} + + Mat(int _rows, int _cols, int flags) : data(0), refcount(0) + { + create(_rows, _cols, flags); + } + + // copy + Mat(const Mat& m) : data(m.data), refcount(m.refcount) + { + if (refcount) + NCNN_XADD(refcount, 1); + + rows = m.rows; + cols = m.cols; + c = m.c; + } + + Mat(int _rows, int _cols, int flags, void* _data) : data((unsigned char*)_data), refcount(0) + { + rows = _rows; + cols = _cols; + c = flags; + } + + ~Mat() + { + release(); + } + + // assign + Mat& operator=(const Mat& m) + { + if (this == &m) + return *this; + + if (m.refcount) + NCNN_XADD(m.refcount, 1); + + release(); + + data = m.data; + refcount = m.refcount; + + rows = m.rows; + cols = m.cols; + c = m.c; + + return *this; + } + + void create(int _rows, int _cols, int flags) + { + release(); + + rows = _rows; + cols = _cols; + c = flags; + + if (total() > 0) + { + // refcount address must be aligned, so we expand totalsize here + size_t totalsize = (total() + 3) >> 2 << 2; + data = (unsigned char*)ncnn::fastMalloc(totalsize + (int)sizeof(*refcount)); + refcount = (int*)(((unsigned char*)data) + totalsize); + *refcount = 1; + } + } + + void release() + { + if (refcount && NCNN_XADD(refcount, -1) == 1) + ncnn::fastFree(data); + + data = 0; + + rows = 0; + cols = 0; + c = 0; + + refcount = 0; + } + + Mat clone() const + { + if (empty()) + return Mat(); + + Mat m(rows, cols, c); + + if (total() > 0) + { + memcpy(m.data, data, total()); + } + + return m; + } + + bool empty() const { return data == 0 || total() == 0; } + + int channels() const { return c; } + + size_t total() const { return cols * rows * c; } + + const unsigned char* ptr(int y) const { return data + y * cols * c; } + + unsigned char* ptr(int y) { return data + y * cols * c; } + + // roi + Mat operator()( const Rect& roi ) const + { + if (empty()) + return Mat(); + + Mat m(roi.height, roi.width, c); + + int sy = roi.y; + for (int y = 0; y < roi.height; y++) + { + const unsigned char* sptr = ptr(sy) + roi.x * c; + unsigned char* dptr = m.ptr(y); + memcpy(dptr, sptr, roi.width * c); + sy++; + } + + return m; + } + + unsigned char* data; + + // pointer to the reference counter; + // when points to user-allocated data, the pointer is NULL + int* refcount; + + int rows; + int cols; + + int c; + +}; + +#define CV_LOAD_IMAGE_GRAYSCALE 1 +#define CV_LOAD_IMAGE_COLOR 3 +Mat imread(const std::string& path, int flags); +void imwrite(const std::string& path, const Mat& m); + +#if NCNN_PIXEL +void resize(const Mat& src, Mat& dst, const Size& size, float sw = 0.f, float sh = 0.f, int flags = 0); +#endif // NCNN_PIXEL + +} // namespace cv + +#endif // NCNN_OPENCV + +#endif // NCNN_OPENCV_H diff --git a/Prj-Win/3rd/ncnn/include/paramdict.h b/Prj-Win/3rd/ncnn/include/paramdict.h new file mode 100755 index 0000000..d67e6d2 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/paramdict.h @@ -0,0 +1,79 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_PARAMDICT_H +#define NCNN_PARAMDICT_H + +#include +#include "mat.h" +#include "platform.h" + +// at most 20 parameters +#define NCNN_MAX_PARAM_COUNT 20 + +namespace ncnn { + +class Net; +class ParamDict +{ +public: + // empty + ParamDict(); + + // get int + int get(int id, int def) const; + // get float + float get(int id, float def) const; + // get array + Mat get(int id, const Mat& def) const; + + // set int + void set(int id, int i); + // set float + void set(int id, float f); + // set array + void set(int id, const Mat& v); + +public: + int use_winograd_convolution; + int use_sgemm_convolution; + int use_int8_inference; + int use_vulkan_compute; + +protected: + friend class Net; + + void clear(); + +#if NCNN_STDIO +#if NCNN_STRING + int load_param(FILE* fp); + int load_param_mem(const char*& mem); +#endif // NCNN_STRING + int load_param_bin(FILE* fp); +#endif // NCNN_STDIO + int load_param(const unsigned char*& mem); + +protected: + struct + { + int loaded; + union { int i; float f; }; + Mat v; + } params[NCNN_MAX_PARAM_COUNT]; +}; + +} // namespace ncnn + +#endif // NCNN_PARAMDICT_H diff --git a/Prj-Win/3rd/ncnn/include/pipeline.h b/Prj-Win/3rd/ncnn/include/pipeline.h new file mode 100755 index 0000000..f0e1e97 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/pipeline.h @@ -0,0 +1,69 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_PIPELINE_H +#define NCNN_PIPELINE_H + +#include "platform.h" +#include "mat.h" +#if NCNN_VULKAN +#include +#include "gpu.h" +#endif // NCNN_VULKAN + +namespace ncnn { + +#if NCNN_VULKAN +class Pipeline +{ +public: + Pipeline(const VulkanDevice* vkdev); + ~Pipeline(); + +public: + void set_optimal_local_size_xyz(int w = 32, int h = 32, int c = 32); + + int create(const char* name, const std::vector& specializations, + int binding_count, int push_constant_count); + void destroy(); + +protected: + int create_descriptorset_layout(int binding_count); + int create_pipeline_layout(int push_constant_count); + int create_pipeline(const char* name, const std::vector& specializations); + int create_descriptor_update_template(int binding_count); + +public: + const VulkanDevice* vkdev; + + // shared among each layer type instance + VkShaderModule shader_module; + + VkDescriptorSetLayout descriptorset_layout; + VkPipelineLayout pipeline_layout; + + // op forward TODO use pipeline cache ? + VkPipeline pipeline; + + VkDescriptorUpdateTemplateKHR descriptor_update_template; + + uint32_t local_size_x; + uint32_t local_size_y; + uint32_t local_size_z; +}; +#endif // NCNN_VULKAN + +} // namespace ncnn + +#endif // NCNN_PIPELINE_H diff --git a/Prj-Win/3rd/ncnn/include/platform.h b/Prj-Win/3rd/ncnn/include/platform.h new file mode 100755 index 0000000..d7b2eb3 --- /dev/null +++ b/Prj-Win/3rd/ncnn/include/platform.h @@ -0,0 +1,28 @@ +// Tencent is pleased to support the open source community by making ncnn available. +// +// Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef NCNN_PLATFORM_H +#define NCNN_PLATFORM_H + +#define NCNN_STDIO 1 +#define NCNN_STRING 1 +#define NCNN_OPENCV 0 +#define NCNN_BENCHMARK 0 +#define NCNN_PIXEL 1 +#define NCNN_PIXEL_ROTATE 0 +#define NCNN_VULKAN 0 +#define NCNN_REQUANT 0 +#define NCNN_IM2COL_SGEMM 0 + +#endif // NCNN_PLATFORM_H diff --git a/Prj-Win/3rd/ncnn/lib/ncnn.lib b/Prj-Win/3rd/ncnn/lib/ncnn.lib new file mode 100755 index 0000000000000000000000000000000000000000..56a6a94dfab16b73b898daaf7eaace3984a456c9 GIT binary patch literal 1597712 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⪙DBM@USvr5hy80@x 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%0AC^ELALN8mdfe;1GX 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℘#aYdvmDv4V6EQ+O6XI3iz3fY)Q{w??H{WfQu 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�OiV_C77YH4Fd-p_pfkF!J# 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 z 0 \f$). + +![](pics/distortion_examples.png) +![](pics/distortion_examples2.png) + +In some cases the image sensor may be tilted in order to focus an oblique plane in front of the +camera (Scheimpfug condition). This can be useful for particle image velocimetry (PIV) or +triangulation with a laser fan. The tilt causes a perspective distortion of \f$x''\f$ and +\f$y''\f$. This distortion can be modelled in the following way, see e.g. @cite Louhichi07. + +\f[\begin{array}{l} +s\vecthree{x'''}{y'''}{1} = +\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}(\tau_x, \tau_y)} +{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)} +{0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\ +u = f_x*x''' + c_x \\ +v = f_y*y''' + c_y +\end{array}\f] + +where the matrix \f$R(\tau_x, \tau_y)\f$ is defined by two rotations with angular parameter \f$\tau_x\f$ +and \f$\tau_y\f$, respectively, + +\f[ +R(\tau_x, \tau_y) = +\vecthreethree{\cos(\tau_y)}{0}{-\sin(\tau_y)}{0}{1}{0}{\sin(\tau_y)}{0}{\cos(\tau_y)} +\vecthreethree{1}{0}{0}{0}{\cos(\tau_x)}{\sin(\tau_x)}{0}{-\sin(\tau_x)}{\cos(\tau_x)} = +\vecthreethree{\cos(\tau_y)}{\sin(\tau_y)\sin(\tau_x)}{-\sin(\tau_y)\cos(\tau_x)} +{0}{\cos(\tau_x)}{\sin(\tau_x)} +{\sin(\tau_y)}{-\cos(\tau_y)\sin(\tau_x)}{\cos(\tau_y)\cos(\tau_x)}. +\f] + +In the functions below the coefficients are passed or returned as + +\f[(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f] + +vector. That is, if the vector contains four elements, it means that \f$k_3=0\f$ . 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. If, for example, a +camera has been calibrated on images of 320 x 240 resolution, absolutely the same distortion +coefficients can be used for 640 x 480 images from the same camera while \f$f_x\f$, \f$f_y\f$, \f$c_x\f$, and +\f$c_y\f$ need to be scaled appropriately. + +The functions below use the above model to do the following: + +- 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 (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. + +@note + - A calibration sample for 3 cameras in horizontal position can be found at + opencv_source_code/samples/cpp/3calibration.cpp + - A calibration sample based on a sequence of images can be found at + opencv_source_code/samples/cpp/calibration.cpp + - A calibration sample in order to do 3D reconstruction can be found at + opencv_source_code/samples/cpp/build3dmodel.cpp + - A calibration example on stereo calibration can be found at + opencv_source_code/samples/cpp/stereo_calib.cpp + - A calibration example on stereo matching can be found at + opencv_source_code/samples/cpp/stereo_match.cpp + - (Python) A camera calibration sample can be found at + opencv_source_code/samples/python/calibrate.py + + @{ + @defgroup calib3d_fisheye Fisheye camera model + + Definitions: Let P be a point in 3D of coordinates X in the world reference frame (stored in the + matrix X) The coordinate vector of P in the camera reference frame is: + + \f[Xc = R X + T\f] + + where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om); call x, y + and z the 3 coordinates of Xc: + + \f[x = Xc_1 \\ y = Xc_2 \\ z = Xc_3\f] + + The pinhole projection coordinates of P is [a; b] where + + \f[a = x / z \ and \ b = y / z \\ r^2 = a^2 + b^2 \\ \theta = atan(r)\f] + + Fisheye distortion: + + \f[\theta_d = \theta (1 + k_1 \theta^2 + k_2 \theta^4 + k_3 \theta^6 + k_4 \theta^8)\f] + + The distorted point coordinates are [x'; y'] where + + \f[x' = (\theta_d / r) a \\ y' = (\theta_d / r) b \f] + + Finally, conversion into pixel coordinates: The final pixel coordinates vector [u; v] where: + + \f[u = f_x (x' + \alpha y') + c_x \\ + v = f_y y' + c_y\f] + + @defgroup calib3d_c C API + + @} + */ + +namespace cv +{ + +//! @addtogroup calib3d +//! @{ + +//! type of the robust estimation algorithm +enum { LMEDS = 4, //!< least-median of squares algorithm + RANSAC = 8, //!< RANSAC algorithm + RHO = 16 //!< RHO algorithm + }; + +enum SolvePnPMethod { + SOLVEPNP_ITERATIVE = 0, + SOLVEPNP_EPNP = 1, //!< EPnP: Efficient Perspective-n-Point Camera Pose Estimation @cite lepetit2009epnp + SOLVEPNP_P3P = 2, //!< Complete Solution Classification for the Perspective-Three-Point Problem @cite gao2003complete + SOLVEPNP_DLS = 3, //!< A Direct Least-Squares (DLS) Method for PnP @cite hesch2011direct + SOLVEPNP_UPNP = 4, //!< Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation @cite penate2013exhaustive + SOLVEPNP_AP3P = 5, //!< An Efficient Algebraic Solution to the Perspective-Three-Point Problem @cite Ke17 + SOLVEPNP_IPPE = 6, //!< Infinitesimal Plane-Based Pose Estimation @cite Collins14 \n + //!< Object points must be coplanar. + SOLVEPNP_IPPE_SQUARE = 7, //!< Infinitesimal Plane-Based Pose Estimation @cite Collins14 \n + //!< This is a special case suitable for marker pose estimation.\n + //!< 4 coplanar object points must be defined in the following order: + //!< - point 0: [-squareLength / 2, squareLength / 2, 0] + //!< - point 1: [ squareLength / 2, squareLength / 2, 0] + //!< - point 2: [ squareLength / 2, -squareLength / 2, 0] + //!< - point 3: [-squareLength / 2, -squareLength / 2, 0] +#ifndef CV_DOXYGEN + SOLVEPNP_MAX_COUNT //!< Used for count +#endif +}; + +enum { CALIB_CB_ADAPTIVE_THRESH = 1, + CALIB_CB_NORMALIZE_IMAGE = 2, + CALIB_CB_FILTER_QUADS = 4, + CALIB_CB_FAST_CHECK = 8, + CALIB_CB_EXHAUSTIVE = 16, + CALIB_CB_ACCURACY = 32 + }; + +enum { CALIB_CB_SYMMETRIC_GRID = 1, + CALIB_CB_ASYMMETRIC_GRID = 2, + CALIB_CB_CLUSTERING = 4 + }; + +enum { CALIB_NINTRINSIC = 18, + CALIB_USE_INTRINSIC_GUESS = 0x00001, + CALIB_FIX_ASPECT_RATIO = 0x00002, + CALIB_FIX_PRINCIPAL_POINT = 0x00004, + CALIB_ZERO_TANGENT_DIST = 0x00008, + CALIB_FIX_FOCAL_LENGTH = 0x00010, + CALIB_FIX_K1 = 0x00020, + CALIB_FIX_K2 = 0x00040, + CALIB_FIX_K3 = 0x00080, + CALIB_FIX_K4 = 0x00800, + CALIB_FIX_K5 = 0x01000, + CALIB_FIX_K6 = 0x02000, + CALIB_RATIONAL_MODEL = 0x04000, + CALIB_THIN_PRISM_MODEL = 0x08000, + CALIB_FIX_S1_S2_S3_S4 = 0x10000, + CALIB_TILTED_MODEL = 0x40000, + CALIB_FIX_TAUX_TAUY = 0x80000, + CALIB_USE_QR = 0x100000, //!< use QR instead of SVD decomposition for solving. Faster but potentially less precise + CALIB_FIX_TANGENT_DIST = 0x200000, + // only for stereo + CALIB_FIX_INTRINSIC = 0x00100, + CALIB_SAME_FOCAL_LENGTH = 0x00200, + // for stereo rectification + CALIB_ZERO_DISPARITY = 0x00400, + CALIB_USE_LU = (1 << 17), //!< use LU instead of SVD decomposition for solving. much faster but potentially less precise + CALIB_USE_EXTRINSIC_GUESS = (1 << 22) //!< for stereoCalibrate + }; + +//! the algorithm for finding fundamental matrix +enum { FM_7POINT = 1, //!< 7-point algorithm + FM_8POINT = 2, //!< 8-point algorithm + FM_LMEDS = 4, //!< least-median algorithm. 7-point algorithm is used. + FM_RANSAC = 8 //!< RANSAC algorithm. It needs at least 15 points. 7-point algorithm is used. + }; + +enum HandEyeCalibrationMethod +{ + CALIB_HAND_EYE_TSAI = 0, //!< A New Technique for Fully Autonomous and Efficient 3D Robotics Hand/Eye Calibration @cite Tsai89 + CALIB_HAND_EYE_PARK = 1, //!< Robot Sensor Calibration: Solving AX = XB on the Euclidean Group @cite Park94 + CALIB_HAND_EYE_HORAUD = 2, //!< Hand-eye Calibration @cite Horaud95 + CALIB_HAND_EYE_ANDREFF = 3, //!< On-line Hand-Eye Calibration @cite Andreff99 + CALIB_HAND_EYE_DANIILIDIS = 4 //!< Hand-Eye Calibration Using Dual Quaternions @cite Daniilidis98 +}; + + +/** @brief Converts a rotation matrix to a rotation vector or vice versa. + +@param src Input rotation vector (3x1 or 1x3) or rotation matrix (3x3). +@param dst Output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively. +@param jacobian Optional output Jacobian matrix, 3x9 or 9x3, which is a matrix of partial +derivatives of the output array components with respect to the input array components. + +\f[\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}\f] + +Inverse transformation can be also done easily, since + +\f[\sin ( \theta ) \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} = \frac{R - R^T}{2}\f] + +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 calibrateCamera, stereoCalibrate, or solvePnP . + */ +CV_EXPORTS_W void Rodrigues( InputArray src, OutputArray dst, OutputArray jacobian = noArray() ); + + + +/** Levenberg-Marquardt solver. Starting with the specified vector of parameters it + optimizes the target vector criteria "err" + (finds local minima of each target vector component absolute value). + + When needed, it calls user-provided callback. +*/ +class CV_EXPORTS LMSolver : public Algorithm +{ +public: + class CV_EXPORTS Callback + { + public: + virtual ~Callback() {} + /** + computes error and Jacobian for the specified vector of parameters + + @param param the current vector of parameters + @param err output vector of errors: err_i = actual_f_i - ideal_f_i + @param J output Jacobian: J_ij = d(err_i)/d(param_j) + + when J=noArray(), it means that it does not need to be computed. + Dimensionality of error vector and param vector can be different. + The callback should explicitly allocate (with "create" method) each output array + (unless it's noArray()). + */ + virtual bool compute(InputArray param, OutputArray err, OutputArray J) const = 0; + }; + + /** + Runs Levenberg-Marquardt algorithm using the passed vector of parameters as the start point. + The final vector of parameters (whether the algorithm converged or not) is stored at the same + vector. The method returns the number of iterations used. If it's equal to the previously specified + maxIters, there is a big chance the algorithm did not converge. + + @param param initial/final vector of parameters. + + Note that the dimensionality of parameter space is defined by the size of param vector, + and the dimensionality of optimized criteria is defined by the size of err vector + computed by the callback. + */ + virtual int run(InputOutputArray param) const = 0; + + /** + Sets the maximum number of iterations + @param maxIters the number of iterations + */ + virtual void setMaxIters(int maxIters) = 0; + /** + Retrieves the current maximum number of iterations + */ + virtual int getMaxIters() const = 0; + + /** + Creates Levenberg-Marquard solver + + @param cb callback + @param maxIters maximum number of iterations that can be further + modified using setMaxIters() method. + */ + static Ptr create(const Ptr& cb, int maxIters); + static Ptr create(const Ptr& cb, int maxIters, double eps); +}; + + + +/** @example samples/cpp/tutorial_code/features2D/Homography/pose_from_homography.cpp +An example program about pose estimation from coplanar points + +Check @ref tutorial_homography "the corresponding tutorial" for more details +*/ + +/** @brief Finds a perspective transformation between two planes. + +@param srcPoints Coordinates of the points in the original plane, a matrix of the type CV_32FC2 +or vector\ . +@param dstPoints Coordinates of the points in the target plane, a matrix of the type CV_32FC2 or +a vector\ . +@param method Method used to compute a homography matrix. The following methods are possible: +- **0** - a regular method using all the points, i.e., the least squares method +- **RANSAC** - RANSAC-based robust method +- **LMEDS** - Least-Median robust method +- **RHO** - PROSAC-based robust method +@param ransacReprojThreshold Maximum allowed reprojection error to treat a point pair as an inlier +(used in the RANSAC and RHO methods only). That is, if +\f[\| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} * \texttt{srcPoints} _i) \|_2 > \texttt{ransacReprojThreshold}\f] +then the point \f$i\f$ is considered as an outlier. If srcPoints and dstPoints are measured in pixels, +it usually makes sense to set this parameter somewhere in the range of 1 to 10. +@param mask Optional output mask set by a robust method ( RANSAC or LMEDS ). Note that the input +mask values are ignored. +@param maxIters The maximum number of RANSAC iterations. +@param confidence Confidence level, between 0 and 1. + +The function finds and returns the perspective transformation \f$H\f$ between the source and the +destination planes: + +\f[s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1}\f] + +so that the back-projection error + +\f[\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\f] + +is minimized. If the parameter method is set to the default value 0, the function uses all the point +pairs to compute an initial homography estimate with a simple least-squares scheme. + +However, if not all of the point pairs ( \f$srcPoints_i\f$, \f$dstPoints_i\f$ ) fit the rigid perspective +transformation (that is, there are some outliers), this initial estimate will be poor. In this case, +you can use one of the three robust methods. The methods RANSAC, LMeDS and RHO try many different +random subsets of the corresponding point pairs (of four pairs each, collinear pairs are discarded), estimate the homography matrix +using this subset and a simple least-squares algorithm, and then compute the quality/goodness of the +computed homography (which is the number of inliers for RANSAC or the least 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 case of a robust method) with the Levenberg-Marquardt method to reduce the +re-projection error even more. + +The methods RANSAC and RHO can handle practically any ratio of outliers but need a 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 there are no outliers and the +noise is rather small, use the default method (method=0). + +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 \f$h_{33}=1\f$. Note that whenever an \f$H\f$ matrix +cannot be estimated, an empty one will be returned. + +@sa +getAffineTransform, estimateAffine2D, estimateAffinePartial2D, getPerspectiveTransform, warpPerspective, +perspectiveTransform + */ +CV_EXPORTS_W Mat findHomography( InputArray srcPoints, InputArray dstPoints, + int method = 0, double ransacReprojThreshold = 3, + OutputArray mask=noArray(), const int maxIters = 2000, + const double confidence = 0.995); + +/** @overload */ +CV_EXPORTS Mat findHomography( InputArray srcPoints, InputArray dstPoints, + OutputArray mask, int method = 0, double ransacReprojThreshold = 3 ); + +/** @brief Computes an RQ decomposition of 3x3 matrices. + +@param src 3x3 input matrix. +@param mtxR Output 3x3 upper-triangular matrix. +@param mtxQ Output 3x3 orthogonal matrix. +@param Qx Optional output 3x3 rotation matrix around x-axis. +@param Qy Optional output 3x3 rotation matrix around y-axis. +@param Qz Optional output 3x3 rotation matrix around z-axis. + +The function computes a RQ decomposition using the given rotations. This function is used in +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 in +degrees (as the return value) that could be used in OpenGL. Note, there is always more than one +sequence of rotations about the three principal axes that results in the same orientation of an +object, e.g. see @cite Slabaugh . Returned tree rotation matrices and corresponding three Euler angles +are only one of the possible solutions. + */ +CV_EXPORTS_W Vec3d RQDecomp3x3( InputArray src, OutputArray mtxR, OutputArray mtxQ, + OutputArray Qx = noArray(), + OutputArray Qy = noArray(), + OutputArray Qz = noArray()); + +/** @brief Decomposes a projection matrix into a rotation matrix and a camera matrix. + +@param projMatrix 3x4 input projection matrix P. +@param cameraMatrix Output 3x3 camera matrix K. +@param rotMatrix Output 3x3 external rotation matrix R. +@param transVect Output 4x1 translation vector T. +@param rotMatrixX Optional 3x3 rotation matrix around x-axis. +@param rotMatrixY Optional 3x3 rotation matrix around y-axis. +@param rotMatrixZ Optional 3x3 rotation matrix around z-axis. +@param eulerAngles Optional three-element vector containing three Euler angles of rotation in +degrees. + +The function computes a decomposition of a projection matrix into a calibration and a rotation +matrix and the position of a camera. + +It optionally returns three rotation matrices, one for each axis, and three Euler angles that could +be used in OpenGL. Note, there is always more than one sequence of rotations about the three +principal axes that results in the same orientation of an object, e.g. see @cite Slabaugh . Returned +tree rotation matrices and corresponding three Euler angles are only one of the possible solutions. + +The function is based on RQDecomp3x3 . + */ +CV_EXPORTS_W void decomposeProjectionMatrix( InputArray projMatrix, OutputArray cameraMatrix, + OutputArray rotMatrix, OutputArray transVect, + OutputArray rotMatrixX = noArray(), + OutputArray rotMatrixY = noArray(), + OutputArray rotMatrixZ = noArray(), + OutputArray eulerAngles =noArray() ); + +/** @brief Computes partial derivatives of the matrix product for each multiplied matrix. + +@param A First multiplied matrix. +@param B Second multiplied matrix. +@param dABdA First output derivative matrix d(A\*B)/dA of size +\f$\texttt{A.rows*B.cols} \times {A.rows*A.cols}\f$ . +@param dABdB Second output derivative matrix d(A\*B)/dB of size +\f$\texttt{A.rows*B.cols} \times {B.rows*B.cols}\f$ . + +The function computes partial derivatives of the elements of the matrix product \f$A*B\f$ with regard to +the elements of each of the two input matrices. The function is used to compute the Jacobian +matrices in stereoCalibrate but can also be used in any other similar optimization function. + */ +CV_EXPORTS_W void matMulDeriv( InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB ); + +/** @brief Combines two rotation-and-shift transformations. + +@param rvec1 First rotation vector. +@param tvec1 First translation vector. +@param rvec2 Second rotation vector. +@param tvec2 Second translation vector. +@param rvec3 Output rotation vector of the superposition. +@param tvec3 Output translation vector of the superposition. +@param dr3dr1 Optional output derivative of rvec3 with regard to rvec1 +@param dr3dt1 Optional output derivative of rvec3 with regard to tvec1 +@param dr3dr2 Optional output derivative of rvec3 with regard to rvec2 +@param dr3dt2 Optional output derivative of rvec3 with regard to tvec2 +@param dt3dr1 Optional output derivative of tvec3 with regard to rvec1 +@param dt3dt1 Optional output derivative of tvec3 with regard to tvec1 +@param dt3dr2 Optional output derivative of tvec3 with regard to rvec2 +@param dt3dt2 Optional output derivative of tvec3 with regard to tvec2 + +The functions compute: + +\f[\begin{array}{l} \texttt{rvec3} = \mathrm{rodrigues} ^{-1} \left ( \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \mathrm{rodrigues} ( \texttt{rvec1} ) \right ) \\ \texttt{tvec3} = \mathrm{rodrigues} ( \texttt{rvec2} ) \cdot \texttt{tvec1} + \texttt{tvec2} \end{array} ,\f] + +where \f$\mathrm{rodrigues}\f$ denotes a rotation vector to a rotation matrix transformation, and +\f$\mathrm{rodrigues}^{-1}\f$ denotes the inverse transformation. See Rodrigues for details. + +Also, the functions can compute the derivatives of the output vectors with regards to the input +vectors (see matMulDeriv ). The functions are used inside stereoCalibrate but can also be used in +your own code where Levenberg-Marquardt or another gradient-based solver is used to optimize a +function that contains a matrix multiplication. + */ +CV_EXPORTS_W void composeRT( InputArray rvec1, InputArray tvec1, + InputArray rvec2, InputArray tvec2, + OutputArray rvec3, OutputArray tvec3, + OutputArray dr3dr1 = noArray(), OutputArray dr3dt1 = noArray(), + OutputArray dr3dr2 = noArray(), OutputArray dr3dt2 = noArray(), + OutputArray dt3dr1 = noArray(), OutputArray dt3dt1 = noArray(), + OutputArray dt3dr2 = noArray(), OutputArray dt3dt2 = noArray() ); + +/** @brief Projects 3D points to an image plane. + +@param objectPoints Array of object points, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel (or +vector\ ), where N is the number of points in the view. +@param rvec Rotation vector. See Rodrigues for details. +@param tvec Translation vector. +@param cameraMatrix Camera matrix \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is empty, the zero distortion coefficients are assumed. +@param imagePoints Output array of image points, 1xN/Nx1 2-channel, or +vector\ . +@param jacobian Optional output 2Nx(10+\) jacobian matrix of derivatives of image +points with respect to components of the rotation vector, translation vector, focal lengths, +coordinates of the principal point and the distortion coefficients. In the old interface different +components of the jacobian are returned via different output parameters. +@param aspectRatio Optional "fixed aspect ratio" parameter. If the parameter is not 0, the +function assumes that the aspect ratio (*fx/fy*) is fixed and correspondingly adjusts the jacobian +matrix. + +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 +calibrateCamera, solvePnP, and stereoCalibrate . The function itself can also be used to compute a +re-projection error given the current intrinsic and extrinsic parameters. + +@note By setting rvec=tvec=(0,0,0) or by setting cameraMatrix to a 3x3 identity matrix, or by +passing zero distortion coefficients, you can get various useful partial cases of the function. This +means that 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. + */ +CV_EXPORTS_W void projectPoints( InputArray objectPoints, + InputArray rvec, InputArray tvec, + InputArray cameraMatrix, InputArray distCoeffs, + OutputArray imagePoints, + OutputArray jacobian = noArray(), + double aspectRatio = 0 ); + +/** @example samples/cpp/tutorial_code/features2D/Homography/homography_from_camera_displacement.cpp +An example program about homography from the camera displacement + +Check @ref tutorial_homography "the corresponding tutorial" for more details +*/ + +/** @brief Finds an object pose from 3D-2D point correspondences. +This function returns the rotation and the translation vectors that transform a 3D point expressed in the object +coordinate frame to the camera coordinate frame, using different methods: +- P3P methods (@ref SOLVEPNP_P3P, @ref SOLVEPNP_AP3P): need 4 input points to return a unique solution. +- @ref SOLVEPNP_IPPE Input points must be >= 4 and object points must be coplanar. +- @ref SOLVEPNP_IPPE_SQUARE Special case suitable for marker pose estimation. +Number of input points must be 4. Object points must be defined in the following order: + - point 0: [-squareLength / 2, squareLength / 2, 0] + - point 1: [ squareLength / 2, squareLength / 2, 0] + - point 2: [ squareLength / 2, -squareLength / 2, 0] + - point 3: [-squareLength / 2, -squareLength / 2, 0] +- for all the other flags, number of input points must be >= 4 and object points can be in any configuration. + +@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or +1xN/Nx1 3-channel, where N is the number of points. vector\ can be also passed here. +@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel, +where N is the number of points. vector\ can be also passed here. +@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are +assumed. +@param rvec Output rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from +the model coordinate system to the camera coordinate system. +@param tvec Output translation vector. +@param useExtrinsicGuess Parameter used for #SOLVEPNP_ITERATIVE. If true (1), the function uses +the provided rvec and tvec values as initial approximations of the rotation and translation +vectors, respectively, and further optimizes them. +@param flags Method for solving a PnP problem: +- **SOLVEPNP_ITERATIVE** Iterative method is based on a Levenberg-Marquardt optimization. In +this case the function finds such a pose that minimizes reprojection error, that is the sum +of squared distances between the observed projections imagePoints and the projected (using +projectPoints ) objectPoints . +- **SOLVEPNP_P3P** Method is based on the paper of X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang +"Complete Solution Classification for the Perspective-Three-Point Problem" (@cite gao2003complete). +In this case the function requires exactly four object and image points. +- **SOLVEPNP_AP3P** Method is based on the paper of T. Ke, S. Roumeliotis +"An Efficient Algebraic Solution to the Perspective-Three-Point Problem" (@cite Ke17). +In this case the function requires exactly four object and image points. +- **SOLVEPNP_EPNP** Method has been introduced by F. Moreno-Noguer, V. Lepetit and P. Fua in the +paper "EPnP: Efficient Perspective-n-Point Camera Pose Estimation" (@cite lepetit2009epnp). +- **SOLVEPNP_DLS** Method is based on the paper of J. Hesch and S. Roumeliotis. +"A Direct Least-Squares (DLS) Method for PnP" (@cite hesch2011direct). +- **SOLVEPNP_UPNP** Method is based on the paper of A. Penate-Sanchez, J. Andrade-Cetto, +F. Moreno-Noguer. "Exhaustive Linearization for Robust Camera Pose and Focal Length +Estimation" (@cite penate2013exhaustive). In this case the function also estimates the parameters \f$f_x\f$ and \f$f_y\f$ +assuming that both have the same value. Then the cameraMatrix is updated with the estimated +focal length. +- **SOLVEPNP_IPPE** Method is based on the paper of T. Collins and A. Bartoli. +"Infinitesimal Plane-Based Pose Estimation" (@cite Collins14). This method requires coplanar object points. +- **SOLVEPNP_IPPE_SQUARE** Method is based on the paper of Toby Collins and Adrien Bartoli. +"Infinitesimal Plane-Based Pose Estimation" (@cite Collins14). This method is suitable for marker pose estimation. +It requires 4 coplanar object points defined in the following order: + - point 0: [-squareLength / 2, squareLength / 2, 0] + - point 1: [ squareLength / 2, squareLength / 2, 0] + - point 2: [ squareLength / 2, -squareLength / 2, 0] + - point 3: [-squareLength / 2, -squareLength / 2, 0] + +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, see the figure below +(more precisely, the X-axis of the camera frame is pointing to the right, the Y-axis downward +and the Z-axis forward). + +![](pnp.jpg) + +Points expressed in the world frame \f$ \bf{X}_w \f$ are projected into the image plane \f$ \left[ u, v \right] \f$ +using the perspective projection model \f$ \Pi \f$ and the camera intrinsic parameters matrix \f$ \bf{A} \f$: + +\f[ + \begin{align*} + \begin{bmatrix} + u \\ + v \\ + 1 + \end{bmatrix} &= + \bf{A} \hspace{0.1em} \Pi \hspace{0.2em} ^{c}\bf{M}_w + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} \\ + \begin{bmatrix} + u \\ + v \\ + 1 + \end{bmatrix} &= + \begin{bmatrix} + f_x & 0 & c_x \\ + 0 & f_y & c_y \\ + 0 & 0 & 1 + \end{bmatrix} + \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 0 + \end{bmatrix} + \begin{bmatrix} + r_{11} & r_{12} & r_{13} & t_x \\ + r_{21} & r_{22} & r_{23} & t_y \\ + r_{31} & r_{32} & r_{33} & t_z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} + \end{align*} +\f] + +The estimated pose is thus the rotation (`rvec`) and the translation (`tvec`) vectors that allow transforming +a 3D point expressed in the world frame into the camera frame: + +\f[ + \begin{align*} + \begin{bmatrix} + X_c \\ + Y_c \\ + Z_c \\ + 1 + \end{bmatrix} &= + \hspace{0.2em} ^{c}\bf{M}_w + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} \\ + \begin{bmatrix} + X_c \\ + Y_c \\ + Z_c \\ + 1 + \end{bmatrix} &= + \begin{bmatrix} + r_{11} & r_{12} & r_{13} & t_x \\ + r_{21} & r_{22} & r_{23} & t_y \\ + r_{31} & r_{32} & r_{33} & t_z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} + \end{align*} +\f] + +@note + - An example of how to use solvePnP for planar augmented reality can be found at + opencv_source_code/samples/python/plane_ar.py + - If you are using Python: + - Numpy array slices won't work as input because solvePnP requires contiguous + arrays (enforced by the assertion using cv::Mat::checkVector() around line 55 of + modules/calib3d/src/solvepnp.cpp version 2.4.9) + - The P3P algorithm requires image points to be in an array of shape (N,1,2) due + to its calling of cv::undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9) + which requires 2-channel information. + - Thus, given some data D = np.array(...) where D.shape = (N,M), in order to use a subset of + it as, e.g., imagePoints, one must effectively copy it into a new array: imagePoints = + np.ascontiguousarray(D[:,:2]).reshape((N,1,2)) + - The methods **SOLVEPNP_DLS** and **SOLVEPNP_UPNP** cannot be used as the current implementations are + unstable and sometimes give completely wrong results. If you pass one of these two + flags, **SOLVEPNP_EPNP** method will be used instead. + - The minimum number of points is 4 in the general case. In the case of **SOLVEPNP_P3P** and **SOLVEPNP_AP3P** + methods, it is required to use exactly 4 points (the first 3 points are used to estimate all the solutions + of the P3P problem, the last one is used to retain the best solution that minimizes the reprojection error). + - With **SOLVEPNP_ITERATIVE** method and `useExtrinsicGuess=true`, the minimum number of points is 3 (3 points + are sufficient to compute a pose but there are up to 4 solutions). The initial solution should be close to the + global solution to converge. + - With **SOLVEPNP_IPPE** input points must be >= 4 and object points must be coplanar. + - With **SOLVEPNP_IPPE_SQUARE** this is a special case suitable for marker pose estimation. + Number of input points must be 4. Object points must be defined in the following order: + - point 0: [-squareLength / 2, squareLength / 2, 0] + - point 1: [ squareLength / 2, squareLength / 2, 0] + - point 2: [ squareLength / 2, -squareLength / 2, 0] + - point 3: [-squareLength / 2, -squareLength / 2, 0] + */ +CV_EXPORTS_W bool solvePnP( InputArray objectPoints, InputArray imagePoints, + InputArray cameraMatrix, InputArray distCoeffs, + OutputArray rvec, OutputArray tvec, + bool useExtrinsicGuess = false, int flags = SOLVEPNP_ITERATIVE ); + +/** @brief Finds an object pose from 3D-2D point correspondences using the RANSAC scheme. + +@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or +1xN/Nx1 3-channel, where N is the number of points. vector\ can be also passed here. +@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel, +where N is the number of points. vector\ can be also passed here. +@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are +assumed. +@param rvec Output rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from +the model coordinate system to the camera coordinate system. +@param tvec Output translation vector. +@param useExtrinsicGuess Parameter used for @ref SOLVEPNP_ITERATIVE. If true (1), the function uses +the provided rvec and tvec values as initial approximations of the rotation and translation +vectors, respectively, and further optimizes them. +@param iterationsCount Number of iterations. +@param reprojectionError Inlier threshold value used by the RANSAC procedure. The parameter value +is the maximum allowed distance between the observed and computed point projections to consider it +an inlier. +@param confidence The probability that the algorithm produces a useful result. +@param inliers Output vector that contains indices of inliers in objectPoints and imagePoints . +@param flags Method for solving a PnP problem (see @ref solvePnP ). + +The function estimates an 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, that is, the sum of squared distances between the observed +projections imagePoints and the projected (using @ref projectPoints ) objectPoints. The use of RANSAC +makes the function resistant to outliers. + +@note + - An example of how to use solvePNPRansac for object detection can be found at + opencv_source_code/samples/cpp/tutorial_code/calib3d/real_time_pose_estimation/ + - The default method used to estimate the camera pose for the Minimal Sample Sets step + is #SOLVEPNP_EPNP. Exceptions are: + - if you choose #SOLVEPNP_P3P or #SOLVEPNP_AP3P, these methods will be used. + - if the number of input points is equal to 4, #SOLVEPNP_P3P is used. + - The method used to estimate the camera pose using all the inliers is defined by the + flags parameters unless it is equal to #SOLVEPNP_P3P or #SOLVEPNP_AP3P. In this case, + the method #SOLVEPNP_EPNP will be used instead. + */ +CV_EXPORTS_W bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints, + InputArray cameraMatrix, InputArray distCoeffs, + OutputArray rvec, OutputArray tvec, + bool useExtrinsicGuess = false, int iterationsCount = 100, + float reprojectionError = 8.0, double confidence = 0.99, + OutputArray inliers = noArray(), int flags = SOLVEPNP_ITERATIVE ); + +/** @brief Finds an object pose from 3 3D-2D point correspondences. + +@param objectPoints Array of object points in the object coordinate space, 3x3 1-channel or +1x3/3x1 3-channel. vector\ can be also passed here. +@param imagePoints Array of corresponding image points, 3x2 1-channel or 1x3/3x1 2-channel. + vector\ can be also passed here. +@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are +assumed. +@param rvecs Output rotation vectors (see @ref Rodrigues ) that, together with tvecs, brings points from +the model coordinate system to the camera coordinate system. A P3P problem has up to 4 solutions. +@param tvecs Output translation vectors. +@param flags Method for solving a P3P problem: +- **SOLVEPNP_P3P** Method is based on the paper of X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang +"Complete Solution Classification for the Perspective-Three-Point Problem" (@cite gao2003complete). +- **SOLVEPNP_AP3P** Method is based on the paper of T. Ke and S. Roumeliotis. +"An Efficient Algebraic Solution to the Perspective-Three-Point Problem" (@cite Ke17). + +The function estimates the object pose given 3 object points, their corresponding image +projections, as well as the camera matrix and the distortion coefficients. + +@note +The solutions are sorted by reprojection errors (lowest to highest). + */ +CV_EXPORTS_W int solveP3P( InputArray objectPoints, InputArray imagePoints, + InputArray cameraMatrix, InputArray distCoeffs, + OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, + int flags ); + +/** @brief Refine a pose (the translation and the rotation that transform a 3D point expressed in the object coordinate frame +to the camera coordinate frame) from a 3D-2D point correspondences and starting from an initial solution. + +@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or 1xN/Nx1 3-channel, +where N is the number of points. vector\ can also be passed here. +@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel, +where N is the number of points. vector\ can also be passed here. +@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are +assumed. +@param rvec Input/Output rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from +the model coordinate system to the camera coordinate system. Input values are used as an initial solution. +@param tvec Input/Output translation vector. Input values are used as an initial solution. +@param criteria Criteria when to stop the Levenberg-Marquard iterative algorithm. + +The function refines the object pose given at least 3 object points, their corresponding image +projections, an initial solution for the rotation and translation vector, +as well as the camera matrix and the distortion coefficients. +The function minimizes the projection error with respect to the rotation and the translation vectors, according +to a Levenberg-Marquardt iterative minimization @cite Madsen04 @cite Eade13 process. + */ +CV_EXPORTS_W void solvePnPRefineLM( InputArray objectPoints, InputArray imagePoints, + InputArray cameraMatrix, InputArray distCoeffs, + InputOutputArray rvec, InputOutputArray tvec, + TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 20, FLT_EPSILON)); + +/** @brief Refine a pose (the translation and the rotation that transform a 3D point expressed in the object coordinate frame +to the camera coordinate frame) from a 3D-2D point correspondences and starting from an initial solution. + +@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or 1xN/Nx1 3-channel, +where N is the number of points. vector\ can also be passed here. +@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel, +where N is the number of points. vector\ can also be passed here. +@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are +assumed. +@param rvec Input/Output rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from +the model coordinate system to the camera coordinate system. Input values are used as an initial solution. +@param tvec Input/Output translation vector. Input values are used as an initial solution. +@param criteria Criteria when to stop the Levenberg-Marquard iterative algorithm. +@param VVSlambda Gain for the virtual visual servoing control law, equivalent to the \f$\alpha\f$ +gain in the Damped Gauss-Newton formulation. + +The function refines the object pose given at least 3 object points, their corresponding image +projections, an initial solution for the rotation and translation vector, +as well as the camera matrix and the distortion coefficients. +The function minimizes the projection error with respect to the rotation and the translation vectors, using a +virtual visual servoing (VVS) @cite Chaumette06 @cite Marchand16 scheme. + */ +CV_EXPORTS_W void solvePnPRefineVVS( InputArray objectPoints, InputArray imagePoints, + InputArray cameraMatrix, InputArray distCoeffs, + InputOutputArray rvec, InputOutputArray tvec, + TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 20, FLT_EPSILON), + double VVSlambda = 1); + +/** @brief Finds an object pose from 3D-2D point correspondences. +This function returns a list of all the possible solutions (a solution is a +couple), depending on the number of input points and the chosen method: +- P3P methods (@ref SOLVEPNP_P3P, @ref SOLVEPNP_AP3P): 3 or 4 input points. Number of returned solutions can be between 0 and 4 with 3 input points. +- @ref SOLVEPNP_IPPE Input points must be >= 4 and object points must be coplanar. Returns 2 solutions. +- @ref SOLVEPNP_IPPE_SQUARE Special case suitable for marker pose estimation. +Number of input points must be 4 and 2 solutions are returned. Object points must be defined in the following order: + - point 0: [-squareLength / 2, squareLength / 2, 0] + - point 1: [ squareLength / 2, squareLength / 2, 0] + - point 2: [ squareLength / 2, -squareLength / 2, 0] + - point 3: [-squareLength / 2, -squareLength / 2, 0] +- for all the other flags, number of input points must be >= 4 and object points can be in any configuration. +Only 1 solution is returned. + +@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or +1xN/Nx1 3-channel, where N is the number of points. vector\ can be also passed here. +@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel, +where N is the number of points. vector\ can be also passed here. +@param cameraMatrix Input camera matrix \f$A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are +assumed. +@param rvecs Vector of output rotation vectors (see @ref Rodrigues ) that, together with tvecs, brings points from +the model coordinate system to the camera coordinate system. +@param tvecs Vector of output translation vectors. +@param useExtrinsicGuess Parameter used for #SOLVEPNP_ITERATIVE. If true (1), the function uses +the provided rvec and tvec values as initial approximations of the rotation and translation +vectors, respectively, and further optimizes them. +@param flags Method for solving a PnP problem: +- **SOLVEPNP_ITERATIVE** Iterative method is based on a Levenberg-Marquardt optimization. In +this case the function finds such a pose that minimizes reprojection error, that is the sum +of squared distances between the observed projections imagePoints and the projected (using +projectPoints ) objectPoints . +- **SOLVEPNP_P3P** Method is based on the paper of X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang +"Complete Solution Classification for the Perspective-Three-Point Problem" (@cite gao2003complete). +In this case the function requires exactly four object and image points. +- **SOLVEPNP_AP3P** Method is based on the paper of T. Ke, S. Roumeliotis +"An Efficient Algebraic Solution to the Perspective-Three-Point Problem" (@cite Ke17). +In this case the function requires exactly four object and image points. +- **SOLVEPNP_EPNP** Method has been introduced by F.Moreno-Noguer, V.Lepetit and P.Fua in the +paper "EPnP: Efficient Perspective-n-Point Camera Pose Estimation" (@cite lepetit2009epnp). +- **SOLVEPNP_DLS** Method is based on the paper of Joel A. Hesch and Stergios I. Roumeliotis. +"A Direct Least-Squares (DLS) Method for PnP" (@cite hesch2011direct). +- **SOLVEPNP_UPNP** Method is based on the paper of A.Penate-Sanchez, J.Andrade-Cetto, +F.Moreno-Noguer. "Exhaustive Linearization for Robust Camera Pose and Focal Length +Estimation" (@cite penate2013exhaustive). In this case the function also estimates the parameters \f$f_x\f$ and \f$f_y\f$ +assuming that both have the same value. Then the cameraMatrix is updated with the estimated +focal length. +- **SOLVEPNP_IPPE** Method is based on the paper of T. Collins and A. Bartoli. +"Infinitesimal Plane-Based Pose Estimation" (@cite Collins14). This method requires coplanar object points. +- **SOLVEPNP_IPPE_SQUARE** Method is based on the paper of Toby Collins and Adrien Bartoli. +"Infinitesimal Plane-Based Pose Estimation" (@cite Collins14). This method is suitable for marker pose estimation. +It requires 4 coplanar object points defined in the following order: + - point 0: [-squareLength / 2, squareLength / 2, 0] + - point 1: [ squareLength / 2, squareLength / 2, 0] + - point 2: [ squareLength / 2, -squareLength / 2, 0] + - point 3: [-squareLength / 2, -squareLength / 2, 0] +@param rvec Rotation vector used to initialize an iterative PnP refinement algorithm, when flag is SOLVEPNP_ITERATIVE +and useExtrinsicGuess is set to true. +@param tvec Translation vector used to initialize an iterative PnP refinement algorithm, when flag is SOLVEPNP_ITERATIVE +and useExtrinsicGuess is set to true. +@param reprojectionError Optional vector of reprojection error, that is the RMS error +(\f$ \text{RMSE} = \sqrt{\frac{\sum_{i}^{N} \left ( \hat{y_i} - y_i \right )^2}{N}} \f$) between the input image points +and the 3D object points projected with the estimated pose. + +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, see the figure below +(more precisely, the X-axis of the camera frame is pointing to the right, the Y-axis downward +and the Z-axis forward). + +![](pnp.jpg) + +Points expressed in the world frame \f$ \bf{X}_w \f$ are projected into the image plane \f$ \left[ u, v \right] \f$ +using the perspective projection model \f$ \Pi \f$ and the camera intrinsic parameters matrix \f$ \bf{A} \f$: + +\f[ + \begin{align*} + \begin{bmatrix} + u \\ + v \\ + 1 + \end{bmatrix} &= + \bf{A} \hspace{0.1em} \Pi \hspace{0.2em} ^{c}\bf{M}_w + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} \\ + \begin{bmatrix} + u \\ + v \\ + 1 + \end{bmatrix} &= + \begin{bmatrix} + f_x & 0 & c_x \\ + 0 & f_y & c_y \\ + 0 & 0 & 1 + \end{bmatrix} + \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 0 + \end{bmatrix} + \begin{bmatrix} + r_{11} & r_{12} & r_{13} & t_x \\ + r_{21} & r_{22} & r_{23} & t_y \\ + r_{31} & r_{32} & r_{33} & t_z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} + \end{align*} +\f] + +The estimated pose is thus the rotation (`rvec`) and the translation (`tvec`) vectors that allow transforming +a 3D point expressed in the world frame into the camera frame: + +\f[ + \begin{align*} + \begin{bmatrix} + X_c \\ + Y_c \\ + Z_c \\ + 1 + \end{bmatrix} &= + \hspace{0.2em} ^{c}\bf{M}_w + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} \\ + \begin{bmatrix} + X_c \\ + Y_c \\ + Z_c \\ + 1 + \end{bmatrix} &= + \begin{bmatrix} + r_{11} & r_{12} & r_{13} & t_x \\ + r_{21} & r_{22} & r_{23} & t_y \\ + r_{31} & r_{32} & r_{33} & t_z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + \begin{bmatrix} + X_{w} \\ + Y_{w} \\ + Z_{w} \\ + 1 + \end{bmatrix} + \end{align*} +\f] + +@note + - An example of how to use solvePnP for planar augmented reality can be found at + opencv_source_code/samples/python/plane_ar.py + - If you are using Python: + - Numpy array slices won't work as input because solvePnP requires contiguous + arrays (enforced by the assertion using cv::Mat::checkVector() around line 55 of + modules/calib3d/src/solvepnp.cpp version 2.4.9) + - The P3P algorithm requires image points to be in an array of shape (N,1,2) due + to its calling of cv::undistortPoints (around line 75 of modules/calib3d/src/solvepnp.cpp version 2.4.9) + which requires 2-channel information. + - Thus, given some data D = np.array(...) where D.shape = (N,M), in order to use a subset of + it as, e.g., imagePoints, one must effectively copy it into a new array: imagePoints = + np.ascontiguousarray(D[:,:2]).reshape((N,1,2)) + - The methods **SOLVEPNP_DLS** and **SOLVEPNP_UPNP** cannot be used as the current implementations are + unstable and sometimes give completely wrong results. If you pass one of these two + flags, **SOLVEPNP_EPNP** method will be used instead. + - The minimum number of points is 4 in the general case. In the case of **SOLVEPNP_P3P** and **SOLVEPNP_AP3P** + methods, it is required to use exactly 4 points (the first 3 points are used to estimate all the solutions + of the P3P problem, the last one is used to retain the best solution that minimizes the reprojection error). + - With **SOLVEPNP_ITERATIVE** method and `useExtrinsicGuess=true`, the minimum number of points is 3 (3 points + are sufficient to compute a pose but there are up to 4 solutions). The initial solution should be close to the + global solution to converge. + - With **SOLVEPNP_IPPE** input points must be >= 4 and object points must be coplanar. + - With **SOLVEPNP_IPPE_SQUARE** this is a special case suitable for marker pose estimation. + Number of input points must be 4. Object points must be defined in the following order: + - point 0: [-squareLength / 2, squareLength / 2, 0] + - point 1: [ squareLength / 2, squareLength / 2, 0] + - point 2: [ squareLength / 2, -squareLength / 2, 0] + - point 3: [-squareLength / 2, -squareLength / 2, 0] + */ +CV_EXPORTS_W int solvePnPGeneric( InputArray objectPoints, InputArray imagePoints, + InputArray cameraMatrix, InputArray distCoeffs, + OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, + bool useExtrinsicGuess = false, SolvePnPMethod flags = SOLVEPNP_ITERATIVE, + InputArray rvec = noArray(), InputArray tvec = noArray(), + OutputArray reprojectionError = noArray() ); + +/** @brief Finds an initial camera matrix from 3D-2D point correspondences. + +@param objectPoints Vector of vectors of the calibration pattern points in the calibration pattern +coordinate space. In the old interface all the per-view vectors are concatenated. See +calibrateCamera for details. +@param imagePoints Vector of vectors of the projections of the calibration pattern points. In the +old interface all the per-view vectors are concatenated. +@param imageSize Image size in pixels used to initialize the principal point. +@param aspectRatio If it is zero or negative, both \f$f_x\f$ and \f$f_y\f$ are estimated independently. +Otherwise, \f$f_x = f_y * \texttt{aspectRatio}\f$ . + +The function estimates and returns an initial camera matrix for the camera calibration process. +Currently, the function only supports planar calibration patterns, which are patterns where each +object point has z-coordinate =0. + */ +CV_EXPORTS_W Mat initCameraMatrix2D( InputArrayOfArrays objectPoints, + InputArrayOfArrays imagePoints, + Size imageSize, double aspectRatio = 1.0 ); + +/** @brief Finds the positions of internal corners of the chessboard. + +@param image Source chessboard view. It must be an 8-bit grayscale or color image. +@param patternSize Number of inner corners per a chessboard row and column +( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) ). +@param corners Output array of detected corners. +@param flags Various operation flags that can be zero or a combination of the following values: +- **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). +- **CALIB_CB_NORMALIZE_IMAGE** Normalize the image gamma with equalizeHist before +applying fixed or adaptive thresholding. +- **CALIB_CB_FILTER_QUADS** Use additional criteria (like contour area, perimeter, +square-like shape) to filter out false quads extracted at the contour retrieval stage. +- **CALIB_CB_FAST_CHECK** Run a fast check on the image that looks for chessboard corners, +and shortcut the call if none is 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 +are found and they are 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 detected coordinates are approximate, and to determine their positions +more accurately, the function calls cornerSubPix. You also may use the function cornerSubPix with +different parameters if returned coordinates are not accurate enough. + +Sample usage of detecting and drawing chessboard corners: : +@code + 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 do not 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); +@endcode +@note The function requires white space (like a square-thick border, the wider the better) around +the board to make the detection more robust in various environments. Otherwise, if there is no +border and the background is dark, the outer black squares cannot be segmented properly and so the +square grouping and ordering algorithm fails. + */ +CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize, OutputArray corners, + int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE ); + +/* + Checks whether the image contains chessboard of the specific size or not. + If yes, nonzero value is returned. +*/ +CV_EXPORTS_W bool checkChessboard(InputArray img, Size size); + +/** @brief Finds the positions of internal corners of the chessboard using a sector based approach. + +@param image Source chessboard view. It must be an 8-bit grayscale or color image. +@param patternSize Number of inner corners per a chessboard row and column +( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) ). +@param corners Output array of detected corners. +@param flags Various operation flags that can be zero or a combination of the following values: +- **CALIB_CB_NORMALIZE_IMAGE** Normalize the image gamma with equalizeHist before detection. +- **CALIB_CB_EXHAUSTIVE ** Run an exhaustive search to improve detection rate. +- **CALIB_CB_ACCURACY ** Up sample input image to improve sub-pixel accuracy due to aliasing effects. +This should be used if an accurate camera calibration is required. + +The function is analog to findchessboardCorners but uses a localized radon +transformation approximated by box filters being more robust to all sort of +noise, faster on larger images and is able to directly return the sub-pixel +position of the internal chessboard corners. The Method is based on the paper +@cite duda2018 "Accurate Detection and Localization of Checkerboard Corners for +Calibration" demonstrating that the returned sub-pixel positions are more +accurate than the one returned by cornerSubPix allowing a precise camera +calibration for demanding applications. + +@note The function requires a white boarder with roughly the same width as one +of the checkerboard fields around the whole board to improve the detection in +various environments. In addition, because of the localized radon +transformation it is beneficial to use round corners for the field corners +which are located on the outside of the board. The following figure illustrates +a sample checkerboard optimized for the detection. However, any other checkerboard +can be used as well. +![Checkerboard](pics/checkerboard_radon.png) + */ +CV_EXPORTS_W bool findChessboardCornersSB(InputArray image,Size patternSize, OutputArray corners,int flags=0); + +//! finds subpixel-accurate positions of the chessboard corners +CV_EXPORTS_W bool find4QuadCornerSubpix( InputArray img, InputOutputArray corners, Size region_size ); + +/** @brief Renders the detected chessboard corners. + +@param image Destination image. It must be an 8-bit color image. +@param patternSize Number of inner corners per a chessboard row and column +(patternSize = cv::Size(points_per_row,points_per_column)). +@param corners Array of detected corners, the output of findChessboardCorners. +@param patternWasFound Parameter indicating whether the complete board was found or not. The +return value of findChessboardCorners should be passed here. + +The function draws individual chessboard corners detected either as red circles if the board was not +found, or as colored corners connected with lines if the board was found. + */ +CV_EXPORTS_W void drawChessboardCorners( InputOutputArray image, Size patternSize, + InputArray corners, bool patternWasFound ); + +/** @brief Draw axes of the world/object coordinate system from pose estimation. @sa solvePnP + +@param image Input/output image. It must have 1 or 3 channels. The number of channels is not altered. +@param cameraMatrix Input 3x3 floating-point matrix of camera intrinsic parameters. +\f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is empty, the zero distortion coefficients are assumed. +@param rvec Rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from +the model coordinate system to the camera coordinate system. +@param tvec Translation vector. +@param length Length of the painted axes in the same unit than tvec (usually in meters). +@param thickness Line thickness of the painted axes. + +This function draws the axes of the world/object coordinate system w.r.t. to the camera frame. +OX is drawn in red, OY in green and OZ in blue. + */ +CV_EXPORTS_W void drawFrameAxes(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs, + InputArray rvec, InputArray tvec, float length, int thickness=3); + +struct CV_EXPORTS_W_SIMPLE CirclesGridFinderParameters +{ + CV_WRAP CirclesGridFinderParameters(); + CV_PROP_RW cv::Size2f densityNeighborhoodSize; + CV_PROP_RW float minDensity; + CV_PROP_RW int kmeansAttempts; + CV_PROP_RW int minDistanceToAddKeypoint; + CV_PROP_RW int keypointScale; + CV_PROP_RW float minGraphConfidence; + CV_PROP_RW float vertexGain; + CV_PROP_RW float vertexPenalty; + CV_PROP_RW float existingVertexGain; + CV_PROP_RW float edgeGain; + CV_PROP_RW float edgePenalty; + CV_PROP_RW float convexHullFactor; + CV_PROP_RW float minRNGEdgeSwitchDist; + + enum GridType + { + SYMMETRIC_GRID, ASYMMETRIC_GRID + }; + GridType gridType; + + CV_PROP_RW float squareSize; //!< Distance between two adjacent points. Used by CALIB_CB_CLUSTERING. + CV_PROP_RW float maxRectifiedDistance; //!< Max deviation from predicion. Used by CALIB_CB_CLUSTERING. +}; + +#ifndef DISABLE_OPENCV_3_COMPATIBILITY +typedef CirclesGridFinderParameters CirclesGridFinderParameters2; +#endif + +/** @brief Finds centers in the grid of circles. + +@param image grid view of input circles; it must be an 8-bit grayscale or color image. +@param patternSize number of circles per row and column +( patternSize = Size(points_per_row, points_per_colum) ). +@param centers output array of detected centers. +@param flags various operation flags that can be one of the following values: +- **CALIB_CB_SYMMETRIC_GRID** uses symmetric pattern of circles. +- **CALIB_CB_ASYMMETRIC_GRID** uses asymmetric pattern of circles. +- **CALIB_CB_CLUSTERING** uses a special algorithm for grid detection. It is more robust to +perspective distortions but much more sensitive to background clutter. +@param blobDetector feature detector that finds blobs like dark circles on light background. +@param parameters struct for finding circles in a grid pattern. + +The function attempts to determine whether the input image contains a grid of circles. If it is, the +function locates centers of the circles. The function returns a non-zero value if all of the centers +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. + +Sample usage of detecting and drawing the centers of circles: : +@code + Size patternsize(7,7); //number of centers + Mat gray = ....; //source image + vector centers; //this will be filled by the detected centers + + bool patternfound = findCirclesGrid(gray, patternsize, centers); + + drawChessboardCorners(img, patternsize, Mat(centers), patternfound); +@endcode +@note The function requires white space (like a square-thick border, the wider the better) around +the board to make the detection more robust in various environments. + */ +CV_EXPORTS_W bool findCirclesGrid( InputArray image, Size patternSize, + OutputArray centers, int flags, + const Ptr &blobDetector, + const CirclesGridFinderParameters& parameters); + +/** @overload */ +CV_EXPORTS_W bool findCirclesGrid( InputArray image, Size patternSize, + OutputArray centers, int flags = CALIB_CB_SYMMETRIC_GRID, + const Ptr &blobDetector = SimpleBlobDetector::create()); + +/** @brief Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern. + +@param objectPoints In the new interface it is a vector of vectors of calibration pattern points in +the calibration pattern coordinate space (e.g. std::vector>). The outer +vector contains as many elements as the number of the pattern views. If the same calibration pattern +is shown in each view and it is fully visible, all the vectors will be the same. Although, it is +possible to use partially occluded patterns, or even different patterns in different views. Then, +the vectors will be different. The points are 3D, but since they are in a pattern coordinate system, +then, if the rig is planar, it may make sense to put the model to a XY coordinate plane so that +Z-coordinate of each input object point is 0. +In the old interface all the vectors of object points from different views are concatenated +together. +@param imagePoints In the new interface it is a vector of vectors of the projections of calibration +pattern points (e.g. std::vector>). imagePoints.size() and +objectPoints.size() and imagePoints[i].size() must be equal to objectPoints[i].size() for each i. +In the old interface all the vectors of object points from different views are concatenated +together. +@param imageSize Size of the image used only to initialize the intrinsic camera matrix. +@param cameraMatrix Output 3x3 floating-point camera matrix +\f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . If CV\_CALIB\_USE\_INTRINSIC\_GUESS +and/or CALIB_FIX_ASPECT_RATIO are specified, some or all of fx, fy, cx, cy must be +initialized before calling the function. +@param distCoeffs Output vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. +@param rvecs Output vector of rotation vectors (see Rodrigues ) estimated for each pattern view +(e.g. std::vector>). 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, that is, a real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1). +@param tvecs Output vector of translation vectors estimated for each pattern view. +@param stdDeviationsIntrinsics Output vector of standard deviations estimated for intrinsic parameters. + Order of deviations values: +\f$(f_x, f_y, c_x, c_y, k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6 , s_1, s_2, s_3, + s_4, \tau_x, \tau_y)\f$ If one of parameters is not estimated, it's deviation is equals to zero. +@param stdDeviationsExtrinsics Output vector of standard deviations estimated for extrinsic parameters. + Order of deviations values: \f$(R_1, T_1, \dotsc , R_M, T_M)\f$ where M is number of pattern views, + \f$R_i, T_i\f$ are concatenated 1x3 vectors. + @param perViewErrors Output vector of the RMS re-projection error estimated for each pattern view. +@param flags Different flags that may be zero or a combination of the following values: +- **CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains 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), and focal distances are computed in a least-squares fashion. +Note, that if intrinsic parameters are known, there is no need to use this function just to +estimate extrinsic parameters. Use solvePnP instead. +- **CALIB_FIX_PRINCIPAL_POINT** The principal point is not changed during the global +optimization. It stays at the center or at a different location specified when +CALIB_USE_INTRINSIC_GUESS is set too. +- **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 +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. +- **CALIB_ZERO_TANGENT_DIST** Tangential distortion coefficients \f$(p_1, p_2)\f$ are set +to zeros and stay zero. +- **CALIB_FIX_K1,...,CALIB_FIX_K6** The corresponding radial distortion +coefficient is not changed during the optimization. If CALIB_USE_INTRINSIC_GUESS is +set, the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0. +- **CALIB_RATIONAL_MODEL** Coefficients k4, k5, and k6 are enabled. 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 computes and returns only 5 distortion coefficients. +- **CALIB_THIN_PRISM_MODEL** Coefficients s1, s2, s3 and s4 are enabled. To provide the +backward compatibility, this extra flag should be explicitly specified to make the +calibration function use the thin prism model and return 12 coefficients. If the flag is not +set, the function computes and returns only 5 distortion coefficients. +- **CALIB_FIX_S1_S2_S3_S4** The thin prism distortion coefficients are not changed during +the optimization. If CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the +supplied distCoeffs matrix is used. Otherwise, it is set to 0. +- **CALIB_TILTED_MODEL** Coefficients tauX and tauY are enabled. To provide the +backward compatibility, this extra flag should be explicitly specified to make the +calibration function use the tilted sensor model and return 14 coefficients. If the flag is not +set, the function computes and returns only 5 distortion coefficients. +- **CALIB_FIX_TAUX_TAUY** The coefficients of the tilted sensor model are not changed during +the optimization. If CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the +supplied distCoeffs matrix is used. Otherwise, it is set to 0. +@param criteria Termination criteria for the iterative optimization algorithm. + +@return the overall RMS re-projection error. + +The function estimates the intrinsic camera parameters and extrinsic parameters for each of the +views. The algorithm is based on @cite Zhang2000 and @cite BouguetMCT . The coordinates of 3D object +points and their corresponding 2D projections in each view must be specified. That may be achieved +by using an object with a 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 findChessboardCorners ). Currently, initialization of intrinsic parameters +(when CALIB_USE_INTRINSIC_GUESS is not set) is only implemented for planar calibration +patterns (where Z-coordinates of the object points must be all zeros). 3D calibration rigs can also +be used as long as initial cameraMatrix is provided. + +The algorithm performs the following steps: + +- Compute the initial intrinsic parameters (the option only available for planar calibration + patterns) or read them from the input parameters. The distortion coefficients are all set to + zeros initially unless some of CALIB_FIX_K? are specified. + +- Estimate the initial camera pose as if the intrinsic parameters have been already known. This is + done using solvePnP . + +- Run the global Levenberg-Marquardt optimization algorithm to minimize the reprojection error, + that is, 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 projectPoints for details. + +@note + If you use a non-square (=non-NxN) grid and findChessboardCorners for calibration, and + calibrateCamera returns bad values (zero distortion coefficients, an image center very far from + (w/2-0.5,h/2-0.5), and/or large differences between \f$f_x\f$ and \f$f_y\f$ (ratios of 10:1 or more)), + then you have probably used patternSize=cvSize(rows,cols) instead of using + patternSize=cvSize(cols,rows) in findChessboardCorners . + +@sa + calibrateCameraRO, findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort + */ +CV_EXPORTS_AS(calibrateCameraExtended) double calibrateCamera( InputArrayOfArrays objectPoints, + InputArrayOfArrays imagePoints, Size imageSize, + InputOutputArray cameraMatrix, InputOutputArray distCoeffs, + OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, + OutputArray stdDeviationsIntrinsics, + OutputArray stdDeviationsExtrinsics, + OutputArray perViewErrors, + int flags = 0, TermCriteria criteria = TermCriteria( + TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) ); + +/** @overload */ +CV_EXPORTS_W double calibrateCamera( InputArrayOfArrays objectPoints, + InputArrayOfArrays imagePoints, Size imageSize, + InputOutputArray cameraMatrix, InputOutputArray distCoeffs, + OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, + int flags = 0, TermCriteria criteria = TermCriteria( + TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) ); + +/** @brief Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern. + +This function is an extension of calibrateCamera() with the method of releasing object which was +proposed in @cite strobl2011iccv. In many common cases with inaccurate, unmeasured, roughly planar +targets (calibration plates), this method can dramatically improve the precision of the estimated +camera parameters. Both the object-releasing method and standard method are supported by this +function. Use the parameter **iFixedPoint** for method selection. In the internal implementation, +calibrateCamera() is a wrapper for this function. + +@param objectPoints Vector of vectors of calibration pattern points in the calibration pattern +coordinate space. See calibrateCamera() for details. If the method of releasing object to be used, +the identical calibration board must be used in each view and it must be fully visible, and all +objectPoints[i] must be the same and all points should be roughly close to a plane. **The calibration +target has to be rigid, or at least static if the camera (rather than the calibration target) is +shifted for grabbing images.** +@param imagePoints Vector of vectors of the projections of calibration pattern points. See +calibrateCamera() for details. +@param imageSize Size of the image used only to initialize the intrinsic camera matrix. +@param iFixedPoint The index of the 3D object point in objectPoints[0] to be fixed. It also acts as +a switch for calibration method selection. If object-releasing method to be used, pass in the +parameter in the range of [1, objectPoints[0].size()-2], otherwise a value out of this range will +make standard calibration method selected. Usually the top-right corner point of the calibration +board grid is recommended to be fixed when object-releasing method being utilized. According to +\cite strobl2011iccv, two other points are also fixed. In this implementation, objectPoints[0].front +and objectPoints[0].back.z are used. With object-releasing method, accurate rvecs, tvecs and +newObjPoints are only possible if coordinates of these three fixed points are accurate enough. +@param cameraMatrix Output 3x3 floating-point camera matrix. See calibrateCamera() for details. +@param distCoeffs Output vector of distortion coefficients. See calibrateCamera() for details. +@param rvecs Output vector of rotation vectors estimated for each pattern view. See calibrateCamera() +for details. +@param tvecs Output vector of translation vectors estimated for each pattern view. +@param newObjPoints The updated output vector of calibration pattern points. The coordinates might +be scaled based on three fixed points. The returned coordinates are accurate only if the above +mentioned three fixed points are accurate. If not needed, noArray() can be passed in. This parameter +is ignored with standard calibration method. +@param stdDeviationsIntrinsics Output vector of standard deviations estimated for intrinsic parameters. +See calibrateCamera() for details. +@param stdDeviationsExtrinsics Output vector of standard deviations estimated for extrinsic parameters. +See calibrateCamera() for details. +@param stdDeviationsObjPoints Output vector of standard deviations estimated for refined coordinates +of calibration pattern points. It has the same size and order as objectPoints[0] vector. This +parameter is ignored with standard calibration method. + @param perViewErrors Output vector of the RMS re-projection error estimated for each pattern view. +@param flags Different flags that may be zero or a combination of some predefined values. See +calibrateCamera() for details. If the method of releasing object is used, the calibration time may +be much longer. CALIB_USE_QR or CALIB_USE_LU could be used for faster calibration with potentially +less precise and less stable in some rare cases. +@param criteria Termination criteria for the iterative optimization algorithm. + +@return the overall RMS re-projection error. + +The function estimates the intrinsic camera parameters and extrinsic parameters for each of the +views. The algorithm is based on @cite Zhang2000, @cite BouguetMCT and @cite strobl2011iccv. See +calibrateCamera() for other detailed explanations. +@sa + calibrateCamera, findChessboardCorners, solvePnP, initCameraMatrix2D, stereoCalibrate, undistort + */ +CV_EXPORTS_AS(calibrateCameraROExtended) double calibrateCameraRO( InputArrayOfArrays objectPoints, + InputArrayOfArrays imagePoints, Size imageSize, int iFixedPoint, + InputOutputArray cameraMatrix, InputOutputArray distCoeffs, + OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, + OutputArray newObjPoints, + OutputArray stdDeviationsIntrinsics, + OutputArray stdDeviationsExtrinsics, + OutputArray stdDeviationsObjPoints, + OutputArray perViewErrors, + int flags = 0, TermCriteria criteria = TermCriteria( + TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) ); + +/** @overload */ +CV_EXPORTS_W double calibrateCameraRO( InputArrayOfArrays objectPoints, + InputArrayOfArrays imagePoints, Size imageSize, int iFixedPoint, + InputOutputArray cameraMatrix, InputOutputArray distCoeffs, + OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, + OutputArray newObjPoints, + int flags = 0, TermCriteria criteria = TermCriteria( + TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) ); + +/** @brief Computes useful camera characteristics from the camera matrix. + +@param cameraMatrix Input camera matrix that can be estimated by calibrateCamera or +stereoCalibrate . +@param imageSize Input image size in pixels. +@param apertureWidth Physical width in mm of the sensor. +@param apertureHeight Physical height in mm of the sensor. +@param fovx Output field of view in degrees along the horizontal sensor axis. +@param fovy Output field of view in degrees along the vertical sensor axis. +@param focalLength Focal length of the lens in mm. +@param principalPoint Principal point in mm. +@param aspectRatio \f$f_y/f_x\f$ + +The function computes various useful camera characteristics from the previously estimated camera +matrix. + +@note + Do keep in mind that the unity measure 'mm' stands for whatever unit of measure one chooses for + the chessboard pitch (it can thus be any value). + */ +CV_EXPORTS_W void calibrationMatrixValues( InputArray cameraMatrix, Size imageSize, + double apertureWidth, double apertureHeight, + CV_OUT double& fovx, CV_OUT double& fovy, + CV_OUT double& focalLength, CV_OUT Point2d& principalPoint, + CV_OUT double& aspectRatio ); + +/** @brief Calibrates the stereo camera. + +@param objectPoints Vector of vectors of the calibration pattern points. +@param imagePoints1 Vector of vectors of the projections of the calibration pattern points, +observed by the first camera. +@param imagePoints2 Vector of vectors of the projections of the calibration pattern points, +observed by the second camera. +@param cameraMatrix1 Input/output first camera matrix: +\f$\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}\f$ , \f$j = 0,\, 1\f$ . If +any of CALIB_USE_INTRINSIC_GUESS , CALIB_FIX_ASPECT_RATIO , +CALIB_FIX_INTRINSIC , or CALIB_FIX_FOCAL_LENGTH are specified, some or all of the +matrix components must be initialized. See the flags description for details. +@param distCoeffs1 Input/output vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. The output vector length depends on the flags. +@param cameraMatrix2 Input/output second camera matrix. The parameter is similar to cameraMatrix1 +@param distCoeffs2 Input/output lens distortion coefficients for the second camera. The parameter +is similar to distCoeffs1 . +@param imageSize Size of the image used only to initialize intrinsic camera matrix. +@param R Output rotation matrix between the 1st and the 2nd camera coordinate systems. +@param T Output translation vector between the coordinate systems of the cameras. +@param E Output essential matrix. +@param F Output fundamental matrix. +@param perViewErrors Output vector of the RMS re-projection error estimated for each pattern view. +@param flags Different flags that may be zero or a combination of the following values: +- **CALIB_FIX_INTRINSIC** Fix cameraMatrix? and distCoeffs? so that only R, T, E , and F +matrices are estimated. +- **CALIB_USE_INTRINSIC_GUESS** Optimize some or all of the intrinsic parameters +according to the specified flags. Initial values are provided by the user. +- **CALIB_USE_EXTRINSIC_GUESS** R, T contain valid initial values that are optimized further. +Otherwise R, T are initialized to the median value of the pattern views (each dimension separately). +- **CALIB_FIX_PRINCIPAL_POINT** Fix the principal points during the optimization. +- **CALIB_FIX_FOCAL_LENGTH** Fix \f$f^{(j)}_x\f$ and \f$f^{(j)}_y\f$ . +- **CALIB_FIX_ASPECT_RATIO** Optimize \f$f^{(j)}_y\f$ . Fix the ratio \f$f^{(j)}_x/f^{(j)}_y\f$ +. +- **CALIB_SAME_FOCAL_LENGTH** Enforce \f$f^{(0)}_x=f^{(1)}_x\f$ and \f$f^{(0)}_y=f^{(1)}_y\f$ . +- **CALIB_ZERO_TANGENT_DIST** Set tangential distortion coefficients for each camera to +zeros and fix there. +- **CALIB_FIX_K1,...,CALIB_FIX_K6** Do not change the corresponding radial +distortion coefficient during the optimization. If CALIB_USE_INTRINSIC_GUESS is set, +the coefficient from the supplied distCoeffs matrix is used. Otherwise, it is set to 0. +- **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 computes and returns only 5 distortion coefficients. +- **CALIB_THIN_PRISM_MODEL** Coefficients s1, s2, s3 and s4 are enabled. To provide the +backward compatibility, this extra flag should be explicitly specified to make the +calibration function use the thin prism model and return 12 coefficients. If the flag is not +set, the function computes and returns only 5 distortion coefficients. +- **CALIB_FIX_S1_S2_S3_S4** The thin prism distortion coefficients are not changed during +the optimization. If CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the +supplied distCoeffs matrix is used. Otherwise, it is set to 0. +- **CALIB_TILTED_MODEL** Coefficients tauX and tauY are enabled. To provide the +backward compatibility, this extra flag should be explicitly specified to make the +calibration function use the tilted sensor model and return 14 coefficients. If the flag is not +set, the function computes and returns only 5 distortion coefficients. +- **CALIB_FIX_TAUX_TAUY** The coefficients of the tilted sensor model are not changed during +the optimization. If CALIB_USE_INTRINSIC_GUESS is set, the coefficient from the +supplied distCoeffs matrix is used. Otherwise, it is set to 0. +@param criteria Termination criteria for the iterative optimization algorithm. + +The function estimates transformation between two cameras making a stereo pair. If you have a stereo +camera where the relative position and orientation of two cameras is fixed, and if you computed +poses of an object relative to the first camera and to the second camera, (R1, T1) and (R2, T2), +respectively (this can be done with solvePnP ), then those poses definitely relate to each other. +This means that, given ( \f$R_1\f$,\f$T_1\f$ ), it should be possible to compute ( \f$R_2\f$,\f$T_2\f$ ). You only +need to know the position and orientation of the second camera relative to the first camera. This is +what the described function does. It computes ( \f$R\f$,\f$T\f$ ) so that: + +\f[R_2=R*R_1\f] +\f[T_2=R*T_1 + T,\f] + +Optionally, it computes the essential matrix E: + +\f[E= \vecthreethree{0}{-T_2}{T_1}{T_2}{0}{-T_0}{-T_1}{T_0}{0} *R\f] + +where \f$T_i\f$ are components of the translation vector \f$T\f$ : \f$T=[T_0, T_1, T_2]^T\f$ . And the function +can also compute the fundamental matrix F: + +\f[F = cameraMatrix2^{-T} E cameraMatrix1^{-1}\f] + +Besides the stereo-related information, the function can also perform a full calibration of each of +two cameras. However, due to the high dimensionality of the parameter space and noise in the input +data, the function can diverge from the correct solution. If the intrinsic parameters can be +estimated with high accuracy for each of the cameras individually (for example, using +calibrateCamera ), you are recommended to do so and then pass 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, for example, pass +CALIB_SAME_FOCAL_LENGTH and CALIB_ZERO_TANGENT_DIST flags, which is usually a +reasonable assumption. + +Similarly to calibrateCamera , 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. + */ +CV_EXPORTS_AS(stereoCalibrateExtended) double stereoCalibrate( InputArrayOfArrays objectPoints, + InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, + InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, + InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, + Size imageSize, InputOutputArray R,InputOutputArray T, OutputArray E, OutputArray F, + OutputArray perViewErrors, int flags = CALIB_FIX_INTRINSIC, + TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) ); + +/// @overload +CV_EXPORTS_W double stereoCalibrate( InputArrayOfArrays objectPoints, + InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, + InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, + InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, + Size imageSize, OutputArray R,OutputArray T, OutputArray E, OutputArray F, + int flags = CALIB_FIX_INTRINSIC, + TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6) ); + +/** @brief Computes rectification transforms for each head of a calibrated stereo camera. + +@param cameraMatrix1 First camera matrix. +@param distCoeffs1 First camera distortion parameters. +@param cameraMatrix2 Second camera matrix. +@param distCoeffs2 Second camera distortion parameters. +@param imageSize Size of the image used for stereo calibration. +@param R Rotation matrix between the coordinate systems of the first and the second cameras. +@param T Translation vector between coordinate systems of the cameras. +@param R1 Output 3x3 rectification transform (rotation matrix) for the first camera. +@param R2 Output 3x3 rectification transform (rotation matrix) for the second camera. +@param P1 Output 3x4 projection matrix in the new (rectified) coordinate systems for the first +camera. +@param P2 Output 3x4 projection matrix in the new (rectified) coordinate systems for the second +camera. +@param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see reprojectImageTo3D ). +@param flags Operation flags that may be zero or 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 the +horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the +useful image area. +@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 +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 validPixROI1 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). +@param validPixROI2 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). + +The function computes the rotation matrices for each camera that (virtually) make both camera image +planes the same plane. Consequently, this makes all the epipolar lines parallel and thus simplifies +the dense stereo correspondence problem. The function takes the matrices computed by stereoCalibrate +as input. As output, it provides two rotation matrices and also two projection matrices in the new +coordinates. The function distinguishes the following two cases: + +- **Horizontal stereo**: the first and the second camera views are shifted relative to each other + mainly along the x axis (with possible small vertical shift). In the rectified images, the + corresponding epipolar lines in the left and right cameras are horizontal and have the same + y-coordinate. P1 and P2 look like: + + \f[\texttt{P1} = \begin{bmatrix} f & 0 & cx_1 & 0 \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\f] + + \f[\texttt{P2} = \begin{bmatrix} f & 0 & cx_2 & T_x*f \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} ,\f] + + where \f$T_x\f$ is a horizontal shift between the cameras and \f$cx_1=cx_2\f$ if + CALIB_ZERO_DISPARITY is set. + +- **Vertical stereo**: the first and the second camera views are shifted relative to each other + mainly in vertical direction (and probably a bit in the horizontal direction too). The epipolar + lines in the rectified images are vertical and have the same x-coordinate. P1 and P2 look like: + + \f[\texttt{P1} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_1 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix}\f] + + \f[\texttt{P2} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_2 & T_y*f \\ 0 & 0 & 1 & 0 \end{bmatrix} ,\f] + + where \f$T_y\f$ is a vertical shift between the cameras and \f$cy_1=cy_2\f$ if CALIB_ZERO_DISPARITY is + set. + +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 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. + +![image](pics/stereo_undistort.jpg) + */ +CV_EXPORTS_W void stereoRectify( InputArray cameraMatrix1, InputArray distCoeffs1, + InputArray cameraMatrix2, InputArray distCoeffs2, + Size imageSize, InputArray R, InputArray T, + OutputArray R1, OutputArray R2, + OutputArray P1, OutputArray P2, + OutputArray Q, int flags = CALIB_ZERO_DISPARITY, + double alpha = -1, Size newImageSize = Size(), + CV_OUT Rect* validPixROI1 = 0, CV_OUT Rect* validPixROI2 = 0 ); + +/** @brief Computes a rectification transform for an uncalibrated stereo camera. + +@param points1 Array of feature points in the first image. +@param points2 The corresponding points in the second image. The same formats as in +findFundamentalMat are supported. +@param F Input fundamental matrix. It can be computed from the same set of point pairs using +findFundamentalMat . +@param imgSize Size of the image. +@param H1 Output rectification homography matrix for the first image. +@param H2 Output rectification homography matrix for the second image. +@param threshold Optional threshold used to filter out the outliers. If the parameter is greater +than zero, all the point pairs that do not comply with the epipolar geometry (that is, the points +for which \f$|\texttt{points2[i]}^T*\texttt{F}*\texttt{points1[i]}|>\texttt{threshold}\f$ ) 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 the space, which explains the suffix "uncalibrated". Another +related difference from 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 @cite 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 calibrateCamera . Then, the images can be corrected using undistort , or + just the point coordinates can be corrected with undistortPoints . + */ +CV_EXPORTS_W bool stereoRectifyUncalibrated( InputArray points1, InputArray points2, + InputArray F, Size imgSize, + OutputArray H1, OutputArray H2, + double threshold = 5 ); + +//! computes the rectification transformations for 3-head camera, where all the heads are on the same line. +CV_EXPORTS_W float rectify3Collinear( InputArray cameraMatrix1, InputArray distCoeffs1, + InputArray cameraMatrix2, InputArray distCoeffs2, + InputArray cameraMatrix3, InputArray distCoeffs3, + InputArrayOfArrays imgpt1, InputArrayOfArrays imgpt3, + Size imageSize, InputArray R12, InputArray T12, + InputArray R13, InputArray T13, + OutputArray R1, OutputArray R2, OutputArray R3, + OutputArray P1, OutputArray P2, OutputArray P3, + OutputArray Q, double alpha, Size newImgSize, + CV_OUT Rect* roi1, CV_OUT Rect* roi2, int flags ); + +/** @brief Returns the new camera matrix based on the free scaling parameter. + +@param cameraMatrix Input camera matrix. +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ of +4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are +assumed. +@param imageSize Original image size. +@param alpha Free scaling parameter between 0 (when all the pixels in the undistorted image are +valid) and 1 (when all the source image pixels are retained in the undistorted image). See +stereoRectify for details. +@param newImgSize Image size after rectification. By default, it is set to imageSize . +@param validPixROI Optional output rectangle that outlines all-good-pixels region in the +undistorted image. See roi1, roi2 description in stereoRectify . +@param centerPrincipalPoint Optional flag that indicates whether in the new camera matrix the +principal point should be at the image center or not. By default, the principal point is chosen to +best fit a subset of the source image (determined by alpha) to the corrected image. +@return new_camera_matrix Output new camera matrix. + +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 undistorted 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 +initUndistortRectifyMap to produce the maps for remap . + */ +CV_EXPORTS_W Mat getOptimalNewCameraMatrix( InputArray cameraMatrix, InputArray distCoeffs, + Size imageSize, double alpha, Size newImgSize = Size(), + CV_OUT Rect* validPixROI = 0, + bool centerPrincipalPoint = false); + +/** @brief Computes Hand-Eye calibration: \f$_{}^{g}\textrm{T}_c\f$ + +@param[in] R_gripper2base Rotation part extracted from the homogeneous matrix that transforms a point +expressed in the gripper frame to the robot base frame (\f$_{}^{b}\textrm{T}_g\f$). +This is a vector (`vector`) that contains the rotation matrices for all the transformations +from gripper frame to robot base frame. +@param[in] t_gripper2base Translation part extracted from the homogeneous matrix that transforms a point +expressed in the gripper frame to the robot base frame (\f$_{}^{b}\textrm{T}_g\f$). +This is a vector (`vector`) that contains the translation vectors for all the transformations +from gripper frame to robot base frame. +@param[in] R_target2cam Rotation part extracted from the homogeneous matrix that transforms a point +expressed in the target frame to the camera frame (\f$_{}^{c}\textrm{T}_t\f$). +This is a vector (`vector`) that contains the rotation matrices for all the transformations +from calibration target frame to camera frame. +@param[in] t_target2cam Rotation part extracted from the homogeneous matrix that transforms a point +expressed in the target frame to the camera frame (\f$_{}^{c}\textrm{T}_t\f$). +This is a vector (`vector`) that contains the translation vectors for all the transformations +from calibration target frame to camera frame. +@param[out] R_cam2gripper Estimated rotation part extracted from the homogeneous matrix that transforms a point +expressed in the camera frame to the gripper frame (\f$_{}^{g}\textrm{T}_c\f$). +@param[out] t_cam2gripper Estimated translation part extracted from the homogeneous matrix that transforms a point +expressed in the camera frame to the gripper frame (\f$_{}^{g}\textrm{T}_c\f$). +@param[in] method One of the implemented Hand-Eye calibration method, see cv::HandEyeCalibrationMethod + +The function performs the Hand-Eye calibration using various methods. One approach consists in estimating the +rotation then the translation (separable solutions) and the following methods are implemented: + - R. Tsai, R. Lenz A New Technique for Fully Autonomous and Efficient 3D Robotics Hand/EyeCalibration \cite Tsai89 + - F. Park, B. Martin Robot Sensor Calibration: Solving AX = XB on the Euclidean Group \cite Park94 + - R. Horaud, F. Dornaika Hand-Eye Calibration \cite Horaud95 + +Another approach consists in estimating simultaneously the rotation and the translation (simultaneous solutions), +with the following implemented method: + - N. Andreff, R. Horaud, B. Espiau On-line Hand-Eye Calibration \cite Andreff99 + - K. Daniilidis Hand-Eye Calibration Using Dual Quaternions \cite Daniilidis98 + +The following picture describes the Hand-Eye calibration problem where the transformation between a camera ("eye") +mounted on a robot gripper ("hand") has to be estimated. + +![](pics/hand-eye_figure.png) + +The calibration procedure is the following: + - a static calibration pattern is used to estimate the transformation between the target frame + and the camera frame + - the robot gripper is moved in order to acquire several poses + - for each pose, the homogeneous transformation between the gripper frame and the robot base frame is recorded using for + instance the robot kinematics +\f[ + \begin{bmatrix} + X_b\\ + Y_b\\ + Z_b\\ + 1 + \end{bmatrix} + = + \begin{bmatrix} + _{}^{b}\textrm{R}_g & _{}^{b}\textrm{t}_g \\ + 0_{1 \times 3} & 1 + \end{bmatrix} + \begin{bmatrix} + X_g\\ + Y_g\\ + Z_g\\ + 1 + \end{bmatrix} +\f] + - for each pose, the homogeneous transformation between the calibration target frame and the camera frame is recorded using + for instance a pose estimation method (PnP) from 2D-3D point correspondences +\f[ + \begin{bmatrix} + X_c\\ + Y_c\\ + Z_c\\ + 1 + \end{bmatrix} + = + \begin{bmatrix} + _{}^{c}\textrm{R}_t & _{}^{c}\textrm{t}_t \\ + 0_{1 \times 3} & 1 + \end{bmatrix} + \begin{bmatrix} + X_t\\ + Y_t\\ + Z_t\\ + 1 + \end{bmatrix} +\f] + +The Hand-Eye calibration procedure returns the following homogeneous transformation +\f[ + \begin{bmatrix} + X_g\\ + Y_g\\ + Z_g\\ + 1 + \end{bmatrix} + = + \begin{bmatrix} + _{}^{g}\textrm{R}_c & _{}^{g}\textrm{t}_c \\ + 0_{1 \times 3} & 1 + \end{bmatrix} + \begin{bmatrix} + X_c\\ + Y_c\\ + Z_c\\ + 1 + \end{bmatrix} +\f] + +This problem is also known as solving the \f$\mathbf{A}\mathbf{X}=\mathbf{X}\mathbf{B}\f$ equation: +\f[ + \begin{align*} + ^{b}{\textrm{T}_g}^{(1)} \hspace{0.2em} ^{g}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(1)} &= + \hspace{0.1em} ^{b}{\textrm{T}_g}^{(2)} \hspace{0.2em} ^{g}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(2)} \\ + + (^{b}{\textrm{T}_g}^{(2)})^{-1} \hspace{0.2em} ^{b}{\textrm{T}_g}^{(1)} \hspace{0.2em} ^{g}\textrm{T}_c &= + \hspace{0.1em} ^{g}\textrm{T}_c \hspace{0.2em} ^{c}{\textrm{T}_t}^{(2)} (^{c}{\textrm{T}_t}^{(1)})^{-1} \\ + + \textrm{A}_i \textrm{X} &= \textrm{X} \textrm{B}_i \\ + \end{align*} +\f] + +\note +Additional information can be found on this [website](http://campar.in.tum.de/Chair/HandEyeCalibration). +\note +A minimum of 2 motions with non parallel rotation axes are necessary to determine the hand-eye transformation. +So at least 3 different poses are required, but it is strongly recommended to use many more poses. + + */ +CV_EXPORTS_W void calibrateHandEye( InputArrayOfArrays R_gripper2base, InputArrayOfArrays t_gripper2base, + InputArrayOfArrays R_target2cam, InputArrayOfArrays t_target2cam, + OutputArray R_cam2gripper, OutputArray t_cam2gripper, + HandEyeCalibrationMethod method=CALIB_HAND_EYE_TSAI ); + +/** @brief Converts points from Euclidean to homogeneous space. + +@param src Input vector of N-dimensional points. +@param dst Output vector of N+1-dimensional points. + +The function converts points from Euclidean to homogeneous space by appending 1's to the tuple of +point coordinates. That is, each point (x1, x2, ..., xn) is converted to (x1, x2, ..., xn, 1). + */ +CV_EXPORTS_W void convertPointsToHomogeneous( InputArray src, OutputArray dst ); + +/** @brief Converts points from homogeneous to Euclidean space. + +@param src Input vector of N-dimensional points. +@param dst Output vector of N-1-dimensional points. + +The function converts points homogeneous to Euclidean space using perspective projection. That is, +each point (x1, x2, ... x(n-1), xn) is converted to (x1/xn, x2/xn, ..., x(n-1)/xn). When xn=0, the +output point coordinates will be (0,0,0,...). + */ +CV_EXPORTS_W void convertPointsFromHomogeneous( InputArray src, OutputArray dst ); + +/** @brief Converts points to/from homogeneous coordinates. + +@param src Input array or vector of 2D, 3D, or 4D points. +@param dst Output vector of 2D, 3D, or 4D points. + +The function converts 2D or 3D points from/to homogeneous coordinates by calling either +convertPointsToHomogeneous or convertPointsFromHomogeneous. + +@note The function is obsolete. Use one of the previous two functions instead. + */ +CV_EXPORTS void convertPointsHomogeneous( InputArray src, OutputArray dst ); + +/** @brief Calculates a fundamental matrix from the corresponding points in two images. + +@param points1 Array of N points from the first image. 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 method Method for computing a fundamental matrix. +- **CV_FM_7POINT** for a 7-point algorithm. \f$N = 7\f$ +- **CV_FM_8POINT** for an 8-point algorithm. \f$N \ge 8\f$ +- **CV_FM_RANSAC** for the RANSAC algorithm. \f$N \ge 8\f$ +- **CV_FM_LMEDS** for the LMedS algorithm. \f$N \ge 8\f$ +@param ransacReprojThreshold Parameter used only for RANSAC. It is the maximum distance from a point to an 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 confidence Parameter used for the RANSAC and LMedS methods only. It specifies a desirable level +of confidence (probability) that the estimated matrix is correct. +@param mask + +The epipolar geometry is described by the following equation: + +\f[[p_2; 1]^T F [p_1; 1] = 0\f] + +where \f$F\f$ is a fundamental matrix, \f$p_1\f$ and \f$p_2\f$ 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 found fundamental matrix. Normally just one matrix is found. But in case of the 7-point +algorithm, the function may return up to 3 solutions ( \f$9 \times 3\f$ matrix that stores all 3 +matrices sequentially). + +The calculated fundamental matrix may be passed further to computeCorrespondEpilines that finds the +epipolar lines corresponding to the specified points. It can also be passed to +stereoRectifyUncalibrated to compute the rectification transformation. : +@code + // Example. Estimation of fundamental matrix using the RANSAC algorithm + int point_count = 100; + vector points1(point_count); + vector points2(point_count); + + // initialize the points here ... + for( int i = 0; i < point_count; i++ ) + { + points1[i] = ...; + points2[i] = ...; + } + + Mat fundamental_matrix = + findFundamentalMat(points1, points2, FM_RANSAC, 3, 0.99); +@endcode + */ +CV_EXPORTS_W Mat findFundamentalMat( InputArray points1, InputArray points2, + int method = FM_RANSAC, + double ransacReprojThreshold = 3., double confidence = 0.99, + OutputArray mask = noArray() ); + +/** @overload */ +CV_EXPORTS Mat findFundamentalMat( InputArray points1, InputArray points2, + OutputArray mask, int method = FM_RANSAC, + double ransacReprojThreshold = 3., double confidence = 0.99 ); + +/** @brief Calculates an essential matrix from the corresponding points in two images. + +@param points1 Array of N (N \>= 5) 2D points from the first image. 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 cameraMatrix Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . +Note that this function assumes that points1 and points2 are feature points from cameras with the +same camera matrix. +@param method Method for computing an essential matrix. +- **RANSAC** for the RANSAC algorithm. +- **LMEDS** for the LMedS algorithm. +@param prob Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level of +confidence (probability) that the estimated matrix is correct. +@param threshold Parameter used for RANSAC. It is the maximum distance from a point to an 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 mask 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 the RANSAC and LMedS methods. + +This function estimates essential matrix based on the five-point algorithm solver in @cite Nister03 . +@cite SteweniusCFS is also a related. The epipolar geometry is described by the following equation: + +\f[[p_2; 1]^T K^{-T} E K^{-1} [p_1; 1] = 0\f] + +where \f$E\f$ is an essential matrix, \f$p_1\f$ and \f$p_2\f$ are corresponding points in the first and the +second images, respectively. The result of this function may be passed further to +decomposeEssentialMat or recoverPose to recover the relative pose between cameras. + */ +CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, + InputArray cameraMatrix, int method = RANSAC, + double prob = 0.999, double threshold = 1.0, + OutputArray mask = noArray() ); + +/** @overload +@param points1 Array of N (N \>= 5) 2D points from the first image. 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 focal focal length of the camera. Note that this function assumes that points1 and points2 +are feature points from cameras with same focal length and principal point. +@param pp principal point of the camera. +@param method Method for computing a fundamental matrix. +- **RANSAC** for the RANSAC algorithm. +- **LMEDS** for the LMedS algorithm. +@param threshold Parameter used for RANSAC. It is the maximum distance from a point to an 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 prob Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level of +confidence (probability) that the estimated matrix is correct. +@param mask 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 the RANSAC and LMedS methods. + +This function differs from the one above that it computes camera matrix from focal length and +principal point: + +\f[K = +\begin{bmatrix} +f & 0 & x_{pp} \\ +0 & f & y_{pp} \\ +0 & 0 & 1 +\end{bmatrix}\f] + */ +CV_EXPORTS_W Mat findEssentialMat( InputArray points1, InputArray points2, + double focal = 1.0, Point2d pp = Point2d(0, 0), + int method = RANSAC, double prob = 0.999, + double threshold = 1.0, OutputArray mask = noArray() ); + +/** @brief Decompose an essential matrix to possible rotations and translation. + +@param E The input essential matrix. +@param R1 One possible rotation matrix. +@param R2 Another possible rotation matrix. +@param t One possible translation. + +This function decompose an essential matrix E using svd decomposition @cite HartleyZ00 . Generally 4 +possible poses exists for a given E. They are \f$[R_1, t]\f$, \f$[R_1, -t]\f$, \f$[R_2, t]\f$, \f$[R_2, -t]\f$. By +decomposing E, you can only get the direction of the translation, so the function returns unit t. + */ +CV_EXPORTS_W void decomposeEssentialMat( InputArray E, OutputArray R1, OutputArray R2, OutputArray t ); + +/** @brief Recover relative camera rotation and translation from an estimated essential matrix and the +corresponding points in two images, using cheirality check. Returns the number of inliers which pass +the check. + +@param E The input essential matrix. +@param points1 Array of N 2D points from the first image. 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 cameraMatrix Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . +Note that this function assumes that points1 and points2 are feature points from cameras with the +same camera matrix. +@param R Recovered relative rotation. +@param t Recovered relative translation. +@param mask Input/output mask for inliers in points1 and points2. +: If it is not empty, then it marks inliers in points1 and points2 for then given essential +matrix E. Only these inliers will be used to recover pose. In the output mask only inliers +which pass the cheirality check. +This function decomposes an essential matrix using decomposeEssentialMat and then verifies possible +pose hypotheses by doing cheirality check. The cheirality check basically means that the +triangulated 3D points should have positive depth. Some details can be found in @cite Nister03 . + +This function can be used to process output E and mask from findEssentialMat. In this scenario, +points1 and points2 are the same input for findEssentialMat. : +@code + // Example. Estimation of fundamental matrix using the RANSAC algorithm + int point_count = 100; + vector points1(point_count); + vector points2(point_count); + + // initialize the points here ... + for( int i = 0; i < point_count; i++ ) + { + points1[i] = ...; + points2[i] = ...; + } + + // cametra matrix with both focal lengths = 1, and principal point = (0, 0) + Mat cameraMatrix = Mat::eye(3, 3, CV_64F); + + Mat E, R, t, mask; + + E = findEssentialMat(points1, points2, cameraMatrix, RANSAC, 0.999, 1.0, mask); + recoverPose(E, points1, points2, cameraMatrix, R, t, mask); +@endcode + */ +CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2, + InputArray cameraMatrix, OutputArray R, OutputArray t, + InputOutputArray mask = noArray() ); + +/** @overload +@param E The input essential matrix. +@param points1 Array of N 2D points from the first image. 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 R Recovered relative rotation. +@param t Recovered relative translation. +@param focal Focal length of the camera. Note that this function assumes that points1 and points2 +are feature points from cameras with same focal length and principal point. +@param pp principal point of the camera. +@param mask Input/output mask for inliers in points1 and points2. +: If it is not empty, then it marks inliers in points1 and points2 for then given essential +matrix E. Only these inliers will be used to recover pose. In the output mask only inliers +which pass the cheirality check. + +This function differs from the one above that it computes camera matrix from focal length and +principal point: + +\f[K = +\begin{bmatrix} +f & 0 & x_{pp} \\ +0 & f & y_{pp} \\ +0 & 0 & 1 +\end{bmatrix}\f] + */ +CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2, + OutputArray R, OutputArray t, + double focal = 1.0, Point2d pp = Point2d(0, 0), + InputOutputArray mask = noArray() ); + +/** @overload +@param E The input essential matrix. +@param points1 Array of N 2D points from the first image. 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 cameraMatrix Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . +Note that this function assumes that points1 and points2 are feature points from cameras with the +same camera matrix. +@param R Recovered relative rotation. +@param t Recovered relative translation. +@param distanceThresh threshold distance which is used to filter out far away points (i.e. infinite points). +@param mask Input/output mask for inliers in points1 and points2. +: If it is not empty, then it marks inliers in points1 and points2 for then given essential +matrix E. Only these inliers will be used to recover pose. In the output mask only inliers +which pass the cheirality check. +@param triangulatedPoints 3d points which were reconstructed by triangulation. + */ + +CV_EXPORTS_W int recoverPose( InputArray E, InputArray points1, InputArray points2, + InputArray cameraMatrix, OutputArray R, OutputArray t, double distanceThresh, InputOutputArray mask = noArray(), + OutputArray triangulatedPoints = noArray()); + +/** @brief For points in an image of a stereo pair, computes the corresponding epilines in the other image. + +@param points Input points. \f$N \times 1\f$ or \f$1 \times N\f$ matrix of type CV_32FC2 or +vector\ . +@param whichImage Index of the image (1 or 2) that contains the points . +@param F Fundamental matrix that can be estimated using findFundamentalMat or stereoRectify . +@param lines Output vector of the epipolar lines corresponding to the points in the other image. +Each line \f$ax + by + c=0\f$ is encoded by 3 numbers \f$(a, b, c)\f$ . + +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 findFundamentalMat ), line \f$l^{(2)}_i\f$ in the second +image for the point \f$p^{(1)}_i\f$ in the first image (when whichImage=1 ) is computed as: + +\f[l^{(2)}_i = F p^{(1)}_i\f] + +And vice versa, when whichImage=2, \f$l^{(1)}_i\f$ is computed from \f$p^{(2)}_i\f$ as: + +\f[l^{(1)}_i = F^T p^{(2)}_i\f] + +Line coefficients are defined up to a scale. They are normalized so that \f$a_i^2+b_i^2=1\f$ . + */ +CV_EXPORTS_W void computeCorrespondEpilines( InputArray points, int whichImage, + InputArray F, OutputArray lines ); + +/** @brief Reconstructs points by triangulation. + +@param projMatr1 3x4 projection matrix of the first camera. +@param projMatr2 3x4 projection matrix of the second camera. +@param projPoints1 2xN array of feature points in the first image. In case of c++ version it can +be also a vector of feature points or two-channel matrix of size 1xN or Nx1. +@param projPoints2 2xN array of corresponding points in the second image. In case of c++ version +it can be also a vector of feature points or two-channel matrix of size 1xN or Nx1. +@param points4D 4xN array of reconstructed points in homogeneous coordinates. + +The function reconstructs 3-dimensional points (in homogeneous coordinates) by using their +observations with a stereo camera. Projections matrices can be obtained from stereoRectify. + +@note + Keep in mind that all input data should be of float type in order for this function to work. + +@sa + reprojectImageTo3D + */ +CV_EXPORTS_W void triangulatePoints( InputArray projMatr1, InputArray projMatr2, + InputArray projPoints1, InputArray projPoints2, + OutputArray points4D ); + +/** @brief Refines coordinates of corresponding points. + +@param F 3x3 fundamental matrix. +@param points1 1xN array containing the first set of points. +@param points2 1xN array containing the second set of points. +@param newPoints1 The optimized points1. +@param newPoints2 The optimized points2. + +The function implements the Optimal Triangulation Method (see Multiple View Geometry for details). +For each given point correspondence points1[i] \<-\> points2[i], and a fundamental matrix F, it +computes the corrected correspondences newPoints1[i] \<-\> newPoints2[i] that minimize the geometric +error \f$d(points1[i], newPoints1[i])^2 + d(points2[i],newPoints2[i])^2\f$ (where \f$d(a,b)\f$ is the +geometric distance between points \f$a\f$ and \f$b\f$ ) subject to the epipolar constraint +\f$newPoints2^T * F * newPoints1 = 0\f$ . + */ +CV_EXPORTS_W void correctMatches( InputArray F, InputArray points1, InputArray points2, + OutputArray newPoints1, OutputArray newPoints2 ); + +/** @brief Filters off small noise blobs (speckles) in the disparity map + +@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. + */ +CV_EXPORTS_W void filterSpeckles( InputOutputArray img, double newVal, + int maxSpeckleSize, double maxDiff, + InputOutputArray buf = noArray() ); + +//! computes valid disparity ROI from the valid ROIs of the rectified images (that are returned by cv::stereoRectify()) +CV_EXPORTS_W Rect getValidDisparityROI( Rect roi1, Rect roi2, + int minDisparity, int numberOfDisparities, + int SADWindowSize ); + +//! validates disparity using the left-right check. The matrix "cost" should be computed by the stereo correspondence algorithm +CV_EXPORTS_W void validateDisparity( InputOutputArray disparity, InputArray cost, + int minDisparity, int numberOfDisparities, + int disp12MaxDisp = 1 ); + +/** @brief Reprojects a disparity image to 3D space. + +@param disparity Input single-channel 8-bit unsigned, 16-bit signed, 32-bit signed or 32-bit +floating-point disparity image. If 16-bit signed format is used, the values are assumed to have no +fractional bits. +@param _3dImage Output 3-channel floating-point image of the same size as disparity . Each +element of _3dImage(x,y) contains 3D coordinates of the point (x,y) computed from the disparity +map. +@param Q \f$4 \times 4\f$ perspective transformation matrix that can be obtained with stereoRectify. +@param handleMissingValues Indicates, whether the function should handle missing values (i.e. +points where the disparity was not computed). If handleMissingValues=true, then pixels with the +minimal disparity that corresponds to the outliers (see StereoMatcher::compute ) are transformed +to 3D points with a very large Z value (currently set to 10000). +@param ddepth The optional output array depth. If it is -1, the output image will have CV_32F +depth. ddepth can also be set to CV_16S, CV_32S or CV_32F. + +The function transforms a single-channel disparity map to a 3-channel image representing a 3D +surface. That is, for each pixel (x,y) and the corresponding disparity d=disparity(x,y) , it +computes: + +\f[\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}\f] + +The matrix Q can be an arbitrary \f$4 \times 4\f$ matrix (for example, the one computed by +stereoRectify). To reproject a sparse set of points {(x,y,d),...} to 3D space, use +perspectiveTransform . + */ +CV_EXPORTS_W void reprojectImageTo3D( InputArray disparity, + OutputArray _3dImage, InputArray Q, + bool handleMissingValues = false, + int ddepth = -1 ); + +/** @brief Calculates the Sampson Distance between two points. + +The function cv::sampsonDistance calculates and returns the first order approximation of the geometric error as: +\f[ +sd( \texttt{pt1} , \texttt{pt2} )= +\frac{(\texttt{pt2}^t \cdot \texttt{F} \cdot \texttt{pt1})^2} +{((\texttt{F} \cdot \texttt{pt1})(0))^2 + +((\texttt{F} \cdot \texttt{pt1})(1))^2 + +((\texttt{F}^t \cdot \texttt{pt2})(0))^2 + +((\texttt{F}^t \cdot \texttt{pt2})(1))^2} +\f] +The fundamental matrix may be calculated using the cv::findFundamentalMat function. See @cite HartleyZ00 11.4.3 for details. +@param pt1 first homogeneous 2d point +@param pt2 second homogeneous 2d point +@param F fundamental matrix +@return The computed Sampson distance. +*/ +CV_EXPORTS_W double sampsonDistance(InputArray pt1, InputArray pt2, InputArray F); + +/** @brief Computes an optimal affine transformation between two 3D point sets. + +It computes +\f[ +\begin{bmatrix} +x\\ +y\\ +z\\ +\end{bmatrix} += +\begin{bmatrix} +a_{11} & a_{12} & a_{13}\\ +a_{21} & a_{22} & a_{23}\\ +a_{31} & a_{32} & a_{33}\\ +\end{bmatrix} +\begin{bmatrix} +X\\ +Y\\ +Z\\ +\end{bmatrix} ++ +\begin{bmatrix} +b_1\\ +b_2\\ +b_3\\ +\end{bmatrix} +\f] + +@param src First input 3D point set containing \f$(X,Y,Z)\f$. +@param dst Second input 3D point set containing \f$(x,y,z)\f$. +@param out Output 3D affine transformation matrix \f$3 \times 4\f$ of the form +\f[ +\begin{bmatrix} +a_{11} & a_{12} & a_{13} & b_1\\ +a_{21} & a_{22} & a_{23} & b_2\\ +a_{31} & a_{32} & a_{33} & b_3\\ +\end{bmatrix} +\f] +@param inliers Output vector indicating which points are inliers (1-inlier, 0-outlier). +@param ransacThreshold Maximum reprojection error in the RANSAC algorithm to consider a point as +an inlier. +@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything +between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation +significantly. Values lower than 0.8-0.9 can result in an incorrectly estimated transformation. + +The function estimates an optimal 3D affine transformation between two 3D point sets using the +RANSAC algorithm. + */ +CV_EXPORTS_W int estimateAffine3D(InputArray src, InputArray dst, + OutputArray out, OutputArray inliers, + double ransacThreshold = 3, double confidence = 0.99); + +/** @brief Computes an optimal affine transformation between two 2D point sets. + +It computes +\f[ +\begin{bmatrix} +x\\ +y\\ +\end{bmatrix} += +\begin{bmatrix} +a_{11} & a_{12}\\ +a_{21} & a_{22}\\ +\end{bmatrix} +\begin{bmatrix} +X\\ +Y\\ +\end{bmatrix} ++ +\begin{bmatrix} +b_1\\ +b_2\\ +\end{bmatrix} +\f] + +@param from First input 2D point set containing \f$(X,Y)\f$. +@param to Second input 2D point set containing \f$(x,y)\f$. +@param inliers Output vector indicating which points are inliers (1-inlier, 0-outlier). +@param method Robust method used to compute transformation. The following methods are possible: +- cv::RANSAC - RANSAC-based robust method +- cv::LMEDS - Least-Median robust method +RANSAC is the default method. +@param ransacReprojThreshold Maximum reprojection error in the RANSAC algorithm to consider +a point as an inlier. Applies only to RANSAC. +@param maxIters The maximum number of robust method iterations. +@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything +between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation +significantly. Values lower than 0.8-0.9 can result in an incorrectly estimated transformation. +@param refineIters Maximum number of iterations of refining algorithm (Levenberg-Marquardt). +Passing 0 will disable refining, so the output matrix will be output of robust method. + +@return Output 2D affine transformation matrix \f$2 \times 3\f$ or empty matrix if transformation +could not be estimated. The returned matrix has the following form: +\f[ +\begin{bmatrix} +a_{11} & a_{12} & b_1\\ +a_{21} & a_{22} & b_2\\ +\end{bmatrix} +\f] + +The function estimates an optimal 2D affine transformation between two 2D point sets using the +selected robust algorithm. + +The computed transformation is then refined further (using only inliers) with the +Levenberg-Marquardt method to reduce the re-projection error even more. + +@note +The RANSAC method can handle practically any ratio of outliers but needs a 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. + +@sa estimateAffinePartial2D, getAffineTransform +*/ +CV_EXPORTS_W cv::Mat estimateAffine2D(InputArray from, InputArray to, OutputArray inliers = noArray(), + int method = RANSAC, double ransacReprojThreshold = 3, + size_t maxIters = 2000, double confidence = 0.99, + size_t refineIters = 10); + +/** @brief Computes an optimal limited affine transformation with 4 degrees of freedom between +two 2D point sets. + +@param from First input 2D point set. +@param to Second input 2D point set. +@param inliers Output vector indicating which points are inliers. +@param method Robust method used to compute transformation. The following methods are possible: +- cv::RANSAC - RANSAC-based robust method +- cv::LMEDS - Least-Median robust method +RANSAC is the default method. +@param ransacReprojThreshold Maximum reprojection error in the RANSAC algorithm to consider +a point as an inlier. Applies only to RANSAC. +@param maxIters The maximum number of robust method iterations. +@param confidence Confidence level, between 0 and 1, for the estimated transformation. Anything +between 0.95 and 0.99 is usually good enough. Values too close to 1 can slow down the estimation +significantly. Values lower than 0.8-0.9 can result in an incorrectly estimated transformation. +@param refineIters Maximum number of iterations of refining algorithm (Levenberg-Marquardt). +Passing 0 will disable refining, so the output matrix will be output of robust method. + +@return Output 2D affine transformation (4 degrees of freedom) matrix \f$2 \times 3\f$ or +empty matrix if transformation could not be estimated. + +The function estimates an optimal 2D affine transformation with 4 degrees of freedom limited to +combinations of translation, rotation, and uniform scaling. Uses the selected algorithm for robust +estimation. + +The computed transformation is then refined further (using only inliers) with the +Levenberg-Marquardt method to reduce the re-projection error even more. + +Estimated transformation matrix is: +\f[ \begin{bmatrix} \cos(\theta) \cdot s & -\sin(\theta) \cdot s & t_x \\ + \sin(\theta) \cdot s & \cos(\theta) \cdot s & t_y +\end{bmatrix} \f] +Where \f$ \theta \f$ is the rotation angle, \f$ s \f$ the scaling factor and \f$ t_x, t_y \f$ are +translations in \f$ x, y \f$ axes respectively. + +@note +The RANSAC method can handle practically any ratio of outliers but need a 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. + +@sa estimateAffine2D, getAffineTransform +*/ +CV_EXPORTS_W cv::Mat estimateAffinePartial2D(InputArray from, InputArray to, OutputArray inliers = noArray(), + int method = RANSAC, double ransacReprojThreshold = 3, + size_t maxIters = 2000, double confidence = 0.99, + size_t refineIters = 10); + +/** @example samples/cpp/tutorial_code/features2D/Homography/decompose_homography.cpp +An example program with homography decomposition. + +Check @ref tutorial_homography "the corresponding tutorial" for more details. +*/ + +/** @brief Decompose a homography matrix to rotation(s), translation(s) and plane normal(s). + +@param H The input homography matrix between two images. +@param K The input intrinsic camera calibration matrix. +@param rotations Array of rotation matrices. +@param translations Array of translation matrices. +@param normals Array of plane normal matrices. + +This function extracts relative camera motion between two views observing a planar object from the +homography H induced by the plane. The intrinsic camera matrix K must also be provided. The function +may return up to four mathematical solution sets. At least two of the solutions may further be +invalidated if point correspondences are available by applying positive depth constraint (all points +must be in front of the camera). The decomposition method is described in detail in @cite Malis . + */ +CV_EXPORTS_W int decomposeHomographyMat(InputArray H, + InputArray K, + OutputArrayOfArrays rotations, + OutputArrayOfArrays translations, + OutputArrayOfArrays normals); + +/** @brief Filters homography decompositions based on additional information. + +@param rotations Vector of rotation matrices. +@param normals Vector of plane normal matrices. +@param beforePoints Vector of (rectified) visible reference points before the homography is applied +@param afterPoints Vector of (rectified) visible reference points after the homography is applied +@param possibleSolutions Vector of int indices representing the viable solution set after filtering +@param pointsMask optional Mat/Vector of 8u type representing the mask for the inliers as given by the findHomography function + +This function is intended to filter the output of the decomposeHomographyMat based on additional +information as described in @cite Malis . The summary of the method: the decomposeHomographyMat function +returns 2 unique solutions and their "opposites" for a total of 4 solutions. If we have access to the +sets of points visible in the camera frame before and after the homography transformation is applied, +we can determine which are the true potential solutions and which are the opposites by verifying which +homographies are consistent with all visible reference points being in front of the camera. The inputs +are left unchanged; the filtered solution set is returned as indices into the existing one. + +*/ +CV_EXPORTS_W void filterHomographyDecompByVisibleRefpoints(InputArrayOfArrays rotations, + InputArrayOfArrays normals, + InputArray beforePoints, + InputArray afterPoints, + OutputArray possibleSolutions, + InputArray pointsMask = noArray()); + +/** @brief The base class for stereo correspondence algorithms. + */ +class CV_EXPORTS_W StereoMatcher : public Algorithm +{ +public: + enum { DISP_SHIFT = 4, + DISP_SCALE = (1 << DISP_SHIFT) + }; + + /** @brief Computes disparity map for the specified stereo pair + + @param left Left 8-bit single-channel image. + @param right Right image of the same size and the same type as the left one. + @param disparity Output disparity map. It has the same size as the input images. Some algorithms, + like StereoBM or StereoSGBM compute 16-bit fixed-point disparity map (where each disparity value + has 4 fractional bits), whereas other algorithms output 32-bit floating-point disparity map. + */ + CV_WRAP virtual void compute( InputArray left, InputArray right, + OutputArray disparity ) = 0; + + CV_WRAP virtual int getMinDisparity() const = 0; + CV_WRAP virtual void setMinDisparity(int minDisparity) = 0; + + CV_WRAP virtual int getNumDisparities() const = 0; + CV_WRAP virtual void setNumDisparities(int numDisparities) = 0; + + CV_WRAP virtual int getBlockSize() const = 0; + CV_WRAP virtual void setBlockSize(int blockSize) = 0; + + CV_WRAP virtual int getSpeckleWindowSize() const = 0; + CV_WRAP virtual void setSpeckleWindowSize(int speckleWindowSize) = 0; + + CV_WRAP virtual int getSpeckleRange() const = 0; + CV_WRAP virtual void setSpeckleRange(int speckleRange) = 0; + + CV_WRAP virtual int getDisp12MaxDiff() const = 0; + CV_WRAP virtual void setDisp12MaxDiff(int disp12MaxDiff) = 0; +}; + + +/** @brief Class for computing stereo correspondence using the block matching algorithm, introduced and +contributed to OpenCV by K. Konolige. + */ +class CV_EXPORTS_W StereoBM : public StereoMatcher +{ +public: + enum { PREFILTER_NORMALIZED_RESPONSE = 0, + PREFILTER_XSOBEL = 1 + }; + + CV_WRAP virtual int getPreFilterType() const = 0; + CV_WRAP virtual void setPreFilterType(int preFilterType) = 0; + + CV_WRAP virtual int getPreFilterSize() const = 0; + CV_WRAP virtual void setPreFilterSize(int preFilterSize) = 0; + + CV_WRAP virtual int getPreFilterCap() const = 0; + CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0; + + CV_WRAP virtual int getTextureThreshold() const = 0; + CV_WRAP virtual void setTextureThreshold(int textureThreshold) = 0; + + CV_WRAP virtual int getUniquenessRatio() const = 0; + CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0; + + CV_WRAP virtual int getSmallerBlockSize() const = 0; + CV_WRAP virtual void setSmallerBlockSize(int blockSize) = 0; + + CV_WRAP virtual Rect getROI1() const = 0; + CV_WRAP virtual void setROI1(Rect roi1) = 0; + + CV_WRAP virtual Rect getROI2() const = 0; + CV_WRAP virtual void setROI2(Rect roi2) = 0; + + /** @brief Creates StereoBM object + + @param numDisparities the disparity search range. For each pixel algorithm will find the best + disparity from 0 (default minimum disparity) to numDisparities. The search range can then be + shifted by changing the minimum disparity. + @param blockSize the linear size of the blocks compared by the algorithm. The size should be odd + (as the block is centered at the current pixel). Larger block size implies smoother, though less + accurate disparity map. Smaller block size gives more detailed disparity map, but there is higher + chance for algorithm to find a wrong correspondence. + + The function create StereoBM object. You can then call StereoBM::compute() to compute disparity for + a specific stereo pair. + */ + CV_WRAP static Ptr create(int numDisparities = 0, int blockSize = 21); +}; + +/** @brief The class implements the modified H. Hirschmuller algorithm @cite HH08 that differs from the original +one as follows: + +- By default, the algorithm is single-pass, which means that you consider only 5 directions +instead of 8. Set mode=StereoSGBM::MODE_HH in createStereoSGBM to run the full variant of the +algorithm but beware that it may consume a lot of memory. +- The algorithm matches blocks, not individual pixels. Though, setting blockSize=1 reduces the +blocks to single pixels. +- Mutual information cost function is not implemented. Instead, a simpler Birchfield-Tomasi +sub-pixel metric from @cite BT98 is used. Though, the color images are supported as well. +- Some pre- and post- processing steps from K. Konolige algorithm StereoBM are included, for +example: pre-filtering (StereoBM::PREFILTER_XSOBEL type) and post-filtering (uniqueness +check, quadratic interpolation and speckle filtering). + +@note + - (Python) An example illustrating the use of the StereoSGBM matching algorithm can be found + at opencv_source_code/samples/python/stereo_match.py + */ +class CV_EXPORTS_W StereoSGBM : public StereoMatcher +{ +public: + enum + { + MODE_SGBM = 0, + MODE_HH = 1, + MODE_SGBM_3WAY = 2, + MODE_HH4 = 3 + }; + + CV_WRAP virtual int getPreFilterCap() const = 0; + CV_WRAP virtual void setPreFilterCap(int preFilterCap) = 0; + + CV_WRAP virtual int getUniquenessRatio() const = 0; + CV_WRAP virtual void setUniquenessRatio(int uniquenessRatio) = 0; + + CV_WRAP virtual int getP1() const = 0; + CV_WRAP virtual void setP1(int P1) = 0; + + CV_WRAP virtual int getP2() const = 0; + CV_WRAP virtual void setP2(int P2) = 0; + + CV_WRAP virtual int getMode() const = 0; + CV_WRAP virtual void setMode(int mode) = 0; + + /** @brief Creates StereoSGBM object + + @param minDisparity Minimum possible disparity value. Normally, it is zero but sometimes + rectification algorithms can shift images, so this parameter needs to be adjusted accordingly. + @param numDisparities Maximum disparity minus minimum disparity. The value is always greater than + zero. In the current implementation, this parameter must be divisible by 16. + @param blockSize Matched block size. It must be an odd number \>=1 . Normally, it should be + somewhere in the 3..11 range. + @param P1 The first parameter controlling the disparity smoothness. See below. + @param P2 The second parameter controlling the disparity smoothness. The larger the values are, + the smoother the disparity is. P1 is the penalty on the disparity change by plus or minus 1 + between neighbor pixels. P2 is the penalty on the disparity change by more than 1 between neighbor + pixels. The algorithm requires P2 \> P1 . See stereo_match.cpp sample where some reasonably good + P1 and P2 values are shown (like 8\*number_of_image_channels\*SADWindowSize\*SADWindowSize and + 32\*number_of_image_channels\*SADWindowSize\*SADWindowSize , respectively). + @param disp12MaxDiff Maximum allowed difference (in integer pixel units) in the left-right + disparity check. Set it to a non-positive value to disable the check. + @param preFilterCap Truncation value for the prefiltered image pixels. The algorithm first + computes x-derivative at each pixel and clips its value by [-preFilterCap, preFilterCap] interval. + The result values are passed to the Birchfield-Tomasi pixel cost function. + @param uniquenessRatio Margin in percentage by which the best (minimum) computed cost function + value should "win" the second best value to consider the found match correct. Normally, a value + within the 5-15 range is good enough. + @param speckleWindowSize Maximum size of smooth disparity regions to consider their noise speckles + and invalidate. Set it to 0 to disable speckle filtering. Otherwise, set it somewhere in the + 50-200 range. + @param speckleRange Maximum disparity variation within each connected component. If you do speckle + filtering, set the parameter to a positive value, it will be implicitly multiplied by 16. + Normally, 1 or 2 is good enough. + @param mode Set it to StereoSGBM::MODE_HH to run the full-scale two-pass dynamic programming + algorithm. It will consume O(W\*H\*numDisparities) bytes, which is large for 640x480 stereo and + huge for HD-size pictures. By default, it is set to false . + + The first constructor initializes StereoSGBM with all the default parameters. So, you only have to + set StereoSGBM::numDisparities at minimum. The second constructor enables you to set each parameter + to a custom value. + */ + CV_WRAP static Ptr create(int minDisparity = 0, int numDisparities = 16, int blockSize = 3, + int P1 = 0, int P2 = 0, int disp12MaxDiff = 0, + int preFilterCap = 0, int uniquenessRatio = 0, + int speckleWindowSize = 0, int speckleRange = 0, + int mode = StereoSGBM::MODE_SGBM); +}; + + +//! cv::undistort mode +enum UndistortTypes +{ + PROJ_SPHERICAL_ORTHO = 0, + PROJ_SPHERICAL_EQRECT = 1 +}; + +/** @brief 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 #initUndistortRectifyMap (with unity R ) and #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). + +A particular subset of the source image that will be visible in the corrected image can be regulated +by newCameraMatrix. You can use #getOptimalNewCameraMatrix to compute the appropriate +newCameraMatrix depending on your requirements. + +The camera matrix and the distortion parameters can be determined using #calibrateCamera. If +the resolution of images is different from the resolution used at the calibration stage, \f$f_x, +f_y, c_x\f$ and \f$c_y\f$ need to be scaled accordingly, while the distortion coefficients remain +the same. + +@param src Input (distorted) image. +@param dst Output (corrected) image that has the same size and type as src . +@param cameraMatrix Input camera matrix \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ +of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. +@param newCameraMatrix Camera matrix of the distorted image. By default, it is the same as +cameraMatrix but you may additionally scale and shift the result by using a different matrix. + */ +CV_EXPORTS_W void undistort( InputArray src, OutputArray dst, + InputArray cameraMatrix, + InputArray distCoeffs, + InputArray newCameraMatrix = noArray() ); + +/** @brief Computes the undistortion and rectification transformation map. + +The function computes the joint undistortion and rectification transformation and represents the +result in the form of maps for remap. The undistorted image looks like original, as if it is +captured with a camera using the camera matrix =newCameraMatrix and zero distortion. In case of a +monocular camera, newCameraMatrix is usually equal to cameraMatrix, or it can be computed by +#getOptimalNewCameraMatrix for a better control over scaling. In case of a stereo camera, +newCameraMatrix is normally set to P1 or P2 computed by #stereoRectify . + +Also, this new camera is 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 case of a horizontally aligned stereo camera). + +The function actually builds the maps for the inverse mapping algorithm that is used by remap. That +is, for each pixel \f$(u, v)\f$ in the destination (corrected and rectified) image, the function +computes the corresponding coordinates in the source image (that is, in the original image from +camera). The following process is applied: +\f[ +\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 \\ +r^2 \leftarrow x'^2 + y'^2 \\ +x'' \leftarrow 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} ++ 2p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4\\ +y'' \leftarrow 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' + s_3 r^2 + s_4 r^4 \\ +s\vecthree{x'''}{y'''}{1} = +\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}((\tau_x, \tau_y)} +{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)} +{0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\ +map_x(u,v) \leftarrow x''' f_x + c_x \\ +map_y(u,v) \leftarrow y''' f_y + c_y +\end{array} +\f] +where \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ +are the distortion coefficients. + +In case of a stereo camera, this function is called twice: once for each camera head, after +stereoRectify, which in its turn is called after #stereoCalibrate. But if the stereo camera +was not calibrated, it is still possible to compute the rectification transformations directly from +the fundamental matrix using #stereoRectifyUncalibrated. For each camera, the function computes +homography H as the rectification transformation in a pixel domain, not a rotation matrix R in 3D +space. R can be computed from H as +\f[\texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix}\f] +where cameraMatrix can be chosen arbitrarily. + +@param cameraMatrix Input camera matrix \f$A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ +of 4, 5, 8, 12 or 14 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 #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 \f$A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\f$. +@param size Undistorted image size. +@param m1type Type of the first output map that can be CV_32FC1, CV_32FC2 or CV_16SC2, see #convertMaps +@param map1 The first output map. +@param map2 The second output map. + */ +CV_EXPORTS_W +void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs, + InputArray R, InputArray newCameraMatrix, + Size size, int m1type, OutputArray map1, OutputArray map2); + +//! initializes maps for #remap for wide-angle +CV_EXPORTS +float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs, + Size imageSize, int destImageWidth, + int m1type, OutputArray map1, OutputArray map2, + enum UndistortTypes projType = PROJ_SPHERICAL_EQRECT, double alpha = 0); +static inline +float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs, + Size imageSize, int destImageWidth, + int m1type, OutputArray map1, OutputArray map2, + int projType, double alpha = 0) +{ + return initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize, destImageWidth, + m1type, map1, map2, (UndistortTypes)projType, alpha); +} + +/** @brief Returns the default new camera matrix. + +The function returns the camera matrix that is either an exact copy of the input cameraMatrix (when +centerPrinicipalPoint=false ), or the modified one (when centerPrincipalPoint=true). + +In the latter case, the new camera matrix will be: + +\f[\begin{bmatrix} f_x && 0 && ( \texttt{imgSize.width} -1)*0.5 \\ 0 && f_y && ( \texttt{imgSize.height} -1)*0.5 \\ 0 && 0 && 1 \end{bmatrix} ,\f] + +where \f$f_x\f$ and \f$f_y\f$ are \f$(0,0)\f$ and \f$(1,1)\f$ elements of cameraMatrix, respectively. + +By default, the undistortion functions in OpenCV (see #initUndistortRectifyMap, #undistort) do not +move the principal point. However, when you work with stereo, it is important to move the principal +points in both views to the same y-coordinate (which is required by most of stereo correspondence +algorithms), and may be to the same x-coordinate too. So, you can form the new camera matrix for +each view where the principal points are located at the center. + +@param cameraMatrix Input camera matrix. +@param imgsize Camera view image size in pixels. +@param centerPrincipalPoint Location of the principal point in the new camera matrix. The +parameter indicates whether this location should be at the image center or not. + */ +CV_EXPORTS_W +Mat getDefaultNewCameraMatrix(InputArray cameraMatrix, Size imgsize = Size(), + bool centerPrincipalPoint = false); + +/** @brief Computes the ideal point coordinates from the observed point coordinates. + +The function is similar to #undistort and #initUndistortRectifyMap but it operates on a +sparse set of points instead of a raster image. Also the function performs a reverse transformation +to projectPoints. In case of a 3D object, it does not reconstruct its 3D coordinates, but for a +planar object, it does, up to a translation vector, if the proper R is specified. + +For each observed point coordinate \f$(u, v)\f$ the function computes: +\f[ +\begin{array}{l} +x^{"} \leftarrow (u - c_x)/f_x \\ +y^{"} \leftarrow (v - c_y)/f_y \\ +(x',y') = undistort(x^{"},y^{"}, \texttt{distCoeffs}) \\ +{[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\ +x \leftarrow X/W \\ +y \leftarrow Y/W \\ +\text{only performed if P is specified:} \\ +u' \leftarrow x {f'}_x + {c'}_x \\ +v' \leftarrow y {f'}_y + {c'}_y +\end{array} +\f] + +where *undistort* is an 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 for both a stereo camera head or a monocular camera (when R is empty). +@param src Observed point coordinates, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel (CV_32FC2 or CV_64FC2) (or +vector\ ). +@param dst Output ideal point coordinates (1xN/Nx1 2-channel or vector\ ) after undistortion and reverse perspective +transformation. If matrix P is identity or omitted, dst will contain normalized point coordinates. +@param cameraMatrix Camera matrix \f$\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . +@param distCoeffs Input vector of distortion coefficients +\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$ +of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. +@param R Rectification transformation in the object space (3x3 matrix). R1 or R2 computed by +#stereoRectify can be passed here. If the matrix is empty, the identity transformation is used. +@param P New camera matrix (3x3) or new projection matrix (3x4) \f$\begin{bmatrix} {f'}_x & 0 & {c'}_x & t_x \\ 0 & {f'}_y & {c'}_y & t_y \\ 0 & 0 & 1 & t_z \end{bmatrix}\f$. P1 or P2 computed by +#stereoRectify can be passed here. If the matrix is empty, the identity new camera matrix is used. + */ +CV_EXPORTS_W +void undistortPoints(InputArray src, OutputArray dst, + InputArray cameraMatrix, InputArray distCoeffs, + InputArray R = noArray(), InputArray P = noArray()); +/** @overload + @note Default version of #undistortPoints does 5 iterations to compute undistorted points. + */ +CV_EXPORTS_AS(undistortPointsIter) +void undistortPoints(InputArray src, OutputArray dst, + InputArray cameraMatrix, InputArray distCoeffs, + InputArray R, InputArray P, TermCriteria criteria); + +//! @} calib3d + +/** @brief The methods in this namespace use a so-called fisheye camera model. + @ingroup calib3d_fisheye +*/ +namespace fisheye +{ +//! @addtogroup calib3d_fisheye +//! @{ + + enum{ + CALIB_USE_INTRINSIC_GUESS = 1 << 0, + CALIB_RECOMPUTE_EXTRINSIC = 1 << 1, + CALIB_CHECK_COND = 1 << 2, + CALIB_FIX_SKEW = 1 << 3, + CALIB_FIX_K1 = 1 << 4, + CALIB_FIX_K2 = 1 << 5, + CALIB_FIX_K3 = 1 << 6, + CALIB_FIX_K4 = 1 << 7, + CALIB_FIX_INTRINSIC = 1 << 8, + CALIB_FIX_PRINCIPAL_POINT = 1 << 9 + }; + + /** @brief Projects points using fisheye model + + @param objectPoints Array of object points, 1xN/Nx1 3-channel (or vector\ ), where N is + the number of points in the view. + @param imagePoints Output array of image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, or + vector\. + @param affine + @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$. + @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$. + @param alpha The skew coefficient. + @param jacobian Optional output 2Nx15 jacobian matrix of derivatives of image points with respect + to components of the focal lengths, coordinates of the principal point, distortion coefficients, + rotation vector, translation vector, and the skew. In the old interface different components of + the jacobian are returned via different output parameters. + + 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. + */ + CV_EXPORTS void projectPoints(InputArray objectPoints, OutputArray imagePoints, const Affine3d& affine, + InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray()); + + /** @overload */ + CV_EXPORTS_W void projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray rvec, InputArray tvec, + InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray()); + + /** @brief Distorts 2D points using fisheye model. + + @param undistorted Array of object points, 1xN/Nx1 2-channel (or vector\ ), where N is + the number of points in the view. + @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$. + @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$. + @param alpha The skew coefficient. + @param distorted Output array of image points, 1xN/Nx1 2-channel, or vector\ . + + Note that the function assumes the camera matrix of the undistorted points to be identity. + This means if you want to transform back points undistorted with undistortPoints() you have to + multiply them with \f$P^{-1}\f$. + */ + CV_EXPORTS_W void distortPoints(InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha = 0); + + /** @brief Undistorts 2D points using fisheye model + + @param distorted Array of object points, 1xN/Nx1 2-channel (or vector\ ), where N is the + number of points in the view. + @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$. + @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$. + @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3 + 1-channel or 1x1 3-channel + @param P New camera matrix (3x3) or new projection matrix (3x4) + @param undistorted Output array of image points, 1xN/Nx1 2-channel, or vector\ . + */ + CV_EXPORTS_W void undistortPoints(InputArray distorted, OutputArray undistorted, + InputArray K, InputArray D, InputArray R = noArray(), InputArray P = noArray()); + + /** @brief Computes undistortion and rectification maps for image transform by cv::remap(). If D is empty zero + distortion is used, if R or P is empty identity matrixes are used. + + @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$. + @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$. + @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3 + 1-channel or 1x1 3-channel + @param P New camera matrix (3x3) or new projection matrix (3x4) + @param size Undistorted image size. + @param m1type Type of the first output map that can be CV_32FC1 or CV_16SC2 . See convertMaps() + for details. + @param map1 The first output map. + @param map2 The second output map. + */ + CV_EXPORTS_W void initUndistortRectifyMap(InputArray K, InputArray D, InputArray R, InputArray P, + const cv::Size& size, int m1type, OutputArray map1, OutputArray map2); + + /** @brief Transforms an image to compensate for fisheye lens distortion. + + @param distorted image with fisheye lens distortion. + @param undistorted Output image with compensated fisheye lens distortion. + @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$. + @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$. + @param Knew Camera matrix of the distorted image. By default, it is the identity matrix but you + may additionally scale and shift the result by using a different matrix. + @param new_size the new size + + The function transforms an image to compensate radial and tangential lens distortion. + + The function is simply a combination of fisheye::initUndistortRectifyMap (with unity R ) and remap + (with bilinear interpolation). See the former function for details of the transformation being + performed. + + See below the results of undistortImage. + - a\) result of undistort of perspective camera model (all possible coefficients (k_1, k_2, k_3, + k_4, k_5, k_6) of distortion were optimized under calibration) + - b\) result of fisheye::undistortImage of fisheye camera model (all possible coefficients (k_1, k_2, + k_3, k_4) of fisheye distortion were optimized under calibration) + - c\) original image was captured with fisheye lens + + Pictures a) and b) almost the same. But if we consider points of image located far from the center + of image, we can notice that on image a) these points are distorted. + + ![image](pics/fisheye_undistorted.jpg) + */ + CV_EXPORTS_W void undistortImage(InputArray distorted, OutputArray undistorted, + InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size()); + + /** @brief Estimates new camera matrix for undistortion or rectification. + + @param K Camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}\f$. + @param image_size Size of the image + @param D Input vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$. + @param R Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3 + 1-channel or 1x1 3-channel + @param P New camera matrix (3x3) or new projection matrix (3x4) + @param balance Sets the new focal length in range between the min focal length and the max focal + length. Balance is in range of [0, 1]. + @param new_size the new size + @param fov_scale Divisor for new focal length. + */ + CV_EXPORTS_W void estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R, + OutputArray P, double balance = 0.0, const Size& new_size = Size(), double fov_scale = 1.0); + + /** @brief Performs camera calibaration + + @param objectPoints vector of vectors of calibration pattern points in the calibration pattern + coordinate space. + @param imagePoints vector of vectors of the projections of calibration pattern points. + imagePoints.size() and objectPoints.size() and imagePoints[i].size() must be equal to + objectPoints[i].size() for each i. + @param image_size Size of the image used only to initialize the intrinsic camera matrix. + @param K Output 3x3 floating-point camera matrix + \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ . If + fisheye::CALIB_USE_INTRINSIC_GUESS/ is specified, some or all of fx, fy, cx, cy must be + initialized before calling the function. + @param D Output vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$. + @param rvecs Output vector of rotation vectors (see Rodrigues ) 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, that is, a real + position of the calibration pattern in the k-th pattern view (k=0.. *M* -1). + @param tvecs Output vector of translation vectors estimated for each pattern view. + @param flags Different flags that may be zero or a combination of the following values: + - **fisheye::CALIB_USE_INTRINSIC_GUESS** cameraMatrix contains 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), and focal distances are computed in a least-squares fashion. + - **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration + of intrinsic optimization. + - **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number. + - **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero. + - **fisheye::CALIB_FIX_K1..fisheye::CALIB_FIX_K4** Selected distortion coefficients + are set to zeros and stay zero. + - **fisheye::CALIB_FIX_PRINCIPAL_POINT** The principal point is not changed during the global +optimization. It stays at the center or at a different location specified when CALIB_USE_INTRINSIC_GUESS is set too. + @param criteria Termination criteria for the iterative optimization algorithm. + */ + CV_EXPORTS_W double calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size& image_size, + InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0, + TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON)); + + /** @brief Stereo rectification for fisheye camera model + + @param K1 First camera matrix. + @param D1 First camera distortion parameters. + @param K2 Second camera matrix. + @param D2 Second camera distortion parameters. + @param imageSize Size of the image used for stereo calibration. + @param R Rotation matrix between the coordinate systems of the first and the second + cameras. + @param tvec Translation vector between coordinate systems of the cameras. + @param R1 Output 3x3 rectification transform (rotation matrix) for the first camera. + @param R2 Output 3x3 rectification transform (rotation matrix) for the second camera. + @param P1 Output 3x4 projection matrix in the new (rectified) coordinate systems for the first + camera. + @param P2 Output 3x4 projection matrix in the new (rectified) coordinate systems for the second + camera. + @param Q Output \f$4 \times 4\f$ disparity-to-depth mapping matrix (see reprojectImageTo3D ). + @param flags Operation flags that may be zero or 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 the + horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the + useful image area. + @param newImageSize New image resolution after rectification. The same size should be passed to + 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 balance Sets the new focal length in range between the min focal length and the max focal + length. Balance is in range of [0, 1]. + @param fov_scale Divisor for new focal length. + */ + CV_EXPORTS_W void stereoRectify(InputArray K1, InputArray D1, InputArray K2, InputArray D2, const Size &imageSize, InputArray R, InputArray tvec, + OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags, const Size &newImageSize = Size(), + double balance = 0.0, double fov_scale = 1.0); + + /** @brief Performs stereo calibration + + @param objectPoints Vector of vectors of the calibration pattern points. + @param imagePoints1 Vector of vectors of the projections of the calibration pattern points, + observed by the first camera. + @param imagePoints2 Vector of vectors of the projections of the calibration pattern points, + observed by the second camera. + @param K1 Input/output first camera matrix: + \f$\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}\f$ , \f$j = 0,\, 1\f$ . If + any of fisheye::CALIB_USE_INTRINSIC_GUESS , fisheye::CALIB_FIX_INTRINSIC are specified, + some or all of the matrix components must be initialized. + @param D1 Input/output vector of distortion coefficients \f$(k_1, k_2, k_3, k_4)\f$ of 4 elements. + @param K2 Input/output second camera matrix. The parameter is similar to K1 . + @param D2 Input/output lens distortion coefficients for the second camera. The parameter is + similar to D1 . + @param imageSize Size of the image used only to initialize intrinsic camera matrix. + @param R Output rotation matrix between the 1st and the 2nd camera coordinate systems. + @param T Output translation vector between the coordinate systems of the cameras. + @param flags Different flags that may be zero or a combination of the following values: + - **fisheye::CALIB_FIX_INTRINSIC** Fix K1, K2? and D1, D2? so that only R, T matrices + are estimated. + - **fisheye::CALIB_USE_INTRINSIC_GUESS** K1, K2 contains 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), and focal distances are computed in a least-squares fashion. + - **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration + of intrinsic optimization. + - **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number. + - **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero. + - **fisheye::CALIB_FIX_K1..4** Selected distortion coefficients are set to zeros and stay + zero. + @param criteria Termination criteria for the iterative optimization algorithm. + */ + CV_EXPORTS_W double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, + InputOutputArray K1, InputOutputArray D1, InputOutputArray K2, InputOutputArray D2, Size imageSize, + OutputArray R, OutputArray T, int flags = fisheye::CALIB_FIX_INTRINSIC, + TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON)); + +//! @} calib3d_fisheye +} // end namespace fisheye + +} //end namespace cv + +#if 0 //def __cplusplus +////////////////////////////////////////////////////////////////////////////////////////// +class CV_EXPORTS CvLevMarq +{ +public: + CvLevMarq(); + CvLevMarq( int nparams, int nerrs, CvTermCriteria criteria= + cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON), + bool completeSymmFlag=false ); + ~CvLevMarq(); + void init( int nparams, int nerrs, CvTermCriteria criteria= + cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON), + bool completeSymmFlag=false ); + bool update( const CvMat*& param, CvMat*& J, CvMat*& err ); + bool updateAlt( const CvMat*& param, CvMat*& JtJ, CvMat*& JtErr, double*& errNorm ); + + void clear(); + void step(); + enum { DONE=0, STARTED=1, CALC_J=2, CHECK_ERR=3 }; + + cv::Ptr mask; + cv::Ptr prevParam; + cv::Ptr param; + cv::Ptr J; + cv::Ptr err; + cv::Ptr JtJ; + cv::Ptr JtJN; + cv::Ptr JtErr; + cv::Ptr JtJV; + cv::Ptr JtJW; + double prevErrNorm, errNorm; + int lambdaLg10; + CvTermCriteria criteria; + int state; + int iters; + bool completeSymmFlag; + int solveMethod; +}; +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d.hpp b/Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d.hpp new file mode 100755 index 0000000..b3da45e --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/calib3d.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d_c.h b/Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d_c.h new file mode 100755 index 0000000..e2af07b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/calib3d/calib3d_c.h @@ -0,0 +1,150 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CALIB3D_C_H +#define OPENCV_CALIB3D_C_H + +#include "opencv2/core/types_c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Calculates fundamental matrix given a set of corresponding points */ +#define CV_FM_7POINT 1 +#define CV_FM_8POINT 2 + +#define CV_LMEDS 4 +#define CV_RANSAC 8 + +#define CV_FM_LMEDS_ONLY CV_LMEDS +#define CV_FM_RANSAC_ONLY CV_RANSAC +#define CV_FM_LMEDS CV_LMEDS +#define CV_FM_RANSAC CV_RANSAC + +enum +{ + CV_ITERATIVE = 0, + CV_EPNP = 1, // F.Moreno-Noguer, V.Lepetit and P.Fua "EPnP: Efficient Perspective-n-Point Camera Pose Estimation" + CV_P3P = 2, // X.S. Gao, X.-R. Hou, J. Tang, H.-F. Chang; "Complete Solution Classification for the Perspective-Three-Point Problem" + CV_DLS = 3 // Joel A. Hesch and Stergios I. Roumeliotis. "A Direct Least-Squares (DLS) Method for PnP" +}; + +#define CV_CALIB_CB_ADAPTIVE_THRESH 1 +#define CV_CALIB_CB_NORMALIZE_IMAGE 2 +#define CV_CALIB_CB_FILTER_QUADS 4 +#define CV_CALIB_CB_FAST_CHECK 8 + +#define CV_CALIB_USE_INTRINSIC_GUESS 1 +#define CV_CALIB_FIX_ASPECT_RATIO 2 +#define CV_CALIB_FIX_PRINCIPAL_POINT 4 +#define CV_CALIB_ZERO_TANGENT_DIST 8 +#define CV_CALIB_FIX_FOCAL_LENGTH 16 +#define CV_CALIB_FIX_K1 32 +#define CV_CALIB_FIX_K2 64 +#define CV_CALIB_FIX_K3 128 +#define CV_CALIB_FIX_K4 2048 +#define CV_CALIB_FIX_K5 4096 +#define CV_CALIB_FIX_K6 8192 +#define CV_CALIB_RATIONAL_MODEL 16384 +#define CV_CALIB_THIN_PRISM_MODEL 32768 +#define CV_CALIB_FIX_S1_S2_S3_S4 65536 +#define CV_CALIB_TILTED_MODEL 262144 +#define CV_CALIB_FIX_TAUX_TAUY 524288 +#define CV_CALIB_FIX_TANGENT_DIST 2097152 + +#define CV_CALIB_NINTRINSIC 18 + +#define CV_CALIB_FIX_INTRINSIC 256 +#define CV_CALIB_SAME_FOCAL_LENGTH 512 + +#define CV_CALIB_ZERO_DISPARITY 1024 + +/* stereo correspondence parameters and functions */ +#define CV_STEREO_BM_NORMALIZED_RESPONSE 0 +#define CV_STEREO_BM_XSOBEL 1 + +#ifdef __cplusplus +} // extern "C" + +////////////////////////////////////////////////////////////////////////////////////////// +class CV_EXPORTS CvLevMarq +{ +public: + CvLevMarq(); + CvLevMarq( int nparams, int nerrs, CvTermCriteria criteria= + cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON), + bool completeSymmFlag=false ); + ~CvLevMarq(); + void init( int nparams, int nerrs, CvTermCriteria criteria= + cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,30,DBL_EPSILON), + bool completeSymmFlag=false ); + bool update( const CvMat*& param, CvMat*& J, CvMat*& err ); + bool updateAlt( const CvMat*& param, CvMat*& JtJ, CvMat*& JtErr, double*& errNorm ); + + void clear(); + void step(); + enum { DONE=0, STARTED=1, CALC_J=2, CHECK_ERR=3 }; + + cv::Ptr mask; + cv::Ptr prevParam; + cv::Ptr param; + cv::Ptr J; + cv::Ptr err; + cv::Ptr JtJ; + cv::Ptr JtJN; + cv::Ptr JtErr; + cv::Ptr JtJV; + cv::Ptr JtJW; + double prevErrNorm, errNorm; + int lambdaLg10; + CvTermCriteria criteria; + int state; + int iters; + bool completeSymmFlag; + int solveMethod; +}; + +#endif + +#endif /* OPENCV_CALIB3D_C_H */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core.hpp b/Prj-Win/3rd/opencv/include/opencv2/core.hpp new file mode 100755 index 0000000..1e25089 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core.hpp @@ -0,0 +1,3295 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2015, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Copyright (C) 2015, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_HPP +#define OPENCV_CORE_HPP + +#ifndef __cplusplus +# error core.hpp header must be compiled as C++ +#endif + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/version.hpp" +#include "opencv2/core/base.hpp" +#include "opencv2/core/cvstd.hpp" +#include "opencv2/core/traits.hpp" +#include "opencv2/core/matx.hpp" +#include "opencv2/core/types.hpp" +#include "opencv2/core/mat.hpp" +#include "opencv2/core/persistence.hpp" + +/** +@defgroup core Core functionality +@{ + @defgroup core_basic Basic structures + @defgroup core_c C structures and operations + @{ + @defgroup core_c_glue Connections with C++ + @} + @defgroup core_array Operations on arrays + @defgroup core_async Asynchronous API + @defgroup core_xml XML/YAML Persistence + @defgroup core_cluster Clustering + @defgroup core_utils Utility and system functions and macros + @{ + @defgroup core_utils_sse SSE utilities + @defgroup core_utils_neon NEON utilities + @defgroup core_utils_softfloat Softfloat support + @defgroup core_utils_samples Utility functions for OpenCV samples + @} + @defgroup core_opengl OpenGL interoperability + @defgroup core_ipp Intel IPP Asynchronous C/C++ Converters + @defgroup core_optim Optimization Algorithms + @defgroup core_directx DirectX interoperability + @defgroup core_eigen Eigen support + @defgroup core_opencl OpenCL support + @defgroup core_va_intel Intel VA-API/OpenCL (CL-VA) interoperability + @defgroup core_hal Hardware Acceleration Layer + @{ + @defgroup core_hal_functions Functions + @defgroup core_hal_interface Interface + @defgroup core_hal_intrin Universal intrinsics + @{ + @defgroup core_hal_intrin_impl Private implementation helpers + @} + @defgroup core_lowlevel_api Low-level API for external libraries / plugins + @} +@} + */ + +namespace cv { + +//! @addtogroup core_utils +//! @{ + +/*! @brief Class passed to an error. + +This class encapsulates all or almost all necessary +information about the error happened in the program. The exception is +usually constructed and thrown implicitly via CV_Error and CV_Error_ macros. +@see error + */ +class CV_EXPORTS Exception : public std::exception +{ +public: + /*! + Default constructor + */ + Exception(); + /*! + Full constructor. Normally the constructor is not called explicitly. + Instead, the macros CV_Error(), CV_Error_() and CV_Assert() are used. + */ + Exception(int _code, const String& _err, const String& _func, const String& _file, int _line); + virtual ~Exception() throw(); + + /*! + \return the error description and the context as a text string. + */ + virtual const char *what() const throw() CV_OVERRIDE; + void formatMessage(); + + String msg; ///< the formatted error message + + int code; ///< error code @see CVStatus + String err; ///< error description + String func; ///< function name. Available only when the compiler supports getting it + String file; ///< source file name where the error has occurred + int line; ///< line number in the source file where the error has occurred +}; + +/*! @brief Signals an error and raises the exception. + +By default the function prints information about the error to stderr, +then it either stops if cv::setBreakOnError() had been called before or raises the exception. +It is possible to alternate error processing by using #redirectError(). +@param exc the exception raisen. +@deprecated drop this version + */ +CV_EXPORTS CV_NORETURN void error(const Exception& exc); + +enum SortFlags { SORT_EVERY_ROW = 0, //!< each matrix row is sorted independently + SORT_EVERY_COLUMN = 1, //!< each matrix column is sorted + //!< independently; this flag and the previous one are + //!< mutually exclusive. + SORT_ASCENDING = 0, //!< each matrix row is sorted in the ascending + //!< order. + SORT_DESCENDING = 16 //!< each matrix row is sorted in the + //!< descending order; this flag and the previous one are also + //!< mutually exclusive. + }; + +//! @} core_utils + +//! @addtogroup core +//! @{ + +//! Covariation flags +enum CovarFlags { + /** The output covariance matrix is calculated as: + \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...],\f] + The covariance matrix will be nsamples x nsamples. Such an unusual covariance matrix is used + for fast PCA of a set of very large vectors (see, for example, the EigenFaces technique for + face recognition). Eigenvalues of this "scrambled" matrix match the eigenvalues of the true + covariance matrix. The "true" eigenvectors can be easily calculated from the eigenvectors of + the "scrambled" covariance matrix. */ + COVAR_SCRAMBLED = 0, + /**The output covariance matrix is calculated as: + \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...] \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T,\f] + covar will be a square matrix of the same size as the total number of elements in each input + vector. One and only one of #COVAR_SCRAMBLED and #COVAR_NORMAL must be specified.*/ + COVAR_NORMAL = 1, + /** If the flag is specified, the function does not calculate mean from + the input vectors but, instead, uses the passed mean vector. This is useful if mean has been + pre-calculated or known in advance, or if the covariance matrix is calculated by parts. In + this case, mean is not a mean vector of the input sub-set of vectors but rather the mean + vector of the whole set.*/ + COVAR_USE_AVG = 2, + /** If the flag is specified, the covariance matrix is scaled. In the + "normal" mode, scale is 1./nsamples . In the "scrambled" mode, scale is the reciprocal of the + total number of elements in each input vector. By default (if the flag is not specified), the + covariance matrix is not scaled ( scale=1 ).*/ + COVAR_SCALE = 4, + /** If the flag is + specified, all the input vectors are stored as rows of the samples matrix. mean should be a + single-row vector in this case.*/ + COVAR_ROWS = 8, + /** If the flag is + specified, all the input vectors are stored as columns of the samples matrix. mean should be a + single-column vector in this case.*/ + COVAR_COLS = 16 +}; + +//! k-Means flags +enum KmeansFlags { + /** Select random initial centers in each attempt.*/ + KMEANS_RANDOM_CENTERS = 0, + /** Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].*/ + KMEANS_PP_CENTERS = 2, + /** During the first (and possibly the only) attempt, use the + user-supplied labels instead of computing them from the initial centers. For the second and + further attempts, use the random or semi-random centers. Use one of KMEANS_\*_CENTERS flag + to specify the exact method.*/ + KMEANS_USE_INITIAL_LABELS = 1 +}; + +enum ReduceTypes { REDUCE_SUM = 0, //!< the output is the sum of all rows/columns of the matrix. + REDUCE_AVG = 1, //!< the output is the mean vector of all rows/columns of the matrix. + REDUCE_MAX = 2, //!< the output is the maximum (column/row-wise) of all rows/columns of the matrix. + REDUCE_MIN = 3 //!< the output is the minimum (column/row-wise) of all rows/columns of the matrix. + }; + + +/** @brief Swaps two matrices +*/ +CV_EXPORTS void swap(Mat& a, Mat& b); +/** @overload */ +CV_EXPORTS void swap( UMat& a, UMat& b ); + +//! @} core + +//! @addtogroup core_array +//! @{ + +/** @brief Computes the source location of an extrapolated pixel. + +The function computes and returns the coordinate of a donor pixel corresponding to the specified +extrapolated pixel when using the specified extrapolation border mode. For example, if you use +cv::BORDER_WRAP mode in the horizontal direction, cv::BORDER_REFLECT_101 in the vertical direction and +want to compute value of the "virtual" pixel Point(-5, 100) in a floating-point image img , it +looks like: +@code{.cpp} + float val = img.at(borderInterpolate(100, img.rows, cv::BORDER_REFLECT_101), + borderInterpolate(-5, img.cols, cv::BORDER_WRAP)); +@endcode +Normally, the function is not called directly. It is used inside filtering functions and also in +copyMakeBorder. +@param p 0-based coordinate of the extrapolated pixel along one of the axes, likely \<0 or \>= len +@param len Length of the array along the corresponding axis. +@param borderType Border type, one of the #BorderTypes, except for #BORDER_TRANSPARENT and +#BORDER_ISOLATED . When borderType==#BORDER_CONSTANT , the function always returns -1, regardless +of p and len. + +@sa copyMakeBorder +*/ +CV_EXPORTS_W int borderInterpolate(int p, int len, int borderType); + +/** @example samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp +An example using copyMakeBorder function. +Check @ref tutorial_copyMakeBorder "the corresponding tutorial" for more details +*/ + +/** @brief Forms a border around an image. + +The function copies the source image into the middle of the destination image. The areas to the +left, to the right, above and below the copied source image will be filled with extrapolated +pixels. This is not what filtering functions based on it do (they extrapolate pixels on-fly), but +what other more complex functions, including your own, may do to simplify image boundary handling. + +The function supports the mode when src is already in the middle of dst . In this case, the +function does not copy src itself but simply constructs the border, for example: + +@code{.cpp} + // let border be the same in all directions + int border=2; + // constructs a larger image to fit both the image and the border + Mat gray_buf(rgb.rows + border*2, rgb.cols + border*2, rgb.depth()); + // select the middle part of it w/o copying data + Mat gray(gray_canvas, Rect(border, border, rgb.cols, rgb.rows)); + // convert image from RGB to grayscale + cvtColor(rgb, gray, COLOR_RGB2GRAY); + // form a border in-place + copyMakeBorder(gray, gray_buf, border, border, + border, border, BORDER_REPLICATE); + // now do some custom filtering ... + ... +@endcode +@note When the source image is a part (ROI) of a bigger image, the function will try to use the +pixels outside of the ROI to form a border. To disable this feature and always do extrapolation, as +if src was not a ROI, use borderType | #BORDER_ISOLATED. + +@param src Source image. +@param dst Destination image of the same type as src and the size Size(src.cols+left+right, +src.rows+top+bottom) . +@param top the top pixels +@param bottom the bottom pixels +@param left the left pixels +@param right Parameter specifying how many pixels in each direction from the source image rectangle +to extrapolate. For example, top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs +to be built. +@param borderType Border type. See borderInterpolate for details. +@param value Border value if borderType==BORDER_CONSTANT . + +@sa borderInterpolate +*/ +CV_EXPORTS_W void copyMakeBorder(InputArray src, OutputArray dst, + int top, int bottom, int left, int right, + int borderType, const Scalar& value = Scalar() ); + +/** @brief Calculates the per-element sum of two arrays or an array and a scalar. + +The function add calculates: +- Sum of two arrays when both input arrays have the same size and the same number of channels: +\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f] +- Sum of an array and a scalar when src2 is constructed from Scalar or has the same number of +elements as `src1.channels()`: +\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f] +- Sum of a scalar and an array when src1 is constructed from Scalar or has the same number of +elements as `src2.channels()`: +\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} + \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f] +where `I` is a multi-dimensional index of array elements. In case of multi-channel arrays, each +channel is processed independently. + +The first function in the list above can be replaced with matrix expressions: +@code{.cpp} + dst = src1 + src2; + dst += src1; // equivalent to add(dst, src1, dst); +@endcode +The input arrays and the output array can all have the same or different depths. For example, you +can add a 16-bit unsigned array to a 8-bit signed array and store the sum as a 32-bit +floating-point array. Depth of the output array is determined by the dtype parameter. In the second +and third cases above, as well as in the first case, when src1.depth() == src2.depth(), dtype can +be set to the default -1. In this case, the output array will have the same depth as the input +array, be it src1, src2 or both. +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and number of channels as the input array(s); the +depth is defined by dtype or src1/src2. +@param mask optional operation mask - 8-bit single channel array, that specifies elements of the +output array to be changed. +@param dtype optional depth of the output array (see the discussion below). +@sa subtract, addWeighted, scaleAdd, Mat::convertTo +*/ +CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst, + InputArray mask = noArray(), int dtype = -1); + +/** @brief Calculates the per-element difference between two arrays or array and a scalar. + +The function subtract calculates: +- Difference between two arrays, when both input arrays have the same size and the same number of +channels: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f] +- Difference between an array and a scalar, when src2 is constructed from Scalar or has the same +number of elements as `src1.channels()`: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f] +- Difference between a scalar and an array, when src1 is constructed from Scalar or has the same +number of elements as `src2.channels()`: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} - \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f] +- The reverse difference between a scalar and an array in the case of `SubRS`: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src2} - \texttt{src1}(I) ) \quad \texttt{if mask}(I) \ne0\f] +where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each +channel is processed independently. + +The first function in the list above can be replaced with matrix expressions: +@code{.cpp} + dst = src1 - src2; + dst -= src1; // equivalent to subtract(dst, src1, dst); +@endcode +The input arrays and the output array can all have the same or different depths. For example, you +can subtract to 8-bit unsigned arrays and store the difference in a 16-bit signed array. Depth of +the output array is determined by dtype parameter. In the second and third cases above, as well as +in the first case, when src1.depth() == src2.depth(), dtype can be set to the default -1. In this +case the output array will have the same depth as the input array, be it src1, src2 or both. +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array of the same size and the same number of channels as the input array. +@param mask optional operation mask; this is an 8-bit single channel array that specifies elements +of the output array to be changed. +@param dtype optional depth of the output array +@sa add, addWeighted, scaleAdd, Mat::convertTo + */ +CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst, + InputArray mask = noArray(), int dtype = -1); + + +/** @brief Calculates the per-element scaled product of two arrays. + +The function multiply calculates the per-element product of two arrays: + +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I))\f] + +There is also a @ref MatrixExpressions -friendly variant of the first function. See Mat::mul . + +For a not-per-element matrix product, see gemm . + +@note Saturation is not applied when the output array has the depth +CV_32S. You may even get result of an incorrect sign in the case of +overflow. +@param src1 first input array. +@param src2 second input array of the same size and the same type as src1. +@param dst output array of the same size and type as src1. +@param scale optional scale factor. +@param dtype optional depth of the output array +@sa add, subtract, divide, scaleAdd, addWeighted, accumulate, accumulateProduct, accumulateSquare, +Mat::convertTo +*/ +CV_EXPORTS_W void multiply(InputArray src1, InputArray src2, + OutputArray dst, double scale = 1, int dtype = -1); + +/** @brief Performs per-element division of two arrays or a scalar by an array. + +The function cv::divide divides one array by another: +\f[\texttt{dst(I) = saturate(src1(I)*scale/src2(I))}\f] +or a scalar by an array when there is no src1 : +\f[\texttt{dst(I) = saturate(scale/src2(I))}\f] + +Different channels of multi-channel arrays are processed independently. + +For integer types when src2(I) is zero, dst(I) will also be zero. + +@note In case of floating point data there is no special defined behavior for zero src2(I) values. +Regular floating-point division is used. +Expect correct IEEE-754 behaviour for floating-point data (with NaN, Inf result values). + +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array. +@param src2 second input array of the same size and type as src1. +@param scale scalar factor. +@param dst output array of the same size and type as src2. +@param dtype optional depth of the output array; if -1, dst will have depth src2.depth(), but in +case of an array-by-array division, you can only pass -1 when src1.depth()==src2.depth(). +@sa multiply, add, subtract +*/ +CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst, + double scale = 1, int dtype = -1); + +/** @overload */ +CV_EXPORTS_W void divide(double scale, InputArray src2, + OutputArray dst, int dtype = -1); + +/** @brief Calculates the sum of a scaled array and another array. + +The function scaleAdd is one of the classical primitive linear algebra operations, known as DAXPY +or SAXPY in [BLAS](http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms). It calculates +the sum of a scaled array and another array: +\f[\texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) + \texttt{src2} (I)\f] +The function can also be emulated with a matrix expression, for example: +@code{.cpp} + Mat A(3, 3, CV_64F); + ... + A.row(0) = A.row(1)*2 + A.row(2); +@endcode +@param src1 first input array. +@param alpha scale factor for the first array. +@param src2 second input array of the same size and type as src1. +@param dst output array of the same size and type as src1. +@sa add, addWeighted, subtract, Mat::dot, Mat::convertTo +*/ +CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst); + +/** @example samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp +Check @ref tutorial_trackbar "the corresponding tutorial" for more details +*/ + +/** @brief Calculates the weighted sum of two arrays. + +The function addWeighted calculates the weighted sum of two arrays as follows: +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} )\f] +where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each +channel is processed independently. +The function can be replaced with a matrix expression: +@code{.cpp} + dst = src1*alpha + src2*beta + gamma; +@endcode +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array. +@param alpha weight of the first array elements. +@param src2 second input array of the same size and channel number as src1. +@param beta weight of the second array elements. +@param gamma scalar added to each sum. +@param dst output array that has the same size and number of channels as the input arrays. +@param dtype optional depth of the output array; when both input arrays have the same depth, dtype +can be set to -1, which will be equivalent to src1.depth(). +@sa add, subtract, scaleAdd, Mat::convertTo +*/ +CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2, + double beta, double gamma, OutputArray dst, int dtype = -1); + +/** @brief Scales, calculates absolute values, and converts the result to 8-bit. + +On each element of the input array, the function convertScaleAbs +performs three operations sequentially: scaling, taking an absolute +value, conversion to an unsigned 8-bit type: +\f[\texttt{dst} (I)= \texttt{saturate\_cast} (| \texttt{src} (I)* \texttt{alpha} + \texttt{beta} |)\f] +In case of multi-channel arrays, the function processes each channel +independently. When the output is not 8-bit, the operation can be +emulated by calling the Mat::convertTo method (or by using matrix +expressions) and then by calculating an absolute value of the result. +For example: +@code{.cpp} + Mat_ A(30,30); + randu(A, Scalar(-100), Scalar(100)); + Mat_ B = A*5 + 3; + B = abs(B); + // Mat_ B = abs(A*5+3) will also do the job, + // but it will allocate a temporary matrix +@endcode +@param src input array. +@param dst output array. +@param alpha optional scale factor. +@param beta optional delta added to the scaled values. +@sa Mat::convertTo, cv::abs(const Mat&) +*/ +CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst, + double alpha = 1, double beta = 0); + +/** @brief Converts an array to half precision floating number. + +This function converts FP32 (single precision floating point) from/to FP16 (half precision floating point). CV_16S format is used to represent FP16 data. +There are two use modes (src -> dst): CV_32F -> CV_16S and CV_16S -> CV_32F. The input array has to have type of CV_32F or +CV_16S to represent the bit depth. If the input array is neither of them, the function will raise an error. +The format of half precision floating point is defined in IEEE 754-2008. + +@param src input array. +@param dst output array. +*/ +CV_EXPORTS_W void convertFp16(InputArray src, OutputArray dst); + +/** @brief Performs a look-up table transform of an array. + +The function LUT fills the output array with values from the look-up table. Indices of the entries +are taken from the input array. That is, the function processes each element of src as follows: +\f[\texttt{dst} (I) \leftarrow \texttt{lut(src(I) + d)}\f] +where +\f[d = \fork{0}{if \(\texttt{src}\) has depth \(\texttt{CV_8U}\)}{128}{if \(\texttt{src}\) has depth \(\texttt{CV_8S}\)}\f] +@param src input array of 8-bit elements. +@param lut look-up table of 256 elements; in case of multi-channel input array, the table should +either have a single channel (in this case the same table is used for all channels) or the same +number of channels as in the input array. +@param dst output array of the same size and number of channels as src, and the same depth as lut. +@sa convertScaleAbs, Mat::convertTo +*/ +CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst); + +/** @brief Calculates the sum of array elements. + +The function cv::sum calculates and returns the sum of array elements, +independently for each channel. +@param src input array that must have from 1 to 4 channels. +@sa countNonZero, mean, meanStdDev, norm, minMaxLoc, reduce +*/ +CV_EXPORTS_AS(sumElems) Scalar sum(InputArray src); + +/** @brief Counts non-zero array elements. + +The function returns the number of non-zero elements in src : +\f[\sum _{I: \; \texttt{src} (I) \ne0 } 1\f] +@param src single-channel array. +@sa mean, meanStdDev, norm, minMaxLoc, calcCovarMatrix +*/ +CV_EXPORTS_W int countNonZero( InputArray src ); + +/** @brief Returns the list of locations of non-zero pixels + +Given a binary matrix (likely returned from an operation such +as threshold(), compare(), >, ==, etc, return all of +the non-zero indices as a cv::Mat or std::vector (x,y) +For example: +@code{.cpp} + cv::Mat binaryImage; // input, binary image + cv::Mat locations; // output, locations of non-zero pixels + cv::findNonZero(binaryImage, locations); + + // access pixel coordinates + Point pnt = locations.at(i); +@endcode +or +@code{.cpp} + cv::Mat binaryImage; // input, binary image + vector locations; // output, locations of non-zero pixels + cv::findNonZero(binaryImage, locations); + + // access pixel coordinates + Point pnt = locations[i]; +@endcode +@param src single-channel array +@param idx the output array, type of cv::Mat or std::vector, corresponding to non-zero indices in the input +*/ +CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx ); + +/** @brief Calculates an average (mean) of array elements. + +The function cv::mean calculates the mean value M of array elements, +independently for each channel, and return it: +\f[\begin{array}{l} N = \sum _{I: \; \texttt{mask} (I) \ne 0} 1 \\ M_c = \left ( \sum _{I: \; \texttt{mask} (I) \ne 0}{ \texttt{mtx} (I)_c} \right )/N \end{array}\f] +When all the mask elements are 0's, the function returns Scalar::all(0) +@param src input array that should have from 1 to 4 channels so that the result can be stored in +Scalar_ . +@param mask optional operation mask. +@sa countNonZero, meanStdDev, norm, minMaxLoc +*/ +CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask = noArray()); + +/** Calculates a mean and standard deviation of array elements. + +The function cv::meanStdDev calculates the mean and the standard deviation M +of array elements independently for each channel and returns it via the +output parameters: +\f[\begin{array}{l} N = \sum _{I, \texttt{mask} (I) \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \texttt{src} (I)_c}{N} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N}} \end{array}\f] +When all the mask elements are 0's, the function returns +mean=stddev=Scalar::all(0). +@note The calculated standard deviation is only the diagonal of the +complete normalized covariance matrix. If the full matrix is needed, you +can reshape the multi-channel array M x N to the single-channel array +M\*N x mtx.channels() (only possible when the matrix is continuous) and +then pass the matrix to calcCovarMatrix . +@param src input array that should have from 1 to 4 channels so that the results can be stored in +Scalar_ 's. +@param mean output parameter: calculated mean value. +@param stddev output parameter: calculated standard deviation. +@param mask optional operation mask. +@sa countNonZero, mean, norm, minMaxLoc, calcCovarMatrix +*/ +CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev, + InputArray mask=noArray()); + +/** @brief Calculates the absolute norm of an array. + +This version of #norm calculates the absolute norm of src1. The type of norm to calculate is specified using #NormTypes. + +As example for one array consider the function \f$r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1]\f$. +The \f$ L_{1}, L_{2} \f$ and \f$ L_{\infty} \f$ norm for the sample value \f$r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix}\f$ +is calculated as follows +\f{align*} + \| r(-1) \|_{L_1} &= |-1| + |2| = 3 \\ + \| r(-1) \|_{L_2} &= \sqrt{(-1)^{2} + (2)^{2}} = \sqrt{5} \\ + \| r(-1) \|_{L_\infty} &= \max(|-1|,|2|) = 2 +\f} +and for \f$r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix}\f$ the calculation is +\f{align*} + \| r(0.5) \|_{L_1} &= |0.5| + |0.5| = 1 \\ + \| r(0.5) \|_{L_2} &= \sqrt{(0.5)^{2} + (0.5)^{2}} = \sqrt{0.5} \\ + \| r(0.5) \|_{L_\infty} &= \max(|0.5|,|0.5|) = 0.5. +\f} +The following graphic shows all values for the three norm functions \f$\| r(x) \|_{L_1}, \| r(x) \|_{L_2}\f$ and \f$\| r(x) \|_{L_\infty}\f$. +It is notable that the \f$ L_{1} \f$ norm forms the upper and the \f$ L_{\infty} \f$ norm forms the lower border for the example function \f$ r(x) \f$. +![Graphs for the different norm functions from the above example](pics/NormTypes_OneArray_1-2-INF.png) + +When the mask parameter is specified and it is not empty, the norm is + +If normType is not specified, #NORM_L2 is used. +calculated only over the region specified by the mask. + +Multi-channel input arrays are treated as single-channel arrays, that is, +the results for all channels are combined. + +Hamming norms can only be calculated with CV_8U depth arrays. + +@param src1 first input array. +@param normType type of the norm (see #NormTypes). +@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type. +*/ +CV_EXPORTS_W double norm(InputArray src1, int normType = NORM_L2, InputArray mask = noArray()); + +/** @brief Calculates an absolute difference norm or a relative difference norm. + +This version of cv::norm calculates the absolute difference norm +or the relative difference norm of arrays src1 and src2. +The type of norm to calculate is specified using #NormTypes. + +@param src1 first input array. +@param src2 second input array of the same size and the same type as src1. +@param normType type of the norm (see #NormTypes). +@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type. +*/ +CV_EXPORTS_W double norm(InputArray src1, InputArray src2, + int normType = NORM_L2, InputArray mask = noArray()); +/** @overload +@param src first input array. +@param normType type of the norm (see #NormTypes). +*/ +CV_EXPORTS double norm( const SparseMat& src, int normType ); + +/** @brief Computes the Peak Signal-to-Noise Ratio (PSNR) image quality metric. + +This function calculates the Peak Signal-to-Noise Ratio (PSNR) image quality metric in decibels (dB), +between two input arrays src1 and src2. The arrays must have the same type. + +The PSNR is calculated as follows: + +\f[ +\texttt{PSNR} = 10 \cdot \log_{10}{\left( \frac{R^2}{MSE} \right) } +\f] + +where R is the maximum integer value of depth (e.g. 255 in the case of CV_8U data) +and MSE is the mean squared error between the two arrays. + +@param src1 first input array. +@param src2 second input array of the same size as src1. +@param R the maximum pixel value (255 by default) + + */ +CV_EXPORTS_W double PSNR(InputArray src1, InputArray src2, double R=255.); + +/** @brief naive nearest neighbor finder + +see http://en.wikipedia.org/wiki/Nearest_neighbor_search +@todo document + */ +CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2, + OutputArray dist, int dtype, OutputArray nidx, + int normType = NORM_L2, int K = 0, + InputArray mask = noArray(), int update = 0, + bool crosscheck = false); + +/** @brief Normalizes the norm or value range of an array. + +The function cv::normalize normalizes scale and shift the input array elements so that +\f[\| \texttt{dst} \| _{L_p}= \texttt{alpha}\f] +(where p=Inf, 1 or 2) when normType=NORM_INF, NORM_L1, or NORM_L2, respectively; or so that +\f[\min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta}\f] + +when normType=NORM_MINMAX (for dense arrays only). The optional mask specifies a sub-array to be +normalized. This means that the norm or min-n-max are calculated over the sub-array, and then this +sub-array is modified to be normalized. If you want to only use the mask to calculate the norm or +min-max but modify the whole array, you can use norm and Mat::convertTo. + +In case of sparse matrices, only the non-zero values are analyzed and transformed. Because of this, +the range transformation for sparse matrices is not allowed since it can shift the zero level. + +Possible usage with some positive example data: +@code{.cpp} + vector positiveData = { 2.0, 8.0, 10.0 }; + vector normalizedData_l1, normalizedData_l2, normalizedData_inf, normalizedData_minmax; + + // Norm to probability (total count) + // sum(numbers) = 20.0 + // 2.0 0.1 (2.0/20.0) + // 8.0 0.4 (8.0/20.0) + // 10.0 0.5 (10.0/20.0) + normalize(positiveData, normalizedData_l1, 1.0, 0.0, NORM_L1); + + // Norm to unit vector: ||positiveData|| = 1.0 + // 2.0 0.15 + // 8.0 0.62 + // 10.0 0.77 + normalize(positiveData, normalizedData_l2, 1.0, 0.0, NORM_L2); + + // Norm to max element + // 2.0 0.2 (2.0/10.0) + // 8.0 0.8 (8.0/10.0) + // 10.0 1.0 (10.0/10.0) + normalize(positiveData, normalizedData_inf, 1.0, 0.0, NORM_INF); + + // Norm to range [0.0;1.0] + // 2.0 0.0 (shift to left border) + // 8.0 0.75 (6.0/8.0) + // 10.0 1.0 (shift to right border) + normalize(positiveData, normalizedData_minmax, 1.0, 0.0, NORM_MINMAX); +@endcode + +@param src input array. +@param dst output array of the same size as src . +@param alpha norm value to normalize to or the lower range boundary in case of the range +normalization. +@param beta upper range boundary in case of the range normalization; it is not used for the norm +normalization. +@param norm_type normalization type (see cv::NormTypes). +@param dtype when negative, the output array has the same type as src; otherwise, it has the same +number of channels as src and the depth =CV_MAT_DEPTH(dtype). +@param mask optional operation mask. +@sa norm, Mat::convertTo, SparseMat::convertTo +*/ +CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0, + int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray()); + +/** @overload +@param src input array. +@param dst output array of the same size as src . +@param alpha norm value to normalize to or the lower range boundary in case of the range +normalization. +@param normType normalization type (see cv::NormTypes). +*/ +CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType ); + +/** @brief Finds the global minimum and maximum in an array. + +The function cv::minMaxLoc finds the minimum and maximum element values and their positions. The +extremums are searched across the whole array or, if mask is not an empty array, in the specified +array region. + +The function do not work with multi-channel arrays. If you need to find minimum or maximum +elements across all the channels, use Mat::reshape first to reinterpret the array as +single-channel. Or you may extract the particular channel using either extractImageCOI , or +mixChannels , or split . +@param src input single-channel array. +@param minVal pointer to the returned minimum value; NULL is used if not required. +@param maxVal pointer to the returned maximum value; NULL is used if not required. +@param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required. +@param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required. +@param mask optional mask used to select a sub-array. +@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape +*/ +CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal, + CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0, + CV_OUT Point* maxLoc = 0, InputArray mask = noArray()); + + +/** @brief Finds the global minimum and maximum in an array + +The function cv::minMaxIdx finds the minimum and maximum element values and their positions. The +extremums are searched across the whole array or, if mask is not an empty array, in the specified +array region. The function does not work with multi-channel arrays. If you need to find minimum or +maximum elements across all the channels, use Mat::reshape first to reinterpret the array as +single-channel. Or you may extract the particular channel using either extractImageCOI , or +mixChannels , or split . In case of a sparse matrix, the minimum is found among non-zero elements +only. +@note When minIdx is not NULL, it must have at least 2 elements (as well as maxIdx), even if src is +a single-row or single-column matrix. In OpenCV (following MATLAB) each array has at least 2 +dimensions, i.e. single-column matrix is Mx1 matrix (and therefore minIdx/maxIdx will be +(i1,0)/(i2,0)) and single-row matrix is 1xN matrix (and therefore minIdx/maxIdx will be +(0,j1)/(0,j2)). +@param src input single-channel array. +@param minVal pointer to the returned minimum value; NULL is used if not required. +@param maxVal pointer to the returned maximum value; NULL is used if not required. +@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required; +Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element +in each dimension are stored there sequentially. +@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required. +@param mask specified array region +*/ +CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal = 0, + int* minIdx = 0, int* maxIdx = 0, InputArray mask = noArray()); + +/** @overload +@param a input single-channel array. +@param minVal pointer to the returned minimum value; NULL is used if not required. +@param maxVal pointer to the returned maximum value; NULL is used if not required. +@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required; +Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element +in each dimension are stored there sequentially. +@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required. +*/ +CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal, + double* maxVal, int* minIdx = 0, int* maxIdx = 0); + +/** @brief Reduces a matrix to a vector. + +The function #reduce reduces the matrix to a vector by treating the matrix rows/columns as a set of +1D vectors and performing the specified operation on the vectors until a single row/column is +obtained. For example, the function can be used to compute horizontal and vertical projections of a +raster image. In case of #REDUCE_MAX and #REDUCE_MIN , the output image should have the same type as the source one. +In case of #REDUCE_SUM and #REDUCE_AVG , the output may have a larger element bit-depth to preserve accuracy. +And multi-channel arrays are also supported in these two reduction modes. + +The following code demonstrates its usage for a single channel matrix. +@snippet snippets/core_reduce.cpp example + +And the following code demonstrates its usage for a two-channel matrix. +@snippet snippets/core_reduce.cpp example2 + +@param src input 2D matrix. +@param dst output vector. Its size and type is defined by dim and dtype parameters. +@param dim dimension index along which the matrix is reduced. 0 means that the matrix is reduced to +a single row. 1 means that the matrix is reduced to a single column. +@param rtype reduction operation that could be one of #ReduceTypes +@param dtype when negative, the output vector will have the same type as the input matrix, +otherwise, its type will be CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels()). +@sa repeat +*/ +CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype = -1); + +/** @brief Creates one multi-channel array out of several single-channel ones. + +The function cv::merge merges several arrays to make a single multi-channel array. That is, each +element of the output array will be a concatenation of the elements of the input arrays, where +elements of i-th input array are treated as mv[i].channels()-element vectors. + +The function cv::split does the reverse operation. If you need to shuffle channels in some other +advanced way, use cv::mixChannels. + +The following example shows how to merge 3 single channel matrices into a single 3-channel matrix. +@snippet snippets/core_merge.cpp example + +@param mv input array of matrices to be merged; all the matrices in mv must have the same +size and the same depth. +@param count number of input matrices when mv is a plain C array; it must be greater than zero. +@param dst output array of the same size and the same depth as mv[0]; The number of channels will +be equal to the parameter count. +@sa mixChannels, split, Mat::reshape +*/ +CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst); + +/** @overload +@param mv input vector of matrices to be merged; all the matrices in mv must have the same +size and the same depth. +@param dst output array of the same size and the same depth as mv[0]; The number of channels will +be the total number of channels in the matrix array. + */ +CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst); + +/** @brief Divides a multi-channel array into several single-channel arrays. + +The function cv::split splits a multi-channel array into separate single-channel arrays: +\f[\texttt{mv} [c](I) = \texttt{src} (I)_c\f] +If you need to extract a single channel or do some other sophisticated channel permutation, use +mixChannels . + +The following example demonstrates how to split a 3-channel matrix into 3 single channel matrices. +@snippet snippets/core_split.cpp example + +@param src input multi-channel array. +@param mvbegin output array; the number of arrays must match src.channels(); the arrays themselves are +reallocated, if needed. +@sa merge, mixChannels, cvtColor +*/ +CV_EXPORTS void split(const Mat& src, Mat* mvbegin); + +/** @overload +@param m input multi-channel array. +@param mv output vector of arrays; the arrays themselves are reallocated, if needed. +*/ +CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv); + +/** @brief Copies specified channels from input arrays to the specified channels of +output arrays. + +The function cv::mixChannels provides an advanced mechanism for shuffling image channels. + +cv::split,cv::merge,cv::extractChannel,cv::insertChannel and some forms of cv::cvtColor are partial cases of cv::mixChannels. + +In the example below, the code splits a 4-channel BGRA image into a 3-channel BGR (with B and R +channels swapped) and a separate alpha-channel image: +@code{.cpp} + Mat bgra( 100, 100, CV_8UC4, Scalar(255,0,0,255) ); + Mat bgr( bgra.rows, bgra.cols, CV_8UC3 ); + Mat alpha( bgra.rows, bgra.cols, CV_8UC1 ); + + // forming an array of matrices is a quite efficient operation, + // because the matrix data is not copied, only the headers + Mat out[] = { bgr, alpha }; + // bgra[0] -> bgr[2], bgra[1] -> bgr[1], + // bgra[2] -> bgr[0], bgra[3] -> alpha[0] + int from_to[] = { 0,2, 1,1, 2,0, 3,3 }; + mixChannels( &bgra, 1, out, 2, from_to, 4 ); +@endcode +@note Unlike many other new-style C++ functions in OpenCV (see the introduction section and +Mat::create ), cv::mixChannels requires the output arrays to be pre-allocated before calling the +function. +@param src input array or vector of matrices; all of the matrices must have the same size and the +same depth. +@param nsrcs number of matrices in `src`. +@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and +depth must be the same as in `src[0]`. +@param ndsts number of matrices in `dst`. +@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is +a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in +dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to +src[0].channels()-1, the second input image channels are indexed from src[0].channels() to +src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image +channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is +filled with zero . +@param npairs number of index pairs in `fromTo`. +@sa split, merge, extractChannel, insertChannel, cvtColor +*/ +CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, + const int* fromTo, size_t npairs); + +/** @overload +@param src input array or vector of matrices; all of the matrices must have the same size and the +same depth. +@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and +depth must be the same as in src[0]. +@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is +a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in +dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to +src[0].channels()-1, the second input image channels are indexed from src[0].channels() to +src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image +channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is +filled with zero . +@param npairs number of index pairs in fromTo. +*/ +CV_EXPORTS void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst, + const int* fromTo, size_t npairs); + +/** @overload +@param src input array or vector of matrices; all of the matrices must have the same size and the +same depth. +@param dst output array or vector of matrices; all the matrices **must be allocated**; their size and +depth must be the same as in src[0]. +@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is +a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in +dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to +src[0].channels()-1, the second input image channels are indexed from src[0].channels() to +src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image +channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is +filled with zero . +*/ +CV_EXPORTS_W void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst, + const std::vector& fromTo); + +/** @brief Extracts a single channel from src (coi is 0-based index) +@param src input array +@param dst output array +@param coi index of channel to extract +@sa mixChannels, split +*/ +CV_EXPORTS_W void extractChannel(InputArray src, OutputArray dst, int coi); + +/** @brief Inserts a single channel to dst (coi is 0-based index) +@param src input array +@param dst output array +@param coi index of channel for insertion +@sa mixChannels, merge +*/ +CV_EXPORTS_W void insertChannel(InputArray src, InputOutputArray dst, int coi); + +/** @brief Flips a 2D array around vertical, horizontal, or both axes. + +The function cv::flip flips the array in one of three different ways (row +and column indices are 0-based): +\f[\texttt{dst} _{ij} = +\left\{ +\begin{array}{l l} +\texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\ +\texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\ +\texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\ +\end{array} +\right.\f] +The example scenarios of using the function are the following: +* Vertical flipping of the image (flipCode == 0) to switch between + top-left and bottom-left image origin. This is a typical operation + in video processing on Microsoft Windows\* OS. +* Horizontal flipping of the image with the subsequent horizontal + shift and absolute difference calculation to check for a + vertical-axis symmetry (flipCode \> 0). +* Simultaneous horizontal and vertical flipping of the image with + the subsequent shift and absolute difference calculation to check + for a central symmetry (flipCode \< 0). +* Reversing the order of point arrays (flipCode \> 0 or + flipCode == 0). +@param src input array. +@param dst output array of the same size and type as src. +@param flipCode a flag to specify how to flip the array; 0 means +flipping around the x-axis and positive value (for example, 1) means +flipping around y-axis. Negative value (for example, -1) means flipping +around both axes. +@sa transpose , repeat , completeSymm +*/ +CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode); + +enum RotateFlags { + ROTATE_90_CLOCKWISE = 0, //! A = (cv::Mat_(3, 2) << 1, 4, + 2, 5, + 3, 6); + cv::Mat_ B = (cv::Mat_(3, 2) << 7, 10, + 8, 11, + 9, 12); + + cv::Mat C; + cv::hconcat(A, B, C); + //C: + //[1, 4, 7, 10; + // 2, 5, 8, 11; + // 3, 6, 9, 12] + @endcode + @param src1 first input array to be considered for horizontal concatenation. + @param src2 second input array to be considered for horizontal concatenation. + @param dst output array. It has the same number of rows and depth as the src1 and src2, and the sum of cols of the src1 and src2. + */ +CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst); +/** @overload + @code{.cpp} + std::vector matrices = { cv::Mat(4, 1, CV_8UC1, cv::Scalar(1)), + cv::Mat(4, 1, CV_8UC1, cv::Scalar(2)), + cv::Mat(4, 1, CV_8UC1, cv::Scalar(3)),}; + + cv::Mat out; + cv::hconcat( matrices, out ); + //out: + //[1, 2, 3; + // 1, 2, 3; + // 1, 2, 3; + // 1, 2, 3] + @endcode + @param src input array or vector of matrices. all of the matrices must have the same number of rows and the same depth. + @param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src. +same depth. + */ +CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst); + +/** @brief Applies vertical concatenation to given matrices. + +The function vertically concatenates two or more cv::Mat matrices (with the same number of cols). +@code{.cpp} + cv::Mat matArray[] = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)), + cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)), + cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),}; + + cv::Mat out; + cv::vconcat( matArray, 3, out ); + //out: + //[1, 1, 1, 1; + // 2, 2, 2, 2; + // 3, 3, 3, 3] +@endcode +@param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth. +@param nsrc number of matrices in src. +@param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src. +@sa cv::hconcat(const Mat*, size_t, OutputArray), @sa cv::hconcat(InputArrayOfArrays, OutputArray) and @sa cv::hconcat(InputArray, InputArray, OutputArray) +*/ +CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst); +/** @overload + @code{.cpp} + cv::Mat_ A = (cv::Mat_(3, 2) << 1, 7, + 2, 8, + 3, 9); + cv::Mat_ B = (cv::Mat_(3, 2) << 4, 10, + 5, 11, + 6, 12); + + cv::Mat C; + cv::vconcat(A, B, C); + //C: + //[1, 7; + // 2, 8; + // 3, 9; + // 4, 10; + // 5, 11; + // 6, 12] + @endcode + @param src1 first input array to be considered for vertical concatenation. + @param src2 second input array to be considered for vertical concatenation. + @param dst output array. It has the same number of cols and depth as the src1 and src2, and the sum of rows of the src1 and src2. + */ +CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst); +/** @overload + @code{.cpp} + std::vector matrices = { cv::Mat(1, 4, CV_8UC1, cv::Scalar(1)), + cv::Mat(1, 4, CV_8UC1, cv::Scalar(2)), + cv::Mat(1, 4, CV_8UC1, cv::Scalar(3)),}; + + cv::Mat out; + cv::vconcat( matrices, out ); + //out: + //[1, 1, 1, 1; + // 2, 2, 2, 2; + // 3, 3, 3, 3] + @endcode + @param src input array or vector of matrices. all of the matrices must have the same number of cols and the same depth + @param dst output array. It has the same number of cols and depth as the src, and the sum of rows of the src. +same depth. + */ +CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst); + +/** @brief computes bitwise conjunction of the two arrays (dst = src1 & src2) +Calculates the per-element bit-wise conjunction of two arrays or an +array and a scalar. + +The function cv::bitwise_and calculates the per-element bit-wise logical conjunction for: +* Two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +* An array and a scalar when src2 is constructed from Scalar or has + the same number of elements as `src1.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0\f] +* A scalar and an array when src1 is constructed from Scalar or has + the same number of elements as `src2.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +In case of floating-point arrays, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel arrays, each channel is processed +independently. In the second and third cases above, the scalar is first +converted to the array type. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as the input +arrays. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ +CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2, + OutputArray dst, InputArray mask = noArray()); + +/** @brief Calculates the per-element bit-wise disjunction of two arrays or an +array and a scalar. + +The function cv::bitwise_or calculates the per-element bit-wise logical disjunction for: +* Two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +* An array and a scalar when src2 is constructed from Scalar or has + the same number of elements as `src1.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} \quad \texttt{if mask} (I) \ne0\f] +* A scalar and an array when src1 is constructed from Scalar or has + the same number of elements as `src2.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +In case of floating-point arrays, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel arrays, each channel is processed +independently. In the second and third cases above, the scalar is first +converted to the array type. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as the input +arrays. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ +CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2, + OutputArray dst, InputArray mask = noArray()); + +/** @brief Calculates the per-element bit-wise "exclusive or" operation on two +arrays or an array and a scalar. + +The function cv::bitwise_xor calculates the per-element bit-wise logical "exclusive-or" +operation for: +* Two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +* An array and a scalar when src2 is constructed from Scalar or has + the same number of elements as `src1.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} \quad \texttt{if mask} (I) \ne0\f] +* A scalar and an array when src1 is constructed from Scalar or has + the same number of elements as `src2.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +In case of floating-point arrays, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel arrays, each channel is processed +independently. In the 2nd and 3rd cases above, the scalar is first +converted to the array type. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as the input +arrays. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ +CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2, + OutputArray dst, InputArray mask = noArray()); + +/** @brief Inverts every bit of an array. + +The function cv::bitwise_not calculates per-element bit-wise inversion of the input +array: +\f[\texttt{dst} (I) = \neg \texttt{src} (I)\f] +In case of a floating-point input array, its machine-specific bit +representation (usually IEEE754-compliant) is used for the operation. In +case of multi-channel arrays, each channel is processed independently. +@param src input array. +@param dst output array that has the same size and type as the input +array. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ +CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst, + InputArray mask = noArray()); + +/** @brief Calculates the per-element absolute difference between two arrays or between an array and a scalar. + +The function cv::absdiff calculates: +* Absolute difference between two arrays when they have the same + size and type: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|)\f] +* Absolute difference between an array and a scalar when the second + array is constructed from Scalar or has as many elements as the + number of channels in `src1`: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2} |)\f] +* Absolute difference between a scalar and an array when the first + array is constructed from Scalar or has as many elements as the + number of channels in `src2`: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1} - \texttt{src2}(I) |)\f] + where I is a multi-dimensional index of array elements. In case of + multi-channel arrays, each channel is processed independently. +@note Saturation is not applied when the arrays have the depth CV_32S. +You may even get a negative value in the case of overflow. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as input arrays. +@sa cv::abs(const Mat&) +*/ +CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst); + +/** @brief This is an overloaded member function, provided for convenience (python) +Copies the matrix to another one. +When the operation mask is specified, if the Mat::create call shown above reallocates the matrix, the newly allocated matrix is initialized with all zeros before copying the data. +@param src source matrix. +@param dst Destination matrix. If it does not have a proper size or type before the operation, it is +reallocated. +@param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix +elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels. +*/ + +void CV_EXPORTS_W copyTo(InputArray src, OutputArray dst, InputArray mask); +/** @brief Checks if array elements lie between the elements of two other arrays. + +The function checks the range as follows: +- For every element of a single-channel input array: + \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0\f] +- For two-channel arrays: + \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 \land \texttt{lowerb} (I)_1 \leq \texttt{src} (I)_1 \leq \texttt{upperb} (I)_1\f] +- and so forth. + +That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the +specified 1D, 2D, 3D, ... box and 0 otherwise. + +When the lower and/or upper boundary parameters are scalars, the indexes +(I) at lowerb and upperb in the above formulas should be omitted. +@param src first input array. +@param lowerb inclusive lower boundary array or a scalar. +@param upperb inclusive upper boundary array or a scalar. +@param dst output array of the same size as src and CV_8U type. +*/ +CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb, + InputArray upperb, OutputArray dst); + +/** @brief Performs the per-element comparison of two arrays or an array and scalar value. + +The function compares: +* Elements of two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \,\texttt{cmpop}\, \texttt{src2} (I)\f] +* Elements of src1 with a scalar src2 when src2 is constructed from + Scalar or has a single element: + \f[\texttt{dst} (I) = \texttt{src1}(I) \,\texttt{cmpop}\, \texttt{src2}\f] +* src1 with elements of src2 when src1 is constructed from Scalar or + has a single element: + \f[\texttt{dst} (I) = \texttt{src1} \,\texttt{cmpop}\, \texttt{src2} (I)\f] +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: +@code{.cpp} + Mat dst1 = src1 >= src2; + Mat dst2 = src1 < 8; + ... +@endcode +@param src1 first input array or a scalar; when it is an array, it must have a single channel. +@param src2 second input array or a scalar; when it is an array, it must have a single channel. +@param dst output array of type ref CV_8U that has the same size and the same number of channels as + the input arrays. +@param cmpop a flag, that specifies correspondence between the arrays (cv::CmpTypes) +@sa checkRange, min, max, threshold +*/ +CV_EXPORTS_W void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop); + +/** @brief Calculates per-element minimum of two arrays or an array and a scalar. + +The function cv::min calculates the per-element minimum of two arrays: +\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I))\f] +or array and a scalar: +\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{value} )\f] +@param src1 first input array. +@param src2 second input array of the same size and type as src1. +@param dst output array of the same size and type as src1. +@sa max, compare, inRange, minMaxLoc +*/ +CV_EXPORTS_W void min(InputArray src1, InputArray src2, OutputArray dst); +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ +CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst); +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ +CV_EXPORTS void min(const UMat& src1, const UMat& src2, UMat& dst); + +/** @brief Calculates per-element maximum of two arrays or an array and a scalar. + +The function cv::max calculates the per-element maximum of two arrays: +\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I))\f] +or array and a scalar: +\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{value} )\f] +@param src1 first input array. +@param src2 second input array of the same size and type as src1 . +@param dst output array of the same size and type as src1. +@sa min, compare, inRange, minMaxLoc, @ref MatrixExpressions +*/ +CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst); +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ +CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst); +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ +CV_EXPORTS void max(const UMat& src1, const UMat& src2, UMat& dst); + +/** @brief Calculates a square root of array elements. + +The function cv::sqrt calculates a square root of each input array element. +In case of multi-channel arrays, each channel is processed +independently. The accuracy is approximately the same as of the built-in +std::sqrt . +@param src input floating-point array. +@param dst output array of the same size and type as src. +*/ +CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst); + +/** @brief Raises every array element to a power. + +The function cv::pow raises every element of the input array to power : +\f[\texttt{dst} (I) = \fork{\texttt{src}(I)^{power}}{if \(\texttt{power}\) is integer}{|\texttt{src}(I)|^{power}}{otherwise}\f] + +So, for a non-integer power exponent, the absolute values of input array +elements are used. However, it is possible to get true values for +negative values using some extra operations. In the example below, +computing the 5th root of array src shows: +@code{.cpp} + Mat mask = src < 0; + pow(src, 1./5, dst); + subtract(Scalar::all(0), dst, dst, mask); +@endcode +For some values of power, such as integer values, 0.5 and -0.5, +specialized faster algorithms are used. + +Special values (NaN, Inf) are not handled. +@param src input array. +@param power exponent of power. +@param dst output array of the same size and type as src. +@sa sqrt, exp, log, cartToPolar, polarToCart +*/ +CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst); + +/** @brief Calculates the exponent of every array element. + +The function cv::exp calculates the exponent of every element of the input +array: +\f[\texttt{dst} [I] = e^{ src(I) }\f] + +The maximum relative error is about 7e-6 for single-precision input and +less than 1e-10 for double-precision input. Currently, the function +converts denormalized values to zeros on output. Special values (NaN, +Inf) are not handled. +@param src input array. +@param dst output array of the same size and type as src. +@sa log , cartToPolar , polarToCart , phase , pow , sqrt , magnitude +*/ +CV_EXPORTS_W void exp(InputArray src, OutputArray dst); + +/** @brief Calculates the natural logarithm of every array element. + +The function cv::log calculates the natural logarithm of every element of the input array: +\f[\texttt{dst} (I) = \log (\texttt{src}(I)) \f] + +Output on zero, negative and special (NaN, Inf) values is undefined. + +@param src input array. +@param dst output array of the same size and type as src . +@sa exp, cartToPolar, polarToCart, phase, pow, sqrt, magnitude +*/ +CV_EXPORTS_W void log(InputArray src, OutputArray dst); + +/** @brief Calculates x and y coordinates of 2D vectors from their magnitude and angle. + +The function cv::polarToCart calculates the Cartesian coordinates of each 2D +vector represented by the corresponding elements of magnitude and angle: +\f[\begin{array}{l} \texttt{x} (I) = \texttt{magnitude} (I) \cos ( \texttt{angle} (I)) \\ \texttt{y} (I) = \texttt{magnitude} (I) \sin ( \texttt{angle} (I)) \\ \end{array}\f] + +The relative accuracy of the estimated coordinates is about 1e-6. +@param magnitude input floating-point array of magnitudes of 2D vectors; +it can be an empty matrix (=Mat()), in this case, the function assumes +that all the magnitudes are =1; if it is not empty, it must have the +same size and type as angle. +@param angle input floating-point array of angles of 2D vectors. +@param x output array of x-coordinates of 2D vectors; it has the same +size and type as angle. +@param y output array of y-coordinates of 2D vectors; it has the same +size and type as angle. +@param angleInDegrees when true, the input angles are measured in +degrees, otherwise, they are measured in radians. +@sa cartToPolar, magnitude, phase, exp, log, pow, sqrt +*/ +CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle, + OutputArray x, OutputArray y, bool angleInDegrees = false); + +/** @brief Calculates the magnitude and angle of 2D vectors. + +The function cv::cartToPolar calculates either the magnitude, angle, or both +for every 2D vector (x(I),y(I)): +\f[\begin{array}{l} \texttt{magnitude} (I)= \sqrt{\texttt{x}(I)^2+\texttt{y}(I)^2} , \\ \texttt{angle} (I)= \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))[ \cdot180 / \pi ] \end{array}\f] + +The angles are calculated with accuracy about 0.3 degrees. For the point +(0,0), the angle is set to 0. +@param x array of x-coordinates; this must be a single-precision or +double-precision floating-point array. +@param y array of y-coordinates, that must have the same size and same type as x. +@param magnitude output array of magnitudes of the same size and type as x. +@param angle output array of angles that has the same size and type as +x; the angles are measured in radians (from 0 to 2\*Pi) or in degrees (0 to 360 degrees). +@param angleInDegrees a flag, indicating whether the angles are measured +in radians (which is by default), or in degrees. +@sa Sobel, Scharr +*/ +CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y, + OutputArray magnitude, OutputArray angle, + bool angleInDegrees = false); + +/** @brief Calculates the rotation angle of 2D vectors. + +The function cv::phase calculates the rotation angle of each 2D vector that +is formed from the corresponding elements of x and y : +\f[\texttt{angle} (I) = \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))\f] + +The angle estimation accuracy is about 0.3 degrees. When x(I)=y(I)=0 , +the corresponding angle(I) is set to 0. +@param x input floating-point array of x-coordinates of 2D vectors. +@param y input array of y-coordinates of 2D vectors; it must have the +same size and the same type as x. +@param angle output array of vector angles; it has the same size and +same type as x . +@param angleInDegrees when true, the function calculates the angle in +degrees, otherwise, they are measured in radians. +*/ +CV_EXPORTS_W void phase(InputArray x, InputArray y, OutputArray angle, + bool angleInDegrees = false); + +/** @brief Calculates the magnitude of 2D vectors. + +The function cv::magnitude calculates the magnitude of 2D vectors formed +from the corresponding elements of x and y arrays: +\f[\texttt{dst} (I) = \sqrt{\texttt{x}(I)^2 + \texttt{y}(I)^2}\f] +@param x floating-point array of x-coordinates of the vectors. +@param y floating-point array of y-coordinates of the vectors; it must +have the same size as x. +@param magnitude output array of the same size and type as x. +@sa cartToPolar, polarToCart, phase, sqrt +*/ +CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude); + +/** @brief Checks every element of an input array for invalid values. + +The function cv::checkRange checks that every array element is neither NaN nor infinite. When minVal \> +-DBL_MAX and maxVal \< DBL_MAX, the function also checks that each value is between minVal and +maxVal. In case of multi-channel arrays, each channel is processed independently. If some values +are out of range, position of the first outlier is stored in pos (when pos != NULL). Then, the +function either returns false (when quiet=true) or throws an exception. +@param a input array. +@param quiet a flag, indicating whether the functions quietly return false when the array elements +are out of range or they throw an exception. +@param pos optional output parameter, when not NULL, must be a pointer to array of src.dims +elements. +@param minVal inclusive lower boundary of valid values range. +@param maxVal exclusive upper boundary of valid values range. +*/ +CV_EXPORTS_W bool checkRange(InputArray a, bool quiet = true, CV_OUT Point* pos = 0, + double minVal = -DBL_MAX, double maxVal = DBL_MAX); + +/** @brief converts NaN's to the given number +*/ +CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val = 0); + +/** @brief Performs generalized matrix multiplication. + +The function cv::gemm performs generalized matrix multiplication similar to the +gemm functions in BLAS level 3. For example, +`gemm(src1, src2, alpha, src3, beta, dst, GEMM_1_T + GEMM_3_T)` +corresponds to +\f[\texttt{dst} = \texttt{alpha} \cdot \texttt{src1} ^T \cdot \texttt{src2} + \texttt{beta} \cdot \texttt{src3} ^T\f] + +In case of complex (two-channel) data, performed a complex matrix +multiplication. + +The function can be replaced with a matrix expression. For example, the +above call can be replaced with: +@code{.cpp} + dst = alpha*src1.t()*src2 + beta*src3.t(); +@endcode +@param src1 first multiplied input matrix that could be real(CV_32FC1, +CV_64FC1) or complex(CV_32FC2, CV_64FC2). +@param src2 second multiplied input matrix of the same type as src1. +@param alpha weight of the matrix product. +@param src3 third optional delta matrix added to the matrix product; it +should have the same type as src1 and src2. +@param beta weight of src3. +@param dst output matrix; it has the proper size and the same type as +input matrices. +@param flags operation flags (cv::GemmFlags) +@sa mulTransposed , transform +*/ +CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha, + InputArray src3, double beta, OutputArray dst, int flags = 0); + +/** @brief Calculates the product of a matrix and its transposition. + +The function cv::mulTransposed calculates the product of src and its +transposition: +\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} )\f] +if aTa=true , and +\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T\f] +otherwise. The function is used to calculate the covariance matrix. With +zero delta, it can be used as a faster substitute for general matrix +product A\*B when B=A' +@param src input single-channel matrix. Note that unlike gemm, the +function can multiply not only floating-point matrices. +@param dst output square matrix. +@param aTa Flag specifying the multiplication ordering. See the +description below. +@param delta Optional delta matrix subtracted from src before the +multiplication. When the matrix is empty ( delta=noArray() ), it is +assumed to be zero, that is, nothing is subtracted. If it has the same +size as src , it is simply subtracted. Otherwise, it is "repeated" (see +repeat ) to cover the full src and then subtracted. Type of the delta +matrix, when it is not empty, must be the same as the type of created +output matrix. See the dtype parameter description below. +@param scale Optional scale factor for the matrix product. +@param dtype Optional type of the output matrix. When it is negative, +the output matrix will have the same type as src . Otherwise, it will be +type=CV_MAT_DEPTH(dtype) that should be either CV_32F or CV_64F . +@sa calcCovarMatrix, gemm, repeat, reduce +*/ +CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa, + InputArray delta = noArray(), + double scale = 1, int dtype = -1 ); + +/** @brief Transposes a matrix. + +The function cv::transpose transposes the matrix src : +\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f] +@note No complex conjugation is done in case of a complex matrix. It +should be done separately if needed. +@param src input array. +@param dst output array of the same type as src. +*/ +CV_EXPORTS_W void transpose(InputArray src, OutputArray dst); + +/** @brief Performs the matrix transformation of every array element. + +The function cv::transform performs the matrix transformation of every +element of the array src and stores the results in dst : +\f[\texttt{dst} (I) = \texttt{m} \cdot \texttt{src} (I)\f] +(when m.cols=src.channels() ), or +\f[\texttt{dst} (I) = \texttt{m} \cdot [ \texttt{src} (I); 1]\f] +(when m.cols=src.channels()+1 ) + +Every element of the N -channel array src is interpreted as N -element +vector that is transformed using the M x N or M x (N+1) matrix m to +M-element vector - the corresponding element of the output array dst . + +The function may be used for geometrical transformation of +N -dimensional points, arbitrary linear color space transformation (such +as various kinds of RGB to YUV transforms), shuffling the image +channels, and so forth. +@param src input array that must have as many channels (1 to 4) as +m.cols or m.cols-1. +@param dst output array of the same size and depth as src; it has as +many channels as m.rows. +@param m transformation 2x2 or 2x3 floating-point matrix. +@sa perspectiveTransform, getAffineTransform, estimateAffine2D, warpAffine, warpPerspective +*/ +CV_EXPORTS_W void transform(InputArray src, OutputArray dst, InputArray m ); + +/** @brief Performs the perspective matrix transformation of vectors. + +The function cv::perspectiveTransform transforms every element of src by +treating it as a 2D or 3D vector, in the following way: +\f[(x, y, z) \rightarrow (x'/w, y'/w, z'/w)\f] +where +\f[(x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix}\f] +and +\f[w = \fork{w'}{if \(w' \ne 0\)}{\infty}{otherwise}\f] + +Here a 3D vector transformation is shown. In case of a 2D vector +transformation, the z component is omitted. + +@note The function transforms a sparse set of 2D or 3D vectors. If you +want to transform an image using perspective transformation, use +warpPerspective . If you have an inverse problem, that is, you want to +compute the most probable perspective transformation out of several +pairs of corresponding points, you can use getPerspectiveTransform or +findHomography . +@param src input two-channel or three-channel floating-point array; each +element is a 2D/3D vector to be transformed. +@param dst output array of the same size and type as src. +@param m 3x3 or 4x4 floating-point transformation matrix. +@sa transform, warpPerspective, getPerspectiveTransform, findHomography +*/ +CV_EXPORTS_W void perspectiveTransform(InputArray src, OutputArray dst, InputArray m ); + +/** @brief Copies the lower or the upper half of a square matrix to its another half. + +The function cv::completeSymm copies the lower or the upper half of a square matrix to +its another half. The matrix diagonal remains unchanged: + - \f$\texttt{m}_{ij}=\texttt{m}_{ji}\f$ for \f$i > j\f$ if + lowerToUpper=false + - \f$\texttt{m}_{ij}=\texttt{m}_{ji}\f$ for \f$i < j\f$ if + lowerToUpper=true + +@param m input-output floating-point square matrix. +@param lowerToUpper operation flag; if true, the lower half is copied to +the upper half. Otherwise, the upper half is copied to the lower half. +@sa flip, transpose +*/ +CV_EXPORTS_W void completeSymm(InputOutputArray m, bool lowerToUpper = false); + +/** @brief Initializes a scaled identity matrix. + +The function cv::setIdentity initializes a scaled identity matrix: +\f[\texttt{mtx} (i,j)= \fork{\texttt{value}}{ if \(i=j\)}{0}{otherwise}\f] + +The function can also be emulated using the matrix initializers and the +matrix expressions: +@code + Mat A = Mat::eye(4, 3, CV_32F)*5; + // A will be set to [[5, 0, 0], [0, 5, 0], [0, 0, 5], [0, 0, 0]] +@endcode +@param mtx matrix to initialize (not necessarily square). +@param s value to assign to diagonal elements. +@sa Mat::zeros, Mat::ones, Mat::setTo, Mat::operator= +*/ +CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s = Scalar(1)); + +/** @brief Returns the determinant of a square floating-point matrix. + +The function cv::determinant calculates and returns the determinant of the +specified matrix. For small matrices ( mtx.cols=mtx.rows\<=3 ), the +direct method is used. For larger matrices, the function uses LU +factorization with partial pivoting. + +For symmetric positively-determined matrices, it is also possible to use +eigen decomposition to calculate the determinant. +@param mtx input matrix that must have CV_32FC1 or CV_64FC1 type and +square size. +@sa trace, invert, solve, eigen, @ref MatrixExpressions +*/ +CV_EXPORTS_W double determinant(InputArray mtx); + +/** @brief Returns the trace of a matrix. + +The function cv::trace returns the sum of the diagonal elements of the +matrix mtx . +\f[\mathrm{tr} ( \texttt{mtx} ) = \sum _i \texttt{mtx} (i,i)\f] +@param mtx input matrix. +*/ +CV_EXPORTS_W Scalar trace(InputArray mtx); + +/** @brief Finds the inverse or pseudo-inverse of a matrix. + +The function cv::invert inverts the matrix src and stores the result in dst +. When the matrix src is singular or non-square, the function calculates +the pseudo-inverse matrix (the dst matrix) so that norm(src\*dst - I) is +minimal, where I is an identity matrix. + +In case of the #DECOMP_LU method, the function returns non-zero value if +the inverse has been successfully calculated and 0 if src is singular. + +In case of the #DECOMP_SVD method, the function returns the inverse +condition number of src (the ratio of the smallest singular value to the +largest singular value) and 0 if src is singular. The SVD method +calculates a pseudo-inverse matrix if src is singular. + +Similarly to #DECOMP_LU, the method #DECOMP_CHOLESKY works only with +non-singular square matrices that should also be symmetrical and +positively defined. In this case, the function stores the inverted +matrix in dst and returns non-zero. Otherwise, it returns 0. + +@param src input floating-point M x N matrix. +@param dst output matrix of N x M size and the same type as src. +@param flags inversion method (cv::DecompTypes) +@sa solve, SVD +*/ +CV_EXPORTS_W double invert(InputArray src, OutputArray dst, int flags = DECOMP_LU); + +/** @brief Solves one or more linear systems or least-squares problems. + +The function cv::solve solves a linear system or least-squares problem (the +latter is possible with SVD or QR methods, or by specifying the flag +#DECOMP_NORMAL ): +\f[\texttt{dst} = \arg \min _X \| \texttt{src1} \cdot \texttt{X} - \texttt{src2} \|\f] + +If #DECOMP_LU or #DECOMP_CHOLESKY method is used, the function returns 1 +if src1 (or \f$\texttt{src1}^T\texttt{src1}\f$ ) is non-singular. Otherwise, +it returns 0. In the latter case, dst is not valid. Other methods find a +pseudo-solution in case of a singular left-hand side part. + +@note If you want to find a unity-norm solution of an under-defined +singular system \f$\texttt{src1}\cdot\texttt{dst}=0\f$ , the function solve +will not do the work. Use SVD::solveZ instead. + +@param src1 input matrix on the left-hand side of the system. +@param src2 input matrix on the right-hand side of the system. +@param dst output solution. +@param flags solution (matrix inversion) method (#DecompTypes) +@sa invert, SVD, eigen +*/ +CV_EXPORTS_W bool solve(InputArray src1, InputArray src2, + OutputArray dst, int flags = DECOMP_LU); + +/** @brief Sorts each row or each column of a matrix. + +The function cv::sort sorts each matrix row or each matrix column in +ascending or descending order. So you should pass two operation flags to +get desired behaviour. If you want to sort matrix rows or columns +lexicographically, you can use STL std::sort generic function with the +proper comparison predicate. + +@param src input single-channel array. +@param dst output array of the same size and type as src. +@param flags operation flags, a combination of #SortFlags +@sa sortIdx, randShuffle +*/ +CV_EXPORTS_W void sort(InputArray src, OutputArray dst, int flags); + +/** @brief Sorts each row or each column of a matrix. + +The function cv::sortIdx sorts each matrix row or each matrix column in the +ascending or descending order. So you should pass two operation flags to +get desired behaviour. Instead of reordering the elements themselves, it +stores the indices of sorted elements in the output array. For example: +@code + Mat A = Mat::eye(3,3,CV_32F), B; + sortIdx(A, B, SORT_EVERY_ROW + SORT_ASCENDING); + // B will probably contain + // (because of equal elements in A some permutations are possible): + // [[1, 2, 0], [0, 2, 1], [0, 1, 2]] +@endcode +@param src input single-channel array. +@param dst output integer array of the same size as src. +@param flags operation flags that could be a combination of cv::SortFlags +@sa sort, randShuffle +*/ +CV_EXPORTS_W void sortIdx(InputArray src, OutputArray dst, int flags); + +/** @brief Finds the real roots of a cubic equation. + +The function solveCubic finds the real roots of a cubic equation: +- if coeffs is a 4-element vector: +\f[\texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0\f] +- if coeffs is a 3-element vector: +\f[x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0\f] + +The roots are stored in the roots array. +@param coeffs equation coefficients, an array of 3 or 4 elements. +@param roots output array of real roots that has 1 or 3 elements. +@return number of real roots. It can be 0, 1 or 2. +*/ +CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots); + +/** @brief Finds the real or complex roots of a polynomial equation. + +The function cv::solvePoly finds real and complex roots of a polynomial equation: +\f[\texttt{coeffs} [n] x^{n} + \texttt{coeffs} [n-1] x^{n-1} + ... + \texttt{coeffs} [1] x + \texttt{coeffs} [0] = 0\f] +@param coeffs array of polynomial coefficients. +@param roots output (complex) array of roots. +@param maxIters maximum number of iterations the algorithm does. +*/ +CV_EXPORTS_W double solvePoly(InputArray coeffs, OutputArray roots, int maxIters = 300); + +/** @brief Calculates eigenvalues and eigenvectors of a symmetric matrix. + +The function cv::eigen calculates just eigenvalues, or eigenvalues and eigenvectors of the symmetric +matrix src: +@code + src*eigenvectors.row(i).t() = eigenvalues.at(i)*eigenvectors.row(i).t() +@endcode + +@note Use cv::eigenNonSymmetric for calculation of real eigenvalues and eigenvectors of non-symmetric matrix. + +@param src input matrix that must have CV_32FC1 or CV_64FC1 type, square size and be symmetrical +(src ^T^ == src). +@param eigenvalues output vector of eigenvalues of the same type as src; the eigenvalues are stored +in the descending order. +@param eigenvectors output matrix of eigenvectors; it has the same size and type as src; the +eigenvectors are stored as subsequent matrix rows, in the same order as the corresponding +eigenvalues. +@sa eigenNonSymmetric, completeSymm , PCA +*/ +CV_EXPORTS_W bool eigen(InputArray src, OutputArray eigenvalues, + OutputArray eigenvectors = noArray()); + +/** @brief Calculates eigenvalues and eigenvectors of a non-symmetric matrix (real eigenvalues only). + +@note Assumes real eigenvalues. + +The function calculates eigenvalues and eigenvectors (optional) of the square matrix src: +@code + src*eigenvectors.row(i).t() = eigenvalues.at(i)*eigenvectors.row(i).t() +@endcode + +@param src input matrix (CV_32FC1 or CV_64FC1 type). +@param eigenvalues output vector of eigenvalues (type is the same type as src). +@param eigenvectors output matrix of eigenvectors (type is the same type as src). The eigenvectors are stored as subsequent matrix rows, in the same order as the corresponding eigenvalues. +@sa eigen +*/ +CV_EXPORTS_W void eigenNonSymmetric(InputArray src, OutputArray eigenvalues, + OutputArray eigenvectors); + +/** @brief Calculates the covariance matrix of a set of vectors. + +The function cv::calcCovarMatrix calculates the covariance matrix and, optionally, the mean vector of +the set of input vectors. +@param samples samples stored as separate matrices +@param nsamples number of samples +@param covar output covariance matrix of the type ctype and square size. +@param mean input or output (depending on the flags) array as the average value of the input vectors. +@param flags operation flags as a combination of #CovarFlags +@param ctype type of the matrixl; it equals 'CV_64F' by default. +@sa PCA, mulTransposed, Mahalanobis +@todo InputArrayOfArrays +*/ +CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean, + int flags, int ctype = CV_64F); + +/** @overload +@note use #COVAR_ROWS or #COVAR_COLS flag +@param samples samples stored as rows/columns of a single matrix. +@param covar output covariance matrix of the type ctype and square size. +@param mean input or output (depending on the flags) array as the average value of the input vectors. +@param flags operation flags as a combination of #CovarFlags +@param ctype type of the matrixl; it equals 'CV_64F' by default. +*/ +CV_EXPORTS_W void calcCovarMatrix( InputArray samples, OutputArray covar, + InputOutputArray mean, int flags, int ctype = CV_64F); + +/** wrap PCA::operator() */ +CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean, + OutputArray eigenvectors, int maxComponents = 0); + +/** wrap PCA::operator() and add eigenvalues output parameter */ +CV_EXPORTS_AS(PCACompute2) void PCACompute(InputArray data, InputOutputArray mean, + OutputArray eigenvectors, OutputArray eigenvalues, + int maxComponents = 0); + +/** wrap PCA::operator() */ +CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean, + OutputArray eigenvectors, double retainedVariance); + +/** wrap PCA::operator() and add eigenvalues output parameter */ +CV_EXPORTS_AS(PCACompute2) void PCACompute(InputArray data, InputOutputArray mean, + OutputArray eigenvectors, OutputArray eigenvalues, + double retainedVariance); + +/** wrap PCA::project */ +CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean, + InputArray eigenvectors, OutputArray result); + +/** wrap PCA::backProject */ +CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean, + InputArray eigenvectors, OutputArray result); + +/** wrap SVD::compute */ +CV_EXPORTS_W void SVDecomp( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags = 0 ); + +/** wrap SVD::backSubst */ +CV_EXPORTS_W void SVBackSubst( InputArray w, InputArray u, InputArray vt, + InputArray rhs, OutputArray dst ); + +/** @brief Calculates the Mahalanobis distance between two vectors. + +The function cv::Mahalanobis calculates and returns the weighted distance between two vectors: +\f[d( \texttt{vec1} , \texttt{vec2} )= \sqrt{\sum_{i,j}{\texttt{icovar(i,j)}\cdot(\texttt{vec1}(I)-\texttt{vec2}(I))\cdot(\texttt{vec1(j)}-\texttt{vec2(j)})} }\f] +The covariance matrix may be calculated using the #calcCovarMatrix function and then inverted using +the invert function (preferably using the #DECOMP_SVD method, as the most accurate). +@param v1 first 1D input vector. +@param v2 second 1D input vector. +@param icovar inverse covariance matrix. +*/ +CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar); + +/** @brief Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array. + +The function cv::dft performs one of the following: +- Forward the Fourier transform of a 1D vector of N elements: + \f[Y = F^{(N)} \cdot X,\f] + where \f$F^{(N)}_{jk}=\exp(-2\pi i j k/N)\f$ and \f$i=\sqrt{-1}\f$ +- Inverse the Fourier transform of a 1D vector of N elements: + \f[\begin{array}{l} X'= \left (F^{(N)} \right )^{-1} \cdot Y = \left (F^{(N)} \right )^* \cdot y \\ X = (1/N) \cdot X, \end{array}\f] + where \f$F^*=\left(\textrm{Re}(F^{(N)})-\textrm{Im}(F^{(N)})\right)^T\f$ +- Forward the 2D Fourier transform of a M x N matrix: + \f[Y = F^{(M)} \cdot X \cdot F^{(N)}\f] +- Inverse the 2D Fourier transform of a M x N matrix: + \f[\begin{array}{l} X'= \left (F^{(M)} \right )^* \cdot Y \cdot \left (F^{(N)} \right )^* \\ X = \frac{1}{M \cdot N} \cdot X' \end{array}\f] + +In case of real (single-channel) data, the output spectrum of the forward Fourier transform or input +spectrum of the inverse Fourier transform can be represented in a packed format called *CCS* +(complex-conjugate-symmetrical). It was borrowed from IPL (Intel\* Image Processing Library). Here +is how 2D *CCS* spectrum looks: +\f[\begin{bmatrix} Re Y_{0,0} & Re Y_{0,1} & Im Y_{0,1} & Re Y_{0,2} & Im Y_{0,2} & \cdots & Re Y_{0,N/2-1} & Im Y_{0,N/2-1} & Re Y_{0,N/2} \\ Re Y_{1,0} & Re Y_{1,1} & Im Y_{1,1} & Re Y_{1,2} & Im Y_{1,2} & \cdots & Re Y_{1,N/2-1} & Im Y_{1,N/2-1} & Re Y_{1,N/2} \\ Im Y_{1,0} & Re Y_{2,1} & Im Y_{2,1} & Re Y_{2,2} & Im Y_{2,2} & \cdots & Re Y_{2,N/2-1} & Im Y_{2,N/2-1} & Im Y_{1,N/2} \\ \hdotsfor{9} \\ Re Y_{M/2-1,0} & Re Y_{M-3,1} & Im Y_{M-3,1} & \hdotsfor{3} & Re Y_{M-3,N/2-1} & Im Y_{M-3,N/2-1}& Re Y_{M/2-1,N/2} \\ Im Y_{M/2-1,0} & Re Y_{M-2,1} & Im Y_{M-2,1} & \hdotsfor{3} & Re Y_{M-2,N/2-1} & Im Y_{M-2,N/2-1}& Im Y_{M/2-1,N/2} \\ Re Y_{M/2,0} & Re Y_{M-1,1} & Im Y_{M-1,1} & \hdotsfor{3} & Re Y_{M-1,N/2-1} & Im Y_{M-1,N/2-1}& Re Y_{M/2,N/2} \end{bmatrix}\f] + +In case of 1D transform of a real vector, the output looks like the first row of the matrix above. + +So, the function chooses an operation mode depending on the flags and size of the input array: +- If #DFT_ROWS is set or the input array has a single row or single column, the function + performs a 1D forward or inverse transform of each row of a matrix when #DFT_ROWS is set. + Otherwise, it performs a 2D transform. +- If the input array is real and #DFT_INVERSE is not set, the function performs a forward 1D or + 2D transform: + - When #DFT_COMPLEX_OUTPUT is set, the output is a complex matrix of the same size as + input. + - When #DFT_COMPLEX_OUTPUT is not set, the output is a real matrix of the same size as + input. In case of 2D transform, it uses the packed format as shown above. In case of a + single 1D transform, it looks like the first row of the matrix above. In case of + multiple 1D transforms (when using the #DFT_ROWS flag), each row of the output matrix + looks like the first row of the matrix above. +- If the input array is complex and either #DFT_INVERSE or #DFT_REAL_OUTPUT are not set, the + output is a complex array of the same size as input. The function performs a forward or + inverse 1D or 2D transform of the whole input array or each row of the input array + independently, depending on the flags DFT_INVERSE and DFT_ROWS. +- When #DFT_INVERSE is set and the input array is real, or it is complex but #DFT_REAL_OUTPUT + is set, the output is a real array of the same size as input. The function performs a 1D or 2D + inverse transformation of the whole input array or each individual row, depending on the flags + #DFT_INVERSE and #DFT_ROWS. + +If #DFT_SCALE is set, the scaling is done after the transformation. + +Unlike dct , the function supports arrays of arbitrary size. But only those arrays are processed +efficiently, whose sizes can be factorized in a product of small prime numbers (2, 3, and 5 in the +current implementation). Such an efficient DFT size can be calculated using the getOptimalDFTSize +method. + +The sample below illustrates how to calculate a DFT-based convolution of two 2D real arrays: +@code + void convolveDFT(InputArray A, InputArray B, OutputArray C) + { + // reallocate the output array if needed + C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type()); + Size dftSize; + // calculate the size of DFT transform + dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1); + dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1); + + // allocate temporary buffers and initialize them with 0's + Mat tempA(dftSize, A.type(), Scalar::all(0)); + Mat tempB(dftSize, B.type(), Scalar::all(0)); + + // copy A and B to the top-left corners of tempA and tempB, respectively + Mat roiA(tempA, Rect(0,0,A.cols,A.rows)); + A.copyTo(roiA); + Mat roiB(tempB, Rect(0,0,B.cols,B.rows)); + B.copyTo(roiB); + + // now transform the padded A & B in-place; + // use "nonzeroRows" hint for faster processing + dft(tempA, tempA, 0, A.rows); + dft(tempB, tempB, 0, B.rows); + + // multiply the spectrums; + // the function handles packed spectrum representations well + mulSpectrums(tempA, tempB, tempA); + + // transform the product back from the frequency domain. + // Even though all the result rows will be non-zero, + // you need only the first C.rows of them, and thus you + // pass nonzeroRows == C.rows + dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows); + + // now copy the result back to C. + tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C); + + // all the temporary buffers will be deallocated automatically + } +@endcode +To optimize this sample, consider the following approaches: +- Since nonzeroRows != 0 is passed to the forward transform calls and since A and B are copied to + the top-left corners of tempA and tempB, respectively, it is not necessary to clear the whole + tempA and tempB. It is only necessary to clear the tempA.cols - A.cols ( tempB.cols - B.cols) + rightmost columns of the matrices. +- This DFT-based convolution does not have to be applied to the whole big arrays, especially if B + is significantly smaller than A or vice versa. Instead, you can calculate convolution by parts. + To do this, you need to split the output array C into multiple tiles. For each tile, estimate + which parts of A and B are required to calculate convolution in this tile. If the tiles in C are + too small, the speed will decrease a lot because of repeated work. In the ultimate case, when + each tile in C is a single pixel, the algorithm becomes equivalent to the naive convolution + algorithm. If the tiles are too big, the temporary arrays tempA and tempB become too big and + there is also a slowdown because of bad cache locality. So, there is an optimal tile size + somewhere in the middle. +- If different tiles in C can be calculated in parallel and, thus, the convolution is done by + parts, the loop can be threaded. + +All of the above improvements have been implemented in #matchTemplate and #filter2D . Therefore, by +using them, you can get the performance even better than with the above theoretically optimal +implementation. Though, those two functions actually calculate cross-correlation, not convolution, +so you need to "flip" the second convolution operand B vertically and horizontally using flip . +@note +- An example using the discrete fourier transform can be found at + opencv_source_code/samples/cpp/dft.cpp +- (Python) An example using the dft functionality to perform Wiener deconvolution can be found + at opencv_source/samples/python/deconvolution.py +- (Python) An example rearranging the quadrants of a Fourier image can be found at + opencv_source/samples/python/dft.py +@param src input array that could be real or complex. +@param dst output array whose size and type depends on the flags . +@param flags transformation flags, representing a combination of the #DftFlags +@param nonzeroRows when the parameter is not zero, the function assumes that only the first +nonzeroRows rows of the input array (#DFT_INVERSE is not set) or only the first nonzeroRows of the +output array (#DFT_INVERSE is set) contain non-zeros, thus, the function can handle the rest of the +rows more efficiently and save some time; this technique is very useful for calculating array +cross-correlation or convolution using DFT. +@sa dct , getOptimalDFTSize , mulSpectrums, filter2D , matchTemplate , flip , cartToPolar , +magnitude , phase +*/ +CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0); + +/** @brief Calculates the inverse Discrete Fourier Transform of a 1D or 2D array. + +idft(src, dst, flags) is equivalent to dft(src, dst, flags | #DFT_INVERSE) . +@note None of dft and idft scales the result by default. So, you should pass #DFT_SCALE to one of +dft or idft explicitly to make these transforms mutually inverse. +@sa dft, dct, idct, mulSpectrums, getOptimalDFTSize +@param src input floating-point real or complex array. +@param dst output array whose size and type depend on the flags. +@param flags operation flags (see dft and #DftFlags). +@param nonzeroRows number of dst rows to process; the rest of the rows have undefined content (see +the convolution sample in dft description. +*/ +CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0); + +/** @brief Performs a forward or inverse discrete Cosine transform of 1D or 2D array. + +The function cv::dct performs a forward or inverse discrete Cosine transform (DCT) of a 1D or 2D +floating-point array: +- Forward Cosine transform of a 1D vector of N elements: + \f[Y = C^{(N)} \cdot X\f] + where + \f[C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right )\f] + and + \f$\alpha_0=1\f$, \f$\alpha_j=2\f$ for *j \> 0*. +- Inverse Cosine transform of a 1D vector of N elements: + \f[X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y\f] + (since \f$C^{(N)}\f$ is an orthogonal matrix, \f$C^{(N)} \cdot \left(C^{(N)}\right)^T = I\f$ ) +- Forward 2D Cosine transform of M x N matrix: + \f[Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T\f] +- Inverse 2D Cosine transform of M x N matrix: + \f[X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)}\f] + +The function chooses the mode of operation by looking at the flags and size of the input array: +- If (flags & #DCT_INVERSE) == 0 , the function does a forward 1D or 2D transform. Otherwise, it + is an inverse 1D or 2D transform. +- If (flags & #DCT_ROWS) != 0 , the function performs a 1D transform of each row. +- If the array is a single column or a single row, the function performs a 1D transform. +- If none of the above is true, the function performs a 2D transform. + +@note Currently dct supports even-size arrays (2, 4, 6 ...). For data analysis and approximation, you +can pad the array when necessary. +Also, the function performance depends very much, and not monotonically, on the array size (see +getOptimalDFTSize ). In the current implementation DCT of a vector of size N is calculated via DFT +of a vector of size N/2 . Thus, the optimal DCT size N1 \>= N can be calculated as: +@code + size_t getOptimalDCTSize(size_t N) { return 2*getOptimalDFTSize((N+1)/2); } + N1 = getOptimalDCTSize(N); +@endcode +@param src input floating-point array. +@param dst output array of the same size and type as src . +@param flags transformation flags as a combination of cv::DftFlags (DCT_*) +@sa dft , getOptimalDFTSize , idct +*/ +CV_EXPORTS_W void dct(InputArray src, OutputArray dst, int flags = 0); + +/** @brief Calculates the inverse Discrete Cosine Transform of a 1D or 2D array. + +idct(src, dst, flags) is equivalent to dct(src, dst, flags | DCT_INVERSE). +@param src input floating-point single-channel array. +@param dst output array of the same size and type as src. +@param flags operation flags. +@sa dct, dft, idft, getOptimalDFTSize +*/ +CV_EXPORTS_W void idct(InputArray src, OutputArray dst, int flags = 0); + +/** @brief Performs the per-element multiplication of two Fourier spectrums. + +The function cv::mulSpectrums performs the per-element multiplication of the two CCS-packed or complex +matrices that are results of a real or complex Fourier transform. + +The function, together with dft and idft , may be used to calculate convolution (pass conjB=false ) +or correlation (pass conjB=true ) of two arrays rapidly. When the arrays are complex, they are +simply multiplied (per element) with an optional conjugation of the second-array elements. When the +arrays are real, they are assumed to be CCS-packed (see dft for details). +@param a first input array. +@param b second input array of the same size and type as src1 . +@param c output array of the same size and type as src1 . +@param flags operation flags; currently, the only supported flag is cv::DFT_ROWS, which indicates that +each row of src1 and src2 is an independent 1D Fourier spectrum. If you do not want to use this flag, then simply add a `0` as value. +@param conjB optional flag that conjugates the second input array before the multiplication (true) +or not (false). +*/ +CV_EXPORTS_W void mulSpectrums(InputArray a, InputArray b, OutputArray c, + int flags, bool conjB = false); + +/** @brief Returns the optimal DFT size for a given vector size. + +DFT performance is not a monotonic function of a vector size. Therefore, when you calculate +convolution of two arrays or perform the spectral analysis of an array, it usually makes sense to +pad the input data with zeros to get a bit larger array that can be transformed much faster than the +original one. Arrays whose size is a power-of-two (2, 4, 8, 16, 32, ...) are the fastest to process. +Though, the arrays whose size is a product of 2's, 3's, and 5's (for example, 300 = 5\*5\*3\*2\*2) +are also processed quite efficiently. + +The function cv::getOptimalDFTSize returns the minimum number N that is greater than or equal to vecsize +so that the DFT of a vector of size N can be processed efficiently. In the current implementation N += 2 ^p^ \* 3 ^q^ \* 5 ^r^ for some integer p, q, r. + +The function returns a negative number if vecsize is too large (very close to INT_MAX ). + +While the function cannot be used directly to estimate the optimal vector size for DCT transform +(since the current DCT implementation supports only even-size vectors), it can be easily processed +as getOptimalDFTSize((vecsize+1)/2)\*2. +@param vecsize vector size. +@sa dft , dct , idft , idct , mulSpectrums +*/ +CV_EXPORTS_W int getOptimalDFTSize(int vecsize); + +/** @brief Returns the default random number generator. + +The function cv::theRNG returns the default random number generator. For each thread, there is a +separate random number generator, so you can use the function safely in multi-thread environments. +If you just need to get a single random number using this generator or initialize an array, you can +use randu or randn instead. But if you are going to generate many random numbers inside a loop, it +is much faster to use this function to retrieve the generator and then use RNG::operator _Tp() . +@sa RNG, randu, randn +*/ +CV_EXPORTS RNG& theRNG(); + +/** @brief Sets state of default random number generator. + +The function cv::setRNGSeed sets state of default random number generator to custom value. +@param seed new state for default random number generator +@sa RNG, randu, randn +*/ +CV_EXPORTS_W void setRNGSeed(int seed); + +/** @brief Generates a single uniformly-distributed random number or an array of random numbers. + +Non-template variant of the function fills the matrix dst with uniformly-distributed +random numbers from the specified range: +\f[\texttt{low} _c \leq \texttt{dst} (I)_c < \texttt{high} _c\f] +@param dst output array of random numbers; the array must be pre-allocated. +@param low inclusive lower boundary of the generated random numbers. +@param high exclusive upper boundary of the generated random numbers. +@sa RNG, randn, theRNG +*/ +CV_EXPORTS_W void randu(InputOutputArray dst, InputArray low, InputArray high); + +/** @brief Fills the array with normally distributed random numbers. + +The function cv::randn fills the matrix dst with normally distributed random numbers with the specified +mean vector and the standard deviation matrix. The generated random numbers are clipped to fit the +value range of the output array data type. +@param dst output array of random numbers; the array must be pre-allocated and have 1 to 4 channels. +@param mean mean value (expectation) of the generated random numbers. +@param stddev standard deviation of the generated random numbers; it can be either a vector (in +which case a diagonal standard deviation matrix is assumed) or a square matrix. +@sa RNG, randu +*/ +CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev); + +/** @brief Shuffles the array elements randomly. + +The function cv::randShuffle shuffles the specified 1D array by randomly choosing pairs of elements and +swapping them. The number of such swap operations will be dst.rows\*dst.cols\*iterFactor . +@param dst input/output numerical 1D array. +@param iterFactor scale factor that determines the number of random swap operations (see the details +below). +@param rng optional random number generator used for shuffling; if it is zero, theRNG () is used +instead. +@sa RNG, sort +*/ +CV_EXPORTS_W void randShuffle(InputOutputArray dst, double iterFactor = 1., RNG* rng = 0); + +/** @brief Principal Component Analysis + +The class is used to calculate a special basis for a set of vectors. The +basis will consist of eigenvectors of the covariance matrix calculated +from the input set of vectors. The class %PCA can also transform +vectors to/from the new coordinate space defined by the basis. Usually, +in this new coordinate system, each vector from the original set (and +any linear combination of such vectors) can be quite accurately +approximated by taking its first few components, corresponding to the +eigenvectors of the largest eigenvalues of the covariance matrix. +Geometrically it means that you calculate a projection of the vector to +a subspace formed by a few eigenvectors corresponding to the dominant +eigenvalues of the covariance matrix. And usually such a projection is +very close to the original vector. So, you can represent the original +vector from a high-dimensional space with a much shorter vector +consisting of the projected vector's coordinates in the subspace. Such a +transformation is also known as Karhunen-Loeve Transform, or KLT. +See http://en.wikipedia.org/wiki/Principal_component_analysis + +The sample below is the function that takes two matrices. The first +function stores a set of vectors (a row per vector) that is used to +calculate PCA. The second function stores another "test" set of vectors +(a row per vector). First, these vectors are compressed with PCA, then +reconstructed back, and then the reconstruction error norm is computed +and printed for each vector. : + +@code{.cpp} +using namespace cv; + +PCA compressPCA(const Mat& pcaset, int maxComponents, + const Mat& testset, Mat& compressed) +{ + PCA pca(pcaset, // pass the data + Mat(), // we do not have a pre-computed mean vector, + // so let the PCA engine to compute it + PCA::DATA_AS_ROW, // indicate that the vectors + // are stored as matrix rows + // (use PCA::DATA_AS_COL if the vectors are + // the matrix columns) + maxComponents // specify, how many principal components to retain + ); + // if there is no test data, just return the computed basis, ready-to-use + if( !testset.data ) + return pca; + CV_Assert( testset.cols == pcaset.cols ); + + compressed.create(testset.rows, maxComponents, testset.type()); + + Mat reconstructed; + for( int i = 0; i < testset.rows; i++ ) + { + Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed; + // compress the vector, the result will be stored + // in the i-th row of the output matrix + pca.project(vec, coeffs); + // and then reconstruct it + pca.backProject(coeffs, reconstructed); + // and measure the error + printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2)); + } + return pca; +} +@endcode +@sa calcCovarMatrix, mulTransposed, SVD, dft, dct +*/ +class CV_EXPORTS PCA +{ +public: + enum Flags { DATA_AS_ROW = 0, //!< indicates that the input samples are stored as matrix rows + DATA_AS_COL = 1, //!< indicates that the input samples are stored as matrix columns + USE_AVG = 2 //! + }; + + /** @brief default constructor + + The default constructor initializes an empty %PCA structure. The other + constructors initialize the structure and call PCA::operator()(). + */ + PCA(); + + /** @overload + @param data input samples stored as matrix rows or matrix columns. + @param mean optional mean value; if the matrix is empty (@c noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout (PCA::Flags) + @param maxComponents maximum number of components that %PCA should + retain; by default, all the components are retained. + */ + PCA(InputArray data, InputArray mean, int flags, int maxComponents = 0); + + /** @overload + @param data input samples stored as matrix rows or matrix columns. + @param mean optional mean value; if the matrix is empty (noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout (PCA::Flags) + @param retainedVariance Percentage of variance that PCA should retain. + Using this parameter will let the PCA decided how many components to + retain but it will always keep at least 2. + */ + PCA(InputArray data, InputArray mean, int flags, double retainedVariance); + + /** @brief performs %PCA + + The operator performs %PCA of the supplied dataset. It is safe to reuse + the same PCA structure for multiple datasets. That is, if the structure + has been previously used with another dataset, the existing internal + data is reclaimed and the new @ref eigenvalues, @ref eigenvectors and @ref + mean are allocated and computed. + + The computed @ref eigenvalues are sorted from the largest to the smallest and + the corresponding @ref eigenvectors are stored as eigenvectors rows. + + @param data input samples stored as the matrix rows or as the matrix + columns. + @param mean optional mean value; if the matrix is empty (noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout. (Flags) + @param maxComponents maximum number of components that PCA should + retain; by default, all the components are retained. + */ + PCA& operator()(InputArray data, InputArray mean, int flags, int maxComponents = 0); + + /** @overload + @param data input samples stored as the matrix rows or as the matrix + columns. + @param mean optional mean value; if the matrix is empty (noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout. (PCA::Flags) + @param retainedVariance Percentage of variance that %PCA should retain. + Using this parameter will let the %PCA decided how many components to + retain but it will always keep at least 2. + */ + PCA& operator()(InputArray data, InputArray mean, int flags, double retainedVariance); + + /** @brief Projects vector(s) to the principal component subspace. + + The methods project one or more vectors to the principal component + subspace, where each vector projection is represented by coefficients in + the principal component basis. The first form of the method returns the + matrix that the second form writes to the result. So the first form can + be used as a part of expression while the second form can be more + efficient in a processing loop. + @param vec input vector(s); must have the same dimensionality and the + same layout as the input data used at %PCA phase, that is, if + DATA_AS_ROW are specified, then `vec.cols==data.cols` + (vector dimensionality) and `vec.rows` is the number of vectors to + project, and the same is true for the PCA::DATA_AS_COL case. + */ + Mat project(InputArray vec) const; + + /** @overload + @param vec input vector(s); must have the same dimensionality and the + same layout as the input data used at PCA phase, that is, if + DATA_AS_ROW are specified, then `vec.cols==data.cols` + (vector dimensionality) and `vec.rows` is the number of vectors to + project, and the same is true for the PCA::DATA_AS_COL case. + @param result output vectors; in case of PCA::DATA_AS_COL, the + output matrix has as many columns as the number of input vectors, this + means that `result.cols==vec.cols` and the number of rows match the + number of principal components (for example, `maxComponents` parameter + passed to the constructor). + */ + void project(InputArray vec, OutputArray result) const; + + /** @brief Reconstructs vectors from their PC projections. + + The methods are inverse operations to PCA::project. They take PC + coordinates of projected vectors and reconstruct the original vectors. + Unless all the principal components have been retained, the + reconstructed vectors are different from the originals. But typically, + the difference is small if the number of components is large enough (but + still much smaller than the original vector dimensionality). As a + result, PCA is used. + @param vec coordinates of the vectors in the principal component + subspace, the layout and size are the same as of PCA::project output + vectors. + */ + Mat backProject(InputArray vec) const; + + /** @overload + @param vec coordinates of the vectors in the principal component + subspace, the layout and size are the same as of PCA::project output + vectors. + @param result reconstructed vectors; the layout and size are the same as + of PCA::project input vectors. + */ + void backProject(InputArray vec, OutputArray result) const; + + /** @brief write PCA objects + + Writes @ref eigenvalues @ref eigenvectors and @ref mean to specified FileStorage + */ + void write(FileStorage& fs) const; + + /** @brief load PCA objects + + Loads @ref eigenvalues @ref eigenvectors and @ref mean from specified FileNode + */ + void read(const FileNode& fn); + + Mat eigenvectors; //!< eigenvectors of the covariation matrix + Mat eigenvalues; //!< eigenvalues of the covariation matrix + Mat mean; //!< mean value subtracted before the projection and added after the back projection +}; + +/** @example samples/cpp/pca.cpp +An example using %PCA for dimensionality reduction while maintaining an amount of variance +*/ + +/** @example samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp +Check @ref tutorial_introduction_to_pca "the corresponding tutorial" for more details +*/ + +/** +@brief Linear Discriminant Analysis +@todo document this class +*/ +class CV_EXPORTS LDA +{ +public: + /** @brief constructor + Initializes a LDA with num_components (default 0). + */ + explicit LDA(int num_components = 0); + + /** Initializes and performs a Discriminant Analysis with Fisher's + Optimization Criterion on given data in src and corresponding labels + in labels. If 0 (or less) number of components are given, they are + automatically determined for given data in computation. + */ + LDA(InputArrayOfArrays src, InputArray labels, int num_components = 0); + + /** Serializes this object to a given filename. + */ + void save(const String& filename) const; + + /** Deserializes this object from a given filename. + */ + void load(const String& filename); + + /** Serializes this object to a given cv::FileStorage. + */ + void save(FileStorage& fs) const; + + /** Deserializes this object from a given cv::FileStorage. + */ + void load(const FileStorage& node); + + /** destructor + */ + ~LDA(); + + /** Compute the discriminants for data in src (row aligned) and labels. + */ + void compute(InputArrayOfArrays src, InputArray labels); + + /** Projects samples into the LDA subspace. + src may be one or more row aligned samples. + */ + Mat project(InputArray src); + + /** Reconstructs projections from the LDA subspace. + src may be one or more row aligned projections. + */ + Mat reconstruct(InputArray src); + + /** Returns the eigenvectors of this LDA. + */ + Mat eigenvectors() const { return _eigenvectors; } + + /** Returns the eigenvalues of this LDA. + */ + Mat eigenvalues() const { return _eigenvalues; } + + static Mat subspaceProject(InputArray W, InputArray mean, InputArray src); + static Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src); + +protected: + int _num_components; + Mat _eigenvectors; + Mat _eigenvalues; + void lda(InputArrayOfArrays src, InputArray labels); +}; + +/** @brief Singular Value Decomposition + +Class for computing Singular Value Decomposition of a floating-point +matrix. The Singular Value Decomposition is used to solve least-square +problems, under-determined linear systems, invert matrices, compute +condition numbers, and so on. + +If you want to compute a condition number of a matrix or an absolute value of +its determinant, you do not need `u` and `vt`. You can pass +flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that full-size u +and vt must be computed, which is not necessary most of the time. + +@sa invert, solve, eigen, determinant +*/ +class CV_EXPORTS SVD +{ +public: + enum Flags { + /** allow the algorithm to modify the decomposed matrix; it can save space and speed up + processing. currently ignored. */ + MODIFY_A = 1, + /** indicates that only a vector of singular values `w` is to be processed, while u and vt + will be set to empty matrices */ + NO_UV = 2, + /** when the matrix is not square, by default the algorithm produces u and vt matrices of + sufficiently large size for the further A reconstruction; if, however, FULL_UV flag is + specified, u and vt will be full-size square orthogonal matrices.*/ + FULL_UV = 4 + }; + + /** @brief the default constructor + + initializes an empty SVD structure + */ + SVD(); + + /** @overload + initializes an empty SVD structure and then calls SVD::operator() + @param src decomposed matrix. The depth has to be CV_32F or CV_64F. + @param flags operation flags (SVD::Flags) + */ + SVD( InputArray src, int flags = 0 ); + + /** @brief the operator that performs SVD. The previously allocated u, w and vt are released. + + The operator performs the singular value decomposition of the supplied + matrix. The u,`vt` , and the vector of singular values w are stored in + the structure. The same SVD structure can be reused many times with + different matrices. Each time, if needed, the previous u,`vt` , and w + are reclaimed and the new matrices are created, which is all handled by + Mat::create. + @param src decomposed matrix. The depth has to be CV_32F or CV_64F. + @param flags operation flags (SVD::Flags) + */ + SVD& operator ()( InputArray src, int flags = 0 ); + + /** @brief decomposes matrix and stores the results to user-provided matrices + + The methods/functions perform SVD of matrix. Unlike SVD::SVD constructor + and SVD::operator(), they store the results to the user-provided + matrices: + + @code{.cpp} + Mat A, w, u, vt; + SVD::compute(A, w, u, vt); + @endcode + + @param src decomposed matrix. The depth has to be CV_32F or CV_64F. + @param w calculated singular values + @param u calculated left singular vectors + @param vt transposed matrix of right singular vectors + @param flags operation flags - see SVD::Flags. + */ + static void compute( InputArray src, OutputArray w, + OutputArray u, OutputArray vt, int flags = 0 ); + + /** @overload + computes singular values of a matrix + @param src decomposed matrix. The depth has to be CV_32F or CV_64F. + @param w calculated singular values + @param flags operation flags - see SVD::Flags. + */ + static void compute( InputArray src, OutputArray w, int flags = 0 ); + + /** @brief performs back substitution + */ + static void backSubst( InputArray w, InputArray u, + InputArray vt, InputArray rhs, + OutputArray dst ); + + /** @brief solves an under-determined singular linear system + + The method finds a unit-length solution x of a singular linear system + A\*x = 0. Depending on the rank of A, there can be no solutions, a + single solution or an infinite number of solutions. In general, the + algorithm solves the following problem: + \f[dst = \arg \min _{x: \| x \| =1} \| src \cdot x \|\f] + @param src left-hand-side matrix. + @param dst found solution. + */ + static void solveZ( InputArray src, OutputArray dst ); + + /** @brief performs a singular value back substitution. + + The method calculates a back substitution for the specified right-hand + side: + + \f[\texttt{x} = \texttt{vt} ^T \cdot diag( \texttt{w} )^{-1} \cdot \texttt{u} ^T \cdot \texttt{rhs} \sim \texttt{A} ^{-1} \cdot \texttt{rhs}\f] + + Using this technique you can either get a very accurate solution of the + convenient linear system, or the best (in the least-squares terms) + pseudo-solution of an overdetermined linear system. + + @param rhs right-hand side of a linear system (u\*w\*v')\*dst = rhs to + be solved, where A has been previously decomposed. + + @param dst found solution of the system. + + @note Explicit SVD with the further back substitution only makes sense + if you need to solve many linear systems with the same left-hand side + (for example, src ). If all you need is to solve a single system + (possibly with multiple rhs immediately available), simply call solve + add pass #DECOMP_SVD there. It does absolutely the same thing. + */ + void backSubst( InputArray rhs, OutputArray dst ) const; + + /** @todo document */ + template static + void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt ); + + /** @todo document */ + template static + void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w ); + + /** @todo document */ + template static + void backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst ); + + Mat u, w, vt; +}; + +/** @brief Random Number Generator + +Random number generator. It encapsulates the state (currently, a 64-bit +integer) and has methods to return scalar random values and to fill +arrays with random values. Currently it supports uniform and Gaussian +(normal) distributions. The generator uses Multiply-With-Carry +algorithm, introduced by G. Marsaglia ( + ). +Gaussian-distribution random numbers are generated using the Ziggurat +algorithm ( ), +introduced by G. Marsaglia and W. W. Tsang. +*/ +class CV_EXPORTS RNG +{ +public: + enum { UNIFORM = 0, + NORMAL = 1 + }; + + /** @brief constructor + + These are the RNG constructors. The first form sets the state to some + pre-defined value, equal to 2\*\*32-1 in the current implementation. The + second form sets the state to the specified value. If you passed state=0 + , the constructor uses the above default value instead to avoid the + singular random number sequence, consisting of all zeros. + */ + RNG(); + /** @overload + @param state 64-bit value used to initialize the RNG. + */ + RNG(uint64 state); + /**The method updates the state using the MWC algorithm and returns the + next 32-bit random number.*/ + unsigned next(); + + /**Each of the methods updates the state using the MWC algorithm and + returns the next random number of the specified type. In case of integer + types, the returned number is from the available value range for the + specified type. In case of floating-point types, the returned value is + from [0,1) range. + */ + operator uchar(); + /** @overload */ + operator schar(); + /** @overload */ + operator ushort(); + /** @overload */ + operator short(); + /** @overload */ + operator unsigned(); + /** @overload */ + operator int(); + /** @overload */ + operator float(); + /** @overload */ + operator double(); + + /** @brief returns a random integer sampled uniformly from [0, N). + + The methods transform the state using the MWC algorithm and return the + next random number. The first form is equivalent to RNG::next . The + second form returns the random number modulo N , which means that the + result is in the range [0, N) . + */ + unsigned operator ()(); + /** @overload + @param N upper non-inclusive boundary of the returned random number. + */ + unsigned operator ()(unsigned N); + + /** @brief returns uniformly distributed integer random number from [a,b) range + + The methods transform the state using the MWC algorithm and return the + next uniformly-distributed random number of the specified type, deduced + from the input parameter type, from the range [a, b) . There is a nuance + illustrated by the following sample: + + @code{.cpp} + RNG rng; + + // always produces 0 + double a = rng.uniform(0, 1); + + // produces double from [0, 1) + double a1 = rng.uniform((double)0, (double)1); + + // produces float from [0, 1) + float b = rng.uniform(0.f, 1.f); + + // produces double from [0, 1) + double c = rng.uniform(0., 1.); + + // may cause compiler error because of ambiguity: + // RNG::uniform(0, (int)0.999999)? or RNG::uniform((double)0, 0.99999)? + double d = rng.uniform(0, 0.999999); + @endcode + + The compiler does not take into account the type of the variable to + which you assign the result of RNG::uniform . The only thing that + matters to the compiler is the type of a and b parameters. So, if you + want a floating-point random number, but the range boundaries are + integer numbers, either put dots in the end, if they are constants, or + use explicit type cast operators, as in the a1 initialization above. + @param a lower inclusive boundary of the returned random number. + @param b upper non-inclusive boundary of the returned random number. + */ + int uniform(int a, int b); + /** @overload */ + float uniform(float a, float b); + /** @overload */ + double uniform(double a, double b); + + /** @brief Fills arrays with random numbers. + + @param mat 2D or N-dimensional matrix; currently matrices with more than + 4 channels are not supported by the methods, use Mat::reshape as a + possible workaround. + @param distType distribution type, RNG::UNIFORM or RNG::NORMAL. + @param a first distribution parameter; in case of the uniform + distribution, this is an inclusive lower boundary, in case of the normal + distribution, this is a mean value. + @param b second distribution parameter; in case of the uniform + distribution, this is a non-inclusive upper boundary, in case of the + normal distribution, this is a standard deviation (diagonal of the + standard deviation matrix or the full standard deviation matrix). + @param saturateRange pre-saturation flag; for uniform distribution only; + if true, the method will first convert a and b to the acceptable value + range (according to the mat datatype) and then will generate uniformly + distributed random numbers within the range [saturate(a), saturate(b)), + if saturateRange=false, the method will generate uniformly distributed + random numbers in the original range [a, b) and then will saturate them, + it means, for example, that + theRNG().fill(mat_8u, RNG::UNIFORM, -DBL_MAX, DBL_MAX) will likely + produce array mostly filled with 0's and 255's, since the range (0, 255) + is significantly smaller than [-DBL_MAX, DBL_MAX). + + Each of the methods fills the matrix with the random values from the + specified distribution. As the new numbers are generated, the RNG state + is updated accordingly. In case of multiple-channel images, every + channel is filled independently, which means that RNG cannot generate + samples from the multi-dimensional Gaussian distribution with + non-diagonal covariance matrix directly. To do that, the method + generates samples from multi-dimensional standard Gaussian distribution + with zero mean and identity covariation matrix, and then transforms them + using transform to get samples from the specified Gaussian distribution. + */ + void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange = false ); + + /** @brief Returns the next random number sampled from the Gaussian distribution + @param sigma standard deviation of the distribution. + + The method transforms the state using the MWC algorithm and returns the + next random number from the Gaussian distribution N(0,sigma) . That is, + the mean value of the returned random numbers is zero and the standard + deviation is the specified sigma . + */ + double gaussian(double sigma); + + uint64 state; + + bool operator ==(const RNG& other) const; +}; + +/** @brief Mersenne Twister random number generator + +Inspired by http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c +@todo document +*/ +class CV_EXPORTS RNG_MT19937 +{ +public: + RNG_MT19937(); + RNG_MT19937(unsigned s); + void seed(unsigned s); + + unsigned next(); + + operator int(); + operator unsigned(); + operator float(); + operator double(); + + unsigned operator ()(unsigned N); + unsigned operator ()(); + + /** @brief returns uniformly distributed integer random number from [a,b) range*/ + int uniform(int a, int b); + /** @brief returns uniformly distributed floating-point random number from [a,b) range*/ + float uniform(float a, float b); + /** @brief returns uniformly distributed double-precision floating-point random number from [a,b) range*/ + double uniform(double a, double b); + +private: + enum PeriodParameters {N = 624, M = 397}; + unsigned state[N]; + int mti; +}; + +//! @} core_array + +//! @addtogroup core_cluster +//! @{ + +/** @example samples/cpp/kmeans.cpp +An example on K-means clustering +*/ + +/** @brief Finds centers of clusters and groups input samples around the clusters. + +The function kmeans implements a k-means algorithm that finds the centers of cluster_count clusters +and groups the input samples around the clusters. As an output, \f$\texttt{bestLabels}_i\f$ contains a +0-based cluster index for the sample stored in the \f$i^{th}\f$ row of the samples matrix. + +@note +- (Python) An example on K-means clustering can be found at + opencv_source_code/samples/python/kmeans.py +@param data Data for clustering. An array of N-Dimensional points with float coordinates is needed. +Examples of this array can be: +- Mat points(count, 2, CV_32F); +- Mat points(count, 1, CV_32FC2); +- Mat points(1, count, CV_32FC2); +- std::vector\ points(sampleCount); +@param K Number of clusters to split the set by. +@param bestLabels Input/output integer array that stores the cluster indices for every sample. +@param criteria The algorithm termination criteria, that is, the maximum number of iterations and/or +the desired accuracy. The accuracy is specified as criteria.epsilon. As soon as each of the cluster +centers moves by less than criteria.epsilon on some iteration, the algorithm stops. +@param attempts Flag to specify the number of times the algorithm is executed using different +initial labellings. The algorithm returns the labels that yield the best compactness (see the last +function parameter). +@param flags Flag that can take values of cv::KmeansFlags +@param centers Output matrix of the cluster centers, one row per each cluster center. +@return The function returns the compactness measure that is computed as +\f[\sum _i \| \texttt{samples} _i - \texttt{centers} _{ \texttt{labels} _i} \| ^2\f] +after every attempt. The best (minimum) value is chosen and the corresponding labels and the +compactness value are returned by the function. Basically, you can use only the core of the +function, set the number of attempts to 1, initialize labels each time using a custom algorithm, +pass them with the ( flags = #KMEANS_USE_INITIAL_LABELS ) flag, and then choose the best +(most-compact) clustering. +*/ +CV_EXPORTS_W double kmeans( InputArray data, int K, InputOutputArray bestLabels, + TermCriteria criteria, int attempts, + int flags, OutputArray centers = noArray() ); + +//! @} core_cluster + +//! @addtogroup core_basic +//! @{ + +/////////////////////////////// Formatted output of cv::Mat /////////////////////////// + +/** @todo document */ +class CV_EXPORTS Formatted +{ +public: + virtual const char* next() = 0; + virtual void reset() = 0; + virtual ~Formatted(); +}; + +/** @todo document */ +class CV_EXPORTS Formatter +{ +public: + enum FormatType { + FMT_DEFAULT = 0, + FMT_MATLAB = 1, + FMT_CSV = 2, + FMT_PYTHON = 3, + FMT_NUMPY = 4, + FMT_C = 5 + }; + + virtual ~Formatter(); + + virtual Ptr format(const Mat& mtx) const = 0; + + virtual void set16fPrecision(int p = 4) = 0; + virtual void set32fPrecision(int p = 8) = 0; + virtual void set64fPrecision(int p = 16) = 0; + virtual void setMultiline(bool ml = true) = 0; + + static Ptr get(Formatter::FormatType fmt = FMT_DEFAULT); + +}; + +static inline +String& operator << (String& out, Ptr fmtd) +{ + fmtd->reset(); + for(const char* str = fmtd->next(); str; str = fmtd->next()) + out += cv::String(str); + return out; +} + +static inline +String& operator << (String& out, const Mat& mtx) +{ + return out << Formatter::get()->format(mtx); +} + +//////////////////////////////////////// Algorithm //////////////////////////////////// + +class CV_EXPORTS Algorithm; + +template struct ParamType {}; + + +/** @brief This is a base class for all more or less complex algorithms in OpenCV + +especially for classes of algorithms, for which there can be multiple implementations. The examples +are stereo correspondence (for which there are algorithms like block matching, semi-global block +matching, graph-cut etc.), background subtraction (which can be done using mixture-of-gaussians +models, codebook-based algorithm etc.), optical flow (block matching, Lucas-Kanade, Horn-Schunck +etc.). + +Here is example of SimpleBlobDetector use in your application via Algorithm interface: +@snippet snippets/core_various.cpp Algorithm +*/ +class CV_EXPORTS_W Algorithm +{ +public: + Algorithm(); + virtual ~Algorithm(); + + /** @brief Clears the algorithm state + */ + CV_WRAP virtual void clear() {} + + /** @brief Stores algorithm parameters in a file storage + */ + virtual void write(FileStorage& fs) const { CV_UNUSED(fs); } + + /** @brief simplified API for language bindings + * @overload + */ + CV_WRAP void write(const Ptr& fs, const String& name = String()) const; + + /** @brief Reads algorithm parameters from a file storage + */ + CV_WRAP virtual void read(const FileNode& fn) { CV_UNUSED(fn); } + + /** @brief Returns true if the Algorithm is empty (e.g. in the very beginning or after unsuccessful read + */ + CV_WRAP virtual bool empty() const { return false; } + + /** @brief Reads algorithm from the file node + + This is static template method of Algorithm. It's usage is following (in the case of SVM): + @code + cv::FileStorage fsRead("example.xml", FileStorage::READ); + Ptr svm = Algorithm::read(fsRead.root()); + @endcode + In order to make this method work, the derived class must overwrite Algorithm::read(const + FileNode& fn) and also have static create() method without parameters + (or with all the optional parameters) + */ + template static Ptr<_Tp> read(const FileNode& fn) + { + Ptr<_Tp> obj = _Tp::create(); + obj->read(fn); + return !obj->empty() ? obj : Ptr<_Tp>(); + } + + /** @brief Loads algorithm from the file + + @param filename Name of the file to read. + @param objname The optional name of the node to read (if empty, the first top-level node will be used) + + This is static template method of Algorithm. It's usage is following (in the case of SVM): + @code + Ptr svm = Algorithm::load("my_svm_model.xml"); + @endcode + In order to make this method work, the derived class must overwrite Algorithm::read(const + FileNode& fn). + */ + template static Ptr<_Tp> load(const String& filename, const String& objname=String()) + { + FileStorage fs(filename, FileStorage::READ); + CV_Assert(fs.isOpened()); + FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]; + if (fn.empty()) return Ptr<_Tp>(); + Ptr<_Tp> obj = _Tp::create(); + obj->read(fn); + return !obj->empty() ? obj : Ptr<_Tp>(); + } + + /** @brief Loads algorithm from a String + + @param strModel The string variable containing the model you want to load. + @param objname The optional name of the node to read (if empty, the first top-level node will be used) + + This is static template method of Algorithm. It's usage is following (in the case of SVM): + @code + Ptr svm = Algorithm::loadFromString(myStringModel); + @endcode + */ + template static Ptr<_Tp> loadFromString(const String& strModel, const String& objname=String()) + { + FileStorage fs(strModel, FileStorage::READ + FileStorage::MEMORY); + FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]; + Ptr<_Tp> obj = _Tp::create(); + obj->read(fn); + return !obj->empty() ? obj : Ptr<_Tp>(); + } + + /** Saves the algorithm to a file. + In order to make this method work, the derived class must implement Algorithm::write(FileStorage& fs). */ + CV_WRAP virtual void save(const String& filename) const; + + /** Returns the algorithm string identifier. + This string is used as top level xml/yml node tag when the object is saved to a file or string. */ + CV_WRAP virtual String getDefaultName() const; + +protected: + void writeFormat(FileStorage& fs) const; +}; + +enum struct Param { + INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, + UNSIGNED_INT=8, UINT64=9, UCHAR=11, SCALAR=12 +}; + + + +template<> struct ParamType +{ + typedef bool const_param_type; + typedef bool member_type; + + static const Param type = Param::BOOLEAN; +}; + +template<> struct ParamType +{ + typedef int const_param_type; + typedef int member_type; + + static const Param type = Param::INT; +}; + +template<> struct ParamType +{ + typedef double const_param_type; + typedef double member_type; + + static const Param type = Param::REAL; +}; + +template<> struct ParamType +{ + typedef const String& const_param_type; + typedef String member_type; + + static const Param type = Param::STRING; +}; + +template<> struct ParamType +{ + typedef const Mat& const_param_type; + typedef Mat member_type; + + static const Param type = Param::MAT; +}; + +template<> struct ParamType > +{ + typedef const std::vector& const_param_type; + typedef std::vector member_type; + + static const Param type = Param::MAT_VECTOR; +}; + +template<> struct ParamType +{ + typedef const Ptr& const_param_type; + typedef Ptr member_type; + + static const Param type = Param::ALGORITHM; +}; + +template<> struct ParamType +{ + typedef float const_param_type; + typedef float member_type; + + static const Param type = Param::FLOAT; +}; + +template<> struct ParamType +{ + typedef unsigned const_param_type; + typedef unsigned member_type; + + static const Param type = Param::UNSIGNED_INT; +}; + +template<> struct ParamType +{ + typedef uint64 const_param_type; + typedef uint64 member_type; + + static const Param type = Param::UINT64; +}; + +template<> struct ParamType +{ + typedef uchar const_param_type; + typedef uchar member_type; + + static const Param type = Param::UCHAR; +}; + +template<> struct ParamType +{ + typedef const Scalar& const_param_type; + typedef Scalar member_type; + + static const Param type = Param::SCALAR; +}; + +template +struct ParamType<_Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type> +{ + typedef typename std::underlying_type<_Tp>::type const_param_type; + typedef typename std::underlying_type<_Tp>::type member_type; + + static const Param type = Param::INT; +}; + +//! @} core_basic + +} //namespace cv + +#include "opencv2/core/operations.hpp" +#include "opencv2/core/cvstd.inl.hpp" +#include "opencv2/core/utility.hpp" +#include "opencv2/core/optim.hpp" +#include "opencv2/core/ovx.hpp" + +#endif /*OPENCV_CORE_HPP*/ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/affine.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/affine.hpp new file mode 100755 index 0000000..7e2ed30 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/affine.hpp @@ -0,0 +1,678 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_AFFINE3_HPP +#define OPENCV_CORE_AFFINE3_HPP + +#ifdef __cplusplus + +#include + +namespace cv +{ + +//! @addtogroup core +//! @{ + + /** @brief Affine transform + * + * It represents a 4x4 homogeneous transformation matrix \f$T\f$ + * + * \f[T = + * \begin{bmatrix} + * R & t\\ + * 0 & 1\\ + * \end{bmatrix} + * \f] + * + * where \f$R\f$ is a 3x3 rotation matrix and \f$t\f$ is a 3x1 translation vector. + * + * You can specify \f$R\f$ either by a 3x3 rotation matrix or by a 3x1 rotation vector, + * which is converted to a 3x3 rotation matrix by the Rodrigues formula. + * + * To construct a matrix \f$T\f$ representing first rotation around the axis \f$r\f$ with rotation + * angle \f$|r|\f$ in radian (right hand rule) and then translation by the vector \f$t\f$, you can use + * + * @code + * cv::Vec3f r, t; + * cv::Affine3f T(r, t); + * @endcode + * + * If you already have the rotation matrix \f$R\f$, then you can use + * + * @code + * cv::Matx33f R; + * cv::Affine3f T(R, t); + * @endcode + * + * To extract the rotation matrix \f$R\f$ from \f$T\f$, use + * + * @code + * cv::Matx33f R = T.rotation(); + * @endcode + * + * To extract the translation vector \f$t\f$ from \f$T\f$, use + * + * @code + * cv::Vec3f t = T.translation(); + * @endcode + * + * To extract the rotation vector \f$r\f$ from \f$T\f$, use + * + * @code + * cv::Vec3f r = T.rvec(); + * @endcode + * + * Note that since the mapping from rotation vectors to rotation matrices + * is many to one. The returned rotation vector is not necessarily the one + * you used before to set the matrix. + * + * If you have two transformations \f$T = T_1 * T_2\f$, use + * + * @code + * cv::Affine3f T, T1, T2; + * T = T2.concatenate(T1); + * @endcode + * + * To get the inverse transform of \f$T\f$, use + * + * @code + * cv::Affine3f T, T_inv; + * T_inv = T.inv(); + * @endcode + * + */ + template + class Affine3 + { + public: + typedef T float_type; + typedef Matx Mat3; + typedef Matx Mat4; + typedef Vec Vec3; + + //! Default constructor. It represents a 4x4 identity matrix. + Affine3(); + + //! Augmented affine matrix + Affine3(const Mat4& affine); + + /** + * The resulting 4x4 matrix is + * + * \f[ + * \begin{bmatrix} + * R & t\\ + * 0 & 1\\ + * \end{bmatrix} + * \f] + * + * @param R 3x3 rotation matrix. + * @param t 3x1 translation vector. + */ + Affine3(const Mat3& R, const Vec3& t = Vec3::all(0)); + + /** + * Rodrigues vector. + * + * The last row of the current matrix is set to [0,0,0,1]. + * + * @param rvec 3x1 rotation vector. Its direction indicates the rotation axis and its length + * indicates the rotation angle in radian (using right hand rule). + * @param t 3x1 translation vector. + */ + Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0)); + + /** + * Combines all constructors above. Supports 4x4, 3x4, 3x3, 1x3, 3x1 sizes of data matrix. + * + * The last row of the current matrix is set to [0,0,0,1] when data is not 4x4. + * + * @param data 1-channel matrix. + * when it is 4x4, it is copied to the current matrix and t is not used. + * When it is 3x4, it is copied to the upper part 3x4 of the current matrix and t is not used. + * When it is 3x3, it is copied to the upper left 3x3 part of the current matrix. + * When it is 3x1 or 1x3, it is treated as a rotation vector and the Rodrigues formula is used + * to compute a 3x3 rotation matrix. + * @param t 3x1 translation vector. It is used only when data is neither 4x4 nor 3x4. + */ + explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0)); + + //! From 16-element array + explicit Affine3(const float_type* vals); + + //! Create an 4x4 identity transform + static Affine3 Identity(); + + /** + * Rotation matrix. + * + * Copy the rotation matrix to the upper left 3x3 part of the current matrix. + * The remaining elements of the current matrix are not changed. + * + * @param R 3x3 rotation matrix. + * + */ + void rotation(const Mat3& R); + + /** + * Rodrigues vector. + * + * It sets the upper left 3x3 part of the matrix. The remaining part is unaffected. + * + * @param rvec 3x1 rotation vector. The direction indicates the rotation axis and + * its length indicates the rotation angle in radian (using the right thumb convention). + */ + void rotation(const Vec3& rvec); + + /** + * Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix. + * + * It sets the upper left 3x3 part of the matrix. The remaining part is unaffected. + * + * @param data 1-channel matrix. + * When it is a 3x3 matrix, it sets the upper left 3x3 part of the current matrix. + * When it is a 1x3 or 3x1 matrix, it is used as a rotation vector. The Rodrigues formula + * is used to compute the rotation matrix and sets the upper left 3x3 part of the current matrix. + */ + void rotation(const Mat& data); + + /** + * Copy the 3x3 matrix L to the upper left part of the current matrix + * + * It sets the upper left 3x3 part of the matrix. The remaining part is unaffected. + * + * @param L 3x3 matrix. + */ + void linear(const Mat3& L); + + /** + * Copy t to the first three elements of the last column of the current matrix + * + * It sets the upper right 3x1 part of the matrix. The remaining part is unaffected. + * + * @param t 3x1 translation vector. + */ + void translation(const Vec3& t); + + //! @return the upper left 3x3 part + Mat3 rotation() const; + + //! @return the upper left 3x3 part + Mat3 linear() const; + + //! @return the upper right 3x1 part + Vec3 translation() const; + + //! Rodrigues vector. + //! @return a vector representing the upper left 3x3 rotation matrix of the current matrix. + //! @warning Since the mapping between rotation vectors and rotation matrices is many to one, + //! this function returns only one rotation vector that represents the current rotation matrix, + //! which is not necessarily the same one set by `rotation(const Vec3& rvec)`. + Vec3 rvec() const; + + //! @return the inverse of the current matrix. + Affine3 inv(int method = cv::DECOMP_SVD) const; + + //! a.rotate(R) is equivalent to Affine(R, 0) * a; + Affine3 rotate(const Mat3& R) const; + + //! a.rotate(rvec) is equivalent to Affine(rvec, 0) * a; + Affine3 rotate(const Vec3& rvec) const; + + //! a.translate(t) is equivalent to Affine(E, t) * a, where E is an identity matrix + Affine3 translate(const Vec3& t) const; + + //! a.concatenate(affine) is equivalent to affine * a; + Affine3 concatenate(const Affine3& affine) const; + + template operator Affine3() const; + + template Affine3 cast() const; + + Mat4 matrix; + +#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H + Affine3(const Eigen::Transform& affine); + Affine3(const Eigen::Transform& affine); + operator Eigen::Transform() const; + operator Eigen::Transform() const; +#endif + }; + + template static + Affine3 operator*(const Affine3& affine1, const Affine3& affine2); + + //! V is a 3-element vector with member fields x, y and z + template static + V operator*(const Affine3& affine, const V& vector); + + typedef Affine3 Affine3f; + typedef Affine3 Affine3d; + + static Vec3f operator*(const Affine3f& affine, const Vec3f& vector); + static Vec3d operator*(const Affine3d& affine, const Vec3d& vector); + + template class DataType< Affine3<_Tp> > + { + public: + typedef Affine3<_Tp> value_type; + typedef Affine3::work_type> work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + channels = 16, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; + }; + + namespace traits { + template + struct Depth< Affine3<_Tp> > { enum { value = Depth<_Tp>::value }; }; + template + struct Type< Affine3<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 16) }; }; + } // namespace + +//! @} core + +} + +//! @cond IGNORED + +/////////////////////////////////////////////////////////////////////////////////// +// Implementation + +template inline +cv::Affine3::Affine3() + : matrix(Mat4::eye()) +{} + +template inline +cv::Affine3::Affine3(const Mat4& affine) + : matrix(affine) +{} + +template inline +cv::Affine3::Affine3(const Mat3& R, const Vec3& t) +{ + rotation(R); + translation(t); + matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; + matrix.val[15] = 1; +} + +template inline +cv::Affine3::Affine3(const Vec3& _rvec, const Vec3& t) +{ + rotation(_rvec); + translation(t); + matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; + matrix.val[15] = 1; +} + +template inline +cv::Affine3::Affine3(const cv::Mat& data, const Vec3& t) +{ + CV_Assert(data.type() == cv::traits::Type::value); + CV_Assert(data.channels() == 1); + + if (data.cols == 4 && data.rows == 4) + { + data.copyTo(matrix); + return; + } + else if (data.cols == 4 && data.rows == 3) + { + rotation(data(Rect(0, 0, 3, 3))); + translation(data(Rect(3, 0, 1, 3))); + } + else + { + rotation(data); + translation(t); + } + + matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; + matrix.val[15] = 1; +} + +template inline +cv::Affine3::Affine3(const float_type* vals) : matrix(vals) +{} + +template inline +cv::Affine3 cv::Affine3::Identity() +{ + return Affine3(cv::Affine3::Mat4::eye()); +} + +template inline +void cv::Affine3::rotation(const Mat3& R) +{ + linear(R); +} + +template inline +void cv::Affine3::rotation(const Vec3& _rvec) +{ + double theta = norm(_rvec); + + if (theta < DBL_EPSILON) + rotation(Mat3::eye()); + else + { + double c = std::cos(theta); + double s = std::sin(theta); + double c1 = 1. - c; + double itheta = (theta != 0) ? 1./theta : 0.; + + Point3_ r = _rvec*itheta; + + Mat3 rrt( r.x*r.x, r.x*r.y, r.x*r.z, r.x*r.y, r.y*r.y, r.y*r.z, r.x*r.z, r.y*r.z, r.z*r.z ); + Mat3 r_x( 0, -r.z, r.y, r.z, 0, -r.x, -r.y, r.x, 0 ); + + // R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x] + // where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0] + Mat3 R = c*Mat3::eye() + c1*rrt + s*r_x; + + rotation(R); + } +} + +//Combines rotation methods above. Supports 3x3, 1x3, 3x1 sizes of data matrix; +template inline +void cv::Affine3::rotation(const cv::Mat& data) +{ + CV_Assert(data.type() == cv::traits::Type::value); + CV_Assert(data.channels() == 1); + + if (data.cols == 3 && data.rows == 3) + { + Mat3 R; + data.copyTo(R); + rotation(R); + } + else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3)) + { + Vec3 _rvec; + data.reshape(1, 3).copyTo(_rvec); + rotation(_rvec); + } + else + CV_Error(Error::StsError, "Input matrix can only be 3x3, 1x3 or 3x1"); +} + +template inline +void cv::Affine3::linear(const Mat3& L) +{ + matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2]; + matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5]; + matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8]; +} + +template inline +void cv::Affine3::translation(const Vec3& t) +{ + matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2]; +} + +template inline +typename cv::Affine3::Mat3 cv::Affine3::rotation() const +{ + return linear(); +} + +template inline +typename cv::Affine3::Mat3 cv::Affine3::linear() const +{ + typename cv::Affine3::Mat3 R; + R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2]; + R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6]; + R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10]; + return R; +} + +template inline +typename cv::Affine3::Vec3 cv::Affine3::translation() const +{ + return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]); +} + +template inline +typename cv::Affine3::Vec3 cv::Affine3::rvec() const +{ + cv::Vec3d w; + cv::Matx33d u, vt, R = rotation(); + cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A); + R = u * vt; + + double rx = R.val[7] - R.val[5]; + double ry = R.val[2] - R.val[6]; + double rz = R.val[3] - R.val[1]; + + double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25); + double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5; + c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c; + double theta = acos(c); + + if( s < 1e-5 ) + { + if( c > 0 ) + rx = ry = rz = 0; + else + { + double t; + t = (R.val[0] + 1) * 0.5; + rx = std::sqrt(std::max(t, 0.0)); + t = (R.val[4] + 1) * 0.5; + ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0); + t = (R.val[8] + 1) * 0.5; + rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0); + + if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) ) + rz = -rz; + theta /= std::sqrt(rx*rx + ry*ry + rz*rz); + rx *= theta; + ry *= theta; + rz *= theta; + } + } + else + { + double vth = 1/(2*s); + vth *= theta; + rx *= vth; ry *= vth; rz *= vth; + } + + return cv::Vec3d(rx, ry, rz); +} + +template inline +cv::Affine3 cv::Affine3::inv(int method) const +{ + return matrix.inv(method); +} + +template inline +cv::Affine3 cv::Affine3::rotate(const Mat3& R) const +{ + Mat3 Lc = linear(); + Vec3 tc = translation(); + Mat4 result; + result.val[12] = result.val[13] = result.val[14] = 0; + result.val[15] = 1; + + for(int j = 0; j < 3; ++j) + { + for(int i = 0; i < 3; ++i) + { + float_type value = 0; + for(int k = 0; k < 3; ++k) + value += R(j, k) * Lc(k, i); + result(j, i) = value; + } + + result(j, 3) = R.row(j).dot(tc.t()); + } + return result; +} + +template inline +cv::Affine3 cv::Affine3::rotate(const Vec3& _rvec) const +{ + return rotate(Affine3f(_rvec).rotation()); +} + +template inline +cv::Affine3 cv::Affine3::translate(const Vec3& t) const +{ + Mat4 m = matrix; + m.val[ 3] += t[0]; + m.val[ 7] += t[1]; + m.val[11] += t[2]; + return m; +} + +template inline +cv::Affine3 cv::Affine3::concatenate(const Affine3& affine) const +{ + return (*this).rotate(affine.rotation()).translate(affine.translation()); +} + +template template inline +cv::Affine3::operator Affine3() const +{ + return Affine3(matrix); +} + +template template inline +cv::Affine3 cv::Affine3::cast() const +{ + return Affine3(matrix); +} + +template inline +cv::Affine3 cv::operator*(const cv::Affine3& affine1, const cv::Affine3& affine2) +{ + return affine2.concatenate(affine1); +} + +template inline +V cv::operator*(const cv::Affine3& affine, const V& v) +{ + const typename Affine3::Mat4& m = affine.matrix; + + V r; + r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3]; + r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7]; + r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11]; + return r; +} + +static inline +cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v) +{ + const cv::Matx44f& m = affine.matrix; + cv::Vec3f r; + r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3]; + r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7]; + r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11]; + return r; +} + +static inline +cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v) +{ + const cv::Matx44d& m = affine.matrix; + cv::Vec3d r; + r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3]; + r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7]; + r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11]; + return r; +} + + + +#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H + +template inline +cv::Affine3::Affine3(const Eigen::Transform& affine) +{ + cv::Mat(4, 4, cv::traits::Type::value, affine.matrix().data()).copyTo(matrix); +} + +template inline +cv::Affine3::Affine3(const Eigen::Transform& affine) +{ + Eigen::Transform a = affine; + cv::Mat(4, 4, cv::traits::Type::value, a.matrix().data()).copyTo(matrix); +} + +template inline +cv::Affine3::operator Eigen::Transform() const +{ + Eigen::Transform r; + cv::Mat hdr(4, 4, cv::traits::Type::value, r.matrix().data()); + cv::Mat(matrix, false).copyTo(hdr); + return r; +} + +template inline +cv::Affine3::operator Eigen::Transform() const +{ + return this->operator Eigen::Transform(); +} + +#endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */ + +//! @endcond + +#endif /* __cplusplus */ + +#endif /* OPENCV_CORE_AFFINE3_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/async.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/async.hpp new file mode 100755 index 0000000..54560c7 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/async.hpp @@ -0,0 +1,105 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_ASYNC_HPP +#define OPENCV_CORE_ASYNC_HPP + +#include + +#ifdef CV_CXX11 +//#include +#include +#endif + +namespace cv { + +/** @addtogroup core_async + +@{ +*/ + + +/** @brief Returns result of asynchronous operations + +Object has attached asynchronous state. +Assignment operator doesn't clone asynchronous state (it is shared between all instances). + +Result can be fetched via get() method only once. + +*/ +class CV_EXPORTS_W AsyncArray +{ +public: + ~AsyncArray() CV_NOEXCEPT; + CV_WRAP AsyncArray() CV_NOEXCEPT; + AsyncArray(const AsyncArray& o) CV_NOEXCEPT; + AsyncArray& operator=(const AsyncArray& o) CV_NOEXCEPT; + CV_WRAP void release() CV_NOEXCEPT; + + /** Fetch the result. + @param[out] dst destination array + + Waits for result until container has valid result. + Throws exception if exception was stored as a result. + + Throws exception on invalid container state. + + @note Result or stored exception can be fetched only once. + */ + CV_WRAP void get(OutputArray dst) const; + + /** Retrieving the result with timeout + @param[out] dst destination array + @param[in] timeoutNs timeout in nanoseconds, -1 for infinite wait + + @returns true if result is ready, false if the timeout has expired + + @note Result or stored exception can be fetched only once. + */ + bool get(OutputArray dst, int64 timeoutNs) const; + + CV_WRAP inline + bool get(OutputArray dst, double timeoutNs) const { return get(dst, (int64)timeoutNs); } + + bool wait_for(int64 timeoutNs) const; + + CV_WRAP inline + bool wait_for(double timeoutNs) const { return wait_for((int64)timeoutNs); } + + CV_WRAP bool valid() const CV_NOEXCEPT; + +#ifdef CV_CXX11 + inline AsyncArray(AsyncArray&& o) { p = o.p; o.p = NULL; } + inline AsyncArray& operator=(AsyncArray&& o) CV_NOEXCEPT { std::swap(p, o.p); return *this; } + + template + inline bool get(OutputArray dst, const std::chrono::duration<_Rep, _Period>& timeout) + { + return get(dst, (int64)(std::chrono::nanoseconds(timeout).count())); + } + + template + inline bool wait_for(const std::chrono::duration<_Rep, _Period>& timeout) + { + return wait_for((int64)(std::chrono::nanoseconds(timeout).count())); + } + +#if 0 + std::future getFutureMat() const; + std::future getFutureUMat() const; +#endif +#endif + + + // PImpl + struct Impl; friend struct Impl; + inline void* _getImpl() const CV_NOEXCEPT { return p; } +protected: + Impl* p; +}; + + +//! @} +} // namespace +#endif // OPENCV_CORE_ASYNC_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/base.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/base.hpp new file mode 100755 index 0000000..a3a3e51 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/base.hpp @@ -0,0 +1,654 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2014, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_BASE_HPP +#define OPENCV_CORE_BASE_HPP + +#ifndef __cplusplus +# error base.hpp header must be compiled as C++ +#endif + +#include "opencv2/opencv_modules.hpp" + +#include +#include + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/cvstd.hpp" + +namespace cv +{ + +//! @addtogroup core_utils +//! @{ + +namespace Error { +//! error codes +enum Code { + StsOk= 0, //!< everything is ok + StsBackTrace= -1, //!< pseudo error for back trace + StsError= -2, //!< unknown /unspecified error + StsInternal= -3, //!< internal error (bad state) + StsNoMem= -4, //!< insufficient memory + StsBadArg= -5, //!< function arg/param is bad + StsBadFunc= -6, //!< unsupported function + StsNoConv= -7, //!< iteration didn't converge + StsAutoTrace= -8, //!< tracing + HeaderIsNull= -9, //!< image header is NULL + BadImageSize= -10, //!< image size is invalid + BadOffset= -11, //!< offset is invalid + BadDataPtr= -12, //!< + BadStep= -13, //!< image step is wrong, this may happen for a non-continuous matrix. + BadModelOrChSeq= -14, //!< + BadNumChannels= -15, //!< bad number of channels, for example, some functions accept only single channel matrices. + BadNumChannel1U= -16, //!< + BadDepth= -17, //!< input image depth is not supported by the function + BadAlphaChannel= -18, //!< + BadOrder= -19, //!< number of dimensions is out of range + BadOrigin= -20, //!< incorrect input origin + BadAlign= -21, //!< incorrect input align + BadCallBack= -22, //!< + BadTileSize= -23, //!< + BadCOI= -24, //!< input COI is not supported + BadROISize= -25, //!< incorrect input roi + MaskIsTiled= -26, //!< + StsNullPtr= -27, //!< null pointer + StsVecLengthErr= -28, //!< incorrect vector length + StsFilterStructContentErr= -29, //!< incorrect filter structure content + StsKernelStructContentErr= -30, //!< incorrect transform kernel content + StsFilterOffsetErr= -31, //!< incorrect filter offset value + StsBadSize= -201, //!< the input/output structure size is incorrect + StsDivByZero= -202, //!< division by zero + StsInplaceNotSupported= -203, //!< in-place operation is not supported + StsObjectNotFound= -204, //!< request can't be completed + StsUnmatchedFormats= -205, //!< formats of input/output arrays differ + StsBadFlag= -206, //!< flag is wrong or not supported + StsBadPoint= -207, //!< bad CvPoint + StsBadMask= -208, //!< bad format of mask (neither 8uC1 nor 8sC1) + StsUnmatchedSizes= -209, //!< sizes of input/output structures do not match + StsUnsupportedFormat= -210, //!< the data format/type is not supported by the function + StsOutOfRange= -211, //!< some of parameters are out of range + StsParseError= -212, //!< invalid syntax/structure of the parsed file + StsNotImplemented= -213, //!< the requested function/feature is not implemented + StsBadMemBlock= -214, //!< an allocated block has been corrupted + StsAssert= -215, //!< assertion failed + GpuNotSupported= -216, //!< no CUDA support + GpuApiCallError= -217, //!< GPU API call error + OpenGlNotSupported= -218, //!< no OpenGL support + OpenGlApiCallError= -219, //!< OpenGL API call error + OpenCLApiCallError= -220, //!< OpenCL API call error + OpenCLDoubleNotSupported= -221, + OpenCLInitError= -222, //!< OpenCL initialization error + OpenCLNoAMDBlasFft= -223 +}; +} //Error + +//! @} core_utils + +//! @addtogroup core_array +//! @{ + +//! matrix decomposition types +enum DecompTypes { + /** Gaussian elimination with the optimal pivot element chosen. */ + DECOMP_LU = 0, + /** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix + src1 can be singular */ + DECOMP_SVD = 1, + /** eigenvalue decomposition; the matrix src1 must be symmetrical */ + DECOMP_EIG = 2, + /** Cholesky \f$LL^T\f$ factorization; the matrix src1 must be symmetrical and positively + defined */ + DECOMP_CHOLESKY = 3, + /** QR factorization; the system can be over-defined and/or the matrix src1 can be singular */ + DECOMP_QR = 4, + /** while all the previous flags are mutually exclusive, this flag can be used together with + any of the previous; it means that the normal equations + \f$\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}\f$ are + solved instead of the original system + \f$\texttt{src1}\cdot\texttt{dst}=\texttt{src2}\f$ */ + DECOMP_NORMAL = 16 +}; + +/** norm types + +src1 and src2 denote input arrays. +*/ + +enum NormTypes { + /** + \f[ + norm = \forkthree + {\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) } + {\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_INF}\) } + {\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_INF}\) } + \f] + */ + NORM_INF = 1, + /** + \f[ + norm = \forkthree + {\| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\)} + { \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM_L1}\) } + { \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L1}\) } + \f]*/ + NORM_L1 = 2, + /** + \f[ + norm = \forkthree + { \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) } + { \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if \(\texttt{normType} = \texttt{NORM_L2}\) } + { \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2}\) } + \f] + */ + NORM_L2 = 4, + /** + \f[ + norm = \forkthree + { \| \texttt{src1} \| _{L_2} ^{2} = \sum_I \texttt{src1}(I)^2} {if \(\texttt{normType} = \texttt{NORM_L2SQR}\)} + { \| \texttt{src1} - \texttt{src2} \| _{L_2} ^{2} = \sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2 }{if \(\texttt{normType} = \texttt{NORM_L2SQR}\) } + { \left(\frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}}\right)^2 }{if \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2SQR}\) } + \f] + */ + NORM_L2SQR = 5, + /** + In the case of one input array, calculates the Hamming distance of the array from zero, + In the case of two input arrays, calculates the Hamming distance between the arrays. + */ + NORM_HAMMING = 6, + /** + Similar to NORM_HAMMING, but in the calculation, each two bits of the input sequence will + be added and treated as a single bit to be used in the same calculation as NORM_HAMMING. + */ + NORM_HAMMING2 = 7, + NORM_TYPE_MASK = 7, //!< bit-mask which can be used to separate norm type from norm flags + NORM_RELATIVE = 8, //!< flag + NORM_MINMAX = 32 //!< flag + }; + +//! comparison types +enum CmpTypes { CMP_EQ = 0, //!< src1 is equal to src2. + CMP_GT = 1, //!< src1 is greater than src2. + CMP_GE = 2, //!< src1 is greater than or equal to src2. + CMP_LT = 3, //!< src1 is less than src2. + CMP_LE = 4, //!< src1 is less than or equal to src2. + CMP_NE = 5 //!< src1 is unequal to src2. + }; + +//! generalized matrix multiplication flags +enum GemmFlags { GEMM_1_T = 1, //!< transposes src1 + GEMM_2_T = 2, //!< transposes src2 + GEMM_3_T = 4 //!< transposes src3 + }; + +enum DftFlags { + /** performs an inverse 1D or 2D transform instead of the default forward + transform. */ + DFT_INVERSE = 1, + /** scales the result: divide it by the number of array elements. Normally, it is + combined with DFT_INVERSE. */ + DFT_SCALE = 2, + /** performs a forward or inverse transform of every individual row of the input + matrix; this flag enables you to transform multiple vectors simultaneously and can be used to + decrease the overhead (which is sometimes several times larger than the processing itself) to + perform 3D and higher-dimensional transformations and so forth.*/ + DFT_ROWS = 4, + /** performs a forward transformation of 1D or 2D real array; the result, + though being a complex array, has complex-conjugate symmetry (*CCS*, see the function + description below for details), and such an array can be packed into a real array of the same + size as input, which is the fastest option and which is what the function does by default; + however, you may wish to get a full complex array (for simpler spectrum analysis, and so on) - + pass the flag to enable the function to produce a full-size complex output array. */ + DFT_COMPLEX_OUTPUT = 16, + /** performs an inverse transformation of a 1D or 2D complex array; the + result is normally a complex array of the same size, however, if the input array has + conjugate-complex symmetry (for example, it is a result of forward transformation with + DFT_COMPLEX_OUTPUT flag), the output is a real array; while the function itself does not + check whether the input is symmetrical or not, you can pass the flag and then the function + will assume the symmetry and produce the real output array (note that when the input is packed + into a real array and inverse transformation is executed, the function treats the input as a + packed complex-conjugate symmetrical array, and the output will also be a real array). */ + DFT_REAL_OUTPUT = 32, + /** specifies that input is complex input. If this flag is set, the input must have 2 channels. + On the other hand, for backwards compatibility reason, if input has 2 channels, input is + already considered complex. */ + DFT_COMPLEX_INPUT = 64, + /** performs an inverse 1D or 2D transform instead of the default forward transform. */ + DCT_INVERSE = DFT_INVERSE, + /** performs a forward or inverse transform of every individual row of the input + matrix. This flag enables you to transform multiple vectors simultaneously and can be used to + decrease the overhead (which is sometimes several times larger than the processing itself) to + perform 3D and higher-dimensional transforms and so forth.*/ + DCT_ROWS = DFT_ROWS +}; + +//! Various border types, image boundaries are denoted with `|` +//! @see borderInterpolate, copyMakeBorder +enum BorderTypes { + BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i` + BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh` + BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb` + BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg` + BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba` + BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno` + + BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101 + BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101 + BORDER_ISOLATED = 16 //!< do not look outside of ROI +}; + +//! @} core_array + +//! @addtogroup core_utils +//! @{ + +/*! @brief Signals an error and raises the exception. + +By default the function prints information about the error to stderr, +then it either stops if setBreakOnError() had been called before or raises the exception. +It is possible to alternate error processing by using redirectError(). +@param _code - error code (Error::Code) +@param _err - error description +@param _func - function name. Available only when the compiler supports getting it +@param _file - source file name where the error has occurred +@param _line - line number in the source file where the error has occurred +@see CV_Error, CV_Error_, CV_Assert, CV_DbgAssert + */ +CV_EXPORTS CV_NORETURN void error(int _code, const String& _err, const char* _func, const char* _file, int _line); + +#ifdef CV_STATIC_ANALYSIS + +// In practice, some macro are not processed correctly (noreturn is not detected). +// We need to use simplified definition for them. +#define CV_Error(code, msg) do { (void)(code); (void)(msg); abort(); } while (0) +#define CV_Error_(code, args) do { (void)(code); (void)(cv::format args); abort(); } while (0) +#define CV_Assert( expr ) do { if (!(expr)) abort(); } while (0) + +#else // CV_STATIC_ANALYSIS + +/** @brief Call the error handler. + +Currently, the error handler prints the error code and the error message to the standard +error stream `stderr`. In the Debug configuration, it then provokes memory access violation, so that +the execution stack and all the parameters can be analyzed by the debugger. In the Release +configuration, the exception is thrown. + +@param code one of Error::Code +@param msg error message +*/ +#define CV_Error( code, msg ) cv::error( code, msg, CV_Func, __FILE__, __LINE__ ) + +/** @brief Call the error handler. + +This macro can be used to construct an error message on-fly to include some dynamic information, +for example: +@code + // note the extra parentheses around the formatted text message + CV_Error_(Error::StsOutOfRange, + ("the value at (%d, %d)=%g is out of range", badPt.x, badPt.y, badValue)); +@endcode +@param code one of Error::Code +@param args printf-like formatted error message in parentheses +*/ +#define CV_Error_( code, args ) cv::error( code, cv::format args, CV_Func, __FILE__, __LINE__ ) + +/** @brief Checks a condition at runtime and throws exception if it fails + +The macros CV_Assert (and CV_DbgAssert(expr)) evaluate the specified expression. If it is 0, the macros +raise an error (see cv::error). The macro CV_Assert checks the condition in both Debug and Release +configurations while CV_DbgAssert is only retained in the Debug configuration. +*/ +#define CV_Assert( expr ) do { if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ ); } while(0) + +#endif // CV_STATIC_ANALYSIS + +//! @cond IGNORED +#if !defined(__OPENCV_BUILD) // TODO: backward compatibility only +#ifndef CV_ErrorNoReturn +#define CV_ErrorNoReturn CV_Error +#endif +#ifndef CV_ErrorNoReturn_ +#define CV_ErrorNoReturn_ CV_Error_ +#endif +#endif + +#define CV_Assert_1 CV_Assert +#define CV_Assert_2( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_1( __VA_ARGS__ )) +#define CV_Assert_3( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_2( __VA_ARGS__ )) +#define CV_Assert_4( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_3( __VA_ARGS__ )) +#define CV_Assert_5( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_4( __VA_ARGS__ )) +#define CV_Assert_6( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_5( __VA_ARGS__ )) +#define CV_Assert_7( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_6( __VA_ARGS__ )) +#define CV_Assert_8( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_7( __VA_ARGS__ )) +#define CV_Assert_9( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_8( __VA_ARGS__ )) +#define CV_Assert_10( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_9( __VA_ARGS__ )) + +#define CV_Assert_N(...) do { __CV_EXPAND(__CV_CAT(CV_Assert_, __CV_VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__)); } while(0) + +//! @endcond + +#if defined _DEBUG || defined CV_STATIC_ANALYSIS +# define CV_DbgAssert(expr) CV_Assert(expr) +#else +/** replaced with CV_Assert(expr) in Debug configuration */ +# define CV_DbgAssert(expr) +#endif + +/* + * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor + * bit count of A exclusive XOR'ed with B + */ +struct CV_EXPORTS Hamming +{ + static const NormTypes normType = NORM_HAMMING; + typedef unsigned char ValueType; + typedef int ResultType; + + /** this will count the bits in a ^ b + */ + ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const; +}; + +typedef Hamming HammingLUT; + +/////////////////////////////////// inline norms //////////////////////////////////// + +template inline _Tp cv_abs(_Tp x) { return std::abs(x); } +inline int cv_abs(uchar x) { return x; } +inline int cv_abs(schar x) { return std::abs(x); } +inline int cv_abs(ushort x) { return x; } +inline int cv_abs(short x) { return std::abs(x); } + +template static inline +_AccTp normL2Sqr(const _Tp* a, int n) +{ + _AccTp s = 0; + int i=0; +#if CV_ENABLE_UNROLLED + for( ; i <= n - 4; i += 4 ) + { + _AccTp v0 = a[i], v1 = a[i+1], v2 = a[i+2], v3 = a[i+3]; + s += v0*v0 + v1*v1 + v2*v2 + v3*v3; + } +#endif + for( ; i < n; i++ ) + { + _AccTp v = a[i]; + s += v*v; + } + return s; +} + +template static inline +_AccTp normL1(const _Tp* a, int n) +{ + _AccTp s = 0; + int i = 0; +#if CV_ENABLE_UNROLLED + for(; i <= n - 4; i += 4 ) + { + s += (_AccTp)cv_abs(a[i]) + (_AccTp)cv_abs(a[i+1]) + + (_AccTp)cv_abs(a[i+2]) + (_AccTp)cv_abs(a[i+3]); + } +#endif + for( ; i < n; i++ ) + s += cv_abs(a[i]); + return s; +} + +template static inline +_AccTp normInf(const _Tp* a, int n) +{ + _AccTp s = 0; + for( int i = 0; i < n; i++ ) + s = std::max(s, (_AccTp)cv_abs(a[i])); + return s; +} + +template static inline +_AccTp normL2Sqr(const _Tp* a, const _Tp* b, int n) +{ + _AccTp s = 0; + int i= 0; +#if CV_ENABLE_UNROLLED + for(; i <= n - 4; i += 4 ) + { + _AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]); + s += v0*v0 + v1*v1 + v2*v2 + v3*v3; + } +#endif + for( ; i < n; i++ ) + { + _AccTp v = _AccTp(a[i] - b[i]); + s += v*v; + } + return s; +} + +static inline float normL2Sqr(const float* a, const float* b, int n) +{ + float s = 0.f; + for( int i = 0; i < n; i++ ) + { + float v = a[i] - b[i]; + s += v*v; + } + return s; +} + +template static inline +_AccTp normL1(const _Tp* a, const _Tp* b, int n) +{ + _AccTp s = 0; + int i= 0; +#if CV_ENABLE_UNROLLED + for(; i <= n - 4; i += 4 ) + { + _AccTp v0 = _AccTp(a[i] - b[i]), v1 = _AccTp(a[i+1] - b[i+1]), v2 = _AccTp(a[i+2] - b[i+2]), v3 = _AccTp(a[i+3] - b[i+3]); + s += std::abs(v0) + std::abs(v1) + std::abs(v2) + std::abs(v3); + } +#endif + for( ; i < n; i++ ) + { + _AccTp v = _AccTp(a[i] - b[i]); + s += std::abs(v); + } + return s; +} + +inline float normL1(const float* a, const float* b, int n) +{ + float s = 0.f; + for( int i = 0; i < n; i++ ) + { + s += std::abs(a[i] - b[i]); + } + return s; +} + +inline int normL1(const uchar* a, const uchar* b, int n) +{ + int s = 0; + for( int i = 0; i < n; i++ ) + { + s += std::abs(a[i] - b[i]); + } + return s; +} + +template static inline +_AccTp normInf(const _Tp* a, const _Tp* b, int n) +{ + _AccTp s = 0; + for( int i = 0; i < n; i++ ) + { + _AccTp v0 = a[i] - b[i]; + s = std::max(s, std::abs(v0)); + } + return s; +} + +/** @brief Computes the cube root of an argument. + + The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly. + NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for + single-precision data. + @param val A function argument. + */ +CV_EXPORTS_W float cubeRoot(float val); + +/** @brief Calculates the angle of a 2D vector in degrees. + + The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured + in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees. + @param x x-coordinate of the vector. + @param y y-coordinate of the vector. + */ +CV_EXPORTS_W float fastAtan2(float y, float x); + +/** proxy for hal::LU */ +CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n); +/** proxy for hal::LU */ +CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n); +/** proxy for hal::Cholesky */ +CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n); +/** proxy for hal::Cholesky */ +CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n); + +////////////////// forward declarations for important OpenCV types ////////////////// + +//! @cond IGNORED + +template class Vec; +template class Matx; + +template class Complex; +template class Point_; +template class Point3_; +template class Size_; +template class Rect_; +template class Scalar_; + +class CV_EXPORTS RotatedRect; +class CV_EXPORTS Range; +class CV_EXPORTS TermCriteria; +class CV_EXPORTS KeyPoint; +class CV_EXPORTS DMatch; +class CV_EXPORTS RNG; + +class CV_EXPORTS Mat; +class CV_EXPORTS MatExpr; + +class CV_EXPORTS UMat; + +class CV_EXPORTS SparseMat; +typedef Mat MatND; + +template class Mat_; +template class SparseMat_; + +class CV_EXPORTS MatConstIterator; +class CV_EXPORTS SparseMatIterator; +class CV_EXPORTS SparseMatConstIterator; +template class MatIterator_; +template class MatConstIterator_; +template class SparseMatIterator_; +template class SparseMatConstIterator_; + +namespace ogl +{ + class CV_EXPORTS Buffer; + class CV_EXPORTS Texture2D; + class CV_EXPORTS Arrays; +} + +namespace cuda +{ + class CV_EXPORTS GpuMat; + class CV_EXPORTS HostMem; + class CV_EXPORTS Stream; + class CV_EXPORTS Event; +} + +namespace cudev +{ + template class GpuMat_; +} + +namespace ipp +{ +CV_EXPORTS unsigned long long getIppFeatures(); +CV_EXPORTS void setIppStatus(int status, const char * const funcname = NULL, const char * const filename = NULL, + int line = 0); +CV_EXPORTS int getIppStatus(); +CV_EXPORTS String getIppErrorLocation(); +CV_EXPORTS_W bool useIPP(); +CV_EXPORTS_W void setUseIPP(bool flag); +CV_EXPORTS_W String getIppVersion(); + +// IPP Not-Exact mode. This function may force use of IPP then both IPP and OpenCV provide proper results +// but have internal accuracy differences which have too much direct or indirect impact on accuracy tests. +CV_EXPORTS_W bool useIPP_NotExact(); +CV_EXPORTS_W void setUseIPP_NotExact(bool flag); +#ifndef DISABLE_OPENCV_3_COMPATIBILITY +static inline bool useIPP_NE() { return useIPP_NotExact(); } +static inline void setUseIPP_NE(bool flag) { setUseIPP_NotExact(flag); } +#endif + +} // ipp + +//! @endcond + +//! @} core_utils + + + + +} // cv + +#include "opencv2/core/neon_utils.hpp" +#include "opencv2/core/vsx_utils.hpp" +#include "opencv2/core/check.hpp" + +#endif //OPENCV_CORE_BASE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/bindings_utils.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/bindings_utils.hpp new file mode 100755 index 0000000..3e73784 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/bindings_utils.hpp @@ -0,0 +1,49 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_BINDINGS_UTILS_HPP +#define OPENCV_CORE_BINDINGS_UTILS_HPP + +#include +#include + +namespace cv { namespace utils { +//! @addtogroup core_utils +//! @{ + +CV_EXPORTS_W String dumpInputArray(InputArray argument); + +CV_EXPORTS_W String dumpInputArrayOfArrays(InputArrayOfArrays argument); + +CV_EXPORTS_W String dumpInputOutputArray(InputOutputArray argument); + +CV_EXPORTS_W String dumpInputOutputArrayOfArrays(InputOutputArrayOfArrays argument); + +CV_WRAP static inline +AsyncArray testAsyncArray(InputArray argument) +{ + AsyncPromise p; + p.setValue(argument); + return p.getArrayResult(); +} + +CV_WRAP static inline +AsyncArray testAsyncException() +{ + AsyncPromise p; + try + { + CV_Error(Error::StsOk, "Test: Generated async error"); + } + catch (const cv::Exception& e) + { + p.setException(e); + } + return p.getArrayResult(); +} + +//! @} +}} // namespace + +#endif // OPENCV_CORE_BINDINGS_UTILS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/bufferpool.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/bufferpool.hpp new file mode 100755 index 0000000..4698e5d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/bufferpool.hpp @@ -0,0 +1,40 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved. + +#ifndef OPENCV_CORE_BUFFER_POOL_HPP +#define OPENCV_CORE_BUFFER_POOL_HPP + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4265) +#endif + +namespace cv +{ + +//! @addtogroup core +//! @{ + +class BufferPoolController +{ +protected: + ~BufferPoolController() { } +public: + virtual size_t getReservedSize() const = 0; + virtual size_t getMaxReservedSize() const = 0; + virtual void setMaxReservedSize(size_t size) = 0; + virtual void freeAllReservedBuffers() = 0; +}; + +//! @} + +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // OPENCV_CORE_BUFFER_POOL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/check.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/check.hpp new file mode 100755 index 0000000..604447e --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/check.hpp @@ -0,0 +1,159 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_CHECK_HPP +#define OPENCV_CORE_CHECK_HPP + +#include + +namespace cv { + +/** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or "" */ +CV_EXPORTS const char* depthToString(int depth); + +/** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or "" */ +CV_EXPORTS const String typeToString(int type); + + +//! @cond IGNORED +namespace detail { + +/** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or NULL */ +CV_EXPORTS const char* depthToString_(int depth); + +/** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or cv::String() */ +CV_EXPORTS const cv::String typeToString_(int type); + +enum TestOp { + TEST_CUSTOM = 0, + TEST_EQ = 1, + TEST_NE = 2, + TEST_LE = 3, + TEST_LT = 4, + TEST_GE = 5, + TEST_GT = 6, + CV__LAST_TEST_OP +}; + +struct CheckContext { + const char* func; + const char* file; + int line; + enum TestOp testOp; + const char* message; + const char* p1_str; + const char* p2_str; +}; + +#ifndef CV__CHECK_FILENAME +# define CV__CHECK_FILENAME __FILE__ +#endif + +#ifndef CV__CHECK_FUNCTION +# if defined _MSC_VER +# define CV__CHECK_FUNCTION __FUNCSIG__ +# elif defined __GNUC__ +# define CV__CHECK_FUNCTION __PRETTY_FUNCTION__ +# else +# define CV__CHECK_FUNCTION "" +# endif +#endif + +#define CV__CHECK_LOCATION_VARNAME(id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_check_, id), __LINE__) +#define CV__DEFINE_CHECK_CONTEXT(id, message, testOp, p1_str, p2_str) \ + static const cv::detail::CheckContext CV__CHECK_LOCATION_VARNAME(id) = \ + { CV__CHECK_FUNCTION, CV__CHECK_FILENAME, __LINE__, testOp, message, p1_str, p2_str } + +CV_EXPORTS void CV_NORETURN check_failed_auto(const int v1, const int v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v1, const size_t v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const float v1, const float v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const double v1, const double v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_ v1, const Size_ v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v1, const int v2, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx); + +CV_EXPORTS void CV_NORETURN check_failed_auto(const int v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const float v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const double v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_ v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v, const CheckContext& ctx); +CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v, const CheckContext& ctx); + + +#define CV__TEST_EQ(v1, v2) ((v1) == (v2)) +#define CV__TEST_NE(v1, v2) ((v1) != (v2)) +#define CV__TEST_LE(v1, v2) ((v1) <= (v2)) +#define CV__TEST_LT(v1, v2) ((v1) < (v2)) +#define CV__TEST_GE(v1, v2) ((v1) >= (v2)) +#define CV__TEST_GT(v1, v2) ((v1) > (v2)) + +#define CV__CHECK(id, op, type, v1, v2, v1_str, v2_str, msg_str) do { \ + if(CV__TEST_##op((v1), (v2))) ; else { \ + CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_ ## op, v1_str, v2_str); \ + cv::detail::check_failed_ ## type((v1), (v2), CV__CHECK_LOCATION_VARNAME(id)); \ + } \ +} while (0) + +#define CV__CHECK_CUSTOM_TEST(id, type, v, test_expr, v_str, test_expr_str, msg_str) do { \ + if(!!(test_expr)) ; else { \ + CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_CUSTOM, v_str, test_expr_str); \ + cv::detail::check_failed_ ## type((v), CV__CHECK_LOCATION_VARNAME(id)); \ + } \ +} while (0) + +} // namespace +//! @endcond + + +/// Supported values of these types: int, float, double +#define CV_CheckEQ(v1, v2, msg) CV__CHECK(_, EQ, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckNE(v1, v2, msg) CV__CHECK(_, NE, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckLE(v1, v2, msg) CV__CHECK(_, LE, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckLT(v1, v2, msg) CV__CHECK(_, LT, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckGE(v1, v2, msg) CV__CHECK(_, GE, auto, v1, v2, #v1, #v2, msg) +#define CV_CheckGT(v1, v2, msg) CV__CHECK(_, GT, auto, v1, v2, #v1, #v2, msg) + +/// Check with additional "decoding" of type values in error message +#define CV_CheckTypeEQ(t1, t2, msg) CV__CHECK(_, EQ, MatType, t1, t2, #t1, #t2, msg) +/// Check with additional "decoding" of depth values in error message +#define CV_CheckDepthEQ(d1, d2, msg) CV__CHECK(_, EQ, MatDepth, d1, d2, #d1, #d2, msg) + +#define CV_CheckChannelsEQ(c1, c2, msg) CV__CHECK(_, EQ, MatChannels, c1, c2, #c1, #c2, msg) + +/// Example: type == CV_8UC1 || type == CV_8UC3 +#define CV_CheckType(t, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, MatType, t, (test_expr), #t, #test_expr, msg) + +/// Example: depth == CV_32F || depth == CV_64F +#define CV_CheckDepth(t, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, MatDepth, t, (test_expr), #t, #test_expr, msg) + +/// Example: v == A || v == B +#define CV_Check(v, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, auto, v, (test_expr), #v, #test_expr, msg) + +/// Some complex conditions: CV_Check(src2, src2.empty() || (src2.type() == src1.type() && src2.size() == src1.size()), "src2 should have same size/type as src1") +// TODO define pretty-printers + +#ifndef NDEBUG +#define CV_DbgCheck(v, test_expr, msg) CV__CHECK_CUSTOM_TEST(_, auto, v, (test_expr), #v, #test_expr, msg) +#define CV_DbgCheckEQ(v1, v2, msg) CV__CHECK(_, EQ, auto, v1, v2, #v1, #v2, msg) +#define CV_DbgCheckNE(v1, v2, msg) CV__CHECK(_, NE, auto, v1, v2, #v1, #v2, msg) +#define CV_DbgCheckLE(v1, v2, msg) CV__CHECK(_, LE, auto, v1, v2, #v1, #v2, msg) +#define CV_DbgCheckLT(v1, v2, msg) CV__CHECK(_, LT, auto, v1, v2, #v1, #v2, msg) +#define CV_DbgCheckGE(v1, v2, msg) CV__CHECK(_, GE, auto, v1, v2, #v1, #v2, msg) +#define CV_DbgCheckGT(v1, v2, msg) CV__CHECK(_, GT, auto, v1, v2, #v1, #v2, msg) +#else +#define CV_DbgCheck(v, test_expr, msg) do { } while (0) +#define CV_DbgCheckEQ(v1, v2, msg) do { } while (0) +#define CV_DbgCheckNE(v1, v2, msg) do { } while (0) +#define CV_DbgCheckLE(v1, v2, msg) do { } while (0) +#define CV_DbgCheckLT(v1, v2, msg) do { } while (0) +#define CV_DbgCheckGE(v1, v2, msg) do { } while (0) +#define CV_DbgCheckGT(v1, v2, msg) do { } while (0) +#endif + +} // namespace + +#endif // OPENCV_CORE_CHECK_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/core.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/core.hpp new file mode 100755 index 0000000..4389183 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/core.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/core.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/core_c.h b/Prj-Win/3rd/opencv/include/opencv2/core/core_c.h new file mode 100755 index 0000000..3937c49 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/core_c.h @@ -0,0 +1,3125 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + + +#ifndef OPENCV_CORE_C_H +#define OPENCV_CORE_C_H + +#include "opencv2/core/types_c.h" + +#ifdef __cplusplus +# ifdef _MSC_VER +/* disable warning C4190: 'function' has C-linkage specified, but returns UDT 'typename' + which is incompatible with C + + It is OK to disable it because we only extend few plain structures with + C++ construrtors for simpler interoperability with C++ API of the library +*/ +# pragma warning(disable:4190) +# elif defined __clang__ && __clang_major__ >= 3 +# pragma GCC diagnostic ignored "-Wreturn-type-c-linkage" +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup core_c + @{ +*/ + +/****************************************************************************************\ +* Array allocation, deallocation, initialization and access to elements * +\****************************************************************************************/ + +/** `malloc` wrapper. + If there is no enough memory, the function + (as well as other OpenCV functions that call cvAlloc) + raises an error. */ +CVAPI(void*) cvAlloc( size_t size ); + +/** `free` wrapper. + Here and further all the memory releasing functions + (that all call cvFree) take double pointer in order to + to clear pointer to the data after releasing it. + Passing pointer to NULL pointer is Ok: nothing happens in this case +*/ +CVAPI(void) cvFree_( void* ptr ); +#define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0) + +/** @brief Creates an image header but does not allocate the image data. + +@param size Image width and height +@param depth Image depth (see cvCreateImage ) +@param channels Number of channels (see cvCreateImage ) + */ +CVAPI(IplImage*) cvCreateImageHeader( CvSize size, int depth, int channels ); + +/** @brief Initializes an image header that was previously allocated. + +The returned IplImage\* points to the initialized header. +@param image Image header to initialize +@param size Image width and height +@param depth Image depth (see cvCreateImage ) +@param channels Number of channels (see cvCreateImage ) +@param origin Top-left IPL_ORIGIN_TL or bottom-left IPL_ORIGIN_BL +@param align Alignment for image rows, typically 4 or 8 bytes + */ +CVAPI(IplImage*) cvInitImageHeader( IplImage* image, CvSize size, int depth, + int channels, int origin CV_DEFAULT(0), + int align CV_DEFAULT(4)); + +/** @brief Creates an image header and allocates the image data. + +This function call is equivalent to the following code: +@code + header = cvCreateImageHeader(size, depth, channels); + cvCreateData(header); +@endcode +@param size Image width and height +@param depth Bit depth of image elements. See IplImage for valid depths. +@param channels Number of channels per pixel. See IplImage for details. This function only creates +images with interleaved channels. + */ +CVAPI(IplImage*) cvCreateImage( CvSize size, int depth, int channels ); + +/** @brief Deallocates an image header. + +This call is an analogue of : +@code + if(image ) + { + iplDeallocate(*image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI); + *image = 0; + } +@endcode +but it does not use IPL functions by default (see the CV_TURN_ON_IPL_COMPATIBILITY macro). +@param image Double pointer to the image header + */ +CVAPI(void) cvReleaseImageHeader( IplImage** image ); + +/** @brief Deallocates the image header and the image data. + +This call is a shortened form of : +@code + if(*image ) + { + cvReleaseData(*image); + cvReleaseImageHeader(image); + } +@endcode +@param image Double pointer to the image header +*/ +CVAPI(void) cvReleaseImage( IplImage** image ); + +/** Creates a copy of IPL image (widthStep may differ) */ +CVAPI(IplImage*) cvCloneImage( const IplImage* image ); + +/** @brief Sets the channel of interest in an IplImage. + +If the ROI is set to NULL and the coi is *not* 0, the ROI is allocated. Most OpenCV functions do +*not* support the COI setting, so to process an individual image/matrix channel one may copy (via +cvCopy or cvSplit) the channel to a separate image/matrix, process it and then copy the result +back (via cvCopy or cvMerge) if needed. +@param image A pointer to the image header +@param coi The channel of interest. 0 - all channels are selected, 1 - first channel is selected, +etc. Note that the channel indices become 1-based. + */ +CVAPI(void) cvSetImageCOI( IplImage* image, int coi ); + +/** @brief Returns the index of the channel of interest. + +Returns the channel of interest of in an IplImage. Returned values correspond to the coi in +cvSetImageCOI. +@param image A pointer to the image header + */ +CVAPI(int) cvGetImageCOI( const IplImage* image ); + +/** @brief Sets an image Region Of Interest (ROI) for a given rectangle. + +If the original image ROI was NULL and the rect is not the whole image, the ROI structure is +allocated. + +Most OpenCV functions support the use of ROI and treat the image rectangle as a separate image. For +example, all of the pixel coordinates are counted from the top-left (or bottom-left) corner of the +ROI, not the original image. +@param image A pointer to the image header +@param rect The ROI rectangle + */ +CVAPI(void) cvSetImageROI( IplImage* image, CvRect rect ); + +/** @brief Resets the image ROI to include the entire image and releases the ROI structure. + +This produces a similar result to the following, but in addition it releases the ROI structure. : +@code + cvSetImageROI(image, cvRect(0, 0, image->width, image->height )); + cvSetImageCOI(image, 0); +@endcode +@param image A pointer to the image header + */ +CVAPI(void) cvResetImageROI( IplImage* image ); + +/** @brief Returns the image ROI. + +If there is no ROI set, cvRect(0,0,image-\>width,image-\>height) is returned. +@param image A pointer to the image header + */ +CVAPI(CvRect) cvGetImageROI( const IplImage* image ); + +/** @brief Creates a matrix header but does not allocate the matrix data. + +The function allocates a new matrix header and returns a pointer to it. The matrix data can then be +allocated using cvCreateData or set explicitly to user-allocated data via cvSetData. +@param rows Number of rows in the matrix +@param cols Number of columns in the matrix +@param type Type of the matrix elements, see cvCreateMat + */ +CVAPI(CvMat*) cvCreateMatHeader( int rows, int cols, int type ); + +#define CV_AUTOSTEP 0x7fffffff + +/** @brief Initializes a pre-allocated matrix header. + +This function is often used to process raw data with OpenCV matrix functions. For example, the +following code computes the matrix product of two matrices, stored as ordinary arrays: +@code + double a[] = { 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12 }; + + double b[] = { 1, 5, 9, + 2, 6, 10, + 3, 7, 11, + 4, 8, 12 }; + + double c[9]; + CvMat Ma, Mb, Mc ; + + cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a); + cvInitMatHeader(&Mb, 4, 3, CV_64FC1, b); + cvInitMatHeader(&Mc, 3, 3, CV_64FC1, c); + + cvMatMulAdd(&Ma, &Mb, 0, &Mc); + // the c array now contains the product of a (3x4) and b (4x3) +@endcode +@param mat A pointer to the matrix header to be initialized +@param rows Number of rows in the matrix +@param cols Number of columns in the matrix +@param type Type of the matrix elements, see cvCreateMat . +@param data Optional: data pointer assigned to the matrix header +@param step Optional: full row width in bytes of the assigned data. By default, the minimal +possible step is used which assumes there are no gaps between subsequent rows of the matrix. + */ +CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols, + int type, void* data CV_DEFAULT(NULL), + int step CV_DEFAULT(CV_AUTOSTEP) ); + +/** @brief Creates a matrix header and allocates the matrix data. + +The function call is equivalent to the following code: +@code + CvMat* mat = cvCreateMatHeader(rows, cols, type); + cvCreateData(mat); +@endcode +@param rows Number of rows in the matrix +@param cols Number of columns in the matrix +@param type The type of the matrix elements in the form +CV_\\C\ , where S=signed, U=unsigned, F=float. For +example, CV _ 8UC1 means the elements are 8-bit unsigned and the there is 1 channel, and CV _ +32SC2 means the elements are 32-bit signed and there are 2 channels. + */ +CVAPI(CvMat*) cvCreateMat( int rows, int cols, int type ); + +/** @brief Deallocates a matrix. + +The function decrements the matrix data reference counter and deallocates matrix header. If the data +reference counter is 0, it also deallocates the data. : +@code + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); +@endcode +@param mat Double pointer to the matrix + */ +CVAPI(void) cvReleaseMat( CvMat** mat ); + +/** @brief Decrements an array data reference counter. + +The function decrements the data reference counter in a CvMat or CvMatND if the reference counter + +pointer is not NULL. If the counter reaches zero, the data is deallocated. In the current +implementation the reference counter is not NULL only if the data was allocated using the +cvCreateData function. The counter will be NULL in other cases such as: external data was assigned +to the header using cvSetData, header is part of a larger matrix or image, or the header was +converted from an image or n-dimensional matrix header. +@param arr Pointer to an array header + */ +CV_INLINE void cvDecRefData( CvArr* arr ) +{ + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + mat->data.ptr = NULL; + if( mat->refcount != NULL && --*mat->refcount == 0 ) + cvFree( &mat->refcount ); + mat->refcount = NULL; + } + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + mat->data.ptr = NULL; + if( mat->refcount != NULL && --*mat->refcount == 0 ) + cvFree( &mat->refcount ); + mat->refcount = NULL; + } +} + +/** @brief Increments array data reference counter. + +The function increments CvMat or CvMatND data reference counter and returns the new counter value if +the reference counter pointer is not NULL, otherwise it returns zero. +@param arr Array header + */ +CV_INLINE int cvIncRefData( CvArr* arr ) +{ + int refcount = 0; + if( CV_IS_MAT( arr )) + { + CvMat* mat = (CvMat*)arr; + if( mat->refcount != NULL ) + refcount = ++*mat->refcount; + } + else if( CV_IS_MATND( arr )) + { + CvMatND* mat = (CvMatND*)arr; + if( mat->refcount != NULL ) + refcount = ++*mat->refcount; + } + return refcount; +} + + +/** Creates an exact copy of the input matrix (except, may be, step value) */ +CVAPI(CvMat*) cvCloneMat( const CvMat* mat ); + + +/** @brief Returns matrix header corresponding to the rectangular sub-array of input image or matrix. + +The function returns header, corresponding to a specified rectangle of the input array. In other + +words, it allows the user to treat a rectangular part of input array as a stand-alone array. ROI is +taken into account by the function so the sub-array of ROI is actually extracted. +@param arr Input array +@param submat Pointer to the resultant sub-array header +@param rect Zero-based coordinates of the rectangle of interest + */ +CVAPI(CvMat*) cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ); +#define cvGetSubArr cvGetSubRect + +/** @brief Returns array row or row span. + +The function returns the header, corresponding to a specified row/row span of the input array. +cvGetRow(arr, submat, row) is a shortcut for cvGetRows(arr, submat, row, row+1). +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param start_row Zero-based index of the starting row (inclusive) of the span +@param end_row Zero-based index of the ending row (exclusive) of the span +@param delta_row Index step in the row span. That is, the function extracts every delta_row -th +row from start_row and up to (but not including) end_row . + */ +CVAPI(CvMat*) cvGetRows( const CvArr* arr, CvMat* submat, + int start_row, int end_row, + int delta_row CV_DEFAULT(1)); + +/** @overload +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param row Zero-based index of the selected row +*/ +CV_INLINE CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row ) +{ + return cvGetRows( arr, submat, row, row + 1, 1 ); +} + + +/** @brief Returns one of more array columns. + +The function returns the header, corresponding to a specified column span of the input array. That + +is, no data is copied. Therefore, any modifications of the submatrix will affect the original array. +If you need to copy the columns, use cvCloneMat. cvGetCol(arr, submat, col) is a shortcut for +cvGetCols(arr, submat, col, col+1). +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param start_col Zero-based index of the starting column (inclusive) of the span +@param end_col Zero-based index of the ending column (exclusive) of the span + */ +CVAPI(CvMat*) cvGetCols( const CvArr* arr, CvMat* submat, + int start_col, int end_col ); + +/** @overload +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param col Zero-based index of the selected column +*/ +CV_INLINE CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col ) +{ + return cvGetCols( arr, submat, col, col + 1 ); +} + +/** @brief Returns one of array diagonals. + +The function returns the header, corresponding to a specified diagonal of the input array. +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param diag Index of the array diagonal. Zero value corresponds to the main diagonal, -1 +corresponds to the diagonal above the main, 1 corresponds to the diagonal below the main, and so +forth. + */ +CVAPI(CvMat*) cvGetDiag( const CvArr* arr, CvMat* submat, + int diag CV_DEFAULT(0)); + +/** low-level scalar <-> raw data conversion functions */ +CVAPI(void) cvScalarToRawData( const CvScalar* scalar, void* data, int type, + int extend_to_12 CV_DEFAULT(0) ); + +CVAPI(void) cvRawDataToScalar( const void* data, int type, CvScalar* scalar ); + +/** @brief Creates a new matrix header but does not allocate the matrix data. + +The function allocates a header for a multi-dimensional dense array. The array data can further be +allocated using cvCreateData or set explicitly to user-allocated data via cvSetData. +@param dims Number of array dimensions +@param sizes Array of dimension sizes +@param type Type of array elements, see cvCreateMat + */ +CVAPI(CvMatND*) cvCreateMatNDHeader( int dims, const int* sizes, int type ); + +/** @brief Creates the header and allocates the data for a multi-dimensional dense array. + +This function call is equivalent to the following code: +@code + CvMatND* mat = cvCreateMatNDHeader(dims, sizes, type); + cvCreateData(mat); +@endcode +@param dims Number of array dimensions. This must not exceed CV_MAX_DIM (32 by default, but can be +changed at build time). +@param sizes Array of dimension sizes. +@param type Type of array elements, see cvCreateMat . + */ +CVAPI(CvMatND*) cvCreateMatND( int dims, const int* sizes, int type ); + +/** @brief Initializes a pre-allocated multi-dimensional array header. + +@param mat A pointer to the array header to be initialized +@param dims The number of array dimensions +@param sizes An array of dimension sizes +@param type Type of array elements, see cvCreateMat +@param data Optional data pointer assigned to the matrix header + */ +CVAPI(CvMatND*) cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, + int type, void* data CV_DEFAULT(NULL) ); + +/** @brief Deallocates a multi-dimensional array. + +The function decrements the array data reference counter and releases the array header. If the +reference counter reaches 0, it also deallocates the data. : +@code + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); +@endcode +@param mat Double pointer to the array + */ +CV_INLINE void cvReleaseMatND( CvMatND** mat ) +{ + cvReleaseMat( (CvMat**)mat ); +} + +/** Creates a copy of CvMatND (except, may be, steps) */ +CVAPI(CvMatND*) cvCloneMatND( const CvMatND* mat ); + +/** @brief Creates sparse array. + +The function allocates a multi-dimensional sparse array. Initially the array contain no elements, +that is PtrND and other related functions will return 0 for every index. +@param dims Number of array dimensions. In contrast to the dense matrix, the number of dimensions is +practically unlimited (up to \f$2^{16}\f$ ). +@param sizes Array of dimension sizes +@param type Type of array elements. The same as for CvMat + */ +CVAPI(CvSparseMat*) cvCreateSparseMat( int dims, const int* sizes, int type ); + +/** @brief Deallocates sparse array. + +The function releases the sparse array and clears the array pointer upon exit. +@param mat Double pointer to the array + */ +CVAPI(void) cvReleaseSparseMat( CvSparseMat** mat ); + +/** Creates a copy of CvSparseMat (except, may be, zero items) */ +CVAPI(CvSparseMat*) cvCloneSparseMat( const CvSparseMat* mat ); + +/** @brief Initializes sparse array elements iterator. + +The function initializes iterator of sparse array elements and returns pointer to the first element, +or NULL if the array is empty. +@param mat Input array +@param mat_iterator Initialized iterator + */ +CVAPI(CvSparseNode*) cvInitSparseMatIterator( const CvSparseMat* mat, + CvSparseMatIterator* mat_iterator ); + +/** @brief Returns the next sparse matrix element + +The function moves iterator to the next sparse matrix element and returns pointer to it. In the +current version there is no any particular order of the elements, because they are stored in the +hash table. The sample below demonstrates how to iterate through the sparse matrix: +@code + // print all the non-zero sparse matrix elements and compute their sum + double sum = 0; + int i, dims = cvGetDims(sparsemat); + CvSparseMatIterator it; + CvSparseNode* node = cvInitSparseMatIterator(sparsemat, &it); + + for(; node != 0; node = cvGetNextSparseNode(&it)) + { + int* idx = CV_NODE_IDX(array, node); + float val = *(float*)CV_NODE_VAL(array, node); + printf("M"); + for(i = 0; i < dims; i++ ) + printf("[%d]", idx[i]); + printf("=%g\n", val); + + sum += val; + } + + printf("nTotal sum = %g\n", sum); +@endcode +@param mat_iterator Sparse array iterator + */ +CV_INLINE CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator ) +{ + if( mat_iterator->node->next ) + return mat_iterator->node = mat_iterator->node->next; + else + { + int idx; + for( idx = ++mat_iterator->curidx; idx < mat_iterator->mat->hashsize; idx++ ) + { + CvSparseNode* node = (CvSparseNode*)mat_iterator->mat->hashtable[idx]; + if( node ) + { + mat_iterator->curidx = idx; + return mat_iterator->node = node; + } + } + return NULL; + } +} + + +#define CV_MAX_ARR 10 + +/** matrix iterator: used for n-ary operations on dense arrays */ +typedef struct CvNArrayIterator +{ + int count; /**< number of arrays */ + int dims; /**< number of dimensions to iterate */ + CvSize size; /**< maximal common linear size: { width = size, height = 1 } */ + uchar* ptr[CV_MAX_ARR]; /**< pointers to the array slices */ + int stack[CV_MAX_DIM]; /**< for internal use */ + CvMatND* hdr[CV_MAX_ARR]; /**< pointers to the headers of the + matrices that are processed */ +} +CvNArrayIterator; + +#define CV_NO_DEPTH_CHECK 1 +#define CV_NO_CN_CHECK 2 +#define CV_NO_SIZE_CHECK 4 + +/** initializes iterator that traverses through several arrays simultaneously + (the function together with cvNextArraySlice is used for + N-ari element-wise operations) */ +CVAPI(int) cvInitNArrayIterator( int count, CvArr** arrs, + const CvArr* mask, CvMatND* stubs, + CvNArrayIterator* array_iterator, + int flags CV_DEFAULT(0) ); + +/** returns zero value if iteration is finished, non-zero (slice length) otherwise */ +CVAPI(int) cvNextNArraySlice( CvNArrayIterator* array_iterator ); + + +/** @brief Returns type of array elements. + +The function returns type of the array elements. In the case of IplImage the type is converted to +CvMat-like representation. For example, if the image has been created as: +@code + IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); +@endcode +The code cvGetElemType(img) will return CV_8UC3. +@param arr Input array + */ +CVAPI(int) cvGetElemType( const CvArr* arr ); + +/** @brief Return number of array dimensions + +The function returns the array dimensionality and the array of dimension sizes. In the case of +IplImage or CvMat it always returns 2 regardless of number of image/matrix rows. For example, the +following code calculates total number of array elements: +@code + int sizes[CV_MAX_DIM]; + int i, total = 1; + int dims = cvGetDims(arr, size); + for(i = 0; i < dims; i++ ) + total *= sizes[i]; +@endcode +@param arr Input array +@param sizes Optional output vector of the array dimension sizes. For 2d arrays the number of rows +(height) goes first, number of columns (width) next. + */ +CVAPI(int) cvGetDims( const CvArr* arr, int* sizes CV_DEFAULT(NULL) ); + + +/** @brief Returns array size along the specified dimension. + +@param arr Input array +@param index Zero-based dimension index (for matrices 0 means number of rows, 1 means number of +columns; for images 0 means height, 1 means width) + */ +CVAPI(int) cvGetDimSize( const CvArr* arr, int index ); + + +/** @brief Return pointer to a particular array element. + +The functions return a pointer to a specific array element. Number of array dimension should match +to the number of indices passed to the function except for cvPtr1D function that can be used for +sequential access to 1D, 2D or nD dense arrays. + +The functions can be used for sparse arrays as well - if the requested node does not exist they +create it and set it to zero. + +All these as well as other functions accessing array elements ( cvGetND , cvGetRealND , cvSet +, cvSetND , cvSetRealND ) raise an error in case if the element index is out of range. +@param arr Input array +@param idx0 The first zero-based component of the element index +@param type Optional output parameter: type of matrix elements + */ +CVAPI(uchar*) cvPtr1D( const CvArr* arr, int idx0, int* type CV_DEFAULT(NULL)); +/** @overload */ +CVAPI(uchar*) cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type CV_DEFAULT(NULL) ); +/** @overload */ +CVAPI(uchar*) cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, + int* type CV_DEFAULT(NULL)); +/** @overload +@param arr Input array +@param idx Array of the element indices +@param type Optional output parameter: type of matrix elements +@param create_node Optional input parameter for sparse matrices. Non-zero value of the parameter +means that the requested element is created if it does not exist already. +@param precalc_hashval Optional input parameter for sparse matrices. If the pointer is not NULL, +the function does not recalculate the node hash value, but takes it from the specified location. +It is useful for speeding up pair-wise operations (TODO: provide an example) +*/ +CVAPI(uchar*) cvPtrND( const CvArr* arr, const int* idx, int* type CV_DEFAULT(NULL), + int create_node CV_DEFAULT(1), + unsigned* precalc_hashval CV_DEFAULT(NULL)); + +/** @brief Return a specific array element. + +The functions return a specific array element. In the case of a sparse array the functions return 0 +if the requested node does not exist (no new node is created by the functions). +@param arr Input array +@param idx0 The first zero-based component of the element index + */ +CVAPI(CvScalar) cvGet1D( const CvArr* arr, int idx0 ); +/** @overload */ +CVAPI(CvScalar) cvGet2D( const CvArr* arr, int idx0, int idx1 ); +/** @overload */ +CVAPI(CvScalar) cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 ); +/** @overload +@param arr Input array +@param idx Array of the element indices +*/ +CVAPI(CvScalar) cvGetND( const CvArr* arr, const int* idx ); + +/** @brief Return a specific element of single-channel 1D, 2D, 3D or nD array. + +Returns a specific element of a single-channel array. If the array has multiple channels, a runtime +error is raised. Note that Get?D functions can be used safely for both single-channel and +multiple-channel arrays though they are a bit slower. + +In the case of a sparse array the functions return 0 if the requested node does not exist (no new +node is created by the functions). +@param arr Input array. Must have a single channel. +@param idx0 The first zero-based component of the element index + */ +CVAPI(double) cvGetReal1D( const CvArr* arr, int idx0 ); +/** @overload */ +CVAPI(double) cvGetReal2D( const CvArr* arr, int idx0, int idx1 ); +/** @overload */ +CVAPI(double) cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 ); +/** @overload +@param arr Input array. Must have a single channel. +@param idx Array of the element indices +*/ +CVAPI(double) cvGetRealND( const CvArr* arr, const int* idx ); + +/** @brief Change the particular array element. + +The functions assign the new value to a particular array element. In the case of a sparse array the +functions create the node if it does not exist yet. +@param arr Input array +@param idx0 The first zero-based component of the element index +@param value The assigned value + */ +CVAPI(void) cvSet1D( CvArr* arr, int idx0, CvScalar value ); +/** @overload */ +CVAPI(void) cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value ); +/** @overload */ +CVAPI(void) cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value ); +/** @overload +@param arr Input array +@param idx Array of the element indices +@param value The assigned value +*/ +CVAPI(void) cvSetND( CvArr* arr, const int* idx, CvScalar value ); + +/** @brief Change a specific array element. + +The functions assign a new value to a specific element of a single-channel array. If the array has +multiple channels, a runtime error is raised. Note that the Set\*D function can be used safely for +both single-channel and multiple-channel arrays, though they are a bit slower. + +In the case of a sparse array the functions create the node if it does not yet exist. +@param arr Input array +@param idx0 The first zero-based component of the element index +@param value The assigned value + */ +CVAPI(void) cvSetReal1D( CvArr* arr, int idx0, double value ); +/** @overload */ +CVAPI(void) cvSetReal2D( CvArr* arr, int idx0, int idx1, double value ); +/** @overload */ +CVAPI(void) cvSetReal3D( CvArr* arr, int idx0, + int idx1, int idx2, double value ); +/** @overload +@param arr Input array +@param idx Array of the element indices +@param value The assigned value +*/ +CVAPI(void) cvSetRealND( CvArr* arr, const int* idx, double value ); + +/** clears element of ND dense array, + in case of sparse arrays it deletes the specified node */ +CVAPI(void) cvClearND( CvArr* arr, const int* idx ); + +/** @brief Returns matrix header for arbitrary array. + +The function returns a matrix header for the input array that can be a matrix - CvMat, an image - +IplImage, or a multi-dimensional dense array - CvMatND (the third option is allowed only if +allowND != 0) . In the case of matrix the function simply returns the input pointer. In the case of +IplImage\* or CvMatND it initializes the header structure with parameters of the current image ROI +and returns &header. Because COI is not supported by CvMat, it is returned separately. + +The function provides an easy way to handle both types of arrays - IplImage and CvMat using the same +code. Input array must have non-zero data pointer, otherwise the function will report an error. + +@note If the input array is IplImage with planar data layout and COI set, the function returns the +pointer to the selected plane and COI == 0. This feature allows user to process IplImage structures +with planar data layout, even though OpenCV does not support such images. +@param arr Input array +@param header Pointer to CvMat structure used as a temporary buffer +@param coi Optional output parameter for storing COI +@param allowND If non-zero, the function accepts multi-dimensional dense arrays (CvMatND\*) and +returns 2D matrix (if CvMatND has two dimensions) or 1D matrix (when CvMatND has 1 dimension or +more than 2 dimensions). The CvMatND array must be continuous. +@sa cvGetImage, cvarrToMat. + */ +CVAPI(CvMat*) cvGetMat( const CvArr* arr, CvMat* header, + int* coi CV_DEFAULT(NULL), + int allowND CV_DEFAULT(0)); + +/** @brief Returns image header for arbitrary array. + +The function returns the image header for the input array that can be a matrix (CvMat) or image +(IplImage). In the case of an image the function simply returns the input pointer. In the case of +CvMat it initializes an image_header structure with the parameters of the input matrix. Note that +if we transform IplImage to CvMat using cvGetMat and then transform CvMat back to IplImage using +this function, we will get different headers if the ROI is set in the original image. +@param arr Input array +@param image_header Pointer to IplImage structure used as a temporary buffer + */ +CVAPI(IplImage*) cvGetImage( const CvArr* arr, IplImage* image_header ); + + +/** @brief Changes the shape of a multi-dimensional array without copying the data. + +The function is an advanced version of cvReshape that can work with multi-dimensional arrays as +well (though it can work with ordinary images and matrices) and change the number of dimensions. + +Below are the two samples from the cvReshape description rewritten using cvReshapeMatND: +@code + IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + IplImage gray_img_hdr, *gray_img; + gray_img = (IplImage*)cvReshapeMatND(color_img, sizeof(gray_img_hdr), &gray_img_hdr, 1, 0, 0); + ... + int size[] = { 2, 2, 2 }; + CvMatND* mat = cvCreateMatND(3, size, CV_32F); + CvMat row_header, *row; + row = (CvMat*)cvReshapeMatND(mat, sizeof(row_header), &row_header, 0, 1, 0); +@endcode +In C, the header file for this function includes a convenient macro cvReshapeND that does away with +the sizeof_header parameter. So, the lines containing the call to cvReshapeMatND in the examples +may be replaced as follow: +@code + gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0); + ... + row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0); +@endcode +@param arr Input array +@param sizeof_header Size of output header to distinguish between IplImage, CvMat and CvMatND +output headers +@param header Output header to be filled +@param new_cn New number of channels. new_cn = 0 means that the number of channels remains +unchanged. +@param new_dims New number of dimensions. new_dims = 0 means that the number of dimensions +remains the same. +@param new_sizes Array of new dimension sizes. Only new_dims-1 values are used, because the +total number of elements must remain the same. Thus, if new_dims = 1, new_sizes array is not +used. + */ +CVAPI(CvArr*) cvReshapeMatND( const CvArr* arr, + int sizeof_header, CvArr* header, + int new_cn, int new_dims, int* new_sizes ); + +#define cvReshapeND( arr, header, new_cn, new_dims, new_sizes ) \ + cvReshapeMatND( (arr), sizeof(*(header)), (header), \ + (new_cn), (new_dims), (new_sizes)) + +/** @brief Changes shape of matrix/image without copying data. + +The function initializes the CvMat header so that it points to the same data as the original array +but has a different shape - different number of channels, different number of rows, or both. + +The following example code creates one image buffer and two image headers, the first is for a +320x240x3 image and the second is for a 960x240x1 image: +@code + IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + CvMat gray_mat_hdr; + IplImage gray_img_hdr, *gray_img; + cvReshape(color_img, &gray_mat_hdr, 1); + gray_img = cvGetImage(&gray_mat_hdr, &gray_img_hdr); +@endcode +And the next example converts a 3x3 matrix to a single 1x9 vector: +@code + CvMat* mat = cvCreateMat(3, 3, CV_32F); + CvMat row_header, *row; + row = cvReshape(mat, &row_header, 0, 1); +@endcode +@param arr Input array +@param header Output header to be filled +@param new_cn New number of channels. 'new_cn = 0' means that the number of channels remains +unchanged. +@param new_rows New number of rows. 'new_rows = 0' means that the number of rows remains +unchanged unless it needs to be changed according to new_cn value. +*/ +CVAPI(CvMat*) cvReshape( const CvArr* arr, CvMat* header, + int new_cn, int new_rows CV_DEFAULT(0) ); + +/** Repeats source 2d array several times in both horizontal and + vertical direction to fill destination array */ +CVAPI(void) cvRepeat( const CvArr* src, CvArr* dst ); + +/** @brief Allocates array data + +The function allocates image, matrix or multi-dimensional dense array data. Note that in the case of +matrix types OpenCV allocation functions are used. In the case of IplImage they are used unless +CV_TURN_ON_IPL_COMPATIBILITY() has been called before. In the latter case IPL functions are used +to allocate the data. +@param arr Array header + */ +CVAPI(void) cvCreateData( CvArr* arr ); + +/** @brief Releases array data. + +The function releases the array data. In the case of CvMat or CvMatND it simply calls +cvDecRefData(), that is the function can not deallocate external data. See also the note to +cvCreateData . +@param arr Array header + */ +CVAPI(void) cvReleaseData( CvArr* arr ); + +/** @brief Assigns user data to the array header. + +The function assigns user data to the array header. Header should be initialized before using +cvCreateMatHeader, cvCreateImageHeader, cvCreateMatNDHeader, cvInitMatHeader, +cvInitImageHeader or cvInitMatNDHeader. +@param arr Array header +@param data User data +@param step Full row length in bytes + */ +CVAPI(void) cvSetData( CvArr* arr, void* data, int step ); + +/** @brief Retrieves low-level information about the array. + +The function fills output variables with low-level information about the array data. All output + +parameters are optional, so some of the pointers may be set to NULL. If the array is IplImage with +ROI set, the parameters of ROI are returned. + +The following example shows how to get access to array elements. It computes absolute values of the +array elements : +@code + float* data; + int step; + CvSize size; + + cvGetRawData(array, (uchar**)&data, &step, &size); + step /= sizeof(data[0]); + + for(int y = 0; y < size.height; y++, data += step ) + for(int x = 0; x < size.width; x++ ) + data[x] = (float)fabs(data[x]); +@endcode +@param arr Array header +@param data Output pointer to the whole image origin or ROI origin if ROI is set +@param step Output full row length in bytes +@param roi_size Output ROI size + */ +CVAPI(void) cvGetRawData( const CvArr* arr, uchar** data, + int* step CV_DEFAULT(NULL), + CvSize* roi_size CV_DEFAULT(NULL)); + +/** @brief Returns size of matrix or image ROI. + +The function returns number of rows (CvSize::height) and number of columns (CvSize::width) of the +input matrix or image. In the case of image the size of ROI is returned. +@param arr array header + */ +CVAPI(CvSize) cvGetSize( const CvArr* arr ); + +/** @brief Copies one array to another. + +The function copies selected elements from an input array to an output array: + +\f[\texttt{dst} (I)= \texttt{src} (I) \quad \text{if} \quad \texttt{mask} (I) \ne 0.\f] + +If any of the passed arrays is of IplImage type, then its ROI and COI fields are used. Both arrays +must have the same type, the same number of dimensions, and the same size. The function can also +copy sparse arrays (mask is not supported in this case). +@param src The source array +@param dst The destination array +@param mask Operation mask, 8-bit single channel array; specifies elements of the destination array +to be changed + */ +CVAPI(void) cvCopy( const CvArr* src, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @brief Sets every element of an array to a given value. + +The function copies the scalar value to every selected element of the destination array: +\f[\texttt{arr} (I)= \texttt{value} \quad \text{if} \quad \texttt{mask} (I) \ne 0\f] +If array arr is of IplImage type, then is ROI used, but COI must not be set. +@param arr The destination array +@param value Fill value +@param mask Operation mask, 8-bit single channel array; specifies elements of the destination +array to be changed + */ +CVAPI(void) cvSet( CvArr* arr, CvScalar value, + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @brief Clears the array. + +The function clears the array. In the case of dense arrays (CvMat, CvMatND or IplImage), +cvZero(array) is equivalent to cvSet(array,cvScalarAll(0),0). In the case of sparse arrays all the +elements are removed. +@param arr Array to be cleared + */ +CVAPI(void) cvSetZero( CvArr* arr ); +#define cvZero cvSetZero + + +/** Splits a multi-channel array into the set of single-channel arrays or + extracts particular [color] plane */ +CVAPI(void) cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1, + CvArr* dst2, CvArr* dst3 ); + +/** Merges a set of single-channel arrays into the single multi-channel array + or inserts one particular [color] plane to the array */ +CVAPI(void) cvMerge( const CvArr* src0, const CvArr* src1, + const CvArr* src2, const CvArr* src3, + CvArr* dst ); + +/** Copies several channels from input arrays to + certain channels of output arrays */ +CVAPI(void) cvMixChannels( const CvArr** src, int src_count, + CvArr** dst, int dst_count, + const int* from_to, int pair_count ); + +/** @brief Converts one array to another with optional linear transformation. + +The function has several different purposes, and thus has several different names. It copies one +array to another with optional scaling, which is performed first, and/or optional type conversion, +performed after: + +\f[\texttt{dst} (I) = \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...)\f] + +All the channels of multi-channel arrays are processed independently. + +The type of conversion is done with rounding and saturation, that is if the result of scaling + +conversion can not be represented exactly by a value of the destination array element type, it is +set to the nearest representable value on the real axis. +@param src Source array +@param dst Destination array +@param scale Scale factor +@param shift Value added to the scaled source array elements + */ +CVAPI(void) cvConvertScale( const CvArr* src, CvArr* dst, + double scale CV_DEFAULT(1), + double shift CV_DEFAULT(0) ); +#define cvCvtScale cvConvertScale +#define cvScale cvConvertScale +#define cvConvert( src, dst ) cvConvertScale( (src), (dst), 1, 0 ) + + +/** Performs linear transformation on every source array element, + stores absolute value of the result: + dst(x,y,c) = abs(scale*src(x,y,c)+shift). + destination array must have 8u type. + In other cases one may use cvConvertScale + cvAbsDiffS */ +CVAPI(void) cvConvertScaleAbs( const CvArr* src, CvArr* dst, + double scale CV_DEFAULT(1), + double shift CV_DEFAULT(0) ); +#define cvCvtScaleAbs cvConvertScaleAbs + + +/** checks termination criteria validity and + sets eps to default_eps (if it is not set), + max_iter to default_max_iters (if it is not set) +*/ +CVAPI(CvTermCriteria) cvCheckTermCriteria( CvTermCriteria criteria, + double default_eps, + int default_max_iters ); + +/****************************************************************************************\ +* Arithmetic, logic and comparison operations * +\****************************************************************************************/ + +/** dst(mask) = src1(mask) + src2(mask) */ +CVAPI(void) cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(mask) = src(mask) + value */ +CVAPI(void) cvAddS( const CvArr* src, CvScalar value, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(mask) = src1(mask) - src2(mask) */ +CVAPI(void) cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(mask) = src(mask) - value = src(mask) + (-value) */ +CV_INLINE void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)) +{ + cvAddS( src, cvScalar( -value.val[0], -value.val[1], -value.val[2], -value.val[3]), + dst, mask ); +} + +/** dst(mask) = value - src(mask) */ +CVAPI(void) cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, + const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(idx) = src1(idx) * src2(idx) * scale + (scaled element-wise multiplication of 2 arrays) */ +CVAPI(void) cvMul( const CvArr* src1, const CvArr* src2, + CvArr* dst, double scale CV_DEFAULT(1) ); + +/** element-wise division/inversion with scaling: + dst(idx) = src1(idx) * scale / src2(idx) + or dst(idx) = scale / src2(idx) if src1 == 0 */ +CVAPI(void) cvDiv( const CvArr* src1, const CvArr* src2, + CvArr* dst, double scale CV_DEFAULT(1)); + +/** dst = src1 * scale + src2 */ +CVAPI(void) cvScaleAdd( const CvArr* src1, CvScalar scale, + const CvArr* src2, CvArr* dst ); +#define cvAXPY( A, real_scalar, B, C ) cvScaleAdd(A, cvRealScalar(real_scalar), B, C) + +/** dst = src1 * alpha + src2 * beta + gamma */ +CVAPI(void) cvAddWeighted( const CvArr* src1, double alpha, + const CvArr* src2, double beta, + double gamma, CvArr* dst ); + +/** @brief Calculates the dot product of two arrays in Euclidean metrics. + +The function calculates and returns the Euclidean dot product of two arrays. + +\f[src1 \bullet src2 = \sum _I ( \texttt{src1} (I) \texttt{src2} (I))\f] + +In the case of multiple channel arrays, the results for all channels are accumulated. In particular, +cvDotProduct(a,a) where a is a complex vector, will return \f$||\texttt{a}||^2\f$. The function can +process multi-dimensional arrays, row by row, layer by layer, and so on. +@param src1 The first source array +@param src2 The second source array + */ +CVAPI(double) cvDotProduct( const CvArr* src1, const CvArr* src2 ); + +/** dst(idx) = src1(idx) & src2(idx) */ +CVAPI(void) cvAnd( const CvArr* src1, const CvArr* src2, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(idx) = src(idx) & value */ +CVAPI(void) cvAndS( const CvArr* src, CvScalar value, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(idx) = src1(idx) | src2(idx) */ +CVAPI(void) cvOr( const CvArr* src1, const CvArr* src2, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(idx) = src(idx) | value */ +CVAPI(void) cvOrS( const CvArr* src, CvScalar value, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(idx) = src1(idx) ^ src2(idx) */ +CVAPI(void) cvXor( const CvArr* src1, const CvArr* src2, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(idx) = src(idx) ^ value */ +CVAPI(void) cvXorS( const CvArr* src, CvScalar value, + CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); + +/** dst(idx) = ~src(idx) */ +CVAPI(void) cvNot( const CvArr* src, CvArr* dst ); + +/** dst(idx) = lower(idx) <= src(idx) < upper(idx) */ +CVAPI(void) cvInRange( const CvArr* src, const CvArr* lower, + const CvArr* upper, CvArr* dst ); + +/** dst(idx) = lower <= src(idx) < upper */ +CVAPI(void) cvInRangeS( const CvArr* src, CvScalar lower, + CvScalar upper, CvArr* dst ); + +#define CV_CMP_EQ 0 +#define CV_CMP_GT 1 +#define CV_CMP_GE 2 +#define CV_CMP_LT 3 +#define CV_CMP_LE 4 +#define CV_CMP_NE 5 + +/** The comparison operation support single-channel arrays only. + Destination image should be 8uC1 or 8sC1 */ + +/** dst(idx) = src1(idx) _cmp_op_ src2(idx) */ +CVAPI(void) cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op ); + +/** dst(idx) = src1(idx) _cmp_op_ value */ +CVAPI(void) cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op ); + +/** dst(idx) = min(src1(idx),src2(idx)) */ +CVAPI(void) cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/** dst(idx) = max(src1(idx),src2(idx)) */ +CVAPI(void) cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/** dst(idx) = min(src(idx),value) */ +CVAPI(void) cvMinS( const CvArr* src, double value, CvArr* dst ); + +/** dst(idx) = max(src(idx),value) */ +CVAPI(void) cvMaxS( const CvArr* src, double value, CvArr* dst ); + +/** dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c)) */ +CVAPI(void) cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/** dst(x,y,c) = abs(src(x,y,c) - value(c)) */ +CVAPI(void) cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value ); +#define cvAbs( src, dst ) cvAbsDiffS( (src), (dst), cvScalarAll(0)) + +/****************************************************************************************\ +* Math operations * +\****************************************************************************************/ + +/** Does cartesian->polar coordinates conversion. + Either of output components (magnitude or angle) is optional */ +CVAPI(void) cvCartToPolar( const CvArr* x, const CvArr* y, + CvArr* magnitude, CvArr* angle CV_DEFAULT(NULL), + int angle_in_degrees CV_DEFAULT(0)); + +/** Does polar->cartesian coordinates conversion. + Either of output components (magnitude or angle) is optional. + If magnitude is missing it is assumed to be all 1's */ +CVAPI(void) cvPolarToCart( const CvArr* magnitude, const CvArr* angle, + CvArr* x, CvArr* y, + int angle_in_degrees CV_DEFAULT(0)); + +/** Does powering: dst(idx) = src(idx)^power */ +CVAPI(void) cvPow( const CvArr* src, CvArr* dst, double power ); + +/** Does exponention: dst(idx) = exp(src(idx)). + Overflow is not handled yet. Underflow is handled. + Maximal relative error is ~7e-6 for single-precision input */ +CVAPI(void) cvExp( const CvArr* src, CvArr* dst ); + +/** Calculates natural logarithms: dst(idx) = log(abs(src(idx))). + Logarithm of 0 gives large negative number(~-700) + Maximal relative error is ~3e-7 for single-precision output +*/ +CVAPI(void) cvLog( const CvArr* src, CvArr* dst ); + +/** Fast arctangent calculation */ +CVAPI(float) cvFastArctan( float y, float x ); + +/** Fast cubic root calculation */ +CVAPI(float) cvCbrt( float value ); + +#define CV_CHECK_RANGE 1 +#define CV_CHECK_QUIET 2 +/** Checks array values for NaNs, Infs or simply for too large numbers + (if CV_CHECK_RANGE is set). If CV_CHECK_QUIET is set, + no runtime errors is raised (function returns zero value in case of "bad" values). + Otherwise cvError is called */ +CVAPI(int) cvCheckArr( const CvArr* arr, int flags CV_DEFAULT(0), + double min_val CV_DEFAULT(0), double max_val CV_DEFAULT(0)); +#define cvCheckArray cvCheckArr + +#define CV_RAND_UNI 0 +#define CV_RAND_NORMAL 1 + +/** @brief Fills an array with random numbers and updates the RNG state. + +The function fills the destination array with uniformly or normally distributed random numbers. +@param rng CvRNG state initialized by cvRNG +@param arr The destination array +@param dist_type Distribution type +> - **CV_RAND_UNI** uniform distribution +> - **CV_RAND_NORMAL** normal or Gaussian distribution +@param param1 The first parameter of the distribution. In the case of a uniform distribution it is +the inclusive lower boundary of the random numbers range. In the case of a normal distribution it +is the mean value of the random numbers. +@param param2 The second parameter of the distribution. In the case of a uniform distribution it +is the exclusive upper boundary of the random numbers range. In the case of a normal distribution +it is the standard deviation of the random numbers. +@sa randu, randn, RNG::fill. + */ +CVAPI(void) cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, + CvScalar param1, CvScalar param2 ); + +CVAPI(void) cvRandShuffle( CvArr* mat, CvRNG* rng, + double iter_factor CV_DEFAULT(1.)); + +#define CV_SORT_EVERY_ROW 0 +#define CV_SORT_EVERY_COLUMN 1 +#define CV_SORT_ASCENDING 0 +#define CV_SORT_DESCENDING 16 + +CVAPI(void) cvSort( const CvArr* src, CvArr* dst CV_DEFAULT(NULL), + CvArr* idxmat CV_DEFAULT(NULL), + int flags CV_DEFAULT(0)); + +/** Finds real roots of a cubic equation */ +CVAPI(int) cvSolveCubic( const CvMat* coeffs, CvMat* roots ); + +/** Finds all real and complex roots of a polynomial equation */ +CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2, + int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100)); + +/****************************************************************************************\ +* Matrix operations * +\****************************************************************************************/ + +/** @brief Calculates the cross product of two 3D vectors. + +The function calculates the cross product of two 3D vectors: +\f[\texttt{dst} = \texttt{src1} \times \texttt{src2}\f] +or: +\f[\begin{array}{l} \texttt{dst} _1 = \texttt{src1} _2 \texttt{src2} _3 - \texttt{src1} _3 \texttt{src2} _2 \\ \texttt{dst} _2 = \texttt{src1} _3 \texttt{src2} _1 - \texttt{src1} _1 \texttt{src2} _3 \\ \texttt{dst} _3 = \texttt{src1} _1 \texttt{src2} _2 - \texttt{src1} _2 \texttt{src2} _1 \end{array}\f] +@param src1 The first source vector +@param src2 The second source vector +@param dst The destination vector + */ +CVAPI(void) cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst ); + +/** Matrix transform: dst = A*B + C, C is optional */ +#define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( (src1), (src2), 1., (src3), 1., (dst), 0 ) +#define cvMatMul( src1, src2, dst ) cvMatMulAdd( (src1), (src2), NULL, (dst)) + +#define CV_GEMM_A_T 1 +#define CV_GEMM_B_T 2 +#define CV_GEMM_C_T 4 +/** Extended matrix transform: + dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T */ +CVAPI(void) cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, + const CvArr* src3, double beta, CvArr* dst, + int tABC CV_DEFAULT(0)); +#define cvMatMulAddEx cvGEMM + +/** Transforms each element of source array and stores + resultant vectors in destination array */ +CVAPI(void) cvTransform( const CvArr* src, CvArr* dst, + const CvMat* transmat, + const CvMat* shiftvec CV_DEFAULT(NULL)); +#define cvMatMulAddS cvTransform + +/** Does perspective transform on every element of input array */ +CVAPI(void) cvPerspectiveTransform( const CvArr* src, CvArr* dst, + const CvMat* mat ); + +/** Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1) */ +CVAPI(void) cvMulTransposed( const CvArr* src, CvArr* dst, int order, + const CvArr* delta CV_DEFAULT(NULL), + double scale CV_DEFAULT(1.) ); + +/** Tranposes matrix. Square matrices can be transposed in-place */ +CVAPI(void) cvTranspose( const CvArr* src, CvArr* dst ); +#define cvT cvTranspose + +/** Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part */ +CVAPI(void) cvCompleteSymm( CvMat* matrix, int LtoR CV_DEFAULT(0) ); + +/** Mirror array data around horizontal (flip=0), + vertical (flip=1) or both(flip=-1) axises: + cvFlip(src) flips images vertically and sequences horizontally (inplace) */ +CVAPI(void) cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL), + int flip_mode CV_DEFAULT(0)); +#define cvMirror cvFlip + + +#define CV_SVD_MODIFY_A 1 +#define CV_SVD_U_T 2 +#define CV_SVD_V_T 4 + +/** Performs Singular Value Decomposition of a matrix */ +CVAPI(void) cvSVD( CvArr* A, CvArr* W, CvArr* U CV_DEFAULT(NULL), + CvArr* V CV_DEFAULT(NULL), int flags CV_DEFAULT(0)); + +/** Performs Singular Value Back Substitution (solves A*X = B): + flags must be the same as in cvSVD */ +CVAPI(void) cvSVBkSb( const CvArr* W, const CvArr* U, + const CvArr* V, const CvArr* B, + CvArr* X, int flags ); + +#define CV_LU 0 +#define CV_SVD 1 +#define CV_SVD_SYM 2 +#define CV_CHOLESKY 3 +#define CV_QR 4 +#define CV_NORMAL 16 + +/** Inverts matrix */ +CVAPI(double) cvInvert( const CvArr* src, CvArr* dst, + int method CV_DEFAULT(CV_LU)); +#define cvInv cvInvert + +/** Solves linear system (src1)*(dst) = (src2) + (returns 0 if src1 is a singular and CV_LU method is used) */ +CVAPI(int) cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst, + int method CV_DEFAULT(CV_LU)); + +/** Calculates determinant of input matrix */ +CVAPI(double) cvDet( const CvArr* mat ); + +/** Calculates trace of the matrix (sum of elements on the main diagonal) */ +CVAPI(CvScalar) cvTrace( const CvArr* mat ); + +/** Finds eigen values and vectors of a symmetric matrix */ +CVAPI(void) cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, + double eps CV_DEFAULT(0), + int lowindex CV_DEFAULT(-1), + int highindex CV_DEFAULT(-1)); + +///* Finds selected eigen values and vectors of a symmetric matrix */ +//CVAPI(void) cvSelectedEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, +// int lowindex, int highindex ); + +/** Makes an identity matrix (mat_ij = i == j) */ +CVAPI(void) cvSetIdentity( CvArr* mat, CvScalar value CV_DEFAULT(cvRealScalar(1)) ); + +/** Fills matrix with given range of numbers */ +CVAPI(CvArr*) cvRange( CvArr* mat, double start, double end ); + +/** @anchor core_c_CovarFlags +@name Flags for cvCalcCovarMatrix +@see cvCalcCovarMatrix + @{ +*/ + +/** flag for cvCalcCovarMatrix, transpose([v1-avg, v2-avg,...]) * [v1-avg,v2-avg,...] */ +#define CV_COVAR_SCRAMBLED 0 + +/** flag for cvCalcCovarMatrix, [v1-avg, v2-avg,...] * transpose([v1-avg,v2-avg,...]) */ +#define CV_COVAR_NORMAL 1 + +/** flag for cvCalcCovarMatrix, do not calc average (i.e. mean vector) - use the input vector instead + (useful for calculating covariance matrix by parts) */ +#define CV_COVAR_USE_AVG 2 + +/** flag for cvCalcCovarMatrix, scale the covariance matrix coefficients by number of the vectors */ +#define CV_COVAR_SCALE 4 + +/** flag for cvCalcCovarMatrix, all the input vectors are stored in a single matrix, as its rows */ +#define CV_COVAR_ROWS 8 + +/** flag for cvCalcCovarMatrix, all the input vectors are stored in a single matrix, as its columns */ +#define CV_COVAR_COLS 16 + +/** @} */ + +/** Calculates covariation matrix for a set of vectors +@see @ref core_c_CovarFlags "flags" +*/ +CVAPI(void) cvCalcCovarMatrix( const CvArr** vects, int count, + CvArr* cov_mat, CvArr* avg, int flags ); + +#define CV_PCA_DATA_AS_ROW 0 +#define CV_PCA_DATA_AS_COL 1 +#define CV_PCA_USE_AVG 2 +CVAPI(void) cvCalcPCA( const CvArr* data, CvArr* mean, + CvArr* eigenvals, CvArr* eigenvects, int flags ); + +CVAPI(void) cvProjectPCA( const CvArr* data, const CvArr* mean, + const CvArr* eigenvects, CvArr* result ); + +CVAPI(void) cvBackProjectPCA( const CvArr* proj, const CvArr* mean, + const CvArr* eigenvects, CvArr* result ); + +/** Calculates Mahalanobis(weighted) distance */ +CVAPI(double) cvMahalanobis( const CvArr* vec1, const CvArr* vec2, const CvArr* mat ); +#define cvMahalonobis cvMahalanobis + +/****************************************************************************************\ +* Array Statistics * +\****************************************************************************************/ + +/** Finds sum of array elements */ +CVAPI(CvScalar) cvSum( const CvArr* arr ); + +/** Calculates number of non-zero pixels */ +CVAPI(int) cvCountNonZero( const CvArr* arr ); + +/** Calculates mean value of array elements */ +CVAPI(CvScalar) cvAvg( const CvArr* arr, const CvArr* mask CV_DEFAULT(NULL) ); + +/** Calculates mean and standard deviation of pixel values */ +CVAPI(void) cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, + const CvArr* mask CV_DEFAULT(NULL) ); + +/** Finds global minimum, maximum and their positions */ +CVAPI(void) cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val, + CvPoint* min_loc CV_DEFAULT(NULL), + CvPoint* max_loc CV_DEFAULT(NULL), + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @anchor core_c_NormFlags + @name Flags for cvNorm and cvNormalize + @{ +*/ +#define CV_C 1 +#define CV_L1 2 +#define CV_L2 4 +#define CV_NORM_MASK 7 +#define CV_RELATIVE 8 +#define CV_DIFF 16 +#define CV_MINMAX 32 + +#define CV_DIFF_C (CV_DIFF | CV_C) +#define CV_DIFF_L1 (CV_DIFF | CV_L1) +#define CV_DIFF_L2 (CV_DIFF | CV_L2) +#define CV_RELATIVE_C (CV_RELATIVE | CV_C) +#define CV_RELATIVE_L1 (CV_RELATIVE | CV_L1) +#define CV_RELATIVE_L2 (CV_RELATIVE | CV_L2) +/** @} */ + +/** Finds norm, difference norm or relative difference norm for an array (or two arrays) +@see ref core_c_NormFlags "flags" +*/ +CVAPI(double) cvNorm( const CvArr* arr1, const CvArr* arr2 CV_DEFAULT(NULL), + int norm_type CV_DEFAULT(CV_L2), + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @see ref core_c_NormFlags "flags" */ +CVAPI(void) cvNormalize( const CvArr* src, CvArr* dst, + double a CV_DEFAULT(1.), double b CV_DEFAULT(0.), + int norm_type CV_DEFAULT(CV_L2), + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @anchor core_c_ReduceFlags + @name Flags for cvReduce + @{ +*/ +#define CV_REDUCE_SUM 0 +#define CV_REDUCE_AVG 1 +#define CV_REDUCE_MAX 2 +#define CV_REDUCE_MIN 3 +/** @} */ + +/** @see @ref core_c_ReduceFlags "flags" */ +CVAPI(void) cvReduce( const CvArr* src, CvArr* dst, int dim CV_DEFAULT(-1), + int op CV_DEFAULT(CV_REDUCE_SUM) ); + +/****************************************************************************************\ +* Discrete Linear Transforms and Related Functions * +\****************************************************************************************/ + +/** @anchor core_c_DftFlags + @name Flags for cvDFT, cvDCT and cvMulSpectrums + @{ + */ +#define CV_DXT_FORWARD 0 +#define CV_DXT_INVERSE 1 +#define CV_DXT_SCALE 2 /**< divide result by size of array */ +#define CV_DXT_INV_SCALE (CV_DXT_INVERSE + CV_DXT_SCALE) +#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE +#define CV_DXT_ROWS 4 /**< transform each row individually */ +#define CV_DXT_MUL_CONJ 8 /**< conjugate the second argument of cvMulSpectrums */ +/** @} */ + +/** Discrete Fourier Transform: + complex->complex, + real->ccs (forward), + ccs->real (inverse) +@see core_c_DftFlags "flags" +*/ +CVAPI(void) cvDFT( const CvArr* src, CvArr* dst, int flags, + int nonzero_rows CV_DEFAULT(0) ); +#define cvFFT cvDFT + +/** Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y)) +@see core_c_DftFlags "flags" +*/ +CVAPI(void) cvMulSpectrums( const CvArr* src1, const CvArr* src2, + CvArr* dst, int flags ); + +/** Finds optimal DFT vector size >= size0 */ +CVAPI(int) cvGetOptimalDFTSize( int size0 ); + +/** Discrete Cosine Transform +@see core_c_DftFlags "flags" +*/ +CVAPI(void) cvDCT( const CvArr* src, CvArr* dst, int flags ); + +/****************************************************************************************\ +* Dynamic data structures * +\****************************************************************************************/ + +/** Calculates length of sequence slice (with support of negative indices). */ +CVAPI(int) cvSliceLength( CvSlice slice, const CvSeq* seq ); + + +/** Creates new memory storage. + block_size == 0 means that default, + somewhat optimal size, is used (currently, it is 64K) */ +CVAPI(CvMemStorage*) cvCreateMemStorage( int block_size CV_DEFAULT(0)); + + +/** Creates a memory storage that will borrow memory blocks from parent storage */ +CVAPI(CvMemStorage*) cvCreateChildMemStorage( CvMemStorage* parent ); + + +/** Releases memory storage. All the children of a parent must be released before + the parent. A child storage returns all the blocks to parent when it is released */ +CVAPI(void) cvReleaseMemStorage( CvMemStorage** storage ); + + +/** Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos) + to reuse memory allocated for the storage - cvClearSeq,cvClearSet ... + do not free any memory. + A child storage returns all the blocks to the parent when it is cleared */ +CVAPI(void) cvClearMemStorage( CvMemStorage* storage ); + +/** Remember a storage "free memory" position */ +CVAPI(void) cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos ); + +/** Restore a storage "free memory" position */ +CVAPI(void) cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos ); + +/** Allocates continuous buffer of the specified size in the storage */ +CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size ); + +/** Allocates string in memory storage */ +//CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, +// int len CV_DEFAULT(-1) ); + +/** Creates new empty sequence that will reside in the specified storage */ +CVAPI(CvSeq*) cvCreateSeq( int seq_flags, size_t header_size, + size_t elem_size, CvMemStorage* storage ); + +/** Changes default size (granularity) of sequence blocks. + The default size is ~1Kbyte */ +CVAPI(void) cvSetSeqBlockSize( CvSeq* seq, int delta_elems ); + + +/** Adds new element to the end of sequence. Returns pointer to the element */ +CVAPI(schar*) cvSeqPush( CvSeq* seq, const void* element CV_DEFAULT(NULL)); + + +/** Adds new element to the beginning of sequence. Returns pointer to it */ +CVAPI(schar*) cvSeqPushFront( CvSeq* seq, const void* element CV_DEFAULT(NULL)); + + +/** Removes the last element from sequence and optionally saves it */ +CVAPI(void) cvSeqPop( CvSeq* seq, void* element CV_DEFAULT(NULL)); + + +/** Removes the first element from sequence and optioanally saves it */ +CVAPI(void) cvSeqPopFront( CvSeq* seq, void* element CV_DEFAULT(NULL)); + + +#define CV_FRONT 1 +#define CV_BACK 0 +/** Adds several new elements to the end of sequence */ +CVAPI(void) cvSeqPushMulti( CvSeq* seq, const void* elements, + int count, int in_front CV_DEFAULT(0) ); + +/** Removes several elements from the end of sequence and optionally saves them */ +CVAPI(void) cvSeqPopMulti( CvSeq* seq, void* elements, + int count, int in_front CV_DEFAULT(0) ); + +/** Inserts a new element in the middle of sequence. + cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem) */ +CVAPI(schar*) cvSeqInsert( CvSeq* seq, int before_index, + const void* element CV_DEFAULT(NULL)); + +/** Removes specified sequence element */ +CVAPI(void) cvSeqRemove( CvSeq* seq, int index ); + + +/** Removes all the elements from the sequence. The freed memory + can be reused later only by the same sequence unless cvClearMemStorage + or cvRestoreMemStoragePos is called */ +CVAPI(void) cvClearSeq( CvSeq* seq ); + + +/** Retrieves pointer to specified sequence element. + Negative indices are supported and mean counting from the end + (e.g -1 means the last sequence element) */ +CVAPI(schar*) cvGetSeqElem( const CvSeq* seq, int index ); + +/** Calculates index of the specified sequence element. + Returns -1 if element does not belong to the sequence */ +CVAPI(int) cvSeqElemIdx( const CvSeq* seq, const void* element, + CvSeqBlock** block CV_DEFAULT(NULL) ); + +/** Initializes sequence writer. The new elements will be added to the end of sequence */ +CVAPI(void) cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer ); + + +/** Combination of cvCreateSeq and cvStartAppendToSeq */ +CVAPI(void) cvStartWriteSeq( int seq_flags, int header_size, + int elem_size, CvMemStorage* storage, + CvSeqWriter* writer ); + +/** Closes sequence writer, updates sequence header and returns pointer + to the resultant sequence + (which may be useful if the sequence was created using cvStartWriteSeq)) +*/ +CVAPI(CvSeq*) cvEndWriteSeq( CvSeqWriter* writer ); + + +/** Updates sequence header. May be useful to get access to some of previously + written elements via cvGetSeqElem or sequence reader */ +CVAPI(void) cvFlushSeqWriter( CvSeqWriter* writer ); + + +/** Initializes sequence reader. + The sequence can be read in forward or backward direction */ +CVAPI(void) cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, + int reverse CV_DEFAULT(0) ); + + +/** Returns current sequence reader position (currently observed sequence element) */ +CVAPI(int) cvGetSeqReaderPos( CvSeqReader* reader ); + + +/** Changes sequence reader position. It may seek to an absolute or + to relative to the current position */ +CVAPI(void) cvSetSeqReaderPos( CvSeqReader* reader, int index, + int is_relative CV_DEFAULT(0)); + +/** Copies sequence content to a continuous piece of memory */ +CVAPI(void*) cvCvtSeqToArray( const CvSeq* seq, void* elements, + CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ) ); + +/** Creates sequence header for array. + After that all the operations on sequences that do not alter the content + can be applied to the resultant sequence */ +CVAPI(CvSeq*) cvMakeSeqHeaderForArray( int seq_type, int header_size, + int elem_size, void* elements, int total, + CvSeq* seq, CvSeqBlock* block ); + +/** Extracts sequence slice (with or without copying sequence elements) */ +CVAPI(CvSeq*) cvSeqSlice( const CvSeq* seq, CvSlice slice, + CvMemStorage* storage CV_DEFAULT(NULL), + int copy_data CV_DEFAULT(0)); + +CV_INLINE CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage CV_DEFAULT(NULL)) +{ + return cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 ); +} + +/** Removes sequence slice */ +CVAPI(void) cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ); + +/** Inserts a sequence or array into another sequence */ +CVAPI(void) cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr ); + +/** a < b ? -1 : a > b ? 1 : 0 */ +typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata ); + +/** Sorts sequence in-place given element comparison function */ +CVAPI(void) cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata CV_DEFAULT(NULL) ); + +/** Finds element in a [sorted] sequence */ +CVAPI(schar*) cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func, + int is_sorted, int* elem_idx, + void* userdata CV_DEFAULT(NULL) ); + +/** Reverses order of sequence elements in-place */ +CVAPI(void) cvSeqInvert( CvSeq* seq ); + +/** Splits sequence into one or more equivalence classes using the specified criteria */ +CVAPI(int) cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, + CvSeq** labels, CvCmpFunc is_equal, void* userdata ); + +/************ Internal sequence functions ************/ +CVAPI(void) cvChangeSeqBlock( void* reader, int direction ); +CVAPI(void) cvCreateSeqBlock( CvSeqWriter* writer ); + + +/** Creates a new set */ +CVAPI(CvSet*) cvCreateSet( int set_flags, int header_size, + int elem_size, CvMemStorage* storage ); + +/** Adds new element to the set and returns pointer to it */ +CVAPI(int) cvSetAdd( CvSet* set_header, CvSetElem* elem CV_DEFAULT(NULL), + CvSetElem** inserted_elem CV_DEFAULT(NULL) ); + +/** Fast variant of cvSetAdd */ +CV_INLINE CvSetElem* cvSetNew( CvSet* set_header ) +{ + CvSetElem* elem = set_header->free_elems; + if( elem ) + { + set_header->free_elems = elem->next_free; + elem->flags = elem->flags & CV_SET_ELEM_IDX_MASK; + set_header->active_count++; + } + else + cvSetAdd( set_header, NULL, &elem ); + return elem; +} + +/** Removes set element given its pointer */ +CV_INLINE void cvSetRemoveByPtr( CvSet* set_header, void* elem ) +{ + CvSetElem* _elem = (CvSetElem*)elem; + assert( _elem->flags >= 0 /*&& (elem->flags & CV_SET_ELEM_IDX_MASK) < set_header->total*/ ); + _elem->next_free = set_header->free_elems; + _elem->flags = (_elem->flags & CV_SET_ELEM_IDX_MASK) | CV_SET_ELEM_FREE_FLAG; + set_header->free_elems = _elem; + set_header->active_count--; +} + +/** Removes element from the set by its index */ +CVAPI(void) cvSetRemove( CvSet* set_header, int index ); + +/** Returns a set element by index. If the element doesn't belong to the set, + NULL is returned */ +CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int idx ) +{ + CvSetElem* elem = (CvSetElem*)(void *)cvGetSeqElem( (CvSeq*)set_header, idx ); + return elem && CV_IS_SET_ELEM( elem ) ? elem : 0; +} + +/** Removes all the elements from the set */ +CVAPI(void) cvClearSet( CvSet* set_header ); + +/** Creates new graph */ +CVAPI(CvGraph*) cvCreateGraph( int graph_flags, int header_size, + int vtx_size, int edge_size, + CvMemStorage* storage ); + +/** Adds new vertex to the graph */ +CVAPI(int) cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx CV_DEFAULT(NULL), + CvGraphVtx** inserted_vtx CV_DEFAULT(NULL) ); + + +/** Removes vertex from the graph together with all incident edges */ +CVAPI(int) cvGraphRemoveVtx( CvGraph* graph, int index ); +CVAPI(int) cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ); + + +/** Link two vertices specified by indices or pointers if they + are not connected or return pointer to already existing edge + connecting the vertices. + Functions return 1 if a new edge was created, 0 otherwise */ +CVAPI(int) cvGraphAddEdge( CvGraph* graph, + int start_idx, int end_idx, + const CvGraphEdge* edge CV_DEFAULT(NULL), + CvGraphEdge** inserted_edge CV_DEFAULT(NULL) ); + +CVAPI(int) cvGraphAddEdgeByPtr( CvGraph* graph, + CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, + const CvGraphEdge* edge CV_DEFAULT(NULL), + CvGraphEdge** inserted_edge CV_DEFAULT(NULL) ); + +/** Remove edge connecting two vertices */ +CVAPI(void) cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ); +CVAPI(void) cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, + CvGraphVtx* end_vtx ); + +/** Find edge connecting two vertices */ +CVAPI(CvGraphEdge*) cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ); +CVAPI(CvGraphEdge*) cvFindGraphEdgeByPtr( const CvGraph* graph, + const CvGraphVtx* start_vtx, + const CvGraphVtx* end_vtx ); +#define cvGraphFindEdge cvFindGraphEdge +#define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr + +/** Remove all vertices and edges from the graph */ +CVAPI(void) cvClearGraph( CvGraph* graph ); + + +/** Count number of edges incident to the vertex */ +CVAPI(int) cvGraphVtxDegree( const CvGraph* graph, int vtx_idx ); +CVAPI(int) cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx ); + + +/** Retrieves graph vertex by given index */ +#define cvGetGraphVtx( graph, idx ) (CvGraphVtx*)cvGetSetElem((CvSet*)(graph), (idx)) + +/** Retrieves index of a graph vertex given its pointer */ +#define cvGraphVtxIdx( graph, vtx ) ((vtx)->flags & CV_SET_ELEM_IDX_MASK) + +/** Retrieves index of a graph edge given its pointer */ +#define cvGraphEdgeIdx( graph, edge ) ((edge)->flags & CV_SET_ELEM_IDX_MASK) + +#define cvGraphGetVtxCount( graph ) ((graph)->active_count) +#define cvGraphGetEdgeCount( graph ) ((graph)->edges->active_count) + +#define CV_GRAPH_VERTEX 1 +#define CV_GRAPH_TREE_EDGE 2 +#define CV_GRAPH_BACK_EDGE 4 +#define CV_GRAPH_FORWARD_EDGE 8 +#define CV_GRAPH_CROSS_EDGE 16 +#define CV_GRAPH_ANY_EDGE 30 +#define CV_GRAPH_NEW_TREE 32 +#define CV_GRAPH_BACKTRACKING 64 +#define CV_GRAPH_OVER -1 + +#define CV_GRAPH_ALL_ITEMS -1 + +/** flags for graph vertices and edges */ +#define CV_GRAPH_ITEM_VISITED_FLAG (1 << 30) +#define CV_IS_GRAPH_VERTEX_VISITED(vtx) \ + (((CvGraphVtx*)(vtx))->flags & CV_GRAPH_ITEM_VISITED_FLAG) +#define CV_IS_GRAPH_EDGE_VISITED(edge) \ + (((CvGraphEdge*)(edge))->flags & CV_GRAPH_ITEM_VISITED_FLAG) +#define CV_GRAPH_SEARCH_TREE_NODE_FLAG (1 << 29) +#define CV_GRAPH_FORWARD_EDGE_FLAG (1 << 28) + +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; + +/** Creates new graph scanner. */ +CVAPI(CvGraphScanner*) cvCreateGraphScanner( CvGraph* graph, + CvGraphVtx* vtx CV_DEFAULT(NULL), + int mask CV_DEFAULT(CV_GRAPH_ALL_ITEMS)); + +/** Releases graph scanner. */ +CVAPI(void) cvReleaseGraphScanner( CvGraphScanner** scanner ); + +/** Get next graph element */ +CVAPI(int) cvNextGraphItem( CvGraphScanner* scanner ); + +/** Creates a copy of graph */ +CVAPI(CvGraph*) cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ); + + +/** Does look-up transformation. Elements of the source array + (that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table */ +CVAPI(void) cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut ); + + +/******************* Iteration through the sequence tree *****************/ +typedef struct CvTreeNodeIterator +{ + const void* node; + int level; + int max_level; +} +CvTreeNodeIterator; + +CVAPI(void) cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator, + const void* first, int max_level ); +CVAPI(void*) cvNextTreeNode( CvTreeNodeIterator* tree_iterator ); +CVAPI(void*) cvPrevTreeNode( CvTreeNodeIterator* tree_iterator ); + +/** Inserts sequence into tree with specified "parent" sequence. + If parent is equal to frame (e.g. the most external contour), + then added contour will have null pointer to parent. */ +CVAPI(void) cvInsertNodeIntoTree( void* node, void* parent, void* frame ); + +/** Removes contour from tree (together with the contour children). */ +CVAPI(void) cvRemoveNodeFromTree( void* node, void* frame ); + +/** Gathers pointers to all the sequences, + accessible from the `first`, to the single sequence */ +CVAPI(CvSeq*) cvTreeToNodeSeq( const void* first, int header_size, + CvMemStorage* storage ); + +/** The function implements the K-means algorithm for clustering an array of sample + vectors in a specified number of classes */ +#define CV_KMEANS_USE_INITIAL_LABELS 1 +CVAPI(int) cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels, + CvTermCriteria termcrit, int attempts CV_DEFAULT(1), + CvRNG* rng CV_DEFAULT(0), int flags CV_DEFAULT(0), + CvArr* _centers CV_DEFAULT(0), double* compactness CV_DEFAULT(0) ); + +/****************************************************************************************\ +* System functions * +\****************************************************************************************/ + +/** Loads optimized functions from IPP, MKL etc. or switches back to pure C code */ +CVAPI(int) cvUseOptimized( int on_off ); + +typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader) + (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*); + +/** @brief Makes OpenCV use IPL functions for allocating IplImage and IplROI structures. + +Normally, the function is not called directly. Instead, a simple macro +CV_TURN_ON_IPL_COMPATIBILITY() is used that calls cvSetIPLAllocators and passes there pointers +to IPL allocation functions. : +@code + ... + CV_TURN_ON_IPL_COMPATIBILITY() + ... +@endcode +@param create_header pointer to a function, creating IPL image header. +@param allocate_data pointer to a function, allocating IPL image data. +@param deallocate pointer to a function, deallocating IPL image. +@param create_roi pointer to a function, creating IPL image ROI (i.e. Region of Interest). +@param clone_image pointer to a function, cloning an IPL image. + */ +CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, + Cv_iplAllocateImageData allocate_data, + Cv_iplDeallocate deallocate, + Cv_iplCreateROI create_roi, + Cv_iplCloneImage clone_image ); + +#define CV_TURN_ON_IPL_COMPATIBILITY() \ + cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage, \ + iplDeallocate, iplCreateROI, iplCloneImage ) + +/****************************************************************************************\ +* Data Persistence * +\****************************************************************************************/ + +#if 0 +/********************************** High-level functions ********************************/ + +/** @brief Opens file storage for reading or writing data. + +The function opens file storage for reading or writing data. In the latter case, a new file is +created or an existing file is rewritten. The type of the read or written file is determined by the +filename extension: .xml for XML, .yml or .yaml for YAML and .json for JSON. + +At the same time, it also supports adding parameters like "example.xml?base64". + +The function returns a pointer to the CvFileStorage structure. +If the file cannot be opened then the function returns NULL. +@param filename Name of the file associated with the storage +@param memstorage Memory storage used for temporary data and for +: storing dynamic structures, such as CvSeq or CvGraph . If it is NULL, a temporary memory + storage is created and used. +@param flags Can be one of the following: +> - **CV_STORAGE_READ** the storage is open for reading +> - **CV_STORAGE_WRITE** the storage is open for writing + (use **CV_STORAGE_WRITE | CV_STORAGE_WRITE_BASE64** to write rawdata in Base64) +@param encoding + */ +CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, + int flags, const char* encoding CV_DEFAULT(NULL) ); + +/** @brief Releases file storage. + +The function closes the file associated with the storage and releases all the temporary structures. +It must be called after all I/O operations with the storage are finished. +@param fs Double pointer to the released file storage + */ +CVAPI(void) cvReleaseFileStorage( CvFileStorage** fs ); + +/** returns attribute value or 0 (NULL) if there is no such attribute */ +CVAPI(const char*) cvAttrValue( const CvAttrList* attr, const char* attr_name ); + +/** @brief Starts writing a new structure. + +The function starts writing a compound structure (collection) that can be a sequence or a map. After +all the structure fields, which can be scalars or structures, are written, cvEndWriteStruct should +be called. The function can be used to group some objects or to implement the write function for a +some user object (see CvTypeInfo). +@param fs File storage +@param name Name of the written structure. The structure can be accessed by this name when the +storage is read. +@param struct_flags A combination one of the following values: +- **CV_NODE_SEQ** the written structure is a sequence (see discussion of CvFileStorage ), + that is, its elements do not have a name. +- **CV_NODE_MAP** the written structure is a map (see discussion of CvFileStorage ), that + is, all its elements have names. +One and only one of the two above flags must be specified +- **CV_NODE_FLOW** the optional flag that makes sense only for YAML streams. It means that + the structure is written as a flow (not as a block), which is more compact. It is + recommended to use this flag for structures or arrays whose elements are all scalars. +@param type_name Optional parameter - the object type name. In + case of XML it is written as a type_id attribute of the structure opening tag. In the case of + YAML it is written after a colon following the structure name (see the example in + CvFileStorage description). In case of JSON it is written as a name/value pair. + Mainly it is used with user objects. When the storage is read, the + encoded type name is used to determine the object type (see CvTypeInfo and cvFindType ). +@param attributes This parameter is not used in the current implementation + */ +CVAPI(void) cvStartWriteStruct( CvFileStorage* fs, const char* name, + int struct_flags, const char* type_name CV_DEFAULT(NULL), + CvAttrList attributes CV_DEFAULT(cvAttrList())); + +/** @brief Finishes writing to a file node collection. +@param fs File storage +@sa cvStartWriteStruct. + */ +CVAPI(void) cvEndWriteStruct( CvFileStorage* fs ); + +/** @brief Writes an integer value. + +The function writes a single integer value (with or without a name) to the file storage. +@param fs File storage +@param name Name of the written value. Should be NULL if and only if the parent structure is a +sequence. +@param value The written value + */ +CVAPI(void) cvWriteInt( CvFileStorage* fs, const char* name, int value ); + +/** @brief Writes a floating-point value. + +The function writes a single floating-point value (with or without a name) to file storage. Special +values are encoded as follows: NaN (Not A Number) as .NaN, infinity as +.Inf or -.Inf. + +The following example shows how to use the low-level writing functions to store custom structures, +such as termination criteria, without registering a new type. : +@code + void write_termcriteria( CvFileStorage* fs, const char* struct_name, + CvTermCriteria* termcrit ) + { + cvStartWriteStruct( fs, struct_name, CV_NODE_MAP, NULL, cvAttrList(0,0)); + cvWriteComment( fs, "termination criteria", 1 ); // just a description + if( termcrit->type & CV_TERMCRIT_ITER ) + cvWriteInteger( fs, "max_iterations", termcrit->max_iter ); + if( termcrit->type & CV_TERMCRIT_EPS ) + cvWriteReal( fs, "accuracy", termcrit->epsilon ); + cvEndWriteStruct( fs ); + } +@endcode +@param fs File storage +@param name Name of the written value. Should be NULL if and only if the parent structure is a +sequence. +@param value The written value +*/ +CVAPI(void) cvWriteReal( CvFileStorage* fs, const char* name, double value ); + +/** @brief Writes a text string. + +The function writes a text string to file storage. +@param fs File storage +@param name Name of the written string . Should be NULL if and only if the parent structure is a +sequence. +@param str The written text string +@param quote If non-zero, the written string is put in quotes, regardless of whether they are +required. Otherwise, if the flag is zero, quotes are used only when they are required (e.g. when +the string starts with a digit or contains spaces). + */ +CVAPI(void) cvWriteString( CvFileStorage* fs, const char* name, + const char* str, int quote CV_DEFAULT(0) ); + +/** @brief Writes a comment. + +The function writes a comment into file storage. The comments are skipped when the storage is read. +@param fs File storage +@param comment The written comment, single-line or multi-line +@param eol_comment If non-zero, the function tries to put the comment at the end of current line. +If the flag is zero, if the comment is multi-line, or if it does not fit at the end of the current +line, the comment starts a new line. + */ +CVAPI(void) cvWriteComment( CvFileStorage* fs, const char* comment, + int eol_comment ); + +/** @brief Writes an object to file storage. + +The function writes an object to file storage. First, the appropriate type info is found using +cvTypeOf. Then, the write method associated with the type info is called. + +Attributes are used to customize the writing procedure. The standard types support the following +attributes (all the dt attributes have the same format as in cvWriteRawData): + +-# CvSeq + - **header_dt** description of user fields of the sequence header that follow CvSeq, or + CvChain (if the sequence is a Freeman chain) or CvContour (if the sequence is a contour or + point sequence) + - **dt** description of the sequence elements. + - **recursive** if the attribute is present and is not equal to "0" or "false", the whole + tree of sequences (contours) is stored. +-# CvGraph + - **header_dt** description of user fields of the graph header that follows CvGraph; + - **vertex_dt** description of user fields of graph vertices + - **edge_dt** description of user fields of graph edges (note that the edge weight is + always written, so there is no need to specify it explicitly) + +Below is the code that creates the YAML file shown in the CvFileStorage description: +@code + #include "cxcore.h" + + int main( int argc, char** argv ) + { + CvMat* mat = cvCreateMat( 3, 3, CV_32F ); + CvFileStorage* fs = cvOpenFileStorage( "example.yml", 0, CV_STORAGE_WRITE ); + + cvSetIdentity( mat ); + cvWrite( fs, "A", mat, cvAttrList(0,0) ); + + cvReleaseFileStorage( &fs ); + cvReleaseMat( &mat ); + return 0; + } +@endcode +@param fs File storage +@param name Name of the written object. Should be NULL if and only if the parent structure is a +sequence. +@param ptr Pointer to the object +@param attributes The attributes of the object. They are specific for each particular type (see +the discussion below). + */ +CVAPI(void) cvWrite( CvFileStorage* fs, const char* name, const void* ptr, + CvAttrList attributes CV_DEFAULT(cvAttrList())); + +/** @brief Starts the next stream. + +The function finishes the currently written stream and starts the next stream. In the case of XML +the file with multiple streams looks like this: +@code{.xml} + + + + + + + ... +@endcode +The YAML file will look like this: +@code{.yaml} + %YAML 1.0 + # stream #1 data + ... + --- + # stream #2 data +@endcode +This is useful for concatenating files or for resuming the writing process. +@param fs File storage + */ +CVAPI(void) cvStartNextStream( CvFileStorage* fs ); + +/** @brief Writes multiple numbers. + +The function writes an array, whose elements consist of single or multiple numbers. The function +call can be replaced with a loop containing a few cvWriteInt and cvWriteReal calls, but a single +call is more efficient. Note that because none of the elements have a name, they should be written +to a sequence rather than a map. +@param fs File storage +@param src Pointer to the written array +@param len Number of the array elements to write +@param dt Specification of each array element, see @ref format_spec "format specification" + */ +CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src, + int len, const char* dt ); + +/** @brief Writes multiple numbers in Base64. + +If either CV_STORAGE_WRITE_BASE64 or cv::FileStorage::WRITE_BASE64 is used, +this function will be the same as cvWriteRawData. If neither, the main +difference is that it outputs a sequence in Base64 encoding rather than +in plain text. + +This function can only be used to write a sequence with a type "binary". + +@param fs File storage +@param src Pointer to the written array +@param len Number of the array elements to write +@param dt Specification of each array element, see @ref format_spec "format specification" +*/ +CVAPI(void) cvWriteRawDataBase64( CvFileStorage* fs, const void* src, + int len, const char* dt ); + +/** @brief Returns a unique pointer for a given name. + +The function returns a unique pointer for each particular file node name. This pointer can be then +passed to the cvGetFileNode function that is faster than cvGetFileNodeByName because it compares +text strings by comparing pointers rather than the strings' content. + +Consider the following example where an array of points is encoded as a sequence of 2-entry maps: +@code + points: + - { x: 10, y: 10 } + - { x: 20, y: 20 } + - { x: 30, y: 30 } + # ... +@endcode +Then, it is possible to get hashed "x" and "y" pointers to speed up decoding of the points. : +@code + #include "cxcore.h" + + int main( int argc, char** argv ) + { + CvFileStorage* fs = cvOpenFileStorage( "points.yml", 0, CV_STORAGE_READ ); + CvStringHashNode* x_key = cvGetHashedNode( fs, "x", -1, 1 ); + CvStringHashNode* y_key = cvGetHashedNode( fs, "y", -1, 1 ); + CvFileNode* points = cvGetFileNodeByName( fs, 0, "points" ); + + if( CV_NODE_IS_SEQ(points->tag) ) + { + CvSeq* seq = points->data.seq; + int i, total = seq->total; + CvSeqReader reader; + cvStartReadSeq( seq, &reader, 0 ); + for( i = 0; i < total; i++ ) + { + CvFileNode* pt = (CvFileNode*)reader.ptr; + #if 1 // faster variant + CvFileNode* xnode = cvGetFileNode( fs, pt, x_key, 0 ); + CvFileNode* ynode = cvGetFileNode( fs, pt, y_key, 0 ); + assert( xnode && CV_NODE_IS_INT(xnode->tag) && + ynode && CV_NODE_IS_INT(ynode->tag)); + int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); + int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); + #elif 1 // slower variant; does not use x_key & y_key + CvFileNode* xnode = cvGetFileNodeByName( fs, pt, "x" ); + CvFileNode* ynode = cvGetFileNodeByName( fs, pt, "y" ); + assert( xnode && CV_NODE_IS_INT(xnode->tag) && + ynode && CV_NODE_IS_INT(ynode->tag)); + int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); + int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); + #else // the slowest yet the easiest to use variant + int x = cvReadIntByName( fs, pt, "x", 0 ); + int y = cvReadIntByName( fs, pt, "y", 0 ); + #endif + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + printf(" + } + } + cvReleaseFileStorage( &fs ); + return 0; + } +@endcode +Please note that whatever method of accessing a map you are using, it is still much slower than +using plain sequences; for example, in the above example, it is more efficient to encode the points +as pairs of integers in a single numeric sequence. +@param fs File storage +@param name Literal node name +@param len Length of the name (if it is known apriori), or -1 if it needs to be calculated +@param create_missing Flag that specifies, whether an absent key should be added into the hash table +*/ +CVAPI(CvStringHashNode*) cvGetHashedKey( CvFileStorage* fs, const char* name, + int len CV_DEFAULT(-1), + int create_missing CV_DEFAULT(0)); + +/** @brief Retrieves one of the top-level nodes of the file storage. + +The function returns one of the top-level file nodes. The top-level nodes do not have a name, they +correspond to the streams that are stored one after another in the file storage. If the index is out +of range, the function returns a NULL pointer, so all the top-level nodes can be iterated by +subsequent calls to the function with stream_index=0,1,..., until the NULL pointer is returned. +This function can be used as a base for recursive traversal of the file storage. +@param fs File storage +@param stream_index Zero-based index of the stream. See cvStartNextStream . In most cases, +there is only one stream in the file; however, there can be several. + */ +CVAPI(CvFileNode*) cvGetRootFileNode( const CvFileStorage* fs, + int stream_index CV_DEFAULT(0) ); + +/** @brief Finds a node in a map or file storage. + +The function finds a file node. It is a faster version of cvGetFileNodeByName (see +cvGetHashedKey discussion). Also, the function can insert a new node, if it is not in the map yet. +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. If both map and +key are NULLs, the function returns the root file node - a map that contains top-level nodes. +@param key Unique pointer to the node name, retrieved with cvGetHashedKey +@param create_missing Flag that specifies whether an absent node should be added to the map + */ +CVAPI(CvFileNode*) cvGetFileNode( CvFileStorage* fs, CvFileNode* map, + const CvStringHashNode* key, + int create_missing CV_DEFAULT(0) ); + +/** @brief Finds a node in a map or file storage. + +The function finds a file node by name. The node is searched either in map or, if the pointer is +NULL, among the top-level file storage nodes. Using this function for maps and cvGetSeqElem (or +sequence reader) for sequences, it is possible to navigate through the file storage. To speed up +multiple queries for a certain key (e.g., in the case of an array of structures) one may use a +combination of cvGetHashedKey and cvGetFileNode. +@param fs File storage +@param map The parent map. If it is NULL, the function searches in all the top-level nodes +(streams), starting with the first one. +@param name The file node name + */ +CVAPI(CvFileNode*) cvGetFileNodeByName( const CvFileStorage* fs, + const CvFileNode* map, + const char* name ); + +/** @brief Retrieves an integer value from a file node. + +The function returns an integer that is represented by the file node. If the file node is NULL, the +default_value is returned (thus, it is convenient to call the function right after cvGetFileNode +without checking for a NULL pointer). If the file node has type CV_NODE_INT, then node-\>data.i is +returned. If the file node has type CV_NODE_REAL, then node-\>data.f is converted to an integer +and returned. Otherwise the error is reported. +@param node File node +@param default_value The value that is returned if node is NULL + */ +CV_INLINE int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) ) +{ + return !node ? default_value : + CV_NODE_IS_INT(node->tag) ? node->data.i : + CV_NODE_IS_REAL(node->tag) ? cvRound(node->data.f) : 0x7fffffff; +} + +/** @brief Finds a file node and returns its value. + +The function is a simple superposition of cvGetFileNodeByName and cvReadInt. +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param default_value The value that is returned if the file node is not found + */ +CV_INLINE int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map, + const char* name, int default_value CV_DEFAULT(0) ) +{ + return cvReadInt( cvGetFileNodeByName( fs, map, name ), default_value ); +} + +/** @brief Retrieves a floating-point value from a file node. + +The function returns a floating-point value that is represented by the file node. If the file node +is NULL, the default_value is returned (thus, it is convenient to call the function right after +cvGetFileNode without checking for a NULL pointer). If the file node has type CV_NODE_REAL , +then node-\>data.f is returned. If the file node has type CV_NODE_INT , then node-:math:\>data.f +is converted to floating-point and returned. Otherwise the result is not determined. +@param node File node +@param default_value The value that is returned if node is NULL + */ +CV_INLINE double cvReadReal( const CvFileNode* node, double default_value CV_DEFAULT(0.) ) +{ + return !node ? default_value : + CV_NODE_IS_INT(node->tag) ? (double)node->data.i : + CV_NODE_IS_REAL(node->tag) ? node->data.f : 1e300; +} + +/** @brief Finds a file node and returns its value. + +The function is a simple superposition of cvGetFileNodeByName and cvReadReal . +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param default_value The value that is returned if the file node is not found + */ +CV_INLINE double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map, + const char* name, double default_value CV_DEFAULT(0.) ) +{ + return cvReadReal( cvGetFileNodeByName( fs, map, name ), default_value ); +} + +/** @brief Retrieves a text string from a file node. + +The function returns a text string that is represented by the file node. If the file node is NULL, +the default_value is returned (thus, it is convenient to call the function right after +cvGetFileNode without checking for a NULL pointer). If the file node has type CV_NODE_STR , then +node-:math:\>data.str.ptr is returned. Otherwise the result is not determined. +@param node File node +@param default_value The value that is returned if node is NULL + */ +CV_INLINE const char* cvReadString( const CvFileNode* node, + const char* default_value CV_DEFAULT(NULL) ) +{ + return !node ? default_value : CV_NODE_IS_STRING(node->tag) ? node->data.str.ptr : 0; +} + +/** @brief Finds a file node by its name and returns its value. + +The function is a simple superposition of cvGetFileNodeByName and cvReadString . +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param default_value The value that is returned if the file node is not found + */ +CV_INLINE const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map, + const char* name, const char* default_value CV_DEFAULT(NULL) ) +{ + return cvReadString( cvGetFileNodeByName( fs, map, name ), default_value ); +} + + +/** @brief Decodes an object and returns a pointer to it. + +The function decodes a user object (creates an object in a native representation from the file +storage subtree) and returns it. The object to be decoded must be an instance of a registered type +that supports the read method (see CvTypeInfo). The type of the object is determined by the type +name that is encoded in the file. If the object is a dynamic structure, it is created either in +memory storage and passed to cvOpenFileStorage or, if a NULL pointer was passed, in temporary +memory storage, which is released when cvReleaseFileStorage is called. Otherwise, if the object is +not a dynamic structure, it is created in a heap and should be released with a specialized function +or by using the generic cvRelease. +@param fs File storage +@param node The root object node +@param attributes Unused parameter + */ +CVAPI(void*) cvRead( CvFileStorage* fs, CvFileNode* node, + CvAttrList* attributes CV_DEFAULT(NULL)); + +/** @brief Finds an object by name and decodes it. + +The function is a simple superposition of cvGetFileNodeByName and cvRead. +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param attributes Unused parameter + */ +CV_INLINE void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, + const char* name, CvAttrList* attributes CV_DEFAULT(NULL) ) +{ + return cvRead( fs, cvGetFileNodeByName( fs, map, name ), attributes ); +} + + +/** @brief Initializes the file node sequence reader. + +The function initializes the sequence reader to read data from a file node. The initialized reader +can be then passed to cvReadRawDataSlice. +@param fs File storage +@param src The file node (a sequence) to read numbers from +@param reader Pointer to the sequence reader + */ +CVAPI(void) cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, + CvSeqReader* reader ); + +/** @brief Initializes file node sequence reader. + +The function reads one or more elements from the file node, representing a sequence, to a +user-specified array. The total number of read sequence elements is a product of total and the +number of components in each array element. For example, if dt=2if, the function will read total\*3 +sequence elements. As with any sequence, some parts of the file node sequence can be skipped or read +repeatedly by repositioning the reader using cvSetSeqReaderPos. +@param fs File storage +@param reader The sequence reader. Initialize it with cvStartReadRawData . +@param count The number of elements to read +@param dst Pointer to the destination array +@param dt Specification of each array element. It has the same format as in cvWriteRawData . + */ +CVAPI(void) cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, + int count, void* dst, const char* dt ); + +/** @brief Reads multiple numbers. + +The function reads elements from a file node that represents a sequence of scalars. +@param fs File storage +@param src The file node (a sequence) to read numbers from +@param dst Pointer to the destination array +@param dt Specification of each array element. It has the same format as in cvWriteRawData . + */ +CVAPI(void) cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, + void* dst, const char* dt ); + +/** @brief Writes a file node to another file storage. + +The function writes a copy of a file node to file storage. Possible applications of the function are +merging several file storages into one and conversion between XML, YAML and JSON formats. +@param fs Destination file storage +@param new_node_name New name of the file node in the destination file storage. To keep the +existing name, use cvcvGetFileNodeName +@param node The written node +@param embed If the written node is a collection and this parameter is not zero, no extra level of +hierarchy is created. Instead, all the elements of node are written into the currently written +structure. Of course, map elements can only be embedded into another map, and sequence elements +can only be embedded into another sequence. + */ +CVAPI(void) cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, + const CvFileNode* node, int embed ); + +/** @brief Returns the name of a file node. + +The function returns the name of a file node or NULL, if the file node does not have a name or if +node is NULL. +@param node File node + */ +CVAPI(const char*) cvGetFileNodeName( const CvFileNode* node ); + +/*********************************** Adding own types ***********************************/ + +/** @brief Registers a new type. + +The function registers a new type, which is described by info . The function creates a copy of the +structure, so the user should delete it after calling the function. +@param info Type info structure + */ +CVAPI(void) cvRegisterType( const CvTypeInfo* info ); + +/** @brief Unregisters the type. + +The function unregisters a type with a specified name. If the name is unknown, it is possible to +locate the type info by an instance of the type using cvTypeOf or by iterating the type list, +starting from cvFirstType, and then calling cvUnregisterType(info-\>typeName). +@param type_name Name of an unregistered type + */ +CVAPI(void) cvUnregisterType( const char* type_name ); + +/** @brief Returns the beginning of a type list. + +The function returns the first type in the list of registered types. Navigation through the list can +be done via the prev and next fields of the CvTypeInfo structure. + */ +CVAPI(CvTypeInfo*) cvFirstType(void); + +/** @brief Finds a type by its name. + +The function finds a registered type by its name. It returns NULL if there is no type with the +specified name. +@param type_name Type name + */ +CVAPI(CvTypeInfo*) cvFindType( const char* type_name ); + +/** @brief Returns the type of an object. + +The function finds the type of a given object. It iterates through the list of registered types and +calls the is_instance function/method for every type info structure with that object until one of +them returns non-zero or until the whole list has been traversed. In the latter case, the function +returns NULL. +@param struct_ptr The object pointer + */ +CVAPI(CvTypeInfo*) cvTypeOf( const void* struct_ptr ); + +#endif + +/** @brief Releases an object. + + The function finds the type of a given object and calls release with the double pointer. + @param struct_ptr Double pointer to the object + */ +CVAPI(void) cvRelease( void** struct_ptr ); + +/** @brief Makes a clone of an object. + +The function finds the type of a given object and calls clone with the passed object. Of course, if +you know the object type, for example, struct_ptr is CvMat\*, it is faster to call the specific +function, like cvCloneMat. +@param struct_ptr The object to clone + */ +CVAPI(void*) cvClone( const void* struct_ptr ); + +/*********************************** Measuring Execution Time ***************************/ + +/** helper functions for RNG initialization and accurate time measurement: + uses internal clock counter on x86 */ +CVAPI(int64) cvGetTickCount( void ); +CVAPI(double) cvGetTickFrequency( void ); + +/*********************************** CPU capabilities ***********************************/ + +CVAPI(int) cvCheckHardwareSupport(int feature); + +/*********************************** Multi-Threading ************************************/ + +/** retrieve/set the number of threads used in OpenMP implementations */ +CVAPI(int) cvGetNumThreads( void ); +CVAPI(void) cvSetNumThreads( int threads CV_DEFAULT(0) ); +/** get index of the thread being executed */ +CVAPI(int) cvGetThreadNum( void ); + + +/********************************** Error Handling **************************************/ + +/** Get current OpenCV error status */ +CVAPI(int) cvGetErrStatus( void ); + +/** Sets error status silently */ +CVAPI(void) cvSetErrStatus( int status ); + +#define CV_ErrModeLeaf 0 /* Print error and exit program */ +#define CV_ErrModeParent 1 /* Print error and continue */ +#define CV_ErrModeSilent 2 /* Don't print and continue */ + +/** Retrieves current error processing mode */ +CVAPI(int) cvGetErrMode( void ); + +/** Sets error processing mode, returns previously used mode */ +CVAPI(int) cvSetErrMode( int mode ); + +/** Sets error status and performs some additional actions (displaying message box, + writing message to stderr, terminating application etc.) + depending on the current error mode */ +CVAPI(void) cvError( int status, const char* func_name, + const char* err_msg, const char* file_name, int line ); + +/** Retrieves textual description of the error given its code */ +CVAPI(const char*) cvErrorStr( int status ); + +/** Retrieves detailed information about the last error occurred */ +CVAPI(int) cvGetErrInfo( const char** errcode_desc, const char** description, + const char** filename, int* line ); + +/** Maps IPP error codes to the counterparts from OpenCV */ +CVAPI(int) cvErrorFromIppStatus( int ipp_status ); + +typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name, + const char* err_msg, const char* file_name, int line, void* userdata ); + +/** Assigns a new error-handling function */ +CVAPI(CvErrorCallback) cvRedirectError( CvErrorCallback error_handler, + void* userdata CV_DEFAULT(NULL), + void** prev_userdata CV_DEFAULT(NULL) ); + +/** Output nothing */ +CVAPI(int) cvNulDevReport( int status, const char* func_name, const char* err_msg, + const char* file_name, int line, void* userdata ); + +/** Output to console(fprintf(stderr,...)) */ +CVAPI(int) cvStdErrReport( int status, const char* func_name, const char* err_msg, + const char* file_name, int line, void* userdata ); + +/** Output to MessageBox(WIN32) */ +CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg, + const char* file_name, int line, void* userdata ); + +#define OPENCV_ERROR(status,func,context) \ +cvError((status),(func),(context),__FILE__,__LINE__) + +#define OPENCV_ASSERT(expr,func,context) \ +{if (! (expr)) \ +{OPENCV_ERROR(CV_StsInternal,(func),(context));}} + +#define OPENCV_CALL( Func ) \ +{ \ +Func; \ +} + + +/** CV_FUNCNAME macro defines icvFuncName constant which is used by CV_ERROR macro */ +#ifdef CV_NO_FUNC_NAMES +#define CV_FUNCNAME( Name ) +#define cvFuncName "" +#else +#define CV_FUNCNAME( Name ) \ +static char cvFuncName[] = Name +#endif + + +/** + CV_ERROR macro unconditionally raises error with passed code and message. + After raising error, control will be transferred to the exit label. + */ +#define CV_ERROR( Code, Msg ) \ +{ \ + cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \ + __CV_EXIT__; \ +} + +/** + CV_CHECK macro checks error status after CV (or IPL) + function call. If error detected, control will be transferred to the exit + label. + */ +#define CV_CHECK() \ +{ \ + if( cvGetErrStatus() < 0 ) \ + CV_ERROR( CV_StsBackTrace, "Inner function failed." ); \ +} + + +/** + CV_CALL macro calls CV (or IPL) function, checks error status and + signals a error if the function failed. Useful in "parent node" + error processing mode + */ +#define CV_CALL( Func ) \ +{ \ + Func; \ + CV_CHECK(); \ +} + + +/** Runtime assertion macro */ +#define CV_ASSERT( Condition ) \ +{ \ + if( !(Condition) ) \ + CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); \ +} + +#define __CV_BEGIN__ { +#define __CV_END__ goto exit; exit: ; } +#define __CV_EXIT__ goto exit + +/** @} core_c */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#ifdef __cplusplus + +#include "opencv2/core/utility.hpp" + +namespace cv +{ + +//! @addtogroup core_c_glue +//! @{ + +/////////////////////////////////////////// glue /////////////////////////////////////////// + +//! converts array (CvMat or IplImage) to cv::Mat +CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false, + bool allowND=true, int coiMode=0, + AutoBuffer* buf=0); + +static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0) +{ + return cvarrToMat(arr, copyData, true, coiMode); +} + + +//! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it. +CV_EXPORTS void extractImageCOI(const CvArr* arr, OutputArray coiimg, int coi=-1); +//! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage +CV_EXPORTS void insertImageCOI(InputArray coiimg, CvArr* arr, int coi=-1); + + + +////// specialized implementations of DefaultDeleter::operator() for classic OpenCV types ////// + +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(CvMat* obj) const; }; +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(IplImage* obj) const; }; +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(CvMatND* obj) const; }; +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(CvSparseMat* obj) const; }; +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(CvMemStorage* obj) const; }; + +////////////// convenient wrappers for operating old-style dynamic structures ////////////// + +template class SeqIterator; + +typedef Ptr MemStorage; + +/*! + Template Sequence Class derived from CvSeq + + The class provides more convenient access to sequence elements, + STL-style operations and iterators. + + \note The class is targeted for simple data types, + i.e. no constructors or destructors + are called for the sequence elements. +*/ +template class Seq +{ +public: + typedef SeqIterator<_Tp> iterator; + typedef SeqIterator<_Tp> const_iterator; + + //! the default constructor + Seq(); + //! the constructor for wrapping CvSeq structure. The real element type in CvSeq should match _Tp. + Seq(const CvSeq* seq); + //! creates the empty sequence that resides in the specified storage + Seq(MemStorage& storage, int headerSize = sizeof(CvSeq)); + //! returns read-write reference to the specified element + _Tp& operator [](int idx); + //! returns read-only reference to the specified element + const _Tp& operator[](int idx) const; + //! returns iterator pointing to the beginning of the sequence + SeqIterator<_Tp> begin() const; + //! returns iterator pointing to the element following the last sequence element + SeqIterator<_Tp> end() const; + //! returns the number of elements in the sequence + size_t size() const; + //! returns the type of sequence elements (CV_8UC1 ... CV_64FC(CV_CN_MAX) ...) + int type() const; + //! returns the depth of sequence elements (CV_8U ... CV_64F) + int depth() const; + //! returns the number of channels in each sequence element + int channels() const; + //! returns the size of each sequence element + size_t elemSize() const; + //! returns index of the specified sequence element + size_t index(const _Tp& elem) const; + //! appends the specified element to the end of the sequence + void push_back(const _Tp& elem); + //! appends the specified element to the front of the sequence + void push_front(const _Tp& elem); + //! appends zero or more elements to the end of the sequence + void push_back(const _Tp* elems, size_t count); + //! appends zero or more elements to the front of the sequence + void push_front(const _Tp* elems, size_t count); + //! inserts the specified element to the specified position + void insert(int idx, const _Tp& elem); + //! inserts zero or more elements to the specified position + void insert(int idx, const _Tp* elems, size_t count); + //! removes element at the specified position + void remove(int idx); + //! removes the specified subsequence + void remove(const Range& r); + + //! returns reference to the first sequence element + _Tp& front(); + //! returns read-only reference to the first sequence element + const _Tp& front() const; + //! returns reference to the last sequence element + _Tp& back(); + //! returns read-only reference to the last sequence element + const _Tp& back() const; + //! returns true iff the sequence contains no elements + bool empty() const; + + //! removes all the elements from the sequence + void clear(); + //! removes the first element from the sequence + void pop_front(); + //! removes the last element from the sequence + void pop_back(); + //! removes zero or more elements from the beginning of the sequence + void pop_front(_Tp* elems, size_t count); + //! removes zero or more elements from the end of the sequence + void pop_back(_Tp* elems, size_t count); + + //! copies the whole sequence or the sequence slice to the specified vector + void copyTo(std::vector<_Tp>& vec, const Range& range=Range::all()) const; + //! returns the vector containing all the sequence elements + operator std::vector<_Tp>() const; + + CvSeq* seq; +}; + + +/*! + STL-style Sequence Iterator inherited from the CvSeqReader structure +*/ +template class SeqIterator : public CvSeqReader +{ +public: + //! the default constructor + SeqIterator(); + //! the constructor setting the iterator to the beginning or to the end of the sequence + SeqIterator(const Seq<_Tp>& seq, bool seekEnd=false); + //! positions the iterator within the sequence + void seek(size_t pos); + //! reports the current iterator position + size_t tell() const; + //! returns reference to the current sequence element + _Tp& operator *(); + //! returns read-only reference to the current sequence element + const _Tp& operator *() const; + //! moves iterator to the next sequence element + SeqIterator& operator ++(); + //! moves iterator to the next sequence element + SeqIterator operator ++(int) const; + //! moves iterator to the previous sequence element + SeqIterator& operator --(); + //! moves iterator to the previous sequence element + SeqIterator operator --(int) const; + + //! moves iterator forward by the specified offset (possibly negative) + SeqIterator& operator +=(int); + //! moves iterator backward by the specified offset (possibly negative) + SeqIterator& operator -=(int); + + // this is index of the current element module seq->total*2 + // (to distinguish between 0 and seq->total) + int index; +}; + + + +// bridge C++ => C Seq API +CV_EXPORTS schar* seqPush( CvSeq* seq, const void* element=0); +CV_EXPORTS schar* seqPushFront( CvSeq* seq, const void* element=0); +CV_EXPORTS void seqPop( CvSeq* seq, void* element=0); +CV_EXPORTS void seqPopFront( CvSeq* seq, void* element=0); +CV_EXPORTS void seqPopMulti( CvSeq* seq, void* elements, + int count, int in_front=0 ); +CV_EXPORTS void seqRemove( CvSeq* seq, int index ); +CV_EXPORTS void clearSeq( CvSeq* seq ); +CV_EXPORTS schar* getSeqElem( const CvSeq* seq, int index ); +CV_EXPORTS void seqRemoveSlice( CvSeq* seq, CvSlice slice ); +CV_EXPORTS void seqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr ); + +template inline Seq<_Tp>::Seq() : seq(0) {} +template inline Seq<_Tp>::Seq( const CvSeq* _seq ) : seq((CvSeq*)_seq) +{ + CV_Assert(!_seq || _seq->elem_size == sizeof(_Tp)); +} + +template inline Seq<_Tp>::Seq( MemStorage& storage, + int headerSize ) +{ + CV_Assert(headerSize >= (int)sizeof(CvSeq)); + seq = cvCreateSeq(DataType<_Tp>::type, headerSize, sizeof(_Tp), storage); +} + +template inline _Tp& Seq<_Tp>::operator [](int idx) +{ return *(_Tp*)getSeqElem(seq, idx); } + +template inline const _Tp& Seq<_Tp>::operator [](int idx) const +{ return *(_Tp*)getSeqElem(seq, idx); } + +template inline SeqIterator<_Tp> Seq<_Tp>::begin() const +{ return SeqIterator<_Tp>(*this); } + +template inline SeqIterator<_Tp> Seq<_Tp>::end() const +{ return SeqIterator<_Tp>(*this, true); } + +template inline size_t Seq<_Tp>::size() const +{ return seq ? seq->total : 0; } + +template inline int Seq<_Tp>::type() const +{ return seq ? CV_MAT_TYPE(seq->flags) : 0; } + +template inline int Seq<_Tp>::depth() const +{ return seq ? CV_MAT_DEPTH(seq->flags) : 0; } + +template inline int Seq<_Tp>::channels() const +{ return seq ? CV_MAT_CN(seq->flags) : 0; } + +template inline size_t Seq<_Tp>::elemSize() const +{ return seq ? seq->elem_size : 0; } + +template inline size_t Seq<_Tp>::index(const _Tp& elem) const +{ return cvSeqElemIdx(seq, &elem); } + +template inline void Seq<_Tp>::push_back(const _Tp& elem) +{ cvSeqPush(seq, &elem); } + +template inline void Seq<_Tp>::push_front(const _Tp& elem) +{ cvSeqPushFront(seq, &elem); } + +template inline void Seq<_Tp>::push_back(const _Tp* elem, size_t count) +{ cvSeqPushMulti(seq, elem, (int)count, 0); } + +template inline void Seq<_Tp>::push_front(const _Tp* elem, size_t count) +{ cvSeqPushMulti(seq, elem, (int)count, 1); } + +template inline _Tp& Seq<_Tp>::back() +{ return *(_Tp*)getSeqElem(seq, -1); } + +template inline const _Tp& Seq<_Tp>::back() const +{ return *(const _Tp*)getSeqElem(seq, -1); } + +template inline _Tp& Seq<_Tp>::front() +{ return *(_Tp*)getSeqElem(seq, 0); } + +template inline const _Tp& Seq<_Tp>::front() const +{ return *(const _Tp*)getSeqElem(seq, 0); } + +template inline bool Seq<_Tp>::empty() const +{ return !seq || seq->total == 0; } + +template inline void Seq<_Tp>::clear() +{ if(seq) clearSeq(seq); } + +template inline void Seq<_Tp>::pop_back() +{ seqPop(seq); } + +template inline void Seq<_Tp>::pop_front() +{ seqPopFront(seq); } + +template inline void Seq<_Tp>::pop_back(_Tp* elem, size_t count) +{ seqPopMulti(seq, elem, (int)count, 0); } + +template inline void Seq<_Tp>::pop_front(_Tp* elem, size_t count) +{ seqPopMulti(seq, elem, (int)count, 1); } + +template inline void Seq<_Tp>::insert(int idx, const _Tp& elem) +{ seqInsert(seq, idx, &elem); } + +template inline void Seq<_Tp>::insert(int idx, const _Tp* elems, size_t count) +{ + CvMat m = cvMat(1, count, DataType<_Tp>::type, elems); + seqInsertSlice(seq, idx, &m); +} + +template inline void Seq<_Tp>::remove(int idx) +{ seqRemove(seq, idx); } + +template inline void Seq<_Tp>::remove(const Range& r) +{ seqRemoveSlice(seq, cvSlice(r.start, r.end)); } + +template inline void Seq<_Tp>::copyTo(std::vector<_Tp>& vec, const Range& range) const +{ + size_t len = !seq ? 0 : range == Range::all() ? seq->total : range.end - range.start; + vec.resize(len); + if( seq && len ) + cvCvtSeqToArray(seq, &vec[0], cvSlice(range)); +} + +template inline Seq<_Tp>::operator std::vector<_Tp>() const +{ + std::vector<_Tp> vec; + copyTo(vec); + return vec; +} + +template inline SeqIterator<_Tp>::SeqIterator() +{ memset(this, 0, sizeof(*this)); } + +template inline SeqIterator<_Tp>::SeqIterator(const Seq<_Tp>& _seq, bool seekEnd) +{ + cvStartReadSeq(_seq.seq, this); + index = seekEnd ? _seq.seq->total : 0; +} + +template inline void SeqIterator<_Tp>::seek(size_t pos) +{ + cvSetSeqReaderPos(this, (int)pos, false); + index = pos; +} + +template inline size_t SeqIterator<_Tp>::tell() const +{ return index; } + +template inline _Tp& SeqIterator<_Tp>::operator *() +{ return *(_Tp*)ptr; } + +template inline const _Tp& SeqIterator<_Tp>::operator *() const +{ return *(const _Tp*)ptr; } + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator ++() +{ + CV_NEXT_SEQ_ELEM(sizeof(_Tp), *this); + if( ++index >= seq->total*2 ) + index = 0; + return *this; +} + +template inline SeqIterator<_Tp> SeqIterator<_Tp>::operator ++(int) const +{ + SeqIterator<_Tp> it = *this; + ++*this; + return it; +} + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator --() +{ + CV_PREV_SEQ_ELEM(sizeof(_Tp), *this); + if( --index < 0 ) + index = seq->total*2-1; + return *this; +} + +template inline SeqIterator<_Tp> SeqIterator<_Tp>::operator --(int) const +{ + SeqIterator<_Tp> it = *this; + --*this; + return it; +} + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator +=(int delta) +{ + cvSetSeqReaderPos(this, delta, 1); + index += delta; + int n = seq->total*2; + if( index < 0 ) + index += n; + if( index >= n ) + index -= n; + return *this; +} + +template inline SeqIterator<_Tp>& SeqIterator<_Tp>::operator -=(int delta) +{ + return (*this += -delta); +} + +template inline ptrdiff_t operator - (const SeqIterator<_Tp>& a, + const SeqIterator<_Tp>& b) +{ + ptrdiff_t delta = a.index - b.index, n = a.seq->total; + if( delta > n || delta < -n ) + delta += delta < 0 ? n : -n; + return delta; +} + +template inline bool operator == (const SeqIterator<_Tp>& a, + const SeqIterator<_Tp>& b) +{ + return a.seq == b.seq && a.index == b.index; +} + +template inline bool operator != (const SeqIterator<_Tp>& a, + const SeqIterator<_Tp>& b) +{ + return !(a == b); +} + +//! @} + +} // cv + +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda.hpp new file mode 100755 index 0000000..b49e75d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda.hpp @@ -0,0 +1,1049 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_CUDA_HPP +#define OPENCV_CORE_CUDA_HPP + +#ifndef __cplusplus +# error cuda.hpp header must be compiled as C++ +#endif + +#include "opencv2/core.hpp" +#include "opencv2/core/cuda_types.hpp" + +/** + @defgroup cuda CUDA-accelerated Computer Vision + @{ + @defgroup cudacore Core part + @{ + @defgroup cudacore_init Initialization and Information + @defgroup cudacore_struct Data Structures + @} + @} + */ + +namespace cv { namespace cuda { + +//! @addtogroup cudacore_struct +//! @{ + +//=================================================================================== +// GpuMat +//=================================================================================== + +/** @brief Base storage class for GPU memory with reference counting. + +Its interface matches the Mat interface with the following limitations: + +- no arbitrary dimensions support (only 2D) +- no functions that return references to their data (because references on GPU are not valid for + CPU) +- no expression templates technique support + +Beware that the latter limitation may lead to overloaded matrix operators that cause memory +allocations. The GpuMat class is convertible to cuda::PtrStepSz and cuda::PtrStep so it can be +passed directly to the kernel. + +@note In contrast with Mat, in most cases GpuMat::isContinuous() == false . This means that rows are +aligned to a size depending on the hardware. Single-row GpuMat is always a continuous matrix. + +@note You are not recommended to leave static or global GpuMat variables allocated, that is, to rely +on its destructor. The destruction order of such variables and CUDA context is undefined. GPU memory +release function returns error if the CUDA context has been destroyed before. + +Some member functions are described as a "Blocking Call" while some are described as a +"Non-Blocking Call". Blocking functions are synchronous to host. It is guaranteed that the GPU +operation is finished when the function returns. However, non-blocking functions are asynchronous to +host. Those functions may return even if the GPU operation is not finished. + +Compared to their blocking counterpart, non-blocking functions accept Stream as an additional +argument. If a non-default stream is passed, the GPU operation may overlap with operations in other +streams. + +@sa Mat + */ +class CV_EXPORTS_W GpuMat +{ +public: + class CV_EXPORTS_W Allocator + { + public: + virtual ~Allocator() {} + + // allocator must fill data, step and refcount fields + virtual bool allocate(GpuMat* mat, int rows, int cols, size_t elemSize) = 0; + virtual void free(GpuMat* mat) = 0; + }; + + //! default allocator + CV_WRAP static GpuMat::Allocator* defaultAllocator(); + CV_WRAP static void setDefaultAllocator(GpuMat::Allocator* allocator); + + //! default constructor + CV_WRAP explicit GpuMat(GpuMat::Allocator* allocator = GpuMat::defaultAllocator()); + + //! constructs GpuMat of the specified size and type + CV_WRAP GpuMat(int rows, int cols, int type, GpuMat::Allocator* allocator = GpuMat::defaultAllocator()); + CV_WRAP GpuMat(Size size, int type, GpuMat::Allocator* allocator = GpuMat::defaultAllocator()); + + //! constucts GpuMat and fills it with the specified value _s + CV_WRAP GpuMat(int rows, int cols, int type, Scalar s, GpuMat::Allocator* allocator = GpuMat::defaultAllocator()); + CV_WRAP GpuMat(Size size, int type, Scalar s, GpuMat::Allocator* allocator = GpuMat::defaultAllocator()); + + //! copy constructor + CV_WRAP GpuMat(const GpuMat& m); + + //! constructor for GpuMat headers pointing to user-allocated data + GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP); + GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP); + + //! creates a GpuMat header for a part of the bigger matrix + CV_WRAP GpuMat(const GpuMat& m, Range rowRange, Range colRange); + CV_WRAP GpuMat(const GpuMat& m, Rect roi); + + //! builds GpuMat from host memory (Blocking call) + CV_WRAP explicit GpuMat(InputArray arr, GpuMat::Allocator* allocator = GpuMat::defaultAllocator()); + + //! destructor - calls release() + ~GpuMat(); + + //! assignment operators + GpuMat& operator =(const GpuMat& m); + + //! allocates new GpuMat data unless the GpuMat already has specified size and type + CV_WRAP void create(int rows, int cols, int type); + CV_WRAP void create(Size size, int type); + + //! decreases reference counter, deallocate the data when reference counter reaches 0 + void release(); + + //! swaps with other smart pointer + CV_WRAP void swap(GpuMat& mat); + + /** @brief Performs data upload to GpuMat (Blocking call) + + This function copies data from host memory to device memory. As being a blocking call, it is + guaranteed that the copy operation is finished when this function returns. + */ + CV_WRAP void upload(InputArray arr); + + /** @brief Performs data upload to GpuMat (Non-Blocking call) + + This function copies data from host memory to device memory. As being a non-blocking call, this + function may return even if the copy operation is not finished. + + The copy operation may be overlapped with operations in other non-default streams if \p stream is + not the default stream and \p dst is HostMem allocated with HostMem::PAGE_LOCKED option. + */ + CV_WRAP void upload(InputArray arr, Stream& stream); + + /** @brief Performs data download from GpuMat (Blocking call) + + This function copies data from device memory to host memory. As being a blocking call, it is + guaranteed that the copy operation is finished when this function returns. + */ + CV_WRAP void download(OutputArray dst) const; + + /** @brief Performs data download from GpuMat (Non-Blocking call) + + This function copies data from device memory to host memory. As being a non-blocking call, this + function may return even if the copy operation is not finished. + + The copy operation may be overlapped with operations in other non-default streams if \p stream is + not the default stream and \p dst is HostMem allocated with HostMem::PAGE_LOCKED option. + */ + CV_WRAP void download(OutputArray dst, Stream& stream) const; + + //! returns deep copy of the GpuMat, i.e. the data is copied + CV_WRAP GpuMat clone() const; + + //! copies the GpuMat content to device memory (Blocking call) + CV_WRAP void copyTo(OutputArray dst) const; + + //! copies the GpuMat content to device memory (Non-Blocking call) + CV_WRAP void copyTo(OutputArray dst, Stream& stream) const; + + //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Blocking call) + CV_WRAP void copyTo(OutputArray dst, InputArray mask) const; + + //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Non-Blocking call) + CV_WRAP void copyTo(OutputArray dst, InputArray mask, Stream& stream) const; + + //! sets some of the GpuMat elements to s (Blocking call) + CV_WRAP GpuMat& setTo(Scalar s); + + //! sets some of the GpuMat elements to s (Non-Blocking call) + CV_WRAP GpuMat& setTo(Scalar s, Stream& stream); + + //! sets some of the GpuMat elements to s, according to the mask (Blocking call) + CV_WRAP GpuMat& setTo(Scalar s, InputArray mask); + + //! sets some of the GpuMat elements to s, according to the mask (Non-Blocking call) + CV_WRAP GpuMat& setTo(Scalar s, InputArray mask, Stream& stream); + + //! converts GpuMat to another datatype (Blocking call) + CV_WRAP void convertTo(OutputArray dst, int rtype) const; + + //! converts GpuMat to another datatype (Non-Blocking call) + CV_WRAP void convertTo(OutputArray dst, int rtype, Stream& stream) const; + + //! converts GpuMat to another datatype with scaling (Blocking call) + CV_WRAP void convertTo(OutputArray dst, int rtype, double alpha, double beta = 0.0) const; + + //! converts GpuMat to another datatype with scaling (Non-Blocking call) + CV_WRAP void convertTo(OutputArray dst, int rtype, double alpha, Stream& stream) const; + + //! converts GpuMat to another datatype with scaling (Non-Blocking call) + CV_WRAP void convertTo(OutputArray dst, int rtype, double alpha, double beta, Stream& stream) const; + + CV_WRAP void assignTo(GpuMat& m, int type = -1) const; + + //! returns pointer to y-th row + uchar* ptr(int y = 0); + const uchar* ptr(int y = 0) const; + + //! template version of the above method + template _Tp* ptr(int y = 0); + template const _Tp* ptr(int y = 0) const; + + template operator PtrStepSz<_Tp>() const; + template operator PtrStep<_Tp>() const; + + //! returns a new GpuMat header for the specified row + CV_WRAP GpuMat row(int y) const; + + //! returns a new GpuMat header for the specified column + CV_WRAP GpuMat col(int x) const; + + //! ... for the specified row span + CV_WRAP GpuMat rowRange(int startrow, int endrow) const; + CV_WRAP GpuMat rowRange(Range r) const; + + //! ... for the specified column span + CV_WRAP GpuMat colRange(int startcol, int endcol) const; + CV_WRAP GpuMat colRange(Range r) const; + + //! extracts a rectangular sub-GpuMat (this is a generalized form of row, rowRange etc.) + GpuMat operator ()(Range rowRange, Range colRange) const; + GpuMat operator ()(Rect roi) const; + + //! creates alternative GpuMat header for the same data, with different + //! number of channels and/or different number of rows + CV_WRAP GpuMat reshape(int cn, int rows = 0) const; + + //! locates GpuMat header within a parent GpuMat + CV_WRAP void locateROI(Size& wholeSize, Point& ofs) const; + + //! moves/resizes the current GpuMat ROI inside the parent GpuMat + CV_WRAP GpuMat& adjustROI(int dtop, int dbottom, int dleft, int dright); + + //! returns true iff the GpuMat data is continuous + //! (i.e. when there are no gaps between successive rows) + CV_WRAP bool isContinuous() const; + + //! returns element size in bytes + CV_WRAP size_t elemSize() const; + + //! returns the size of element channel in bytes + CV_WRAP size_t elemSize1() const; + + //! returns element type + CV_WRAP int type() const; + + //! returns element type + CV_WRAP int depth() const; + + //! returns number of channels + CV_WRAP int channels() const; + + //! returns step/elemSize1() + CV_WRAP size_t step1() const; + + //! returns GpuMat size : width == number of columns, height == number of rows + CV_WRAP Size size() const; + + //! returns true if GpuMat data is NULL + CV_WRAP bool empty() const; + + //! internal use method: updates the continuity flag + CV_WRAP void updateContinuityFlag(); + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + + //! the number of rows and columns + int rows, cols; + + //! a distance between successive rows in bytes; includes the gap if any + CV_PROP size_t step; + + //! pointer to the data + uchar* data; + + //! pointer to the reference counter; + //! when GpuMat points to user-allocated data, the pointer is NULL + int* refcount; + + //! helper fields used in locateROI and adjustROI + uchar* datastart; + const uchar* dataend; + + //! allocator + Allocator* allocator; +}; + +/** @brief Creates a continuous matrix. + +@param rows Row count. +@param cols Column count. +@param type Type of the matrix. +@param arr Destination matrix. This parameter changes only if it has a proper type and area ( +\f$\texttt{rows} \times \texttt{cols}\f$ ). + +Matrix is called continuous if its elements are stored continuously, that is, without gaps at the +end of each row. + */ +CV_EXPORTS_W void createContinuous(int rows, int cols, int type, OutputArray arr); + +/** @brief Ensures that the size of a matrix is big enough and the matrix has a proper type. + +@param rows Minimum desired number of rows. +@param cols Minimum desired number of columns. +@param type Desired matrix type. +@param arr Destination matrix. + +The function does not reallocate memory if the matrix has proper attributes already. + */ +CV_EXPORTS_W void ensureSizeIsEnough(int rows, int cols, int type, OutputArray arr); + +/** @brief BufferPool for use with CUDA streams + +BufferPool utilizes Stream's allocator to create new buffers for GpuMat's. It is +only useful when enabled with #setBufferPoolUsage. + +@code + setBufferPoolUsage(true); +@endcode + +@note #setBufferPoolUsage must be called \em before any Stream declaration. + +Users may specify custom allocator for Stream and may implement their own stream based +functions utilizing the same underlying GPU memory management. + +If custom allocator is not specified, BufferPool utilizes StackAllocator by +default. StackAllocator allocates a chunk of GPU device memory beforehand, +and when GpuMat is declared later on, it is given the pre-allocated memory. +This kind of strategy reduces the number of calls for memory allocating APIs +such as cudaMalloc or cudaMallocPitch. + +Below is an example that utilizes BufferPool with StackAllocator: + +@code + #include + + using namespace cv; + using namespace cv::cuda + + int main() + { + setBufferPoolUsage(true); // Tell OpenCV that we are going to utilize BufferPool + setBufferPoolConfig(getDevice(), 1024 * 1024 * 64, 2); // Allocate 64 MB, 2 stacks (default is 10 MB, 5 stacks) + + Stream stream1, stream2; // Each stream uses 1 stack + BufferPool pool1(stream1), pool2(stream2); + + GpuMat d_src1 = pool1.getBuffer(4096, 4096, CV_8UC1); // 16MB + GpuMat d_dst1 = pool1.getBuffer(4096, 4096, CV_8UC3); // 48MB, pool1 is now full + + GpuMat d_src2 = pool2.getBuffer(1024, 1024, CV_8UC1); // 1MB + GpuMat d_dst2 = pool2.getBuffer(1024, 1024, CV_8UC3); // 3MB + + cvtColor(d_src1, d_dst1, CV_GRAY2BGR, 0, stream1); + cvtColor(d_src2, d_dst2, CV_GRAY2BGR, 0, stream2); + } +@endcode + +If we allocate another GpuMat on pool1 in the above example, it will be carried out by +the DefaultAllocator since the stack for pool1 is full. + +@code + GpuMat d_add1 = pool1.getBuffer(1024, 1024, CV_8UC1); // Stack for pool1 is full, memory is allocated with DefaultAllocator +@endcode + +If a third stream is declared in the above example, allocating with #getBuffer +within that stream will also be carried out by the DefaultAllocator because we've run out of +stacks. + +@code + Stream stream3; // Only 2 stacks were allocated, we've run out of stacks + BufferPool pool3(stream3); + GpuMat d_src3 = pool3.getBuffer(1024, 1024, CV_8UC1); // Memory is allocated with DefaultAllocator +@endcode + +@warning When utilizing StackAllocator, deallocation order is important. + +Just like a stack, deallocation must be done in LIFO order. Below is an example of +erroneous usage that violates LIFO rule. If OpenCV is compiled in Debug mode, this +sample code will emit CV_Assert error. + +@code + int main() + { + setBufferPoolUsage(true); // Tell OpenCV that we are going to utilize BufferPool + Stream stream; // A default size (10 MB) stack is allocated to this stream + BufferPool pool(stream); + + GpuMat mat1 = pool.getBuffer(1024, 1024, CV_8UC1); // Allocate mat1 (1MB) + GpuMat mat2 = pool.getBuffer(1024, 1024, CV_8UC1); // Allocate mat2 (1MB) + + mat1.release(); // erroneous usage : mat2 must be deallocated before mat1 + } +@endcode + +Since C++ local variables are destroyed in the reverse order of construction, +the code sample below satisfies the LIFO rule. Local GpuMat's are deallocated +and the corresponding memory is automatically returned to the pool for later usage. + +@code + int main() + { + setBufferPoolUsage(true); // Tell OpenCV that we are going to utilize BufferPool + setBufferPoolConfig(getDevice(), 1024 * 1024 * 64, 2); // Allocate 64 MB, 2 stacks (default is 10 MB, 5 stacks) + + Stream stream1, stream2; // Each stream uses 1 stack + BufferPool pool1(stream1), pool2(stream2); + + for (int i = 0; i < 10; i++) + { + GpuMat d_src1 = pool1.getBuffer(4096, 4096, CV_8UC1); // 16MB + GpuMat d_dst1 = pool1.getBuffer(4096, 4096, CV_8UC3); // 48MB, pool1 is now full + + GpuMat d_src2 = pool2.getBuffer(1024, 1024, CV_8UC1); // 1MB + GpuMat d_dst2 = pool2.getBuffer(1024, 1024, CV_8UC3); // 3MB + + d_src1.setTo(Scalar(i), stream1); + d_src2.setTo(Scalar(i), stream2); + + cvtColor(d_src1, d_dst1, CV_GRAY2BGR, 0, stream1); + cvtColor(d_src2, d_dst2, CV_GRAY2BGR, 0, stream2); + // The order of destruction of the local variables is: + // d_dst2 => d_src2 => d_dst1 => d_src1 + // LIFO rule is satisfied, this code runs without error + } + } +@endcode + */ +class CV_EXPORTS_W BufferPool +{ +public: + + //! Gets the BufferPool for the given stream. + explicit BufferPool(Stream& stream); + + //! Allocates a new GpuMat of given size and type. + CV_WRAP GpuMat getBuffer(int rows, int cols, int type); + + //! Allocates a new GpuMat of given size and type. + CV_WRAP GpuMat getBuffer(Size size, int type) { return getBuffer(size.height, size.width, type); } + + //! Returns the allocator associated with the stream. + CV_WRAP Ptr getAllocator() const { return allocator_; } + +private: + Ptr allocator_; +}; + +//! BufferPool management (must be called before Stream creation) +CV_EXPORTS_W void setBufferPoolUsage(bool on); +CV_EXPORTS_W void setBufferPoolConfig(int deviceId, size_t stackSize, int stackCount); + +//=================================================================================== +// HostMem +//=================================================================================== + +/** @brief Class with reference counting wrapping special memory type allocation functions from CUDA. + +Its interface is also Mat-like but with additional memory type parameters. + +- **PAGE_LOCKED** sets a page locked memory type used commonly for fast and asynchronous + uploading/downloading data from/to GPU. +- **SHARED** specifies a zero copy memory allocation that enables mapping the host memory to GPU + address space, if supported. +- **WRITE_COMBINED** sets the write combined buffer that is not cached by CPU. Such buffers are + used to supply GPU with data when GPU only reads it. The advantage is a better CPU cache + utilization. + +@note Allocation size of such memory types is usually limited. For more details, see *CUDA 2.2 +Pinned Memory APIs* document or *CUDA C Programming Guide*. + */ +class CV_EXPORTS_W HostMem +{ +public: + enum AllocType { PAGE_LOCKED = 1, SHARED = 2, WRITE_COMBINED = 4 }; + + static MatAllocator* getAllocator(HostMem::AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED); + + CV_WRAP explicit HostMem(HostMem::AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED); + + HostMem(const HostMem& m); + + CV_WRAP HostMem(int rows, int cols, int type, HostMem::AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED); + CV_WRAP HostMem(Size size, int type, HostMem::AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED); + + //! creates from host memory with coping data + CV_WRAP explicit HostMem(InputArray arr, HostMem::AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED); + + ~HostMem(); + + HostMem& operator =(const HostMem& m); + + //! swaps with other smart pointer + CV_WRAP void swap(HostMem& b); + + //! returns deep copy of the matrix, i.e. the data is copied + CV_WRAP HostMem clone() const; + + //! allocates new matrix data unless the matrix already has specified size and type. + CV_WRAP void create(int rows, int cols, int type); + void create(Size size, int type); + + //! creates alternative HostMem header for the same data, with different + //! number of channels and/or different number of rows + CV_WRAP HostMem reshape(int cn, int rows = 0) const; + + //! decrements reference counter and released memory if needed. + void release(); + + //! returns matrix header with disabled reference counting for HostMem data. + CV_WRAP Mat createMatHeader() const; + + /** @brief Maps CPU memory to GPU address space and creates the cuda::GpuMat header without reference counting + for it. + + This can be done only if memory was allocated with the SHARED flag and if it is supported by the + hardware. Laptops often share video and CPU memory, so address spaces can be mapped, which + eliminates an extra copy. + */ + GpuMat createGpuMatHeader() const; + + // Please see cv::Mat for descriptions + CV_WRAP bool isContinuous() const; + CV_WRAP size_t elemSize() const; + CV_WRAP size_t elemSize1() const; + CV_WRAP int type() const; + CV_WRAP int depth() const; + CV_WRAP int channels() const; + CV_WRAP size_t step1() const; + CV_WRAP Size size() const; + CV_WRAP bool empty() const; + + // Please see cv::Mat for descriptions + int flags; + int rows, cols; + CV_PROP size_t step; + + uchar* data; + int* refcount; + + uchar* datastart; + const uchar* dataend; + + AllocType alloc_type; +}; + +/** @brief Page-locks the memory of matrix and maps it for the device(s). + +@param m Input matrix. + */ +CV_EXPORTS_W void registerPageLocked(Mat& m); + +/** @brief Unmaps the memory of matrix and makes it pageable again. + +@param m Input matrix. + */ +CV_EXPORTS_W void unregisterPageLocked(Mat& m); + +//=================================================================================== +// Stream +//=================================================================================== + +/** @brief This class encapsulates a queue of asynchronous calls. + +@note Currently, you may face problems if an operation is enqueued twice with different data. Some +functions use the constant GPU memory, and next call may update the memory before the previous one +has been finished. But calling different operations asynchronously is safe because each operation +has its own constant buffer. Memory copy/upload/download/set operations to the buffers you hold are +also safe. + +@note The Stream class is not thread-safe. Please use different Stream objects for different CPU threads. + +@code +void thread1() +{ + cv::cuda::Stream stream1; + cv::cuda::func1(..., stream1); +} + +void thread2() +{ + cv::cuda::Stream stream2; + cv::cuda::func2(..., stream2); +} +@endcode + +@note By default all CUDA routines are launched in Stream::Null() object, if the stream is not specified by user. +In multi-threading environment the stream objects must be passed explicitly (see previous note). + */ +class CV_EXPORTS_W Stream +{ + typedef void (Stream::*bool_type)() const; + void this_type_does_not_support_comparisons() const {} + +public: + typedef void (*StreamCallback)(int status, void* userData); + + //! creates a new asynchronous stream + CV_WRAP Stream(); + + //! creates a new asynchronous stream with custom allocator + CV_WRAP Stream(const Ptr& allocator); + + /** @brief Returns true if the current stream queue is finished. Otherwise, it returns false. + */ + CV_WRAP bool queryIfComplete() const; + + /** @brief Blocks the current CPU thread until all operations in the stream are complete. + */ + CV_WRAP void waitForCompletion(); + + /** @brief Makes a compute stream wait on an event. + */ + CV_WRAP void waitEvent(const Event& event); + + /** @brief Adds a callback to be called on the host after all currently enqueued items in the stream have + completed. + + @note Callbacks must not make any CUDA API calls. Callbacks must not perform any synchronization + that may depend on outstanding device work or other callbacks that are not mandated to run earlier. + Callbacks without a mandated order (in independent streams) execute in undefined order and may be + serialized. + */ + void enqueueHostCallback(StreamCallback callback, void* userData); + + //! return Stream object for default CUDA stream + CV_WRAP static Stream& Null(); + + //! returns true if stream object is not default (!= 0) + operator bool_type() const; + + class Impl; + +private: + Ptr impl_; + Stream(const Ptr& impl); + + friend struct StreamAccessor; + friend class BufferPool; + friend class DefaultDeviceInitializer; +}; + +class CV_EXPORTS_W Event +{ +public: + enum CreateFlags + { + DEFAULT = 0x00, /**< Default event flag */ + BLOCKING_SYNC = 0x01, /**< Event uses blocking synchronization */ + DISABLE_TIMING = 0x02, /**< Event will not record timing data */ + INTERPROCESS = 0x04 /**< Event is suitable for interprocess use. DisableTiming must be set */ + }; + + CV_WRAP explicit Event(Event::CreateFlags flags = Event::CreateFlags::DEFAULT); + + //! records an event + CV_WRAP void record(Stream& stream = Stream::Null()); + + //! queries an event's status + CV_WRAP bool queryIfComplete() const; + + //! waits for an event to complete + CV_WRAP void waitForCompletion(); + + //! computes the elapsed time between events + CV_WRAP static float elapsedTime(const Event& start, const Event& end); + + class Impl; + +private: + Ptr impl_; + Event(const Ptr& impl); + + friend struct EventAccessor; +}; + +//! @} cudacore_struct + +//=================================================================================== +// Initialization & Info +//=================================================================================== + +//! @addtogroup cudacore_init +//! @{ + +/** @brief Returns the number of installed CUDA-enabled devices. + +Use this function before any other CUDA functions calls. If OpenCV is compiled without CUDA support, +this function returns 0. If the CUDA driver is not installed, or is incompatible, this function +returns -1. + */ +CV_EXPORTS_W int getCudaEnabledDeviceCount(); + +/** @brief Sets a device and initializes it for the current thread. + +@param device System index of a CUDA device starting with 0. + +If the call of this function is omitted, a default device is initialized at the fist CUDA usage. + */ +CV_EXPORTS_W void setDevice(int device); + +/** @brief Returns the current device index set by cuda::setDevice or initialized by default. + */ +CV_EXPORTS_W int getDevice(); + +/** @brief Explicitly destroys and cleans up all resources associated with the current device in the current +process. + +Any subsequent API call to this device will reinitialize the device. + */ +CV_EXPORTS_W void resetDevice(); + +/** @brief Enumeration providing CUDA computing features. + */ +enum FeatureSet +{ + FEATURE_SET_COMPUTE_10 = 10, + FEATURE_SET_COMPUTE_11 = 11, + FEATURE_SET_COMPUTE_12 = 12, + FEATURE_SET_COMPUTE_13 = 13, + FEATURE_SET_COMPUTE_20 = 20, + FEATURE_SET_COMPUTE_21 = 21, + FEATURE_SET_COMPUTE_30 = 30, + FEATURE_SET_COMPUTE_32 = 32, + FEATURE_SET_COMPUTE_35 = 35, + FEATURE_SET_COMPUTE_50 = 50, + + GLOBAL_ATOMICS = FEATURE_SET_COMPUTE_11, + SHARED_ATOMICS = FEATURE_SET_COMPUTE_12, + NATIVE_DOUBLE = FEATURE_SET_COMPUTE_13, + WARP_SHUFFLE_FUNCTIONS = FEATURE_SET_COMPUTE_30, + DYNAMIC_PARALLELISM = FEATURE_SET_COMPUTE_35 +}; + +//! checks whether current device supports the given feature +CV_EXPORTS bool deviceSupports(FeatureSet feature_set); + +/** @brief Class providing a set of static methods to check what NVIDIA\* card architecture the CUDA module was +built for. + +According to the CUDA C Programming Guide Version 3.2: "PTX code produced for some specific compute +capability can always be compiled to binary code of greater or equal compute capability". + */ +class CV_EXPORTS_W TargetArchs +{ +public: + /** @brief The following method checks whether the module was built with the support of the given feature: + + @param feature_set Features to be checked. See :ocvcuda::FeatureSet. + */ + static bool builtWith(FeatureSet feature_set); + + /** @brief There is a set of methods to check whether the module contains intermediate (PTX) or binary CUDA + code for the given architecture(s): + + @param major Major compute capability version. + @param minor Minor compute capability version. + */ + CV_WRAP static bool has(int major, int minor); + CV_WRAP static bool hasPtx(int major, int minor); + CV_WRAP static bool hasBin(int major, int minor); + + CV_WRAP static bool hasEqualOrLessPtx(int major, int minor); + CV_WRAP static bool hasEqualOrGreater(int major, int minor); + CV_WRAP static bool hasEqualOrGreaterPtx(int major, int minor); + CV_WRAP static bool hasEqualOrGreaterBin(int major, int minor); +}; + +/** @brief Class providing functionality for querying the specified GPU properties. + */ +class CV_EXPORTS_W DeviceInfo +{ +public: + //! creates DeviceInfo object for the current GPU + CV_WRAP DeviceInfo(); + + /** @brief The constructors. + + @param device_id System index of the CUDA device starting with 0. + + Constructs the DeviceInfo object for the specified device. If device_id parameter is missed, it + constructs an object for the current device. + */ + CV_WRAP DeviceInfo(int device_id); + + /** @brief Returns system index of the CUDA device starting with 0. + */ + CV_WRAP int deviceID() const; + + //! ASCII string identifying device + const char* name() const; + + //! global memory available on device in bytes + CV_WRAP size_t totalGlobalMem() const; + + //! shared memory available per block in bytes + CV_WRAP size_t sharedMemPerBlock() const; + + //! 32-bit registers available per block + CV_WRAP int regsPerBlock() const; + + //! warp size in threads + CV_WRAP int warpSize() const; + + //! maximum pitch in bytes allowed by memory copies + CV_WRAP size_t memPitch() const; + + //! maximum number of threads per block + CV_WRAP int maxThreadsPerBlock() const; + + //! maximum size of each dimension of a block + CV_WRAP Vec3i maxThreadsDim() const; + + //! maximum size of each dimension of a grid + CV_WRAP Vec3i maxGridSize() const; + + //! clock frequency in kilohertz + CV_WRAP int clockRate() const; + + //! constant memory available on device in bytes + CV_WRAP size_t totalConstMem() const; + + //! major compute capability + CV_WRAP int majorVersion() const; + + //! minor compute capability + CV_WRAP int minorVersion() const; + + //! alignment requirement for textures + CV_WRAP size_t textureAlignment() const; + + //! pitch alignment requirement for texture references bound to pitched memory + CV_WRAP size_t texturePitchAlignment() const; + + //! number of multiprocessors on device + CV_WRAP int multiProcessorCount() const; + + //! specified whether there is a run time limit on kernels + CV_WRAP bool kernelExecTimeoutEnabled() const; + + //! device is integrated as opposed to discrete + CV_WRAP bool integrated() const; + + //! device can map host memory with cudaHostAlloc/cudaHostGetDevicePointer + CV_WRAP bool canMapHostMemory() const; + + enum ComputeMode + { + ComputeModeDefault, /**< default compute mode (Multiple threads can use cudaSetDevice with this device) */ + ComputeModeExclusive, /**< compute-exclusive-thread mode (Only one thread in one process will be able to use cudaSetDevice with this device) */ + ComputeModeProhibited, /**< compute-prohibited mode (No threads can use cudaSetDevice with this device) */ + ComputeModeExclusiveProcess /**< compute-exclusive-process mode (Many threads in one process will be able to use cudaSetDevice with this device) */ + }; + + //! compute mode + CV_WRAP DeviceInfo::ComputeMode computeMode() const; + + //! maximum 1D texture size + CV_WRAP int maxTexture1D() const; + + //! maximum 1D mipmapped texture size + CV_WRAP int maxTexture1DMipmap() const; + + //! maximum size for 1D textures bound to linear memory + CV_WRAP int maxTexture1DLinear() const; + + //! maximum 2D texture dimensions + CV_WRAP Vec2i maxTexture2D() const; + + //! maximum 2D mipmapped texture dimensions + CV_WRAP Vec2i maxTexture2DMipmap() const; + + //! maximum dimensions (width, height, pitch) for 2D textures bound to pitched memory + CV_WRAP Vec3i maxTexture2DLinear() const; + + //! maximum 2D texture dimensions if texture gather operations have to be performed + CV_WRAP Vec2i maxTexture2DGather() const; + + //! maximum 3D texture dimensions + CV_WRAP Vec3i maxTexture3D() const; + + //! maximum Cubemap texture dimensions + CV_WRAP int maxTextureCubemap() const; + + //! maximum 1D layered texture dimensions + CV_WRAP Vec2i maxTexture1DLayered() const; + + //! maximum 2D layered texture dimensions + CV_WRAP Vec3i maxTexture2DLayered() const; + + //! maximum Cubemap layered texture dimensions + CV_WRAP Vec2i maxTextureCubemapLayered() const; + + //! maximum 1D surface size + CV_WRAP int maxSurface1D() const; + + //! maximum 2D surface dimensions + CV_WRAP Vec2i maxSurface2D() const; + + //! maximum 3D surface dimensions + CV_WRAP Vec3i maxSurface3D() const; + + //! maximum 1D layered surface dimensions + CV_WRAP Vec2i maxSurface1DLayered() const; + + //! maximum 2D layered surface dimensions + CV_WRAP Vec3i maxSurface2DLayered() const; + + //! maximum Cubemap surface dimensions + CV_WRAP int maxSurfaceCubemap() const; + + //! maximum Cubemap layered surface dimensions + CV_WRAP Vec2i maxSurfaceCubemapLayered() const; + + //! alignment requirements for surfaces + CV_WRAP size_t surfaceAlignment() const; + + //! device can possibly execute multiple kernels concurrently + CV_WRAP bool concurrentKernels() const; + + //! device has ECC support enabled + CV_WRAP bool ECCEnabled() const; + + //! PCI bus ID of the device + CV_WRAP int pciBusID() const; + + //! PCI device ID of the device + CV_WRAP int pciDeviceID() const; + + //! PCI domain ID of the device + CV_WRAP int pciDomainID() const; + + //! true if device is a Tesla device using TCC driver, false otherwise + CV_WRAP bool tccDriver() const; + + //! number of asynchronous engines + CV_WRAP int asyncEngineCount() const; + + //! device shares a unified address space with the host + CV_WRAP bool unifiedAddressing() const; + + //! peak memory clock frequency in kilohertz + CV_WRAP int memoryClockRate() const; + + //! global memory bus width in bits + CV_WRAP int memoryBusWidth() const; + + //! size of L2 cache in bytes + CV_WRAP int l2CacheSize() const; + + //! maximum resident threads per multiprocessor + CV_WRAP int maxThreadsPerMultiProcessor() const; + + //! gets free and total device memory + CV_WRAP void queryMemory(size_t& totalMemory, size_t& freeMemory) const; + CV_WRAP size_t freeMemory() const; + CV_WRAP size_t totalMemory() const; + + /** @brief Provides information on CUDA feature support. + + @param feature_set Features to be checked. See cuda::FeatureSet. + + This function returns true if the device has the specified CUDA feature. Otherwise, it returns false + */ + bool supports(FeatureSet feature_set) const; + + /** @brief Checks the CUDA module and device compatibility. + + This function returns true if the CUDA module can be run on the specified device. Otherwise, it + returns false . + */ + CV_WRAP bool isCompatible() const; + +private: + int device_id_; +}; + +CV_EXPORTS_W void printCudaDeviceInfo(int device); +CV_EXPORTS_W void printShortCudaDeviceInfo(int device); + +/** @brief Converts an array to half precision floating number. + +@param _src input array. +@param _dst output array. +@param stream Stream for the asynchronous version. +@sa convertFp16 +*/ +CV_EXPORTS void convertFp16(InputArray _src, OutputArray _dst, Stream& stream = Stream::Null()); + +//! @} cudacore_init + +}} // namespace cv { namespace cuda { + + +#include "opencv2/core/cuda.inl.hpp" + +#endif /* OPENCV_CORE_CUDA_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda.inl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda.inl.hpp new file mode 100755 index 0000000..35ae2e4 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda.inl.hpp @@ -0,0 +1,631 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_CUDAINL_HPP +#define OPENCV_CORE_CUDAINL_HPP + +#include "opencv2/core/cuda.hpp" + +//! @cond IGNORED + +namespace cv { namespace cuda { + +//=================================================================================== +// GpuMat +//=================================================================================== + +inline +GpuMat::GpuMat(Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_) +{} + +inline +GpuMat::GpuMat(int rows_, int cols_, int type_, Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_) +{ + if (rows_ > 0 && cols_ > 0) + create(rows_, cols_, type_); +} + +inline +GpuMat::GpuMat(Size size_, int type_, Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_) +{ + if (size_.height > 0 && size_.width > 0) + create(size_.height, size_.width, type_); +} + +inline +GpuMat::GpuMat(int rows_, int cols_, int type_, Scalar s_, Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_) +{ + if (rows_ > 0 && cols_ > 0) + { + create(rows_, cols_, type_); + setTo(s_); + } +} + +inline +GpuMat::GpuMat(Size size_, int type_, Scalar s_, Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_) +{ + if (size_.height > 0 && size_.width > 0) + { + create(size_.height, size_.width, type_); + setTo(s_); + } +} + +inline +GpuMat::GpuMat(const GpuMat& m) + : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), refcount(m.refcount), datastart(m.datastart), dataend(m.dataend), allocator(m.allocator) +{ + if (refcount) + CV_XADD(refcount, 1); +} + +inline +GpuMat::GpuMat(InputArray arr, Allocator* allocator_) : + flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), allocator(allocator_) +{ + upload(arr); +} + +inline +GpuMat::~GpuMat() +{ + release(); +} + +inline +GpuMat& GpuMat::operator =(const GpuMat& m) +{ + if (this != &m) + { + GpuMat temp(m); + swap(temp); + } + + return *this; +} + +inline +void GpuMat::create(Size size_, int type_) +{ + create(size_.height, size_.width, type_); +} + +inline +void GpuMat::swap(GpuMat& b) +{ + std::swap(flags, b.flags); + std::swap(rows, b.rows); + std::swap(cols, b.cols); + std::swap(step, b.step); + std::swap(data, b.data); + std::swap(datastart, b.datastart); + std::swap(dataend, b.dataend); + std::swap(refcount, b.refcount); + std::swap(allocator, b.allocator); +} + +inline +GpuMat GpuMat::clone() const +{ + GpuMat m; + copyTo(m); + return m; +} + +inline +void GpuMat::copyTo(OutputArray dst, InputArray mask) const +{ + copyTo(dst, mask, Stream::Null()); +} + +inline +GpuMat& GpuMat::setTo(Scalar s) +{ + return setTo(s, Stream::Null()); +} + +inline +GpuMat& GpuMat::setTo(Scalar s, InputArray mask) +{ + return setTo(s, mask, Stream::Null()); +} + +inline +void GpuMat::convertTo(OutputArray dst, int rtype) const +{ + convertTo(dst, rtype, Stream::Null()); +} + +inline +void GpuMat::convertTo(OutputArray dst, int rtype, double alpha, double beta) const +{ + convertTo(dst, rtype, alpha, beta, Stream::Null()); +} + +inline +void GpuMat::convertTo(OutputArray dst, int rtype, double alpha, Stream& stream) const +{ + convertTo(dst, rtype, alpha, 0.0, stream); +} + +inline +void GpuMat::assignTo(GpuMat& m, int _type) const +{ + if (_type < 0) + m = *this; + else + convertTo(m, _type); +} + +inline +uchar* GpuMat::ptr(int y) +{ + CV_DbgAssert( (unsigned)y < (unsigned)rows ); + return data + step * y; +} + +inline +const uchar* GpuMat::ptr(int y) const +{ + CV_DbgAssert( (unsigned)y < (unsigned)rows ); + return data + step * y; +} + +template inline +_Tp* GpuMat::ptr(int y) +{ + return (_Tp*)ptr(y); +} + +template inline +const _Tp* GpuMat::ptr(int y) const +{ + return (const _Tp*)ptr(y); +} + +template inline +GpuMat::operator PtrStepSz() const +{ + return PtrStepSz(rows, cols, (T*)data, step); +} + +template inline +GpuMat::operator PtrStep() const +{ + return PtrStep((T*)data, step); +} + +inline +GpuMat GpuMat::row(int y) const +{ + return GpuMat(*this, Range(y, y+1), Range::all()); +} + +inline +GpuMat GpuMat::col(int x) const +{ + return GpuMat(*this, Range::all(), Range(x, x+1)); +} + +inline +GpuMat GpuMat::rowRange(int startrow, int endrow) const +{ + return GpuMat(*this, Range(startrow, endrow), Range::all()); +} + +inline +GpuMat GpuMat::rowRange(Range r) const +{ + return GpuMat(*this, r, Range::all()); +} + +inline +GpuMat GpuMat::colRange(int startcol, int endcol) const +{ + return GpuMat(*this, Range::all(), Range(startcol, endcol)); +} + +inline +GpuMat GpuMat::colRange(Range r) const +{ + return GpuMat(*this, Range::all(), r); +} + +inline +GpuMat GpuMat::operator ()(Range rowRange_, Range colRange_) const +{ + return GpuMat(*this, rowRange_, colRange_); +} + +inline +GpuMat GpuMat::operator ()(Rect roi) const +{ + return GpuMat(*this, roi); +} + +inline +bool GpuMat::isContinuous() const +{ + return (flags & Mat::CONTINUOUS_FLAG) != 0; +} + +inline +size_t GpuMat::elemSize() const +{ + return CV_ELEM_SIZE(flags); +} + +inline +size_t GpuMat::elemSize1() const +{ + return CV_ELEM_SIZE1(flags); +} + +inline +int GpuMat::type() const +{ + return CV_MAT_TYPE(flags); +} + +inline +int GpuMat::depth() const +{ + return CV_MAT_DEPTH(flags); +} + +inline +int GpuMat::channels() const +{ + return CV_MAT_CN(flags); +} + +inline +size_t GpuMat::step1() const +{ + return step / elemSize1(); +} + +inline +Size GpuMat::size() const +{ + return Size(cols, rows); +} + +inline +bool GpuMat::empty() const +{ + return data == 0; +} + +static inline +GpuMat createContinuous(int rows, int cols, int type) +{ + GpuMat m; + createContinuous(rows, cols, type, m); + return m; +} + +static inline +void createContinuous(Size size, int type, OutputArray arr) +{ + createContinuous(size.height, size.width, type, arr); +} + +static inline +GpuMat createContinuous(Size size, int type) +{ + GpuMat m; + createContinuous(size, type, m); + return m; +} + +static inline +void ensureSizeIsEnough(Size size, int type, OutputArray arr) +{ + ensureSizeIsEnough(size.height, size.width, type, arr); +} + +static inline +void swap(GpuMat& a, GpuMat& b) +{ + a.swap(b); +} + +//=================================================================================== +// HostMem +//=================================================================================== + +inline +HostMem::HostMem(AllocType alloc_type_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_) +{ +} + +inline +HostMem::HostMem(const HostMem& m) + : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), refcount(m.refcount), datastart(m.datastart), dataend(m.dataend), alloc_type(m.alloc_type) +{ + if( refcount ) + CV_XADD(refcount, 1); +} + +inline +HostMem::HostMem(int rows_, int cols_, int type_, AllocType alloc_type_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_) +{ + if (rows_ > 0 && cols_ > 0) + create(rows_, cols_, type_); +} + +inline +HostMem::HostMem(Size size_, int type_, AllocType alloc_type_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_) +{ + if (size_.height > 0 && size_.width > 0) + create(size_.height, size_.width, type_); +} + +inline +HostMem::HostMem(InputArray arr, AllocType alloc_type_) + : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(alloc_type_) +{ + arr.getMat().copyTo(*this); +} + +inline +HostMem::~HostMem() +{ + release(); +} + +inline +HostMem& HostMem::operator =(const HostMem& m) +{ + if (this != &m) + { + HostMem temp(m); + swap(temp); + } + + return *this; +} + +inline +void HostMem::swap(HostMem& b) +{ + std::swap(flags, b.flags); + std::swap(rows, b.rows); + std::swap(cols, b.cols); + std::swap(step, b.step); + std::swap(data, b.data); + std::swap(datastart, b.datastart); + std::swap(dataend, b.dataend); + std::swap(refcount, b.refcount); + std::swap(alloc_type, b.alloc_type); +} + +inline +HostMem HostMem::clone() const +{ + HostMem m(size(), type(), alloc_type); + createMatHeader().copyTo(m); + return m; +} + +inline +void HostMem::create(Size size_, int type_) +{ + create(size_.height, size_.width, type_); +} + +inline +Mat HostMem::createMatHeader() const +{ + return Mat(size(), type(), data, step); +} + +inline +bool HostMem::isContinuous() const +{ + return (flags & Mat::CONTINUOUS_FLAG) != 0; +} + +inline +size_t HostMem::elemSize() const +{ + return CV_ELEM_SIZE(flags); +} + +inline +size_t HostMem::elemSize1() const +{ + return CV_ELEM_SIZE1(flags); +} + +inline +int HostMem::type() const +{ + return CV_MAT_TYPE(flags); +} + +inline +int HostMem::depth() const +{ + return CV_MAT_DEPTH(flags); +} + +inline +int HostMem::channels() const +{ + return CV_MAT_CN(flags); +} + +inline +size_t HostMem::step1() const +{ + return step / elemSize1(); +} + +inline +Size HostMem::size() const +{ + return Size(cols, rows); +} + +inline +bool HostMem::empty() const +{ + return data == 0; +} + +static inline +void swap(HostMem& a, HostMem& b) +{ + a.swap(b); +} + +//=================================================================================== +// Stream +//=================================================================================== + +inline +Stream::Stream(const Ptr& impl) + : impl_(impl) +{ +} + +//=================================================================================== +// Event +//=================================================================================== + +inline +Event::Event(const Ptr& impl) + : impl_(impl) +{ +} + +//=================================================================================== +// Initialization & Info +//=================================================================================== + +inline +bool TargetArchs::has(int major, int minor) +{ + return hasPtx(major, minor) || hasBin(major, minor); +} + +inline +bool TargetArchs::hasEqualOrGreater(int major, int minor) +{ + return hasEqualOrGreaterPtx(major, minor) || hasEqualOrGreaterBin(major, minor); +} + +inline +DeviceInfo::DeviceInfo() +{ + device_id_ = getDevice(); +} + +inline +DeviceInfo::DeviceInfo(int device_id) +{ + CV_Assert( device_id >= 0 && device_id < getCudaEnabledDeviceCount() ); + device_id_ = device_id; +} + +inline +int DeviceInfo::deviceID() const +{ + return device_id_; +} + +inline +size_t DeviceInfo::freeMemory() const +{ + size_t _totalMemory = 0, _freeMemory = 0; + queryMemory(_totalMemory, _freeMemory); + return _freeMemory; +} + +inline +size_t DeviceInfo::totalMemory() const +{ + size_t _totalMemory = 0, _freeMemory = 0; + queryMemory(_totalMemory, _freeMemory); + return _totalMemory; +} + +inline +bool DeviceInfo::supports(FeatureSet feature_set) const +{ + int version = majorVersion() * 10 + minorVersion(); + return version >= feature_set; +} + + +}} // namespace cv { namespace cuda { + +//=================================================================================== +// Mat +//=================================================================================== + +namespace cv { + +inline +Mat::Mat(const cuda::GpuMat& m) + : flags(0), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows) +{ + m.download(*this); +} + +} + +//! @endcond + +#endif // OPENCV_CORE_CUDAINL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/block.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/block.hpp new file mode 100755 index 0000000..c277f0e --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/block.hpp @@ -0,0 +1,211 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_DEVICE_BLOCK_HPP +#define OPENCV_CUDA_DEVICE_BLOCK_HPP + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + struct Block + { + static __device__ __forceinline__ unsigned int id() + { + return blockIdx.x; + } + + static __device__ __forceinline__ unsigned int stride() + { + return blockDim.x * blockDim.y * blockDim.z; + } + + static __device__ __forceinline__ void sync() + { + __syncthreads(); + } + + static __device__ __forceinline__ int flattenedThreadId() + { + return threadIdx.z * blockDim.x * blockDim.y + threadIdx.y * blockDim.x + threadIdx.x; + } + + template + static __device__ __forceinline__ void fill(It beg, It end, const T& value) + { + int STRIDE = stride(); + It t = beg + flattenedThreadId(); + + for(; t < end; t += STRIDE) + *t = value; + } + + template + static __device__ __forceinline__ void yota(OutIt beg, OutIt end, T value) + { + int STRIDE = stride(); + int tid = flattenedThreadId(); + value += tid; + + for(OutIt t = beg + tid; t < end; t += STRIDE, value += STRIDE) + *t = value; + } + + template + static __device__ __forceinline__ void copy(InIt beg, InIt end, OutIt out) + { + int STRIDE = stride(); + InIt t = beg + flattenedThreadId(); + OutIt o = out + (t - beg); + + for(; t < end; t += STRIDE, o += STRIDE) + *o = *t; + } + + template + static __device__ __forceinline__ void transform(InIt beg, InIt end, OutIt out, UnOp op) + { + int STRIDE = stride(); + InIt t = beg + flattenedThreadId(); + OutIt o = out + (t - beg); + + for(; t < end; t += STRIDE, o += STRIDE) + *o = op(*t); + } + + template + static __device__ __forceinline__ void transform(InIt1 beg1, InIt1 end1, InIt2 beg2, OutIt out, BinOp op) + { + int STRIDE = stride(); + InIt1 t1 = beg1 + flattenedThreadId(); + InIt2 t2 = beg2 + flattenedThreadId(); + OutIt o = out + (t1 - beg1); + + for(; t1 < end1; t1 += STRIDE, t2 += STRIDE, o += STRIDE) + *o = op(*t1, *t2); + } + + template + static __device__ __forceinline__ void reduce(volatile T* buffer, BinOp op) + { + int tid = flattenedThreadId(); + T val = buffer[tid]; + + if (CTA_SIZE >= 1024) { if (tid < 512) buffer[tid] = val = op(val, buffer[tid + 512]); __syncthreads(); } + if (CTA_SIZE >= 512) { if (tid < 256) buffer[tid] = val = op(val, buffer[tid + 256]); __syncthreads(); } + if (CTA_SIZE >= 256) { if (tid < 128) buffer[tid] = val = op(val, buffer[tid + 128]); __syncthreads(); } + if (CTA_SIZE >= 128) { if (tid < 64) buffer[tid] = val = op(val, buffer[tid + 64]); __syncthreads(); } + + if (tid < 32) + { + if (CTA_SIZE >= 64) { buffer[tid] = val = op(val, buffer[tid + 32]); } + if (CTA_SIZE >= 32) { buffer[tid] = val = op(val, buffer[tid + 16]); } + if (CTA_SIZE >= 16) { buffer[tid] = val = op(val, buffer[tid + 8]); } + if (CTA_SIZE >= 8) { buffer[tid] = val = op(val, buffer[tid + 4]); } + if (CTA_SIZE >= 4) { buffer[tid] = val = op(val, buffer[tid + 2]); } + if (CTA_SIZE >= 2) { buffer[tid] = val = op(val, buffer[tid + 1]); } + } + } + + template + static __device__ __forceinline__ T reduce(volatile T* buffer, T init, BinOp op) + { + int tid = flattenedThreadId(); + T val = buffer[tid] = init; + __syncthreads(); + + if (CTA_SIZE >= 1024) { if (tid < 512) buffer[tid] = val = op(val, buffer[tid + 512]); __syncthreads(); } + if (CTA_SIZE >= 512) { if (tid < 256) buffer[tid] = val = op(val, buffer[tid + 256]); __syncthreads(); } + if (CTA_SIZE >= 256) { if (tid < 128) buffer[tid] = val = op(val, buffer[tid + 128]); __syncthreads(); } + if (CTA_SIZE >= 128) { if (tid < 64) buffer[tid] = val = op(val, buffer[tid + 64]); __syncthreads(); } + + if (tid < 32) + { + if (CTA_SIZE >= 64) { buffer[tid] = val = op(val, buffer[tid + 32]); } + if (CTA_SIZE >= 32) { buffer[tid] = val = op(val, buffer[tid + 16]); } + if (CTA_SIZE >= 16) { buffer[tid] = val = op(val, buffer[tid + 8]); } + if (CTA_SIZE >= 8) { buffer[tid] = val = op(val, buffer[tid + 4]); } + if (CTA_SIZE >= 4) { buffer[tid] = val = op(val, buffer[tid + 2]); } + if (CTA_SIZE >= 2) { buffer[tid] = val = op(val, buffer[tid + 1]); } + } + __syncthreads(); + return buffer[0]; + } + + template + static __device__ __forceinline__ void reduce_n(T* data, unsigned int n, BinOp op) + { + int ftid = flattenedThreadId(); + int sft = stride(); + + if (sft < n) + { + for (unsigned int i = sft + ftid; i < n; i += sft) + data[ftid] = op(data[ftid], data[i]); + + __syncthreads(); + + n = sft; + } + + while (n > 1) + { + unsigned int half = n/2; + + if (ftid < half) + data[ftid] = op(data[ftid], data[n - ftid - 1]); + + __syncthreads(); + + n = n - half; + } + } + }; +}}} + +//! @endcond + +#endif /* OPENCV_CUDA_DEVICE_BLOCK_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/border_interpolate.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/border_interpolate.hpp new file mode 100755 index 0000000..874f705 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/border_interpolate.hpp @@ -0,0 +1,722 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_BORDER_INTERPOLATE_HPP +#define OPENCV_CUDA_BORDER_INTERPOLATE_HPP + +#include "saturate_cast.hpp" +#include "vec_traits.hpp" +#include "vec_math.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + ////////////////////////////////////////////////////////////// + // BrdConstant + + template struct BrdRowConstant + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdRowConstant(int width_, const D& val_ = VecTraits::all(0)) : width(width_), val(val_) {} + + template __device__ __forceinline__ D at_low(int x, const T* data) const + { + return x >= 0 ? saturate_cast(data[x]) : val; + } + + template __device__ __forceinline__ D at_high(int x, const T* data) const + { + return x < width ? saturate_cast(data[x]) : val; + } + + template __device__ __forceinline__ D at(int x, const T* data) const + { + return (x >= 0 && x < width) ? saturate_cast(data[x]) : val; + } + + int width; + D val; + }; + + template struct BrdColConstant + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdColConstant(int height_, const D& val_ = VecTraits::all(0)) : height(height_), val(val_) {} + + template __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const + { + return y >= 0 ? saturate_cast(*(const T*)((const char*)data + y * step)) : val; + } + + template __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const + { + return y < height ? saturate_cast(*(const T*)((const char*)data + y * step)) : val; + } + + template __device__ __forceinline__ D at(int y, const T* data, size_t step) const + { + return (y >= 0 && y < height) ? saturate_cast(*(const T*)((const char*)data + y * step)) : val; + } + + int height; + D val; + }; + + template struct BrdConstant + { + typedef D result_type; + + __host__ __device__ __forceinline__ BrdConstant(int height_, int width_, const D& val_ = VecTraits::all(0)) : height(height_), width(width_), val(val_) + { + } + + template __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const + { + return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast(((const T*)((const uchar*)data + y * step))[x]) : val; + } + + template __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const + { + return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast(src(y, x)) : val; + } + + int height; + int width; + D val; + }; + + ////////////////////////////////////////////////////////////// + // BrdReplicate + + template struct BrdRowReplicate + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdRowReplicate(int width) : last_col(width - 1) {} + template __host__ __device__ __forceinline__ BrdRowReplicate(int width, U) : last_col(width - 1) {} + + __device__ __forceinline__ int idx_col_low(int x) const + { + return ::max(x, 0); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return ::min(x, last_col); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_low(idx_col_high(x)); + } + + template __device__ __forceinline__ D at_low(int x, const T* data) const + { + return saturate_cast(data[idx_col_low(x)]); + } + + template __device__ __forceinline__ D at_high(int x, const T* data) const + { + return saturate_cast(data[idx_col_high(x)]); + } + + template __device__ __forceinline__ D at(int x, const T* data) const + { + return saturate_cast(data[idx_col(x)]); + } + + int last_col; + }; + + template struct BrdColReplicate + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdColReplicate(int height) : last_row(height - 1) {} + template __host__ __device__ __forceinline__ BrdColReplicate(int height, U) : last_row(height - 1) {} + + __device__ __forceinline__ int idx_row_low(int y) const + { + return ::max(y, 0); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return ::min(y, last_row); + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_low(idx_row_high(y)); + } + + template __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const + { + return saturate_cast(*(const T*)((const char*)data + idx_row_low(y) * step)); + } + + template __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const + { + return saturate_cast(*(const T*)((const char*)data + idx_row_high(y) * step)); + } + + template __device__ __forceinline__ D at(int y, const T* data, size_t step) const + { + return saturate_cast(*(const T*)((const char*)data + idx_row(y) * step)); + } + + int last_row; + }; + + template struct BrdReplicate + { + typedef D result_type; + + __host__ __device__ __forceinline__ BrdReplicate(int height, int width) : last_row(height - 1), last_col(width - 1) {} + template __host__ __device__ __forceinline__ BrdReplicate(int height, int width, U) : last_row(height - 1), last_col(width - 1) {} + + __device__ __forceinline__ int idx_row_low(int y) const + { + return ::max(y, 0); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return ::min(y, last_row); + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_low(idx_row_high(y)); + } + + __device__ __forceinline__ int idx_col_low(int x) const + { + return ::max(x, 0); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return ::min(x, last_col); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_low(idx_col_high(x)); + } + + template __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const + { + return saturate_cast(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]); + } + + template __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const + { + return saturate_cast(src(idx_row(y), idx_col(x))); + } + + int last_row; + int last_col; + }; + + ////////////////////////////////////////////////////////////// + // BrdReflect101 + + template struct BrdRowReflect101 + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdRowReflect101(int width) : last_col(width - 1) {} + template __host__ __device__ __forceinline__ BrdRowReflect101(int width, U) : last_col(width - 1) {} + + __device__ __forceinline__ int idx_col_low(int x) const + { + return ::abs(x) % (last_col + 1); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return ::abs(last_col - ::abs(last_col - x)) % (last_col + 1); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_low(idx_col_high(x)); + } + + template __device__ __forceinline__ D at_low(int x, const T* data) const + { + return saturate_cast(data[idx_col_low(x)]); + } + + template __device__ __forceinline__ D at_high(int x, const T* data) const + { + return saturate_cast(data[idx_col_high(x)]); + } + + template __device__ __forceinline__ D at(int x, const T* data) const + { + return saturate_cast(data[idx_col(x)]); + } + + int last_col; + }; + + template struct BrdColReflect101 + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdColReflect101(int height) : last_row(height - 1) {} + template __host__ __device__ __forceinline__ BrdColReflect101(int height, U) : last_row(height - 1) {} + + __device__ __forceinline__ int idx_row_low(int y) const + { + return ::abs(y) % (last_row + 1); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return ::abs(last_row - ::abs(last_row - y)) % (last_row + 1); + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_low(idx_row_high(y)); + } + + template __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row_low(y) * step)); + } + + template __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row_high(y) * step)); + } + + template __device__ __forceinline__ D at(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row(y) * step)); + } + + int last_row; + }; + + template struct BrdReflect101 + { + typedef D result_type; + + __host__ __device__ __forceinline__ BrdReflect101(int height, int width) : last_row(height - 1), last_col(width - 1) {} + template __host__ __device__ __forceinline__ BrdReflect101(int height, int width, U) : last_row(height - 1), last_col(width - 1) {} + + __device__ __forceinline__ int idx_row_low(int y) const + { + return ::abs(y) % (last_row + 1); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return ::abs(last_row - ::abs(last_row - y)) % (last_row + 1); + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_low(idx_row_high(y)); + } + + __device__ __forceinline__ int idx_col_low(int x) const + { + return ::abs(x) % (last_col + 1); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return ::abs(last_col - ::abs(last_col - x)) % (last_col + 1); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_low(idx_col_high(x)); + } + + template __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const + { + return saturate_cast(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]); + } + + template __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const + { + return saturate_cast(src(idx_row(y), idx_col(x))); + } + + int last_row; + int last_col; + }; + + ////////////////////////////////////////////////////////////// + // BrdReflect + + template struct BrdRowReflect + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdRowReflect(int width) : last_col(width - 1) {} + template __host__ __device__ __forceinline__ BrdRowReflect(int width, U) : last_col(width - 1) {} + + __device__ __forceinline__ int idx_col_low(int x) const + { + return (::abs(x) - (x < 0)) % (last_col + 1); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return ::abs(last_col - ::abs(last_col - x) + (x > last_col)) % (last_col + 1); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_high(::abs(x) - (x < 0)); + } + + template __device__ __forceinline__ D at_low(int x, const T* data) const + { + return saturate_cast(data[idx_col_low(x)]); + } + + template __device__ __forceinline__ D at_high(int x, const T* data) const + { + return saturate_cast(data[idx_col_high(x)]); + } + + template __device__ __forceinline__ D at(int x, const T* data) const + { + return saturate_cast(data[idx_col(x)]); + } + + int last_col; + }; + + template struct BrdColReflect + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdColReflect(int height) : last_row(height - 1) {} + template __host__ __device__ __forceinline__ BrdColReflect(int height, U) : last_row(height - 1) {} + + __device__ __forceinline__ int idx_row_low(int y) const + { + return (::abs(y) - (y < 0)) % (last_row + 1); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return ::abs(last_row - ::abs(last_row - y) + (y > last_row)) % (last_row + 1); + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_high(::abs(y) - (y < 0)); + } + + template __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row_low(y) * step)); + } + + template __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row_high(y) * step)); + } + + template __device__ __forceinline__ D at(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row(y) * step)); + } + + int last_row; + }; + + template struct BrdReflect + { + typedef D result_type; + + __host__ __device__ __forceinline__ BrdReflect(int height, int width) : last_row(height - 1), last_col(width - 1) {} + template __host__ __device__ __forceinline__ BrdReflect(int height, int width, U) : last_row(height - 1), last_col(width - 1) {} + + __device__ __forceinline__ int idx_row_low(int y) const + { + return (::abs(y) - (y < 0)) % (last_row + 1); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return /*::abs*/(last_row - ::abs(last_row - y) + (y > last_row)) /*% (last_row + 1)*/; + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_low(idx_row_high(y)); + } + + __device__ __forceinline__ int idx_col_low(int x) const + { + return (::abs(x) - (x < 0)) % (last_col + 1); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return (last_col - ::abs(last_col - x) + (x > last_col)); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_low(idx_col_high(x)); + } + + template __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const + { + return saturate_cast(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]); + } + + template __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const + { + return saturate_cast(src(idx_row(y), idx_col(x))); + } + + int last_row; + int last_col; + }; + + ////////////////////////////////////////////////////////////// + // BrdWrap + + template struct BrdRowWrap + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdRowWrap(int width_) : width(width_) {} + template __host__ __device__ __forceinline__ BrdRowWrap(int width_, U) : width(width_) {} + + __device__ __forceinline__ int idx_col_low(int x) const + { + return (x >= 0) * x + (x < 0) * (x - ((x - width + 1) / width) * width); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return (x < width) * x + (x >= width) * (x % width); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_high(idx_col_low(x)); + } + + template __device__ __forceinline__ D at_low(int x, const T* data) const + { + return saturate_cast(data[idx_col_low(x)]); + } + + template __device__ __forceinline__ D at_high(int x, const T* data) const + { + return saturate_cast(data[idx_col_high(x)]); + } + + template __device__ __forceinline__ D at(int x, const T* data) const + { + return saturate_cast(data[idx_col(x)]); + } + + int width; + }; + + template struct BrdColWrap + { + typedef D result_type; + + explicit __host__ __device__ __forceinline__ BrdColWrap(int height_) : height(height_) {} + template __host__ __device__ __forceinline__ BrdColWrap(int height_, U) : height(height_) {} + + __device__ __forceinline__ int idx_row_low(int y) const + { + return (y >= 0) * y + (y < 0) * (y - ((y - height + 1) / height) * height); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return (y < height) * y + (y >= height) * (y % height); + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_high(idx_row_low(y)); + } + + template __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row_low(y) * step)); + } + + template __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row_high(y) * step)); + } + + template __device__ __forceinline__ D at(int y, const T* data, size_t step) const + { + return saturate_cast(*(const D*)((const char*)data + idx_row(y) * step)); + } + + int height; + }; + + template struct BrdWrap + { + typedef D result_type; + + __host__ __device__ __forceinline__ BrdWrap(int height_, int width_) : + height(height_), width(width_) + { + } + template + __host__ __device__ __forceinline__ BrdWrap(int height_, int width_, U) : + height(height_), width(width_) + { + } + + __device__ __forceinline__ int idx_row_low(int y) const + { + return (y >= 0) ? y : (y - ((y - height + 1) / height) * height); + } + + __device__ __forceinline__ int idx_row_high(int y) const + { + return (y < height) ? y : (y % height); + } + + __device__ __forceinline__ int idx_row(int y) const + { + return idx_row_high(idx_row_low(y)); + } + + __device__ __forceinline__ int idx_col_low(int x) const + { + return (x >= 0) ? x : (x - ((x - width + 1) / width) * width); + } + + __device__ __forceinline__ int idx_col_high(int x) const + { + return (x < width) ? x : (x % width); + } + + __device__ __forceinline__ int idx_col(int x) const + { + return idx_col_high(idx_col_low(x)); + } + + template __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const + { + return saturate_cast(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]); + } + + template __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const + { + return saturate_cast(src(idx_row(y), idx_col(x))); + } + + int height; + int width; + }; + + ////////////////////////////////////////////////////////////// + // BorderReader + + template struct BorderReader + { + typedef typename B::result_type elem_type; + typedef typename Ptr2D::index_type index_type; + + __host__ __device__ __forceinline__ BorderReader(const Ptr2D& ptr_, const B& b_) : ptr(ptr_), b(b_) {} + + __device__ __forceinline__ elem_type operator ()(index_type y, index_type x) const + { + return b.at(y, x, ptr); + } + + Ptr2D ptr; + B b; + }; + + // under win32 there is some bug with templated types that passed as kernel parameters + // with this specialization all works fine + template struct BorderReader< Ptr2D, BrdConstant > + { + typedef typename BrdConstant::result_type elem_type; + typedef typename Ptr2D::index_type index_type; + + __host__ __device__ __forceinline__ BorderReader(const Ptr2D& src_, const BrdConstant& b) : + src(src_), height(b.height), width(b.width), val(b.val) + { + } + + __device__ __forceinline__ D operator ()(index_type y, index_type x) const + { + return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast(src(y, x)) : val; + } + + Ptr2D src; + int height; + int width; + D val; + }; +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_BORDER_INTERPOLATE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/color.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/color.hpp new file mode 100755 index 0000000..dcce280 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/color.hpp @@ -0,0 +1,309 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_COLOR_HPP +#define OPENCV_CUDA_COLOR_HPP + +#include "detail/color_detail.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + // All OPENCV_CUDA_IMPLEMENT_*_TRAITS(ColorSpace1_to_ColorSpace2, ...) macros implements + // template class ColorSpace1_to_ColorSpace2_traits + // { + // typedef ... functor_type; + // static __host__ __device__ functor_type create_functor(); + // }; + + OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS(bgr_to_rgb, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS(bgr_to_bgra, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS(bgr_to_rgba, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS(bgra_to_bgr, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS(bgra_to_rgb, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS(bgra_to_rgba, 4, 4, 2) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(bgr_to_bgr555, 3, 0, 5) + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(bgr_to_bgr565, 3, 0, 6) + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(rgb_to_bgr555, 3, 2, 5) + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(rgb_to_bgr565, 3, 2, 6) + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(bgra_to_bgr555, 4, 0, 5) + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(bgra_to_bgr565, 4, 0, 6) + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(rgba_to_bgr555, 4, 2, 5) + OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(rgba_to_bgr565, 4, 2, 6) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr555_to_rgb, 3, 2, 5) + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr565_to_rgb, 3, 2, 6) + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr555_to_bgr, 3, 0, 5) + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr565_to_bgr, 3, 0, 6) + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr555_to_rgba, 4, 2, 5) + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr565_to_rgba, 4, 2, 6) + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr555_to_bgra, 4, 0, 5) + OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(bgr565_to_bgra, 4, 0, 6) + + #undef OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_GRAY2RGB_TRAITS(gray_to_bgr, 3) + OPENCV_CUDA_IMPLEMENT_GRAY2RGB_TRAITS(gray_to_bgra, 4) + + #undef OPENCV_CUDA_IMPLEMENT_GRAY2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_GRAY2RGB5x5_TRAITS(gray_to_bgr555, 5) + OPENCV_CUDA_IMPLEMENT_GRAY2RGB5x5_TRAITS(gray_to_bgr565, 6) + + #undef OPENCV_CUDA_IMPLEMENT_GRAY2RGB5x5_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB5x52GRAY_TRAITS(bgr555_to_gray, 5) + OPENCV_CUDA_IMPLEMENT_RGB5x52GRAY_TRAITS(bgr565_to_gray, 6) + + #undef OPENCV_CUDA_IMPLEMENT_RGB5x52GRAY_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2GRAY_TRAITS(rgb_to_gray, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2GRAY_TRAITS(bgr_to_gray, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2GRAY_TRAITS(rgba_to_gray, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2GRAY_TRAITS(bgra_to_gray, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2GRAY_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(rgb_to_yuv, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(rgba_to_yuv, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(rgb_to_yuv4, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(rgba_to_yuv4, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(bgr_to_yuv, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(bgra_to_yuv, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(bgr_to_yuv4, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(bgra_to_yuv4, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS + + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv_to_rgb, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv_to_rgba, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv4_to_rgb, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv4_to_rgba, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv_to_bgr, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv_to_bgra, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv4_to_bgr, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(yuv4_to_bgra, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(rgb_to_YCrCb, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(rgba_to_YCrCb, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(rgb_to_YCrCb4, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(rgba_to_YCrCb4, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(bgr_to_YCrCb, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(bgra_to_YCrCb, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(bgr_to_YCrCb4, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(bgra_to_YCrCb4, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS + + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb_to_rgb, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb_to_rgba, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb4_to_rgb, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb4_to_rgba, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb_to_bgr, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb_to_bgra, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb4_to_bgr, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(YCrCb4_to_bgra, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(rgb_to_xyz, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(rgba_to_xyz, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(rgb_to_xyz4, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(rgba_to_xyz4, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(bgr_to_xyz, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(bgra_to_xyz, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(bgr_to_xyz4, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(bgra_to_xyz4, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS + + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz_to_rgb, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz4_to_rgb, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz_to_rgba, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz4_to_rgba, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz_to_bgr, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz4_to_bgr, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz_to_bgra, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(xyz4_to_bgra, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(rgb_to_hsv, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(rgba_to_hsv, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(rgb_to_hsv4, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(rgba_to_hsv4, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(bgr_to_hsv, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(bgra_to_hsv, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(bgr_to_hsv4, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(bgra_to_hsv4, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS + + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv_to_rgb, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv_to_rgba, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv4_to_rgb, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv4_to_rgba, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv_to_bgr, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv_to_bgra, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv4_to_bgr, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(hsv4_to_bgra, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(rgb_to_hls, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(rgba_to_hls, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(rgb_to_hls4, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(rgba_to_hls4, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(bgr_to_hls, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(bgra_to_hls, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(bgr_to_hls4, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(bgra_to_hls4, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS + + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls_to_rgb, 3, 3, 2) + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls_to_rgba, 3, 4, 2) + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls4_to_rgb, 4, 3, 2) + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls4_to_rgba, 4, 4, 2) + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls_to_bgr, 3, 3, 0) + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls_to_bgra, 3, 4, 0) + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls4_to_bgr, 4, 3, 0) + OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(hls4_to_bgra, 4, 4, 0) + + #undef OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(rgb_to_lab, 3, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(rgba_to_lab, 4, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(rgb_to_lab4, 3, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(rgba_to_lab4, 4, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(bgr_to_lab, 3, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(bgra_to_lab, 4, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(bgr_to_lab4, 3, 4, true, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(bgra_to_lab4, 4, 4, true, 0) + + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lrgb_to_lab, 3, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lrgba_to_lab, 4, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lrgb_to_lab4, 3, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lrgba_to_lab4, 4, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lbgr_to_lab, 3, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lbgra_to_lab, 4, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lbgr_to_lab4, 3, 4, false, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(lbgra_to_lab4, 4, 4, false, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS + + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_rgb, 3, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_rgb, 4, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_rgba, 3, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_rgba, 4, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_bgr, 3, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_bgr, 4, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_bgra, 3, 4, true, 0) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_bgra, 4, 4, true, 0) + + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_lrgb, 3, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_lrgb, 4, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_lrgba, 3, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_lrgba, 4, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_lbgr, 3, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_lbgr, 4, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab_to_lbgra, 3, 4, false, 0) + OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(lab4_to_lbgra, 4, 4, false, 0) + + #undef OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS + + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(rgb_to_luv, 3, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(rgba_to_luv, 4, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(rgb_to_luv4, 3, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(rgba_to_luv4, 4, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(bgr_to_luv, 3, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(bgra_to_luv, 4, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(bgr_to_luv4, 3, 4, true, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(bgra_to_luv4, 4, 4, true, 0) + + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lrgb_to_luv, 3, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lrgba_to_luv, 4, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lrgb_to_luv4, 3, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lrgba_to_luv4, 4, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lbgr_to_luv, 3, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lbgra_to_luv, 4, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lbgr_to_luv4, 3, 4, false, 0) + OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(lbgra_to_luv4, 4, 4, false, 0) + + #undef OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS + + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_rgb, 3, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_rgb, 4, 3, true, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_rgba, 3, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_rgba, 4, 4, true, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_bgr, 3, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_bgr, 4, 3, true, 0) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_bgra, 3, 4, true, 0) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_bgra, 4, 4, true, 0) + + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_lrgb, 3, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_lrgb, 4, 3, false, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_lrgba, 3, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_lrgba, 4, 4, false, 2) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_lbgr, 3, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_lbgr, 4, 3, false, 0) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv_to_lbgra, 3, 4, false, 0) + OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_lbgra, 4, 4, false, 0) + + #undef OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_COLOR_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/common.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/common.hpp new file mode 100755 index 0000000..14b1f3f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/common.hpp @@ -0,0 +1,109 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_COMMON_HPP +#define OPENCV_CUDA_COMMON_HPP + +#include +#include "opencv2/core/cuda_types.hpp" +#include "opencv2/core/cvdef.h" +#include "opencv2/core/base.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +#ifndef CV_PI_F + #ifndef CV_PI + #define CV_PI_F 3.14159265f + #else + #define CV_PI_F ((float)CV_PI) + #endif +#endif + +namespace cv { namespace cuda { + static inline void checkCudaError(cudaError_t err, const char* file, const int line, const char* func) + { + if (cudaSuccess != err) + cv::error(cv::Error::GpuApiCallError, cudaGetErrorString(err), func, file, line); + } +}} + +#ifndef cudaSafeCall + #define cudaSafeCall(expr) cv::cuda::checkCudaError(expr, __FILE__, __LINE__, CV_Func) +#endif + +namespace cv { namespace cuda +{ + template static inline bool isAligned(const T* ptr, size_t size) + { + return reinterpret_cast(ptr) % size == 0; + } + + static inline bool isAligned(size_t step, size_t size) + { + return step % size == 0; + } +}} + +namespace cv { namespace cuda +{ + namespace device + { + __host__ __device__ __forceinline__ int divUp(int total, int grain) + { + return (total + grain - 1) / grain; + } + + template inline void bindTexture(const textureReference* tex, const PtrStepSz& img) + { + cudaChannelFormatDesc desc = cudaCreateChannelDesc(); + cudaSafeCall( cudaBindTexture2D(0, tex, img.ptr(), &desc, img.cols, img.rows, img.step) ); + } + } +}} + +//! @endcond + +#endif // OPENCV_CUDA_COMMON_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/datamov_utils.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/datamov_utils.hpp new file mode 100755 index 0000000..6820d0f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/datamov_utils.hpp @@ -0,0 +1,113 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_DATAMOV_UTILS_HPP +#define OPENCV_CUDA_DATAMOV_UTILS_HPP + +#include "common.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 200 + + // for Fermi memory space is detected automatically + template struct ForceGlob + { + __device__ __forceinline__ static void Load(const T* ptr, int offset, T& val) { val = ptr[offset]; } + }; + + #else // __CUDA_ARCH__ >= 200 + + #if defined(_WIN64) || defined(__LP64__) + // 64-bit register modifier for inlined asm + #define OPENCV_CUDA_ASM_PTR "l" + #else + // 32-bit register modifier for inlined asm + #define OPENCV_CUDA_ASM_PTR "r" + #endif + + template struct ForceGlob; + + #define OPENCV_CUDA_DEFINE_FORCE_GLOB(base_type, ptx_type, reg_mod) \ + template <> struct ForceGlob \ + { \ + __device__ __forceinline__ static void Load(const base_type* ptr, int offset, base_type& val) \ + { \ + asm("ld.global."#ptx_type" %0, [%1];" : "="#reg_mod(val) : OPENCV_CUDA_ASM_PTR(ptr + offset)); \ + } \ + }; + + #define OPENCV_CUDA_DEFINE_FORCE_GLOB_B(base_type, ptx_type) \ + template <> struct ForceGlob \ + { \ + __device__ __forceinline__ static void Load(const base_type* ptr, int offset, base_type& val) \ + { \ + asm("ld.global."#ptx_type" %0, [%1];" : "=r"(*reinterpret_cast(&val)) : OPENCV_CUDA_ASM_PTR(ptr + offset)); \ + } \ + }; + + OPENCV_CUDA_DEFINE_FORCE_GLOB_B(uchar, u8) + OPENCV_CUDA_DEFINE_FORCE_GLOB_B(schar, s8) + OPENCV_CUDA_DEFINE_FORCE_GLOB_B(char, b8) + OPENCV_CUDA_DEFINE_FORCE_GLOB (ushort, u16, h) + OPENCV_CUDA_DEFINE_FORCE_GLOB (short, s16, h) + OPENCV_CUDA_DEFINE_FORCE_GLOB (uint, u32, r) + OPENCV_CUDA_DEFINE_FORCE_GLOB (int, s32, r) + OPENCV_CUDA_DEFINE_FORCE_GLOB (float, f32, f) + OPENCV_CUDA_DEFINE_FORCE_GLOB (double, f64, d) + + #undef OPENCV_CUDA_DEFINE_FORCE_GLOB + #undef OPENCV_CUDA_DEFINE_FORCE_GLOB_B + #undef OPENCV_CUDA_ASM_PTR + + #endif // __CUDA_ARCH__ >= 200 +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_DATAMOV_UTILS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/color_detail.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/color_detail.hpp new file mode 100755 index 0000000..f4b4796 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/color_detail.hpp @@ -0,0 +1,2018 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_COLOR_DETAIL_HPP +#define OPENCV_CUDA_COLOR_DETAIL_HPP + +#include "../common.hpp" +#include "../vec_traits.hpp" +#include "../saturate_cast.hpp" +#include "../limits.hpp" +#include "../functional.hpp" + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + #ifndef CV_DESCALE + #define CV_DESCALE(x, n) (((x) + (1 << ((n)-1))) >> (n)) + #endif + + namespace color_detail + { + template struct ColorChannel + { + typedef float worktype_f; + static __device__ __forceinline__ T max() { return numeric_limits::max(); } + static __device__ __forceinline__ T half() { return (T)(max()/2 + 1); } + }; + + template<> struct ColorChannel + { + typedef float worktype_f; + static __device__ __forceinline__ float max() { return 1.f; } + static __device__ __forceinline__ float half() { return 0.5f; } + }; + + template static __device__ __forceinline__ void setAlpha(typename TypeVec::vec_type& vec, T val) + { + } + + template static __device__ __forceinline__ void setAlpha(typename TypeVec::vec_type& vec, T val) + { + vec.w = val; + } + + template static __device__ __forceinline__ T getAlpha(const typename TypeVec::vec_type& vec) + { + return ColorChannel::max(); + } + + template static __device__ __forceinline__ T getAlpha(const typename TypeVec::vec_type& vec) + { + return vec.w; + } + + //constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601 + constexpr float B2YF = 0.114f; + constexpr float G2YF = 0.587f; + constexpr float R2YF = 0.299f; + + //to YCbCr + constexpr float YCBF = 0.564f; // == 1/2/(1-B2YF) + constexpr float YCRF = 0.713f; // == 1/2/(1-R2YF) + const int YCBI = 9241; // == YCBF*16384 + const int YCRI = 11682; // == YCRF*16384 + //to YUV + constexpr float B2UF = 0.492f; + constexpr float R2VF = 0.877f; + const int B2UI = 8061; // == B2UF*16384 + const int R2VI = 14369; // == R2VF*16384 + //from YUV + constexpr float U2BF = 2.032f; + constexpr float U2GF = -0.395f; + constexpr float V2GF = -0.581f; + constexpr float V2RF = 1.140f; + const int U2BI = 33292; + const int U2GI = -6472; + const int V2GI = -9519; + const int V2RI = 18678; + //from YCrCb + constexpr float CB2BF = 1.773f; + constexpr float CB2GF = -0.344f; + constexpr float CR2GF = -0.714f; + constexpr float CR2RF = 1.403f; + const int CB2BI = 29049; + const int CB2GI = -5636; + const int CR2GI = -11698; + const int CR2RI = 22987; + + enum + { + yuv_shift = 14, + xyz_shift = 12, + gray_shift = 15, + R2Y = 4899, + G2Y = 9617, + B2Y = 1868, + RY15 = 9798, // == R2YF*32768 + 0.5 + GY15 = 19235, // == G2YF*32768 + 0.5 + BY15 = 3735, // == B2YF*32768 + 0.5 + BLOCK_SIZE = 256 + }; + } + +////////////////// Various 3/4-channel to 3/4-channel RGB transformations ///////////////// + + namespace color_detail + { + template struct RGB2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ typename TypeVec::vec_type operator()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + dst.x = (&src.x)[bidx]; + dst.y = src.y; + dst.z = (&src.x)[bidx^2]; + setAlpha(dst, getAlpha(src)); + + return dst; + } + + __host__ __device__ __forceinline__ RGB2RGB() {} + __host__ __device__ __forceinline__ RGB2RGB(const RGB2RGB&) {} + }; + + template <> struct RGB2RGB : unary_function + { + __device__ uint operator()(uint src) const + { + uint dst = 0; + + dst |= (0xffu & (src >> 16)); + dst |= (0xffu & (src >> 8)) << 8; + dst |= (0xffu & (src)) << 16; + dst |= (0xffu & (src >> 24)) << 24; + + return dst; + } + + __host__ __device__ __forceinline__ RGB2RGB() {} + __host__ __device__ __forceinline__ RGB2RGB(const RGB2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2RGB_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +/////////// Transforming 16-bit (565 or 555) RGB to/from 24/32-bit (888[8]) RGB ////////// + + namespace color_detail + { + template struct RGB2RGB5x5Converter; + template struct RGB2RGB5x5Converter<6, bidx> + { + static __device__ __forceinline__ ushort cvt(const uchar3& src) + { + return (ushort)(((&src.x)[bidx] >> 3) | ((src.y & ~3) << 3) | (((&src.x)[bidx^2] & ~7) << 8)); + } + + static __device__ __forceinline__ ushort cvt(uint src) + { + uint b = 0xffu & (src >> (bidx * 8)); + uint g = 0xffu & (src >> 8); + uint r = 0xffu & (src >> ((bidx ^ 2) * 8)); + return (ushort)((b >> 3) | ((g & ~3) << 3) | ((r & ~7) << 8)); + } + }; + + template struct RGB2RGB5x5Converter<5, bidx> + { + static __device__ __forceinline__ ushort cvt(const uchar3& src) + { + return (ushort)(((&src.x)[bidx] >> 3) | ((src.y & ~7) << 2) | (((&src.x)[bidx^2] & ~7) << 7)); + } + + static __device__ __forceinline__ ushort cvt(uint src) + { + uint b = 0xffu & (src >> (bidx * 8)); + uint g = 0xffu & (src >> 8); + uint r = 0xffu & (src >> ((bidx ^ 2) * 8)); + uint a = 0xffu & (src >> 24); + return (ushort)((b >> 3) | ((g & ~7) << 2) | ((r & ~7) << 7) | (a * 0x8000)); + } + }; + + template struct RGB2RGB5x5; + + template struct RGB2RGB5x5<3, bidx,green_bits> : unary_function + { + __device__ __forceinline__ ushort operator()(const uchar3& src) const + { + return RGB2RGB5x5Converter::cvt(src); + } + + __host__ __device__ __forceinline__ RGB2RGB5x5() {} + __host__ __device__ __forceinline__ RGB2RGB5x5(const RGB2RGB5x5&) {} + }; + + template struct RGB2RGB5x5<4, bidx,green_bits> : unary_function + { + __device__ __forceinline__ ushort operator()(uint src) const + { + return RGB2RGB5x5Converter::cvt(src); + } + + __host__ __device__ __forceinline__ RGB2RGB5x5() {} + __host__ __device__ __forceinline__ RGB2RGB5x5(const RGB2RGB5x5&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2RGB5x5_TRAITS(name, scn, bidx, green_bits) \ + struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2RGB5x5 functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + template struct RGB5x52RGBConverter; + + template struct RGB5x52RGBConverter<5, bidx> + { + static __device__ __forceinline__ void cvt(uint src, uchar3& dst) + { + (&dst.x)[bidx] = src << 3; + dst.y = (src >> 2) & ~7; + (&dst.x)[bidx ^ 2] = (src >> 7) & ~7; + } + + static __device__ __forceinline__ void cvt(uint src, uint& dst) + { + dst = 0; + + dst |= (0xffu & (src << 3)) << (bidx * 8); + dst |= (0xffu & ((src >> 2) & ~7)) << 8; + dst |= (0xffu & ((src >> 7) & ~7)) << ((bidx ^ 2) * 8); + dst |= ((src & 0x8000) * 0xffu) << 24; + } + }; + + template struct RGB5x52RGBConverter<6, bidx> + { + static __device__ __forceinline__ void cvt(uint src, uchar3& dst) + { + (&dst.x)[bidx] = src << 3; + dst.y = (src >> 3) & ~3; + (&dst.x)[bidx ^ 2] = (src >> 8) & ~7; + } + + static __device__ __forceinline__ void cvt(uint src, uint& dst) + { + dst = 0xffu << 24; + + dst |= (0xffu & (src << 3)) << (bidx * 8); + dst |= (0xffu &((src >> 3) & ~3)) << 8; + dst |= (0xffu & ((src >> 8) & ~7)) << ((bidx ^ 2) * 8); + } + }; + + template struct RGB5x52RGB; + + template struct RGB5x52RGB<3, bidx, green_bits> : unary_function + { + __device__ __forceinline__ uchar3 operator()(ushort src) const + { + uchar3 dst; + RGB5x52RGBConverter::cvt(src, dst); + return dst; + } + __host__ __device__ __forceinline__ RGB5x52RGB() {} + __host__ __device__ __forceinline__ RGB5x52RGB(const RGB5x52RGB&) {} + + }; + + template struct RGB5x52RGB<4, bidx, green_bits> : unary_function + { + __device__ __forceinline__ uint operator()(ushort src) const + { + uint dst; + RGB5x52RGBConverter::cvt(src, dst); + return dst; + } + __host__ __device__ __forceinline__ RGB5x52RGB() {} + __host__ __device__ __forceinline__ RGB5x52RGB(const RGB5x52RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB5x52RGB_TRAITS(name, dcn, bidx, green_bits) \ + struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB5x52RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +///////////////////////////////// Grayscale to Color //////////////////////////////// + + namespace color_detail + { + template struct Gray2RGB : unary_function::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator()(T src) const + { + typename TypeVec::vec_type dst; + + dst.z = dst.y = dst.x = src; + setAlpha(dst, ColorChannel::max()); + + return dst; + } + __host__ __device__ __forceinline__ Gray2RGB() {} + __host__ __device__ __forceinline__ Gray2RGB(const Gray2RGB&) {} + }; + + template <> struct Gray2RGB : unary_function + { + __device__ __forceinline__ uint operator()(uint src) const + { + uint dst = 0xffu << 24; + + dst |= src; + dst |= src << 8; + dst |= src << 16; + + return dst; + } + __host__ __device__ __forceinline__ Gray2RGB() {} + __host__ __device__ __forceinline__ Gray2RGB(const Gray2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_GRAY2RGB_TRAITS(name, dcn) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::Gray2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + template struct Gray2RGB5x5Converter; + template<> struct Gray2RGB5x5Converter<6> + { + static __device__ __forceinline__ ushort cvt(uint t) + { + return (ushort)((t >> 3) | ((t & ~3) << 3) | ((t & ~7) << 8)); + } + }; + + template<> struct Gray2RGB5x5Converter<5> + { + static __device__ __forceinline__ ushort cvt(uint t) + { + t >>= 3; + return (ushort)(t | (t << 5) | (t << 10)); + } + }; + + template struct Gray2RGB5x5 : unary_function + { + __device__ __forceinline__ ushort operator()(uint src) const + { + return Gray2RGB5x5Converter::cvt(src); + } + + __host__ __device__ __forceinline__ Gray2RGB5x5() {} + __host__ __device__ __forceinline__ Gray2RGB5x5(const Gray2RGB5x5&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_GRAY2RGB5x5_TRAITS(name, green_bits) \ + struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::Gray2RGB5x5 functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +///////////////////////////////// Color to Grayscale //////////////////////////////// + + namespace color_detail + { + template struct RGB5x52GrayConverter; + template <> struct RGB5x52GrayConverter<6> + { + static __device__ __forceinline__ uchar cvt(uint t) + { + return (uchar)CV_DESCALE(((t << 3) & 0xf8) * BY15 + ((t >> 3) & 0xfc) * GY15 + ((t >> 8) & 0xf8) * RY15, gray_shift); + } + }; + + template <> struct RGB5x52GrayConverter<5> + { + static __device__ __forceinline__ uchar cvt(uint t) + { + return (uchar)CV_DESCALE(((t << 3) & 0xf8) * BY15 + ((t >> 2) & 0xf8) * GY15 + ((t >> 7) & 0xf8) * RY15, gray_shift); + } + }; + + template struct RGB5x52Gray : unary_function + { + __device__ __forceinline__ uchar operator()(uint src) const + { + return RGB5x52GrayConverter::cvt(src); + } + __host__ __device__ __forceinline__ RGB5x52Gray() {} + __host__ __device__ __forceinline__ RGB5x52Gray(const RGB5x52Gray&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB5x52GRAY_TRAITS(name, green_bits) \ + struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB5x52Gray functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + template static __device__ __forceinline__ T RGB2GrayConvert(const T* src) + { + return (T)CV_DESCALE((unsigned)(src[bidx] * BY15 + src[1] * GY15 + src[bidx^2] * RY15), gray_shift); + } + + template static __device__ __forceinline__ uchar RGB2GrayConvert(uint src) + { + uint b = 0xffu & (src >> (bidx * 8)); + uint g = 0xffu & (src >> 8); + uint r = 0xffu & (src >> ((bidx ^ 2) * 8)); + return CV_DESCALE((uint)(b * BY15 + g * GY15 + r * RY15), gray_shift); + } + + template static __device__ __forceinline__ float RGB2GrayConvert(const float* src) + { + return src[bidx] * B2YF + src[1] * G2YF + src[bidx^2] * R2YF; + } + + template struct RGB2Gray : unary_function::vec_type, T> + { + __device__ __forceinline__ T operator()(const typename TypeVec::vec_type& src) const + { + return RGB2GrayConvert(&src.x); + } + __host__ __device__ __forceinline__ RGB2Gray() {} + __host__ __device__ __forceinline__ RGB2Gray(const RGB2Gray&) {} + }; + + template struct RGB2Gray : unary_function + { + __device__ __forceinline__ uchar operator()(uint src) const + { + return RGB2GrayConvert(src); + } + __host__ __device__ __forceinline__ RGB2Gray() {} + __host__ __device__ __forceinline__ RGB2Gray(const RGB2Gray&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2GRAY_TRAITS(name, scn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2Gray functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +///////////////////////////////////// RGB <-> YUV ////////////////////////////////////// + + namespace color_detail + { + __constant__ float c_RGB2YUVCoeffs_f[5] = { B2YF, G2YF, R2YF, B2UF, R2VF }; + __constant__ int c_RGB2YUVCoeffs_i[5] = { B2Y, G2Y, R2Y, B2UI, R2VI }; + + template static __device__ void RGB2YUVConvert(const T* src, D& dst) + { + const int delta = ColorChannel::half() * (1 << yuv_shift); + + const int Y = CV_DESCALE(src[0] * c_RGB2YUVCoeffs_i[bidx^2] + src[1] * c_RGB2YUVCoeffs_i[1] + src[2] * c_RGB2YUVCoeffs_i[bidx], yuv_shift); + const int Cr = CV_DESCALE((src[bidx^2] - Y) * c_RGB2YUVCoeffs_i[3] + delta, yuv_shift); + const int Cb = CV_DESCALE((src[bidx] - Y) * c_RGB2YUVCoeffs_i[4] + delta, yuv_shift); + + dst.x = saturate_cast(Y); + dst.y = saturate_cast(Cr); + dst.z = saturate_cast(Cb); + } + + template static __device__ __forceinline__ void RGB2YUVConvert(const float* src, D& dst) + { + dst.x = src[0] * c_RGB2YUVCoeffs_f[bidx^2] + src[1] * c_RGB2YUVCoeffs_f[1] + src[2] * c_RGB2YUVCoeffs_f[bidx]; + dst.y = (src[bidx^2] - dst.x) * c_RGB2YUVCoeffs_f[3] + ColorChannel::half(); + dst.z = (src[bidx] - dst.x) * c_RGB2YUVCoeffs_f[4] + ColorChannel::half(); + } + + template struct RGB2YUV + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + RGB2YUVConvert(&src.x, dst); + return dst; + } + __host__ __device__ __forceinline__ RGB2YUV() {} + __host__ __device__ __forceinline__ RGB2YUV(const RGB2YUV&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2YUV_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2YUV functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + __constant__ float c_YUV2RGBCoeffs_f[5] = { U2BF, U2GF, V2GF, V2RF }; + __constant__ int c_YUV2RGBCoeffs_i[5] = { U2BI, U2GI, V2GI, V2RI }; + + template static __device__ void YUV2RGBConvert(const T& src, D* dst) + { + const int b = src.x + CV_DESCALE((src.z - ColorChannel::half()) * c_YUV2RGBCoeffs_i[3], yuv_shift); + + const int g = src.x + CV_DESCALE((src.z - ColorChannel::half()) * c_YUV2RGBCoeffs_i[2] + + (src.y - ColorChannel::half()) * c_YUV2RGBCoeffs_i[1], yuv_shift); + + const int r = src.x + CV_DESCALE((src.y - ColorChannel::half()) * c_YUV2RGBCoeffs_i[0], yuv_shift); + + dst[bidx] = saturate_cast(b); + dst[1] = saturate_cast(g); + dst[bidx^2] = saturate_cast(r); + } + + template static __device__ uint YUV2RGBConvert(uint src) + { + const int x = 0xff & (src); + const int y = 0xff & (src >> 8); + const int z = 0xff & (src >> 16); + + const int b = x + CV_DESCALE((z - ColorChannel::half()) * c_YUV2RGBCoeffs_i[3], yuv_shift); + + const int g = x + CV_DESCALE((z - ColorChannel::half()) * c_YUV2RGBCoeffs_i[2] + + (y - ColorChannel::half()) * c_YUV2RGBCoeffs_i[1], yuv_shift); + + const int r = x + CV_DESCALE((y - ColorChannel::half()) * c_YUV2RGBCoeffs_i[0], yuv_shift); + + uint dst = 0xffu << 24; + + dst |= saturate_cast(b) << (bidx * 8); + dst |= saturate_cast(g) << 8; + dst |= saturate_cast(r) << ((bidx ^ 2) * 8); + + return dst; + } + + template static __device__ __forceinline__ void YUV2RGBConvert(const T& src, float* dst) + { + dst[bidx] = src.x + (src.z - ColorChannel::half()) * c_YUV2RGBCoeffs_f[3]; + + dst[1] = src.x + (src.z - ColorChannel::half()) * c_YUV2RGBCoeffs_f[2] + + (src.y - ColorChannel::half()) * c_YUV2RGBCoeffs_f[1]; + + dst[bidx^2] = src.x + (src.y - ColorChannel::half()) * c_YUV2RGBCoeffs_f[0]; + } + + template struct YUV2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + YUV2RGBConvert(src, &dst.x); + setAlpha(dst, ColorChannel::max()); + + return dst; + } + __host__ __device__ __forceinline__ YUV2RGB() {} + __host__ __device__ __forceinline__ YUV2RGB(const YUV2RGB&) {} + }; + + template struct YUV2RGB : unary_function + { + __device__ __forceinline__ uint operator ()(uint src) const + { + return YUV2RGBConvert(src); + } + __host__ __device__ __forceinline__ YUV2RGB() {} + __host__ __device__ __forceinline__ YUV2RGB(const YUV2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_YUV2RGB_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::YUV2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +///////////////////////////////////// RGB <-> YCrCb ////////////////////////////////////// + + namespace color_detail + { + __constant__ float c_RGB2YCrCbCoeffs_f[5] = {R2YF, G2YF, B2YF, YCRF, YCBF}; + __constant__ int c_RGB2YCrCbCoeffs_i[5] = {R2Y, G2Y, B2Y, YCRI, YCBI}; + + template static __device__ void RGB2YCrCbConvert(const T* src, D& dst) + { + const int delta = ColorChannel::half() * (1 << yuv_shift); + + const int Y = CV_DESCALE(src[0] * c_RGB2YCrCbCoeffs_i[bidx^2] + src[1] * c_RGB2YCrCbCoeffs_i[1] + src[2] * c_RGB2YCrCbCoeffs_i[bidx], yuv_shift); + const int Cr = CV_DESCALE((src[bidx^2] - Y) * c_RGB2YCrCbCoeffs_i[3] + delta, yuv_shift); + const int Cb = CV_DESCALE((src[bidx] - Y) * c_RGB2YCrCbCoeffs_i[4] + delta, yuv_shift); + + dst.x = saturate_cast(Y); + dst.y = saturate_cast(Cr); + dst.z = saturate_cast(Cb); + } + + template static __device__ uint RGB2YCrCbConvert(uint src) + { + const int delta = ColorChannel::half() * (1 << yuv_shift); + + const int Y = CV_DESCALE((0xffu & src) * c_RGB2YCrCbCoeffs_i[bidx^2] + (0xffu & (src >> 8)) * c_RGB2YCrCbCoeffs_i[1] + (0xffu & (src >> 16)) * c_RGB2YCrCbCoeffs_i[bidx], yuv_shift); + const int Cr = CV_DESCALE(((0xffu & (src >> ((bidx ^ 2) * 8))) - Y) * c_RGB2YCrCbCoeffs_i[3] + delta, yuv_shift); + const int Cb = CV_DESCALE(((0xffu & (src >> (bidx * 8))) - Y) * c_RGB2YCrCbCoeffs_i[4] + delta, yuv_shift); + + uint dst = 0; + + dst |= saturate_cast(Y); + dst |= saturate_cast(Cr) << 8; + dst |= saturate_cast(Cb) << 16; + + return dst; + } + + template static __device__ __forceinline__ void RGB2YCrCbConvert(const float* src, D& dst) + { + dst.x = src[0] * c_RGB2YCrCbCoeffs_f[bidx^2] + src[1] * c_RGB2YCrCbCoeffs_f[1] + src[2] * c_RGB2YCrCbCoeffs_f[bidx]; + dst.y = (src[bidx^2] - dst.x) * c_RGB2YCrCbCoeffs_f[3] + ColorChannel::half(); + dst.z = (src[bidx] - dst.x) * c_RGB2YCrCbCoeffs_f[4] + ColorChannel::half(); + } + + template struct RGB2YCrCb + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + RGB2YCrCbConvert(&src.x, dst); + return dst; + } + __host__ __device__ __forceinline__ RGB2YCrCb() {} + __host__ __device__ __forceinline__ RGB2YCrCb(const RGB2YCrCb&) {} + }; + + template struct RGB2YCrCb : unary_function + { + __device__ __forceinline__ uint operator ()(uint src) const + { + return RGB2YCrCbConvert(src); + } + + __host__ __device__ __forceinline__ RGB2YCrCb() {} + __host__ __device__ __forceinline__ RGB2YCrCb(const RGB2YCrCb&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2YCrCb_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2YCrCb functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + __constant__ float c_YCrCb2RGBCoeffs_f[5] = {CR2RF, CR2GF, CB2GF, CB2BF}; + __constant__ int c_YCrCb2RGBCoeffs_i[5] = {CR2RI, CR2GI, CB2GI, CB2BI}; + + template static __device__ void YCrCb2RGBConvert(const T& src, D* dst) + { + const int b = src.x + CV_DESCALE((src.z - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[3], yuv_shift); + const int g = src.x + CV_DESCALE((src.z - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[2] + (src.y - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[1], yuv_shift); + const int r = src.x + CV_DESCALE((src.y - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[0], yuv_shift); + + dst[bidx] = saturate_cast(b); + dst[1] = saturate_cast(g); + dst[bidx^2] = saturate_cast(r); + } + + template static __device__ uint YCrCb2RGBConvert(uint src) + { + const int x = 0xff & (src); + const int y = 0xff & (src >> 8); + const int z = 0xff & (src >> 16); + + const int b = x + CV_DESCALE((z - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[3], yuv_shift); + const int g = x + CV_DESCALE((z - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[2] + (y - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[1], yuv_shift); + const int r = x + CV_DESCALE((y - ColorChannel::half()) * c_YCrCb2RGBCoeffs_i[0], yuv_shift); + + uint dst = 0xffu << 24; + + dst |= saturate_cast(b) << (bidx * 8); + dst |= saturate_cast(g) << 8; + dst |= saturate_cast(r) << ((bidx ^ 2) * 8); + + return dst; + } + + template __device__ __forceinline__ void YCrCb2RGBConvert(const T& src, float* dst) + { + dst[bidx] = src.x + (src.z - ColorChannel::half()) * c_YCrCb2RGBCoeffs_f[3]; + dst[1] = src.x + (src.z - ColorChannel::half()) * c_YCrCb2RGBCoeffs_f[2] + (src.y - ColorChannel::half()) * c_YCrCb2RGBCoeffs_f[1]; + dst[bidx^2] = src.x + (src.y - ColorChannel::half()) * c_YCrCb2RGBCoeffs_f[0]; + } + + template struct YCrCb2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + YCrCb2RGBConvert(src, &dst.x); + setAlpha(dst, ColorChannel::max()); + + return dst; + } + __host__ __device__ __forceinline__ YCrCb2RGB() {} + __host__ __device__ __forceinline__ YCrCb2RGB(const YCrCb2RGB&) {} + }; + + template struct YCrCb2RGB : unary_function + { + __device__ __forceinline__ uint operator ()(uint src) const + { + return YCrCb2RGBConvert(src); + } + __host__ __device__ __forceinline__ YCrCb2RGB() {} + __host__ __device__ __forceinline__ YCrCb2RGB(const YCrCb2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_YCrCb2RGB_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::YCrCb2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +////////////////////////////////////// RGB <-> XYZ /////////////////////////////////////// + + namespace color_detail + { + __constant__ float c_RGB2XYZ_D65f[9] = { 0.412453f, 0.357580f, 0.180423f, 0.212671f, 0.715160f, 0.072169f, 0.019334f, 0.119193f, 0.950227f }; + __constant__ int c_RGB2XYZ_D65i[9] = { 1689, 1465, 739, 871, 2929, 296, 79, 488, 3892 }; + + template static __device__ __forceinline__ void RGB2XYZConvert(const T* src, D& dst) + { + dst.z = saturate_cast(CV_DESCALE(src[bidx^2] * c_RGB2XYZ_D65i[6] + src[1] * c_RGB2XYZ_D65i[7] + src[bidx] * c_RGB2XYZ_D65i[8], xyz_shift)); + dst.x = saturate_cast(CV_DESCALE(src[bidx^2] * c_RGB2XYZ_D65i[0] + src[1] * c_RGB2XYZ_D65i[1] + src[bidx] * c_RGB2XYZ_D65i[2], xyz_shift)); + dst.y = saturate_cast(CV_DESCALE(src[bidx^2] * c_RGB2XYZ_D65i[3] + src[1] * c_RGB2XYZ_D65i[4] + src[bidx] * c_RGB2XYZ_D65i[5], xyz_shift)); + } + + template static __device__ __forceinline__ uint RGB2XYZConvert(uint src) + { + const uint b = 0xffu & (src >> (bidx * 8)); + const uint g = 0xffu & (src >> 8); + const uint r = 0xffu & (src >> ((bidx ^ 2) * 8)); + + const uint x = saturate_cast(CV_DESCALE(r * c_RGB2XYZ_D65i[0] + g * c_RGB2XYZ_D65i[1] + b * c_RGB2XYZ_D65i[2], xyz_shift)); + const uint y = saturate_cast(CV_DESCALE(r * c_RGB2XYZ_D65i[3] + g * c_RGB2XYZ_D65i[4] + b * c_RGB2XYZ_D65i[5], xyz_shift)); + const uint z = saturate_cast(CV_DESCALE(r * c_RGB2XYZ_D65i[6] + g * c_RGB2XYZ_D65i[7] + b * c_RGB2XYZ_D65i[8], xyz_shift)); + + uint dst = 0; + + dst |= x; + dst |= y << 8; + dst |= z << 16; + + return dst; + } + + template static __device__ __forceinline__ void RGB2XYZConvert(const float* src, D& dst) + { + dst.x = src[bidx^2] * c_RGB2XYZ_D65f[0] + src[1] * c_RGB2XYZ_D65f[1] + src[bidx] * c_RGB2XYZ_D65f[2]; + dst.y = src[bidx^2] * c_RGB2XYZ_D65f[3] + src[1] * c_RGB2XYZ_D65f[4] + src[bidx] * c_RGB2XYZ_D65f[5]; + dst.z = src[bidx^2] * c_RGB2XYZ_D65f[6] + src[1] * c_RGB2XYZ_D65f[7] + src[bidx] * c_RGB2XYZ_D65f[8]; + } + + template struct RGB2XYZ + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + RGB2XYZConvert(&src.x, dst); + + return dst; + } + __host__ __device__ __forceinline__ RGB2XYZ() {} + __host__ __device__ __forceinline__ RGB2XYZ(const RGB2XYZ&) {} + }; + + template struct RGB2XYZ : unary_function + { + __device__ __forceinline__ uint operator()(uint src) const + { + return RGB2XYZConvert(src); + } + __host__ __device__ __forceinline__ RGB2XYZ() {} + __host__ __device__ __forceinline__ RGB2XYZ(const RGB2XYZ&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2XYZ_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2XYZ functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + __constant__ float c_XYZ2sRGB_D65f[9] = { 3.240479f, -1.53715f, -0.498535f, -0.969256f, 1.875991f, 0.041556f, 0.055648f, -0.204043f, 1.057311f }; + __constant__ int c_XYZ2sRGB_D65i[9] = { 13273, -6296, -2042, -3970, 7684, 170, 228, -836, 4331 }; + + template static __device__ __forceinline__ void XYZ2RGBConvert(const T& src, D* dst) + { + dst[bidx^2] = saturate_cast(CV_DESCALE(src.x * c_XYZ2sRGB_D65i[0] + src.y * c_XYZ2sRGB_D65i[1] + src.z * c_XYZ2sRGB_D65i[2], xyz_shift)); + dst[1] = saturate_cast(CV_DESCALE(src.x * c_XYZ2sRGB_D65i[3] + src.y * c_XYZ2sRGB_D65i[4] + src.z * c_XYZ2sRGB_D65i[5], xyz_shift)); + dst[bidx] = saturate_cast(CV_DESCALE(src.x * c_XYZ2sRGB_D65i[6] + src.y * c_XYZ2sRGB_D65i[7] + src.z * c_XYZ2sRGB_D65i[8], xyz_shift)); + } + + template static __device__ __forceinline__ uint XYZ2RGBConvert(uint src) + { + const int x = 0xff & src; + const int y = 0xff & (src >> 8); + const int z = 0xff & (src >> 16); + + const uint r = saturate_cast(CV_DESCALE(x * c_XYZ2sRGB_D65i[0] + y * c_XYZ2sRGB_D65i[1] + z * c_XYZ2sRGB_D65i[2], xyz_shift)); + const uint g = saturate_cast(CV_DESCALE(x * c_XYZ2sRGB_D65i[3] + y * c_XYZ2sRGB_D65i[4] + z * c_XYZ2sRGB_D65i[5], xyz_shift)); + const uint b = saturate_cast(CV_DESCALE(x * c_XYZ2sRGB_D65i[6] + y * c_XYZ2sRGB_D65i[7] + z * c_XYZ2sRGB_D65i[8], xyz_shift)); + + uint dst = 0xffu << 24; + + dst |= b << (bidx * 8); + dst |= g << 8; + dst |= r << ((bidx ^ 2) * 8); + + return dst; + } + + template static __device__ __forceinline__ void XYZ2RGBConvert(const T& src, float* dst) + { + dst[bidx^2] = src.x * c_XYZ2sRGB_D65f[0] + src.y * c_XYZ2sRGB_D65f[1] + src.z * c_XYZ2sRGB_D65f[2]; + dst[1] = src.x * c_XYZ2sRGB_D65f[3] + src.y * c_XYZ2sRGB_D65f[4] + src.z * c_XYZ2sRGB_D65f[5]; + dst[bidx] = src.x * c_XYZ2sRGB_D65f[6] + src.y * c_XYZ2sRGB_D65f[7] + src.z * c_XYZ2sRGB_D65f[8]; + } + + template struct XYZ2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + XYZ2RGBConvert(src, &dst.x); + setAlpha(dst, ColorChannel::max()); + + return dst; + } + __host__ __device__ __forceinline__ XYZ2RGB() {} + __host__ __device__ __forceinline__ XYZ2RGB(const XYZ2RGB&) {} + }; + + template struct XYZ2RGB : unary_function + { + __device__ __forceinline__ uint operator()(uint src) const + { + return XYZ2RGBConvert(src); + } + __host__ __device__ __forceinline__ XYZ2RGB() {} + __host__ __device__ __forceinline__ XYZ2RGB(const XYZ2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_XYZ2RGB_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::XYZ2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +////////////////////////////////////// RGB <-> HSV /////////////////////////////////////// + + namespace color_detail + { + __constant__ int c_HsvDivTable [256] = {0, 1044480, 522240, 348160, 261120, 208896, 174080, 149211, 130560, 116053, 104448, 94953, 87040, 80345, 74606, 69632, 65280, 61440, 58027, 54973, 52224, 49737, 47476, 45412, 43520, 41779, 40172, 38684, 37303, 36017, 34816, 33693, 32640, 31651, 30720, 29842, 29013, 28229, 27486, 26782, 26112, 25475, 24869, 24290, 23738, 23211, 22706, 22223, 21760, 21316, 20890, 20480, 20086, 19707, 19342, 18991, 18651, 18324, 18008, 17703, 17408, 17123, 16846, 16579, 16320, 16069, 15825, 15589, 15360, 15137, 14921, 14711, 14507, 14308, 14115, 13926, 13743, 13565, 13391, 13221, 13056, 12895, 12738, 12584, 12434, 12288, 12145, 12006, 11869, 11736, 11605, 11478, 11353, 11231, 11111, 10995, 10880, 10768, 10658, 10550, 10445, 10341, 10240, 10141, 10043, 9947, 9854, 9761, 9671, 9582, 9495, 9410, 9326, 9243, 9162, 9082, 9004, 8927, 8852, 8777, 8704, 8632, 8561, 8492, 8423, 8356, 8290, 8224, 8160, 8097, 8034, 7973, 7913, 7853, 7795, 7737, 7680, 7624, 7569, 7514, 7461, 7408, 7355, 7304, 7253, 7203, 7154, 7105, 7057, 7010, 6963, 6917, 6872, 6827, 6782, 6739, 6695, 6653, 6611, 6569, 6528, 6487, 6447, 6408, 6369, 6330, 6292, 6254, 6217, 6180, 6144, 6108, 6073, 6037, 6003, 5968, 5935, 5901, 5868, 5835, 5803, 5771, 5739, 5708, 5677, 5646, 5615, 5585, 5556, 5526, 5497, 5468, 5440, 5412, 5384, 5356, 5329, 5302, 5275, 5249, 5222, 5196, 5171, 5145, 5120, 5095, 5070, 5046, 5022, 4998, 4974, 4950, 4927, 4904, 4881, 4858, 4836, 4813, 4791, 4769, 4748, 4726, 4705, 4684, 4663, 4642, 4622, 4601, 4581, 4561, 4541, 4522, 4502, 4483, 4464, 4445, 4426, 4407, 4389, 4370, 4352, 4334, 4316, 4298, 4281, 4263, 4246, 4229, 4212, 4195, 4178, 4161, 4145, 4128, 4112, 4096}; + __constant__ int c_HsvDivTable180[256] = {0, 122880, 61440, 40960, 30720, 24576, 20480, 17554, 15360, 13653, 12288, 11171, 10240, 9452, 8777, 8192, 7680, 7228, 6827, 6467, 6144, 5851, 5585, 5343, 5120, 4915, 4726, 4551, 4389, 4237, 4096, 3964, 3840, 3724, 3614, 3511, 3413, 3321, 3234, 3151, 3072, 2997, 2926, 2858, 2793, 2731, 2671, 2614, 2560, 2508, 2458, 2409, 2363, 2318, 2276, 2234, 2194, 2156, 2119, 2083, 2048, 2014, 1982, 1950, 1920, 1890, 1862, 1834, 1807, 1781, 1755, 1731, 1707, 1683, 1661, 1638, 1617, 1596, 1575, 1555, 1536, 1517, 1499, 1480, 1463, 1446, 1429, 1412, 1396, 1381, 1365, 1350, 1336, 1321, 1307, 1293, 1280, 1267, 1254, 1241, 1229, 1217, 1205, 1193, 1182, 1170, 1159, 1148, 1138, 1127, 1117, 1107, 1097, 1087, 1078, 1069, 1059, 1050, 1041, 1033, 1024, 1016, 1007, 999, 991, 983, 975, 968, 960, 953, 945, 938, 931, 924, 917, 910, 904, 897, 890, 884, 878, 871, 865, 859, 853, 847, 842, 836, 830, 825, 819, 814, 808, 803, 798, 793, 788, 783, 778, 773, 768, 763, 759, 754, 749, 745, 740, 736, 731, 727, 723, 719, 714, 710, 706, 702, 698, 694, 690, 686, 683, 679, 675, 671, 668, 664, 661, 657, 654, 650, 647, 643, 640, 637, 633, 630, 627, 624, 621, 617, 614, 611, 608, 605, 602, 599, 597, 594, 591, 588, 585, 582, 580, 577, 574, 572, 569, 566, 564, 561, 559, 556, 554, 551, 549, 546, 544, 541, 539, 537, 534, 532, 530, 527, 525, 523, 521, 518, 516, 514, 512, 510, 508, 506, 504, 502, 500, 497, 495, 493, 492, 490, 488, 486, 484, 482}; + __constant__ int c_HsvDivTable256[256] = {0, 174763, 87381, 58254, 43691, 34953, 29127, 24966, 21845, 19418, 17476, 15888, 14564, 13443, 12483, 11651, 10923, 10280, 9709, 9198, 8738, 8322, 7944, 7598, 7282, 6991, 6722, 6473, 6242, 6026, 5825, 5638, 5461, 5296, 5140, 4993, 4855, 4723, 4599, 4481, 4369, 4263, 4161, 4064, 3972, 3884, 3799, 3718, 3641, 3567, 3495, 3427, 3361, 3297, 3236, 3178, 3121, 3066, 3013, 2962, 2913, 2865, 2819, 2774, 2731, 2689, 2648, 2608, 2570, 2533, 2497, 2461, 2427, 2394, 2362, 2330, 2300, 2270, 2241, 2212, 2185, 2158, 2131, 2106, 2081, 2056, 2032, 2009, 1986, 1964, 1942, 1920, 1900, 1879, 1859, 1840, 1820, 1802, 1783, 1765, 1748, 1730, 1713, 1697, 1680, 1664, 1649, 1633, 1618, 1603, 1589, 1574, 1560, 1547, 1533, 1520, 1507, 1494, 1481, 1469, 1456, 1444, 1432, 1421, 1409, 1398, 1387, 1376, 1365, 1355, 1344, 1334, 1324, 1314, 1304, 1295, 1285, 1276, 1266, 1257, 1248, 1239, 1231, 1222, 1214, 1205, 1197, 1189, 1181, 1173, 1165, 1157, 1150, 1142, 1135, 1128, 1120, 1113, 1106, 1099, 1092, 1085, 1079, 1072, 1066, 1059, 1053, 1046, 1040, 1034, 1028, 1022, 1016, 1010, 1004, 999, 993, 987, 982, 976, 971, 966, 960, 955, 950, 945, 940, 935, 930, 925, 920, 915, 910, 906, 901, 896, 892, 887, 883, 878, 874, 869, 865, 861, 857, 853, 848, 844, 840, 836, 832, 828, 824, 820, 817, 813, 809, 805, 802, 798, 794, 791, 787, 784, 780, 777, 773, 770, 767, 763, 760, 757, 753, 750, 747, 744, 741, 737, 734, 731, 728, 725, 722, 719, 716, 713, 710, 708, 705, 702, 699, 696, 694, 691, 688, 685}; + + template static __device__ void RGB2HSVConvert(const uchar* src, D& dst) + { + const int hsv_shift = 12; + const int* hdiv_table = hr == 180 ? c_HsvDivTable180 : c_HsvDivTable256; + + int b = src[bidx], g = src[1], r = src[bidx^2]; + int h, s, v = b; + int vmin = b, diff; + int vr, vg; + + v = ::max(v, g); + v = ::max(v, r); + vmin = ::min(vmin, g); + vmin = ::min(vmin, r); + + diff = v - vmin; + vr = (v == r) * -1; + vg = (v == g) * -1; + + s = (diff * c_HsvDivTable[v] + (1 << (hsv_shift-1))) >> hsv_shift; + h = (vr & (g - b)) + (~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff)))); + h = (h * hdiv_table[diff] + (1 << (hsv_shift-1))) >> hsv_shift; + h += (h < 0) * hr; + + dst.x = saturate_cast(h); + dst.y = (uchar)s; + dst.z = (uchar)v; + } + + template static __device__ uint RGB2HSVConvert(uint src) + { + const int hsv_shift = 12; + const int* hdiv_table = hr == 180 ? c_HsvDivTable180 : c_HsvDivTable256; + + const int b = 0xff & (src >> (bidx * 8)); + const int g = 0xff & (src >> 8); + const int r = 0xff & (src >> ((bidx ^ 2) * 8)); + + int h, s, v = b; + int vmin = b, diff; + int vr, vg; + + v = ::max(v, g); + v = ::max(v, r); + vmin = ::min(vmin, g); + vmin = ::min(vmin, r); + + diff = v - vmin; + vr = (v == r) * -1; + vg = (v == g) * -1; + + s = (diff * c_HsvDivTable[v] + (1 << (hsv_shift-1))) >> hsv_shift; + h = (vr & (g - b)) + (~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff)))); + h = (h * hdiv_table[diff] + (1 << (hsv_shift-1))) >> hsv_shift; + h += (h < 0) * hr; + + uint dst = 0; + + dst |= saturate_cast(h); + dst |= (0xffu & s) << 8; + dst |= (0xffu & v) << 16; + + return dst; + } + + template static __device__ void RGB2HSVConvert(const float* src, D& dst) + { + const float hscale = hr * (1.f / 360.f); + + float b = src[bidx], g = src[1], r = src[bidx^2]; + float h, s, v; + + float vmin, diff; + + v = vmin = r; + v = fmax(v, g); + v = fmax(v, b); + vmin = fmin(vmin, g); + vmin = fmin(vmin, b); + + diff = v - vmin; + s = diff / (float)(::fabs(v) + numeric_limits::epsilon()); + diff = (float)(60. / (diff + numeric_limits::epsilon())); + + h = (v == r) * (g - b) * diff; + h += (v != r && v == g) * ((b - r) * diff + 120.f); + h += (v != r && v != g) * ((r - g) * diff + 240.f); + h += (h < 0) * 360.f; + + dst.x = h * hscale; + dst.y = s; + dst.z = v; + } + + template struct RGB2HSV + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + RGB2HSVConvert(&src.x, dst); + + return dst; + } + __host__ __device__ __forceinline__ RGB2HSV() {} + __host__ __device__ __forceinline__ RGB2HSV(const RGB2HSV&) {} + }; + + template struct RGB2HSV : unary_function + { + __device__ __forceinline__ uint operator()(uint src) const + { + return RGB2HSVConvert(src); + } + __host__ __device__ __forceinline__ RGB2HSV() {} + __host__ __device__ __forceinline__ RGB2HSV(const RGB2HSV&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2HSV_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HSV functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HSV functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HSV functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HSV functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + __constant__ int c_HsvSectorData[6][3] = { {1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0} }; + + template static __device__ void HSV2RGBConvert(const T& src, float* dst) + { + const float hscale = 6.f / hr; + + float h = src.x, s = src.y, v = src.z; + float b = v, g = v, r = v; + + if (s != 0) + { + h *= hscale; + + if( h < 0 ) + do h += 6; while( h < 0 ); + else if( h >= 6 ) + do h -= 6; while( h >= 6 ); + + int sector = __float2int_rd(h); + h -= sector; + + if ( (unsigned)sector >= 6u ) + { + sector = 0; + h = 0.f; + } + + float tab[4]; + tab[0] = v; + tab[1] = v * (1.f - s); + tab[2] = v * (1.f - s * h); + tab[3] = v * (1.f - s * (1.f - h)); + + b = tab[c_HsvSectorData[sector][0]]; + g = tab[c_HsvSectorData[sector][1]]; + r = tab[c_HsvSectorData[sector][2]]; + } + + dst[bidx] = b; + dst[1] = g; + dst[bidx^2] = r; + } + + template static __device__ void HSV2RGBConvert(const T& src, uchar* dst) + { + float3 buf; + + buf.x = src.x; + buf.y = src.y * (1.f / 255.f); + buf.z = src.z * (1.f / 255.f); + + HSV2RGBConvert(buf, &buf.x); + + dst[0] = saturate_cast(buf.x * 255.f); + dst[1] = saturate_cast(buf.y * 255.f); + dst[2] = saturate_cast(buf.z * 255.f); + } + + template static __device__ uint HSV2RGBConvert(uint src) + { + float3 buf; + + buf.x = src & 0xff; + buf.y = ((src >> 8) & 0xff) * (1.f/255.f); + buf.z = ((src >> 16) & 0xff) * (1.f/255.f); + + HSV2RGBConvert(buf, &buf.x); + + uint dst = 0xffu << 24; + + dst |= saturate_cast(buf.x * 255.f); + dst |= saturate_cast(buf.y * 255.f) << 8; + dst |= saturate_cast(buf.z * 255.f) << 16; + + return dst; + } + + template struct HSV2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + HSV2RGBConvert(src, &dst.x); + setAlpha(dst, ColorChannel::max()); + + return dst; + } + __host__ __device__ __forceinline__ HSV2RGB() {} + __host__ __device__ __forceinline__ HSV2RGB(const HSV2RGB&) {} + }; + + template struct HSV2RGB : unary_function + { + __device__ __forceinline__ uint operator()(uint src) const + { + return HSV2RGBConvert(src); + } + __host__ __device__ __forceinline__ HSV2RGB() {} + __host__ __device__ __forceinline__ HSV2RGB(const HSV2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_HSV2RGB_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::HSV2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::HSV2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::HSV2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::HSV2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +/////////////////////////////////////// RGB <-> HLS //////////////////////////////////////// + + namespace color_detail + { + template static __device__ void RGB2HLSConvert(const float* src, D& dst) + { + const float hscale = hr * (1.f / 360.f); + + float b = src[bidx], g = src[1], r = src[bidx^2]; + float h = 0.f, s = 0.f, l; + float vmin, vmax, diff; + + vmax = vmin = r; + vmax = fmax(vmax, g); + vmax = fmax(vmax, b); + vmin = fmin(vmin, g); + vmin = fmin(vmin, b); + + diff = vmax - vmin; + l = (vmax + vmin) * 0.5f; + + if (diff > numeric_limits::epsilon()) + { + s = (l < 0.5f) * diff / (vmax + vmin); + s += (l >= 0.5f) * diff / (2.0f - vmax - vmin); + + diff = 60.f / diff; + + h = (vmax == r) * (g - b) * diff; + h += (vmax != r && vmax == g) * ((b - r) * diff + 120.f); + h += (vmax != r && vmax != g) * ((r - g) * diff + 240.f); + h += (h < 0.f) * 360.f; + } + + dst.x = h * hscale; + dst.y = l; + dst.z = s; + } + + template static __device__ void RGB2HLSConvert(const uchar* src, D& dst) + { + float3 buf; + + buf.x = src[0] * (1.f / 255.f); + buf.y = src[1] * (1.f / 255.f); + buf.z = src[2] * (1.f / 255.f); + + RGB2HLSConvert(&buf.x, buf); + + dst.x = saturate_cast(buf.x); + dst.y = saturate_cast(buf.y*255.f); + dst.z = saturate_cast(buf.z*255.f); + } + + template static __device__ uint RGB2HLSConvert(uint src) + { + float3 buf; + + buf.x = (0xff & src) * (1.f / 255.f); + buf.y = (0xff & (src >> 8)) * (1.f / 255.f); + buf.z = (0xff & (src >> 16)) * (1.f / 255.f); + + RGB2HLSConvert(&buf.x, buf); + + uint dst = 0xffu << 24; + + dst |= saturate_cast(buf.x); + dst |= saturate_cast(buf.y * 255.f) << 8; + dst |= saturate_cast(buf.z * 255.f) << 16; + + return dst; + } + + template struct RGB2HLS + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + RGB2HLSConvert(&src.x, dst); + + return dst; + } + __host__ __device__ __forceinline__ RGB2HLS() {} + __host__ __device__ __forceinline__ RGB2HLS(const RGB2HLS&) {} + }; + + template struct RGB2HLS : unary_function + { + __device__ __forceinline__ uint operator()(uint src) const + { + return RGB2HLSConvert(src); + } + __host__ __device__ __forceinline__ RGB2HLS() {} + __host__ __device__ __forceinline__ RGB2HLS(const RGB2HLS&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2HLS_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HLS functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HLS functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HLS functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2HLS functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + __constant__ int c_HlsSectorData[6][3] = { {1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0} }; + + template static __device__ void HLS2RGBConvert(const T& src, float* dst) + { + const float hscale = 6.0f / hr; + + float h = src.x, l = src.y, s = src.z; + float b = l, g = l, r = l; + + if (s != 0) + { + float p2 = (l <= 0.5f) * l * (1 + s); + p2 += (l > 0.5f) * (l + s - l * s); + float p1 = 2 * l - p2; + + h *= hscale; + + if( h < 0 ) + do h += 6; while( h < 0 ); + else if( h >= 6 ) + do h -= 6; while( h >= 6 ); + + int sector; + sector = __float2int_rd(h); + + h -= sector; + + float tab[4]; + tab[0] = p2; + tab[1] = p1; + tab[2] = p1 + (p2 - p1) * (1 - h); + tab[3] = p1 + (p2 - p1) * h; + + b = tab[c_HlsSectorData[sector][0]]; + g = tab[c_HlsSectorData[sector][1]]; + r = tab[c_HlsSectorData[sector][2]]; + } + + dst[bidx] = b; + dst[1] = g; + dst[bidx^2] = r; + } + + template static __device__ void HLS2RGBConvert(const T& src, uchar* dst) + { + float3 buf; + + buf.x = src.x; + buf.y = src.y * (1.f / 255.f); + buf.z = src.z * (1.f / 255.f); + + HLS2RGBConvert(buf, &buf.x); + + dst[0] = saturate_cast(buf.x * 255.f); + dst[1] = saturate_cast(buf.y * 255.f); + dst[2] = saturate_cast(buf.z * 255.f); + } + + template static __device__ uint HLS2RGBConvert(uint src) + { + float3 buf; + + buf.x = 0xff & src; + buf.y = (0xff & (src >> 8)) * (1.f / 255.f); + buf.z = (0xff & (src >> 16)) * (1.f / 255.f); + + HLS2RGBConvert(buf, &buf.x); + + uint dst = 0xffu << 24; + + dst |= saturate_cast(buf.x * 255.f); + dst |= saturate_cast(buf.y * 255.f) << 8; + dst |= saturate_cast(buf.z * 255.f) << 16; + + return dst; + } + + template struct HLS2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + HLS2RGBConvert(src, &dst.x); + setAlpha(dst, ColorChannel::max()); + + return dst; + } + __host__ __device__ __forceinline__ HLS2RGB() {} + __host__ __device__ __forceinline__ HLS2RGB(const HLS2RGB&) {} + }; + + template struct HLS2RGB : unary_function + { + __device__ __forceinline__ uint operator()(uint src) const + { + return HLS2RGBConvert(src); + } + __host__ __device__ __forceinline__ HLS2RGB() {} + __host__ __device__ __forceinline__ HLS2RGB(const HLS2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_HLS2RGB_TRAITS(name, scn, dcn, bidx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::HLS2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::HLS2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::HLS2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; \ + template <> struct name ## _full_traits \ + { \ + typedef ::cv::cuda::device::color_detail::HLS2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +///////////////////////////////////// RGB <-> Lab ///////////////////////////////////// + + namespace color_detail + { + enum + { + LAB_CBRT_TAB_SIZE = 1024, + GAMMA_TAB_SIZE = 1024, + lab_shift = xyz_shift, + gamma_shift = 3, + lab_shift2 = (lab_shift + gamma_shift), + LAB_CBRT_TAB_SIZE_B = (256 * 3 / 2 * (1 << gamma_shift)) + }; + + __constant__ ushort c_sRGBGammaTab_b[] = {0,1,1,2,2,3,4,4,5,6,6,7,8,8,9,10,11,11,12,13,14,15,16,17,19,20,21,22,24,25,26,28,29,31,33,34,36,38,40,41,43,45,47,49,51,54,56,58,60,63,65,68,70,73,75,78,81,83,86,89,92,95,98,101,105,108,111,115,118,121,125,129,132,136,140,144,147,151,155,160,164,168,172,176,181,185,190,194,199,204,209,213,218,223,228,233,239,244,249,255,260,265,271,277,282,288,294,300,306,312,318,324,331,337,343,350,356,363,370,376,383,390,397,404,411,418,426,433,440,448,455,463,471,478,486,494,502,510,518,527,535,543,552,560,569,578,586,595,604,613,622,631,641,650,659,669,678,688,698,707,717,727,737,747,757,768,778,788,799,809,820,831,842,852,863,875,886,897,908,920,931,943,954,966,978,990,1002,1014,1026,1038,1050,1063,1075,1088,1101,1113,1126,1139,1152,1165,1178,1192,1205,1218,1232,1245,1259,1273,1287,1301,1315,1329,1343,1357,1372,1386,1401,1415,1430,1445,1460,1475,1490,1505,1521,1536,1551,1567,1583,1598,1614,1630,1646,1662,1678,1695,1711,1728,1744,1761,1778,1794,1811,1828,1846,1863,1880,1897,1915,1933,1950,1968,1986,2004,2022,2040}; + + __device__ __forceinline__ int LabCbrt_b(int i) + { + float x = i * (1.f / (255.f * (1 << gamma_shift))); + return (1 << lab_shift2) * (x < 0.008856f ? x * 7.787f + 0.13793103448275862f : ::cbrtf(x)); + } + + template + __device__ __forceinline__ void RGB2LabConvert_b(const T& src, D& dst) + { + const int Lscale = (116 * 255 + 50) / 100; + const int Lshift = -((16 * 255 * (1 << lab_shift2) + 50) / 100); + + int B = blueIdx == 0 ? src.x : src.z; + int G = src.y; + int R = blueIdx == 0 ? src.z : src.x; + + if (srgb) + { + B = c_sRGBGammaTab_b[B]; + G = c_sRGBGammaTab_b[G]; + R = c_sRGBGammaTab_b[R]; + } + else + { + B <<= 3; + G <<= 3; + R <<= 3; + } + + int fX = LabCbrt_b(CV_DESCALE(B * 778 + G * 1541 + R * 1777, lab_shift)); + int fY = LabCbrt_b(CV_DESCALE(B * 296 + G * 2929 + R * 871, lab_shift)); + int fZ = LabCbrt_b(CV_DESCALE(B * 3575 + G * 448 + R * 73, lab_shift)); + + int L = CV_DESCALE(Lscale * fY + Lshift, lab_shift2); + int a = CV_DESCALE(500 * (fX - fY) + 128 * (1 << lab_shift2), lab_shift2); + int b = CV_DESCALE(200 * (fY - fZ) + 128 * (1 << lab_shift2), lab_shift2); + + dst.x = saturate_cast(L); + dst.y = saturate_cast(a); + dst.z = saturate_cast(b); + } + + __device__ __forceinline__ float splineInterpolate(float x, const float* tab, int n) + { + int ix = ::min(::max(int(x), 0), n-1); + x -= ix; + tab += ix * 4; + return ((tab[3] * x + tab[2]) * x + tab[1]) * x + tab[0]; + } + + __constant__ float c_sRGBGammaTab[] = {0,7.55853e-05,0.,-7.51331e-13,7.55853e-05,7.55853e-05,-2.25399e-12,3.75665e-12,0.000151171,7.55853e-05,9.01597e-12,-6.99932e-12,0.000226756,7.55853e-05,-1.1982e-11,2.41277e-12,0.000302341,7.55853e-05,-4.74369e-12,1.19001e-11,0.000377927,7.55853e-05,3.09568e-11,-2.09095e-11,0.000453512,7.55853e-05,-3.17718e-11,1.35303e-11,0.000529097,7.55853e-05,8.81905e-12,-4.10782e-12,0.000604683,7.55853e-05,-3.50439e-12,2.90097e-12,0.000680268,7.55853e-05,5.19852e-12,-7.49607e-12,0.000755853,7.55853e-05,-1.72897e-11,2.70833e-11,0.000831439,7.55854e-05,6.39602e-11,-4.26295e-11,0.000907024,7.55854e-05,-6.39282e-11,2.70193e-11,0.000982609,7.55853e-05,1.71298e-11,-7.24017e-12,0.00105819,7.55853e-05,-4.59077e-12,1.94137e-12,0.00113378,7.55853e-05,1.23333e-12,-5.25291e-13,0.00120937,7.55853e-05,-3.42545e-13,1.59799e-13,0.00128495,7.55853e-05,1.36852e-13,-1.13904e-13,0.00136054,7.55853e-05,-2.04861e-13,2.95818e-13,0.00143612,7.55853e-05,6.82594e-13,-1.06937e-12,0.00151171,7.55853e-05,-2.52551e-12,3.98166e-12,0.00158729,7.55853e-05,9.41946e-12,-1.48573e-11,0.00166288,7.55853e-05,-3.51523e-11,5.54474e-11,0.00173846,7.55854e-05,1.3119e-10,-9.0517e-11,0.00181405,7.55854e-05,-1.40361e-10,7.37899e-11,0.00188963,7.55853e-05,8.10085e-11,-8.82272e-11,0.00196522,7.55852e-05,-1.83673e-10,1.62704e-10,0.0020408,7.55853e-05,3.04438e-10,-2.13341e-10,0.00211639,7.55853e-05,-3.35586e-10,2.25e-10,0.00219197,7.55853e-05,3.39414e-10,-2.20997e-10,0.00226756,7.55853e-05,-3.23576e-10,1.93326e-10,0.00234315,7.55853e-05,2.564e-10,-8.66446e-11,0.00241873,7.55855e-05,-3.53328e-12,-7.9578e-11,0.00249432,7.55853e-05,-2.42267e-10,1.72126e-10,0.0025699,7.55853e-05,2.74111e-10,-1.43265e-10,0.00264549,7.55854e-05,-1.55683e-10,-6.47292e-11,0.00272107,7.55849e-05,-3.4987e-10,8.67842e-10,0.00279666,7.55868e-05,2.25366e-09,-3.8723e-09,0.00287224,7.55797e-05,-9.36325e-09,1.5087e-08,0.00294783,7.56063e-05,3.58978e-08,-5.69415e-08,0.00302341,7.55072e-05,-1.34927e-07,2.13144e-07,0.003099,7.58768e-05,5.04507e-07,1.38713e-07,0.00317552,7.7302e-05,9.20646e-07,-1.55186e-07,0.00325359,7.86777e-05,4.55087e-07,4.26813e-08,0.00333276,7.97159e-05,5.83131e-07,-1.06495e-08,0.00341305,8.08502e-05,5.51182e-07,3.87467e-09,0.00349446,8.19642e-05,5.62806e-07,-1.92586e-10,0.00357698,8.30892e-05,5.62228e-07,1.0866e-09,0.00366063,8.4217e-05,5.65488e-07,5.02818e-10,0.00374542,8.53494e-05,5.66997e-07,8.60211e-10,0.00383133,8.6486e-05,5.69577e-07,7.13044e-10,0.00391839,8.76273e-05,5.71716e-07,4.78527e-10,0.00400659,8.87722e-05,5.73152e-07,1.09818e-09,0.00409594,8.99218e-05,5.76447e-07,2.50964e-10,0.00418644,9.10754e-05,5.772e-07,1.15762e-09,0.00427809,9.22333e-05,5.80672e-07,2.40865e-10,0.0043709,9.33954e-05,5.81395e-07,1.13854e-09,0.00446488,9.45616e-05,5.84811e-07,3.27267e-10,0.00456003,9.57322e-05,5.85792e-07,8.1197e-10,0.00465635,9.69062e-05,5.88228e-07,6.15823e-10,0.00475384,9.80845e-05,5.90076e-07,9.15747e-10,0.00485252,9.92674e-05,5.92823e-07,3.778e-10,0.00495238,0.000100454,5.93956e-07,8.32623e-10,0.00505343,0.000101645,5.96454e-07,4.82695e-10,0.00515567,0.000102839,5.97902e-07,9.61904e-10,0.00525911,0.000104038,6.00788e-07,3.26281e-10,0.00536375,0.00010524,6.01767e-07,9.926e-10,0.00546959,0.000106447,6.04745e-07,3.59933e-10,0.00557664,0.000107657,6.05824e-07,8.2728e-10,0.0056849,0.000108871,6.08306e-07,5.21898e-10,0.00579438,0.00011009,6.09872e-07,8.10492e-10,0.00590508,0.000111312,6.12303e-07,4.27046e-10,0.00601701,0.000112538,6.13585e-07,7.40878e-10,0.00613016,0.000113767,6.15807e-07,8.00469e-10,0.00624454,0.000115001,6.18209e-07,2.48178e-10,0.00636016,0.000116238,6.18953e-07,1.00073e-09,0.00647702,0.000117479,6.21955e-07,4.05654e-10,0.00659512,0.000118724,6.23172e-07,6.36192e-10,0.00671447,0.000119973,6.25081e-07,7.74927e-10,0.00683507,0.000121225,6.27406e-07,4.54975e-10,0.00695692,0.000122481,6.28771e-07,6.64841e-10,0.00708003,0.000123741,6.30765e-07,6.10972e-10,0.00720441,0.000125004,6.32598e-07,6.16543e-10,0.00733004,0.000126271,6.34448e-07,6.48204e-10,0.00745695,0.000127542,6.36392e-07,5.15835e-10,0.00758513,0.000128816,6.3794e-07,5.48103e-10,0.00771458,0.000130094,6.39584e-07,1.01706e-09,0.00784532,0.000131376,6.42635e-07,4.0283e-11,0.00797734,0.000132661,6.42756e-07,6.84471e-10,0.00811064,0.000133949,6.4481e-07,9.47144e-10,0.00824524,0.000135241,6.47651e-07,1.83472e-10,0.00838112,0.000136537,6.48201e-07,1.11296e-09,0.00851831,0.000137837,6.5154e-07,2.13163e-11,0.0086568,0.00013914,6.51604e-07,6.64462e-10,0.00879659,0.000140445,6.53598e-07,1.04613e-09,0.00893769,0.000141756,6.56736e-07,-1.92377e-10,0.0090801,0.000143069,6.56159e-07,1.58601e-09,0.00922383,0.000144386,6.60917e-07,-5.63754e-10,0.00936888,0.000145706,6.59226e-07,1.60033e-09,0.00951524,0.000147029,6.64027e-07,-2.49543e-10,0.00966294,0.000148356,6.63278e-07,1.26043e-09,0.00981196,0.000149687,6.67059e-07,-1.35572e-10,0.00996231,0.00015102,6.66653e-07,1.14458e-09,0.010114,0.000152357,6.70086e-07,2.13864e-10,0.010267,0.000153698,6.70728e-07,7.93856e-10,0.0104214,0.000155042,6.73109e-07,3.36077e-10,0.0105771,0.000156389,6.74118e-07,6.55765e-10,0.0107342,0.000157739,6.76085e-07,7.66211e-10,0.0108926,0.000159094,6.78384e-07,4.66116e-12,0.0110524,0.000160451,6.78398e-07,1.07775e-09,0.0112135,0.000161811,6.81631e-07,3.41023e-10,0.011376,0.000163175,6.82654e-07,3.5205e-10,0.0115398,0.000164541,6.8371e-07,1.04473e-09,0.0117051,0.000165912,6.86844e-07,1.25757e-10,0.0118717,0.000167286,6.87222e-07,3.14818e-10,0.0120396,0.000168661,6.88166e-07,1.40886e-09,0.012209,0.000170042,6.92393e-07,-3.62244e-10,0.0123797,0.000171425,6.91306e-07,9.71397e-10,0.0125518,0.000172811,6.9422e-07,2.02003e-10,0.0127253,0.0001742,6.94826e-07,1.01448e-09,0.0129002,0.000175593,6.97869e-07,3.96653e-10,0.0130765,0.00017699,6.99059e-07,1.92927e-10,0.0132542,0.000178388,6.99638e-07,6.94305e-10,0.0134333,0.00017979,7.01721e-07,7.55108e-10,0.0136138,0.000181195,7.03986e-07,1.05918e-11,0.0137957,0.000182603,7.04018e-07,1.06513e-09,0.013979,0.000184015,7.07214e-07,3.85512e-10,0.0141637,0.00018543,7.0837e-07,1.86769e-10,0.0143499,0.000186848,7.0893e-07,7.30116e-10,0.0145374,0.000188268,7.11121e-07,6.17983e-10,0.0147264,0.000189692,7.12975e-07,5.23282e-10,0.0149168,0.000191119,7.14545e-07,8.28398e-11,0.0151087,0.000192549,7.14793e-07,1.0081e-09,0.0153019,0.000193981,7.17817e-07,5.41244e-10,0.0154966,0.000195418,7.19441e-07,-3.7907e-10,0.0156928,0.000196856,7.18304e-07,1.90641e-09,0.0158903,0.000198298,7.24023e-07,-7.27387e-10,0.0160893,0.000199744,7.21841e-07,1.00317e-09,0.0162898,0.000201191,7.24851e-07,4.39949e-10,0.0164917,0.000202642,7.2617e-07,9.6234e-10,0.0166951,0.000204097,7.29057e-07,-5.64019e-10,0.0168999,0.000205554,7.27365e-07,1.29374e-09,0.0171062,0.000207012,7.31247e-07,9.77025e-10,0.017314,0.000208478,7.34178e-07,-1.47651e-09,0.0175232,0.000209942,7.29748e-07,3.06636e-09,0.0177338,0.00021141,7.38947e-07,-1.47573e-09,0.017946,0.000212884,7.3452e-07,9.7386e-10,0.0181596,0.000214356,7.37442e-07,1.30562e-09,0.0183747,0.000215835,7.41358e-07,-6.08376e-10,0.0185913,0.000217315,7.39533e-07,1.12785e-09,0.0188093,0.000218798,7.42917e-07,-1.77711e-10,0.0190289,0.000220283,7.42384e-07,1.44562e-09,0.0192499,0.000221772,7.46721e-07,-1.68825e-11,0.0194724,0.000223266,7.4667e-07,4.84533e-10,0.0196964,0.000224761,7.48124e-07,-5.85298e-11,0.0199219,0.000226257,7.47948e-07,1.61217e-09,0.0201489,0.000227757,7.52785e-07,-8.02136e-10,0.0203775,0.00022926,7.50378e-07,1.59637e-09,0.0206075,0.000230766,7.55167e-07,4.47168e-12,0.020839,0.000232276,7.55181e-07,2.48387e-10,0.021072,0.000233787,7.55926e-07,8.6474e-10,0.0213066,0.000235302,7.5852e-07,1.78299e-11,0.0215426,0.000236819,7.58573e-07,9.26567e-10,0.0217802,0.000238339,7.61353e-07,1.34529e-12,0.0220193,0.000239862,7.61357e-07,9.30659e-10,0.0222599,0.000241387,7.64149e-07,1.34529e-12,0.0225021,0.000242915,7.64153e-07,9.26567e-10,0.0227458,0.000244447,7.66933e-07,1.76215e-11,0.022991,0.00024598,7.66986e-07,8.65536e-10,0.0232377,0.000247517,7.69582e-07,2.45677e-10,0.023486,0.000249057,7.70319e-07,1.44193e-11,0.0237358,0.000250598,7.70363e-07,1.55918e-09,0.0239872,0.000252143,7.7504e-07,-6.63173e-10,0.0242401,0.000253691,7.73051e-07,1.09357e-09,0.0244946,0.000255241,7.76331e-07,1.41919e-11,0.0247506,0.000256793,7.76374e-07,7.12248e-10,0.0250082,0.000258348,7.78511e-07,8.62049e-10,0.0252673,0.000259908,7.81097e-07,-4.35061e-10,0.025528,0.000261469,7.79792e-07,8.7825e-10,0.0257902,0.000263031,7.82426e-07,6.47181e-10,0.0260541,0.000264598,7.84368e-07,2.58448e-10,0.0263194,0.000266167,7.85143e-07,1.81558e-10,0.0265864,0.000267738,7.85688e-07,8.78041e-10,0.0268549,0.000269312,7.88322e-07,3.15102e-11,0.027125,0.000270889,7.88417e-07,8.58525e-10,0.0273967,0.000272468,7.90992e-07,2.59812e-10,0.02767,0.000274051,7.91772e-07,-3.5224e-11,0.0279448,0.000275634,7.91666e-07,1.74377e-09,0.0282212,0.000277223,7.96897e-07,-1.35196e-09,0.0284992,0.000278813,7.92841e-07,1.80141e-09,0.0287788,0.000280404,7.98246e-07,-2.65629e-10,0.0290601,0.000281999,7.97449e-07,1.12374e-09,0.0293428,0.000283598,8.0082e-07,-5.04106e-10,0.0296272,0.000285198,7.99308e-07,8.92764e-10,0.0299132,0.000286799,8.01986e-07,6.58379e-10,0.0302008,0.000288405,8.03961e-07,1.98971e-10,0.0304901,0.000290014,8.04558e-07,4.08382e-10,0.0307809,0.000291624,8.05783e-07,3.01839e-11,0.0310733,0.000293236,8.05874e-07,1.33343e-09,0.0313673,0.000294851,8.09874e-07,2.2419e-10,0.031663,0.000296472,8.10547e-07,-3.67606e-10,0.0319603,0.000298092,8.09444e-07,1.24624e-09,0.0322592,0.000299714,8.13182e-07,-8.92025e-10,0.0325597,0.000301338,8.10506e-07,2.32183e-09,0.0328619,0.000302966,8.17472e-07,-9.44719e-10,0.0331657,0.000304598,8.14638e-07,1.45703e-09,0.0334711,0.000306232,8.19009e-07,-1.15805e-09,0.0337781,0.000307866,8.15535e-07,3.17507e-09,0.0340868,0.000309507,8.2506e-07,-4.09161e-09,0.0343971,0.000311145,8.12785e-07,5.74079e-09,0.0347091,0.000312788,8.30007e-07,-3.97034e-09,0.0350227,0.000314436,8.18096e-07,2.68985e-09,0.035338,0.00031608,8.26166e-07,6.61676e-10,0.0356549,0.000317734,8.28151e-07,-1.61123e-09,0.0359734,0.000319386,8.23317e-07,2.05786e-09,0.0362936,0.000321038,8.29491e-07,8.30388e-10,0.0366155,0.0003227,8.31982e-07,-1.65424e-09,0.036939,0.000324359,8.27019e-07,2.06129e-09,0.0372642,0.000326019,8.33203e-07,8.59719e-10,0.0375911,0.000327688,8.35782e-07,-1.77488e-09,0.0379196,0.000329354,8.30458e-07,2.51464e-09,0.0382498,0.000331023,8.38002e-07,-8.33135e-10,0.0385817,0.000332696,8.35502e-07,8.17825e-10,0.0389152,0.00033437,8.37956e-07,1.28718e-09,0.0392504,0.00033605,8.41817e-07,-2.2413e-09,0.0395873,0.000337727,8.35093e-07,3.95265e-09,0.0399258,0.000339409,8.46951e-07,-2.39332e-09,0.0402661,0.000341095,8.39771e-07,1.89533e-09,0.040608,0.000342781,8.45457e-07,-1.46271e-09,0.0409517,0.000344467,8.41069e-07,3.95554e-09,0.041297,0.000346161,8.52936e-07,-3.18369e-09,0.041644,0.000347857,8.43385e-07,1.32873e-09,0.0419927,0.000349548,8.47371e-07,1.59402e-09,0.0423431,0.000351248,8.52153e-07,-2.54336e-10,0.0426952,0.000352951,8.5139e-07,-5.76676e-10,0.043049,0.000354652,8.4966e-07,2.56114e-09,0.0434045,0.000356359,8.57343e-07,-2.21744e-09,0.0437617,0.000358067,8.50691e-07,2.58344e-09,0.0441206,0.000359776,8.58441e-07,-6.65826e-10,0.0444813,0.000361491,8.56444e-07,7.99218e-11,0.0448436,0.000363204,8.56684e-07,3.46063e-10,0.0452077,0.000364919,8.57722e-07,2.26116e-09,0.0455734,0.000366641,8.64505e-07,-1.94005e-09,0.045941,0.000368364,8.58685e-07,1.77384e-09,0.0463102,0.000370087,8.64007e-07,-1.43005e-09,0.0466811,0.000371811,8.59717e-07,3.94634e-09,0.0470538,0.000373542,8.71556e-07,-3.17946e-09,0.0474282,0.000375276,8.62017e-07,1.32104e-09,0.0478043,0.000377003,8.6598e-07,1.62045e-09,0.0481822,0.00037874,8.70842e-07,-3.52297e-10,0.0485618,0.000380481,8.69785e-07,-2.11211e-10,0.0489432,0.00038222,8.69151e-07,1.19716e-09,0.0493263,0.000383962,8.72743e-07,-8.52026e-10,0.0497111,0.000385705,8.70187e-07,2.21092e-09,0.0500977,0.000387452,8.76819e-07,-5.41339e-10,0.050486,0.000389204,8.75195e-07,-4.5361e-11,0.0508761,0.000390954,8.75059e-07,7.22669e-10,0.0512679,0.000392706,8.77227e-07,8.79936e-10,0.0516615,0.000394463,8.79867e-07,-5.17048e-10,0.0520568,0.000396222,8.78316e-07,1.18833e-09,0.0524539,0.000397982,8.81881e-07,-5.11022e-10,0.0528528,0.000399744,8.80348e-07,8.55683e-10,0.0532534,0.000401507,8.82915e-07,8.13562e-10,0.0536558,0.000403276,8.85356e-07,-3.84603e-10,0.05406,0.000405045,8.84202e-07,7.24962e-10,0.0544659,0.000406816,8.86377e-07,1.20986e-09,0.0548736,0.000408592,8.90006e-07,-1.83896e-09,0.0552831,0.000410367,8.84489e-07,2.42071e-09,0.0556944,0.000412143,8.91751e-07,-3.93413e-10,0.0561074,0.000413925,8.90571e-07,-8.46967e-10,0.0565222,0.000415704,8.8803e-07,3.78122e-09,0.0569388,0.000417491,8.99374e-07,-3.1021e-09,0.0573572,0.000419281,8.90068e-07,1.17658e-09,0.0577774,0.000421064,8.93597e-07,2.12117e-09,0.0581993,0.000422858,8.99961e-07,-2.21068e-09,0.0586231,0.000424651,8.93329e-07,2.9961e-09,0.0590486,0.000426447,9.02317e-07,-2.32311e-09,0.059476,0.000428244,8.95348e-07,2.57122e-09,0.0599051,0.000430043,9.03062e-07,-5.11098e-10,0.0603361,0.000431847,9.01528e-07,-5.27166e-10,0.0607688,0.000433649,8.99947e-07,2.61984e-09,0.0612034,0.000435457,9.07806e-07,-2.50141e-09,0.0616397,0.000437265,9.00302e-07,3.66045e-09,0.0620779,0.000439076,9.11283e-07,-4.68977e-09,0.0625179,0.000440885,8.97214e-07,7.64783e-09,0.0629597,0.000442702,9.20158e-07,-7.27499e-09,0.0634033,0.000444521,8.98333e-07,6.55113e-09,0.0638487,0.000446337,9.17986e-07,-4.02844e-09,0.0642959,0.000448161,9.05901e-07,2.11196e-09,0.064745,0.000449979,9.12236e-07,3.03125e-09,0.0651959,0.000451813,9.2133e-07,-6.78648e-09,0.0656486,0.000453635,9.00971e-07,9.21375e-09,0.0661032,0.000455464,9.28612e-07,-7.71684e-09,0.0665596,0.000457299,9.05462e-07,6.7522e-09,0.0670178,0.00045913,9.25718e-07,-4.3907e-09,0.0674778,0.000460968,9.12546e-07,3.36e-09,0.0679397,0.000462803,9.22626e-07,-1.59876e-09,0.0684034,0.000464644,9.1783e-07,3.0351e-09,0.068869,0.000466488,9.26935e-07,-3.09101e-09,0.0693364,0.000468333,9.17662e-07,1.8785e-09,0.0698057,0.000470174,9.23298e-07,3.02733e-09,0.0702768,0.00047203,9.3238e-07,-6.53722e-09,0.0707497,0.000473875,9.12768e-07,8.22054e-09,0.0712245,0.000475725,9.37429e-07,-3.99325e-09,0.0717012,0.000477588,9.2545e-07,3.01839e-10,0.0721797,0.00047944,9.26355e-07,2.78597e-09,0.0726601,0.000481301,9.34713e-07,-3.99507e-09,0.0731423,0.000483158,9.22728e-07,5.7435e-09,0.0736264,0.000485021,9.39958e-07,-4.07776e-09,0.0741123,0.000486888,9.27725e-07,3.11695e-09,0.0746002,0.000488753,9.37076e-07,-9.39394e-10,0.0750898,0.000490625,9.34258e-07,6.4055e-10,0.0755814,0.000492495,9.3618e-07,-1.62265e-09,0.0760748,0.000494363,9.31312e-07,5.84995e-09,0.0765701,0.000496243,9.48861e-07,-6.87601e-09,0.0770673,0.00049812,9.28233e-07,6.75296e-09,0.0775664,0.000499997,9.48492e-07,-5.23467e-09,0.0780673,0.000501878,9.32788e-07,6.73523e-09,0.0785701,0.000503764,9.52994e-07,-6.80514e-09,0.0790748,0.000505649,9.32578e-07,5.5842e-09,0.0795814,0.000507531,9.49331e-07,-6.30583e-10,0.0800899,0.000509428,9.47439e-07,-3.0618e-09,0.0806003,0.000511314,9.38254e-07,5.4273e-09,0.0811125,0.000513206,9.54536e-07,-3.74627e-09,0.0816267,0.000515104,9.43297e-07,2.10713e-09,0.0821427,0.000516997,9.49618e-07,2.76839e-09,0.0826607,0.000518905,9.57924e-07,-5.73006e-09,0.0831805,0.000520803,9.40733e-07,5.25072e-09,0.0837023,0.0005227,9.56486e-07,-3.71718e-10,0.084226,0.000524612,9.5537e-07,-3.76404e-09,0.0847515,0.000526512,9.44078e-07,7.97735e-09,0.085279,0.000528424,9.6801e-07,-5.79367e-09,0.0858084,0.000530343,9.50629e-07,2.96268e-10,0.0863397,0.000532245,9.51518e-07,4.6086e-09,0.0868729,0.000534162,9.65344e-07,-3.82947e-09,0.087408,0.000536081,9.53856e-07,3.25861e-09,0.087945,0.000537998,9.63631e-07,-1.7543e-09,0.088484,0.00053992,9.58368e-07,3.75849e-09,0.0890249,0.000541848,9.69644e-07,-5.82891e-09,0.0895677,0.00054377,9.52157e-07,4.65593e-09,0.0901124,0.000545688,9.66125e-07,2.10643e-09,0.0906591,0.000547627,9.72444e-07,-5.63099e-09,0.0912077,0.000549555,9.55551e-07,5.51627e-09,0.0917582,0.000551483,9.721e-07,-1.53292e-09,0.0923106,0.000553422,9.67501e-07,6.15311e-10,0.092865,0.000555359,9.69347e-07,-9.28291e-10,0.0934213,0.000557295,9.66562e-07,3.09774e-09,0.0939796,0.000559237,9.75856e-07,-4.01186e-09,0.0945398,0.000561177,9.6382e-07,5.49892e-09,0.095102,0.000563121,9.80317e-07,-3.08258e-09,0.0956661,0.000565073,9.71069e-07,-6.19176e-10,0.0962321,0.000567013,9.69212e-07,5.55932e-09,0.0968001,0.000568968,9.8589e-07,-6.71704e-09,0.09737,0.00057092,9.65738e-07,6.40762e-09,0.0979419,0.00057287,9.84961e-07,-4.0122e-09,0.0985158,0.000574828,9.72925e-07,2.19059e-09,0.0990916,0.000576781,9.79496e-07,2.70048e-09,0.0996693,0.000578748,9.87598e-07,-5.54193e-09,0.100249,0.000580706,9.70972e-07,4.56597e-09,0.100831,0.000582662,9.8467e-07,2.17923e-09,0.101414,0.000584638,9.91208e-07,-5.83232e-09,0.102,0.000586603,9.73711e-07,6.24884e-09,0.102588,0.000588569,9.92457e-07,-4.26178e-09,0.103177,0.000590541,9.79672e-07,3.34781e-09,0.103769,0.00059251,9.89715e-07,-1.67904e-09,0.104362,0.000594485,9.84678e-07,3.36839e-09,0.104958,0.000596464,9.94783e-07,-4.34397e-09,0.105555,0.000598441,9.81751e-07,6.55696e-09,0.106155,0.000600424,1.00142e-06,-6.98272e-09,0.106756,0.000602406,9.80474e-07,6.4728e-09,0.107359,0.000604386,9.99893e-07,-4.00742e-09,0.107965,0.000606374,9.8787e-07,2.10654e-09,0.108572,0.000608356,9.9419e-07,3.0318e-09,0.109181,0.000610353,1.00329e-06,-6.7832e-09,0.109793,0.00061234,9.82936e-07,9.1998e-09,0.110406,0.000614333,1.01054e-06,-7.6642e-09,0.111021,0.000616331,9.87543e-07,6.55579e-09,0.111639,0.000618326,1.00721e-06,-3.65791e-09,0.112258,0.000620329,9.96236e-07,6.25467e-10,0.112879,0.000622324,9.98113e-07,1.15593e-09,0.113503,0.000624323,1.00158e-06,2.20158e-09,0.114128,0.000626333,1.00819e-06,-2.51191e-09,0.114755,0.000628342,1.00065e-06,3.95517e-10,0.115385,0.000630345,1.00184e-06,9.29807e-10,0.116016,0.000632351,1.00463e-06,3.33599e-09,0.116649,0.00063437,1.01463e-06,-6.82329e-09,0.117285,0.000636379,9.94163e-07,9.05595e-09,0.117922,0.000638395,1.02133e-06,-7.04862e-09,0.118562,0.000640416,1.00019e-06,4.23737e-09,0.119203,0.000642429,1.0129e-06,-2.45033e-09,0.119847,0.000644448,1.00555e-06,5.56395e-09,0.120492,0.000646475,1.02224e-06,-4.9043e-09,0.121139,0.000648505,1.00753e-06,-8.47952e-10,0.121789,0.000650518,1.00498e-06,8.29622e-09,0.122441,0.000652553,1.02987e-06,-9.98538e-09,0.123094,0.000654582,9.99914e-07,9.2936e-09,0.12375,0.00065661,1.02779e-06,-4.83707e-09,0.124407,0.000658651,1.01328e-06,2.60411e-09,0.125067,0.000660685,1.0211e-06,-5.57945e-09,0.125729,0.000662711,1.00436e-06,1.22631e-08,0.126392,0.000664756,1.04115e-06,-1.36704e-08,0.127058,0.000666798,1.00014e-06,1.26161e-08,0.127726,0.000668836,1.03798e-06,-6.99155e-09,0.128396,0.000670891,1.01701e-06,4.48836e-10,0.129068,0.000672926,1.01836e-06,5.19606e-09,0.129742,0.000674978,1.03394e-06,-6.3319e-09,0.130418,0.000677027,1.01495e-06,5.2305e-09,0.131096,0.000679073,1.03064e-06,3.11123e-10,0.131776,0.000681135,1.03157e-06,-6.47511e-09,0.132458,0.000683179,1.01215e-06,1.06882e-08,0.133142,0.000685235,1.04421e-06,-6.47519e-09,0.133829,0.000687304,1.02479e-06,3.11237e-10,0.134517,0.000689355,1.02572e-06,5.23035e-09,0.135207,0.000691422,1.04141e-06,-6.3316e-09,0.1359,0.000693486,1.02242e-06,5.19484e-09,0.136594,0.000695546,1.038e-06,4.53497e-10,0.137291,0.000697623,1.03936e-06,-7.00891e-09,0.137989,0.000699681,1.01834e-06,1.2681e-08,0.13869,0.000701756,1.05638e-06,-1.39128e-08,0.139393,0.000703827,1.01464e-06,1.31679e-08,0.140098,0.000705896,1.05414e-06,-8.95659e-09,0.140805,0.000707977,1.02727e-06,7.75742e-09,0.141514,0.000710055,1.05055e-06,-7.17182e-09,0.142225,0.000712135,1.02903e-06,6.02862e-09,0.142938,0.000714211,1.04712e-06,-2.04163e-09,0.143653,0.000716299,1.04099e-06,2.13792e-09,0.144371,0.000718387,1.04741e-06,-6.51009e-09,0.14509,0.000720462,1.02787e-06,9.00123e-09,0.145812,0.000722545,1.05488e-06,3.07523e-10,0.146535,0.000724656,1.0558e-06,-1.02312e-08,0.147261,0.000726737,1.02511e-06,1.0815e-08,0.147989,0.000728819,1.05755e-06,-3.22681e-09,0.148719,0.000730925,1.04787e-06,2.09244e-09,0.14945,0.000733027,1.05415e-06,-5.143e-09,0.150185,0.00073512,1.03872e-06,3.57844e-09,0.150921,0.000737208,1.04946e-06,5.73027e-09,0.151659,0.000739324,1.06665e-06,-1.15983e-08,0.152399,0.000741423,1.03185e-06,1.08605e-08,0.153142,0.000743519,1.06443e-06,-2.04106e-09,0.153886,0.000745642,1.05831e-06,-2.69642e-09,0.154633,0.00074775,1.05022e-06,-2.07425e-09,0.155382,0.000749844,1.044e-06,1.09934e-08,0.156133,0.000751965,1.07698e-06,-1.20972e-08,0.156886,0.000754083,1.04069e-06,7.59288e-09,0.157641,0.000756187,1.06347e-06,-3.37305e-09,0.158398,0.000758304,1.05335e-06,5.89921e-09,0.159158,0.000760428,1.07104e-06,-5.32248e-09,0.159919,0.000762554,1.05508e-06,4.8927e-10,0.160683,0.000764666,1.05654e-06,3.36547e-09,0.161448,0.000766789,1.06664e-06,9.50081e-10,0.162216,0.000768925,1.06949e-06,-7.16568e-09,0.162986,0.000771043,1.04799e-06,1.28114e-08,0.163758,0.000773177,1.08643e-06,-1.42774e-08,0.164533,0.000775307,1.0436e-06,1.44956e-08,0.165309,0.000777438,1.08708e-06,-1.39025e-08,0.166087,0.00077957,1.04538e-06,1.13118e-08,0.166868,0.000781695,1.07931e-06,-1.54224e-09,0.167651,0.000783849,1.07468e-06,-5.14312e-09,0.168436,0.000785983,1.05925e-06,7.21381e-09,0.169223,0.000788123,1.0809e-06,-8.81096e-09,0.170012,0.000790259,1.05446e-06,1.31289e-08,0.170803,0.000792407,1.09385e-06,-1.39022e-08,0.171597,0.000794553,1.05214e-06,1.26775e-08,0.172392,0.000796695,1.09018e-06,-7.00557e-09,0.17319,0.000798855,1.06916e-06,4.43796e-10,0.17399,0.000800994,1.07049e-06,5.23031e-09,0.174792,0.000803151,1.08618e-06,-6.46397e-09,0.175596,0.000805304,1.06679e-06,5.72444e-09,0.176403,0.000807455,1.08396e-06,-1.53254e-09,0.177211,0.000809618,1.07937e-06,4.05673e-10,0.178022,0.000811778,1.08058e-06,-9.01916e-11,0.178835,0.000813939,1.08031e-06,-4.49821e-11,0.17965,0.000816099,1.08018e-06,2.70234e-10,0.180467,0.00081826,1.08099e-06,-1.03603e-09,0.181286,0.000820419,1.07788e-06,3.87392e-09,0.182108,0.000822587,1.0895e-06,4.41522e-10,0.182932,0.000824767,1.09083e-06,-5.63997e-09,0.183758,0.000826932,1.07391e-06,7.21707e-09,0.184586,0.000829101,1.09556e-06,-8.32718e-09,0.185416,0.000831267,1.07058e-06,1.11907e-08,0.186248,0.000833442,1.10415e-06,-6.63336e-09,0.187083,0.00083563,1.08425e-06,4.41484e-10,0.187919,0.0008378,1.08557e-06,4.86754e-09,0.188758,0.000839986,1.10017e-06,-5.01041e-09,0.189599,0.000842171,1.08514e-06,2.72811e-10,0.190443,0.000844342,1.08596e-06,3.91916e-09,0.191288,0.000846526,1.09772e-06,-1.04819e-09,0.192136,0.000848718,1.09457e-06,2.73531e-10,0.192985,0.000850908,1.0954e-06,-4.58916e-11,0.193837,0.000853099,1.09526e-06,-9.01158e-11,0.194692,0.000855289,1.09499e-06,4.06506e-10,0.195548,0.00085748,1.09621e-06,-1.53595e-09,0.196407,0.000859668,1.0916e-06,5.73717e-09,0.197267,0.000861869,1.10881e-06,-6.51164e-09,0.19813,0.000864067,1.08928e-06,5.40831e-09,0.198995,0.000866261,1.1055e-06,-2.20401e-10,0.199863,0.000868472,1.10484e-06,-4.52652e-09,0.200732,0.000870668,1.09126e-06,3.42508e-09,0.201604,0.000872861,1.10153e-06,5.72762e-09,0.202478,0.000875081,1.11872e-06,-1.14344e-08,0.203354,0.000877284,1.08441e-06,1.02076e-08,0.204233,0.000879484,1.11504e-06,4.06355e-10,0.205113,0.000881715,1.11626e-06,-1.18329e-08,0.205996,0.000883912,1.08076e-06,1.71227e-08,0.206881,0.000886125,1.13213e-06,-1.19546e-08,0.207768,0.000888353,1.09626e-06,8.93465e-10,0.208658,0.000890548,1.09894e-06,8.38062e-09,0.209549,0.000892771,1.12408e-06,-4.61353e-09,0.210443,0.000895006,1.11024e-06,-4.82756e-09,0.211339,0.000897212,1.09576e-06,9.02245e-09,0.212238,0.00089943,1.12283e-06,-1.45997e-09,0.213138,0.000901672,1.11845e-06,-3.18255e-09,0.214041,0.000903899,1.1089e-06,-7.11073e-10,0.214946,0.000906115,1.10677e-06,6.02692e-09,0.215853,0.000908346,1.12485e-06,-8.49548e-09,0.216763,0.00091057,1.09936e-06,1.30537e-08,0.217675,0.000912808,1.13852e-06,-1.3917e-08,0.218588,0.000915044,1.09677e-06,1.28121e-08,0.219505,0.000917276,1.13521e-06,-7.5288e-09,0.220423,0.000919523,1.11262e-06,2.40205e-09,0.221344,0.000921756,1.11983e-06,-2.07941e-09,0.222267,0.000923989,1.11359e-06,5.91551e-09,0.223192,0.000926234,1.13134e-06,-6.68149e-09,0.224119,0.000928477,1.11129e-06,5.90929e-09,0.225049,0.000930717,1.12902e-06,-2.05436e-09,0.22598,0.000932969,1.12286e-06,2.30807e-09,0.226915,0.000935222,1.12978e-06,-7.17796e-09,0.227851,0.00093746,1.10825e-06,1.15028e-08,0.228789,0.000939711,1.14276e-06,-9.03083e-09,0.22973,0.000941969,1.11566e-06,9.71932e-09,0.230673,0.00094423,1.14482e-06,-1.49452e-08,0.231619,0.000946474,1.09998e-06,2.02591e-08,0.232566,0.000948735,1.16076e-06,-2.13879e-08,0.233516,0.000950993,1.0966e-06,2.05888e-08,0.234468,0.000953247,1.15837e-06,-1.62642e-08,0.235423,0.000955515,1.10957e-06,1.46658e-08,0.236379,0.000957779,1.15357e-06,-1.25966e-08,0.237338,0.000960048,1.11578e-06,5.91793e-09,0.238299,0.000962297,1.13353e-06,3.82602e-09,0.239263,0.000964576,1.14501e-06,-6.3208e-09,0.240229,0.000966847,1.12605e-06,6.55613e-09,0.241197,0.000969119,1.14572e-06,-5.00268e-09,0.242167,0.000971395,1.13071e-06,-1.44659e-09,0.243139,0.000973652,1.12637e-06,1.07891e-08,0.244114,0.000975937,1.15874e-06,-1.19073e-08,0.245091,0.000978219,1.12302e-06,7.03782e-09,0.246071,0.000980486,1.14413e-06,-1.34276e-09,0.247052,0.00098277,1.1401e-06,-1.66669e-09,0.248036,0.000985046,1.1351e-06,8.00935e-09,0.249022,0.00098734,1.15913e-06,-1.54694e-08,0.250011,0.000989612,1.11272e-06,2.4066e-08,0.251002,0.000991909,1.18492e-06,-2.11901e-08,0.251995,0.000994215,1.12135e-06,1.08973e-09,0.25299,0.000996461,1.12462e-06,1.68311e-08,0.253988,0.000998761,1.17511e-06,-8.8094e-09,0.254987,0.00100109,1.14868e-06,-1.13958e-08,0.25599,0.00100335,1.1145e-06,2.45902e-08,0.256994,0.00100565,1.18827e-06,-2.73603e-08,0.258001,0.00100795,1.10618e-06,2.52464e-08,0.25901,0.00101023,1.18192e-06,-1.40207e-08,0.260021,0.00101256,1.13986e-06,1.03387e-09,0.261035,0.00101484,1.14296e-06,9.8853e-09,0.262051,0.00101715,1.17262e-06,-1.07726e-08,0.263069,0.00101947,1.1403e-06,3.40272e-09,0.26409,0.00102176,1.15051e-06,-2.83827e-09,0.265113,0.00102405,1.142e-06,7.95039e-09,0.266138,0.00102636,1.16585e-06,8.39047e-10,0.267166,0.00102869,1.16836e-06,-1.13066e-08,0.268196,0.00103099,1.13444e-06,1.4585e-08,0.269228,0.00103331,1.1782e-06,-1.72314e-08,0.270262,0.00103561,1.1265e-06,2.45382e-08,0.271299,0.00103794,1.20012e-06,-2.13166e-08,0.272338,0.00104028,1.13617e-06,1.12364e-09,0.273379,0.00104255,1.13954e-06,1.68221e-08,0.274423,0.00104488,1.19001e-06,-8.80736e-09,0.275469,0.00104723,1.16358e-06,-1.13948e-08,0.276518,0.00104953,1.1294e-06,2.45839e-08,0.277568,0.00105186,1.20315e-06,-2.73361e-08,0.278621,0.00105418,1.12114e-06,2.51559e-08,0.279677,0.0010565,1.19661e-06,-1.36832e-08,0.280734,0.00105885,1.15556e-06,-2.25706e-10,0.281794,0.00106116,1.15488e-06,1.45862e-08,0.282857,0.00106352,1.19864e-06,-2.83167e-08,0.283921,0.00106583,1.11369e-06,3.90759e-08,0.284988,0.00106817,1.23092e-06,-3.85801e-08,0.286058,0.00107052,1.11518e-06,2.58375e-08,0.287129,0.00107283,1.19269e-06,-5.16498e-09,0.288203,0.0010752,1.1772e-06,-5.17768e-09,0.28928,0.00107754,1.16167e-06,-3.92671e-09,0.290358,0.00107985,1.14988e-06,2.08846e-08,0.29144,0.00108221,1.21254e-06,-2.00072e-08,0.292523,0.00108458,1.15252e-06,-4.60659e-10,0.293609,0.00108688,1.15114e-06,2.18499e-08,0.294697,0.00108925,1.21669e-06,-2.73343e-08,0.295787,0.0010916,1.13468e-06,2.78826e-08,0.29688,0.00109395,1.21833e-06,-2.45915e-08,0.297975,0.00109632,1.14456e-06,1.08787e-08,0.299073,0.00109864,1.17719e-06,1.08788e-08,0.300172,0.00110102,1.20983e-06,-2.45915e-08,0.301275,0.00110337,1.13605e-06,2.78828e-08,0.302379,0.00110573,1.2197e-06,-2.73348e-08,0.303486,0.00110808,1.1377e-06,2.18518e-08,0.304595,0.00111042,1.20325e-06,-4.67556e-10,0.305707,0.00111283,1.20185e-06,-1.99816e-08,0.306821,0.00111517,1.14191e-06,2.07891e-08,0.307937,0.00111752,1.20427e-06,-3.57026e-09,0.309056,0.00111992,1.19356e-06,-6.50797e-09,0.310177,0.00112228,1.17404e-06,-2.00165e-10,0.3113,0.00112463,1.17344e-06,7.30874e-09,0.312426,0.001127,1.19536e-06,7.67424e-10,0.313554,0.00112939,1.19767e-06,-1.03784e-08,0.314685,0.00113176,1.16653e-06,1.09437e-08,0.315818,0.00113412,1.19936e-06,-3.59406e-09,0.316953,0.00113651,1.18858e-06,3.43251e-09,0.318091,0.0011389,1.19888e-06,-1.0136e-08,0.319231,0.00114127,1.16847e-06,7.30915e-09,0.320374,0.00114363,1.1904e-06,1.07018e-08,0.321518,0.00114604,1.2225e-06,-2.03137e-08,0.322666,0.00114842,1.16156e-06,1.09484e-08,0.323815,0.00115078,1.19441e-06,6.32224e-09,0.324967,0.00115319,1.21337e-06,-6.43509e-09,0.326122,0.00115559,1.19407e-06,-1.03842e-08,0.327278,0.00115795,1.16291e-06,1.81697e-08,0.328438,0.00116033,1.21742e-06,-2.6901e-09,0.329599,0.00116276,1.20935e-06,-7.40939e-09,0.330763,0.00116515,1.18713e-06,2.52533e-09,0.331929,0.00116754,1.1947e-06,-2.69191e-09,0.333098,0.00116992,1.18663e-06,8.24218e-09,0.334269,0.00117232,1.21135e-06,-4.74377e-10,0.335443,0.00117474,1.20993e-06,-6.34471e-09,0.336619,0.00117714,1.1909e-06,-3.94922e-09,0.337797,0.00117951,1.17905e-06,2.21417e-08,0.338978,0.00118193,1.24547e-06,-2.50128e-08,0.340161,0.00118435,1.17043e-06,1.8305e-08,0.341346,0.00118674,1.22535e-06,-1.84048e-08,0.342534,0.00118914,1.17013e-06,2.55121e-08,0.343725,0.00119156,1.24667e-06,-2.40389e-08,0.344917,0.00119398,1.17455e-06,1.10389e-08,0.346113,0.00119636,1.20767e-06,9.68574e-09,0.34731,0.0011988,1.23673e-06,-1.99797e-08,0.34851,0.00120122,1.17679e-06,1.06284e-08,0.349713,0.0012036,1.20867e-06,7.26868e-09,0.350917,0.00120604,1.23048e-06,-9.90072e-09,0.352125,0.00120847,1.20078e-06,2.53177e-09,0.353334,0.00121088,1.20837e-06,-2.26199e-10,0.354546,0.0012133,1.20769e-06,-1.62705e-09,0.355761,0.00121571,1.20281e-06,6.73435e-09,0.356978,0.00121813,1.22302e-06,4.49207e-09,0.358197,0.00122059,1.23649e-06,-2.47027e-08,0.359419,0.00122299,1.16238e-06,3.47142e-08,0.360643,0.00122542,1.26653e-06,-2.47472e-08,0.36187,0.00122788,1.19229e-06,4.66965e-09,0.363099,0.00123028,1.20629e-06,6.06872e-09,0.36433,0.00123271,1.2245e-06,8.57729e-10,0.365564,0.00123516,1.22707e-06,-9.49952e-09,0.366801,0.00123759,1.19858e-06,7.33792e-09,0.36804,0.00124001,1.22059e-06,9.95025e-09,0.369281,0.00124248,1.25044e-06,-1.73366e-08,0.370525,0.00124493,1.19843e-06,-2.08464e-10,0.371771,0.00124732,1.1978e-06,1.81704e-08,0.373019,0.00124977,1.25232e-06,-1.28683e-08,0.37427,0.00125224,1.21371e-06,3.50042e-09,0.375524,0.00125468,1.22421e-06,-1.1335e-09,0.37678,0.00125712,1.22081e-06,1.03345e-09,0.378038,0.00125957,1.22391e-06,-3.00023e-09,0.379299,0.00126201,1.21491e-06,1.09676e-08,0.380562,0.00126447,1.24781e-06,-1.10676e-08,0.381828,0.00126693,1.21461e-06,3.50042e-09,0.383096,0.00126937,1.22511e-06,-2.93403e-09,0.384366,0.00127181,1.21631e-06,8.23574e-09,0.385639,0.00127427,1.24102e-06,-2.06607e-10,0.386915,0.00127675,1.2404e-06,-7.40935e-09,0.388193,0.00127921,1.21817e-06,4.1761e-11,0.389473,0.00128165,1.21829e-06,7.24223e-09,0.390756,0.0012841,1.24002e-06,7.91564e-10,0.392042,0.00128659,1.2424e-06,-1.04086e-08,0.393329,0.00128904,1.21117e-06,1.10405e-08,0.39462,0.0012915,1.24429e-06,-3.951e-09,0.395912,0.00129397,1.23244e-06,4.7634e-09,0.397208,0.00129645,1.24673e-06,-1.51025e-08,0.398505,0.0012989,1.20142e-06,2.58443e-08,0.399805,0.00130138,1.27895e-06,-2.86702e-08,0.401108,0.00130385,1.19294e-06,2.92318e-08,0.402413,0.00130632,1.28064e-06,-2.86524e-08,0.403721,0.0013088,1.19468e-06,2.57731e-08,0.405031,0.00131127,1.272e-06,-1.48355e-08,0.406343,0.00131377,1.2275e-06,3.76652e-09,0.407658,0.00131623,1.23879e-06,-2.30784e-10,0.408976,0.00131871,1.2381e-06,-2.84331e-09,0.410296,0.00132118,1.22957e-06,1.16041e-08,0.411618,0.00132367,1.26438e-06,-1.37708e-08,0.412943,0.00132616,1.22307e-06,1.36768e-08,0.41427,0.00132865,1.2641e-06,-1.1134e-08,0.4156,0.00133114,1.2307e-06,1.05714e-09,0.416933,0.00133361,1.23387e-06,6.90538e-09,0.418267,0.00133609,1.25459e-06,1.12372e-09,0.419605,0.00133861,1.25796e-06,-1.14002e-08,0.420945,0.00134109,1.22376e-06,1.46747e-08,0.422287,0.00134358,1.26778e-06,-1.7496e-08,0.423632,0.00134606,1.21529e-06,2.5507e-08,0.424979,0.00134857,1.29182e-06,-2.49272e-08,0.426329,0.00135108,1.21703e-06,1.45972e-08,0.427681,0.00135356,1.26083e-06,-3.65935e-09,0.429036,0.00135607,1.24985e-06,4.00178e-11,0.430393,0.00135857,1.24997e-06,3.49917e-09,0.431753,0.00136108,1.26047e-06,-1.40366e-08,0.433116,0.00136356,1.21836e-06,2.28448e-08,0.43448,0.00136606,1.28689e-06,-1.77378e-08,0.435848,0.00136858,1.23368e-06,1.83043e-08,0.437218,0.0013711,1.28859e-06,-2.56769e-08,0.43859,0.0013736,1.21156e-06,2.47987e-08,0.439965,0.0013761,1.28595e-06,-1.39133e-08,0.441342,0.00137863,1.24421e-06,1.05202e-09,0.442722,0.00138112,1.24737e-06,9.70507e-09,0.444104,0.00138365,1.27649e-06,-1.00698e-08,0.445489,0.00138617,1.24628e-06,7.72123e-10,0.446877,0.00138867,1.24859e-06,6.98132e-09,0.448267,0.00139118,1.26954e-06,1.10477e-09,0.449659,0.00139373,1.27285e-06,-1.14003e-08,0.451054,0.00139624,1.23865e-06,1.4694e-08,0.452452,0.00139876,1.28273e-06,-1.75734e-08,0.453852,0.00140127,1.23001e-06,2.5797e-08,0.455254,0.00140381,1.3074e-06,-2.60097e-08,0.456659,0.00140635,1.22937e-06,1.86371e-08,0.458067,0.00140886,1.28529e-06,-1.8736e-08,0.459477,0.00141137,1.22908e-06,2.65048e-08,0.46089,0.00141391,1.30859e-06,-2.76784e-08,0.462305,0.00141645,1.22556e-06,2.46043e-08,0.463722,0.00141897,1.29937e-06,-1.11341e-08,0.465143,0.00142154,1.26597e-06,-9.87033e-09,0.466565,0.00142404,1.23636e-06,2.08131e-08,0.467991,0.00142657,1.2988e-06,-1.37773e-08,0.469419,0.00142913,1.25746e-06,4.49378e-09,0.470849,0.00143166,1.27094e-06,-4.19781e-09,0.472282,0.00143419,1.25835e-06,1.22975e-08,0.473717,0.00143674,1.29524e-06,-1.51902e-08,0.475155,0.00143929,1.24967e-06,1.86608e-08,0.476596,0.00144184,1.30566e-06,-2.96506e-08,0.478039,0.00144436,1.2167e-06,4.03368e-08,0.479485,0.00144692,1.33771e-06,-4.22896e-08,0.480933,0.00144947,1.21085e-06,3.94148e-08,0.482384,0.00145201,1.32909e-06,-2.59626e-08,0.483837,0.00145459,1.2512e-06,4.83124e-09,0.485293,0.0014571,1.2657e-06,6.63757e-09,0.486751,0.00145966,1.28561e-06,-1.57911e-09,0.488212,0.00146222,1.28087e-06,-3.21468e-10,0.489676,0.00146478,1.27991e-06,2.86517e-09,0.491142,0.00146735,1.2885e-06,-1.11392e-08,0.49261,0.00146989,1.25508e-06,1.18893e-08,0.494081,0.00147244,1.29075e-06,-6.61574e-09,0.495555,0.001475,1.27091e-06,1.45736e-08,0.497031,0.00147759,1.31463e-06,-2.18759e-08,0.49851,0.00148015,1.249e-06,1.33252e-08,0.499992,0.00148269,1.28897e-06,-1.62277e-09,0.501476,0.00148526,1.28411e-06,-6.83421e-09,0.502962,0.00148781,1.2636e-06,2.89596e-08,0.504451,0.00149042,1.35048e-06,-4.93997e-08,0.505943,0.00149298,1.20228e-06,4.94299e-08,0.507437,0.00149553,1.35057e-06,-2.91107e-08,0.508934,0.00149814,1.26324e-06,7.40848e-09,0.510434,0.00150069,1.28547e-06,-5.23187e-10,0.511936,0.00150326,1.2839e-06,-5.31585e-09,0.51344,0.00150581,1.26795e-06,2.17866e-08,0.514947,0.00150841,1.33331e-06,-2.22257e-08,0.516457,0.00151101,1.26663e-06,7.51178e-09,0.517969,0.00151357,1.28917e-06,-7.82128e-09,0.519484,0.00151613,1.2657e-06,2.37733e-08,0.521002,0.00151873,1.33702e-06,-2.76674e-08,0.522522,0.00152132,1.25402e-06,2.72917e-08,0.524044,0.00152391,1.3359e-06,-2.18949e-08,0.525569,0.00152652,1.27021e-06,6.83372e-10,0.527097,0.00152906,1.27226e-06,1.91613e-08,0.528628,0.00153166,1.32974e-06,-1.77241e-08,0.53016,0.00153427,1.27657e-06,-7.86963e-09,0.531696,0.0015368,1.25296e-06,4.92027e-08,0.533234,0.00153945,1.40057e-06,-6.9732e-08,0.534775,0.00154204,1.19138e-06,5.09114e-08,0.536318,0.00154458,1.34411e-06,-1.4704e-08,0.537864,0.00154722,1.3e-06,7.9048e-09,0.539413,0.00154984,1.32371e-06,-1.69152e-08,0.540964,0.00155244,1.27297e-06,1.51355e-10,0.542517,0.00155499,1.27342e-06,1.63099e-08,0.544074,0.00155758,1.32235e-06,-5.78647e-09,0.545633,0.00156021,1.30499e-06,6.83599e-09,0.547194,0.00156284,1.3255e-06,-2.15575e-08,0.548758,0.00156543,1.26083e-06,1.97892e-08,0.550325,0.00156801,1.32019e-06,2.00525e-09,0.551894,0.00157065,1.32621e-06,-2.78103e-08,0.553466,0.00157322,1.24278e-06,4.96314e-08,0.555041,0.00157586,1.39167e-06,-5.1506e-08,0.556618,0.00157849,1.23716e-06,3.71835e-08,0.558198,0.00158107,1.34871e-06,-3.76233e-08,0.55978,0.00158366,1.23584e-06,5.37052e-08,0.561365,0.00158629,1.39695e-06,-5.79884e-08,0.562953,0.00158891,1.22299e-06,5.90392e-08,0.564543,0.00159153,1.4001e-06,-5.89592e-08,0.566136,0.00159416,1.22323e-06,5.7588e-08,0.567731,0.00159678,1.39599e-06,-5.21835e-08,0.569329,0.00159941,1.23944e-06,3.19369e-08,0.57093,0.00160199,1.33525e-06,-1.59594e-08,0.572533,0.00160461,1.28737e-06,3.19006e-08,0.574139,0.00160728,1.38307e-06,-5.20383e-08,0.575748,0.00160989,1.22696e-06,5.70431e-08,0.577359,0.00161251,1.39809e-06,-5.69247e-08,0.578973,0.00161514,1.22731e-06,5.14463e-08,0.580589,0.00161775,1.38165e-06,-2.9651e-08,0.582208,0.00162042,1.2927e-06,7.55339e-09,0.58383,0.00162303,1.31536e-06,-5.62636e-10,0.585455,0.00162566,1.31367e-06,-5.30281e-09,0.587081,0.00162827,1.29776e-06,2.17738e-08,0.588711,0.00163093,1.36309e-06,-2.21875e-08,0.590343,0.00163359,1.29652e-06,7.37164e-09,0.591978,0.00163621,1.31864e-06,-7.29907e-09,0.593616,0.00163882,1.29674e-06,2.18247e-08,0.595256,0.00164148,1.36221e-06,-2.03952e-08,0.596899,0.00164414,1.30103e-06,1.51241e-10,0.598544,0.00164675,1.30148e-06,1.97902e-08,0.600192,0.00164941,1.36085e-06,-1.97074e-08,0.601843,0.00165207,1.30173e-06,-5.65175e-10,0.603496,0.00165467,1.30004e-06,2.1968e-08,0.605152,0.00165734,1.36594e-06,-2.77024e-08,0.606811,0.00165999,1.28283e-06,2.92369e-08,0.608472,0.00166264,1.37054e-06,-2.96407e-08,0.610136,0.00166529,1.28162e-06,2.97215e-08,0.611803,0.00166795,1.37079e-06,-2.96408e-08,0.613472,0.0016706,1.28186e-06,2.92371e-08,0.615144,0.00167325,1.36957e-06,-2.77031e-08,0.616819,0.00167591,1.28647e-06,2.19708e-08,0.618496,0.00167855,1.35238e-06,-5.75407e-10,0.620176,0.00168125,1.35065e-06,-1.9669e-08,0.621858,0.00168389,1.29164e-06,1.96468e-08,0.623544,0.00168653,1.35058e-06,6.86403e-10,0.625232,0.00168924,1.35264e-06,-2.23924e-08,0.626922,0.00169187,1.28547e-06,2.92788e-08,0.628615,0.00169453,1.3733e-06,-3.51181e-08,0.630311,0.00169717,1.26795e-06,5.15889e-08,0.63201,0.00169987,1.42272e-06,-5.2028e-08,0.633711,0.00170255,1.26663e-06,3.73139e-08,0.635415,0.0017052,1.37857e-06,-3.76227e-08,0.637121,0.00170784,1.2657e-06,5.35722e-08,0.63883,0.00171054,1.42642e-06,-5.74567e-08,0.640542,0.00171322,1.25405e-06,5.70456e-08,0.642257,0.0017159,1.42519e-06,-5.15163e-08,0.643974,0.00171859,1.27064e-06,2.98103e-08,0.645694,0.00172122,1.36007e-06,-8.12016e-09,0.647417,0.00172392,1.33571e-06,2.67039e-09,0.649142,0.0017266,1.34372e-06,-2.56152e-09,0.65087,0.00172928,1.33604e-06,7.57571e-09,0.6526,0.00173197,1.35876e-06,-2.77413e-08,0.654334,0.00173461,1.27554e-06,4.3785e-08,0.65607,0.00173729,1.40689e-06,-2.81896e-08,0.657808,0.00174002,1.32233e-06,9.36893e-09,0.65955,0.00174269,1.35043e-06,-9.28617e-09,0.661294,0.00174536,1.32257e-06,2.77757e-08,0.66304,0.00174809,1.4059e-06,-4.2212e-08,0.66479,0.00175078,1.27926e-06,2.1863e-08,0.666542,0.0017534,1.34485e-06,1.43648e-08,0.668297,0.00175613,1.38795e-06,-1.97177e-08,0.670054,0.00175885,1.3288e-06,4.90115e-09,0.671814,0.00176152,1.3435e-06,1.13232e-10,0.673577,0.00176421,1.34384e-06,-5.3542e-09,0.675343,0.00176688,1.32778e-06,2.13035e-08,0.677111,0.0017696,1.39169e-06,-2.02553e-08,0.678882,0.00177232,1.33092e-06,1.13005e-10,0.680656,0.00177499,1.33126e-06,1.98031e-08,0.682432,0.00177771,1.39067e-06,-1.97211e-08,0.684211,0.00178043,1.33151e-06,-5.2349e-10,0.685993,0.00178309,1.32994e-06,2.18151e-08,0.687777,0.00178582,1.39538e-06,-2.71325e-08,0.689564,0.00178853,1.31398e-06,2.71101e-08,0.691354,0.00179124,1.39531e-06,-2.17035e-08,0.693147,0.00179396,1.3302e-06,9.92865e-11,0.694942,0.00179662,1.3305e-06,2.13063e-08,0.69674,0.00179935,1.39442e-06,-2.57198e-08,0.698541,0.00180206,1.31726e-06,2.19682e-08,0.700344,0.00180476,1.38317e-06,-2.54852e-09,0.70215,0.00180752,1.37552e-06,-1.17741e-08,0.703959,0.00181023,1.3402e-06,-9.95999e-09,0.705771,0.00181288,1.31032e-06,5.16141e-08,0.707585,0.00181566,1.46516e-06,-7.72869e-08,0.709402,0.00181836,1.2333e-06,7.87197e-08,0.711222,0.00182106,1.46946e-06,-5.87781e-08,0.713044,0.00182382,1.29312e-06,3.71834e-08,0.714869,0.00182652,1.40467e-06,-3.03511e-08,0.716697,0.00182924,1.31362e-06,2.46161e-08,0.718528,0.00183194,1.38747e-06,-8.5087e-09,0.720361,0.00183469,1.36194e-06,9.41892e-09,0.722197,0.00183744,1.3902e-06,-2.91671e-08,0.724036,0.00184014,1.3027e-06,4.76448e-08,0.725878,0.00184288,1.44563e-06,-4.22028e-08,0.727722,0.00184565,1.31902e-06,1.95682e-09,0.729569,0.00184829,1.3249e-06,3.43754e-08,0.731419,0.00185104,1.42802e-06,-2.0249e-08,0.733271,0.00185384,1.36727e-06,-1.29838e-08,0.735126,0.00185654,1.32832e-06,1.25794e-08,0.736984,0.00185923,1.36606e-06,2.22711e-08,0.738845,0.00186203,1.43287e-06,-4.20594e-08,0.740708,0.00186477,1.3067e-06,2.67571e-08,0.742574,0.00186746,1.38697e-06,-5.36424e-09,0.744443,0.00187022,1.37087e-06,-5.30023e-09,0.746315,0.00187295,1.35497e-06,2.65653e-08,0.748189,0.00187574,1.43467e-06,-4.13564e-08,0.750066,0.00187848,1.3106e-06,1.9651e-08,0.751946,0.00188116,1.36955e-06,2.23572e-08,0.753828,0.00188397,1.43663e-06,-4.9475e-08,0.755714,0.00188669,1.2882e-06,5.63335e-08,0.757602,0.00188944,1.4572e-06,-5.66499e-08,0.759493,0.00189218,1.28725e-06,5.10567e-08,0.761386,0.00189491,1.44042e-06,-2.83677e-08,0.763283,0.00189771,1.35532e-06,2.80962e-09,0.765182,0.00190042,1.36375e-06,1.71293e-08,0.767083,0.0019032,1.41513e-06,-1.17221e-08,0.768988,0.001906,1.37997e-06,-2.98453e-08,0.770895,0.00190867,1.29043e-06,7.14987e-08,0.772805,0.00191146,1.50493e-06,-7.73354e-08,0.774718,0.00191424,1.27292e-06,5.90292e-08,0.776634,0.00191697,1.45001e-06,-3.9572e-08,0.778552,0.00191975,1.33129e-06,3.9654e-08,0.780473,0.00192253,1.45026e-06,-5.94395e-08,0.782397,0.00192525,1.27194e-06,7.88945e-08,0.784324,0.00192803,1.50862e-06,-7.73249e-08,0.786253,0.00193082,1.27665e-06,5.15913e-08,0.788185,0.00193352,1.43142e-06,-9.83099e-09,0.79012,0.00193636,1.40193e-06,-1.22672e-08,0.792058,0.00193912,1.36513e-06,-7.05275e-10,0.793999,0.00194185,1.36301e-06,1.50883e-08,0.795942,0.00194462,1.40828e-06,-4.33147e-11,0.797888,0.00194744,1.40815e-06,-1.49151e-08,0.799837,0.00195021,1.3634e-06,9.93244e-11,0.801788,0.00195294,1.3637e-06,1.45179e-08,0.803743,0.00195571,1.40725e-06,1.43363e-09,0.8057,0.00195853,1.41155e-06,-2.02525e-08,0.80766,0.00196129,1.35079e-06,1.99718e-08,0.809622,0.00196405,1.41071e-06,-3.01649e-11,0.811588,0.00196687,1.41062e-06,-1.9851e-08,0.813556,0.00196964,1.35107e-06,1.98296e-08,0.815527,0.0019724,1.41056e-06,1.37485e-10,0.817501,0.00197522,1.41097e-06,-2.03796e-08,0.819477,0.00197798,1.34983e-06,2.17763e-08,0.821457,0.00198074,1.41516e-06,-7.12085e-09,0.823439,0.00198355,1.3938e-06,6.70707e-09,0.825424,0.00198636,1.41392e-06,-1.97074e-08,0.827412,0.00198913,1.35479e-06,1.25179e-08,0.829402,0.00199188,1.39235e-06,2.92405e-08,0.831396,0.00199475,1.48007e-06,-6.98755e-08,0.833392,0.0019975,1.27044e-06,7.14477e-08,0.835391,0.00200026,1.48479e-06,-3.71014e-08,0.837392,0.00200311,1.37348e-06,1.73533e-08,0.839397,0.00200591,1.42554e-06,-3.23118e-08,0.841404,0.00200867,1.32861e-06,5.2289e-08,0.843414,0.00201148,1.48547e-06,-5.76348e-08,0.845427,0.00201428,1.31257e-06,5.9041e-08,0.847443,0.00201708,1.48969e-06,-5.93197e-08,0.849461,0.00201988,1.31173e-06,5.90289e-08,0.851482,0.00202268,1.48882e-06,-5.75864e-08,0.853507,0.00202549,1.31606e-06,5.21075e-08,0.855533,0.00202828,1.47238e-06,-3.16344e-08,0.857563,0.00203113,1.37748e-06,1.48257e-08,0.859596,0.00203393,1.42196e-06,-2.76684e-08,0.861631,0.00203669,1.33895e-06,3.62433e-08,0.863669,0.00203947,1.44768e-06,1.90463e-09,0.86571,0.00204237,1.45339e-06,-4.38617e-08,0.867754,0.00204515,1.32181e-06,5.43328e-08,0.8698,0.00204796,1.48481e-06,-5.42603e-08,0.87185,0.00205076,1.32203e-06,4.34989e-08,0.873902,0.00205354,1.45252e-06,-5.26029e-10,0.875957,0.00205644,1.45095e-06,-4.13949e-08,0.878015,0.00205922,1.32676e-06,4.68962e-08,0.880075,0.00206201,1.46745e-06,-2.69807e-08,0.882139,0.00206487,1.38651e-06,1.42181e-09,0.884205,0.00206764,1.39077e-06,2.12935e-08,0.886274,0.00207049,1.45465e-06,-2.69912e-08,0.888346,0.00207332,1.37368e-06,2.70664e-08,0.890421,0.00207615,1.45488e-06,-2.16698e-08,0.892498,0.00207899,1.38987e-06,8.14756e-12,0.894579,0.00208177,1.38989e-06,2.16371e-08,0.896662,0.00208462,1.45481e-06,-2.6952e-08,0.898748,0.00208744,1.37395e-06,2.65663e-08,0.900837,0.00209027,1.45365e-06,-1.97084e-08,0.902928,0.00209312,1.39452e-06,-7.33731e-09,0.905023,0.00209589,1.37251e-06,4.90578e-08,0.90712,0.00209878,1.51968e-06,-6.96845e-08,0.90922,0.00210161,1.31063e-06,5.08664e-08,0.911323,0.00210438,1.46323e-06,-1.45717e-08,0.913429,0.00210727,1.41952e-06,7.42038e-09,0.915538,0.00211013,1.44178e-06,-1.51097e-08,0.917649,0.00211297,1.39645e-06,-6.58618e-09,0.919764,0.00211574,1.37669e-06,4.14545e-08,0.921881,0.00211862,1.50105e-06,-4.00222e-08,0.924001,0.0021215,1.38099e-06,-5.7518e-10,0.926124,0.00212426,1.37926e-06,4.23229e-08,0.92825,0.00212714,1.50623e-06,-4.9507e-08,0.930378,0.00213001,1.35771e-06,3.64958e-08,0.93251,0.00213283,1.4672e-06,-3.68713e-08,0.934644,0.00213566,1.35658e-06,5.13848e-08,0.936781,0.00213852,1.51074e-06,-4.94585e-08,0.938921,0.0021414,1.36236e-06,2.72399e-08,0.941064,0.0021442,1.44408e-06,1.0372e-10,0.943209,0.00214709,1.44439e-06,-2.76547e-08,0.945358,0.0021499,1.36143e-06,5.09106e-08,0.947509,0.00215277,1.51416e-06,-5.67784e-08,0.949663,0.00215563,1.34382e-06,5.69935e-08,0.95182,0.00215849,1.5148e-06,-5.19861e-08,0.95398,0.00216136,1.35885e-06,3.17417e-08,0.956143,0.00216418,1.45407e-06,-1.53758e-08,0.958309,0.00216704,1.40794e-06,2.97615e-08,0.960477,0.00216994,1.49723e-06,-4.40657e-08,0.962649,0.00217281,1.36503e-06,2.72919e-08,0.964823,0.00217562,1.44691e-06,-5.49729e-09,0.967,0.0021785,1.43041e-06,-5.30273e-09,0.96918,0.00218134,1.41451e-06,2.67084e-08,0.971363,0.00218425,1.49463e-06,-4.19265e-08,0.973548,0.00218711,1.36885e-06,2.17881e-08,0.975737,0.00218992,1.43422e-06,1.43789e-08,0.977928,0.00219283,1.47735e-06,-1.96989e-08,0.980122,0.00219572,1.41826e-06,4.81221e-09,0.98232,0.00219857,1.43269e-06,4.50048e-10,0.98452,0.00220144,1.43404e-06,-6.61237e-09,0.986722,0.00220429,1.41421e-06,2.59993e-08,0.988928,0.0022072,1.4922e-06,-3.77803e-08,0.991137,0.00221007,1.37886e-06,5.9127e-09,0.993348,0.00221284,1.3966e-06,1.33339e-07,0.995563,0.00221604,1.79662e-06,-5.98872e-07,0.99778,0.00222015,0.,0.}; + + template + __device__ __forceinline__ void RGB2LabConvert_f(const T& src, D& dst) + { + const float _1_3 = 1.0f / 3.0f; + const float _a = 16.0f / 116.0f; + + float B = blueIdx == 0 ? src.x : src.z; + float G = src.y; + float R = blueIdx == 0 ? src.z : src.x; + + if (srgb) + { + B = splineInterpolate(B * GAMMA_TAB_SIZE, c_sRGBGammaTab, GAMMA_TAB_SIZE); + G = splineInterpolate(G * GAMMA_TAB_SIZE, c_sRGBGammaTab, GAMMA_TAB_SIZE); + R = splineInterpolate(R * GAMMA_TAB_SIZE, c_sRGBGammaTab, GAMMA_TAB_SIZE); + } + + float X = B * 0.189828f + G * 0.376219f + R * 0.433953f; + float Y = B * 0.072169f + G * 0.715160f + R * 0.212671f; + float Z = B * 0.872766f + G * 0.109477f + R * 0.017758f; + + float FX = X > 0.008856f ? ::powf(X, _1_3) : (7.787f * X + _a); + float FY = Y > 0.008856f ? ::powf(Y, _1_3) : (7.787f * Y + _a); + float FZ = Z > 0.008856f ? ::powf(Z, _1_3) : (7.787f * Z + _a); + + float L = Y > 0.008856f ? (116.f * FY - 16.f) : (903.3f * Y); + float a = 500.f * (FX - FY); + float b = 200.f * (FY - FZ); + + dst.x = L; + dst.y = a; + dst.z = b; + } + + template struct RGB2Lab; + template + struct RGB2Lab + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + RGB2LabConvert_b(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ RGB2Lab() {} + __host__ __device__ __forceinline__ RGB2Lab(const RGB2Lab&) {} + }; + template + struct RGB2Lab + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + RGB2LabConvert_f(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ RGB2Lab() {} + __host__ __device__ __forceinline__ RGB2Lab(const RGB2Lab&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2Lab_TRAITS(name, scn, dcn, srgb, blueIdx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2Lab functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + __constant__ float c_sRGBInvGammaTab[] = {0,0.0126255,0.,-8.33961e-06,0.0126172,0.0126005,-2.50188e-05,4.1698e-05,0.0252344,0.0126756,0.000100075,-0.000158451,0.0378516,0.0124004,-0.000375277,-0.000207393,0.0496693,0.0110276,-0.000997456,0.00016837,0.0598678,0.00953783,-0.000492346,2.07235e-05,0.068934,0.00861531,-0.000430176,3.62876e-05,0.0771554,0.00786382,-0.000321313,1.87625e-05,0.0847167,0.00727748,-0.000265025,1.53594e-05,0.0917445,0.00679351,-0.000218947,1.10545e-05,0.0983301,0.00638877,-0.000185784,8.66984e-06,0.104542,0.00604322,-0.000159774,6.82996e-06,0.110432,0.00574416,-0.000139284,5.51008e-06,0.116042,0.00548212,-0.000122754,4.52322e-06,0.121406,0.00525018,-0.000109184,3.75557e-06,0.126551,0.00504308,-9.79177e-05,3.17134e-06,0.131499,0.00485676,-8.84037e-05,2.68469e-06,0.13627,0.004688,-8.03496e-05,2.31725e-06,0.14088,0.00453426,-7.33978e-05,2.00868e-06,0.145343,0.00439349,-6.73718e-05,1.74775e-06,0.149671,0.00426399,-6.21286e-05,1.53547e-06,0.153875,0.00414434,-5.75222e-05,1.364e-06,0.157963,0.00403338,-5.34301e-05,1.20416e-06,0.161944,0.00393014,-4.98177e-05,1.09114e-06,0.165825,0.00383377,-4.65443e-05,9.57987e-07,0.169613,0.00374356,-4.36703e-05,8.88359e-07,0.173314,0.00365888,-4.10052e-05,7.7849e-07,0.176933,0.00357921,-3.86697e-05,7.36254e-07,0.180474,0.00350408,-3.6461e-05,6.42534e-07,0.183942,0.00343308,-3.45334e-05,6.12614e-07,0.187342,0.00336586,-3.26955e-05,5.42894e-07,0.190675,0.00330209,-3.10669e-05,5.08967e-07,0.193947,0.00324149,-2.954e-05,4.75977e-07,0.197159,0.00318383,-2.8112e-05,4.18343e-07,0.200315,0.00312887,-2.6857e-05,4.13651e-07,0.203418,0.00307639,-2.5616e-05,3.70847e-07,0.206469,0.00302627,-2.45035e-05,3.3813e-07,0.209471,0.00297828,-2.34891e-05,3.32999e-07,0.212426,0.0029323,-2.24901e-05,2.96826e-07,0.215336,0.00288821,-2.15996e-05,2.82736e-07,0.218203,0.00284586,-2.07514e-05,2.70961e-07,0.221029,0.00280517,-1.99385e-05,2.42744e-07,0.223814,0.00276602,-1.92103e-05,2.33277e-07,0.226561,0.0027283,-1.85105e-05,2.2486e-07,0.229271,0.00269195,-1.78359e-05,2.08383e-07,0.231945,0.00265691,-1.72108e-05,1.93305e-07,0.234585,0.00262307,-1.66308e-05,1.80687e-07,0.237192,0.00259035,-1.60888e-05,1.86632e-07,0.239766,0.00255873,-1.55289e-05,1.60569e-07,0.24231,0.00252815,-1.50472e-05,1.54566e-07,0.244823,0.00249852,-1.45835e-05,1.59939e-07,0.247307,0.00246983,-1.41037e-05,1.29549e-07,0.249763,0.00244202,-1.3715e-05,1.41429e-07,0.252191,0.00241501,-1.32907e-05,1.39198e-07,0.254593,0.00238885,-1.28731e-05,1.06444e-07,0.256969,0.00236342,-1.25538e-05,1.2048e-07,0.25932,0.00233867,-1.21924e-05,1.26892e-07,0.261647,0.00231467,-1.18117e-05,8.72084e-08,0.26395,0.00229131,-1.15501e-05,1.20323e-07,0.26623,0.00226857,-1.11891e-05,8.71514e-08,0.268487,0.00224645,-1.09276e-05,9.73165e-08,0.270723,0.00222489,-1.06357e-05,8.98259e-08,0.272937,0.00220389,-1.03662e-05,7.98218e-08,0.275131,0.00218339,-1.01267e-05,9.75254e-08,0.277304,0.00216343,-9.83416e-06,6.65195e-08,0.279458,0.00214396,-9.63461e-06,8.34313e-08,0.281592,0.00212494,-9.38431e-06,7.65919e-08,0.283708,0.00210641,-9.15454e-06,5.7236e-08,0.285805,0.00208827,-8.98283e-06,8.18939e-08,0.287885,0.00207055,-8.73715e-06,6.2224e-08,0.289946,0.00205326,-8.55047e-06,5.66388e-08,0.291991,0.00203633,-8.38056e-06,6.88491e-08,0.294019,0.00201978,-8.17401e-06,5.53955e-08,0.296031,0.00200359,-8.00782e-06,6.71971e-08,0.298027,0.00198778,-7.80623e-06,3.34439e-08,0.300007,0.00197227,-7.7059e-06,6.7248e-08,0.301971,0.00195706,-7.50416e-06,5.51915e-08,0.303921,0.00194221,-7.33858e-06,3.98124e-08,0.305856,0.00192766,-7.21915e-06,5.37795e-08,0.307776,0.00191338,-7.05781e-06,4.30919e-08,0.309683,0.00189939,-6.92853e-06,4.20744e-08,0.311575,0.00188566,-6.80231e-06,5.68321e-08,0.313454,0.00187223,-6.63181e-06,2.86195e-08,0.31532,0.00185905,-6.54595e-06,3.73075e-08,0.317172,0.00184607,-6.43403e-06,6.05684e-08,0.319012,0.00183338,-6.25233e-06,1.84426e-08,0.320839,0.00182094,-6.197e-06,4.44757e-08,0.322654,0.00180867,-6.06357e-06,4.20729e-08,0.324456,0.00179667,-5.93735e-06,2.56511e-08,0.326247,0.00178488,-5.8604e-06,3.41368e-08,0.328026,0.00177326,-5.75799e-06,4.64177e-08,0.329794,0.00176188,-5.61874e-06,1.86107e-08,0.33155,0.0017507,-5.5629e-06,2.81511e-08,0.333295,0.00173966,-5.47845e-06,4.75987e-08,0.335029,0.00172884,-5.33565e-06,1.98726e-08,0.336753,0.00171823,-5.27604e-06,2.19226e-08,0.338466,0.00170775,-5.21027e-06,4.14483e-08,0.340169,0.00169745,-5.08592e-06,2.09017e-08,0.341861,0.00168734,-5.02322e-06,2.39561e-08,0.343543,0.00167737,-4.95135e-06,3.22852e-08,0.345216,0.00166756,-4.85449e-06,2.57173e-08,0.346878,0.00165793,-4.77734e-06,1.38569e-08,0.348532,0.00164841,-4.73577e-06,3.80634e-08,0.350175,0.00163906,-4.62158e-06,1.27043e-08,0.35181,0.00162985,-4.58347e-06,3.03279e-08,0.353435,0.00162078,-4.49249e-06,1.49961e-08,0.355051,0.00161184,-4.4475e-06,2.88977e-08,0.356659,0.00160303,-4.3608e-06,1.84241e-08,0.358257,0.00159436,-4.30553e-06,1.6616e-08,0.359848,0.0015858,-4.25568e-06,3.43218e-08,0.361429,0.00157739,-4.15272e-06,-4.89172e-09,0.363002,0.00156907,-4.16739e-06,4.48498e-08,0.364567,0.00156087,-4.03284e-06,4.30676e-09,0.366124,0.00155282,-4.01992e-06,2.73303e-08,0.367673,0.00154486,-3.93793e-06,5.58036e-09,0.369214,0.001537,-3.92119e-06,3.97554e-08,0.370747,0.00152928,-3.80193e-06,-1.55904e-08,0.372272,0.00152163,-3.8487e-06,5.24081e-08,0.37379,0.00151409,-3.69147e-06,-1.52272e-08,0.375301,0.00150666,-3.73715e-06,3.83028e-08,0.376804,0.0014993,-3.62225e-06,1.10278e-08,0.378299,0.00149209,-3.58916e-06,6.99326e-09,0.379788,0.00148493,-3.56818e-06,2.06038e-08,0.381269,0.00147786,-3.50637e-06,2.98009e-08,0.382744,0.00147093,-3.41697e-06,-2.05978e-08,0.384211,0.00146404,-3.47876e-06,5.25899e-08,0.385672,0.00145724,-3.32099e-06,-1.09471e-08,0.387126,0.00145056,-3.35383e-06,2.10009e-08,0.388573,0.00144392,-3.29083e-06,1.63501e-08,0.390014,0.00143739,-3.24178e-06,3.00641e-09,0.391448,0.00143091,-3.23276e-06,3.12282e-08,0.392875,0.00142454,-3.13908e-06,-8.70932e-09,0.394297,0.00141824,-3.16521e-06,3.34114e-08,0.395712,0.00141201,-3.06497e-06,-5.72754e-09,0.397121,0.00140586,-3.08215e-06,1.9301e-08,0.398524,0.00139975,-3.02425e-06,1.7931e-08,0.39992,0.00139376,-2.97046e-06,-1.61822e-09,0.401311,0.00138781,-2.97531e-06,1.83442e-08,0.402696,0.00138192,-2.92028e-06,1.76485e-08,0.404075,0.00137613,-2.86733e-06,4.68617e-10,0.405448,0.00137039,-2.86593e-06,1.02794e-08,0.406816,0.00136469,-2.83509e-06,1.80179e-08,0.408178,0.00135908,-2.78104e-06,7.05594e-09,0.409534,0.00135354,-2.75987e-06,1.33633e-08,0.410885,0.00134806,-2.71978e-06,-9.04568e-10,0.41223,0.00134261,-2.72249e-06,2.0057e-08,0.41357,0.00133723,-2.66232e-06,1.00841e-08,0.414905,0.00133194,-2.63207e-06,-7.88835e-10,0.416234,0.00132667,-2.63444e-06,2.28734e-08,0.417558,0.00132147,-2.56582e-06,-1.29785e-09,0.418877,0.00131633,-2.56971e-06,1.21205e-08,0.420191,0.00131123,-2.53335e-06,1.24202e-08,0.421499,0.0013062,-2.49609e-06,-2.19681e-09,0.422803,0.0013012,-2.50268e-06,2.61696e-08,0.424102,0.00129628,-2.42417e-06,-1.30747e-08,0.425396,0.00129139,-2.46339e-06,2.6129e-08,0.426685,0.00128654,-2.38501e-06,-2.03454e-09,0.427969,0.00128176,-2.39111e-06,1.18115e-08,0.429248,0.00127702,-2.35567e-06,1.43932e-08,0.430523,0.00127235,-2.31249e-06,-9.77965e-09,0.431793,0.00126769,-2.34183e-06,2.47253e-08,0.433058,0.00126308,-2.26766e-06,2.85278e-10,0.434319,0.00125855,-2.2668e-06,3.93614e-09,0.435575,0.00125403,-2.25499e-06,1.37722e-08,0.436827,0.00124956,-2.21368e-06,5.79803e-10,0.438074,0.00124513,-2.21194e-06,1.37112e-08,0.439317,0.00124075,-2.1708e-06,4.17973e-09,0.440556,0.00123642,-2.15826e-06,-6.27703e-10,0.44179,0.0012321,-2.16015e-06,2.81332e-08,0.44302,0.00122787,-2.07575e-06,-2.24985e-08,0.444246,0.00122365,-2.14324e-06,3.20586e-08,0.445467,0.00121946,-2.04707e-06,-1.6329e-08,0.446685,0.00121532,-2.09605e-06,3.32573e-08,0.447898,0.00121122,-1.99628e-06,-2.72927e-08,0.449107,0.00120715,-2.07816e-06,4.6111e-08,0.450312,0.00120313,-1.93983e-06,-3.79416e-08,0.451514,0.00119914,-2.05365e-06,4.60507e-08,0.452711,0.00119517,-1.9155e-06,-2.7052e-08,0.453904,0.00119126,-1.99666e-06,3.23551e-08,0.455093,0.00118736,-1.89959e-06,-1.29613e-08,0.456279,0.00118352,-1.93848e-06,1.94905e-08,0.45746,0.0011797,-1.88e-06,-5.39588e-09,0.458638,0.00117593,-1.89619e-06,2.09282e-09,0.459812,0.00117214,-1.88991e-06,2.68267e-08,0.460982,0.00116844,-1.80943e-06,-1.99925e-08,0.462149,0.00116476,-1.86941e-06,2.3341e-08,0.463312,0.00116109,-1.79939e-06,-1.37674e-08,0.464471,0.00115745,-1.84069e-06,3.17287e-08,0.465627,0.00115387,-1.7455e-06,-2.37407e-08,0.466779,0.00115031,-1.81673e-06,3.34315e-08,0.467927,0.00114677,-1.71643e-06,-2.05786e-08,0.469073,0.00114328,-1.77817e-06,1.90802e-08,0.470214,0.00113978,-1.72093e-06,3.86247e-09,0.471352,0.00113635,-1.70934e-06,-4.72759e-09,0.472487,0.00113292,-1.72352e-06,1.50478e-08,0.473618,0.00112951,-1.67838e-06,4.14108e-09,0.474746,0.00112617,-1.66595e-06,-1.80986e-09,0.47587,0.00112283,-1.67138e-06,3.09816e-09,0.476991,0.0011195,-1.66209e-06,1.92198e-08,0.478109,0.00111623,-1.60443e-06,-2.03726e-08,0.479224,0.00111296,-1.66555e-06,3.2468e-08,0.480335,0.00110973,-1.56814e-06,-2.00922e-08,0.481443,0.00110653,-1.62842e-06,1.80983e-08,0.482548,0.00110333,-1.57413e-06,7.30362e-09,0.48365,0.0011002,-1.55221e-06,-1.75107e-08,0.484749,0.00109705,-1.60475e-06,3.29373e-08,0.485844,0.00109393,-1.50594e-06,-2.48315e-08,0.486937,0.00109085,-1.58043e-06,3.65865e-08,0.488026,0.0010878,-1.47067e-06,-3.21078e-08,0.489112,0.00108476,-1.56699e-06,3.22397e-08,0.490195,0.00108172,-1.47027e-06,-7.44391e-09,0.491276,0.00107876,-1.49261e-06,-2.46428e-09,0.492353,0.00107577,-1.5e-06,1.73011e-08,0.493427,0.00107282,-1.4481e-06,-7.13552e-09,0.494499,0.0010699,-1.4695e-06,1.1241e-08,0.495567,0.001067,-1.43578e-06,-8.02637e-09,0.496633,0.0010641,-1.45986e-06,2.08645e-08,0.497695,0.00106124,-1.39726e-06,-1.58271e-08,0.498755,0.0010584,-1.44475e-06,1.26415e-08,0.499812,0.00105555,-1.40682e-06,2.48655e-08,0.500866,0.00105281,-1.33222e-06,-5.24988e-08,0.501918,0.00104999,-1.48972e-06,6.59206e-08,0.502966,0.00104721,-1.29196e-06,-3.237e-08,0.504012,0.00104453,-1.38907e-06,3.95479e-09,0.505055,0.00104176,-1.3772e-06,1.65509e-08,0.506096,0.00103905,-1.32755e-06,-1.05539e-08,0.507133,0.00103637,-1.35921e-06,2.56648e-08,0.508168,0.00103373,-1.28222e-06,-3.25007e-08,0.509201,0.00103106,-1.37972e-06,4.47336e-08,0.51023,0.00102844,-1.24552e-06,-2.72245e-08,0.511258,0.00102587,-1.32719e-06,4.55952e-09,0.512282,0.00102323,-1.31352e-06,8.98645e-09,0.513304,0.00102063,-1.28656e-06,1.90992e-08,0.514323,0.00101811,-1.22926e-06,-2.57786e-08,0.51534,0.00101557,-1.30659e-06,2.44104e-08,0.516355,0.00101303,-1.23336e-06,-1.22581e-08,0.517366,0.00101053,-1.27014e-06,2.4622e-08,0.518376,0.00100806,-1.19627e-06,-2.66253e-08,0.519383,0.00100559,-1.27615e-06,2.22744e-08,0.520387,0.00100311,-1.20932e-06,-2.8679e-09,0.521389,0.00100068,-1.21793e-06,-1.08029e-08,0.522388,0.000998211,-1.25034e-06,4.60795e-08,0.523385,0.000995849,-1.1121e-06,-5.4306e-08,0.52438,0.000993462,-1.27502e-06,5.19354e-08,0.525372,0.000991067,-1.11921e-06,-3.42262e-08,0.526362,0.000988726,-1.22189e-06,2.53646e-08,0.52735,0.000986359,-1.14579e-06,-7.62782e-09,0.528335,0.000984044,-1.16868e-06,5.14668e-09,0.529318,0.000981722,-1.15324e-06,-1.29589e-08,0.530298,0.000979377,-1.19211e-06,4.66888e-08,0.531276,0.000977133,-1.05205e-06,-5.45868e-08,0.532252,0.000974865,-1.21581e-06,5.24495e-08,0.533226,0.000972591,-1.05846e-06,-3.60019e-08,0.534198,0.000970366,-1.16647e-06,3.19537e-08,0.535167,0.000968129,-1.07061e-06,-3.2208e-08,0.536134,0.000965891,-1.16723e-06,3.72738e-08,0.537099,0.000963668,-1.05541e-06,2.32205e-09,0.538061,0.000961564,-1.04844e-06,-4.65618e-08,0.539022,0.000959328,-1.18813e-06,6.47159e-08,0.53998,0.000957146,-9.93979e-07,-3.3488e-08,0.540936,0.000955057,-1.09444e-06,9.63166e-09,0.54189,0.000952897,-1.06555e-06,-5.03871e-09,0.542842,0.000950751,-1.08066e-06,1.05232e-08,0.543792,0.000948621,-1.04909e-06,2.25503e-08,0.544739,0.000946591,-9.81444e-07,-4.11195e-08,0.545685,0.000944504,-1.1048e-06,2.27182e-08,0.546628,0.000942363,-1.03665e-06,9.85146e-09,0.54757,0.000940319,-1.00709e-06,-2.51938e-09,0.548509,0.000938297,-1.01465e-06,2.25858e-10,0.549446,0.000936269,-1.01397e-06,1.61598e-09,0.550381,0.000934246,-1.00913e-06,-6.68983e-09,0.551315,0.000932207,-1.0292e-06,2.51434e-08,0.552246,0.000930224,-9.53765e-07,-3.42793e-08,0.553175,0.000928214,-1.0566e-06,5.23688e-08,0.554102,0.000926258,-8.99497e-07,-5.59865e-08,0.555028,0.000924291,-1.06746e-06,5.23679e-08,0.555951,0.000922313,-9.10352e-07,-3.42763e-08,0.556872,0.00092039,-1.01318e-06,2.51326e-08,0.557792,0.000918439,-9.37783e-07,-6.64954e-09,0.558709,0.000916543,-9.57732e-07,1.46554e-09,0.559625,0.000914632,-9.53335e-07,7.87281e-10,0.560538,0.000912728,-9.50973e-07,-4.61466e-09,0.56145,0.000910812,-9.64817e-07,1.76713e-08,0.56236,0.000908935,-9.11804e-07,-6.46564e-09,0.563268,0.000907092,-9.312e-07,8.19121e-09,0.564174,0.000905255,-9.06627e-07,-2.62992e-08,0.565078,0.000903362,-9.85524e-07,3.74007e-08,0.565981,0.000901504,-8.73322e-07,-4.0942e-09,0.566882,0.000899745,-8.85605e-07,-2.1024e-08,0.56778,0.00089791,-9.48677e-07,2.85854e-08,0.568677,0.000896099,-8.62921e-07,-3.3713e-08,0.569573,0.000894272,-9.64059e-07,4.6662e-08,0.570466,0.000892484,-8.24073e-07,-3.37258e-08,0.571358,0.000890734,-9.25251e-07,2.86365e-08,0.572247,0.00088897,-8.39341e-07,-2.12155e-08,0.573135,0.000887227,-9.02988e-07,-3.37913e-09,0.574022,0.000885411,-9.13125e-07,3.47319e-08,0.574906,0.000883689,-8.08929e-07,-1.63394e-08,0.575789,0.000882022,-8.57947e-07,-2.8979e-08,0.57667,0.00088022,-9.44885e-07,7.26509e-08,0.57755,0.000878548,-7.26932e-07,-8.28106e-08,0.578427,0.000876845,-9.75364e-07,7.97774e-08,0.579303,0.000875134,-7.36032e-07,-5.74849e-08,0.580178,0.00087349,-9.08486e-07,3.09529e-08,0.58105,0.000871765,-8.15628e-07,-6.72206e-09,0.581921,0.000870114,-8.35794e-07,-4.06451e-09,0.582791,0.00086843,-8.47987e-07,2.29799e-08,0.583658,0.000866803,-7.79048e-07,-2.82503e-08,0.584524,0.00086516,-8.63799e-07,3.04167e-08,0.585388,0.000863524,-7.72548e-07,-3.38119e-08,0.586251,0.000861877,-8.73984e-07,4.52264e-08,0.587112,0.000860265,-7.38305e-07,-2.78842e-08,0.587972,0.000858705,-8.21958e-07,6.70567e-09,0.58883,0.000857081,-8.01841e-07,1.06161e-09,0.589686,0.000855481,-7.98656e-07,-1.09521e-08,0.590541,0.00085385,-8.31512e-07,4.27468e-08,0.591394,0.000852316,-7.03272e-07,-4.08257e-08,0.592245,0.000850787,-8.25749e-07,1.34677e-09,0.593095,0.000849139,-8.21709e-07,3.54387e-08,0.593944,0.000847602,-7.15393e-07,-2.38924e-08,0.59479,0.0008461,-7.8707e-07,5.26143e-10,0.595636,0.000844527,-7.85491e-07,2.17879e-08,0.596479,0.000843021,-7.20127e-07,-2.80733e-08,0.597322,0.000841497,-8.04347e-07,3.09005e-08,0.598162,0.000839981,-7.11646e-07,-3.5924e-08,0.599002,0.00083845,-8.19418e-07,5.3191e-08,0.599839,0.000836971,-6.59845e-07,-5.76307e-08,0.600676,0.000835478,-8.32737e-07,5.81227e-08,0.60151,0.000833987,-6.58369e-07,-5.56507e-08,0.602344,0.000832503,-8.25321e-07,4.52706e-08,0.603175,0.000830988,-6.89509e-07,-6.22236e-09,0.604006,0.000829591,-7.08176e-07,-2.03811e-08,0.604834,0.000828113,-7.6932e-07,2.8142e-08,0.605662,0.000826659,-6.84894e-07,-3.25822e-08,0.606488,0.000825191,-7.8264e-07,4.25823e-08,0.607312,0.000823754,-6.54893e-07,-1.85376e-08,0.608135,0.000822389,-7.10506e-07,-2.80365e-08,0.608957,0.000820883,-7.94616e-07,7.1079e-08,0.609777,0.000819507,-5.81379e-07,-7.74655e-08,0.610596,0.000818112,-8.13775e-07,5.9969e-08,0.611413,0.000816665,-6.33868e-07,-4.32013e-08,0.612229,0.000815267,-7.63472e-07,5.32313e-08,0.613044,0.0008139,-6.03778e-07,-5.05148e-08,0.613857,0.000812541,-7.55323e-07,2.96187e-08,0.614669,0.000811119,-6.66466e-07,-8.35545e-09,0.615479,0.000809761,-6.91533e-07,3.80301e-09,0.616288,0.00080839,-6.80124e-07,-6.85666e-09,0.617096,0.000807009,-7.00694e-07,2.36237e-08,0.617903,0.000805678,-6.29822e-07,-2.80336e-08,0.618708,0.000804334,-7.13923e-07,2.8906e-08,0.619511,0.000802993,-6.27205e-07,-2.79859e-08,0.620314,0.000801655,-7.11163e-07,2.34329e-08,0.621114,0.000800303,-6.40864e-07,-6.14108e-09,0.621914,0.000799003,-6.59287e-07,1.13151e-09,0.622712,0.000797688,-6.55893e-07,1.61507e-09,0.62351,0.000796381,-6.51048e-07,-7.59186e-09,0.624305,0.000795056,-6.73823e-07,2.87524e-08,0.6251,0.000793794,-5.87566e-07,-4.7813e-08,0.625893,0.000792476,-7.31005e-07,4.32901e-08,0.626685,0.000791144,-6.01135e-07,-6.13814e-09,0.627475,0.000789923,-6.19549e-07,-1.87376e-08,0.628264,0.000788628,-6.75762e-07,2.14837e-08,0.629052,0.000787341,-6.11311e-07,-7.59265e-09,0.629839,0.000786095,-6.34089e-07,8.88692e-09,0.630625,0.000784854,-6.07428e-07,-2.7955e-08,0.631409,0.000783555,-6.91293e-07,4.33285e-08,0.632192,0.000782302,-5.61307e-07,-2.61497e-08,0.632973,0.000781101,-6.39757e-07,1.6658e-09,0.633754,0.000779827,-6.34759e-07,1.94866e-08,0.634533,0.000778616,-5.76299e-07,-2.00076e-08,0.635311,0.000777403,-6.36322e-07,9.39091e-10,0.636088,0.000776133,-6.33505e-07,1.62512e-08,0.636863,0.000774915,-5.84751e-07,-6.33937e-09,0.637638,0.000773726,-6.03769e-07,9.10609e-09,0.638411,0.000772546,-5.76451e-07,-3.00849e-08,0.639183,0.000771303,-6.66706e-07,5.1629e-08,0.639953,0.000770125,-5.11819e-07,-5.7222e-08,0.640723,0.000768929,-6.83485e-07,5.80497e-08,0.641491,0.000767736,-5.09336e-07,-5.57674e-08,0.642259,0.000766551,-6.76638e-07,4.58105e-08,0.643024,0.000765335,-5.39206e-07,-8.26541e-09,0.643789,0.000764231,-5.64002e-07,-1.27488e-08,0.644553,0.000763065,-6.02249e-07,-3.44168e-10,0.645315,0.00076186,-6.03281e-07,1.41254e-08,0.646077,0.000760695,-5.60905e-07,3.44727e-09,0.646837,0.000759584,-5.50563e-07,-2.79144e-08,0.647596,0.000758399,-6.34307e-07,4.86057e-08,0.648354,0.000757276,-4.88489e-07,-4.72989e-08,0.64911,0.000756158,-6.30386e-07,2.13807e-08,0.649866,0.000754961,-5.66244e-07,2.13808e-08,0.65062,0.000753893,-5.02102e-07,-4.7299e-08,0.651374,0.000752746,-6.43999e-07,4.86059e-08,0.652126,0.000751604,-4.98181e-07,-2.79154e-08,0.652877,0.000750524,-5.81927e-07,3.45089e-09,0.653627,0.000749371,-5.71575e-07,1.41119e-08,0.654376,0.00074827,-5.29239e-07,-2.93748e-10,0.655123,0.00074721,-5.3012e-07,-1.29368e-08,0.65587,0.000746111,-5.68931e-07,-7.56355e-09,0.656616,0.000744951,-5.91621e-07,4.3191e-08,0.65736,0.000743897,-4.62048e-07,-4.59911e-08,0.658103,0.000742835,-6.00022e-07,2.15642e-08,0.658846,0.0007417,-5.35329e-07,1.93389e-08,0.659587,0.000740687,-4.77312e-07,-3.93152e-08,0.660327,0.000739615,-5.95258e-07,1.87126e-08,0.661066,0.00073848,-5.3912e-07,2.40695e-08,0.661804,0.000737474,-4.66912e-07,-5.53859e-08,0.662541,0.000736374,-6.33069e-07,7.82648e-08,0.663277,0.000735343,-3.98275e-07,-7.88593e-08,0.664012,0.00073431,-6.34853e-07,5.83585e-08,0.664745,0.000733215,-4.59777e-07,-3.53656e-08,0.665478,0.000732189,-5.65874e-07,2.34994e-08,0.66621,0.000731128,-4.95376e-07,9.72743e-10,0.66694,0.00073014,-4.92458e-07,-2.73903e-08,0.66767,0.000729073,-5.74629e-07,4.89839e-08,0.668398,0.000728071,-4.27677e-07,-4.93359e-08,0.669126,0.000727068,-5.75685e-07,2.91504e-08,0.669853,0.000726004,-4.88234e-07,-7.66109e-09,0.670578,0.000725004,-5.11217e-07,1.49392e-09,0.671303,0.000723986,-5.06735e-07,1.68533e-09,0.672026,0.000722978,-5.01679e-07,-8.23525e-09,0.672749,0.00072195,-5.26385e-07,3.12556e-08,0.67347,0.000720991,-4.32618e-07,-5.71825e-08,0.674191,0.000719954,-6.04166e-07,7.8265e-08,0.67491,0.00071898,-3.69371e-07,-7.70634e-08,0.675628,0.00071801,-6.00561e-07,5.11747e-08,0.676346,0.000716963,-4.47037e-07,-8.42615e-09,0.677062,0.000716044,-4.72315e-07,-1.747e-08,0.677778,0.000715046,-5.24725e-07,1.87015e-08,0.678493,0.000714053,-4.68621e-07,2.26856e-09,0.679206,0.000713123,-4.61815e-07,-2.77758e-08,0.679919,0.000712116,-5.45142e-07,4.92298e-08,0.68063,0.000711173,-3.97453e-07,-4.99339e-08,0.681341,0.000710228,-5.47255e-07,3.12967e-08,0.682051,0.000709228,-4.53365e-07,-1.56481e-08,0.68276,0.000708274,-5.00309e-07,3.12958e-08,0.683467,0.000707367,-4.06422e-07,-4.99303e-08,0.684174,0.000706405,-5.56213e-07,4.9216e-08,0.68488,0.00070544,-4.08565e-07,-2.77245e-08,0.685585,0.00070454,-4.91738e-07,2.07748e-09,0.686289,0.000703562,-4.85506e-07,1.94146e-08,0.686992,0.00070265,-4.27262e-07,-2.01314e-08,0.687695,0.000701735,-4.87656e-07,1.50616e-09,0.688396,0.000700764,-4.83137e-07,1.41067e-08,0.689096,0.00069984,-4.40817e-07,1.67168e-09,0.689795,0.000698963,-4.35802e-07,-2.07934e-08,0.690494,0.000698029,-4.98182e-07,2.18972e-08,0.691192,0.000697099,-4.32491e-07,-7.19092e-09,0.691888,0.000696212,-4.54064e-07,6.86642e-09,0.692584,0.000695325,-4.33464e-07,-2.02747e-08,0.693279,0.000694397,-4.94288e-07,1.46279e-08,0.693973,0.000693452,-4.50405e-07,2.13678e-08,0.694666,0.000692616,-3.86301e-07,-4.04945e-08,0.695358,0.000691721,-5.07785e-07,2.14009e-08,0.696049,0.00069077,-4.43582e-07,1.44955e-08,0.69674,0.000689926,-4.00096e-07,-1.97783e-08,0.697429,0.000689067,-4.5943e-07,5.01296e-09,0.698118,0.000688163,-4.44392e-07,-2.73521e-10,0.698805,0.000687273,-4.45212e-07,-3.91893e-09,0.699492,0.000686371,-4.56969e-07,1.59493e-08,0.700178,0.000685505,-4.09121e-07,-2.73351e-10,0.700863,0.000684686,-4.09941e-07,-1.4856e-08,0.701548,0.000683822,-4.54509e-07,9.25979e-11,0.702231,0.000682913,-4.54231e-07,1.44855e-08,0.702913,0.000682048,-4.10775e-07,1.56992e-09,0.703595,0.000681231,-4.06065e-07,-2.07652e-08,0.704276,0.000680357,-4.68361e-07,2.18864e-08,0.704956,0.000679486,-4.02701e-07,-7.17595e-09,0.705635,0.000678659,-4.24229e-07,6.81748e-09,0.706313,0.000677831,-4.03777e-07,-2.0094e-08,0.70699,0.000676963,-4.64059e-07,1.39538e-08,0.707667,0.000676077,-4.22197e-07,2.38835e-08,0.708343,0.000675304,-3.50547e-07,-4.98831e-08,0.709018,0.000674453,-5.00196e-07,5.64395e-08,0.709692,0.000673622,-3.30878e-07,-5.66657e-08,0.710365,0.00067279,-5.00875e-07,5.1014e-08,0.711037,0.000671942,-3.47833e-07,-2.81809e-08,0.711709,0.000671161,-4.32376e-07,2.10513e-09,0.712379,0.000670303,-4.2606e-07,1.97604e-08,0.713049,0.00066951,-3.66779e-07,-2.15422e-08,0.713718,0.000668712,-4.31406e-07,6.8038e-09,0.714387,0.000667869,-4.10994e-07,-5.67295e-09,0.715054,0.00066703,-4.28013e-07,1.5888e-08,0.715721,0.000666222,-3.80349e-07,1.72576e-09,0.716387,0.000665467,-3.75172e-07,-2.27911e-08,0.717052,0.000664648,-4.43545e-07,2.9834e-08,0.717716,0.00066385,-3.54043e-07,-3.69401e-08,0.718379,0.000663031,-4.64864e-07,5.83219e-08,0.719042,0.000662277,-2.89898e-07,-7.71382e-08,0.719704,0.000661465,-5.21313e-07,7.14171e-08,0.720365,0.000660637,-3.07061e-07,-2.97161e-08,0.721025,0.000659934,-3.96209e-07,-1.21575e-08,0.721685,0.000659105,-4.32682e-07,1.87412e-08,0.722343,0.000658296,-3.76458e-07,-3.2029e-09,0.723001,0.000657533,-3.86067e-07,-5.9296e-09,0.723659,0.000656743,-4.03856e-07,2.69213e-08,0.724315,0.000656016,-3.23092e-07,-4.21511e-08,0.724971,0.000655244,-4.49545e-07,2.24737e-08,0.725625,0.000654412,-3.82124e-07,1.18611e-08,0.726279,0.000653683,-3.46541e-07,-1.03132e-08,0.726933,0.000652959,-3.7748e-07,-3.02128e-08,0.727585,0.000652114,-4.68119e-07,7.15597e-08,0.728237,0.000651392,-2.5344e-07,-7.72119e-08,0.728888,0.000650654,-4.85075e-07,5.8474e-08,0.729538,0.000649859,-3.09654e-07,-3.74746e-08,0.730188,0.000649127,-4.22077e-07,3.18197e-08,0.730837,0.000648379,-3.26618e-07,-3.01997e-08,0.731485,0.000647635,-4.17217e-07,2.93747e-08,0.732132,0.000646888,-3.29093e-07,-2.76943e-08,0.732778,0.000646147,-4.12176e-07,2.17979e-08,0.733424,0.000645388,-3.46783e-07,1.07292e-10,0.734069,0.000644695,-3.46461e-07,-2.22271e-08,0.734713,0.000643935,-4.13142e-07,2.91963e-08,0.735357,0.000643197,-3.25553e-07,-3.49536e-08,0.736,0.000642441,-4.30414e-07,5.10133e-08,0.736642,0.000641733,-2.77374e-07,-4.98904e-08,0.737283,0.000641028,-4.27045e-07,2.93392e-08,0.737924,0.000640262,-3.39028e-07,-7.86156e-09,0.738564,0.000639561,-3.62612e-07,2.10703e-09,0.739203,0.000638842,-3.56291e-07,-5.6653e-10,0.739842,0.000638128,-3.57991e-07,1.59086e-10,0.740479,0.000637412,-3.57513e-07,-6.98321e-11,0.741116,0.000636697,-3.57723e-07,1.20214e-10,0.741753,0.000635982,-3.57362e-07,-4.10987e-10,0.742388,0.000635266,-3.58595e-07,1.5237e-09,0.743023,0.000634553,-3.54024e-07,-5.68376e-09,0.743657,0.000633828,-3.71075e-07,2.12113e-08,0.744291,0.00063315,-3.07441e-07,-1.95569e-08,0.744924,0.000632476,-3.66112e-07,-2.58816e-09,0.745556,0.000631736,-3.73877e-07,2.99096e-08,0.746187,0.000631078,-2.84148e-07,-5.74454e-08,0.746818,0.000630337,-4.56484e-07,8.06629e-08,0.747448,0.000629666,-2.14496e-07,-8.63922e-08,0.748077,0.000628978,-4.73672e-07,8.60918e-08,0.748706,0.000628289,-2.15397e-07,-7.91613e-08,0.749334,0.000627621,-4.5288e-07,5.17393e-08,0.749961,0.00062687,-2.97663e-07,-8.58662e-09,0.750588,0.000626249,-3.23422e-07,-1.73928e-08,0.751214,0.00062555,-3.75601e-07,1.85532e-08,0.751839,0.000624855,-3.19941e-07,2.78479e-09,0.752463,0.000624223,-3.11587e-07,-2.96923e-08,0.753087,0.000623511,-4.00664e-07,5.63799e-08,0.75371,0.000622879,-2.31524e-07,-7.66179e-08,0.754333,0.000622186,-4.61378e-07,7.12778e-08,0.754955,0.000621477,-2.47545e-07,-2.96794e-08,0.755576,0.000620893,-3.36583e-07,-1.21648e-08,0.756196,0.000620183,-3.73077e-07,1.87339e-08,0.756816,0.000619493,-3.16875e-07,-3.16622e-09,0.757435,0.00061885,-3.26374e-07,-6.0691e-09,0.758054,0.000618179,-3.44581e-07,2.74426e-08,0.758672,0.000617572,-2.62254e-07,-4.40968e-08,0.759289,0.000616915,-3.94544e-07,2.97352e-08,0.759906,0.000616215,-3.05338e-07,-1.52393e-08,0.760522,0.000615559,-3.51056e-07,3.12221e-08,0.761137,0.000614951,-2.5739e-07,-5.00443e-08,0.761751,0.000614286,-4.07523e-07,4.9746e-08,0.762365,0.00061362,-2.58285e-07,-2.97303e-08,0.762979,0.000613014,-3.47476e-07,9.57079e-09,0.763591,0.000612348,-3.18764e-07,-8.55287e-09,0.764203,0.000611685,-3.44422e-07,2.46407e-08,0.764815,0.00061107,-2.705e-07,-3.04053e-08,0.765426,0.000610437,-3.61716e-07,3.73759e-08,0.766036,0.000609826,-2.49589e-07,-5.94935e-08,0.766645,0.000609149,-4.28069e-07,8.13889e-08,0.767254,0.000608537,-1.83902e-07,-8.72483e-08,0.767862,0.000607907,-4.45647e-07,8.87901e-08,0.76847,0.000607282,-1.79277e-07,-8.90983e-08,0.769077,0.000606656,-4.46572e-07,8.87892e-08,0.769683,0.000606029,-1.80204e-07,-8.72446e-08,0.770289,0.000605407,-4.41938e-07,8.13752e-08,0.770894,0.000604768,-1.97812e-07,-5.94423e-08,0.771498,0.000604194,-3.76139e-07,3.71848e-08,0.772102,0.000603553,-2.64585e-07,-2.96922e-08,0.772705,0.000602935,-3.53661e-07,2.19793e-08,0.773308,0.000602293,-2.87723e-07,1.37955e-09,0.77391,0.000601722,-2.83585e-07,-2.74976e-08,0.774512,0.000601072,-3.66077e-07,4.9006e-08,0.775112,0.000600487,-2.19059e-07,-4.93171e-08,0.775712,0.000599901,-3.67011e-07,2.90531e-08,0.776312,0.000599254,-2.79851e-07,-7.29081e-09,0.776911,0.000598673,-3.01724e-07,1.10077e-10,0.777509,0.00059807,-3.01393e-07,6.85053e-09,0.778107,0.000597487,-2.80842e-07,-2.75123e-08,0.778704,0.000596843,-3.63379e-07,4.35939e-08,0.779301,0.000596247,-2.32597e-07,-2.7654e-08,0.779897,0.000595699,-3.15559e-07,7.41741e-09,0.780492,0.00059509,-2.93307e-07,-2.01562e-09,0.781087,0.000594497,-2.99354e-07,6.45059e-10,0.781681,0.000593901,-2.97418e-07,-5.64635e-10,0.782275,0.000593304,-2.99112e-07,1.61347e-09,0.782868,0.000592711,-2.94272e-07,-5.88926e-09,0.78346,0.000592105,-3.1194e-07,2.19436e-08,0.784052,0.000591546,-2.46109e-07,-2.22805e-08,0.784643,0.000590987,-3.1295e-07,7.57368e-09,0.785234,0.000590384,-2.90229e-07,-8.01428e-09,0.785824,0.00058978,-3.14272e-07,2.44834e-08,0.786414,0.000589225,-2.40822e-07,-3.03148e-08,0.787003,0.000588652,-3.31766e-07,3.7171e-08,0.787591,0.0005881,-2.20253e-07,-5.87646e-08,0.788179,0.000587483,-3.96547e-07,7.86782e-08,0.788766,0.000586926,-1.60512e-07,-7.71342e-08,0.789353,0.000586374,-3.91915e-07,5.10444e-08,0.789939,0.000585743,-2.38782e-07,-7.83422e-09,0.790524,0.000585242,-2.62284e-07,-1.97076e-08,0.791109,0.000584658,-3.21407e-07,2.70598e-08,0.791693,0.000584097,-2.40228e-07,-2.89269e-08,0.792277,0.000583529,-3.27008e-07,2.90431e-08,0.792861,0.000582963,-2.39879e-07,-2.76409e-08,0.793443,0.0005824,-3.22802e-07,2.1916e-08,0.794025,0.00058182,-2.57054e-07,-4.18368e-10,0.794607,0.000581305,-2.58309e-07,-2.02425e-08,0.795188,0.000580727,-3.19036e-07,2.17838e-08,0.795768,0.000580155,-2.53685e-07,-7.28814e-09,0.796348,0.000579625,-2.75549e-07,7.36871e-09,0.796928,0.000579096,-2.53443e-07,-2.21867e-08,0.797506,0.000578523,-3.20003e-07,2.17736e-08,0.798085,0.000577948,-2.54683e-07,-5.30296e-09,0.798662,0.000577423,-2.70592e-07,-5.61698e-10,0.799239,0.00057688,-2.72277e-07,7.54977e-09,0.799816,0.000576358,-2.49627e-07,-2.96374e-08,0.800392,0.00057577,-3.38539e-07,5.1395e-08,0.800968,0.000575247,-1.84354e-07,-5.67335e-08,0.801543,0.000574708,-3.54555e-07,5.63297e-08,0.802117,0.000574168,-1.85566e-07,-4.93759e-08,0.802691,0.000573649,-3.33693e-07,2.19646e-08,0.803264,0.000573047,-2.678e-07,2.1122e-08,0.803837,0.000572575,-2.04433e-07,-4.68482e-08,0.804409,0.000572026,-3.44978e-07,4.70613e-08,0.804981,0.000571477,-2.03794e-07,-2.21877e-08,0.805552,0.000571003,-2.70357e-07,-1.79153e-08,0.806123,0.000570408,-3.24103e-07,3.42443e-08,0.806693,0.000569863,-2.2137e-07,1.47556e-10,0.807263,0.000569421,-2.20928e-07,-3.48345e-08,0.807832,0.000568874,-3.25431e-07,1.99812e-08,0.808401,0.000568283,-2.65487e-07,1.45143e-08,0.808969,0.000567796,-2.21945e-07,-1.84338e-08,0.809536,0.000567297,-2.77246e-07,-3.83608e-10,0.810103,0.000566741,-2.78397e-07,1.99683e-08,0.81067,0.000566244,-2.18492e-07,-1.98848e-08,0.811236,0.000565747,-2.78146e-07,-3.38976e-11,0.811801,0.000565191,-2.78248e-07,2.00204e-08,0.812366,0.000564695,-2.18187e-07,-2.04429e-08,0.812931,0.000564197,-2.79516e-07,2.1467e-09,0.813495,0.000563644,-2.73076e-07,1.18561e-08,0.814058,0.000563134,-2.37507e-07,1.00334e-08,0.814621,0.000562689,-2.07407e-07,-5.19898e-08,0.815183,0.000562118,-3.63376e-07,7.87163e-08,0.815745,0.000561627,-1.27227e-07,-8.40616e-08,0.816306,0.000561121,-3.79412e-07,7.87163e-08,0.816867,0.000560598,-1.43263e-07,-5.19898e-08,0.817428,0.000560156,-2.99233e-07,1.00335e-08,0.817988,0.000559587,-2.69132e-07,1.18559e-08,0.818547,0.000559085,-2.33564e-07,2.14764e-09,0.819106,0.000558624,-2.27122e-07,-2.04464e-08,0.819664,0.000558108,-2.88461e-07,2.00334e-08,0.820222,0.000557591,-2.28361e-07,-8.24277e-11,0.820779,0.000557135,-2.28608e-07,-1.97037e-08,0.821336,0.000556618,-2.87719e-07,1.92925e-08,0.821893,0.000556101,-2.29841e-07,2.13831e-09,0.822448,0.000555647,-2.23427e-07,-2.78458e-08,0.823004,0.000555117,-3.06964e-07,4.96402e-08,0.823559,0.000554652,-1.58043e-07,-5.15058e-08,0.824113,0.000554181,-3.12561e-07,3.71737e-08,0.824667,0.000553668,-2.0104e-07,-3.75844e-08,0.82522,0.000553153,-3.13793e-07,5.35592e-08,0.825773,0.000552686,-1.53115e-07,-5.74431e-08,0.826326,0.000552207,-3.25444e-07,5.7004e-08,0.826878,0.000551728,-1.54433e-07,-5.13635e-08,0.827429,0.000551265,-3.08523e-07,2.92406e-08,0.82798,0.000550735,-2.20801e-07,-5.99424e-09,0.828531,0.000550276,-2.38784e-07,-5.26363e-09,0.829081,0.000549782,-2.54575e-07,2.70488e-08,0.82963,0.000549354,-1.73429e-07,-4.33268e-08,0.83018,0.000548878,-3.03409e-07,2.7049e-08,0.830728,0.000548352,-2.22262e-07,-5.26461e-09,0.831276,0.000547892,-2.38056e-07,-5.99057e-09,0.831824,0.000547397,-2.56027e-07,2.92269e-08,0.832371,0.000546973,-1.68347e-07,-5.13125e-08,0.832918,0.000546482,-3.22284e-07,5.68139e-08,0.833464,0.000546008,-1.51843e-07,-5.67336e-08,0.83401,0.000545534,-3.22043e-07,5.09113e-08,0.834555,0.000545043,-1.6931e-07,-2.77022e-08,0.8351,0.000544621,-2.52416e-07,2.92924e-10,0.835644,0.000544117,-2.51537e-07,2.65305e-08,0.836188,0.000543694,-1.71946e-07,-4.68105e-08,0.836732,0.00054321,-3.12377e-07,4.15021e-08,0.837275,0.000542709,-1.87871e-07,1.13355e-11,0.837817,0.000542334,-1.87837e-07,-4.15474e-08,0.838359,0.000541833,-3.12479e-07,4.69691e-08,0.838901,0.000541349,-1.71572e-07,-2.71196e-08,0.839442,0.000540925,-2.52931e-07,1.90462e-09,0.839983,0.000540425,-2.47217e-07,1.95011e-08,0.840523,0.000539989,-1.88713e-07,-2.03045e-08,0.841063,0.00053955,-2.49627e-07,2.11216e-09,0.841602,0.000539057,-2.4329e-07,1.18558e-08,0.842141,0.000538606,-2.07723e-07,1.00691e-08,0.842679,0.000538221,-1.77516e-07,-5.21324e-08,0.843217,0.00053771,-3.33913e-07,7.92513e-08,0.843755,0.00053728,-9.6159e-08,-8.60587e-08,0.844292,0.000536829,-3.54335e-07,8.61696e-08,0.844828,0.000536379,-9.58263e-08,-7.98057e-08,0.845364,0.000535948,-3.35243e-07,5.42394e-08,0.8459,0.00053544,-1.72525e-07,-1.79426e-08,0.846435,0.000535041,-2.26353e-07,1.75308e-08,0.84697,0.000534641,-1.73761e-07,-5.21806e-08,0.847505,0.000534137,-3.30302e-07,7.19824e-08,0.848038,0.000533692,-1.14355e-07,-5.69349e-08,0.848572,0.000533293,-2.8516e-07,3.65479e-08,0.849105,0.000532832,-1.75516e-07,-2.96519e-08,0.849638,0.000532392,-2.64472e-07,2.2455e-08,0.85017,0.000531931,-1.97107e-07,-5.63451e-10,0.850702,0.000531535,-1.98797e-07,-2.02011e-08,0.851233,0.000531077,-2.59401e-07,2.17634e-08,0.851764,0.000530623,-1.94111e-07,-7.24794e-09,0.852294,0.000530213,-2.15854e-07,7.22832e-09,0.852824,0.000529803,-1.94169e-07,-2.16653e-08,0.853354,0.00052935,-2.59165e-07,1.98283e-08,0.853883,0.000528891,-1.9968e-07,1.95678e-09,0.854412,0.000528497,-1.9381e-07,-2.76554e-08,0.85494,0.000528027,-2.76776e-07,4.90603e-08,0.855468,0.00052762,-1.29596e-07,-4.93764e-08,0.855995,0.000527213,-2.77725e-07,2.92361e-08,0.856522,0.000526745,-1.90016e-07,-7.96341e-09,0.857049,0.000526341,-2.13907e-07,2.61752e-09,0.857575,0.000525922,-2.06054e-07,-2.50665e-09,0.8581,0.000525502,-2.13574e-07,7.40906e-09,0.858626,0.000525097,-1.91347e-07,-2.71296e-08,0.859151,0.000524633,-2.72736e-07,4.15048e-08,0.859675,0.000524212,-1.48221e-07,-1.96802e-08,0.860199,0.000523856,-2.07262e-07,-2.23886e-08,0.860723,0.000523375,-2.74428e-07,4.96299e-08,0.861246,0.000522975,-1.25538e-07,-5.69216e-08,0.861769,0.000522553,-2.96303e-07,5.88473e-08,0.862291,0.000522137,-1.19761e-07,-5.92584e-08,0.862813,0.00052172,-2.97536e-07,5.8977e-08,0.863334,0.000521301,-1.20605e-07,-5.74403e-08,0.863855,0.000520888,-2.92926e-07,5.15751e-08,0.864376,0.000520457,-1.38201e-07,-2.96506e-08,0.864896,0.000520091,-2.27153e-07,7.42277e-09,0.865416,0.000519659,-2.04885e-07,-4.05057e-11,0.865936,0.00051925,-2.05006e-07,-7.26074e-09,0.866455,0.000518818,-2.26788e-07,2.90835e-08,0.866973,0.000518451,-1.39538e-07,-4.94686e-08,0.867492,0.000518024,-2.87944e-07,4.95814e-08,0.868009,0.000517597,-1.39199e-07,-2.96479e-08,0.868527,0.000517229,-2.28143e-07,9.40539e-09,0.869044,0.000516801,-1.99927e-07,-7.9737e-09,0.86956,0.000516378,-2.23848e-07,2.24894e-08,0.870077,0.000515997,-1.5638e-07,-2.23793e-08,0.870592,0.000515617,-2.23517e-07,7.42302e-09,0.871108,0.000515193,-2.01248e-07,-7.31283e-09,0.871623,0.000514768,-2.23187e-07,2.18283e-08,0.872137,0.000514387,-1.57702e-07,-2.03959e-08,0.872652,0.000514011,-2.1889e-07,1.50711e-10,0.873165,0.000513573,-2.18437e-07,1.97931e-08,0.873679,0.000513196,-1.59058e-07,-1.97183e-08,0.874192,0.000512819,-2.18213e-07,-5.24324e-10,0.874704,0.000512381,-2.19786e-07,2.18156e-08,0.875217,0.000512007,-1.54339e-07,-2.71336e-08,0.875728,0.000511616,-2.3574e-07,2.71141e-08,0.87624,0.000511226,-1.54398e-07,-2.17182e-08,0.876751,0.000510852,-2.19552e-07,1.54131e-10,0.877262,0.000510414,-2.1909e-07,2.11017e-08,0.877772,0.000510039,-1.55785e-07,-2.49562e-08,0.878282,0.000509652,-2.30654e-07,1.91183e-08,0.878791,0.000509248,-1.73299e-07,8.08751e-09,0.8793,0.000508926,-1.49036e-07,-5.14684e-08,0.879809,0.000508474,-3.03441e-07,7.85766e-08,0.880317,0.000508103,-6.77112e-08,-8.40242e-08,0.880825,0.000507715,-3.19784e-07,7.87063e-08,0.881333,0.000507312,-8.36649e-08,-5.19871e-08,0.88184,0.000506988,-2.39626e-07,1.00327e-08,0.882346,0.000506539,-2.09528e-07,1.18562e-08,0.882853,0.000506156,-1.73959e-07,2.14703e-09,0.883359,0.000505814,-1.67518e-07,-2.04444e-08,0.883864,0.000505418,-2.28851e-07,2.00258e-08,0.88437,0.00050502,-1.68774e-07,-5.42855e-11,0.884874,0.000504682,-1.68937e-07,-1.98087e-08,0.885379,0.000504285,-2.28363e-07,1.96842e-08,0.885883,0.000503887,-1.6931e-07,6.76342e-10,0.886387,0.000503551,-1.67281e-07,-2.23896e-08,0.88689,0.000503149,-2.3445e-07,2.92774e-08,0.887393,0.000502768,-1.46618e-07,-3.51152e-08,0.887896,0.00050237,-2.51963e-07,5.15787e-08,0.888398,0.00050202,-9.72271e-08,-5.19903e-08,0.8889,0.00050167,-2.53198e-07,3.71732e-08,0.889401,0.000501275,-1.41678e-07,-3.70978e-08,0.889902,0.00050088,-2.52972e-07,5.16132e-08,0.890403,0.000500529,-9.81321e-08,-5.01459e-08,0.890903,0.000500183,-2.4857e-07,2.9761e-08,0.891403,0.000499775,-1.59287e-07,-9.29351e-09,0.891903,0.000499428,-1.87167e-07,7.41301e-09,0.892402,0.000499076,-1.64928e-07,-2.03585e-08,0.892901,0.000498685,-2.26004e-07,1.44165e-08,0.893399,0.000498276,-1.82754e-07,2.22974e-08,0.893898,0.000497978,-1.15862e-07,-4.40013e-08,0.894395,0.000497614,-2.47866e-07,3.44985e-08,0.894893,0.000497222,-1.44371e-07,-3.43882e-08,0.89539,0.00049683,-2.47535e-07,4.34497e-08,0.895886,0.000496465,-1.17186e-07,-2.02012e-08,0.896383,0.00049617,-1.7779e-07,-2.22497e-08,0.896879,0.000495748,-2.44539e-07,4.95952e-08,0.897374,0.000495408,-9.57532e-08,-5.69217e-08,0.89787,0.000495045,-2.66518e-07,5.88823e-08,0.898364,0.000494689,-8.98713e-08,-5.93983e-08,0.898859,0.000494331,-2.68066e-07,5.95017e-08,0.899353,0.000493973,-8.95613e-08,-5.9399e-08,0.899847,0.000493616,-2.67758e-07,5.8885e-08,0.90034,0.000493257,-9.11033e-08,-5.69317e-08,0.900833,0.000492904,-2.61898e-07,4.96326e-08,0.901326,0.000492529,-1.13001e-07,-2.23893e-08,0.901819,0.000492236,-1.80169e-07,-1.968e-08,0.902311,0.000491817,-2.39209e-07,4.15047e-08,0.902802,0.000491463,-1.14694e-07,-2.71296e-08,0.903293,0.000491152,-1.96083e-07,7.409e-09,0.903784,0.000490782,-1.73856e-07,-2.50645e-09,0.904275,0.000490427,-1.81376e-07,2.61679e-09,0.904765,0.000490072,-1.73525e-07,-7.96072e-09,0.905255,0.000489701,-1.97407e-07,2.92261e-08,0.905745,0.000489394,-1.09729e-07,-4.93389e-08,0.906234,0.000489027,-2.57746e-07,4.89204e-08,0.906723,0.000488658,-1.10985e-07,-2.71333e-08,0.907211,0.000488354,-1.92385e-07,8.30861e-12,0.907699,0.00048797,-1.9236e-07,2.71001e-08,0.908187,0.000487666,-1.1106e-07,-4.88041e-08,0.908675,0.000487298,-2.57472e-07,4.89069e-08,0.909162,0.000486929,-1.10751e-07,-2.76143e-08,0.909649,0.000486625,-1.93594e-07,1.9457e-09,0.910135,0.000486244,-1.87757e-07,1.98315e-08,0.910621,0.000485928,-1.28262e-07,-2.16671e-08,0.911107,0.000485606,-1.93264e-07,7.23216e-09,0.911592,0.000485241,-1.71567e-07,-7.26152e-09,0.912077,0.000484877,-1.93352e-07,2.18139e-08,0.912562,0.000484555,-1.2791e-07,-2.03895e-08,0.913047,0.000484238,-1.89078e-07,1.39494e-10,0.913531,0.000483861,-1.8866e-07,1.98315e-08,0.914014,0.000483543,-1.29165e-07,-1.98609e-08,0.914498,0.000483225,-1.88748e-07,7.39912e-12,0.914981,0.000482847,-1.88726e-07,1.98313e-08,0.915463,0.000482529,-1.29232e-07,-1.9728e-08,0.915946,0.000482212,-1.88416e-07,-5.24035e-10,0.916428,0.000481833,-1.89988e-07,2.18241e-08,0.916909,0.000481519,-1.24516e-07,-2.71679e-08,0.917391,0.000481188,-2.06019e-07,2.72427e-08,0.917872,0.000480858,-1.24291e-07,-2.21985e-08,0.918353,0.000480543,-1.90886e-07,1.94644e-09,0.918833,0.000480167,-1.85047e-07,1.44127e-08,0.919313,0.00047984,-1.41809e-07,7.39438e-12,0.919793,0.000479556,-1.41787e-07,-1.44423e-08,0.920272,0.000479229,-1.85114e-07,-1.84291e-09,0.920751,0.000478854,-1.90642e-07,2.18139e-08,0.92123,0.000478538,-1.25201e-07,-2.58081e-08,0.921708,0.00047821,-2.02625e-07,2.18139e-08,0.922186,0.00047787,-1.37183e-07,-1.84291e-09,0.922664,0.00047759,-1.42712e-07,-1.44423e-08,0.923141,0.000477262,-1.86039e-07,7.34701e-12,0.923618,0.00047689,-1.86017e-07,1.44129e-08,0.924095,0.000476561,-1.42778e-07,1.94572e-09,0.924572,0.000476281,-1.36941e-07,-2.21958e-08,0.925048,0.000475941,-2.03528e-07,2.72327e-08,0.925523,0.000475615,-1.2183e-07,-2.71304e-08,0.925999,0.00047529,-2.03221e-07,2.16843e-08,0.926474,0.000474949,-1.38168e-07,-2.16005e-12,0.926949,0.000474672,-1.38175e-07,-2.16756e-08,0.927423,0.000474331,-2.03202e-07,2.71001e-08,0.927897,0.000474006,-1.21902e-07,-2.71201e-08,0.928371,0.000473681,-2.03262e-07,2.17757e-08,0.928845,0.00047334,-1.37935e-07,-3.78028e-10,0.929318,0.000473063,-1.39069e-07,-2.02636e-08,0.929791,0.000472724,-1.9986e-07,2.18276e-08,0.930263,0.000472389,-1.34377e-07,-7.44231e-09,0.930736,0.000472098,-1.56704e-07,7.94165e-09,0.931208,0.000471809,-1.32879e-07,-2.43243e-08,0.931679,0.00047147,-2.05851e-07,2.97508e-08,0.932151,0.000471148,-1.16599e-07,-3.50742e-08,0.932622,0.000470809,-2.21822e-07,5.09414e-08,0.933092,0.000470518,-6.89976e-08,-4.94821e-08,0.933563,0.000470232,-2.17444e-07,2.77775e-08,0.934033,0.00046988,-1.34111e-07,-2.02351e-09,0.934502,0.000469606,-1.40182e-07,-1.96835e-08,0.934972,0.000469267,-1.99232e-07,2.11529e-08,0.935441,0.000468932,-1.35774e-07,-5.32332e-09,0.93591,0.000468644,-1.51743e-07,1.40413e-10,0.936378,0.000468341,-1.51322e-07,4.76166e-09,0.936846,0.000468053,-1.37037e-07,-1.9187e-08,0.937314,0.000467721,-1.94598e-07,1.23819e-08,0.937782,0.000467369,-1.57453e-07,2.92642e-08,0.938249,0.000467142,-6.96601e-08,-6.98342e-08,0.938716,0.000466793,-2.79163e-07,7.12586e-08,0.939183,0.000466449,-6.53869e-08,-3.63863e-08,0.939649,0.000466209,-1.74546e-07,1.46818e-08,0.940115,0.000465904,-1.305e-07,-2.2341e-08,0.940581,0.000465576,-1.97523e-07,1.50774e-08,0.941046,0.000465226,-1.52291e-07,2.16359e-08,0.941511,0.000464986,-8.73832e-08,-4.20162e-08,0.941976,0.000464685,-2.13432e-07,2.72198e-08,0.942441,0.00046434,-1.31773e-07,-7.2581e-09,0.942905,0.000464055,-1.53547e-07,1.81263e-09,0.943369,0.000463753,-1.48109e-07,7.58386e-12,0.943832,0.000463457,-1.48086e-07,-1.84298e-09,0.944296,0.000463155,-1.53615e-07,7.36433e-09,0.944759,0.00046287,-1.31522e-07,-2.76143e-08,0.945221,0.000462524,-2.14365e-07,4.34883e-08,0.945684,0.000462226,-8.39003e-08,-2.71297e-08,0.946146,0.000461977,-1.65289e-07,5.42595e-09,0.946608,0.000461662,-1.49012e-07,5.42593e-09,0.947069,0.000461381,-1.32734e-07,-2.71297e-08,0.94753,0.000461034,-2.14123e-07,4.34881e-08,0.947991,0.000460736,-8.36585e-08,-2.76134e-08,0.948452,0.000460486,-1.66499e-07,7.36083e-09,0.948912,0.000460175,-1.44416e-07,-1.82993e-09,0.949372,0.000459881,-1.49906e-07,-4.11073e-11,0.949832,0.000459581,-1.50029e-07,1.99434e-09,0.950291,0.000459287,-1.44046e-07,-7.93627e-09,0.950751,0.000458975,-1.67855e-07,2.97507e-08,0.951209,0.000458728,-7.86029e-08,-5.1462e-08,0.951668,0.000458417,-2.32989e-07,5.6888e-08,0.952126,0.000458121,-6.2325e-08,-5.68806e-08,0.952584,0.000457826,-2.32967e-07,5.14251e-08,0.953042,0.000457514,-7.86914e-08,-2.96107e-08,0.953499,0.000457268,-1.67523e-07,7.41296e-09,0.953956,0.000456955,-1.45285e-07,-4.11262e-11,0.954413,0.000456665,-1.45408e-07,-7.24847e-09,0.95487,0.000456352,-1.67153e-07,2.9035e-08,0.955326,0.000456105,-8.00484e-08,-4.92869e-08,0.955782,0.000455797,-2.27909e-07,4.89032e-08,0.956238,0.000455488,-8.11994e-08,-2.71166e-08,0.956693,0.000455244,-1.62549e-07,-4.13678e-11,0.957148,0.000454919,-1.62673e-07,2.72821e-08,0.957603,0.000454675,-8.0827e-08,-4.94824e-08,0.958057,0.000454365,-2.29274e-07,5.14382e-08,0.958512,0.000454061,-7.49597e-08,-3.7061e-08,0.958965,0.0004538,-1.86143e-07,3.72013e-08,0.959419,0.000453539,-7.45389e-08,-5.21396e-08,0.959873,0.000453234,-2.30958e-07,5.21476e-08,0.960326,0.000452928,-7.45146e-08,-3.72416e-08,0.960778,0.000452667,-1.8624e-07,3.72143e-08,0.961231,0.000452407,-7.45967e-08,-5.20109e-08,0.961683,0.000452101,-2.30629e-07,5.16199e-08,0.962135,0.000451795,-7.57696e-08,-3.52595e-08,0.962587,0.000451538,-1.81548e-07,2.98133e-08,0.963038,0.000451264,-9.2108e-08,-2.43892e-08,0.963489,0.000451007,-1.65276e-07,8.13892e-09,0.96394,0.000450701,-1.40859e-07,-8.16647e-09,0.964391,0.000450394,-1.65358e-07,2.45269e-08,0.964841,0.000450137,-9.17775e-08,-3.03367e-08,0.965291,0.000449863,-1.82787e-07,3.7215e-08,0.965741,0.000449609,-7.11424e-08,-5.89188e-08,0.96619,0.00044929,-2.47899e-07,7.92509e-08,0.966639,0.000449032,-1.01462e-08,-7.92707e-08,0.967088,0.000448773,-2.47958e-07,5.90181e-08,0.967537,0.000448455,-7.0904e-08,-3.75925e-08,0.967985,0.0004482,-1.83681e-07,3.17471e-08,0.968433,0.000447928,-8.84401e-08,-2.97913e-08,0.968881,0.000447662,-1.77814e-07,2.78133e-08,0.969329,0.000447389,-9.4374e-08,-2.18572e-08,0.969776,0.000447135,-1.59946e-07,1.10134e-11,0.970223,0.000446815,-1.59913e-07,2.18132e-08,0.97067,0.000446561,-9.44732e-08,-2.76591e-08,0.971116,0.000446289,-1.7745e-07,2.92185e-08,0.971562,0.000446022,-8.97948e-08,-2.96104e-08,0.972008,0.000445753,-1.78626e-07,2.96185e-08,0.972454,0.000445485,-8.97706e-08,-2.92588e-08,0.972899,0.000445218,-1.77547e-07,2.78123e-08,0.973344,0.000444946,-9.41103e-08,-2.23856e-08,0.973789,0.000444691,-1.61267e-07,2.12559e-09,0.974233,0.000444374,-1.5489e-07,1.38833e-08,0.974678,0.000444106,-1.13241e-07,1.94591e-09,0.975122,0.000443886,-1.07403e-07,-2.16669e-08,0.975565,0.000443606,-1.72404e-07,2.5117e-08,0.976009,0.000443336,-9.70526e-08,-1.91963e-08,0.976452,0.000443085,-1.54642e-07,-7.93627e-09,0.976895,0.000442752,-1.7845e-07,5.09414e-08,0.977338,0.000442548,-2.56262e-08,-7.66201e-08,0.97778,0.000442266,-2.55486e-07,7.67249e-08,0.978222,0.000441986,-2.53118e-08,-5.14655e-08,0.978664,0.000441781,-1.79708e-07,9.92773e-09,0.979106,0.000441451,-1.49925e-07,1.17546e-08,0.979547,0.000441186,-1.14661e-07,2.65868e-09,0.979988,0.000440965,-1.06685e-07,-2.23893e-08,0.980429,0.000440684,-1.73853e-07,2.72939e-08,0.980869,0.000440419,-9.19716e-08,-2.71816e-08,0.98131,0.000440153,-1.73516e-07,2.18278e-08,0.98175,0.000439872,-1.08033e-07,-5.24833e-10,0.982189,0.000439654,-1.09607e-07,-1.97284e-08,0.982629,0.000439376,-1.68793e-07,1.98339e-08,0.983068,0.000439097,-1.09291e-07,-2.62901e-12,0.983507,0.000438879,-1.09299e-07,-1.98234e-08,0.983946,0.000438601,-1.68769e-07,1.96916e-08,0.984384,0.000438322,-1.09694e-07,6.6157e-10,0.984823,0.000438105,-1.0771e-07,-2.23379e-08,0.985261,0.000437823,-1.74723e-07,2.90855e-08,0.985698,0.00043756,-8.74669e-08,-3.43992e-08,0.986136,0.000437282,-1.90665e-07,4.89068e-08,0.986573,0.000437048,-4.39442e-08,-4.20188e-08,0.98701,0.000436834,-1.7e-07,-4.11073e-11,0.987446,0.000436494,-1.70124e-07,4.21832e-08,0.987883,0.00043628,-4.35742e-08,-4.94824e-08,0.988319,0.000436044,-1.92021e-07,3.6537e-08,0.988755,0.00043577,-8.24102e-08,-3.70611e-08,0.989191,0.000435494,-1.93593e-07,5.21026e-08,0.989626,0.000435263,-3.72855e-08,-5.21402e-08,0.990061,0.000435032,-1.93706e-07,3.7249e-08,0.990496,0.000434756,-8.19592e-08,-3.72512e-08,0.990931,0.000434481,-1.93713e-07,5.21511e-08,0.991365,0.00043425,-3.72595e-08,-5.21439e-08,0.991799,0.000434019,-1.93691e-07,3.72152e-08,0.992233,0.000433743,-8.20456e-08,-3.71123e-08,0.992667,0.000433468,-1.93382e-07,5.16292e-08,0.9931,0.000433236,-3.84947e-08,-5.01953e-08,0.993533,0.000433008,-1.89081e-07,2.99427e-08,0.993966,0.00043272,-9.92525e-08,-9.9708e-09,0.994399,0.000432491,-1.29165e-07,9.94051e-09,0.994831,0.000432263,-9.93434e-08,-2.97912e-08,0.995263,0.000431975,-1.88717e-07,4.96198e-08,0.995695,0.000431746,-3.98578e-08,-4.94785e-08,0.996127,0.000431518,-1.88293e-07,2.9085e-08,0.996558,0.000431229,-1.01038e-07,-7.25675e-09,0.996989,0.000431005,-1.22809e-07,-5.79945e-11,0.99742,0.000430759,-1.22983e-07,7.48873e-09,0.997851,0.000430536,-1.00516e-07,-2.98969e-08,0.998281,0.000430245,-1.90207e-07,5.24942e-08,0.998711,0.000430022,-3.27246e-08,-6.08706e-08,0.999141,0.000429774,-2.15336e-07,7.17788e-08,0.999571,0.000429392,0.,0.}; + + template + __device__ __forceinline__ void Lab2RGBConvert_f(const T& src, D& dst) + { + const float lThresh = 0.008856f * 903.3f; + const float fThresh = 7.787f * 0.008856f + 16.0f / 116.0f; + + float Y, fy; + + if (src.x <= lThresh) + { + Y = src.x / 903.3f; + fy = 7.787f * Y + 16.0f / 116.0f; + } + else + { + fy = (src.x + 16.0f) / 116.0f; + Y = fy * fy * fy; + } + + float X = src.y / 500.0f + fy; + float Z = fy - src.z / 200.0f; + + if (X <= fThresh) + X = (X - 16.0f / 116.0f) / 7.787f; + else + X = X * X * X; + + if (Z <= fThresh) + Z = (Z - 16.0f / 116.0f) / 7.787f; + else + Z = Z * Z * Z; + + float B = 0.052891f * X - 0.204043f * Y + 1.151152f * Z; + float G = -0.921235f * X + 1.875991f * Y + 0.045244f * Z; + float R = 3.079933f * X - 1.537150f * Y - 0.542782f * Z; + + if (srgb) + { + B = splineInterpolate(B * GAMMA_TAB_SIZE, c_sRGBInvGammaTab, GAMMA_TAB_SIZE); + G = splineInterpolate(G * GAMMA_TAB_SIZE, c_sRGBInvGammaTab, GAMMA_TAB_SIZE); + R = splineInterpolate(R * GAMMA_TAB_SIZE, c_sRGBInvGammaTab, GAMMA_TAB_SIZE); + } + + dst.x = blueIdx == 0 ? B : R; + dst.y = G; + dst.z = blueIdx == 0 ? R : B; + setAlpha(dst, ColorChannel::max()); + } + + template + __device__ __forceinline__ void Lab2RGBConvert_b(const T& src, D& dst) + { + float3 srcf, dstf; + + srcf.x = src.x * (100.f / 255.f); + srcf.y = src.y - 128; + srcf.z = src.z - 128; + + Lab2RGBConvert_f(srcf, dstf); + + dst.x = saturate_cast(dstf.x * 255.f); + dst.y = saturate_cast(dstf.y * 255.f); + dst.z = saturate_cast(dstf.z * 255.f); + setAlpha(dst, ColorChannel::max()); + } + + template struct Lab2RGB; + template + struct Lab2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + Lab2RGBConvert_b(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ Lab2RGB() {} + __host__ __device__ __forceinline__ Lab2RGB(const Lab2RGB&) {} + }; + template + struct Lab2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + Lab2RGBConvert_f(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ Lab2RGB() {} + __host__ __device__ __forceinline__ Lab2RGB(const Lab2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_Lab2RGB_TRAITS(name, scn, dcn, srgb, blueIdx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::Lab2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + +///////////////////////////////////// RGB <-> Luv ///////////////////////////////////// + + namespace color_detail + { + __constant__ float c_LabCbrtTab[] = {0.137931,0.0114066,0.,1.18859e-07,0.149338,0.011407,3.56578e-07,-5.79396e-07,0.160745,0.0114059,-1.38161e-06,2.16892e-06,0.172151,0.0114097,5.12516e-06,-8.0814e-06,0.183558,0.0113957,-1.9119e-05,3.01567e-05,0.194965,0.0114479,7.13509e-05,-0.000112545,0.206371,0.011253,-0.000266285,-0.000106493,0.217252,0.0104009,-0.000585765,7.32149e-05,0.22714,0.00944906,-0.00036612,1.21917e-05,0.236235,0.0087534,-0.000329545,2.01753e-05,0.244679,0.00815483,-0.000269019,1.24435e-05,0.252577,0.00765412,-0.000231689,1.05618e-05,0.26001,0.00722243,-0.000200003,8.26662e-06,0.267041,0.00684723,-0.000175203,6.76746e-06,0.27372,0.00651712,-0.000154901,5.61192e-06,0.280088,0.00622416,-0.000138065,4.67009e-06,0.286179,0.00596204,-0.000124055,3.99012e-06,0.292021,0.0057259,-0.000112085,3.36032e-06,0.297638,0.00551181,-0.000102004,2.95338e-06,0.30305,0.00531666,-9.31435e-05,2.52875e-06,0.308277,0.00513796,-8.55572e-05,2.22022e-06,0.313331,0.00497351,-7.88966e-05,1.97163e-06,0.318228,0.00482163,-7.29817e-05,1.7248e-06,0.322978,0.00468084,-6.78073e-05,1.55998e-06,0.327593,0.0045499,-6.31274e-05,1.36343e-06,0.332081,0.00442774,-5.90371e-05,1.27136e-06,0.336451,0.00431348,-5.5223e-05,1.09111e-06,0.34071,0.00420631,-5.19496e-05,1.0399e-06,0.344866,0.00410553,-4.88299e-05,9.18347e-07,0.348923,0.00401062,-4.60749e-05,8.29942e-07,0.352889,0.00392096,-4.35851e-05,7.98478e-07,0.356767,0.00383619,-4.11896e-05,6.84917e-07,0.360562,0.00375586,-3.91349e-05,6.63976e-07,0.36428,0.00367959,-3.7143e-05,5.93086e-07,0.367923,0.00360708,-3.53637e-05,5.6976e-07,0.371495,0.00353806,-3.36544e-05,4.95533e-07,0.375,0.00347224,-3.21678e-05,4.87951e-07,0.378441,0.00340937,-3.0704e-05,4.4349e-07,0.38182,0.00334929,-2.93735e-05,4.20297e-07,0.38514,0.0032918,-2.81126e-05,3.7872e-07,0.388404,0.00323671,-2.69764e-05,3.596e-07,0.391614,0.00318384,-2.58976e-05,3.5845e-07,0.394772,0.00313312,-2.48223e-05,2.92765e-07,0.397881,0.00308435,-2.3944e-05,3.18232e-07,0.400942,0.00303742,-2.29893e-05,2.82046e-07,0.403957,0.00299229,-2.21432e-05,2.52315e-07,0.406927,0.00294876,-2.13862e-05,2.58416e-07,0.409855,0.00290676,-2.0611e-05,2.33939e-07,0.412741,0.00286624,-1.99092e-05,2.36342e-07,0.415587,0.00282713,-1.92001e-05,1.916e-07,0.418396,0.00278931,-1.86253e-05,2.1915e-07,0.421167,0.00275271,-1.79679e-05,1.83498e-07,0.423901,0.00271733,-1.74174e-05,1.79343e-07,0.426602,0.00268303,-1.68794e-05,1.72013e-07,0.429268,0.00264979,-1.63633e-05,1.75686e-07,0.431901,0.00261759,-1.58363e-05,1.3852e-07,0.434503,0.00258633,-1.54207e-05,1.64304e-07,0.437074,0.00255598,-1.49278e-05,1.28136e-07,0.439616,0.00252651,-1.45434e-05,1.57618e-07,0.442128,0.0024979,-1.40705e-05,1.0566e-07,0.444612,0.00247007,-1.37535e-05,1.34998e-07,0.447068,0.00244297,-1.33485e-05,1.29207e-07,0.449498,0.00241666,-1.29609e-05,9.32347e-08,0.451902,0.00239102,-1.26812e-05,1.23703e-07,0.45428,0.00236603,-1.23101e-05,9.74072e-08,0.456634,0.0023417,-1.20179e-05,1.12518e-07,0.458964,0.002318,-1.16803e-05,7.83681e-08,0.46127,0.00229488,-1.14452e-05,1.10452e-07,0.463554,0.00227232,-1.11139e-05,7.58719e-08,0.465815,0.00225032,-1.08863e-05,9.2699e-08,0.468055,0.00222882,-1.06082e-05,8.97738e-08,0.470273,0.00220788,-1.03388e-05,5.4845e-08,0.47247,0.00218736,-1.01743e-05,1.0808e-07,0.474648,0.00216734,-9.85007e-06,4.9277e-08,0.476805,0.00214779,-9.70224e-06,8.22408e-08,0.478943,0.00212863,-9.45551e-06,6.87942e-08,0.481063,0.00210993,-9.24913e-06,5.98144e-08,0.483163,0.00209161,-9.06969e-06,7.93789e-08,0.485246,0.00207371,-8.83155e-06,3.99032e-08,0.487311,0.00205616,-8.71184e-06,8.88325e-08,0.489358,0.002039,-8.44534e-06,2.20004e-08,0.491389,0.00202218,-8.37934e-06,9.13872e-08,0.493403,0.0020057,-8.10518e-06,2.96829e-08,0.495401,0.00198957,-8.01613e-06,5.81028e-08,0.497382,0.00197372,-7.84183e-06,6.5731e-08,0.499348,0.00195823,-7.64463e-06,3.66019e-08,0.501299,0.00194305,-7.53483e-06,2.62811e-08,0.503234,0.00192806,-7.45598e-06,9.66907e-08,0.505155,0.00191344,-7.16591e-06,4.18928e-09,0.507061,0.00189912,-7.15334e-06,6.53665e-08,0.508953,0.00188501,-6.95724e-06,3.23686e-08,0.510831,0.00187119,-6.86014e-06,4.35774e-08,0.512696,0.0018576,-6.72941e-06,3.17406e-08,0.514547,0.00184424,-6.63418e-06,6.78785e-08,0.516384,0.00183117,-6.43055e-06,-5.23126e-09,0.518209,0.0018183,-6.44624e-06,7.22562e-08,0.520021,0.00180562,-6.22947e-06,1.42292e-08,0.52182,0.0017932,-6.18679e-06,4.9641e-08,0.523607,0.00178098,-6.03786e-06,2.56259e-08,0.525382,0.00176898,-5.96099e-06,2.66696e-08,0.527145,0.00175714,-5.88098e-06,4.65094e-08,0.528897,0.00174552,-5.74145e-06,2.57114e-08,0.530637,0.00173411,-5.66431e-06,2.94588e-08,0.532365,0.00172287,-5.57594e-06,3.52667e-08,0.534082,0.00171182,-5.47014e-06,8.28868e-09,0.535789,0.00170091,-5.44527e-06,5.07871e-08,0.537484,0.00169017,-5.29291e-06,2.69817e-08,0.539169,0.00167967,-5.21197e-06,2.01009e-08,0.540844,0.0016693,-5.15166e-06,1.18237e-08,0.542508,0.00165903,-5.11619e-06,5.18135e-08,0.544162,0.00164896,-4.96075e-06,1.9341e-08,0.545806,0.00163909,-4.90273e-06,-9.96867e-09,0.54744,0.00162926,-4.93263e-06,8.01382e-08,0.549064,0.00161963,-4.69222e-06,-1.25601e-08,0.550679,0.00161021,-4.7299e-06,2.97067e-08,0.552285,0.00160084,-4.64078e-06,1.29426e-08,0.553881,0.0015916,-4.60195e-06,3.77327e-08,0.555468,0.00158251,-4.48875e-06,1.49412e-08,0.557046,0.00157357,-4.44393e-06,2.17118e-08,0.558615,0.00156475,-4.3788e-06,1.74206e-08,0.560176,0.00155605,-4.32653e-06,2.78152e-08,0.561727,0.00154748,-4.24309e-06,-9.47239e-09,0.563271,0.00153896,-4.27151e-06,6.9679e-08,0.564805,0.00153063,-4.06247e-06,-3.08246e-08,0.566332,0.00152241,-4.15494e-06,5.36188e-08,0.56785,0.00151426,-3.99409e-06,-4.83594e-09,0.56936,0.00150626,-4.00859e-06,2.53293e-08,0.570863,0.00149832,-3.93261e-06,2.27286e-08,0.572357,0.00149052,-3.86442e-06,2.96541e-09,0.573844,0.0014828,-3.85552e-06,2.50147e-08,0.575323,0.00147516,-3.78048e-06,1.61842e-08,0.576794,0.00146765,-3.73193e-06,2.94582e-08,0.578258,0.00146028,-3.64355e-06,-1.48076e-08,0.579715,0.00145295,-3.68798e-06,2.97724e-08,0.581164,0.00144566,-3.59866e-06,1.49272e-08,0.582606,0.00143851,-3.55388e-06,2.97285e-08,0.584041,0.00143149,-3.46469e-06,-1.46323e-08,0.585469,0.00142451,-3.50859e-06,2.88004e-08,0.58689,0.00141758,-3.42219e-06,1.864e-08,0.588304,0.00141079,-3.36627e-06,1.58482e-08,0.589712,0.00140411,-3.31872e-06,-2.24279e-08,0.591112,0.00139741,-3.38601e-06,7.38639e-08,0.592507,0.00139085,-3.16441e-06,-3.46088e-08,0.593894,0.00138442,-3.26824e-06,4.96675e-09,0.595275,0.0013779,-3.25334e-06,7.4346e-08,0.59665,0.00137162,-3.0303e-06,-6.39319e-08,0.598019,0.00136536,-3.2221e-06,6.21725e-08,0.599381,0.00135911,-3.03558e-06,-5.94423e-09,0.600737,0.00135302,-3.05341e-06,2.12091e-08,0.602087,0.00134697,-2.98979e-06,-1.92876e-08,0.603431,0.00134094,-3.04765e-06,5.5941e-08,0.604769,0.00133501,-2.87983e-06,-2.56622e-08,0.606101,0.00132917,-2.95681e-06,4.67078e-08,0.607427,0.0013234,-2.81669e-06,-4.19592e-08,0.608748,0.00131764,-2.94257e-06,6.15243e-08,0.610062,0.00131194,-2.75799e-06,-2.53244e-08,0.611372,0.00130635,-2.83397e-06,3.97739e-08,0.612675,0.0013008,-2.71465e-06,-1.45618e-08,0.613973,0.00129533,-2.75833e-06,1.84733e-08,0.615266,0.00128986,-2.70291e-06,2.73606e-10,0.616553,0.00128446,-2.70209e-06,4.00367e-08,0.617835,0.00127918,-2.58198e-06,-4.12113e-08,0.619111,0.00127389,-2.70561e-06,6.52039e-08,0.620383,0.00126867,-2.51e-06,-4.07901e-08,0.621649,0.00126353,-2.63237e-06,3.83516e-08,0.62291,0.00125838,-2.51732e-06,6.59315e-09,0.624166,0.00125337,-2.49754e-06,-5.11939e-09,0.625416,0.00124836,-2.5129e-06,1.38846e-08,0.626662,0.00124337,-2.47124e-06,9.18514e-09,0.627903,0.00123846,-2.44369e-06,8.97952e-09,0.629139,0.0012336,-2.41675e-06,1.45012e-08,0.63037,0.00122881,-2.37325e-06,-7.37949e-09,0.631597,0.00122404,-2.39538e-06,1.50169e-08,0.632818,0.00121929,-2.35033e-06,6.91648e-09,0.634035,0.00121461,-2.32958e-06,1.69219e-08,0.635248,0.00121,-2.27882e-06,-1.49997e-08,0.636455,0.0012054,-2.32382e-06,4.30769e-08,0.637659,0.00120088,-2.19459e-06,-3.80986e-08,0.638857,0.00119638,-2.30888e-06,4.97134e-08,0.640051,0.00119191,-2.15974e-06,-4.15463e-08,0.641241,0.00118747,-2.28438e-06,5.68667e-08,0.642426,0.00118307,-2.11378e-06,-7.10641e-09,0.643607,0.00117882,-2.1351e-06,-2.8441e-08,0.644784,0.00117446,-2.22042e-06,6.12658e-08,0.645956,0.00117021,-2.03663e-06,-3.78083e-08,0.647124,0.00116602,-2.15005e-06,3.03627e-08,0.648288,0.00116181,-2.05896e-06,-2.40379e-08,0.649448,0.00115762,-2.13108e-06,6.57887e-08,0.650603,0.00115356,-1.93371e-06,-6.03028e-08,0.651755,0.00114951,-2.11462e-06,5.62134e-08,0.652902,0.00114545,-1.94598e-06,-4.53417e-08,0.654046,0.00114142,-2.082e-06,6.55489e-08,0.655185,0.00113745,-1.88536e-06,-3.80396e-08,0.656321,0.00113357,-1.99948e-06,2.70049e-08,0.657452,0.00112965,-1.91846e-06,-1.03755e-08,0.65858,0.00112578,-1.94959e-06,1.44973e-08,0.659704,0.00112192,-1.9061e-06,1.1991e-08,0.660824,0.00111815,-1.87012e-06,-2.85634e-09,0.66194,0.0011144,-1.87869e-06,-5.65782e-10,0.663053,0.00111064,-1.88039e-06,5.11947e-09,0.664162,0.0011069,-1.86503e-06,3.96924e-08,0.665267,0.00110328,-1.74595e-06,-4.46795e-08,0.666368,0.00109966,-1.87999e-06,1.98161e-08,0.667466,0.00109596,-1.82054e-06,2.502e-08,0.66856,0.00109239,-1.74548e-06,-6.86593e-10,0.669651,0.0010889,-1.74754e-06,-2.22739e-08,0.670738,0.00108534,-1.81437e-06,3.01776e-08,0.671821,0.0010818,-1.72383e-06,2.07732e-08,0.672902,0.00107841,-1.66151e-06,-5.36658e-08,0.673978,0.00107493,-1.82251e-06,7.46802e-08,0.675051,0.00107151,-1.59847e-06,-6.62411e-08,0.676121,0.00106811,-1.79719e-06,7.10748e-08,0.677188,0.00106473,-1.58397e-06,-3.92441e-08,0.678251,0.00106145,-1.7017e-06,2.62973e-08,0.679311,0.00105812,-1.62281e-06,-6.34035e-09,0.680367,0.00105486,-1.64183e-06,-9.36249e-10,0.68142,0.00105157,-1.64464e-06,1.00854e-08,0.68247,0.00104831,-1.61438e-06,2.01995e-08,0.683517,0.00104514,-1.55378e-06,-3.1279e-08,0.68456,0.00104194,-1.64762e-06,4.53114e-08,0.685601,0.00103878,-1.51169e-06,-3.07573e-08,0.686638,0.00103567,-1.60396e-06,1.81133e-08,0.687672,0.00103251,-1.54962e-06,1.79085e-08,0.688703,0.00102947,-1.49589e-06,-3.01428e-08,0.689731,0.00102639,-1.58632e-06,4.30583e-08,0.690756,0.00102334,-1.45715e-06,-2.28814e-08,0.691778,0.00102036,-1.52579e-06,-1.11373e-08,0.692797,0.00101727,-1.5592e-06,6.74305e-08,0.693812,0.00101436,-1.35691e-06,-7.97709e-08,0.694825,0.0010114,-1.59622e-06,7.28391e-08,0.695835,0.00100843,-1.37771e-06,-3.27715e-08,0.696842,0.00100558,-1.47602e-06,-1.35807e-09,0.697846,0.00100262,-1.48009e-06,3.82037e-08,0.698847,0.000999775,-1.36548e-06,-3.22474e-08,0.699846,0.000996948,-1.46223e-06,3.11809e-08,0.700841,0.000994117,-1.36868e-06,-3.28714e-08,0.701834,0.000991281,-1.4673e-06,4.07001e-08,0.702824,0.000988468,-1.3452e-06,-1.07197e-08,0.703811,0.000985746,-1.37736e-06,2.17866e-09,0.704795,0.000982998,-1.37082e-06,2.00521e-09,0.705777,0.000980262,-1.3648e-06,-1.01996e-08,0.706756,0.000977502,-1.3954e-06,3.87931e-08,0.707732,0.000974827,-1.27902e-06,-2.57632e-08,0.708706,0.000972192,-1.35631e-06,4.65513e-09,0.709676,0.000969493,-1.34235e-06,7.14257e-09,0.710645,0.00096683,-1.32092e-06,2.63791e-08,0.71161,0.000964267,-1.24178e-06,-5.30543e-08,0.712573,0.000961625,-1.40095e-06,6.66289e-08,0.713533,0.000959023,-1.20106e-06,-3.46474e-08,0.714491,0.000956517,-1.305e-06,1.23559e-08,0.715446,0.000953944,-1.26793e-06,-1.47763e-08,0.716399,0.000951364,-1.31226e-06,4.67494e-08,0.717349,0.000948879,-1.17201e-06,-5.3012e-08,0.718297,0.000946376,-1.33105e-06,4.60894e-08,0.719242,0.000943852,-1.19278e-06,-1.21366e-08,0.720185,0.00094143,-1.22919e-06,2.45673e-09,0.721125,0.000938979,-1.22182e-06,2.30966e-09,0.722063,0.000936543,-1.21489e-06,-1.16954e-08,0.722998,0.000934078,-1.24998e-06,4.44718e-08,0.723931,0.000931711,-1.11656e-06,-4.69823e-08,0.724861,0.000929337,-1.25751e-06,2.4248e-08,0.725789,0.000926895,-1.18477e-06,9.5949e-09,0.726715,0.000924554,-1.15598e-06,-3.02286e-09,0.727638,0.000922233,-1.16505e-06,2.49649e-09,0.72856,0.00091991,-1.15756e-06,-6.96321e-09,0.729478,0.000917575,-1.17845e-06,2.53564e-08,0.730395,0.000915294,-1.10238e-06,-3.48578e-08,0.731309,0.000912984,-1.20695e-06,5.44704e-08,0.732221,0.000910734,-1.04354e-06,-6.38144e-08,0.73313,0.000908455,-1.23499e-06,8.15781e-08,0.734038,0.00090623,-9.90253e-07,-8.3684e-08,0.734943,0.000903999,-1.2413e-06,7.43441e-08,0.735846,0.000901739,-1.01827e-06,-3.48787e-08,0.736746,0.000899598,-1.12291e-06,5.56596e-09,0.737645,0.000897369,-1.10621e-06,1.26148e-08,0.738541,0.000895194,-1.06837e-06,3.57935e-09,0.739435,0.000893068,-1.05763e-06,-2.69322e-08,0.740327,0.000890872,-1.13842e-06,4.45448e-08,0.741217,0.000888729,-1.00479e-06,-3.20376e-08,0.742105,0.000886623,-1.1009e-06,2.40011e-08,0.74299,0.000884493,-1.0289e-06,-4.36209e-09,0.743874,0.000882422,-1.04199e-06,-6.55268e-09,0.744755,0.000880319,-1.06164e-06,3.05728e-08,0.745634,0.000878287,-9.69926e-07,-5.61338e-08,0.746512,0.000876179,-1.13833e-06,7.4753e-08,0.747387,0.000874127,-9.14068e-07,-6.40644e-08,0.74826,0.000872106,-1.10626e-06,6.22955e-08,0.749131,0.000870081,-9.19375e-07,-6.59083e-08,0.75,0.000868044,-1.1171e-06,8.21284e-08,0.750867,0.000866056,-8.70714e-07,-8.37915e-08,0.751732,0.000864064,-1.12209e-06,7.42237e-08,0.752595,0.000862042,-8.99418e-07,-3.42894e-08,0.753456,0.00086014,-1.00229e-06,3.32955e-09,0.754315,0.000858146,-9.92297e-07,2.09712e-08,0.755173,0.000856224,-9.29384e-07,-2.76096e-08,0.756028,0.000854282,-1.01221e-06,2.98627e-08,0.756881,0.000852348,-9.22625e-07,-3.22365e-08,0.757733,0.000850406,-1.01933e-06,3.94786e-08,0.758582,0.000848485,-9.00898e-07,-6.46833e-09,0.75943,0.000846664,-9.20303e-07,-1.36052e-08,0.760275,0.000844783,-9.61119e-07,1.28447e-09,0.761119,0.000842864,-9.57266e-07,8.4674e-09,0.761961,0.000840975,-9.31864e-07,2.44506e-08,0.762801,0.000839185,-8.58512e-07,-4.6665e-08,0.763639,0.000837328,-9.98507e-07,4.30001e-08,0.764476,0.00083546,-8.69507e-07,-6.12609e-09,0.76531,0.000833703,-8.87885e-07,-1.84959e-08,0.766143,0.000831871,-9.43372e-07,2.05052e-08,0.766974,0.000830046,-8.81857e-07,-3.92026e-09,0.767803,0.000828271,-8.93618e-07,-4.82426e-09,0.768631,0.000826469,-9.0809e-07,2.32172e-08,0.769456,0.000824722,-8.38439e-07,-2.84401e-08,0.77028,0.00082296,-9.23759e-07,3.09386e-08,0.771102,0.000821205,-8.30943e-07,-3.57099e-08,0.771922,0.000819436,-9.38073e-07,5.22963e-08,0.772741,0.000817717,-7.81184e-07,-5.42658e-08,0.773558,0.000815992,-9.43981e-07,4.55579e-08,0.774373,0.000814241,-8.07308e-07,-8.75656e-09,0.775186,0.0008126,-8.33578e-07,-1.05315e-08,0.775998,0.000810901,-8.65172e-07,-8.72188e-09,0.776808,0.000809145,-8.91338e-07,4.54191e-08,0.777616,0.000807498,-7.5508e-07,-5.37454e-08,0.778423,0.000805827,-9.16317e-07,5.03532e-08,0.779228,0.000804145,-7.65257e-07,-2.84584e-08,0.780031,0.000802529,-8.50632e-07,3.87579e-09,0.780833,0.00080084,-8.39005e-07,1.29552e-08,0.781633,0.0007992,-8.00139e-07,3.90804e-09,0.782432,0.000797612,-7.88415e-07,-2.85874e-08,0.783228,0.000795949,-8.74177e-07,5.0837e-08,0.784023,0.000794353,-7.21666e-07,-5.55513e-08,0.784817,0.000792743,-8.8832e-07,5.21587e-08,0.785609,0.000791123,-7.31844e-07,-3.38744e-08,0.786399,0.000789558,-8.33467e-07,2.37342e-08,0.787188,0.000787962,-7.62264e-07,-1.45775e-09,0.787975,0.000786433,-7.66638e-07,-1.79034e-08,0.788761,0.000784846,-8.20348e-07,1.34665e-08,0.789545,0.000783246,-7.79948e-07,2.3642e-08,0.790327,0.000781757,-7.09022e-07,-4.84297e-08,0.791108,0.000780194,-8.54311e-07,5.08674e-08,0.791888,0.000778638,-7.01709e-07,-3.58303e-08,0.792666,0.000777127,-8.092e-07,3.28493e-08,0.793442,0.000775607,-7.10652e-07,-3.59624e-08,0.794217,0.000774078,-8.1854e-07,5.13959e-08,0.79499,0.000772595,-6.64352e-07,-5.04121e-08,0.795762,0.000771115,-8.15588e-07,3.10431e-08,0.796532,0.000769577,-7.22459e-07,-1.41557e-08,0.797301,0.00076809,-7.64926e-07,2.55795e-08,0.798069,0.000766636,-6.88187e-07,-2.85578e-08,0.798835,0.000765174,-7.73861e-07,2.90472e-08,0.799599,0.000763714,-6.86719e-07,-2.80262e-08,0.800362,0.000762256,-7.70798e-07,2.34531e-08,0.801123,0.000760785,-7.00438e-07,-6.18144e-09,0.801884,0.000759366,-7.18983e-07,1.27263e-09,0.802642,0.000757931,-7.15165e-07,1.09101e-09,0.803399,0.000756504,-7.11892e-07,-5.63675e-09,0.804155,0.000755064,-7.28802e-07,2.14559e-08,0.80491,0.00075367,-6.64434e-07,-2.05821e-08,0.805663,0.00075228,-7.26181e-07,1.26812e-09,0.806414,0.000750831,-7.22377e-07,1.55097e-08,0.807164,0.000749433,-6.75848e-07,-3.70216e-09,0.807913,0.00074807,-6.86954e-07,-7.0105e-10,0.80866,0.000746694,-6.89057e-07,6.5063e-09,0.809406,0.000745336,-6.69538e-07,-2.53242e-08,0.810151,0.000743921,-7.45511e-07,3.51858e-08,0.810894,0.000742535,-6.39953e-07,3.79034e-09,0.811636,0.000741267,-6.28582e-07,-5.03471e-08,0.812377,0.000739858,-7.79624e-07,7.83886e-08,0.813116,0.000738534,-5.44458e-07,-8.43935e-08,0.813854,0.000737192,-7.97638e-07,8.03714e-08,0.81459,0.000735838,-5.56524e-07,-5.82784e-08,0.815325,0.00073455,-7.31359e-07,3.35329e-08,0.816059,0.000733188,-6.3076e-07,-1.62486e-08,0.816792,0.000731878,-6.79506e-07,3.14614e-08,0.817523,0.000730613,-5.85122e-07,-4.99925e-08,0.818253,0.000729293,-7.35099e-07,4.92994e-08,0.818982,0.000727971,-5.87201e-07,-2.79959e-08,0.819709,0.000726712,-6.71189e-07,3.07959e-09,0.820435,0.000725379,-6.6195e-07,1.56777e-08,0.82116,0.000724102,-6.14917e-07,-6.18564e-09,0.821883,0.000722854,-6.33474e-07,9.06488e-09,0.822606,0.000721614,-6.06279e-07,-3.00739e-08,0.823327,0.000720311,-6.96501e-07,5.16262e-08,0.824046,0.000719073,-5.41623e-07,-5.72214e-08,0.824765,0.000717818,-7.13287e-07,5.80503e-08,0.825482,0.000716566,-5.39136e-07,-5.57703e-08,0.826198,0.00071532,-7.06447e-07,4.58215e-08,0.826912,0.000714045,-5.68983e-07,-8.30636e-09,0.827626,0.000712882,-5.93902e-07,-1.25961e-08,0.828338,0.000711656,-6.3169e-07,-9.13985e-10,0.829049,0.00071039,-6.34432e-07,1.62519e-08,0.829759,0.00070917,-5.85676e-07,-4.48904e-09,0.830468,0.000707985,-5.99143e-07,1.70418e-09,0.831175,0.000706792,-5.9403e-07,-2.32768e-09,0.831881,0.000705597,-6.01014e-07,7.60648e-09,0.832586,0.000704418,-5.78194e-07,-2.80982e-08,0.83329,0.000703177,-6.62489e-07,4.51817e-08,0.833993,0.000701988,-5.26944e-07,-3.34192e-08,0.834694,0.000700834,-6.27201e-07,2.88904e-08,0.835394,0.000699666,-5.4053e-07,-2.25378e-08,0.836093,0.000698517,-6.08143e-07,1.65589e-09,0.836791,0.000697306,-6.03176e-07,1.59142e-08,0.837488,0.000696147,-5.55433e-07,-5.70801e-09,0.838184,0.000695019,-5.72557e-07,6.91792e-09,0.838878,0.000693895,-5.51803e-07,-2.19637e-08,0.839571,0.000692725,-6.17694e-07,2.13321e-08,0.840263,0.000691554,-5.53698e-07,-3.75996e-09,0.840954,0.000690435,-5.64978e-07,-6.29219e-09,0.841644,0.000689287,-5.83855e-07,2.89287e-08,0.842333,0.000688206,-4.97068e-07,-4.98181e-08,0.843021,0.000687062,-6.46523e-07,5.11344e-08,0.843707,0.000685922,-4.9312e-07,-3.55102e-08,0.844393,0.00068483,-5.9965e-07,3.13019e-08,0.845077,0.000683724,-5.05745e-07,-3.00925e-08,0.84576,0.000682622,-5.96022e-07,2.94636e-08,0.846442,0.000681519,-5.07631e-07,-2.81572e-08,0.847123,0.000680419,-5.92103e-07,2.35606e-08,0.847803,0.000679306,-5.21421e-07,-6.48045e-09,0.848482,0.000678243,-5.40863e-07,2.36124e-09,0.849159,0.000677169,-5.33779e-07,-2.96461e-09,0.849836,0.000676092,-5.42673e-07,9.49728e-09,0.850512,0.000675035,-5.14181e-07,-3.50245e-08,0.851186,0.000673902,-6.19254e-07,7.09959e-08,0.851859,0.000672876,-4.06267e-07,-7.01453e-08,0.852532,0.000671853,-6.16703e-07,3.07714e-08,0.853203,0.000670712,-5.24388e-07,6.66423e-09,0.853873,0.000669684,-5.04396e-07,2.17629e-09,0.854542,0.000668681,-4.97867e-07,-1.53693e-08,0.855211,0.000667639,-5.43975e-07,-3.03752e-10,0.855878,0.000666551,-5.44886e-07,1.65844e-08,0.856544,0.000665511,-4.95133e-07,-6.42907e-09,0.857209,0.000664501,-5.1442e-07,9.13195e-09,0.857873,0.0006635,-4.87024e-07,-3.00987e-08,0.858536,0.000662435,-5.7732e-07,5.16584e-08,0.859198,0.000661436,-4.22345e-07,-5.73255e-08,0.859859,0.000660419,-5.94322e-07,5.84343e-08,0.860518,0.000659406,-4.19019e-07,-5.72022e-08,0.861177,0.000658396,-5.90626e-07,5.11653e-08,0.861835,0.000657368,-4.3713e-07,-2.82495e-08,0.862492,0.000656409,-5.21878e-07,2.22788e-09,0.863148,0.000655372,-5.15195e-07,1.9338e-08,0.863803,0.0006544,-4.5718e-07,-1.99754e-08,0.864457,0.000653425,-5.17107e-07,9.59024e-10,0.86511,0.000652394,-5.1423e-07,1.61393e-08,0.865762,0.000651414,-4.65812e-07,-5.91149e-09,0.866413,0.000650465,-4.83546e-07,7.50665e-09,0.867063,0.00064952,-4.61026e-07,-2.4115e-08,0.867712,0.000648526,-5.33371e-07,2.93486e-08,0.86836,0.000647547,-4.45325e-07,-3.36748e-08,0.869007,0.000646555,-5.4635e-07,4.57461e-08,0.869653,0.0006456,-4.09112e-07,-3.01002e-08,0.870298,0.000644691,-4.99412e-07,1.50501e-08,0.870942,0.000643738,-4.54262e-07,-3.01002e-08,0.871585,0.000642739,-5.44563e-07,4.57461e-08,0.872228,0.000641787,-4.07324e-07,-3.36748e-08,0.872869,0.000640871,-5.08349e-07,2.93486e-08,0.873509,0.000639943,-4.20303e-07,-2.4115e-08,0.874149,0.00063903,-4.92648e-07,7.50655e-09,0.874787,0.000638067,-4.70128e-07,-5.91126e-09,0.875425,0.000637109,-4.87862e-07,1.61385e-08,0.876062,0.000636182,-4.39447e-07,9.61961e-10,0.876697,0.000635306,-4.36561e-07,-1.99863e-08,0.877332,0.000634373,-4.9652e-07,1.93785e-08,0.877966,0.000633438,-4.38384e-07,2.07697e-09,0.878599,0.000632567,-4.32153e-07,-2.76864e-08,0.879231,0.00063162,-5.15212e-07,4.90641e-08,0.879862,0.000630737,-3.6802e-07,-4.93606e-08,0.880493,0.000629852,-5.16102e-07,2.9169e-08,0.881122,0.000628908,-4.28595e-07,-7.71083e-09,0.881751,0.000628027,-4.51727e-07,1.6744e-09,0.882378,0.000627129,-4.46704e-07,1.01317e-09,0.883005,0.000626239,-4.43665e-07,-5.72703e-09,0.883631,0.000625334,-4.60846e-07,2.1895e-08,0.884255,0.000624478,-3.95161e-07,-2.22481e-08,0.88488,0.000623621,-4.61905e-07,7.4928e-09,0.885503,0.00062272,-4.39427e-07,-7.72306e-09,0.886125,0.000621818,-4.62596e-07,2.33995e-08,0.886746,0.000620963,-3.92398e-07,-2.62704e-08,0.887367,0.000620099,-4.71209e-07,2.20775e-08,0.887987,0.000619223,-4.04976e-07,-2.43496e-09,0.888605,0.000618406,-4.12281e-07,-1.23377e-08,0.889223,0.000617544,-4.49294e-07,-7.81876e-09,0.88984,0.000616622,-4.72751e-07,4.36128e-08,0.890457,0.000615807,-3.41912e-07,-4.7423e-08,0.891072,0.000614981,-4.84181e-07,2.68698e-08,0.891687,0.000614093,-4.03572e-07,-4.51384e-10,0.8923,0.000613285,-4.04926e-07,-2.50643e-08,0.892913,0.0006124,-4.80119e-07,4.11038e-08,0.893525,0.000611563,-3.56808e-07,-2.01414e-08,0.894136,0.000610789,-4.17232e-07,-2.01426e-08,0.894747,0.000609894,-4.7766e-07,4.11073e-08,0.895356,0.000609062,-3.54338e-07,-2.50773e-08,0.895965,0.000608278,-4.2957e-07,-4.02954e-10,0.896573,0.000607418,-4.30779e-07,2.66891e-08,0.89718,0.000606636,-3.50711e-07,-4.67489e-08,0.897786,0.000605795,-4.90958e-07,4.10972e-08,0.898391,0.000604936,-3.67666e-07,1.56948e-09,0.898996,0.000604205,-3.62958e-07,-4.73751e-08,0.8996,0.000603337,-5.05083e-07,6.87214e-08,0.900202,0.000602533,-2.98919e-07,-4.86966e-08,0.900805,0.000601789,-4.45009e-07,6.85589e-09,0.901406,0.00060092,-4.24441e-07,2.1273e-08,0.902007,0.000600135,-3.60622e-07,-3.23434e-08,0.902606,0.000599317,-4.57652e-07,4.84959e-08,0.903205,0.000598547,-3.12164e-07,-4.24309e-08,0.903803,0.000597795,-4.39457e-07,2.01844e-09,0.904401,0.000596922,-4.33402e-07,3.43571e-08,0.904997,0.000596159,-3.30331e-07,-2.02374e-08,0.905593,0.000595437,-3.91043e-07,-1.30123e-08,0.906188,0.000594616,-4.3008e-07,1.26819e-08,0.906782,0.000593794,-3.92034e-07,2.18894e-08,0.907376,0.000593076,-3.26366e-07,-4.06349e-08,0.907968,0.000592301,-4.4827e-07,2.1441e-08,0.90856,0.000591469,-3.83947e-07,1.44754e-08,0.909151,0.000590744,-3.40521e-07,-1.97379e-08,0.909742,0.000590004,-3.99735e-07,4.87161e-09,0.910331,0.000589219,-3.8512e-07,2.51532e-10,0.91092,0.00058845,-3.84366e-07,-5.87776e-09,0.911508,0.000587663,-4.01999e-07,2.32595e-08,0.912096,0.000586929,-3.3222e-07,-2.75554e-08,0.912682,0.000586182,-4.14887e-07,2.73573e-08,0.913268,0.000585434,-3.32815e-07,-2.22692e-08,0.913853,0.000584702,-3.99622e-07,2.11486e-09,0.914437,0.000583909,-3.93278e-07,1.38098e-08,0.915021,0.000583164,-3.51848e-07,2.25042e-09,0.915604,0.000582467,-3.45097e-07,-2.28115e-08,0.916186,0.000581708,-4.13531e-07,2.93911e-08,0.916767,0.000580969,-3.25358e-07,-3.51481e-08,0.917348,0.000580213,-4.30803e-07,5.15967e-08,0.917928,0.000579506,-2.76012e-07,-5.20296e-08,0.918507,0.000578798,-4.32101e-07,3.73124e-08,0.919085,0.000578046,-3.20164e-07,-3.76154e-08,0.919663,0.000577293,-4.3301e-07,5.35447e-08,0.92024,0.000576587,-2.72376e-07,-5.7354e-08,0.920816,0.000575871,-4.44438e-07,5.66621e-08,0.921391,0.000575152,-2.74452e-07,-5.00851e-08,0.921966,0.000574453,-4.24707e-07,2.4469e-08,0.92254,0.000573677,-3.513e-07,1.18138e-08,0.923114,0.000573009,-3.15859e-07,-1.21195e-08,0.923686,0.000572341,-3.52217e-07,-2.29403e-08,0.924258,0.000571568,-4.21038e-07,4.4276e-08,0.924829,0.000570859,-2.8821e-07,-3.49546e-08,0.9254,0.000570178,-3.93074e-07,3.59377e-08,0.92597,0.000569499,-2.85261e-07,-4.91915e-08,0.926539,0.000568781,-4.32835e-07,4.16189e-08,0.927107,0.00056804,-3.07979e-07,1.92523e-09,0.927675,0.00056743,-3.02203e-07,-4.93198e-08,0.928242,0.000566678,-4.50162e-07,7.61447e-08,0.928809,0.000566006,-2.21728e-07,-7.6445e-08,0.929374,0.000565333,-4.51063e-07,5.08216e-08,0.929939,0.000564583,-2.98599e-07,-7.63212e-09,0.930503,0.000563963,-3.21495e-07,-2.02931e-08,0.931067,0.000563259,-3.82374e-07,2.92001e-08,0.93163,0.000562582,-2.94774e-07,-3.69025e-08,0.932192,0.000561882,-4.05482e-07,5.88053e-08,0.932754,0.000561247,-2.29066e-07,-7.91094e-08,0.933315,0.000560552,-4.66394e-07,7.88184e-08,0.933875,0.000559856,-2.29939e-07,-5.73501e-08,0.934434,0.000559224,-4.01989e-07,3.13727e-08,0.934993,0.000558514,-3.07871e-07,-8.53611e-09,0.935551,0.000557873,-3.33479e-07,2.77175e-09,0.936109,0.000557214,-3.25164e-07,-2.55091e-09,0.936666,0.000556556,-3.32817e-07,7.43188e-09,0.937222,0.000555913,-3.10521e-07,-2.71766e-08,0.937778,0.00055521,-3.92051e-07,4.167e-08,0.938333,0.000554551,-2.67041e-07,-2.02941e-08,0.938887,0.000553956,-3.27923e-07,-2.00984e-08,0.93944,0.00055324,-3.88218e-07,4.10828e-08,0.939993,0.000552587,-2.6497e-07,-2.50237e-08,0.940546,0.000551982,-3.40041e-07,-5.92583e-10,0.941097,0.0005513,-3.41819e-07,2.7394e-08,0.941648,0.000550698,-2.59637e-07,-4.93788e-08,0.942199,0.000550031,-4.07773e-07,5.09119e-08,0.942748,0.000549368,-2.55038e-07,-3.50595e-08,0.943297,0.000548753,-3.60216e-07,2.97214e-08,0.943846,0.000548122,-2.71052e-07,-2.42215e-08,0.944394,0.000547507,-3.43716e-07,7.55985e-09,0.944941,0.000546842,-3.21037e-07,-6.01796e-09,0.945487,0.000546182,-3.3909e-07,1.65119e-08,0.946033,0.000545553,-2.89555e-07,-4.2498e-10,0.946578,0.000544973,-2.9083e-07,-1.4812e-08,0.947123,0.000544347,-3.35266e-07,6.83068e-11,0.947667,0.000543676,-3.35061e-07,1.45388e-08,0.94821,0.00054305,-2.91444e-07,1.38123e-09,0.948753,0.000542471,-2.87301e-07,-2.00637e-08,0.949295,0.000541836,-3.47492e-07,1.92688e-08,0.949837,0.000541199,-2.89685e-07,2.59298e-09,0.950378,0.000540628,-2.81906e-07,-2.96407e-08,0.950918,0.000539975,-3.70829e-07,5.63652e-08,0.951458,0.000539402,-2.01733e-07,-7.66107e-08,0.951997,0.000538769,-4.31565e-07,7.12638e-08,0.952535,0.00053812,-2.17774e-07,-2.96305e-08,0.953073,0.000537595,-3.06665e-07,-1.23464e-08,0.95361,0.000536945,-3.43704e-07,1.94114e-08,0.954147,0.000536316,-2.8547e-07,-5.69451e-09,0.954683,0.000535728,-3.02554e-07,3.36666e-09,0.955219,0.000535133,-2.92454e-07,-7.77208e-09,0.955753,0.000534525,-3.1577e-07,2.77216e-08,0.956288,0.000533976,-2.32605e-07,-4.35097e-08,0.956821,0.00053338,-3.63134e-07,2.7108e-08,0.957354,0.000532735,-2.8181e-07,-5.31772e-09,0.957887,0.000532156,-2.97764e-07,-5.83718e-09,0.958419,0.000531543,-3.15275e-07,2.86664e-08,0.95895,0.000530998,-2.29276e-07,-4.9224e-08,0.959481,0.000530392,-3.76948e-07,4.90201e-08,0.960011,0.000529785,-2.29887e-07,-2.76471e-08,0.96054,0.000529243,-3.12829e-07,1.96385e-09,0.961069,0.000528623,-3.06937e-07,1.97917e-08,0.961598,0.000528068,-2.47562e-07,-2.15261e-08,0.962125,0.000527508,-3.1214e-07,6.70795e-09,0.962653,0.000526904,-2.92016e-07,-5.30573e-09,0.963179,0.000526304,-3.07934e-07,1.4515e-08,0.963705,0.000525732,-2.64389e-07,6.85048e-09,0.964231,0.000525224,-2.43837e-07,-4.19169e-08,0.964756,0.00052461,-3.69588e-07,4.1608e-08,0.96528,0.000523996,-2.44764e-07,-5.30598e-09,0.965804,0.000523491,-2.60682e-07,-2.03841e-08,0.966327,0.000522908,-3.21834e-07,2.72378e-08,0.966849,0.000522346,-2.40121e-07,-2.89625e-08,0.967371,0.000521779,-3.27008e-07,2.90075e-08,0.967893,0.000521212,-2.39986e-07,-2.74629e-08,0.968414,0.00052065,-3.22374e-07,2.12396e-08,0.968934,0.000520069,-2.58656e-07,2.10922e-09,0.969454,0.000519558,-2.52328e-07,-2.96765e-08,0.969973,0.000518964,-3.41357e-07,5.6992e-08,0.970492,0.000518452,-1.70382e-07,-7.90821e-08,0.97101,0.000517874,-4.07628e-07,8.05224e-08,0.971528,0.000517301,-1.66061e-07,-6.41937e-08,0.972045,0.000516776,-3.58642e-07,5.70429e-08,0.972561,0.00051623,-1.87513e-07,-4.47686e-08,0.973077,0.00051572,-3.21819e-07,2.82237e-09,0.973593,0.000515085,-3.13352e-07,3.34792e-08,0.974108,0.000514559,-2.12914e-07,-1.75298e-08,0.974622,0.000514081,-2.65503e-07,-2.29648e-08,0.975136,0.000513481,-3.34398e-07,4.97843e-08,0.975649,0.000512961,-1.85045e-07,-5.6963e-08,0.976162,0.00051242,-3.55934e-07,5.88585e-08,0.976674,0.000511885,-1.79359e-07,-5.92616e-08,0.977185,0.000511348,-3.57143e-07,5.89785e-08,0.977696,0.000510811,-1.80208e-07,-5.74433e-08,0.978207,0.000510278,-3.52538e-07,5.15854e-08,0.978717,0.000509728,-1.97781e-07,-2.9689e-08,0.979226,0.000509243,-2.86848e-07,7.56591e-09,0.979735,0.000508692,-2.64151e-07,-5.74649e-10,0.980244,0.000508162,-2.65875e-07,-5.26732e-09,0.980752,0.000507615,-2.81677e-07,2.16439e-08,0.981259,0.000507116,-2.16745e-07,-2.17037e-08,0.981766,0.000506618,-2.81856e-07,5.56636e-09,0.982272,0.000506071,-2.65157e-07,-5.61689e-10,0.982778,0.000505539,-2.66842e-07,-3.31963e-09,0.983283,0.000504995,-2.76801e-07,1.38402e-08,0.983788,0.000504483,-2.3528e-07,7.56339e-09,0.984292,0.000504035,-2.1259e-07,-4.40938e-08,0.984796,0.000503478,-3.44871e-07,4.96026e-08,0.985299,0.000502937,-1.96064e-07,-3.51071e-08,0.985802,0.000502439,-3.01385e-07,3.12212e-08,0.986304,0.00050193,-2.07721e-07,-3.0173e-08,0.986806,0.000501424,-2.9824e-07,2.9866e-08,0.987307,0.000500917,-2.08642e-07,-2.96865e-08,0.987808,0.000500411,-2.97702e-07,2.92753e-08,0.988308,0.000499903,-2.09876e-07,-2.78101e-08,0.988807,0.0004994,-2.93306e-07,2.23604e-08,0.989307,0.000498881,-2.26225e-07,-2.02681e-09,0.989805,0.000498422,-2.32305e-07,-1.42531e-08,0.990303,0.000497915,-2.75065e-07,-5.65232e-10,0.990801,0.000497363,-2.76761e-07,1.65141e-08,0.991298,0.000496859,-2.27218e-07,-5.88639e-09,0.991795,0.000496387,-2.44878e-07,7.0315e-09,0.992291,0.000495918,-2.23783e-07,-2.22396e-08,0.992787,0.000495404,-2.90502e-07,2.23224e-08,0.993282,0.00049489,-2.23535e-07,-7.44543e-09,0.993776,0.000494421,-2.45871e-07,7.45924e-09,0.994271,0.000493951,-2.23493e-07,-2.23915e-08,0.994764,0.000493437,-2.90668e-07,2.25021e-08,0.995257,0.000492923,-2.23161e-07,-8.01218e-09,0.99575,0.000492453,-2.47198e-07,9.54669e-09,0.996242,0.000491987,-2.18558e-07,-3.01746e-08,0.996734,0.000491459,-3.09082e-07,5.1547e-08,0.997225,0.000490996,-1.54441e-07,-5.68039e-08,0.997716,0.000490517,-3.24853e-07,5.64594e-08,0.998206,0.000490036,-1.55474e-07,-4.98245e-08,0.998696,0.000489576,-3.04948e-07,2.36292e-08,0.999186,0.000489037,-2.3406e-07,1.49121e-08,0.999674,0.000488613,-1.89324e-07,-2.3673e-08,1.00016,0.000488164,-2.60343e-07,2.01754e-08,1.00065,0.000487704,-1.99816e-07,-5.70288e-08,1.00114,0.000487133,-3.70903e-07,8.87303e-08,1.00162,0.000486657,-1.04712e-07,-5.94737e-08,1.00211,0.000486269,-2.83133e-07,2.99553e-08,1.0026,0.000485793,-1.93267e-07,-6.03474e-08,1.00308,0.000485225,-3.74309e-07,9.2225e-08,1.00357,0.000484754,-9.76345e-08,-7.0134e-08,1.00405,0.000484348,-3.08036e-07,6.91016e-08,1.00454,0.000483939,-1.00731e-07,-8.70633e-08,1.00502,0.000483476,-3.61921e-07,4.07328e-08,1.0055,0.000482875,-2.39723e-07,4.33413e-08,1.00599,0.000482525,-1.09699e-07,-9.48886e-08,1.00647,0.000482021,-3.94365e-07,9.77947e-08,1.00695,0.000481526,-1.00981e-07,-5.78713e-08,1.00743,0.00048115,-2.74595e-07,1.44814e-08,1.00791,0.000480645,-2.31151e-07,-5.42665e-11,1.00839,0.000480182,-2.31314e-07,-1.42643e-08,1.00887,0.000479677,-2.74106e-07,5.71115e-08,1.00935,0.0004793,-1.02772e-07,-9.49724e-08,1.00983,0.000478809,-3.87689e-07,8.43596e-08,1.01031,0.000478287,-1.3461e-07,-4.04755e-09,1.01079,0.000478006,-1.46753e-07,-6.81694e-08,1.01127,0.000477508,-3.51261e-07,3.83067e-08,1.01174,0.00047692,-2.36341e-07,3.41521e-08,1.01222,0.00047655,-1.33885e-07,-5.57058e-08,1.0127,0.000476115,-3.01002e-07,6.94616e-08,1.01317,0.000475721,-9.26174e-08,-1.02931e-07,1.01365,0.000475227,-4.01412e-07,1.03846e-07,1.01412,0.000474736,-8.98751e-08,-7.40321e-08,1.0146,0.000474334,-3.11971e-07,7.30735e-08,1.01507,0.00047393,-9.27508e-08,-9.90527e-08,1.01554,0.000473447,-3.89909e-07,8.47188e-08,1.01602,0.000472921,-1.35753e-07,-1.40381e-09,1.01649,0.000472645,-1.39964e-07,-7.91035e-08,1.01696,0.000472128,-3.77275e-07,7.93993e-08,1.01744,0.000471612,-1.39077e-07,-7.52607e-11,1.01791,0.000471334,-1.39302e-07,-7.90983e-08,1.01838,0.000470818,-3.76597e-07,7.80499e-08,1.01885,0.000470299,-1.42448e-07,5.31733e-09,1.01932,0.00047003,-1.26496e-07,-9.93193e-08,1.01979,0.000469479,-4.24453e-07,1.53541e-07,1.02026,0.00046909,3.617e-08,-1.57217e-07,1.02073,0.000468691,-4.35482e-07,1.177e-07,1.02119,0.000468173,-8.23808e-08,-7.51659e-08,1.02166,0.000467783,-3.07878e-07,6.37538e-08,1.02213,0.000467358,-1.16617e-07,-6.064e-08,1.0226,0.000466943,-2.98537e-07,5.9597e-08,1.02306,0.000466525,-1.19746e-07,-5.85386e-08,1.02353,0.00046611,-2.95362e-07,5.53482e-08,1.024,0.000465685,-1.29317e-07,-4.36449e-08,1.02446,0.000465296,-2.60252e-07,2.20268e-11,1.02493,0.000464775,-2.60186e-07,4.35568e-08,1.02539,0.000464386,-1.29516e-07,-5.50398e-08,1.02586,0.000463961,-2.94635e-07,5.73932e-08,1.02632,0.000463544,-1.22456e-07,-5.53236e-08,1.02678,0.000463133,-2.88426e-07,4.46921e-08,1.02725,0.000462691,-1.5435e-07,-4.23534e-09,1.02771,0.000462369,-1.67056e-07,-2.77507e-08,1.02817,0.000461952,-2.50308e-07,-3.97101e-09,1.02863,0.000461439,-2.62221e-07,4.36348e-08,1.02909,0.000461046,-1.31317e-07,-5.13589e-08,1.02955,0.000460629,-2.85394e-07,4.25913e-08,1.03001,0.000460186,-1.5762e-07,2.0285e-10,1.03047,0.000459871,-1.57011e-07,-4.34027e-08,1.03093,0.000459427,-2.87219e-07,5.41987e-08,1.03139,0.000459015,-1.24623e-07,-5.4183e-08,1.03185,0.000458604,-2.87172e-07,4.33239e-08,1.03231,0.000458159,-1.572e-07,9.65817e-11,1.03277,0.000457845,-1.56911e-07,-4.37103e-08,1.03323,0.0004574,-2.88041e-07,5.55351e-08,1.03368,0.000456991,-1.21436e-07,-5.9221e-08,1.03414,0.00045657,-2.99099e-07,6.21394e-08,1.0346,0.000456158,-1.1268e-07,-7.01275e-08,1.03505,0.000455723,-3.23063e-07,9.91614e-08,1.03551,0.000455374,-2.55788e-08,-8.80996e-08,1.03596,0.000455058,-2.89878e-07,1.48184e-08,1.03642,0.000454523,-2.45422e-07,2.88258e-08,1.03687,0.000454119,-1.58945e-07,-1.09125e-08,1.03733,0.000453768,-1.91682e-07,1.48241e-08,1.03778,0.000453429,-1.4721e-07,-4.83838e-08,1.03823,0.00045299,-2.92361e-07,5.95019e-08,1.03869,0.000452584,-1.13856e-07,-7.04146e-08,1.03914,0.000452145,-3.25099e-07,1.02947e-07,1.03959,0.000451803,-1.62583e-08,-1.02955e-07,1.04004,0.000451462,-3.25123e-07,7.04544e-08,1.04049,0.000451023,-1.1376e-07,-5.96534e-08,1.04094,0.000450616,-2.9272e-07,4.89499e-08,1.04139,0.000450178,-1.45871e-07,-1.69369e-08,1.04184,0.000449835,-1.96681e-07,1.87977e-08,1.04229,0.000449498,-1.40288e-07,-5.82539e-08,1.04274,0.000449043,-3.1505e-07,9.50087e-08,1.04319,0.000448698,-3.00238e-08,-8.33623e-08,1.04364,0.000448388,-2.80111e-07,2.20363e-11,1.04409,0.000447828,-2.80045e-07,8.32742e-08,1.04454,0.000447517,-3.02221e-08,-9.47002e-08,1.04498,0.000447173,-3.14323e-07,5.7108e-08,1.04543,0.000446716,-1.42999e-07,-1.45225e-08,1.04588,0.000446386,-1.86566e-07,9.82022e-10,1.04632,0.000446016,-1.8362e-07,1.05944e-08,1.04677,0.00044568,-1.51837e-07,-4.33597e-08,1.04721,0.000445247,-2.81916e-07,4.36352e-08,1.04766,0.000444814,-1.51011e-07,-1.19717e-08,1.0481,0.000444476,-1.86926e-07,4.25158e-09,1.04855,0.000444115,-1.74171e-07,-5.03461e-09,1.04899,0.000443751,-1.89275e-07,1.58868e-08,1.04944,0.00044342,-1.41614e-07,-5.85127e-08,1.04988,0.000442961,-3.17152e-07,9.89548e-08,1.05032,0.000442624,-2.0288e-08,-9.88878e-08,1.05076,0.000442287,-3.16951e-07,5.81779e-08,1.05121,0.000441827,-1.42418e-07,-1.46144e-08,1.05165,0.000441499,-1.86261e-07,2.79892e-10,1.05209,0.000441127,-1.85421e-07,1.34949e-08,1.05253,0.000440797,-1.44937e-07,-5.42594e-08,1.05297,0.000440344,-3.07715e-07,8.43335e-08,1.05341,0.000439982,-5.47146e-08,-4.46558e-08,1.05385,0.000439738,-1.88682e-07,-2.49193e-08,1.05429,0.000439286,-2.6344e-07,2.5124e-08,1.05473,0.000438835,-1.88068e-07,4.36328e-08,1.05517,0.000438589,-5.71699e-08,-8.04459e-08,1.05561,0.000438234,-2.98508e-07,3.97324e-08,1.05605,0.000437756,-1.79311e-07,4.07258e-08,1.05648,0.000437519,-5.71332e-08,-8.34263e-08,1.05692,0.000437155,-3.07412e-07,5.45608e-08,1.05736,0.000436704,-1.4373e-07,-1.56078e-08,1.05779,0.000436369,-1.90553e-07,7.87043e-09,1.05823,0.000436012,-1.66942e-07,-1.58739e-08,1.05867,0.00043563,-2.14563e-07,5.56251e-08,1.0591,0.000435368,-4.76881e-08,-8.74172e-08,1.05954,0.000435011,-3.0994e-07,5.56251e-08,1.05997,0.000434558,-1.43064e-07,-1.58739e-08,1.06041,0.000434224,-1.90686e-07,7.87042e-09,1.06084,0.000433866,-1.67075e-07,-1.56078e-08,1.06127,0.000433485,-2.13898e-07,5.45609e-08,1.06171,0.000433221,-5.02157e-08,-8.34263e-08,1.06214,0.00043287,-3.00495e-07,4.07258e-08,1.06257,0.000432391,-1.78317e-07,3.97325e-08,1.063,0.000432154,-5.91198e-08,-8.04464e-08,1.06344,0.000431794,-3.00459e-07,4.36347e-08,1.06387,0.000431324,-1.69555e-07,2.5117e-08,1.0643,0.000431061,-9.42041e-08,-2.48934e-08,1.06473,0.000430798,-1.68884e-07,-4.47527e-08,1.06516,0.000430326,-3.03142e-07,8.46951e-08,1.06559,0.000429973,-4.90573e-08,-5.56089e-08,1.06602,0.000429708,-2.15884e-07,1.85314e-08,1.06645,0.000429332,-1.6029e-07,-1.85166e-08,1.06688,0.000428956,-2.1584e-07,5.5535e-08,1.06731,0.000428691,-4.92347e-08,-8.44142e-08,1.06774,0.000428339,-3.02477e-07,4.37032e-08,1.06816,0.000427865,-1.71368e-07,2.88107e-08,1.06859,0.000427609,-8.49356e-08,-3.97367e-08,1.06902,0.00042732,-2.04146e-07,1.09267e-08,1.06945,0.000426945,-1.71365e-07,-3.97023e-09,1.06987,0.00042659,-1.83276e-07,4.9542e-09,1.0703,0.000426238,-1.68414e-07,-1.58466e-08,1.07073,0.000425854,-2.15953e-07,5.84321e-08,1.07115,0.000425597,-4.0657e-08,-9.86725e-08,1.07158,0.00042522,-3.36674e-07,9.78392e-08,1.072,0.00042484,-4.31568e-08,-5.42658e-08,1.07243,0.000424591,-2.05954e-07,1.45377e-11,1.07285,0.000424179,-2.0591e-07,5.42076e-08,1.07328,0.00042393,-4.32877e-08,-9.76357e-08,1.0737,0.00042355,-3.36195e-07,9.79165e-08,1.07412,0.000423172,-4.24451e-08,-5.56118e-08,1.07455,0.00042292,-2.09281e-07,5.32143e-09,1.07497,0.000422518,-1.93316e-07,3.43261e-08,1.07539,0.000422234,-9.0338e-08,-2.34165e-08,1.07581,0.000421983,-1.60588e-07,-5.98692e-08,1.07623,0.000421482,-3.40195e-07,1.43684e-07,1.07666,0.000421233,9.08574e-08,-1.5724e-07,1.07708,0.000420943,-3.80862e-07,1.27647e-07,1.0775,0.000420564,2.0791e-09,-1.1493e-07,1.07792,0.000420223,-3.4271e-07,9.36534e-08,1.07834,0.000419819,-6.17499e-08,-2.12653e-08,1.07876,0.000419632,-1.25546e-07,-8.59219e-09,1.07918,0.000419355,-1.51322e-07,-6.35752e-08,1.0796,0.000418861,-3.42048e-07,1.43684e-07,1.08002,0.000418608,8.90034e-08,-1.53532e-07,1.08043,0.000418326,-3.71593e-07,1.12817e-07,1.08085,0.000417921,-3.31414e-08,-5.93184e-08,1.08127,0.000417677,-2.11097e-07,5.24697e-09,1.08169,0.00041727,-1.95356e-07,3.83305e-08,1.0821,0.000416995,-8.03642e-08,-3.93597e-08,1.08252,0.000416716,-1.98443e-07,-1.0094e-10,1.08294,0.000416319,-1.98746e-07,3.97635e-08,1.08335,0.00041604,-7.94557e-08,-3.97437e-08,1.08377,0.000415762,-1.98687e-07,1.94215e-12,1.08419,0.000415365,-1.98681e-07,3.97359e-08,1.0846,0.000415087,-7.94732e-08,-3.97362e-08,1.08502,0.000414809,-1.98682e-07,-4.31063e-13,1.08543,0.000414411,-1.98683e-07,3.97379e-08,1.08584,0.000414133,-7.94694e-08,-3.97418e-08,1.08626,0.000413855,-1.98695e-07,2.00563e-11,1.08667,0.000413458,-1.98635e-07,3.96616e-08,1.08709,0.000413179,-7.965e-08,-3.9457e-08,1.0875,0.000412902,-1.98021e-07,-1.04281e-09,1.08791,0.000412502,-2.01149e-07,4.36282e-08,1.08832,0.000412231,-7.02648e-08,-5.42608e-08,1.08874,0.000411928,-2.33047e-07,5.42057e-08,1.08915,0.000411624,-7.04301e-08,-4.33527e-08,1.08956,0.000411353,-2.00488e-07,-4.07378e-12,1.08997,0.000410952,-2.005e-07,4.3369e-08,1.09038,0.000410681,-7.03934e-08,-5.42627e-08,1.09079,0.000410378,-2.33182e-07,5.44726e-08,1.0912,0.000410075,-6.97637e-08,-4.44186e-08,1.09161,0.000409802,-2.03019e-07,3.99235e-09,1.09202,0.000409408,-1.91042e-07,2.84491e-08,1.09243,0.000409111,-1.05695e-07,1.42043e-09,1.09284,0.000408904,-1.01434e-07,-3.41308e-08,1.09325,0.000408599,-2.03826e-07,1.58937e-08,1.09366,0.000408239,-1.56145e-07,-2.94438e-08,1.09406,0.000407838,-2.44476e-07,1.01881e-07,1.09447,0.000407655,6.11676e-08,-1.39663e-07,1.09488,0.000407358,-3.57822e-07,9.91432e-08,1.09529,0.00040694,-6.03921e-08,-1.84912e-08,1.09569,0.000406764,-1.15866e-07,-2.51785e-08,1.0961,0.000406457,-1.91401e-07,-4.03115e-12,1.09651,0.000406074,-1.91413e-07,2.51947e-08,1.09691,0.000405767,-1.15829e-07,1.84346e-08,1.09732,0.00040559,-6.05254e-08,-9.89332e-08,1.09772,0.000405172,-3.57325e-07,1.3888e-07,1.09813,0.000404874,5.93136e-08,-9.8957e-08,1.09853,0.000404696,-2.37557e-07,1.853e-08,1.09894,0.000404277,-1.81968e-07,2.48372e-08,1.09934,0.000403987,-1.07456e-07,1.33047e-09,1.09975,0.000403776,-1.03465e-07,-3.01591e-08,1.10015,0.000403479,-1.93942e-07,9.66054e-11,1.10055,0.000403091,-1.93652e-07,2.97727e-08,1.10096,0.000402793,-1.04334e-07,2.19273e-11,1.10136,0.000402585,-1.04268e-07,-2.98604e-08,1.10176,0.000402287,-1.93849e-07,2.10325e-10,1.10216,0.0004019,-1.93218e-07,2.90191e-08,1.10256,0.0004016,-1.06161e-07,2.92264e-09,1.10297,0.000401397,-9.73931e-08,-4.07096e-08,1.10337,0.00040108,-2.19522e-07,4.07067e-08,1.10377,0.000400763,-9.7402e-08,-2.90783e-09,1.10417,0.000400559,-1.06126e-07,-2.90754e-08,1.10457,0.00040026,-1.93352e-07,9.00021e-14,1.10497,0.000399873,-1.93351e-07,2.9075e-08,1.10537,0.000399574,-1.06126e-07,2.90902e-09,1.10577,0.00039937,-9.73992e-08,-4.07111e-08,1.10617,0.000399053,-2.19533e-07,4.07262e-08,1.10657,0.000398736,-9.73541e-08,-2.98424e-09,1.10697,0.000398533,-1.06307e-07,-2.87892e-08,1.10736,0.000398234,-1.92674e-07,-1.06824e-09,1.10776,0.000397845,-1.95879e-07,3.30622e-08,1.10816,0.000397552,-9.66926e-08,-1.19712e-08,1.10856,0.000397323,-1.32606e-07,1.48225e-08,1.10895,0.000397102,-8.81387e-08,-4.73187e-08,1.10935,0.000396784,-2.30095e-07,5.52429e-08,1.10975,0.00039649,-6.4366e-08,-5.44437e-08,1.11014,0.000396198,-2.27697e-07,4.33226e-08,1.11054,0.000395872,-9.77293e-08,3.62656e-10,1.11094,0.000395678,-9.66414e-08,-4.47732e-08,1.11133,0.00039535,-2.30961e-07,5.95208e-08,1.11173,0.000395067,-5.23985e-08,-7.41008e-08,1.11212,0.00039474,-2.74701e-07,1.17673e-07,1.11252,0.000394543,7.83181e-08,-1.58172e-07,1.11291,0.000394225,-3.96199e-07,1.57389e-07,1.1133,0.000393905,7.59679e-08,-1.13756e-07,1.1137,0.000393716,-2.653e-07,5.92165e-08,1.11409,0.000393363,-8.76507e-08,-3.90074e-09,1.11449,0.000393176,-9.93529e-08,-4.36136e-08,1.11488,0.000392846,-2.30194e-07,5.91457e-08,1.11527,0.000392563,-5.27564e-08,-7.376e-08,1.11566,0.000392237,-2.74037e-07,1.16685e-07,1.11606,0.000392039,7.60189e-08,-1.54562e-07,1.11645,0.000391727,-3.87667e-07,1.43935e-07,1.11684,0.000391384,4.4137e-08,-6.35487e-08,1.11723,0.000391281,-1.46509e-07,-8.94896e-09,1.11762,0.000390961,-1.73356e-07,-1.98647e-08,1.11801,0.000390555,-2.3295e-07,8.8408e-08,1.1184,0.000390354,3.22736e-08,-9.53486e-08,1.11879,0.000390133,-2.53772e-07,5.45677e-08,1.11918,0.000389789,-9.0069e-08,-3.71296e-09,1.11957,0.000389598,-1.01208e-07,-3.97159e-08,1.11996,0.000389276,-2.20355e-07,4.33671e-08,1.12035,0.000388966,-9.02542e-08,-1.45431e-08,1.12074,0.000388741,-1.33883e-07,1.48052e-08,1.12113,0.000388518,-8.94678e-08,-4.46778e-08,1.12152,0.000388205,-2.23501e-07,4.46966e-08,1.12191,0.000387892,-8.94114e-08,-1.48992e-08,1.12229,0.000387669,-1.34109e-07,1.49003e-08,1.12268,0.000387445,-8.94082e-08,-4.47019e-08,1.12307,0.000387132,-2.23514e-07,4.4698e-08,1.12345,0.000386819,-8.942e-08,-1.48806e-08,1.12384,0.000386596,-1.34062e-07,1.48245e-08,1.12423,0.000386372,-8.95885e-08,-4.44172e-08,1.12461,0.00038606,-2.2284e-07,4.36351e-08,1.125,0.000385745,-9.19348e-08,-1.09139e-08,1.12539,0.000385528,-1.24677e-07,2.05584e-11,1.12577,0.000385279,-1.24615e-07,1.08317e-08,1.12616,0.000385062,-9.21198e-08,-4.33473e-08,1.12654,0.000384748,-2.22162e-07,4.33481e-08,1.12693,0.000384434,-9.21174e-08,-1.08356e-08,1.12731,0.000384217,-1.24624e-07,-5.50907e-12,1.12769,0.000383968,-1.24641e-07,1.08577e-08,1.12808,0.000383751,-9.20679e-08,-4.34252e-08,1.12846,0.000383437,-2.22343e-07,4.36337e-08,1.12884,0.000383123,-9.14422e-08,-1.19005e-08,1.12923,0.000382904,-1.27144e-07,3.96813e-09,1.12961,0.000382662,-1.15239e-07,-3.97207e-09,1.12999,0.000382419,-1.27155e-07,1.19201e-08,1.13038,0.000382201,-9.1395e-08,-4.37085e-08,1.13076,0.000381887,-2.2252e-07,4.37046e-08,1.13114,0.000381573,-9.14068e-08,-1.19005e-08,1.13152,0.000381355,-1.27108e-07,3.89734e-09,1.1319,0.000381112,-1.15416e-07,-3.68887e-09,1.13228,0.00038087,-1.26483e-07,1.08582e-08,1.13266,0.00038065,-9.39083e-08,-3.97438e-08,1.13304,0.000380343,-2.1314e-07,2.89076e-08,1.13342,0.000380003,-1.26417e-07,4.33225e-08,1.1338,0.00037988,3.55072e-09,-8.29883e-08,1.13418,0.000379638,-2.45414e-07,5.0212e-08,1.13456,0.000379298,-9.47781e-08,1.34964e-09,1.13494,0.000379113,-9.07292e-08,-5.56105e-08,1.13532,0.000378764,-2.57561e-07,1.01883e-07,1.1357,0.000378555,4.80889e-08,-1.13504e-07,1.13608,0.000378311,-2.92423e-07,1.13713e-07,1.13646,0.000378067,4.87176e-08,-1.02931e-07,1.13683,0.000377856,-2.60076e-07,5.95923e-08,1.13721,0.000377514,-8.12988e-08,-1.62288e-08,1.13759,0.000377303,-1.29985e-07,5.32278e-09,1.13797,0.000377059,-1.14017e-07,-5.06237e-09,1.13834,0.000376816,-1.29204e-07,1.49267e-08,1.13872,0.000376602,-8.44237e-08,-5.46444e-08,1.1391,0.000376269,-2.48357e-07,8.44417e-08,1.13947,0.000376026,4.96815e-09,-4.47039e-08,1.13985,0.000375902,-1.29143e-07,-2.48355e-08,1.14023,0.000375569,-2.0365e-07,2.48368e-08,1.1406,0.000375236,-1.2914e-07,4.46977e-08,1.14098,0.000375112,4.95341e-09,-8.44184e-08,1.14135,0.000374869,-2.48302e-07,5.45572e-08,1.14173,0.000374536,-8.463e-08,-1.46013e-08,1.1421,0.000374323,-1.28434e-07,3.8478e-09,1.14247,0.000374077,-1.1689e-07,-7.89941e-10,1.14285,0.000373841,-1.1926e-07,-6.88042e-10,1.14322,0.0003736,-1.21324e-07,3.54213e-09,1.1436,0.000373368,-1.10698e-07,-1.34805e-08,1.14397,0.000373107,-1.51139e-07,5.03798e-08,1.14434,0.000372767,0.,0.}; + + template + __device__ __forceinline__ void RGB2LuvConvert_f(const T& src, D& dst) + { + const float _d = 1.f / (0.950456f + 15 + 1.088754f * 3); + const float _un = 13 * (4 * 0.950456f * _d); + const float _vn = 13 * (9 * _d); + + float B = blueIdx == 0 ? src.x : src.z; + float G = src.y; + float R = blueIdx == 0 ? src.z : src.x; + + if (srgb) + { + B = splineInterpolate(B * GAMMA_TAB_SIZE, c_sRGBGammaTab, GAMMA_TAB_SIZE); + G = splineInterpolate(G * GAMMA_TAB_SIZE, c_sRGBGammaTab, GAMMA_TAB_SIZE); + R = splineInterpolate(R * GAMMA_TAB_SIZE, c_sRGBGammaTab, GAMMA_TAB_SIZE); + } + + float X = R * 0.412453f + G * 0.357580f + B * 0.180423f; + float Y = R * 0.212671f + G * 0.715160f + B * 0.072169f; + float Z = R * 0.019334f + G * 0.119193f + B * 0.950227f; + + float L = splineInterpolate(Y * (LAB_CBRT_TAB_SIZE / 1.5f), c_LabCbrtTab, LAB_CBRT_TAB_SIZE); + L = 116.f * L - 16.f; + + const float d = (4 * 13) / ::fmaxf(X + 15 * Y + 3 * Z, numeric_limits::epsilon()); + float u = L * (X * d - _un); + float v = L * ((9 * 0.25f) * Y * d - _vn); + + dst.x = L; + dst.y = u; + dst.z = v; + } + + template + __device__ __forceinline__ void RGB2LuvConvert_b(const T& src, D& dst) + { + float3 srcf, dstf; + + srcf.x = src.x * (1.f / 255.f); + srcf.y = src.y * (1.f / 255.f); + srcf.z = src.z * (1.f / 255.f); + + RGB2LuvConvert_f(srcf, dstf); + + dst.x = saturate_cast(dstf.x * 2.55f); + dst.y = saturate_cast(dstf.y * 0.72033898305084743f + 96.525423728813564f); + dst.z = saturate_cast(dstf.z * 0.9732824427480916f + 136.259541984732824f); + } + + template struct RGB2Luv; + template + struct RGB2Luv + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + RGB2LuvConvert_b(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ RGB2Luv() {} + __host__ __device__ __forceinline__ RGB2Luv(const RGB2Luv&) {} + }; + template + struct RGB2Luv + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + RGB2LuvConvert_f(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ RGB2Luv() {} + __host__ __device__ __forceinline__ RGB2Luv(const RGB2Luv&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_RGB2Luv_TRAITS(name, scn, dcn, srgb, blueIdx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::RGB2Luv functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + namespace color_detail + { + template + __device__ __forceinline__ void Luv2RGBConvert_f(const T& src, D& dst) + { + const float _d = 1.f / (0.950456f + 15 + 1.088754f * 3); + const float _un = 4 * 0.950456f * _d; + const float _vn = 9 * _d; + + float L = src.x; + float u = src.y; + float v = src.z; + + float Y = (L + 16.f) * (1.f / 116.f); + Y = Y * Y * Y; + + float d = (1.f / 13.f) / L; + u = u * d + _un; + v = v * d + _vn; + + float iv = 1.f / v; + float X = 2.25f * u * Y * iv; + float Z = (12 - 3 * u - 20 * v) * Y * 0.25f * iv; + + float B = 0.055648f * X - 0.204043f * Y + 1.057311f * Z; + float G = -0.969256f * X + 1.875991f * Y + 0.041556f * Z; + float R = 3.240479f * X - 1.537150f * Y - 0.498535f * Z; + + if (srgb) + { + B = splineInterpolate(B * GAMMA_TAB_SIZE, c_sRGBInvGammaTab, GAMMA_TAB_SIZE); + G = splineInterpolate(G * GAMMA_TAB_SIZE, c_sRGBInvGammaTab, GAMMA_TAB_SIZE); + R = splineInterpolate(R * GAMMA_TAB_SIZE, c_sRGBInvGammaTab, GAMMA_TAB_SIZE); + } + + dst.x = blueIdx == 0 ? B : R; + dst.y = G; + dst.z = blueIdx == 0 ? R : B; + setAlpha(dst, ColorChannel::max()); + } + + template + __device__ __forceinline__ void Luv2RGBConvert_b(const T& src, D& dst) + { + float3 srcf, dstf; + + srcf.x = src.x * (100.f / 255.f); + srcf.y = src.y * 1.388235294117647f - 134.f; + srcf.z = src.z * 1.027450980392157f - 140.f; + + Luv2RGBConvert_f(srcf, dstf); + + dst.x = saturate_cast(dstf.x * 255.f); + dst.y = saturate_cast(dstf.y * 255.f); + dst.z = saturate_cast(dstf.z * 255.f); + setAlpha(dst, ColorChannel::max()); + } + + template struct Luv2RGB; + template + struct Luv2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + Luv2RGBConvert_b(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ Luv2RGB() {} + __host__ __device__ __forceinline__ Luv2RGB(const Luv2RGB&) {} + }; + template + struct Luv2RGB + : unary_function::vec_type, typename TypeVec::vec_type> + { + __device__ __forceinline__ typename TypeVec::vec_type operator ()(const typename TypeVec::vec_type& src) const + { + typename TypeVec::vec_type dst; + + Luv2RGBConvert_f(src, dst); + + return dst; + } + __host__ __device__ __forceinline__ Luv2RGB() {} + __host__ __device__ __forceinline__ Luv2RGB(const Luv2RGB&) {} + }; + } + +#define OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(name, scn, dcn, srgb, blueIdx) \ + template struct name ## _traits \ + { \ + typedef ::cv::cuda::device::color_detail::Luv2RGB functor_type; \ + static __host__ __device__ __forceinline__ functor_type create_functor() \ + { \ + return functor_type(); \ + } \ + }; + + #undef CV_DESCALE + +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_COLOR_DETAIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce.hpp new file mode 100755 index 0000000..8af20b0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce.hpp @@ -0,0 +1,365 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_REDUCE_DETAIL_HPP +#define OPENCV_CUDA_REDUCE_DETAIL_HPP + +#include +#include "../warp.hpp" +#include "../warp_shuffle.hpp" + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + namespace reduce_detail + { + template struct GetType; + template struct GetType + { + typedef T type; + }; + template struct GetType + { + typedef T type; + }; + template struct GetType + { + typedef T type; + }; + + template + struct For + { + template + static __device__ void loadToSmem(const PointerTuple& smem, const ValTuple& val, unsigned int tid) + { + thrust::get(smem)[tid] = thrust::get(val); + + For::loadToSmem(smem, val, tid); + } + template + static __device__ void loadFromSmem(const PointerTuple& smem, const ValTuple& val, unsigned int tid) + { + thrust::get(val) = thrust::get(smem)[tid]; + + For::loadFromSmem(smem, val, tid); + } + + template + static __device__ void merge(const PointerTuple& smem, const ValTuple& val, unsigned int tid, unsigned int delta, const OpTuple& op) + { + typename GetType::type>::type reg = thrust::get(smem)[tid + delta]; + thrust::get(smem)[tid] = thrust::get(val) = thrust::get(op)(thrust::get(val), reg); + + For::merge(smem, val, tid, delta, op); + } + template + static __device__ void mergeShfl(const ValTuple& val, unsigned int delta, unsigned int width, const OpTuple& op) + { + typename GetType::type>::type reg = shfl_down(thrust::get(val), delta, width); + thrust::get(val) = thrust::get(op)(thrust::get(val), reg); + + For::mergeShfl(val, delta, width, op); + } + }; + template + struct For + { + template + static __device__ void loadToSmem(const PointerTuple&, const ValTuple&, unsigned int) + { + } + template + static __device__ void loadFromSmem(const PointerTuple&, const ValTuple&, unsigned int) + { + } + + template + static __device__ void merge(const PointerTuple&, const ValTuple&, unsigned int, unsigned int, const OpTuple&) + { + } + template + static __device__ void mergeShfl(const ValTuple&, unsigned int, unsigned int, const OpTuple&) + { + } + }; + + template + __device__ __forceinline__ void loadToSmem(volatile T* smem, T& val, unsigned int tid) + { + smem[tid] = val; + } + template + __device__ __forceinline__ void loadFromSmem(volatile T* smem, T& val, unsigned int tid) + { + val = smem[tid]; + } + template + __device__ __forceinline__ void loadToSmem(const thrust::tuple& smem, + const thrust::tuple& val, + unsigned int tid) + { + For<0, thrust::tuple_size >::value>::loadToSmem(smem, val, tid); + } + template + __device__ __forceinline__ void loadFromSmem(const thrust::tuple& smem, + const thrust::tuple& val, + unsigned int tid) + { + For<0, thrust::tuple_size >::value>::loadFromSmem(smem, val, tid); + } + + template + __device__ __forceinline__ void merge(volatile T* smem, T& val, unsigned int tid, unsigned int delta, const Op& op) + { + T reg = smem[tid + delta]; + smem[tid] = val = op(val, reg); + } + template + __device__ __forceinline__ void mergeShfl(T& val, unsigned int delta, unsigned int width, const Op& op) + { + T reg = shfl_down(val, delta, width); + val = op(val, reg); + } + template + __device__ __forceinline__ void merge(const thrust::tuple& smem, + const thrust::tuple& val, + unsigned int tid, + unsigned int delta, + const thrust::tuple& op) + { + For<0, thrust::tuple_size >::value>::merge(smem, val, tid, delta, op); + } + template + __device__ __forceinline__ void mergeShfl(const thrust::tuple& val, + unsigned int delta, + unsigned int width, + const thrust::tuple& op) + { + For<0, thrust::tuple_size >::value>::mergeShfl(val, delta, width, op); + } + + template struct Generic + { + template + static __device__ void reduce(Pointer smem, Reference val, unsigned int tid, Op op) + { + loadToSmem(smem, val, tid); + if (N >= 32) + __syncthreads(); + + if (N >= 2048) + { + if (tid < 1024) + merge(smem, val, tid, 1024, op); + + __syncthreads(); + } + if (N >= 1024) + { + if (tid < 512) + merge(smem, val, tid, 512, op); + + __syncthreads(); + } + if (N >= 512) + { + if (tid < 256) + merge(smem, val, tid, 256, op); + + __syncthreads(); + } + if (N >= 256) + { + if (tid < 128) + merge(smem, val, tid, 128, op); + + __syncthreads(); + } + if (N >= 128) + { + if (tid < 64) + merge(smem, val, tid, 64, op); + + __syncthreads(); + } + if (N >= 64) + { + if (tid < 32) + merge(smem, val, tid, 32, op); + } + + if (tid < 16) + { + merge(smem, val, tid, 16, op); + merge(smem, val, tid, 8, op); + merge(smem, val, tid, 4, op); + merge(smem, val, tid, 2, op); + merge(smem, val, tid, 1, op); + } + } + }; + + template + struct Unroll + { + static __device__ void loopShfl(Reference val, Op op, unsigned int N) + { + mergeShfl(val, I, N, op); + Unroll::loopShfl(val, op, N); + } + static __device__ void loop(Pointer smem, Reference val, unsigned int tid, Op op) + { + merge(smem, val, tid, I, op); + Unroll::loop(smem, val, tid, op); + } + }; + template + struct Unroll<0, Pointer, Reference, Op> + { + static __device__ void loopShfl(Reference, Op, unsigned int) + { + } + static __device__ void loop(Pointer, Reference, unsigned int, Op) + { + } + }; + + template struct WarpOptimized + { + template + static __device__ void reduce(Pointer smem, Reference val, unsigned int tid, Op op) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + CV_UNUSED(smem); + CV_UNUSED(tid); + + Unroll::loopShfl(val, op, N); + #else + loadToSmem(smem, val, tid); + + if (tid < N / 2) + Unroll::loop(smem, val, tid, op); + #endif + } + }; + + template struct GenericOptimized32 + { + enum { M = N / 32 }; + + template + static __device__ void reduce(Pointer smem, Reference val, unsigned int tid, Op op) + { + const unsigned int laneId = Warp::laneId(); + + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + Unroll<16, Pointer, Reference, Op>::loopShfl(val, op, warpSize); + + if (laneId == 0) + loadToSmem(smem, val, tid / 32); + #else + loadToSmem(smem, val, tid); + + if (laneId < 16) + Unroll<16, Pointer, Reference, Op>::loop(smem, val, tid, op); + + __syncthreads(); + + if (laneId == 0) + loadToSmem(smem, val, tid / 32); + #endif + + __syncthreads(); + + loadFromSmem(smem, val, tid); + + if (tid < 32) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + Unroll::loopShfl(val, op, M); + #else + Unroll::loop(smem, val, tid, op); + #endif + } + } + }; + + template struct StaticIf; + template struct StaticIf + { + typedef T1 type; + }; + template struct StaticIf + { + typedef T2 type; + }; + + template struct IsPowerOf2 + { + enum { value = ((N != 0) && !(N & (N - 1))) }; + }; + + template struct Dispatcher + { + typedef typename StaticIf< + (N <= 32) && IsPowerOf2::value, + WarpOptimized, + typename StaticIf< + (N <= 1024) && IsPowerOf2::value, + GenericOptimized32, + Generic + >::type + >::type reductor; + }; + } +}}} + +//! @endcond + +#endif // OPENCV_CUDA_REDUCE_DETAIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp new file mode 100755 index 0000000..df37c17 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp @@ -0,0 +1,502 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_PRED_VAL_REDUCE_DETAIL_HPP +#define OPENCV_CUDA_PRED_VAL_REDUCE_DETAIL_HPP + +#include +#include "../warp.hpp" +#include "../warp_shuffle.hpp" + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + namespace reduce_key_val_detail + { + template struct GetType; + template struct GetType + { + typedef T type; + }; + template struct GetType + { + typedef T type; + }; + template struct GetType + { + typedef T type; + }; + + template + struct For + { + template + static __device__ void loadToSmem(const PointerTuple& smem, const ReferenceTuple& data, unsigned int tid) + { + thrust::get(smem)[tid] = thrust::get(data); + + For::loadToSmem(smem, data, tid); + } + template + static __device__ void loadFromSmem(const PointerTuple& smem, const ReferenceTuple& data, unsigned int tid) + { + thrust::get(data) = thrust::get(smem)[tid]; + + For::loadFromSmem(smem, data, tid); + } + + template + static __device__ void copyShfl(const ReferenceTuple& val, unsigned int delta, int width) + { + thrust::get(val) = shfl_down(thrust::get(val), delta, width); + + For::copyShfl(val, delta, width); + } + template + static __device__ void copy(const PointerTuple& svals, const ReferenceTuple& val, unsigned int tid, unsigned int delta) + { + thrust::get(svals)[tid] = thrust::get(val) = thrust::get(svals)[tid + delta]; + + For::copy(svals, val, tid, delta); + } + + template + static __device__ void mergeShfl(const KeyReferenceTuple& key, const ValReferenceTuple& val, const CmpTuple& cmp, unsigned int delta, int width) + { + typename GetType::type>::type reg = shfl_down(thrust::get(key), delta, width); + + if (thrust::get(cmp)(reg, thrust::get(key))) + { + thrust::get(key) = reg; + thrust::get(val) = shfl_down(thrust::get(val), delta, width); + } + + For::mergeShfl(key, val, cmp, delta, width); + } + template + static __device__ void merge(const KeyPointerTuple& skeys, const KeyReferenceTuple& key, + const ValPointerTuple& svals, const ValReferenceTuple& val, + const CmpTuple& cmp, + unsigned int tid, unsigned int delta) + { + typename GetType::type>::type reg = thrust::get(skeys)[tid + delta]; + + if (thrust::get(cmp)(reg, thrust::get(key))) + { + thrust::get(skeys)[tid] = thrust::get(key) = reg; + thrust::get(svals)[tid] = thrust::get(val) = thrust::get(svals)[tid + delta]; + } + + For::merge(skeys, key, svals, val, cmp, tid, delta); + } + }; + template + struct For + { + template + static __device__ void loadToSmem(const PointerTuple&, const ReferenceTuple&, unsigned int) + { + } + template + static __device__ void loadFromSmem(const PointerTuple&, const ReferenceTuple&, unsigned int) + { + } + + template + static __device__ void copyShfl(const ReferenceTuple&, unsigned int, int) + { + } + template + static __device__ void copy(const PointerTuple&, const ReferenceTuple&, unsigned int, unsigned int) + { + } + + template + static __device__ void mergeShfl(const KeyReferenceTuple&, const ValReferenceTuple&, const CmpTuple&, unsigned int, int) + { + } + template + static __device__ void merge(const KeyPointerTuple&, const KeyReferenceTuple&, + const ValPointerTuple&, const ValReferenceTuple&, + const CmpTuple&, + unsigned int, unsigned int) + { + } + }; + + ////////////////////////////////////////////////////// + // loadToSmem + + template + __device__ __forceinline__ void loadToSmem(volatile T* smem, T& data, unsigned int tid) + { + smem[tid] = data; + } + template + __device__ __forceinline__ void loadFromSmem(volatile T* smem, T& data, unsigned int tid) + { + data = smem[tid]; + } + template + __device__ __forceinline__ void loadToSmem(const thrust::tuple& smem, + const thrust::tuple& data, + unsigned int tid) + { + For<0, thrust::tuple_size >::value>::loadToSmem(smem, data, tid); + } + template + __device__ __forceinline__ void loadFromSmem(const thrust::tuple& smem, + const thrust::tuple& data, + unsigned int tid) + { + For<0, thrust::tuple_size >::value>::loadFromSmem(smem, data, tid); + } + + ////////////////////////////////////////////////////// + // copyVals + + template + __device__ __forceinline__ void copyValsShfl(V& val, unsigned int delta, int width) + { + val = shfl_down(val, delta, width); + } + template + __device__ __forceinline__ void copyVals(volatile V* svals, V& val, unsigned int tid, unsigned int delta) + { + svals[tid] = val = svals[tid + delta]; + } + template + __device__ __forceinline__ void copyValsShfl(const thrust::tuple& val, + unsigned int delta, + int width) + { + For<0, thrust::tuple_size >::value>::copyShfl(val, delta, width); + } + template + __device__ __forceinline__ void copyVals(const thrust::tuple& svals, + const thrust::tuple& val, + unsigned int tid, unsigned int delta) + { + For<0, thrust::tuple_size >::value>::copy(svals, val, tid, delta); + } + + ////////////////////////////////////////////////////// + // merge + + template + __device__ __forceinline__ void mergeShfl(K& key, V& val, const Cmp& cmp, unsigned int delta, int width) + { + K reg = shfl_down(key, delta, width); + + if (cmp(reg, key)) + { + key = reg; + copyValsShfl(val, delta, width); + } + } + template + __device__ __forceinline__ void merge(volatile K* skeys, K& key, volatile V* svals, V& val, const Cmp& cmp, unsigned int tid, unsigned int delta) + { + K reg = skeys[tid + delta]; + + if (cmp(reg, key)) + { + skeys[tid] = key = reg; + copyVals(svals, val, tid, delta); + } + } + template + __device__ __forceinline__ void mergeShfl(K& key, + const thrust::tuple& val, + const Cmp& cmp, + unsigned int delta, int width) + { + K reg = shfl_down(key, delta, width); + + if (cmp(reg, key)) + { + key = reg; + copyValsShfl(val, delta, width); + } + } + template + __device__ __forceinline__ void merge(volatile K* skeys, K& key, + const thrust::tuple& svals, + const thrust::tuple& val, + const Cmp& cmp, unsigned int tid, unsigned int delta) + { + K reg = skeys[tid + delta]; + + if (cmp(reg, key)) + { + skeys[tid] = key = reg; + copyVals(svals, val, tid, delta); + } + } + template + __device__ __forceinline__ void mergeShfl(const thrust::tuple& key, + const thrust::tuple& val, + const thrust::tuple& cmp, + unsigned int delta, int width) + { + For<0, thrust::tuple_size >::value>::mergeShfl(key, val, cmp, delta, width); + } + template + __device__ __forceinline__ void merge(const thrust::tuple& skeys, + const thrust::tuple& key, + const thrust::tuple& svals, + const thrust::tuple& val, + const thrust::tuple& cmp, + unsigned int tid, unsigned int delta) + { + For<0, thrust::tuple_size >::value>::merge(skeys, key, svals, val, cmp, tid, delta); + } + + ////////////////////////////////////////////////////// + // Generic + + template struct Generic + { + template + static __device__ void reduce(KP skeys, KR key, VP svals, VR val, unsigned int tid, Cmp cmp) + { + loadToSmem(skeys, key, tid); + loadValsToSmem(svals, val, tid); + if (N >= 32) + __syncthreads(); + + if (N >= 2048) + { + if (tid < 1024) + merge(skeys, key, svals, val, cmp, tid, 1024); + + __syncthreads(); + } + if (N >= 1024) + { + if (tid < 512) + merge(skeys, key, svals, val, cmp, tid, 512); + + __syncthreads(); + } + if (N >= 512) + { + if (tid < 256) + merge(skeys, key, svals, val, cmp, tid, 256); + + __syncthreads(); + } + if (N >= 256) + { + if (tid < 128) + merge(skeys, key, svals, val, cmp, tid, 128); + + __syncthreads(); + } + if (N >= 128) + { + if (tid < 64) + merge(skeys, key, svals, val, cmp, tid, 64); + + __syncthreads(); + } + if (N >= 64) + { + if (tid < 32) + merge(skeys, key, svals, val, cmp, tid, 32); + } + + if (tid < 16) + { + merge(skeys, key, svals, val, cmp, tid, 16); + merge(skeys, key, svals, val, cmp, tid, 8); + merge(skeys, key, svals, val, cmp, tid, 4); + merge(skeys, key, svals, val, cmp, tid, 2); + merge(skeys, key, svals, val, cmp, tid, 1); + } + } + }; + + template + struct Unroll + { + static __device__ void loopShfl(KR key, VR val, Cmp cmp, unsigned int N) + { + mergeShfl(key, val, cmp, I, N); + Unroll::loopShfl(key, val, cmp, N); + } + static __device__ void loop(KP skeys, KR key, VP svals, VR val, unsigned int tid, Cmp cmp) + { + merge(skeys, key, svals, val, cmp, tid, I); + Unroll::loop(skeys, key, svals, val, tid, cmp); + } + }; + template + struct Unroll<0, KP, KR, VP, VR, Cmp> + { + static __device__ void loopShfl(KR, VR, Cmp, unsigned int) + { + } + static __device__ void loop(KP, KR, VP, VR, unsigned int, Cmp) + { + } + }; + + template struct WarpOptimized + { + template + static __device__ void reduce(KP skeys, KR key, VP svals, VR val, unsigned int tid, Cmp cmp) + { + #if 0 // __CUDA_ARCH__ >= 300 + CV_UNUSED(skeys); + CV_UNUSED(svals); + CV_UNUSED(tid); + + Unroll::loopShfl(key, val, cmp, N); + #else + loadToSmem(skeys, key, tid); + loadToSmem(svals, val, tid); + + if (tid < N / 2) + Unroll::loop(skeys, key, svals, val, tid, cmp); + #endif + } + }; + + template struct GenericOptimized32 + { + enum { M = N / 32 }; + + template + static __device__ void reduce(KP skeys, KR key, VP svals, VR val, unsigned int tid, Cmp cmp) + { + const unsigned int laneId = Warp::laneId(); + + #if 0 // __CUDA_ARCH__ >= 300 + Unroll<16, KP, KR, VP, VR, Cmp>::loopShfl(key, val, cmp, warpSize); + + if (laneId == 0) + { + loadToSmem(skeys, key, tid / 32); + loadToSmem(svals, val, tid / 32); + } + #else + loadToSmem(skeys, key, tid); + loadToSmem(svals, val, tid); + + if (laneId < 16) + Unroll<16, KP, KR, VP, VR, Cmp>::loop(skeys, key, svals, val, tid, cmp); + + __syncthreads(); + + if (laneId == 0) + { + loadToSmem(skeys, key, tid / 32); + loadToSmem(svals, val, tid / 32); + } + #endif + + __syncthreads(); + + loadFromSmem(skeys, key, tid); + + if (tid < 32) + { + #if 0 // __CUDA_ARCH__ >= 300 + loadFromSmem(svals, val, tid); + + Unroll::loopShfl(key, val, cmp, M); + #else + Unroll::loop(skeys, key, svals, val, tid, cmp); + #endif + } + } + }; + + template struct StaticIf; + template struct StaticIf + { + typedef T1 type; + }; + template struct StaticIf + { + typedef T2 type; + }; + + template struct IsPowerOf2 + { + enum { value = ((N != 0) && !(N & (N - 1))) }; + }; + + template struct Dispatcher + { + typedef typename StaticIf< + (N <= 32) && IsPowerOf2::value, + WarpOptimized, + typename StaticIf< + (N <= 1024) && IsPowerOf2::value, + GenericOptimized32, + Generic + >::type + >::type reductor; + }; + } +}}} + +//! @endcond + +#endif // OPENCV_CUDA_PRED_VAL_REDUCE_DETAIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/transform_detail.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/transform_detail.hpp new file mode 100755 index 0000000..1919848 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/transform_detail.hpp @@ -0,0 +1,392 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_TRANSFORM_DETAIL_HPP +#define OPENCV_CUDA_TRANSFORM_DETAIL_HPP + +#include "../common.hpp" +#include "../vec_traits.hpp" +#include "../functional.hpp" + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + namespace transform_detail + { + //! Read Write Traits + + template struct UnaryReadWriteTraits + { + typedef typename TypeVec::vec_type read_type; + typedef typename TypeVec::vec_type write_type; + }; + + template struct BinaryReadWriteTraits + { + typedef typename TypeVec::vec_type read_type1; + typedef typename TypeVec::vec_type read_type2; + typedef typename TypeVec::vec_type write_type; + }; + + //! Transform kernels + + template struct OpUnroller; + template <> struct OpUnroller<1> + { + template + static __device__ __forceinline__ void unroll(const T& src, D& dst, const Mask& mask, UnOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src.x); + } + + template + static __device__ __forceinline__ void unroll(const T1& src1, const T2& src2, D& dst, const Mask& mask, BinOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src1.x, src2.x); + } + }; + template <> struct OpUnroller<2> + { + template + static __device__ __forceinline__ void unroll(const T& src, D& dst, const Mask& mask, UnOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src.x); + if (mask(y, x_shifted + 1)) + dst.y = op(src.y); + } + + template + static __device__ __forceinline__ void unroll(const T1& src1, const T2& src2, D& dst, const Mask& mask, BinOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src1.x, src2.x); + if (mask(y, x_shifted + 1)) + dst.y = op(src1.y, src2.y); + } + }; + template <> struct OpUnroller<3> + { + template + static __device__ __forceinline__ void unroll(const T& src, D& dst, const Mask& mask, const UnOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src.x); + if (mask(y, x_shifted + 1)) + dst.y = op(src.y); + if (mask(y, x_shifted + 2)) + dst.z = op(src.z); + } + + template + static __device__ __forceinline__ void unroll(const T1& src1, const T2& src2, D& dst, const Mask& mask, const BinOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src1.x, src2.x); + if (mask(y, x_shifted + 1)) + dst.y = op(src1.y, src2.y); + if (mask(y, x_shifted + 2)) + dst.z = op(src1.z, src2.z); + } + }; + template <> struct OpUnroller<4> + { + template + static __device__ __forceinline__ void unroll(const T& src, D& dst, const Mask& mask, const UnOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src.x); + if (mask(y, x_shifted + 1)) + dst.y = op(src.y); + if (mask(y, x_shifted + 2)) + dst.z = op(src.z); + if (mask(y, x_shifted + 3)) + dst.w = op(src.w); + } + + template + static __device__ __forceinline__ void unroll(const T1& src1, const T2& src2, D& dst, const Mask& mask, const BinOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.x = op(src1.x, src2.x); + if (mask(y, x_shifted + 1)) + dst.y = op(src1.y, src2.y); + if (mask(y, x_shifted + 2)) + dst.z = op(src1.z, src2.z); + if (mask(y, x_shifted + 3)) + dst.w = op(src1.w, src2.w); + } + }; + template <> struct OpUnroller<8> + { + template + static __device__ __forceinline__ void unroll(const T& src, D& dst, const Mask& mask, const UnOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.a0 = op(src.a0); + if (mask(y, x_shifted + 1)) + dst.a1 = op(src.a1); + if (mask(y, x_shifted + 2)) + dst.a2 = op(src.a2); + if (mask(y, x_shifted + 3)) + dst.a3 = op(src.a3); + if (mask(y, x_shifted + 4)) + dst.a4 = op(src.a4); + if (mask(y, x_shifted + 5)) + dst.a5 = op(src.a5); + if (mask(y, x_shifted + 6)) + dst.a6 = op(src.a6); + if (mask(y, x_shifted + 7)) + dst.a7 = op(src.a7); + } + + template + static __device__ __forceinline__ void unroll(const T1& src1, const T2& src2, D& dst, const Mask& mask, const BinOp& op, int x_shifted, int y) + { + if (mask(y, x_shifted)) + dst.a0 = op(src1.a0, src2.a0); + if (mask(y, x_shifted + 1)) + dst.a1 = op(src1.a1, src2.a1); + if (mask(y, x_shifted + 2)) + dst.a2 = op(src1.a2, src2.a2); + if (mask(y, x_shifted + 3)) + dst.a3 = op(src1.a3, src2.a3); + if (mask(y, x_shifted + 4)) + dst.a4 = op(src1.a4, src2.a4); + if (mask(y, x_shifted + 5)) + dst.a5 = op(src1.a5, src2.a5); + if (mask(y, x_shifted + 6)) + dst.a6 = op(src1.a6, src2.a6); + if (mask(y, x_shifted + 7)) + dst.a7 = op(src1.a7, src2.a7); + } + }; + + template + static __global__ void transformSmart(const PtrStepSz src_, PtrStep dst_, const Mask mask, const UnOp op) + { + typedef TransformFunctorTraits ft; + typedef typename UnaryReadWriteTraits::read_type read_type; + typedef typename UnaryReadWriteTraits::write_type write_type; + + const int x = threadIdx.x + blockIdx.x * blockDim.x; + const int y = threadIdx.y + blockIdx.y * blockDim.y; + const int x_shifted = x * ft::smart_shift; + + if (y < src_.rows) + { + const T* src = src_.ptr(y); + D* dst = dst_.ptr(y); + + if (x_shifted + ft::smart_shift - 1 < src_.cols) + { + const read_type src_n_el = ((const read_type*)src)[x]; + OpUnroller::unroll(src_n_el, ((write_type*)dst)[x], mask, op, x_shifted, y); + } + else + { + for (int real_x = x_shifted; real_x < src_.cols; ++real_x) + { + if (mask(y, real_x)) + dst[real_x] = op(src[real_x]); + } + } + } + } + + template + __global__ static void transformSimple(const PtrStepSz src, PtrStep dst, const Mask mask, const UnOp op) + { + const int x = blockDim.x * blockIdx.x + threadIdx.x; + const int y = blockDim.y * blockIdx.y + threadIdx.y; + + if (x < src.cols && y < src.rows && mask(y, x)) + { + dst.ptr(y)[x] = op(src.ptr(y)[x]); + } + } + + template + static __global__ void transformSmart(const PtrStepSz src1_, const PtrStep src2_, PtrStep dst_, + const Mask mask, const BinOp op) + { + typedef TransformFunctorTraits ft; + typedef typename BinaryReadWriteTraits::read_type1 read_type1; + typedef typename BinaryReadWriteTraits::read_type2 read_type2; + typedef typename BinaryReadWriteTraits::write_type write_type; + + const int x = threadIdx.x + blockIdx.x * blockDim.x; + const int y = threadIdx.y + blockIdx.y * blockDim.y; + const int x_shifted = x * ft::smart_shift; + + if (y < src1_.rows) + { + const T1* src1 = src1_.ptr(y); + const T2* src2 = src2_.ptr(y); + D* dst = dst_.ptr(y); + + if (x_shifted + ft::smart_shift - 1 < src1_.cols) + { + const read_type1 src1_n_el = ((const read_type1*)src1)[x]; + const read_type2 src2_n_el = ((const read_type2*)src2)[x]; + + OpUnroller::unroll(src1_n_el, src2_n_el, ((write_type*)dst)[x], mask, op, x_shifted, y); + } + else + { + for (int real_x = x_shifted; real_x < src1_.cols; ++real_x) + { + if (mask(y, real_x)) + dst[real_x] = op(src1[real_x], src2[real_x]); + } + } + } + } + + template + static __global__ void transformSimple(const PtrStepSz src1, const PtrStep src2, PtrStep dst, + const Mask mask, const BinOp op) + { + const int x = blockDim.x * blockIdx.x + threadIdx.x; + const int y = blockDim.y * blockIdx.y + threadIdx.y; + + if (x < src1.cols && y < src1.rows && mask(y, x)) + { + const T1 src1_data = src1.ptr(y)[x]; + const T2 src2_data = src2.ptr(y)[x]; + dst.ptr(y)[x] = op(src1_data, src2_data); + } + } + + template struct TransformDispatcher; + template<> struct TransformDispatcher + { + template + static void call(PtrStepSz src, PtrStepSz dst, UnOp op, Mask mask, cudaStream_t stream) + { + typedef TransformFunctorTraits ft; + + const dim3 threads(ft::simple_block_dim_x, ft::simple_block_dim_y, 1); + const dim3 grid(divUp(src.cols, threads.x), divUp(src.rows, threads.y), 1); + + transformSimple<<>>(src, dst, mask, op); + cudaSafeCall( cudaGetLastError() ); + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); + } + + template + static void call(PtrStepSz src1, PtrStepSz src2, PtrStepSz dst, BinOp op, Mask mask, cudaStream_t stream) + { + typedef TransformFunctorTraits ft; + + const dim3 threads(ft::simple_block_dim_x, ft::simple_block_dim_y, 1); + const dim3 grid(divUp(src1.cols, threads.x), divUp(src1.rows, threads.y), 1); + + transformSimple<<>>(src1, src2, dst, mask, op); + cudaSafeCall( cudaGetLastError() ); + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + template<> struct TransformDispatcher + { + template + static void call(PtrStepSz src, PtrStepSz dst, UnOp op, Mask mask, cudaStream_t stream) + { + typedef TransformFunctorTraits ft; + + CV_StaticAssert(ft::smart_shift != 1, ""); + + if (!isAligned(src.data, ft::smart_shift * sizeof(T)) || !isAligned(src.step, ft::smart_shift * sizeof(T)) || + !isAligned(dst.data, ft::smart_shift * sizeof(D)) || !isAligned(dst.step, ft::smart_shift * sizeof(D))) + { + TransformDispatcher::call(src, dst, op, mask, stream); + return; + } + + const dim3 threads(ft::smart_block_dim_x, ft::smart_block_dim_y, 1); + const dim3 grid(divUp(src.cols, threads.x * ft::smart_shift), divUp(src.rows, threads.y), 1); + + transformSmart<<>>(src, dst, mask, op); + cudaSafeCall( cudaGetLastError() ); + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); + } + + template + static void call(PtrStepSz src1, PtrStepSz src2, PtrStepSz dst, BinOp op, Mask mask, cudaStream_t stream) + { + typedef TransformFunctorTraits ft; + + CV_StaticAssert(ft::smart_shift != 1, ""); + + if (!isAligned(src1.data, ft::smart_shift * sizeof(T1)) || !isAligned(src1.step, ft::smart_shift * sizeof(T1)) || + !isAligned(src2.data, ft::smart_shift * sizeof(T2)) || !isAligned(src2.step, ft::smart_shift * sizeof(T2)) || + !isAligned(dst.data, ft::smart_shift * sizeof(D)) || !isAligned(dst.step, ft::smart_shift * sizeof(D))) + { + TransformDispatcher::call(src1, src2, dst, op, mask, stream); + return; + } + + const dim3 threads(ft::smart_block_dim_x, ft::smart_block_dim_y, 1); + const dim3 grid(divUp(src1.cols, threads.x * ft::smart_shift), divUp(src1.rows, threads.y), 1); + + transformSmart<<>>(src1, src2, dst, mask, op); + cudaSafeCall( cudaGetLastError() ); + + if (stream == 0) + cudaSafeCall( cudaDeviceSynchronize() ); + } + }; + } // namespace transform_detail +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_TRANSFORM_DETAIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp new file mode 100755 index 0000000..a78bd2c --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp @@ -0,0 +1,191 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_TYPE_TRAITS_DETAIL_HPP +#define OPENCV_CUDA_TYPE_TRAITS_DETAIL_HPP + +#include "../common.hpp" +#include "../vec_traits.hpp" + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + namespace type_traits_detail + { + template struct Select { typedef T1 type; }; + template struct Select { typedef T2 type; }; + + template struct IsSignedIntergral { enum {value = 0}; }; + template <> struct IsSignedIntergral { enum {value = 1}; }; + template <> struct IsSignedIntergral { enum {value = 1}; }; + template <> struct IsSignedIntergral { enum {value = 1}; }; + template <> struct IsSignedIntergral { enum {value = 1}; }; + template <> struct IsSignedIntergral { enum {value = 1}; }; + template <> struct IsSignedIntergral { enum {value = 1}; }; + + template struct IsUnsignedIntegral { enum {value = 0}; }; + template <> struct IsUnsignedIntegral { enum {value = 1}; }; + template <> struct IsUnsignedIntegral { enum {value = 1}; }; + template <> struct IsUnsignedIntegral { enum {value = 1}; }; + template <> struct IsUnsignedIntegral { enum {value = 1}; }; + template <> struct IsUnsignedIntegral { enum {value = 1}; }; + template <> struct IsUnsignedIntegral { enum {value = 1}; }; + + template struct IsIntegral { enum {value = IsSignedIntergral::value || IsUnsignedIntegral::value}; }; + template <> struct IsIntegral { enum {value = 1}; }; + template <> struct IsIntegral { enum {value = 1}; }; + + template struct IsFloat { enum {value = 0}; }; + template <> struct IsFloat { enum {value = 1}; }; + template <> struct IsFloat { enum {value = 1}; }; + + template struct IsVec { enum {value = 0}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + template <> struct IsVec { enum {value = 1}; }; + + template struct AddParameterType { typedef const U& type; }; + template struct AddParameterType { typedef U& type; }; + template <> struct AddParameterType { typedef void type; }; + + template struct ReferenceTraits + { + enum { value = false }; + typedef U type; + }; + template struct ReferenceTraits + { + enum { value = true }; + typedef U type; + }; + + template struct PointerTraits + { + enum { value = false }; + typedef void type; + }; + template struct PointerTraits + { + enum { value = true }; + typedef U type; + }; + template struct PointerTraits + { + enum { value = true }; + typedef U type; + }; + + template struct UnConst + { + typedef U type; + enum { value = 0 }; + }; + template struct UnConst + { + typedef U type; + enum { value = 1 }; + }; + template struct UnConst + { + typedef U& type; + enum { value = 1 }; + }; + + template struct UnVolatile + { + typedef U type; + enum { value = 0 }; + }; + template struct UnVolatile + { + typedef U type; + enum { value = 1 }; + }; + template struct UnVolatile + { + typedef U& type; + enum { value = 1 }; + }; + } // namespace type_traits_detail +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_TYPE_TRAITS_DETAIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp new file mode 100755 index 0000000..8283a99 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp @@ -0,0 +1,121 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_VEC_DISTANCE_DETAIL_HPP +#define OPENCV_CUDA_VEC_DISTANCE_DETAIL_HPP + +#include "../datamov_utils.hpp" + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + namespace vec_distance_detail + { + template struct UnrollVecDiffCached + { + template + static __device__ void calcCheck(const T1* vecCached, const T2* vecGlob, int len, Dist& dist, int ind) + { + if (ind < len) + { + T1 val1 = *vecCached++; + + T2 val2; + ForceGlob::Load(vecGlob, ind, val2); + + dist.reduceIter(val1, val2); + + UnrollVecDiffCached::calcCheck(vecCached, vecGlob, len, dist, ind + THREAD_DIM); + } + } + + template + static __device__ void calcWithoutCheck(const T1* vecCached, const T2* vecGlob, Dist& dist) + { + T1 val1 = *vecCached++; + + T2 val2; + ForceGlob::Load(vecGlob, 0, val2); + vecGlob += THREAD_DIM; + + dist.reduceIter(val1, val2); + + UnrollVecDiffCached::calcWithoutCheck(vecCached, vecGlob, dist); + } + }; + template struct UnrollVecDiffCached + { + template + static __device__ __forceinline__ void calcCheck(const T1*, const T2*, int, Dist&, int) + { + } + + template + static __device__ __forceinline__ void calcWithoutCheck(const T1*, const T2*, Dist&) + { + } + }; + + template struct VecDiffCachedCalculator; + template struct VecDiffCachedCalculator + { + template + static __device__ __forceinline__ void calc(const T1* vecCached, const T2* vecGlob, int len, Dist& dist, int tid) + { + UnrollVecDiffCached::calcCheck(vecCached, vecGlob, len, dist, tid); + } + }; + template struct VecDiffCachedCalculator + { + template + static __device__ __forceinline__ void calc(const T1* vecCached, const T2* vecGlob, int len, Dist& dist, int tid) + { + UnrollVecDiffCached::calcWithoutCheck(vecCached, vecGlob + tid, dist); + } + }; + } // namespace vec_distance_detail +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_VEC_DISTANCE_DETAIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/dynamic_smem.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/dynamic_smem.hpp new file mode 100755 index 0000000..42570c6 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/dynamic_smem.hpp @@ -0,0 +1,88 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_DYNAMIC_SMEM_HPP +#define OPENCV_CUDA_DYNAMIC_SMEM_HPP + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template struct DynamicSharedMem + { + __device__ __forceinline__ operator T*() + { + extern __shared__ int __smem[]; + return (T*)__smem; + } + + __device__ __forceinline__ operator const T*() const + { + extern __shared__ int __smem[]; + return (T*)__smem; + } + }; + + // specialize for double to avoid unaligned memory access compile errors + template<> struct DynamicSharedMem + { + __device__ __forceinline__ operator double*() + { + extern __shared__ double __smem_d[]; + return (double*)__smem_d; + } + + __device__ __forceinline__ operator const double*() const + { + extern __shared__ double __smem_d[]; + return (double*)__smem_d; + } + }; +}}} + +//! @endcond + +#endif // OPENCV_CUDA_DYNAMIC_SMEM_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/emulation.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/emulation.hpp new file mode 100755 index 0000000..17dc117 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/emulation.hpp @@ -0,0 +1,269 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_EMULATION_HPP_ +#define OPENCV_CUDA_EMULATION_HPP_ + +#include "common.hpp" +#include "warp_reduce.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + struct Emulation + { + + static __device__ __forceinline__ int syncthreadsOr(int pred) + { +#if defined (__CUDA_ARCH__) && (__CUDA_ARCH__ < 200) + // just campilation stab + return 0; +#else + return __syncthreads_or(pred); +#endif + } + + template + static __forceinline__ __device__ int Ballot(int predicate) + { +#if defined (__CUDA_ARCH__) && (__CUDA_ARCH__ >= 200) + return __ballot(predicate); +#else + __shared__ volatile int cta_buffer[CTA_SIZE]; + + int tid = threadIdx.x; + cta_buffer[tid] = predicate ? (1 << (tid & 31)) : 0; + return warp_reduce(cta_buffer); +#endif + } + + struct smem + { + enum { TAG_MASK = (1U << ( (sizeof(unsigned int) << 3) - 5U)) - 1U }; + + template + static __device__ __forceinline__ T atomicInc(T* address, T val) + { +#if defined (__CUDA_ARCH__) && (__CUDA_ARCH__ < 120) + T count; + unsigned int tag = threadIdx.x << ( (sizeof(unsigned int) << 3) - 5U); + do + { + count = *address & TAG_MASK; + count = tag | (count + 1); + *address = count; + } while (*address != count); + + return (count & TAG_MASK) - 1; +#else + return ::atomicInc(address, val); +#endif + } + + template + static __device__ __forceinline__ T atomicAdd(T* address, T val) + { +#if defined (__CUDA_ARCH__) && (__CUDA_ARCH__ < 120) + T count; + unsigned int tag = threadIdx.x << ( (sizeof(unsigned int) << 3) - 5U); + do + { + count = *address & TAG_MASK; + count = tag | (count + val); + *address = count; + } while (*address != count); + + return (count & TAG_MASK) - val; +#else + return ::atomicAdd(address, val); +#endif + } + + template + static __device__ __forceinline__ T atomicMin(T* address, T val) + { +#if defined (__CUDA_ARCH__) && (__CUDA_ARCH__ < 120) + T count = ::min(*address, val); + do + { + *address = count; + } while (*address > count); + + return count; +#else + return ::atomicMin(address, val); +#endif + } + }; // struct cmem + + struct glob + { + static __device__ __forceinline__ int atomicAdd(int* address, int val) + { + return ::atomicAdd(address, val); + } + static __device__ __forceinline__ unsigned int atomicAdd(unsigned int* address, unsigned int val) + { + return ::atomicAdd(address, val); + } + static __device__ __forceinline__ float atomicAdd(float* address, float val) + { + #if __CUDA_ARCH__ >= 200 + return ::atomicAdd(address, val); + #else + int* address_as_i = (int*) address; + int old = *address_as_i, assumed; + do { + assumed = old; + old = ::atomicCAS(address_as_i, assumed, + __float_as_int(val + __int_as_float(assumed))); + } while (assumed != old); + return __int_as_float(old); + #endif + } + static __device__ __forceinline__ double atomicAdd(double* address, double val) + { + #if __CUDA_ARCH__ >= 130 + unsigned long long int* address_as_ull = (unsigned long long int*) address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = ::atomicCAS(address_as_ull, assumed, + __double_as_longlong(val + __longlong_as_double(assumed))); + } while (assumed != old); + return __longlong_as_double(old); + #else + CV_UNUSED(address); + CV_UNUSED(val); + return 0.0; + #endif + } + + static __device__ __forceinline__ int atomicMin(int* address, int val) + { + return ::atomicMin(address, val); + } + static __device__ __forceinline__ float atomicMin(float* address, float val) + { + #if __CUDA_ARCH__ >= 120 + int* address_as_i = (int*) address; + int old = *address_as_i, assumed; + do { + assumed = old; + old = ::atomicCAS(address_as_i, assumed, + __float_as_int(::fminf(val, __int_as_float(assumed)))); + } while (assumed != old); + return __int_as_float(old); + #else + CV_UNUSED(address); + CV_UNUSED(val); + return 0.0f; + #endif + } + static __device__ __forceinline__ double atomicMin(double* address, double val) + { + #if __CUDA_ARCH__ >= 130 + unsigned long long int* address_as_ull = (unsigned long long int*) address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = ::atomicCAS(address_as_ull, assumed, + __double_as_longlong(::fmin(val, __longlong_as_double(assumed)))); + } while (assumed != old); + return __longlong_as_double(old); + #else + CV_UNUSED(address); + CV_UNUSED(val); + return 0.0; + #endif + } + + static __device__ __forceinline__ int atomicMax(int* address, int val) + { + return ::atomicMax(address, val); + } + static __device__ __forceinline__ float atomicMax(float* address, float val) + { + #if __CUDA_ARCH__ >= 120 + int* address_as_i = (int*) address; + int old = *address_as_i, assumed; + do { + assumed = old; + old = ::atomicCAS(address_as_i, assumed, + __float_as_int(::fmaxf(val, __int_as_float(assumed)))); + } while (assumed != old); + return __int_as_float(old); + #else + CV_UNUSED(address); + CV_UNUSED(val); + return 0.0f; + #endif + } + static __device__ __forceinline__ double atomicMax(double* address, double val) + { + #if __CUDA_ARCH__ >= 130 + unsigned long long int* address_as_ull = (unsigned long long int*) address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = ::atomicCAS(address_as_ull, assumed, + __double_as_longlong(::fmax(val, __longlong_as_double(assumed)))); + } while (assumed != old); + return __longlong_as_double(old); + #else + CV_UNUSED(address); + CV_UNUSED(val); + return 0.0; + #endif + } + }; + }; //struct Emulation +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif /* OPENCV_CUDA_EMULATION_HPP_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/filters.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/filters.hpp new file mode 100755 index 0000000..bb94212 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/filters.hpp @@ -0,0 +1,286 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_FILTERS_HPP +#define OPENCV_CUDA_FILTERS_HPP + +#include "saturate_cast.hpp" +#include "vec_traits.hpp" +#include "vec_math.hpp" +#include "type_traits.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template struct PointFilter + { + typedef typename Ptr2D::elem_type elem_type; + typedef float index_type; + + explicit __host__ __device__ __forceinline__ PointFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f) + : src(src_) + { + CV_UNUSED(fx); + CV_UNUSED(fy); + } + + __device__ __forceinline__ elem_type operator ()(float y, float x) const + { + return src(__float2int_rz(y), __float2int_rz(x)); + } + + Ptr2D src; + }; + + template struct LinearFilter + { + typedef typename Ptr2D::elem_type elem_type; + typedef float index_type; + + explicit __host__ __device__ __forceinline__ LinearFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f) + : src(src_) + { + CV_UNUSED(fx); + CV_UNUSED(fy); + } + __device__ __forceinline__ elem_type operator ()(float y, float x) const + { + typedef typename TypeVec::cn>::vec_type work_type; + + work_type out = VecTraits::all(0); + + const int x1 = __float2int_rd(x); + const int y1 = __float2int_rd(y); + const int x2 = x1 + 1; + const int y2 = y1 + 1; + + elem_type src_reg = src(y1, x1); + out = out + src_reg * ((x2 - x) * (y2 - y)); + + src_reg = src(y1, x2); + out = out + src_reg * ((x - x1) * (y2 - y)); + + src_reg = src(y2, x1); + out = out + src_reg * ((x2 - x) * (y - y1)); + + src_reg = src(y2, x2); + out = out + src_reg * ((x - x1) * (y - y1)); + + return saturate_cast(out); + } + + Ptr2D src; + }; + + template struct CubicFilter + { + typedef typename Ptr2D::elem_type elem_type; + typedef float index_type; + typedef typename TypeVec::cn>::vec_type work_type; + + explicit __host__ __device__ __forceinline__ CubicFilter(const Ptr2D& src_, float fx = 0.f, float fy = 0.f) + : src(src_) + { + CV_UNUSED(fx); + CV_UNUSED(fy); + } + + static __device__ __forceinline__ float bicubicCoeff(float x_) + { + float x = fabsf(x_); + if (x <= 1.0f) + { + return x * x * (1.5f * x - 2.5f) + 1.0f; + } + else if (x < 2.0f) + { + return x * (x * (-0.5f * x + 2.5f) - 4.0f) + 2.0f; + } + else + { + return 0.0f; + } + } + + __device__ elem_type operator ()(float y, float x) const + { + const float xmin = ::ceilf(x - 2.0f); + const float xmax = ::floorf(x + 2.0f); + + const float ymin = ::ceilf(y - 2.0f); + const float ymax = ::floorf(y + 2.0f); + + work_type sum = VecTraits::all(0); + float wsum = 0.0f; + + for (float cy = ymin; cy <= ymax; cy += 1.0f) + { + for (float cx = xmin; cx <= xmax; cx += 1.0f) + { + const float w = bicubicCoeff(x - cx) * bicubicCoeff(y - cy); + sum = sum + w * src(__float2int_rd(cy), __float2int_rd(cx)); + wsum += w; + } + } + + work_type res = (!wsum)? VecTraits::all(0) : sum / wsum; + + return saturate_cast(res); + } + + Ptr2D src; + }; + // for integer scaling + template struct IntegerAreaFilter + { + typedef typename Ptr2D::elem_type elem_type; + typedef float index_type; + + explicit __host__ __device__ __forceinline__ IntegerAreaFilter(const Ptr2D& src_, float scale_x_, float scale_y_) + : src(src_), scale_x(scale_x_), scale_y(scale_y_), scale(1.f / (scale_x * scale_y)) {} + + __device__ __forceinline__ elem_type operator ()(float y, float x) const + { + float fsx1 = x * scale_x; + float fsx2 = fsx1 + scale_x; + + int sx1 = __float2int_ru(fsx1); + int sx2 = __float2int_rd(fsx2); + + float fsy1 = y * scale_y; + float fsy2 = fsy1 + scale_y; + + int sy1 = __float2int_ru(fsy1); + int sy2 = __float2int_rd(fsy2); + + typedef typename TypeVec::cn>::vec_type work_type; + work_type out = VecTraits::all(0.f); + + for(int dy = sy1; dy < sy2; ++dy) + for(int dx = sx1; dx < sx2; ++dx) + { + out = out + src(dy, dx) * scale; + } + + return saturate_cast(out); + } + + Ptr2D src; + float scale_x, scale_y ,scale; + }; + + template struct AreaFilter + { + typedef typename Ptr2D::elem_type elem_type; + typedef float index_type; + + explicit __host__ __device__ __forceinline__ AreaFilter(const Ptr2D& src_, float scale_x_, float scale_y_) + : src(src_), scale_x(scale_x_), scale_y(scale_y_){} + + __device__ __forceinline__ elem_type operator ()(float y, float x) const + { + float fsx1 = x * scale_x; + float fsx2 = fsx1 + scale_x; + + int sx1 = __float2int_ru(fsx1); + int sx2 = __float2int_rd(fsx2); + + float fsy1 = y * scale_y; + float fsy2 = fsy1 + scale_y; + + int sy1 = __float2int_ru(fsy1); + int sy2 = __float2int_rd(fsy2); + + float scale = 1.f / (fminf(scale_x, src.width - fsx1) * fminf(scale_y, src.height - fsy1)); + + typedef typename TypeVec::cn>::vec_type work_type; + work_type out = VecTraits::all(0.f); + + for (int dy = sy1; dy < sy2; ++dy) + { + for (int dx = sx1; dx < sx2; ++dx) + out = out + src(dy, dx) * scale; + + if (sx1 > fsx1) + out = out + src(dy, (sx1 -1) ) * ((sx1 - fsx1) * scale); + + if (sx2 < fsx2) + out = out + src(dy, sx2) * ((fsx2 -sx2) * scale); + } + + if (sy1 > fsy1) + for (int dx = sx1; dx < sx2; ++dx) + out = out + src( (sy1 - 1) , dx) * ((sy1 -fsy1) * scale); + + if (sy2 < fsy2) + for (int dx = sx1; dx < sx2; ++dx) + out = out + src(sy2, dx) * ((fsy2 -sy2) * scale); + + if ((sy1 > fsy1) && (sx1 > fsx1)) + out = out + src( (sy1 - 1) , (sx1 - 1)) * ((sy1 -fsy1) * (sx1 -fsx1) * scale); + + if ((sy1 > fsy1) && (sx2 < fsx2)) + out = out + src( (sy1 - 1) , sx2) * ((sy1 -fsy1) * (fsx2 -sx2) * scale); + + if ((sy2 < fsy2) && (sx2 < fsx2)) + out = out + src(sy2, sx2) * ((fsy2 -sy2) * (fsx2 -sx2) * scale); + + if ((sy2 < fsy2) && (sx1 > fsx1)) + out = out + src(sy2, (sx1 - 1)) * ((fsy2 -sy2) * (sx1 -fsx1) * scale); + + return saturate_cast(out); + } + + Ptr2D src; + float scale_x, scale_y; + int width, haight; + }; +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_FILTERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/funcattrib.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/funcattrib.hpp new file mode 100755 index 0000000..f582080 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/funcattrib.hpp @@ -0,0 +1,79 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_DEVICE_FUNCATTRIB_HPP +#define OPENCV_CUDA_DEVICE_FUNCATTRIB_HPP + +#include + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template + void printFuncAttrib(Func& func) + { + + cudaFuncAttributes attrs; + cudaFuncGetAttributes(&attrs, func); + + printf("=== Function stats ===\n"); + printf("Name: \n"); + printf("sharedSizeBytes = %d\n", attrs.sharedSizeBytes); + printf("constSizeBytes = %d\n", attrs.constSizeBytes); + printf("localSizeBytes = %d\n", attrs.localSizeBytes); + printf("maxThreadsPerBlock = %d\n", attrs.maxThreadsPerBlock); + printf("numRegs = %d\n", attrs.numRegs); + printf("ptxVersion = %d\n", attrs.ptxVersion); + printf("binaryVersion = %d\n", attrs.binaryVersion); + printf("\n"); + fflush(stdout); + } +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif /* OPENCV_CUDA_DEVICE_FUNCATTRIB_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/functional.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/functional.hpp new file mode 100755 index 0000000..9f53d87 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/functional.hpp @@ -0,0 +1,805 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_FUNCTIONAL_HPP +#define OPENCV_CUDA_FUNCTIONAL_HPP + +#include +#include "saturate_cast.hpp" +#include "vec_traits.hpp" +#include "type_traits.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + // Function Objects + template struct unary_function + { + typedef Argument argument_type; + typedef Result result_type; + }; + template struct binary_function + { + typedef Argument1 first_argument_type; + typedef Argument2 second_argument_type; + typedef Result result_type; + }; + + // Arithmetic Operations + template struct plus : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a + b; + } + __host__ __device__ __forceinline__ plus() {} + __host__ __device__ __forceinline__ plus(const plus&) {} + }; + + template struct minus : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a - b; + } + __host__ __device__ __forceinline__ minus() {} + __host__ __device__ __forceinline__ minus(const minus&) {} + }; + + template struct multiplies : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a * b; + } + __host__ __device__ __forceinline__ multiplies() {} + __host__ __device__ __forceinline__ multiplies(const multiplies&) {} + }; + + template struct divides : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a / b; + } + __host__ __device__ __forceinline__ divides() {} + __host__ __device__ __forceinline__ divides(const divides&) {} + }; + + template struct modulus : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a % b; + } + __host__ __device__ __forceinline__ modulus() {} + __host__ __device__ __forceinline__ modulus(const modulus&) {} + }; + + template struct negate : unary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a) const + { + return -a; + } + __host__ __device__ __forceinline__ negate() {} + __host__ __device__ __forceinline__ negate(const negate&) {} + }; + + // Comparison Operations + template struct equal_to : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a == b; + } + __host__ __device__ __forceinline__ equal_to() {} + __host__ __device__ __forceinline__ equal_to(const equal_to&) {} + }; + + template struct not_equal_to : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a != b; + } + __host__ __device__ __forceinline__ not_equal_to() {} + __host__ __device__ __forceinline__ not_equal_to(const not_equal_to&) {} + }; + + template struct greater : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a > b; + } + __host__ __device__ __forceinline__ greater() {} + __host__ __device__ __forceinline__ greater(const greater&) {} + }; + + template struct less : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a < b; + } + __host__ __device__ __forceinline__ less() {} + __host__ __device__ __forceinline__ less(const less&) {} + }; + + template struct greater_equal : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a >= b; + } + __host__ __device__ __forceinline__ greater_equal() {} + __host__ __device__ __forceinline__ greater_equal(const greater_equal&) {} + }; + + template struct less_equal : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a <= b; + } + __host__ __device__ __forceinline__ less_equal() {} + __host__ __device__ __forceinline__ less_equal(const less_equal&) {} + }; + + // Logical Operations + template struct logical_and : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a && b; + } + __host__ __device__ __forceinline__ logical_and() {} + __host__ __device__ __forceinline__ logical_and(const logical_and&) {} + }; + + template struct logical_or : binary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a || b; + } + __host__ __device__ __forceinline__ logical_or() {} + __host__ __device__ __forceinline__ logical_or(const logical_or&) {} + }; + + template struct logical_not : unary_function + { + __device__ __forceinline__ bool operator ()(typename TypeTraits::ParameterType a) const + { + return !a; + } + __host__ __device__ __forceinline__ logical_not() {} + __host__ __device__ __forceinline__ logical_not(const logical_not&) {} + }; + + // Bitwise Operations + template struct bit_and : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a & b; + } + __host__ __device__ __forceinline__ bit_and() {} + __host__ __device__ __forceinline__ bit_and(const bit_and&) {} + }; + + template struct bit_or : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a | b; + } + __host__ __device__ __forceinline__ bit_or() {} + __host__ __device__ __forceinline__ bit_or(const bit_or&) {} + }; + + template struct bit_xor : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType a, + typename TypeTraits::ParameterType b) const + { + return a ^ b; + } + __host__ __device__ __forceinline__ bit_xor() {} + __host__ __device__ __forceinline__ bit_xor(const bit_xor&) {} + }; + + template struct bit_not : unary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType v) const + { + return ~v; + } + __host__ __device__ __forceinline__ bit_not() {} + __host__ __device__ __forceinline__ bit_not(const bit_not&) {} + }; + + // Generalized Identity Operations + template struct identity : unary_function + { + __device__ __forceinline__ typename TypeTraits::ParameterType operator()(typename TypeTraits::ParameterType x) const + { + return x; + } + __host__ __device__ __forceinline__ identity() {} + __host__ __device__ __forceinline__ identity(const identity&) {} + }; + + template struct project1st : binary_function + { + __device__ __forceinline__ typename TypeTraits::ParameterType operator()(typename TypeTraits::ParameterType lhs, typename TypeTraits::ParameterType rhs) const + { + return lhs; + } + __host__ __device__ __forceinline__ project1st() {} + __host__ __device__ __forceinline__ project1st(const project1st&) {} + }; + + template struct project2nd : binary_function + { + __device__ __forceinline__ typename TypeTraits::ParameterType operator()(typename TypeTraits::ParameterType lhs, typename TypeTraits::ParameterType rhs) const + { + return rhs; + } + __host__ __device__ __forceinline__ project2nd() {} + __host__ __device__ __forceinline__ project2nd(const project2nd&) {} + }; + + // Min/Max Operations + +#define OPENCV_CUDA_IMPLEMENT_MINMAX(name, type, op) \ + template <> struct name : binary_function \ + { \ + __device__ __forceinline__ type operator()(type lhs, type rhs) const {return op(lhs, rhs);} \ + __host__ __device__ __forceinline__ name() {}\ + __host__ __device__ __forceinline__ name(const name&) {}\ + }; + + template struct maximum : binary_function + { + __device__ __forceinline__ T operator()(typename TypeTraits::ParameterType lhs, typename TypeTraits::ParameterType rhs) const + { + return max(lhs, rhs); + } + __host__ __device__ __forceinline__ maximum() {} + __host__ __device__ __forceinline__ maximum(const maximum&) {} + }; + + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, uchar, ::max) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, schar, ::max) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, char, ::max) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, ushort, ::max) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, short, ::max) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, int, ::max) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, uint, ::max) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, float, ::fmax) + OPENCV_CUDA_IMPLEMENT_MINMAX(maximum, double, ::fmax) + + template struct minimum : binary_function + { + __device__ __forceinline__ T operator()(typename TypeTraits::ParameterType lhs, typename TypeTraits::ParameterType rhs) const + { + return min(lhs, rhs); + } + __host__ __device__ __forceinline__ minimum() {} + __host__ __device__ __forceinline__ minimum(const minimum&) {} + }; + + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, uchar, ::min) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, schar, ::min) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, char, ::min) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, ushort, ::min) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, short, ::min) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, int, ::min) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, uint, ::min) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, float, ::fmin) + OPENCV_CUDA_IMPLEMENT_MINMAX(minimum, double, ::fmin) + +#undef OPENCV_CUDA_IMPLEMENT_MINMAX + + // Math functions + + template struct abs_func : unary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType x) const + { + return abs(x); + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ unsigned char operator ()(unsigned char x) const + { + return x; + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ signed char operator ()(signed char x) const + { + return ::abs((int)x); + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ char operator ()(char x) const + { + return ::abs((int)x); + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ unsigned short operator ()(unsigned short x) const + { + return x; + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ short operator ()(short x) const + { + return ::abs((int)x); + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ unsigned int operator ()(unsigned int x) const + { + return x; + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ int operator ()(int x) const + { + return ::abs(x); + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ float operator ()(float x) const + { + return ::fabsf(x); + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + template <> struct abs_func : unary_function + { + __device__ __forceinline__ double operator ()(double x) const + { + return ::fabs(x); + } + + __host__ __device__ __forceinline__ abs_func() {} + __host__ __device__ __forceinline__ abs_func(const abs_func&) {} + }; + +#define OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(name, func) \ + template struct name ## _func : unary_function \ + { \ + __device__ __forceinline__ float operator ()(typename TypeTraits::ParameterType v) const \ + { \ + return func ## f(v); \ + } \ + __host__ __device__ __forceinline__ name ## _func() {} \ + __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \ + }; \ + template <> struct name ## _func : unary_function \ + { \ + __device__ __forceinline__ double operator ()(double v) const \ + { \ + return func(v); \ + } \ + __host__ __device__ __forceinline__ name ## _func() {} \ + __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \ + }; + +#define OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(name, func) \ + template struct name ## _func : binary_function \ + { \ + __device__ __forceinline__ float operator ()(typename TypeTraits::ParameterType v1, typename TypeTraits::ParameterType v2) const \ + { \ + return func ## f(v1, v2); \ + } \ + __host__ __device__ __forceinline__ name ## _func() {} \ + __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \ + }; \ + template <> struct name ## _func : binary_function \ + { \ + __device__ __forceinline__ double operator ()(double v1, double v2) const \ + { \ + return func(v1, v2); \ + } \ + __host__ __device__ __forceinline__ name ## _func() {} \ + __host__ __device__ __forceinline__ name ## _func(const name ## _func&) {} \ + }; + + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(sqrt, ::sqrt) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(exp, ::exp) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(exp2, ::exp2) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(exp10, ::exp10) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(log, ::log) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(log2, ::log2) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(log10, ::log10) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(sin, ::sin) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(cos, ::cos) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(tan, ::tan) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(asin, ::asin) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(acos, ::acos) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(atan, ::atan) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(sinh, ::sinh) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(cosh, ::cosh) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(tanh, ::tanh) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(asinh, ::asinh) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(acosh, ::acosh) + OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR(atanh, ::atanh) + + OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(hypot, ::hypot) + OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(atan2, ::atan2) + OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR(pow, ::pow) + + #undef OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR + #undef OPENCV_CUDA_IMPLEMENT_UN_FUNCTOR_NO_DOUBLE + #undef OPENCV_CUDA_IMPLEMENT_BIN_FUNCTOR + + template struct hypot_sqr_func : binary_function + { + __device__ __forceinline__ T operator ()(typename TypeTraits::ParameterType src1, typename TypeTraits::ParameterType src2) const + { + return src1 * src1 + src2 * src2; + } + __host__ __device__ __forceinline__ hypot_sqr_func() {} + __host__ __device__ __forceinline__ hypot_sqr_func(const hypot_sqr_func&) {} + }; + + // Saturate Cast Functor + template struct saturate_cast_func : unary_function + { + __device__ __forceinline__ D operator ()(typename TypeTraits::ParameterType v) const + { + return saturate_cast(v); + } + __host__ __device__ __forceinline__ saturate_cast_func() {} + __host__ __device__ __forceinline__ saturate_cast_func(const saturate_cast_func&) {} + }; + + // Threshold Functors + template struct thresh_binary_func : unary_function + { + __host__ __device__ __forceinline__ thresh_binary_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {} + + __device__ __forceinline__ T operator()(typename TypeTraits::ParameterType src) const + { + return (src > thresh) * maxVal; + } + + __host__ __device__ __forceinline__ thresh_binary_func() {} + __host__ __device__ __forceinline__ thresh_binary_func(const thresh_binary_func& other) + : thresh(other.thresh), maxVal(other.maxVal) {} + + T thresh; + T maxVal; + }; + + template struct thresh_binary_inv_func : unary_function + { + __host__ __device__ __forceinline__ thresh_binary_inv_func(T thresh_, T maxVal_) : thresh(thresh_), maxVal(maxVal_) {} + + __device__ __forceinline__ T operator()(typename TypeTraits::ParameterType src) const + { + return (src <= thresh) * maxVal; + } + + __host__ __device__ __forceinline__ thresh_binary_inv_func() {} + __host__ __device__ __forceinline__ thresh_binary_inv_func(const thresh_binary_inv_func& other) + : thresh(other.thresh), maxVal(other.maxVal) {} + + T thresh; + T maxVal; + }; + + template struct thresh_trunc_func : unary_function + { + explicit __host__ __device__ __forceinline__ thresh_trunc_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {CV_UNUSED(maxVal_);} + + __device__ __forceinline__ T operator()(typename TypeTraits::ParameterType src) const + { + return minimum()(src, thresh); + } + + __host__ __device__ __forceinline__ thresh_trunc_func() {} + __host__ __device__ __forceinline__ thresh_trunc_func(const thresh_trunc_func& other) + : thresh(other.thresh) {} + + T thresh; + }; + + template struct thresh_to_zero_func : unary_function + { + explicit __host__ __device__ __forceinline__ thresh_to_zero_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {CV_UNUSED(maxVal_);} + + __device__ __forceinline__ T operator()(typename TypeTraits::ParameterType src) const + { + return (src > thresh) * src; + } + + __host__ __device__ __forceinline__ thresh_to_zero_func() {} + __host__ __device__ __forceinline__ thresh_to_zero_func(const thresh_to_zero_func& other) + : thresh(other.thresh) {} + + T thresh; + }; + + template struct thresh_to_zero_inv_func : unary_function + { + explicit __host__ __device__ __forceinline__ thresh_to_zero_inv_func(T thresh_, T maxVal_ = 0) : thresh(thresh_) {CV_UNUSED(maxVal_);} + + __device__ __forceinline__ T operator()(typename TypeTraits::ParameterType src) const + { + return (src <= thresh) * src; + } + + __host__ __device__ __forceinline__ thresh_to_zero_inv_func() {} + __host__ __device__ __forceinline__ thresh_to_zero_inv_func(const thresh_to_zero_inv_func& other) + : thresh(other.thresh) {} + + T thresh; + }; + + // Function Object Adaptors + template struct unary_negate : unary_function + { + explicit __host__ __device__ __forceinline__ unary_negate(const Predicate& p) : pred(p) {} + + __device__ __forceinline__ bool operator()(typename TypeTraits::ParameterType x) const + { + return !pred(x); + } + + __host__ __device__ __forceinline__ unary_negate() {} + __host__ __device__ __forceinline__ unary_negate(const unary_negate& other) : pred(other.pred) {} + + Predicate pred; + }; + + template __host__ __device__ __forceinline__ unary_negate not1(const Predicate& pred) + { + return unary_negate(pred); + } + + template struct binary_negate : binary_function + { + explicit __host__ __device__ __forceinline__ binary_negate(const Predicate& p) : pred(p) {} + + __device__ __forceinline__ bool operator()(typename TypeTraits::ParameterType x, + typename TypeTraits::ParameterType y) const + { + return !pred(x,y); + } + + __host__ __device__ __forceinline__ binary_negate() {} + __host__ __device__ __forceinline__ binary_negate(const binary_negate& other) : pred(other.pred) {} + + Predicate pred; + }; + + template __host__ __device__ __forceinline__ binary_negate not2(const BinaryPredicate& pred) + { + return binary_negate(pred); + } + + template struct binder1st : unary_function + { + __host__ __device__ __forceinline__ binder1st(const Op& op_, const typename Op::first_argument_type& arg1_) : op(op_), arg1(arg1_) {} + + __device__ __forceinline__ typename Op::result_type operator ()(typename TypeTraits::ParameterType a) const + { + return op(arg1, a); + } + + __host__ __device__ __forceinline__ binder1st() {} + __host__ __device__ __forceinline__ binder1st(const binder1st& other) : op(other.op), arg1(other.arg1) {} + + Op op; + typename Op::first_argument_type arg1; + }; + + template __host__ __device__ __forceinline__ binder1st bind1st(const Op& op, const T& x) + { + return binder1st(op, typename Op::first_argument_type(x)); + } + + template struct binder2nd : unary_function + { + __host__ __device__ __forceinline__ binder2nd(const Op& op_, const typename Op::second_argument_type& arg2_) : op(op_), arg2(arg2_) {} + + __forceinline__ __device__ typename Op::result_type operator ()(typename TypeTraits::ParameterType a) const + { + return op(a, arg2); + } + + __host__ __device__ __forceinline__ binder2nd() {} + __host__ __device__ __forceinline__ binder2nd(const binder2nd& other) : op(other.op), arg2(other.arg2) {} + + Op op; + typename Op::second_argument_type arg2; + }; + + template __host__ __device__ __forceinline__ binder2nd bind2nd(const Op& op, const T& x) + { + return binder2nd(op, typename Op::second_argument_type(x)); + } + + // Functor Traits + template struct IsUnaryFunction + { + typedef char Yes; + struct No {Yes a[2];}; + + template static Yes check(unary_function); + static No check(...); + + static F makeF(); + + enum { value = (sizeof(check(makeF())) == sizeof(Yes)) }; + }; + + template struct IsBinaryFunction + { + typedef char Yes; + struct No {Yes a[2];}; + + template static Yes check(binary_function); + static No check(...); + + static F makeF(); + + enum { value = (sizeof(check(makeF())) == sizeof(Yes)) }; + }; + + namespace functional_detail + { + template struct UnOpShift { enum { shift = 1 }; }; + template struct UnOpShift { enum { shift = 4 }; }; + template struct UnOpShift { enum { shift = 2 }; }; + + template struct DefaultUnaryShift + { + enum { shift = UnOpShift::shift }; + }; + + template struct BinOpShift { enum { shift = 1 }; }; + template struct BinOpShift { enum { shift = 4 }; }; + template struct BinOpShift { enum { shift = 2 }; }; + + template struct DefaultBinaryShift + { + enum { shift = BinOpShift::shift }; + }; + + template ::value> struct ShiftDispatcher; + template struct ShiftDispatcher + { + enum { shift = DefaultUnaryShift::shift }; + }; + template struct ShiftDispatcher + { + enum { shift = DefaultBinaryShift::shift }; + }; + } + + template struct DefaultTransformShift + { + enum { shift = functional_detail::ShiftDispatcher::shift }; + }; + + template struct DefaultTransformFunctorTraits + { + enum { simple_block_dim_x = 16 }; + enum { simple_block_dim_y = 16 }; + + enum { smart_block_dim_x = 16 }; + enum { smart_block_dim_y = 16 }; + enum { smart_shift = DefaultTransformShift::shift }; + }; + + template struct TransformFunctorTraits : DefaultTransformFunctorTraits {}; + +#define OPENCV_CUDA_TRANSFORM_FUNCTOR_TRAITS(type) \ + template <> struct TransformFunctorTraits< type > : DefaultTransformFunctorTraits< type > +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_FUNCTIONAL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/limits.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/limits.hpp new file mode 100755 index 0000000..7e15ed6 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/limits.hpp @@ -0,0 +1,128 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_LIMITS_HPP +#define OPENCV_CUDA_LIMITS_HPP + +#include +#include +#include "common.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ +template struct numeric_limits; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static bool min() { return false; } + __device__ __forceinline__ static bool max() { return true; } + static const bool is_signed = false; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static signed char min() { return SCHAR_MIN; } + __device__ __forceinline__ static signed char max() { return SCHAR_MAX; } + static const bool is_signed = true; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static unsigned char min() { return 0; } + __device__ __forceinline__ static unsigned char max() { return UCHAR_MAX; } + static const bool is_signed = false; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static short min() { return SHRT_MIN; } + __device__ __forceinline__ static short max() { return SHRT_MAX; } + static const bool is_signed = true; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static unsigned short min() { return 0; } + __device__ __forceinline__ static unsigned short max() { return USHRT_MAX; } + static const bool is_signed = false; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static int min() { return INT_MIN; } + __device__ __forceinline__ static int max() { return INT_MAX; } + static const bool is_signed = true; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static unsigned int min() { return 0; } + __device__ __forceinline__ static unsigned int max() { return UINT_MAX; } + static const bool is_signed = false; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static float min() { return FLT_MIN; } + __device__ __forceinline__ static float max() { return FLT_MAX; } + __device__ __forceinline__ static float epsilon() { return FLT_EPSILON; } + static const bool is_signed = true; +}; + +template <> struct numeric_limits +{ + __device__ __forceinline__ static double min() { return DBL_MIN; } + __device__ __forceinline__ static double max() { return DBL_MAX; } + __device__ __forceinline__ static double epsilon() { return DBL_EPSILON; } + static const bool is_signed = true; +}; +}}} // namespace cv { namespace cuda { namespace cudev { + +//! @endcond + +#endif // OPENCV_CUDA_LIMITS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/reduce.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/reduce.hpp new file mode 100755 index 0000000..5de3650 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/reduce.hpp @@ -0,0 +1,209 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_REDUCE_HPP +#define OPENCV_CUDA_REDUCE_HPP + +#ifndef THRUST_DEBUG // eliminate -Wundef warning +#define THRUST_DEBUG 0 +#endif + +#include +#include "detail/reduce.hpp" +#include "detail/reduce_key_val.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template + __device__ __forceinline__ void reduce(volatile T* smem, T& val, unsigned int tid, const Op& op) + { + reduce_detail::Dispatcher::reductor::template reduce(smem, val, tid, op); + } + template + __device__ __forceinline__ void reduce(const thrust::tuple& smem, + const thrust::tuple& val, + unsigned int tid, + const thrust::tuple& op) + { + reduce_detail::Dispatcher::reductor::template reduce< + const thrust::tuple&, + const thrust::tuple&, + const thrust::tuple&>(smem, val, tid, op); + } + + template + __device__ __forceinline__ void reduceKeyVal(volatile K* skeys, K& key, volatile V* svals, V& val, unsigned int tid, const Cmp& cmp) + { + reduce_key_val_detail::Dispatcher::reductor::template reduce(skeys, key, svals, val, tid, cmp); + } + template + __device__ __forceinline__ void reduceKeyVal(volatile K* skeys, K& key, + const thrust::tuple& svals, + const thrust::tuple& val, + unsigned int tid, const Cmp& cmp) + { + reduce_key_val_detail::Dispatcher::reductor::template reduce&, + const thrust::tuple&, + const Cmp&>(skeys, key, svals, val, tid, cmp); + } + template + __device__ __forceinline__ void reduceKeyVal(const thrust::tuple& skeys, + const thrust::tuple& key, + const thrust::tuple& svals, + const thrust::tuple& val, + unsigned int tid, + const thrust::tuple& cmp) + { + reduce_key_val_detail::Dispatcher::reductor::template reduce< + const thrust::tuple&, + const thrust::tuple&, + const thrust::tuple&, + const thrust::tuple&, + const thrust::tuple& + >(skeys, key, svals, val, tid, cmp); + } + + // smem_tuple + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0) + { + return thrust::make_tuple((volatile T0*) t0); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2, T3* t3) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2, T3* t3, T4* t4) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3, (volatile T4*) t4); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2, T3* t3, T4* t4, T5* t5) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3, (volatile T4*) t4, (volatile T5*) t5); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2, T3* t3, T4* t4, T5* t5, T6* t6) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3, (volatile T4*) t4, (volatile T5*) t5, (volatile T6*) t6); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2, T3* t3, T4* t4, T5* t5, T6* t6, T7* t7) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3, (volatile T4*) t4, (volatile T5*) t5, (volatile T6*) t6, (volatile T7*) t7); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2, T3* t3, T4* t4, T5* t5, T6* t6, T7* t7, T8* t8) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3, (volatile T4*) t4, (volatile T5*) t5, (volatile T6*) t6, (volatile T7*) t7, (volatile T8*) t8); + } + + template + __device__ __forceinline__ + thrust::tuple + smem_tuple(T0* t0, T1* t1, T2* t2, T3* t3, T4* t4, T5* t5, T6* t6, T7* t7, T8* t8, T9* t9) + { + return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3, (volatile T4*) t4, (volatile T5*) t5, (volatile T6*) t6, (volatile T7*) t7, (volatile T8*) t8, (volatile T9*) t9); + } +}}} + +//! @endcond + +#endif // OPENCV_CUDA_REDUCE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/saturate_cast.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/saturate_cast.hpp new file mode 100755 index 0000000..c3a3d1c --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/saturate_cast.hpp @@ -0,0 +1,292 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_SATURATE_CAST_HPP +#define OPENCV_CUDA_SATURATE_CAST_HPP + +#include "common.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template __device__ __forceinline__ _Tp saturate_cast(uchar v) { return _Tp(v); } + template __device__ __forceinline__ _Tp saturate_cast(schar v) { return _Tp(v); } + template __device__ __forceinline__ _Tp saturate_cast(ushort v) { return _Tp(v); } + template __device__ __forceinline__ _Tp saturate_cast(short v) { return _Tp(v); } + template __device__ __forceinline__ _Tp saturate_cast(uint v) { return _Tp(v); } + template __device__ __forceinline__ _Tp saturate_cast(int v) { return _Tp(v); } + template __device__ __forceinline__ _Tp saturate_cast(float v) { return _Tp(v); } + template __device__ __forceinline__ _Tp saturate_cast(double v) { return _Tp(v); } + + template<> __device__ __forceinline__ uchar saturate_cast(schar v) + { + uint res = 0; + int vi = v; + asm("cvt.sat.u8.s8 %0, %1;" : "=r"(res) : "r"(vi)); + return res; + } + template<> __device__ __forceinline__ uchar saturate_cast(short v) + { + uint res = 0; + asm("cvt.sat.u8.s16 %0, %1;" : "=r"(res) : "h"(v)); + return res; + } + template<> __device__ __forceinline__ uchar saturate_cast(ushort v) + { + uint res = 0; + asm("cvt.sat.u8.u16 %0, %1;" : "=r"(res) : "h"(v)); + return res; + } + template<> __device__ __forceinline__ uchar saturate_cast(int v) + { + uint res = 0; + asm("cvt.sat.u8.s32 %0, %1;" : "=r"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ uchar saturate_cast(uint v) + { + uint res = 0; + asm("cvt.sat.u8.u32 %0, %1;" : "=r"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ uchar saturate_cast(float v) + { + uint res = 0; + asm("cvt.rni.sat.u8.f32 %0, %1;" : "=r"(res) : "f"(v)); + return res; + } + template<> __device__ __forceinline__ uchar saturate_cast(double v) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 130 + uint res = 0; + asm("cvt.rni.sat.u8.f64 %0, %1;" : "=r"(res) : "d"(v)); + return res; + #else + return saturate_cast((float)v); + #endif + } + + template<> __device__ __forceinline__ schar saturate_cast(uchar v) + { + uint res = 0; + uint vi = v; + asm("cvt.sat.s8.u8 %0, %1;" : "=r"(res) : "r"(vi)); + return res; + } + template<> __device__ __forceinline__ schar saturate_cast(short v) + { + uint res = 0; + asm("cvt.sat.s8.s16 %0, %1;" : "=r"(res) : "h"(v)); + return res; + } + template<> __device__ __forceinline__ schar saturate_cast(ushort v) + { + uint res = 0; + asm("cvt.sat.s8.u16 %0, %1;" : "=r"(res) : "h"(v)); + return res; + } + template<> __device__ __forceinline__ schar saturate_cast(int v) + { + uint res = 0; + asm("cvt.sat.s8.s32 %0, %1;" : "=r"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ schar saturate_cast(uint v) + { + uint res = 0; + asm("cvt.sat.s8.u32 %0, %1;" : "=r"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ schar saturate_cast(float v) + { + uint res = 0; + asm("cvt.rni.sat.s8.f32 %0, %1;" : "=r"(res) : "f"(v)); + return res; + } + template<> __device__ __forceinline__ schar saturate_cast(double v) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 130 + uint res = 0; + asm("cvt.rni.sat.s8.f64 %0, %1;" : "=r"(res) : "d"(v)); + return res; + #else + return saturate_cast((float)v); + #endif + } + + template<> __device__ __forceinline__ ushort saturate_cast(schar v) + { + ushort res = 0; + int vi = v; + asm("cvt.sat.u16.s8 %0, %1;" : "=h"(res) : "r"(vi)); + return res; + } + template<> __device__ __forceinline__ ushort saturate_cast(short v) + { + ushort res = 0; + asm("cvt.sat.u16.s16 %0, %1;" : "=h"(res) : "h"(v)); + return res; + } + template<> __device__ __forceinline__ ushort saturate_cast(int v) + { + ushort res = 0; + asm("cvt.sat.u16.s32 %0, %1;" : "=h"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ ushort saturate_cast(uint v) + { + ushort res = 0; + asm("cvt.sat.u16.u32 %0, %1;" : "=h"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ ushort saturate_cast(float v) + { + ushort res = 0; + asm("cvt.rni.sat.u16.f32 %0, %1;" : "=h"(res) : "f"(v)); + return res; + } + template<> __device__ __forceinline__ ushort saturate_cast(double v) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 130 + ushort res = 0; + asm("cvt.rni.sat.u16.f64 %0, %1;" : "=h"(res) : "d"(v)); + return res; + #else + return saturate_cast((float)v); + #endif + } + + template<> __device__ __forceinline__ short saturate_cast(ushort v) + { + short res = 0; + asm("cvt.sat.s16.u16 %0, %1;" : "=h"(res) : "h"(v)); + return res; + } + template<> __device__ __forceinline__ short saturate_cast(int v) + { + short res = 0; + asm("cvt.sat.s16.s32 %0, %1;" : "=h"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ short saturate_cast(uint v) + { + short res = 0; + asm("cvt.sat.s16.u32 %0, %1;" : "=h"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ short saturate_cast(float v) + { + short res = 0; + asm("cvt.rni.sat.s16.f32 %0, %1;" : "=h"(res) : "f"(v)); + return res; + } + template<> __device__ __forceinline__ short saturate_cast(double v) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 130 + short res = 0; + asm("cvt.rni.sat.s16.f64 %0, %1;" : "=h"(res) : "d"(v)); + return res; + #else + return saturate_cast((float)v); + #endif + } + + template<> __device__ __forceinline__ int saturate_cast(uint v) + { + int res = 0; + asm("cvt.sat.s32.u32 %0, %1;" : "=r"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ int saturate_cast(float v) + { + return __float2int_rn(v); + } + template<> __device__ __forceinline__ int saturate_cast(double v) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 130 + return __double2int_rn(v); + #else + return saturate_cast((float)v); + #endif + } + + template<> __device__ __forceinline__ uint saturate_cast(schar v) + { + uint res = 0; + int vi = v; + asm("cvt.sat.u32.s8 %0, %1;" : "=r"(res) : "r"(vi)); + return res; + } + template<> __device__ __forceinline__ uint saturate_cast(short v) + { + uint res = 0; + asm("cvt.sat.u32.s16 %0, %1;" : "=r"(res) : "h"(v)); + return res; + } + template<> __device__ __forceinline__ uint saturate_cast(int v) + { + uint res = 0; + asm("cvt.sat.u32.s32 %0, %1;" : "=r"(res) : "r"(v)); + return res; + } + template<> __device__ __forceinline__ uint saturate_cast(float v) + { + return __float2uint_rn(v); + } + template<> __device__ __forceinline__ uint saturate_cast(double v) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 130 + return __double2uint_rn(v); + #else + return saturate_cast((float)v); + #endif + } +}}} + +//! @endcond + +#endif /* OPENCV_CUDA_SATURATE_CAST_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/scan.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/scan.hpp new file mode 100755 index 0000000..e128fb0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/scan.hpp @@ -0,0 +1,258 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_SCAN_HPP +#define OPENCV_CUDA_SCAN_HPP + +#include "opencv2/core/cuda/common.hpp" +#include "opencv2/core/cuda/utility.hpp" +#include "opencv2/core/cuda/warp.hpp" +#include "opencv2/core/cuda/warp_shuffle.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + enum ScanKind { EXCLUSIVE = 0, INCLUSIVE = 1 }; + + template struct WarpScan + { + __device__ __forceinline__ WarpScan() {} + __device__ __forceinline__ WarpScan(const WarpScan& other) { CV_UNUSED(other); } + + __device__ __forceinline__ T operator()( volatile T *ptr , const unsigned int idx) + { + const unsigned int lane = idx & 31; + F op; + + if ( lane >= 1) ptr [idx ] = op(ptr [idx - 1], ptr [idx]); + if ( lane >= 2) ptr [idx ] = op(ptr [idx - 2], ptr [idx]); + if ( lane >= 4) ptr [idx ] = op(ptr [idx - 4], ptr [idx]); + if ( lane >= 8) ptr [idx ] = op(ptr [idx - 8], ptr [idx]); + if ( lane >= 16) ptr [idx ] = op(ptr [idx - 16], ptr [idx]); + + if( Kind == INCLUSIVE ) + return ptr [idx]; + else + return (lane > 0) ? ptr [idx - 1] : 0; + } + + __device__ __forceinline__ unsigned int index(const unsigned int tid) + { + return tid; + } + + __device__ __forceinline__ void init(volatile T *ptr){} + + static const int warp_offset = 0; + + typedef WarpScan merge; + }; + + template struct WarpScanNoComp + { + __device__ __forceinline__ WarpScanNoComp() {} + __device__ __forceinline__ WarpScanNoComp(const WarpScanNoComp& other) { CV_UNUSED(other); } + + __device__ __forceinline__ T operator()( volatile T *ptr , const unsigned int idx) + { + const unsigned int lane = threadIdx.x & 31; + F op; + + ptr [idx ] = op(ptr [idx - 1], ptr [idx]); + ptr [idx ] = op(ptr [idx - 2], ptr [idx]); + ptr [idx ] = op(ptr [idx - 4], ptr [idx]); + ptr [idx ] = op(ptr [idx - 8], ptr [idx]); + ptr [idx ] = op(ptr [idx - 16], ptr [idx]); + + if( Kind == INCLUSIVE ) + return ptr [idx]; + else + return (lane > 0) ? ptr [idx - 1] : 0; + } + + __device__ __forceinline__ unsigned int index(const unsigned int tid) + { + return (tid >> warp_log) * warp_smem_stride + 16 + (tid & warp_mask); + } + + __device__ __forceinline__ void init(volatile T *ptr) + { + ptr[threadIdx.x] = 0; + } + + static const int warp_smem_stride = 32 + 16 + 1; + static const int warp_offset = 16; + static const int warp_log = 5; + static const int warp_mask = 31; + + typedef WarpScanNoComp merge; + }; + + template struct BlockScan + { + __device__ __forceinline__ BlockScan() {} + __device__ __forceinline__ BlockScan(const BlockScan& other) { CV_UNUSED(other); } + + __device__ __forceinline__ T operator()(volatile T *ptr) + { + const unsigned int tid = threadIdx.x; + const unsigned int lane = tid & warp_mask; + const unsigned int warp = tid >> warp_log; + + Sc scan; + typename Sc::merge merge_scan; + const unsigned int idx = scan.index(tid); + + T val = scan(ptr, idx); + __syncthreads (); + + if( warp == 0) + scan.init(ptr); + __syncthreads (); + + if( lane == 31 ) + ptr [scan.warp_offset + warp ] = (Kind == INCLUSIVE) ? val : ptr [idx]; + __syncthreads (); + + if( warp == 0 ) + merge_scan(ptr, idx); + __syncthreads(); + + if ( warp > 0) + val = ptr [scan.warp_offset + warp - 1] + val; + __syncthreads (); + + ptr[idx] = val; + __syncthreads (); + + return val ; + } + + static const int warp_log = 5; + static const int warp_mask = 31; + }; + + template + __device__ T warpScanInclusive(T idata, volatile T* s_Data, unsigned int tid) + { + #if __CUDA_ARCH__ >= 300 + const unsigned int laneId = cv::cuda::device::Warp::laneId(); + + // scan on shuffl functions + #pragma unroll + for (int i = 1; i <= (OPENCV_CUDA_WARP_SIZE / 2); i *= 2) + { + const T n = cv::cuda::device::shfl_up(idata, i); + if (laneId >= i) + idata += n; + } + + return idata; + #else + unsigned int pos = 2 * tid - (tid & (OPENCV_CUDA_WARP_SIZE - 1)); + s_Data[pos] = 0; + pos += OPENCV_CUDA_WARP_SIZE; + s_Data[pos] = idata; + + s_Data[pos] += s_Data[pos - 1]; + s_Data[pos] += s_Data[pos - 2]; + s_Data[pos] += s_Data[pos - 4]; + s_Data[pos] += s_Data[pos - 8]; + s_Data[pos] += s_Data[pos - 16]; + + return s_Data[pos]; + #endif + } + + template + __device__ __forceinline__ T warpScanExclusive(T idata, volatile T* s_Data, unsigned int tid) + { + return warpScanInclusive(idata, s_Data, tid) - idata; + } + + template + __device__ T blockScanInclusive(T idata, volatile T* s_Data, unsigned int tid) + { + if (tiNumScanThreads > OPENCV_CUDA_WARP_SIZE) + { + //Bottom-level inclusive warp scan + T warpResult = warpScanInclusive(idata, s_Data, tid); + + //Save top elements of each warp for exclusive warp scan + //sync to wait for warp scans to complete (because s_Data is being overwritten) + __syncthreads(); + if ((tid & (OPENCV_CUDA_WARP_SIZE - 1)) == (OPENCV_CUDA_WARP_SIZE - 1)) + { + s_Data[tid >> OPENCV_CUDA_LOG_WARP_SIZE] = warpResult; + } + + //wait for warp scans to complete + __syncthreads(); + + if (tid < (tiNumScanThreads / OPENCV_CUDA_WARP_SIZE) ) + { + //grab top warp elements + T val = s_Data[tid]; + //calculate exclusive scan and write back to shared memory + s_Data[tid] = warpScanExclusive(val, s_Data, tid); + } + + //return updated warp scans with exclusive scan results + __syncthreads(); + + return warpResult + s_Data[tid >> OPENCV_CUDA_LOG_WARP_SIZE]; + } + else + { + return warpScanInclusive(idata, s_Data, tid); + } + } +}}} + +//! @endcond + +#endif // OPENCV_CUDA_SCAN_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/simd_functions.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/simd_functions.hpp new file mode 100755 index 0000000..3d8c2e0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/simd_functions.hpp @@ -0,0 +1,869 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* + * Copyright (c) 2013 NVIDIA Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of NVIDIA Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef OPENCV_CUDA_SIMD_FUNCTIONS_HPP +#define OPENCV_CUDA_SIMD_FUNCTIONS_HPP + +#include "common.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + // 2 + + static __device__ __forceinline__ unsigned int vadd2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vadd2.u32.u32.u32.sat %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vadd.u32.u32.u32.sat %0.h0, %1.h0, %2.h0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vadd.u32.u32.u32.sat %0.h1, %1.h1, %2.h1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s; + s = a ^ b; // sum bits + r = a + b; // actual sum + s = s ^ r; // determine carry-ins for each bit position + s = s & 0x00010000; // carry-in to high word (= carry-out from low word) + r = r - s; // subtract out carry-out from low word + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsub2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vsub2.u32.u32.u32.sat %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vsub.u32.u32.u32.sat %0.h0, %1.h0, %2.h0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vsub.u32.u32.u32.sat %0.h1, %1.h1, %2.h1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s; + s = a ^ b; // sum bits + r = a - b; // actual sum + s = s ^ r; // determine carry-ins for each bit position + s = s & 0x00010000; // borrow to high word + r = r + s; // compensate for borrow from low word + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vabsdiff2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vabsdiff2.u32.u32.u32.sat %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vabsdiff.u32.u32.u32.sat %0.h0, %1.h0, %2.h0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vabsdiff.u32.u32.u32.sat %0.h1, %1.h1, %2.h1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s, t, u, v; + s = a & 0x0000ffff; // extract low halfword + r = b & 0x0000ffff; // extract low halfword + u = ::max(r, s); // maximum of low halfwords + v = ::min(r, s); // minimum of low halfwords + s = a & 0xffff0000; // extract high halfword + r = b & 0xffff0000; // extract high halfword + t = ::max(r, s); // maximum of high halfwords + s = ::min(r, s); // minimum of high halfwords + r = u | t; // maximum of both halfwords + s = v | s; // minimum of both halfwords + r = r - s; // |a - b| = max(a,b) - min(a,b); + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vavg2(unsigned int a, unsigned int b) + { + unsigned int r, s; + + // HAKMEM #23: a + b = 2 * (a & b) + (a ^ b) ==> + // (a + b) / 2 = (a & b) + ((a ^ b) >> 1) + s = a ^ b; + r = a & b; + s = s & 0xfffefffe; // ensure shift doesn't cross halfword boundaries + s = s >> 1; + s = r + s; + + return s; + } + + static __device__ __forceinline__ unsigned int vavrg2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vavrg2.u32.u32.u32 %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + // HAKMEM #23: a + b = 2 * (a | b) - (a ^ b) ==> + // (a + b + 1) / 2 = (a | b) - ((a ^ b) >> 1) + unsigned int s; + s = a ^ b; + r = a | b; + s = s & 0xfffefffe; // ensure shift doesn't cross half-word boundaries + s = s >> 1; + r = r - s; + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vseteq2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset2.u32.u32.eq %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + unsigned int c; + r = a ^ b; // 0x0000 if a == b + c = r | 0x80008000; // set msbs, to catch carry out + r = r ^ c; // extract msbs, msb = 1 if r < 0x8000 + c = c - 0x00010001; // msb = 0, if r was 0x0000 or 0x8000 + c = r & ~c; // msb = 1, if r was 0x0000 + r = c >> 15; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpeq2(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vseteq2(a, b); + c = r << 16; // convert bool + r = c - r; // into mask + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + r = a ^ b; // 0x0000 if a == b + c = r | 0x80008000; // set msbs, to catch carry out + r = r ^ c; // extract msbs, msb = 1 if r < 0x8000 + c = c - 0x00010001; // msb = 0, if r was 0x0000 or 0x8000 + c = r & ~c; // msb = 1, if r was 0x0000 + r = c >> 15; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetge2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset2.u32.u32.ge %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(b)); + c = vavrg2(a, b); // (a + ~b + 1) / 2 = (a - b) / 2 + c = c & 0x80008000; // msb = carry-outs + r = c >> 15; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpge2(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetge2(a, b); + c = r << 16; // convert bool + r = c - r; // into mask + #else + asm("not.b32 %0, %0;" : "+r"(b)); + c = vavrg2(a, b); // (a + ~b + 1) / 2 = (a - b) / 2 + c = c & 0x80008000; // msb = carry-outs + r = c >> 15; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetgt2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset2.u32.u32.gt %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(b)); + c = vavg2(a, b); // (a + ~b) / 2 = (a - b) / 2 [rounded down] + c = c & 0x80008000; // msbs = carry-outs + r = c >> 15; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpgt2(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetgt2(a, b); + c = r << 16; // convert bool + r = c - r; // into mask + #else + asm("not.b32 %0, %0;" : "+r"(b)); + c = vavg2(a, b); // (a + ~b) / 2 = (a - b) / 2 [rounded down] + c = c & 0x80008000; // msbs = carry-outs + r = c >> 15; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetle2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset2.u32.u32.le %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavrg2(a, b); // (b + ~a + 1) / 2 = (b - a) / 2 + c = c & 0x80008000; // msb = carry-outs + r = c >> 15; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmple2(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetle2(a, b); + c = r << 16; // convert bool + r = c - r; // into mask + #else + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavrg2(a, b); // (b + ~a + 1) / 2 = (b - a) / 2 + c = c & 0x80008000; // msb = carry-outs + r = c >> 15; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetlt2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset2.u32.u32.lt %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavg2(a, b); // (b + ~a) / 2 = (b - a) / 2 [rounded down] + c = c & 0x80008000; // msb = carry-outs + r = c >> 15; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmplt2(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetlt2(a, b); + c = r << 16; // convert bool + r = c - r; // into mask + #else + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavg2(a, b); // (b + ~a) / 2 = (b - a) / 2 [rounded down] + c = c & 0x80008000; // msb = carry-outs + r = c >> 15; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetne2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm ("vset2.u32.u32.ne %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + unsigned int c; + r = a ^ b; // 0x0000 if a == b + c = r | 0x80008000; // set msbs, to catch carry out + c = c - 0x00010001; // msb = 0, if r was 0x0000 or 0x8000 + c = r | c; // msb = 1, if r was not 0x0000 + c = c & 0x80008000; // extract msbs + r = c >> 15; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpne2(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetne2(a, b); + c = r << 16; // convert bool + r = c - r; // into mask + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + r = a ^ b; // 0x0000 if a == b + c = r | 0x80008000; // set msbs, to catch carry out + c = c - 0x00010001; // msb = 0, if r was 0x0000 or 0x8000 + c = r | c; // msb = 1, if r was not 0x0000 + c = c & 0x80008000; // extract msbs + r = c >> 15; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vmax2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vmax2.u32.u32.u32 %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vmax.u32.u32.u32 %0.h0, %1.h0, %2.h0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmax.u32.u32.u32 %0.h1, %1.h1, %2.h1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s, t, u; + r = a & 0x0000ffff; // extract low halfword + s = b & 0x0000ffff; // extract low halfword + t = ::max(r, s); // maximum of low halfwords + r = a & 0xffff0000; // extract high halfword + s = b & 0xffff0000; // extract high halfword + u = ::max(r, s); // maximum of high halfwords + r = t | u; // combine halfword maximums + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vmin2(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vmin2.u32.u32.u32 %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vmin.u32.u32.u32 %0.h0, %1.h0, %2.h0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmin.u32.u32.u32 %0.h1, %1.h1, %2.h1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s, t, u; + r = a & 0x0000ffff; // extract low halfword + s = b & 0x0000ffff; // extract low halfword + t = ::min(r, s); // minimum of low halfwords + r = a & 0xffff0000; // extract high halfword + s = b & 0xffff0000; // extract high halfword + u = ::min(r, s); // minimum of high halfwords + r = t | u; // combine halfword minimums + #endif + + return r; + } + + // 4 + + static __device__ __forceinline__ unsigned int vadd4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vadd4.u32.u32.u32.sat %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vadd.u32.u32.u32.sat %0.b0, %1.b0, %2.b0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vadd.u32.u32.u32.sat %0.b1, %1.b1, %2.b1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vadd.u32.u32.u32.sat %0.b2, %1.b2, %2.b2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vadd.u32.u32.u32.sat %0.b3, %1.b3, %2.b3, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s, t; + s = a ^ b; // sum bits + r = a & 0x7f7f7f7f; // clear msbs + t = b & 0x7f7f7f7f; // clear msbs + s = s & 0x80808080; // msb sum bits + r = r + t; // add without msbs, record carry-out in msbs + r = r ^ s; // sum of msb sum and carry-in bits, w/o carry-out + #endif /* __CUDA_ARCH__ >= 300 */ + + return r; + } + + static __device__ __forceinline__ unsigned int vsub4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vsub4.u32.u32.u32.sat %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vsub.u32.u32.u32.sat %0.b0, %1.b0, %2.b0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vsub.u32.u32.u32.sat %0.b1, %1.b1, %2.b1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vsub.u32.u32.u32.sat %0.b2, %1.b2, %2.b2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vsub.u32.u32.u32.sat %0.b3, %1.b3, %2.b3, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s, t; + s = a ^ ~b; // inverted sum bits + r = a | 0x80808080; // set msbs + t = b & 0x7f7f7f7f; // clear msbs + s = s & 0x80808080; // inverted msb sum bits + r = r - t; // subtract w/o msbs, record inverted borrows in msb + r = r ^ s; // combine inverted msb sum bits and borrows + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vavg4(unsigned int a, unsigned int b) + { + unsigned int r, s; + + // HAKMEM #23: a + b = 2 * (a & b) + (a ^ b) ==> + // (a + b) / 2 = (a & b) + ((a ^ b) >> 1) + s = a ^ b; + r = a & b; + s = s & 0xfefefefe; // ensure following shift doesn't cross byte boundaries + s = s >> 1; + s = r + s; + + return s; + } + + static __device__ __forceinline__ unsigned int vavrg4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vavrg4.u32.u32.u32 %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + // HAKMEM #23: a + b = 2 * (a | b) - (a ^ b) ==> + // (a + b + 1) / 2 = (a | b) - ((a ^ b) >> 1) + unsigned int c; + c = a ^ b; + r = a | b; + c = c & 0xfefefefe; // ensure following shift doesn't cross byte boundaries + c = c >> 1; + r = r - c; + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vseteq4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset4.u32.u32.eq %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + unsigned int c; + r = a ^ b; // 0x00 if a == b + c = r | 0x80808080; // set msbs, to catch carry out + r = r ^ c; // extract msbs, msb = 1 if r < 0x80 + c = c - 0x01010101; // msb = 0, if r was 0x00 or 0x80 + c = r & ~c; // msb = 1, if r was 0x00 + r = c >> 7; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpeq4(unsigned int a, unsigned int b) + { + unsigned int r, t; + + #if __CUDA_ARCH__ >= 300 + r = vseteq4(a, b); + t = r << 8; // convert bool + r = t - r; // to mask + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + t = a ^ b; // 0x00 if a == b + r = t | 0x80808080; // set msbs, to catch carry out + t = t ^ r; // extract msbs, msb = 1 if t < 0x80 + r = r - 0x01010101; // msb = 0, if t was 0x00 or 0x80 + r = t & ~r; // msb = 1, if t was 0x00 + t = r >> 7; // build mask + t = r - t; // from + r = t | r; // msbs + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetle4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset4.u32.u32.le %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavrg4(a, b); // (b + ~a + 1) / 2 = (b - a) / 2 + c = c & 0x80808080; // msb = carry-outs + r = c >> 7; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmple4(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetle4(a, b); + c = r << 8; // convert bool + r = c - r; // to mask + #else + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavrg4(a, b); // (b + ~a + 1) / 2 = (b - a) / 2 + c = c & 0x80808080; // msbs = carry-outs + r = c >> 7; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetlt4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset4.u32.u32.lt %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavg4(a, b); // (b + ~a) / 2 = (b - a) / 2 [rounded down] + c = c & 0x80808080; // msb = carry-outs + r = c >> 7; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmplt4(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetlt4(a, b); + c = r << 8; // convert bool + r = c - r; // to mask + #else + asm("not.b32 %0, %0;" : "+r"(a)); + c = vavg4(a, b); // (b + ~a) / 2 = (b - a) / 2 [rounded down] + c = c & 0x80808080; // msbs = carry-outs + r = c >> 7; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetge4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset4.u32.u32.ge %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(b)); + c = vavrg4(a, b); // (a + ~b + 1) / 2 = (a - b) / 2 + c = c & 0x80808080; // msb = carry-outs + r = c >> 7; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpge4(unsigned int a, unsigned int b) + { + unsigned int r, s; + + #if __CUDA_ARCH__ >= 300 + r = vsetge4(a, b); + s = r << 8; // convert bool + r = s - r; // to mask + #else + asm ("not.b32 %0,%0;" : "+r"(b)); + r = vavrg4 (a, b); // (a + ~b + 1) / 2 = (a - b) / 2 + r = r & 0x80808080; // msb = carry-outs + s = r >> 7; // build mask + s = r - s; // from + r = s | r; // msbs + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetgt4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset4.u32.u32.gt %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int c; + asm("not.b32 %0, %0;" : "+r"(b)); + c = vavg4(a, b); // (a + ~b) / 2 = (a - b) / 2 [rounded down] + c = c & 0x80808080; // msb = carry-outs + r = c >> 7; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpgt4(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetgt4(a, b); + c = r << 8; // convert bool + r = c - r; // to mask + #else + asm("not.b32 %0, %0;" : "+r"(b)); + c = vavg4(a, b); // (a + ~b) / 2 = (a - b) / 2 [rounded down] + c = c & 0x80808080; // msb = carry-outs + r = c >> 7; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vsetne4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vset4.u32.u32.ne %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + unsigned int c; + r = a ^ b; // 0x00 if a == b + c = r | 0x80808080; // set msbs, to catch carry out + c = c - 0x01010101; // msb = 0, if r was 0x00 or 0x80 + c = r | c; // msb = 1, if r was not 0x00 + c = c & 0x80808080; // extract msbs + r = c >> 7; // convert to bool + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vcmpne4(unsigned int a, unsigned int b) + { + unsigned int r, c; + + #if __CUDA_ARCH__ >= 300 + r = vsetne4(a, b); + c = r << 8; // convert bool + r = c - r; // to mask + #else + // inspired by Alan Mycroft's null-byte detection algorithm: + // null_byte(x) = ((x - 0x01010101) & (~x & 0x80808080)) + r = a ^ b; // 0x00 if a == b + c = r | 0x80808080; // set msbs, to catch carry out + c = c - 0x01010101; // msb = 0, if r was 0x00 or 0x80 + c = r | c; // msb = 1, if r was not 0x00 + c = c & 0x80808080; // extract msbs + r = c >> 7; // convert + r = c - r; // msbs to + r = c | r; // mask + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vabsdiff4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vabsdiff4.u32.u32.u32.sat %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vabsdiff.u32.u32.u32.sat %0.b0, %1.b0, %2.b0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vabsdiff.u32.u32.u32.sat %0.b1, %1.b1, %2.b1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vabsdiff.u32.u32.u32.sat %0.b2, %1.b2, %2.b2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vabsdiff.u32.u32.u32.sat %0.b3, %1.b3, %2.b3, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s; + s = vcmpge4(a, b); // mask = 0xff if a >= b + r = a ^ b; // + s = (r & s) ^ b; // select a when a >= b, else select b => max(a,b) + r = s ^ r; // select a when b >= a, else select b => min(a,b) + r = s - r; // |a - b| = max(a,b) - min(a,b); + #endif + + return r; + } + + static __device__ __forceinline__ unsigned int vmax4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vmax4.u32.u32.u32 %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vmax.u32.u32.u32 %0.b0, %1.b0, %2.b0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmax.u32.u32.u32 %0.b1, %1.b1, %2.b1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmax.u32.u32.u32 %0.b2, %1.b2, %2.b2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmax.u32.u32.u32 %0.b3, %1.b3, %2.b3, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s; + s = vcmpge4(a, b); // mask = 0xff if a >= b + r = a & s; // select a when b >= a + s = b & ~s; // select b when b < a + r = r | s; // combine byte selections + #endif + + return r; // byte-wise unsigned maximum + } + + static __device__ __forceinline__ unsigned int vmin4(unsigned int a, unsigned int b) + { + unsigned int r = 0; + + #if __CUDA_ARCH__ >= 300 + asm("vmin4.u32.u32.u32 %0, %1, %2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #elif __CUDA_ARCH__ >= 200 + asm("vmin.u32.u32.u32 %0.b0, %1.b0, %2.b0, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmin.u32.u32.u32 %0.b1, %1.b1, %2.b1, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmin.u32.u32.u32 %0.b2, %1.b2, %2.b2, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + asm("vmin.u32.u32.u32 %0.b3, %1.b3, %2.b3, %3;" : "=r"(r) : "r"(a), "r"(b), "r"(r)); + #else + unsigned int s; + s = vcmpge4(b, a); // mask = 0xff if a >= b + r = a & s; // select a when b >= a + s = b & ~s; // select b when b < a + r = r | s; // combine byte selections + #endif + + return r; + } +}}} + +//! @endcond + +#endif // OPENCV_CUDA_SIMD_FUNCTIONS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/transform.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/transform.hpp new file mode 100755 index 0000000..42aa6ea --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/transform.hpp @@ -0,0 +1,75 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_TRANSFORM_HPP +#define OPENCV_CUDA_TRANSFORM_HPP + +#include "common.hpp" +#include "utility.hpp" +#include "detail/transform_detail.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template + static inline void transform(PtrStepSz src, PtrStepSz dst, UnOp op, const Mask& mask, cudaStream_t stream) + { + typedef TransformFunctorTraits ft; + transform_detail::TransformDispatcher::cn == 1 && VecTraits::cn == 1 && ft::smart_shift != 1>::call(src, dst, op, mask, stream); + } + + template + static inline void transform(PtrStepSz src1, PtrStepSz src2, PtrStepSz dst, BinOp op, const Mask& mask, cudaStream_t stream) + { + typedef TransformFunctorTraits ft; + transform_detail::TransformDispatcher::cn == 1 && VecTraits::cn == 1 && VecTraits::cn == 1 && ft::smart_shift != 1>::call(src1, src2, dst, op, mask, stream); + } +}}} + +//! @endcond + +#endif // OPENCV_CUDA_TRANSFORM_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/type_traits.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/type_traits.hpp new file mode 100755 index 0000000..8b7a3fd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/type_traits.hpp @@ -0,0 +1,90 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_TYPE_TRAITS_HPP +#define OPENCV_CUDA_TYPE_TRAITS_HPP + +#include "detail/type_traits_detail.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template struct IsSimpleParameter + { + enum {value = type_traits_detail::IsIntegral::value || type_traits_detail::IsFloat::value || + type_traits_detail::PointerTraits::type>::value}; + }; + + template struct TypeTraits + { + typedef typename type_traits_detail::UnConst::type NonConstType; + typedef typename type_traits_detail::UnVolatile::type NonVolatileType; + typedef typename type_traits_detail::UnVolatile::type>::type UnqualifiedType; + typedef typename type_traits_detail::PointerTraits::type PointeeType; + typedef typename type_traits_detail::ReferenceTraits::type ReferredType; + + enum { isConst = type_traits_detail::UnConst::value }; + enum { isVolatile = type_traits_detail::UnVolatile::value }; + + enum { isReference = type_traits_detail::ReferenceTraits::value }; + enum { isPointer = type_traits_detail::PointerTraits::type>::value }; + + enum { isUnsignedInt = type_traits_detail::IsUnsignedIntegral::value }; + enum { isSignedInt = type_traits_detail::IsSignedIntergral::value }; + enum { isIntegral = type_traits_detail::IsIntegral::value }; + enum { isFloat = type_traits_detail::IsFloat::value }; + enum { isArith = isIntegral || isFloat }; + enum { isVec = type_traits_detail::IsVec::value }; + + typedef typename type_traits_detail::Select::value, + T, typename type_traits_detail::AddParameterType::type>::type ParameterType; + }; +}}} + +//! @endcond + +#endif // OPENCV_CUDA_TYPE_TRAITS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/utility.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/utility.hpp new file mode 100755 index 0000000..7f5db48 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/utility.hpp @@ -0,0 +1,230 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_UTILITY_HPP +#define OPENCV_CUDA_UTILITY_HPP + +#include "saturate_cast.hpp" +#include "datamov_utils.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + struct CV_EXPORTS ThrustAllocator + { + typedef uchar value_type; + virtual ~ThrustAllocator(); + virtual __device__ __host__ uchar* allocate(size_t numBytes) = 0; + virtual __device__ __host__ void deallocate(uchar* ptr, size_t numBytes) = 0; + static ThrustAllocator& getAllocator(); + static void setAllocator(ThrustAllocator* allocator); + }; + #define OPENCV_CUDA_LOG_WARP_SIZE (5) + #define OPENCV_CUDA_WARP_SIZE (1 << OPENCV_CUDA_LOG_WARP_SIZE) + #define OPENCV_CUDA_LOG_MEM_BANKS ((__CUDA_ARCH__ >= 200) ? 5 : 4) // 32 banks on fermi, 16 on tesla + #define OPENCV_CUDA_MEM_BANKS (1 << OPENCV_CUDA_LOG_MEM_BANKS) + + /////////////////////////////////////////////////////////////////////////////// + // swap + + template void __device__ __host__ __forceinline__ swap(T& a, T& b) + { + const T temp = a; + a = b; + b = temp; + } + + /////////////////////////////////////////////////////////////////////////////// + // Mask Reader + + struct SingleMask + { + explicit __host__ __device__ __forceinline__ SingleMask(PtrStepb mask_) : mask(mask_) {} + __host__ __device__ __forceinline__ SingleMask(const SingleMask& mask_): mask(mask_.mask){} + + __device__ __forceinline__ bool operator()(int y, int x) const + { + return mask.ptr(y)[x] != 0; + } + + PtrStepb mask; + }; + + struct SingleMaskChannels + { + __host__ __device__ __forceinline__ SingleMaskChannels(PtrStepb mask_, int channels_) + : mask(mask_), channels(channels_) {} + __host__ __device__ __forceinline__ SingleMaskChannels(const SingleMaskChannels& mask_) + :mask(mask_.mask), channels(mask_.channels){} + + __device__ __forceinline__ bool operator()(int y, int x) const + { + return mask.ptr(y)[x / channels] != 0; + } + + PtrStepb mask; + int channels; + }; + + struct MaskCollection + { + explicit __host__ __device__ __forceinline__ MaskCollection(PtrStepb* maskCollection_) + : maskCollection(maskCollection_) {} + + __device__ __forceinline__ MaskCollection(const MaskCollection& masks_) + : maskCollection(masks_.maskCollection), curMask(masks_.curMask){} + + __device__ __forceinline__ void next() + { + curMask = *maskCollection++; + } + __device__ __forceinline__ void setMask(int z) + { + curMask = maskCollection[z]; + } + + __device__ __forceinline__ bool operator()(int y, int x) const + { + uchar val; + return curMask.data == 0 || (ForceGlob::Load(curMask.ptr(y), x, val), (val != 0)); + } + + const PtrStepb* maskCollection; + PtrStepb curMask; + }; + + struct WithOutMask + { + __host__ __device__ __forceinline__ WithOutMask(){} + __host__ __device__ __forceinline__ WithOutMask(const WithOutMask&){} + + __device__ __forceinline__ void next() const + { + } + __device__ __forceinline__ void setMask(int) const + { + } + + __device__ __forceinline__ bool operator()(int, int) const + { + return true; + } + + __device__ __forceinline__ bool operator()(int, int, int) const + { + return true; + } + + static __device__ __forceinline__ bool check(int, int) + { + return true; + } + + static __device__ __forceinline__ bool check(int, int, int) + { + return true; + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // Solve linear system + + // solve 2x2 linear system Ax=b + template __device__ __forceinline__ bool solve2x2(const T A[2][2], const T b[2], T x[2]) + { + T det = A[0][0] * A[1][1] - A[1][0] * A[0][1]; + + if (det != 0) + { + double invdet = 1.0 / det; + + x[0] = saturate_cast(invdet * (b[0] * A[1][1] - b[1] * A[0][1])); + + x[1] = saturate_cast(invdet * (A[0][0] * b[1] - A[1][0] * b[0])); + + return true; + } + + return false; + } + + // solve 3x3 linear system Ax=b + template __device__ __forceinline__ bool solve3x3(const T A[3][3], const T b[3], T x[3]) + { + T det = A[0][0] * (A[1][1] * A[2][2] - A[1][2] * A[2][1]) + - A[0][1] * (A[1][0] * A[2][2] - A[1][2] * A[2][0]) + + A[0][2] * (A[1][0] * A[2][1] - A[1][1] * A[2][0]); + + if (det != 0) + { + double invdet = 1.0 / det; + + x[0] = saturate_cast(invdet * + (b[0] * (A[1][1] * A[2][2] - A[1][2] * A[2][1]) - + A[0][1] * (b[1] * A[2][2] - A[1][2] * b[2] ) + + A[0][2] * (b[1] * A[2][1] - A[1][1] * b[2] ))); + + x[1] = saturate_cast(invdet * + (A[0][0] * (b[1] * A[2][2] - A[1][2] * b[2] ) - + b[0] * (A[1][0] * A[2][2] - A[1][2] * A[2][0]) + + A[0][2] * (A[1][0] * b[2] - b[1] * A[2][0]))); + + x[2] = saturate_cast(invdet * + (A[0][0] * (A[1][1] * b[2] - b[1] * A[2][1]) - + A[0][1] * (A[1][0] * b[2] - b[1] * A[2][0]) + + b[0] * (A[1][0] * A[2][1] - A[1][1] * A[2][0]))); + + return true; + } + + return false; + } +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_UTILITY_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_distance.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_distance.hpp new file mode 100755 index 0000000..ef6e510 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_distance.hpp @@ -0,0 +1,232 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_VEC_DISTANCE_HPP +#define OPENCV_CUDA_VEC_DISTANCE_HPP + +#include "reduce.hpp" +#include "functional.hpp" +#include "detail/vec_distance_detail.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template struct L1Dist + { + typedef int value_type; + typedef int result_type; + + __device__ __forceinline__ L1Dist() : mySum(0) {} + + __device__ __forceinline__ void reduceIter(int val1, int val2) + { + mySum = __sad(val1, val2, mySum); + } + + template __device__ __forceinline__ void reduceAll(int* smem, int tid) + { + reduce(smem, mySum, tid, plus()); + } + + __device__ __forceinline__ operator int() const + { + return mySum; + } + + int mySum; + }; + template <> struct L1Dist + { + typedef float value_type; + typedef float result_type; + + __device__ __forceinline__ L1Dist() : mySum(0.0f) {} + + __device__ __forceinline__ void reduceIter(float val1, float val2) + { + mySum += ::fabs(val1 - val2); + } + + template __device__ __forceinline__ void reduceAll(float* smem, int tid) + { + reduce(smem, mySum, tid, plus()); + } + + __device__ __forceinline__ operator float() const + { + return mySum; + } + + float mySum; + }; + + struct L2Dist + { + typedef float value_type; + typedef float result_type; + + __device__ __forceinline__ L2Dist() : mySum(0.0f) {} + + __device__ __forceinline__ void reduceIter(float val1, float val2) + { + float reg = val1 - val2; + mySum += reg * reg; + } + + template __device__ __forceinline__ void reduceAll(float* smem, int tid) + { + reduce(smem, mySum, tid, plus()); + } + + __device__ __forceinline__ operator float() const + { + return sqrtf(mySum); + } + + float mySum; + }; + + struct HammingDist + { + typedef int value_type; + typedef int result_type; + + __device__ __forceinline__ HammingDist() : mySum(0) {} + + __device__ __forceinline__ void reduceIter(int val1, int val2) + { + mySum += __popc(val1 ^ val2); + } + + template __device__ __forceinline__ void reduceAll(int* smem, int tid) + { + reduce(smem, mySum, tid, plus()); + } + + __device__ __forceinline__ operator int() const + { + return mySum; + } + + int mySum; + }; + + // calc distance between two vectors in global memory + template + __device__ void calcVecDiffGlobal(const T1* vec1, const T2* vec2, int len, Dist& dist, typename Dist::result_type* smem, int tid) + { + for (int i = tid; i < len; i += THREAD_DIM) + { + T1 val1; + ForceGlob::Load(vec1, i, val1); + + T2 val2; + ForceGlob::Load(vec2, i, val2); + + dist.reduceIter(val1, val2); + } + + dist.reduceAll(smem, tid); + } + + // calc distance between two vectors, first vector is cached in register or shared memory, second vector is in global memory + template + __device__ __forceinline__ void calcVecDiffCached(const T1* vecCached, const T2* vecGlob, int len, Dist& dist, typename Dist::result_type* smem, int tid) + { + vec_distance_detail::VecDiffCachedCalculator::calc(vecCached, vecGlob, len, dist, tid); + + dist.reduceAll(smem, tid); + } + + // calc distance between two vectors in global memory + template struct VecDiffGlobal + { + explicit __device__ __forceinline__ VecDiffGlobal(const T1* vec1_, int = 0, void* = 0, int = 0, int = 0) + { + vec1 = vec1_; + } + + template + __device__ __forceinline__ void calc(const T2* vec2, int len, Dist& dist, typename Dist::result_type* smem, int tid) const + { + calcVecDiffGlobal(vec1, vec2, len, dist, smem, tid); + } + + const T1* vec1; + }; + + // calc distance between two vectors, first vector is cached in register memory, second vector is in global memory + template struct VecDiffCachedRegister + { + template __device__ __forceinline__ VecDiffCachedRegister(const T1* vec1, int len, U* smem, int glob_tid, int tid) + { + if (glob_tid < len) + smem[glob_tid] = vec1[glob_tid]; + __syncthreads(); + + U* vec1ValsPtr = vec1Vals; + + #pragma unroll + for (int i = tid; i < MAX_LEN; i += THREAD_DIM) + *vec1ValsPtr++ = smem[i]; + + __syncthreads(); + } + + template + __device__ __forceinline__ void calc(const T2* vec2, int len, Dist& dist, typename Dist::result_type* smem, int tid) const + { + calcVecDiffCached(vec1Vals, vec2, len, dist, smem, tid); + } + + U vec1Vals[MAX_LEN / THREAD_DIM]; + }; +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_VEC_DISTANCE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_math.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_math.hpp new file mode 100755 index 0000000..80b1303 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_math.hpp @@ -0,0 +1,923 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_VECMATH_HPP +#define OPENCV_CUDA_VECMATH_HPP + +#include "vec_traits.hpp" +#include "saturate_cast.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + +// saturate_cast + +namespace vec_math_detail +{ + template struct SatCastHelper; + template struct SatCastHelper<1, VecD> + { + template static __device__ __forceinline__ VecD cast(const VecS& v) + { + typedef typename VecTraits::elem_type D; + return VecTraits::make(saturate_cast(v.x)); + } + }; + template struct SatCastHelper<2, VecD> + { + template static __device__ __forceinline__ VecD cast(const VecS& v) + { + typedef typename VecTraits::elem_type D; + return VecTraits::make(saturate_cast(v.x), saturate_cast(v.y)); + } + }; + template struct SatCastHelper<3, VecD> + { + template static __device__ __forceinline__ VecD cast(const VecS& v) + { + typedef typename VecTraits::elem_type D; + return VecTraits::make(saturate_cast(v.x), saturate_cast(v.y), saturate_cast(v.z)); + } + }; + template struct SatCastHelper<4, VecD> + { + template static __device__ __forceinline__ VecD cast(const VecS& v) + { + typedef typename VecTraits::elem_type D; + return VecTraits::make(saturate_cast(v.x), saturate_cast(v.y), saturate_cast(v.z), saturate_cast(v.w)); + } + }; + + template static __device__ __forceinline__ VecD saturate_cast_helper(const VecS& v) + { + return SatCastHelper::cn, VecD>::cast(v); + } +} + +template static __device__ __forceinline__ T saturate_cast(const uchar1& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const char1& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const ushort1& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const short1& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const uint1& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const int1& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const float1& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const double1& v) {return vec_math_detail::saturate_cast_helper(v);} + +template static __device__ __forceinline__ T saturate_cast(const uchar2& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const char2& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const ushort2& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const short2& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const uint2& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const int2& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const float2& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const double2& v) {return vec_math_detail::saturate_cast_helper(v);} + +template static __device__ __forceinline__ T saturate_cast(const uchar3& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const char3& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const ushort3& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const short3& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const uint3& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const int3& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const float3& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const double3& v) {return vec_math_detail::saturate_cast_helper(v);} + +template static __device__ __forceinline__ T saturate_cast(const uchar4& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const char4& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const ushort4& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const short4& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const uint4& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const int4& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const float4& v) {return vec_math_detail::saturate_cast_helper(v);} +template static __device__ __forceinline__ T saturate_cast(const double4& v) {return vec_math_detail::saturate_cast_helper(v);} + +// unary operators + +#define CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(op, input_type, output_type) \ + __device__ __forceinline__ output_type ## 1 operator op(const input_type ## 1 & a) \ + { \ + return VecTraits::make(op (a.x)); \ + } \ + __device__ __forceinline__ output_type ## 2 operator op(const input_type ## 2 & a) \ + { \ + return VecTraits::make(op (a.x), op (a.y)); \ + } \ + __device__ __forceinline__ output_type ## 3 operator op(const input_type ## 3 & a) \ + { \ + return VecTraits::make(op (a.x), op (a.y), op (a.z)); \ + } \ + __device__ __forceinline__ output_type ## 4 operator op(const input_type ## 4 & a) \ + { \ + return VecTraits::make(op (a.x), op (a.y), op (a.z), op (a.w)); \ + } + +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(-, char, char) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(-, short, short) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(-, int, int) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(-, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(-, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(!, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(~, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(~, char, char) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(~, ushort, ushort) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(~, short, short) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(~, int, int) +CV_CUDEV_IMPLEMENT_VEC_UNARY_OP(~, uint, uint) + +#undef CV_CUDEV_IMPLEMENT_VEC_UNARY_OP + +// unary functions + +#define CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(func_name, func, input_type, output_type) \ + __device__ __forceinline__ output_type ## 1 func_name(const input_type ## 1 & a) \ + { \ + return VecTraits::make(func (a.x)); \ + } \ + __device__ __forceinline__ output_type ## 2 func_name(const input_type ## 2 & a) \ + { \ + return VecTraits::make(func (a.x), func (a.y)); \ + } \ + __device__ __forceinline__ output_type ## 3 func_name(const input_type ## 3 & a) \ + { \ + return VecTraits::make(func (a.x), func (a.y), func (a.z)); \ + } \ + __device__ __forceinline__ output_type ## 4 func_name(const input_type ## 4 & a) \ + { \ + return VecTraits::make(func (a.x), func (a.y), func (a.z), func (a.w)); \ + } + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::fabsf, float, float) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrtf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrtf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrtf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrtf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrtf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrtf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrtf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sqrt, ::sqrt, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::expf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::expf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::expf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::expf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::expf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::expf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::expf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp, ::exp, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2f, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2f, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2f, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2f, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2f, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2f, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2f, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp2, ::exp2, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10f, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10f, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10f, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10f, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10f, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10f, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10f, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(exp10, ::exp10, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::logf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::logf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::logf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::logf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::logf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::logf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::logf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log, ::log, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2f, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2f, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2f, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2f, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2f, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2f, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2f, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log2, ::log2, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10f, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10f, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10f, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10f, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10f, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10f, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10f, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(log10, ::log10, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sinf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sinf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sinf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sinf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sinf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sinf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sinf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sin, ::sin, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cosf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cosf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cosf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cosf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cosf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cosf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cosf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cos, ::cos, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tanf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tanf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tanf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tanf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tanf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tanf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tanf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tan, ::tan, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asinf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asinf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asinf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asinf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asinf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asinf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asinf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asin, ::asin, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acosf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acosf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acosf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acosf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acosf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acosf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acosf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acos, ::acos, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atanf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atanf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atanf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atanf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atanf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atanf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atanf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atan, ::atan, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinhf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinhf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinhf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinhf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinhf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinhf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinhf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(sinh, ::sinh, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::coshf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::coshf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::coshf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::coshf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::coshf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::coshf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::coshf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(cosh, ::cosh, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanhf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanhf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanhf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanhf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanhf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanhf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanhf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(tanh, ::tanh, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinhf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinhf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinhf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinhf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinhf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinhf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinhf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(asinh, ::asinh, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acoshf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acoshf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acoshf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acoshf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acoshf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acoshf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acoshf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(acosh, ::acosh, double, double) + +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanhf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanhf, char, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanhf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanhf, short, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanhf, int, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanhf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanhf, float, float) +CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(atanh, ::atanh, double, double) + +#undef CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC + +// binary operators (vec & vec) + +#define CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(op, input_type, output_type) \ + __device__ __forceinline__ output_type ## 1 operator op(const input_type ## 1 & a, const input_type ## 1 & b) \ + { \ + return VecTraits::make(a.x op b.x); \ + } \ + __device__ __forceinline__ output_type ## 2 operator op(const input_type ## 2 & a, const input_type ## 2 & b) \ + { \ + return VecTraits::make(a.x op b.x, a.y op b.y); \ + } \ + __device__ __forceinline__ output_type ## 3 operator op(const input_type ## 3 & a, const input_type ## 3 & b) \ + { \ + return VecTraits::make(a.x op b.x, a.y op b.y, a.z op b.z); \ + } \ + __device__ __forceinline__ output_type ## 4 operator op(const input_type ## 4 & a, const input_type ## 4 & b) \ + { \ + return VecTraits::make(a.x op b.x, a.y op b.y, a.z op b.z, a.w op b.w); \ + } + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, uchar, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, char, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, ushort, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, short, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, uint, uint) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(+, double, double) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, uchar, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, char, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, ushort, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, short, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, uint, uint) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(-, double, double) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, uchar, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, char, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, ushort, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, short, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, uint, uint) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(*, double, double) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, uchar, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, char, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, ushort, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, short, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, uint, uint) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(/, double, double) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(==, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(!=, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(>=, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(<=, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&&, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, char, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, ushort, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, short, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, int, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, uint, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, float, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(||, double, uchar) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&, char, char) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&, ushort, ushort) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&, short, short) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(&, uint, uint) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(|, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(|, char, char) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(|, ushort, ushort) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(|, short, short) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(|, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(|, uint, uint) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(^, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(^, char, char) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(^, ushort, ushort) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(^, short, short) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(^, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_OP(^, uint, uint) + +#undef CV_CUDEV_IMPLEMENT_VEC_BINARY_OP + +// binary operators (vec & scalar) + +#define CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(op, input_type, scalar_type, output_type) \ + __device__ __forceinline__ output_type ## 1 operator op(const input_type ## 1 & a, scalar_type s) \ + { \ + return VecTraits::make(a.x op s); \ + } \ + __device__ __forceinline__ output_type ## 1 operator op(scalar_type s, const input_type ## 1 & b) \ + { \ + return VecTraits::make(s op b.x); \ + } \ + __device__ __forceinline__ output_type ## 2 operator op(const input_type ## 2 & a, scalar_type s) \ + { \ + return VecTraits::make(a.x op s, a.y op s); \ + } \ + __device__ __forceinline__ output_type ## 2 operator op(scalar_type s, const input_type ## 2 & b) \ + { \ + return VecTraits::make(s op b.x, s op b.y); \ + } \ + __device__ __forceinline__ output_type ## 3 operator op(const input_type ## 3 & a, scalar_type s) \ + { \ + return VecTraits::make(a.x op s, a.y op s, a.z op s); \ + } \ + __device__ __forceinline__ output_type ## 3 operator op(scalar_type s, const input_type ## 3 & b) \ + { \ + return VecTraits::make(s op b.x, s op b.y, s op b.z); \ + } \ + __device__ __forceinline__ output_type ## 4 operator op(const input_type ## 4 & a, scalar_type s) \ + { \ + return VecTraits::make(a.x op s, a.y op s, a.z op s, a.w op s); \ + } \ + __device__ __forceinline__ output_type ## 4 operator op(scalar_type s, const input_type ## 4 & b) \ + { \ + return VecTraits::make(s op b.x, s op b.y, s op b.z, s op b.w); \ + } + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, uchar, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, char, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, ushort, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, short, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, uint, uint, uint) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(+, double, double, double) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, uchar, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, char, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, ushort, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, short, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, uint, uint, uint) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(-, double, double, double) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, uchar, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, char, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, ushort, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, short, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, uint, uint, uint) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(*, double, double, double) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, uchar, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, char, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, ushort, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, short, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, uint, uint, uint) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(/, double, double, double) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(==, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(!=, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(>=, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(<=, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&&, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, char, char, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, ushort, ushort, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, short, short, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, int, int, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, uint, uint, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, float, float, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(||, double, double, uchar) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&, char, char, char) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&, ushort, ushort, ushort) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&, short, short, short) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(&, uint, uint, uint) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(|, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(|, char, char, char) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(|, ushort, ushort, ushort) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(|, short, short, short) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(|, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(|, uint, uint, uint) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(^, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(^, char, char, char) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(^, ushort, ushort, ushort) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(^, short, short, short) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(^, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP(^, uint, uint, uint) + +#undef CV_CUDEV_IMPLEMENT_SCALAR_BINARY_OP + +// binary function (vec & vec) + +#define CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(func_name, func, input_type, output_type) \ + __device__ __forceinline__ output_type ## 1 func_name(const input_type ## 1 & a, const input_type ## 1 & b) \ + { \ + return VecTraits::make(func (a.x, b.x)); \ + } \ + __device__ __forceinline__ output_type ## 2 func_name(const input_type ## 2 & a, const input_type ## 2 & b) \ + { \ + return VecTraits::make(func (a.x, b.x), func (a.y, b.y)); \ + } \ + __device__ __forceinline__ output_type ## 3 func_name(const input_type ## 3 & a, const input_type ## 3 & b) \ + { \ + return VecTraits::make(func (a.x, b.x), func (a.y, b.y), func (a.z, b.z)); \ + } \ + __device__ __forceinline__ output_type ## 4 func_name(const input_type ## 4 & a, const input_type ## 4 & b) \ + { \ + return VecTraits::make(func (a.x, b.x), func (a.y, b.y), func (a.z, b.z), func (a.w, b.w)); \ + } + +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::max, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::max, char, char) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::max, ushort, ushort) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::max, short, short) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::max, uint, uint) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::max, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::fmaxf, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(max, ::fmax, double, double) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::min, uchar, uchar) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::min, char, char) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::min, ushort, ushort) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::min, short, short) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::min, uint, uint) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::min, int, int) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::fminf, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(min, ::fmin, double, double) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypotf, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypotf, char, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypotf, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypotf, short, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypotf, uint, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypotf, int, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypotf, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(hypot, ::hypot, double, double) + +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2f, uchar, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2f, char, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2f, ushort, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2f, short, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2f, uint, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2f, int, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2f, float, float) +CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC(atan2, ::atan2, double, double) + +#undef CV_CUDEV_IMPLEMENT_VEC_BINARY_FUNC + +// binary function (vec & scalar) + +#define CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(func_name, func, input_type, scalar_type, output_type) \ + __device__ __forceinline__ output_type ## 1 func_name(const input_type ## 1 & a, scalar_type s) \ + { \ + return VecTraits::make(func ((output_type) a.x, (output_type) s)); \ + } \ + __device__ __forceinline__ output_type ## 1 func_name(scalar_type s, const input_type ## 1 & b) \ + { \ + return VecTraits::make(func ((output_type) s, (output_type) b.x)); \ + } \ + __device__ __forceinline__ output_type ## 2 func_name(const input_type ## 2 & a, scalar_type s) \ + { \ + return VecTraits::make(func ((output_type) a.x, (output_type) s), func ((output_type) a.y, (output_type) s)); \ + } \ + __device__ __forceinline__ output_type ## 2 func_name(scalar_type s, const input_type ## 2 & b) \ + { \ + return VecTraits::make(func ((output_type) s, (output_type) b.x), func ((output_type) s, (output_type) b.y)); \ + } \ + __device__ __forceinline__ output_type ## 3 func_name(const input_type ## 3 & a, scalar_type s) \ + { \ + return VecTraits::make(func ((output_type) a.x, (output_type) s), func ((output_type) a.y, (output_type) s), func ((output_type) a.z, (output_type) s)); \ + } \ + __device__ __forceinline__ output_type ## 3 func_name(scalar_type s, const input_type ## 3 & b) \ + { \ + return VecTraits::make(func ((output_type) s, (output_type) b.x), func ((output_type) s, (output_type) b.y), func ((output_type) s, (output_type) b.z)); \ + } \ + __device__ __forceinline__ output_type ## 4 func_name(const input_type ## 4 & a, scalar_type s) \ + { \ + return VecTraits::make(func ((output_type) a.x, (output_type) s), func ((output_type) a.y, (output_type) s), func ((output_type) a.z, (output_type) s), func ((output_type) a.w, (output_type) s)); \ + } \ + __device__ __forceinline__ output_type ## 4 func_name(scalar_type s, const input_type ## 4 & b) \ + { \ + return VecTraits::make(func ((output_type) s, (output_type) b.x), func ((output_type) s, (output_type) b.y), func ((output_type) s, (output_type) b.z), func ((output_type) s, (output_type) b.w)); \ + } + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::max, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmaxf, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::max, char, char, char) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmaxf, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::max, ushort, ushort, ushort) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmaxf, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::max, short, short, short) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmaxf, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::max, uint, uint, uint) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmaxf, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::max, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmaxf, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmaxf, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(max, ::fmax, double, double, double) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::min, uchar, uchar, uchar) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fminf, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::min, char, char, char) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fminf, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::min, ushort, ushort, ushort) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fminf, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::min, short, short, short) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fminf, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::min, uint, uint, uint) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fminf, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::min, int, int, int) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fminf, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fminf, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(min, ::fmin, double, double, double) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypotf, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypotf, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypotf, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypotf, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypotf, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypotf, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypotf, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(hypot, ::hypot, double, double, double) + +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2f, uchar, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, uchar, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2f, char, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, char, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2f, ushort, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, ushort, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2f, short, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, short, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2f, uint, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, uint, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2f, int, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, int, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2f, float, float, float) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, float, double, double) +CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, double, double, double) + +#undef CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC + +}}} // namespace cv { namespace cuda { namespace device + +//! @endcond + +#endif // OPENCV_CUDA_VECMATH_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_traits.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_traits.hpp new file mode 100755 index 0000000..b5ff281 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/vec_traits.hpp @@ -0,0 +1,288 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_VEC_TRAITS_HPP +#define OPENCV_CUDA_VEC_TRAITS_HPP + +#include "common.hpp" + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template struct TypeVec; + + struct __align__(8) uchar8 + { + uchar a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ uchar8 make_uchar8(uchar a0, uchar a1, uchar a2, uchar a3, uchar a4, uchar a5, uchar a6, uchar a7) + { + uchar8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + struct __align__(8) char8 + { + schar a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ char8 make_char8(schar a0, schar a1, schar a2, schar a3, schar a4, schar a5, schar a6, schar a7) + { + char8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + struct __align__(16) ushort8 + { + ushort a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ ushort8 make_ushort8(ushort a0, ushort a1, ushort a2, ushort a3, ushort a4, ushort a5, ushort a6, ushort a7) + { + ushort8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + struct __align__(16) short8 + { + short a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ short8 make_short8(short a0, short a1, short a2, short a3, short a4, short a5, short a6, short a7) + { + short8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + struct __align__(32) uint8 + { + uint a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ uint8 make_uint8(uint a0, uint a1, uint a2, uint a3, uint a4, uint a5, uint a6, uint a7) + { + uint8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + struct __align__(32) int8 + { + int a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ int8 make_int8(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) + { + int8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + struct __align__(32) float8 + { + float a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ float8 make_float8(float a0, float a1, float a2, float a3, float a4, float a5, float a6, float a7) + { + float8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + struct double8 + { + double a0, a1, a2, a3, a4, a5, a6, a7; + }; + static __host__ __device__ __forceinline__ double8 make_double8(double a0, double a1, double a2, double a3, double a4, double a5, double a6, double a7) + { + double8 val = {a0, a1, a2, a3, a4, a5, a6, a7}; + return val; + } + +#define OPENCV_CUDA_IMPLEMENT_TYPE_VEC(type) \ + template<> struct TypeVec { typedef type vec_type; }; \ + template<> struct TypeVec { typedef type ## 1 vec_type; }; \ + template<> struct TypeVec { typedef type ## 2 vec_type; }; \ + template<> struct TypeVec { typedef type ## 2 vec_type; }; \ + template<> struct TypeVec { typedef type ## 3 vec_type; }; \ + template<> struct TypeVec { typedef type ## 3 vec_type; }; \ + template<> struct TypeVec { typedef type ## 4 vec_type; }; \ + template<> struct TypeVec { typedef type ## 4 vec_type; }; \ + template<> struct TypeVec { typedef type ## 8 vec_type; }; \ + template<> struct TypeVec { typedef type ## 8 vec_type; }; + + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(uchar) + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(char) + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(ushort) + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(short) + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(int) + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(uint) + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(float) + OPENCV_CUDA_IMPLEMENT_TYPE_VEC(double) + + #undef OPENCV_CUDA_IMPLEMENT_TYPE_VEC + + template<> struct TypeVec { typedef schar vec_type; }; + template<> struct TypeVec { typedef char2 vec_type; }; + template<> struct TypeVec { typedef char3 vec_type; }; + template<> struct TypeVec { typedef char4 vec_type; }; + template<> struct TypeVec { typedef char8 vec_type; }; + + template<> struct TypeVec { typedef uchar vec_type; }; + template<> struct TypeVec { typedef uchar2 vec_type; }; + template<> struct TypeVec { typedef uchar3 vec_type; }; + template<> struct TypeVec { typedef uchar4 vec_type; }; + template<> struct TypeVec { typedef uchar8 vec_type; }; + + template struct VecTraits; + +#define OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(type) \ + template<> struct VecTraits \ + { \ + typedef type elem_type; \ + enum {cn=1}; \ + static __device__ __host__ __forceinline__ type all(type v) {return v;} \ + static __device__ __host__ __forceinline__ type make(type x) {return x;} \ + static __device__ __host__ __forceinline__ type make(const type* v) {return *v;} \ + }; \ + template<> struct VecTraits \ + { \ + typedef type elem_type; \ + enum {cn=1}; \ + static __device__ __host__ __forceinline__ type ## 1 all(type v) {return make_ ## type ## 1(v);} \ + static __device__ __host__ __forceinline__ type ## 1 make(type x) {return make_ ## type ## 1(x);} \ + static __device__ __host__ __forceinline__ type ## 1 make(const type* v) {return make_ ## type ## 1(*v);} \ + }; \ + template<> struct VecTraits \ + { \ + typedef type elem_type; \ + enum {cn=2}; \ + static __device__ __host__ __forceinline__ type ## 2 all(type v) {return make_ ## type ## 2(v, v);} \ + static __device__ __host__ __forceinline__ type ## 2 make(type x, type y) {return make_ ## type ## 2(x, y);} \ + static __device__ __host__ __forceinline__ type ## 2 make(const type* v) {return make_ ## type ## 2(v[0], v[1]);} \ + }; \ + template<> struct VecTraits \ + { \ + typedef type elem_type; \ + enum {cn=3}; \ + static __device__ __host__ __forceinline__ type ## 3 all(type v) {return make_ ## type ## 3(v, v, v);} \ + static __device__ __host__ __forceinline__ type ## 3 make(type x, type y, type z) {return make_ ## type ## 3(x, y, z);} \ + static __device__ __host__ __forceinline__ type ## 3 make(const type* v) {return make_ ## type ## 3(v[0], v[1], v[2]);} \ + }; \ + template<> struct VecTraits \ + { \ + typedef type elem_type; \ + enum {cn=4}; \ + static __device__ __host__ __forceinline__ type ## 4 all(type v) {return make_ ## type ## 4(v, v, v, v);} \ + static __device__ __host__ __forceinline__ type ## 4 make(type x, type y, type z, type w) {return make_ ## type ## 4(x, y, z, w);} \ + static __device__ __host__ __forceinline__ type ## 4 make(const type* v) {return make_ ## type ## 4(v[0], v[1], v[2], v[3]);} \ + }; \ + template<> struct VecTraits \ + { \ + typedef type elem_type; \ + enum {cn=8}; \ + static __device__ __host__ __forceinline__ type ## 8 all(type v) {return make_ ## type ## 8(v, v, v, v, v, v, v, v);} \ + static __device__ __host__ __forceinline__ type ## 8 make(type a0, type a1, type a2, type a3, type a4, type a5, type a6, type a7) {return make_ ## type ## 8(a0, a1, a2, a3, a4, a5, a6, a7);} \ + static __device__ __host__ __forceinline__ type ## 8 make(const type* v) {return make_ ## type ## 8(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);} \ + }; + + OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(uchar) + OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(ushort) + OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(short) + OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(int) + OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(uint) + OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(float) + OPENCV_CUDA_IMPLEMENT_VEC_TRAITS(double) + + #undef OPENCV_CUDA_IMPLEMENT_VEC_TRAITS + + template<> struct VecTraits + { + typedef char elem_type; + enum {cn=1}; + static __device__ __host__ __forceinline__ char all(char v) {return v;} + static __device__ __host__ __forceinline__ char make(char x) {return x;} + static __device__ __host__ __forceinline__ char make(const char* x) {return *x;} + }; + template<> struct VecTraits + { + typedef schar elem_type; + enum {cn=1}; + static __device__ __host__ __forceinline__ schar all(schar v) {return v;} + static __device__ __host__ __forceinline__ schar make(schar x) {return x;} + static __device__ __host__ __forceinline__ schar make(const schar* x) {return *x;} + }; + template<> struct VecTraits + { + typedef schar elem_type; + enum {cn=1}; + static __device__ __host__ __forceinline__ char1 all(schar v) {return make_char1(v);} + static __device__ __host__ __forceinline__ char1 make(schar x) {return make_char1(x);} + static __device__ __host__ __forceinline__ char1 make(const schar* v) {return make_char1(v[0]);} + }; + template<> struct VecTraits + { + typedef schar elem_type; + enum {cn=2}; + static __device__ __host__ __forceinline__ char2 all(schar v) {return make_char2(v, v);} + static __device__ __host__ __forceinline__ char2 make(schar x, schar y) {return make_char2(x, y);} + static __device__ __host__ __forceinline__ char2 make(const schar* v) {return make_char2(v[0], v[1]);} + }; + template<> struct VecTraits + { + typedef schar elem_type; + enum {cn=3}; + static __device__ __host__ __forceinline__ char3 all(schar v) {return make_char3(v, v, v);} + static __device__ __host__ __forceinline__ char3 make(schar x, schar y, schar z) {return make_char3(x, y, z);} + static __device__ __host__ __forceinline__ char3 make(const schar* v) {return make_char3(v[0], v[1], v[2]);} + }; + template<> struct VecTraits + { + typedef schar elem_type; + enum {cn=4}; + static __device__ __host__ __forceinline__ char4 all(schar v) {return make_char4(v, v, v, v);} + static __device__ __host__ __forceinline__ char4 make(schar x, schar y, schar z, schar w) {return make_char4(x, y, z, w);} + static __device__ __host__ __forceinline__ char4 make(const schar* v) {return make_char4(v[0], v[1], v[2], v[3]);} + }; + template<> struct VecTraits + { + typedef schar elem_type; + enum {cn=8}; + static __device__ __host__ __forceinline__ char8 all(schar v) {return make_char8(v, v, v, v, v, v, v, v);} + static __device__ __host__ __forceinline__ char8 make(schar a0, schar a1, schar a2, schar a3, schar a4, schar a5, schar a6, schar a7) {return make_char8(a0, a1, a2, a3, a4, a5, a6, a7);} + static __device__ __host__ __forceinline__ char8 make(const schar* v) {return make_char8(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);} + }; +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif // OPENCV_CUDA_VEC_TRAITS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp.hpp new file mode 100755 index 0000000..8af7e6a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp.hpp @@ -0,0 +1,139 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_DEVICE_WARP_HPP +#define OPENCV_CUDA_DEVICE_WARP_HPP + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + struct Warp + { + enum + { + LOG_WARP_SIZE = 5, + WARP_SIZE = 1 << LOG_WARP_SIZE, + STRIDE = WARP_SIZE + }; + + /** \brief Returns the warp lane ID of the calling thread. */ + static __device__ __forceinline__ unsigned int laneId() + { + unsigned int ret; + asm("mov.u32 %0, %%laneid;" : "=r"(ret) ); + return ret; + } + + template + static __device__ __forceinline__ void fill(It beg, It end, const T& value) + { + for(It t = beg + laneId(); t < end; t += STRIDE) + *t = value; + } + + template + static __device__ __forceinline__ OutIt copy(InIt beg, InIt end, OutIt out) + { + for(InIt t = beg + laneId(); t < end; t += STRIDE, out += STRIDE) + *out = *t; + return out; + } + + template + static __device__ __forceinline__ OutIt transform(InIt beg, InIt end, OutIt out, UnOp op) + { + for(InIt t = beg + laneId(); t < end; t += STRIDE, out += STRIDE) + *out = op(*t); + return out; + } + + template + static __device__ __forceinline__ OutIt transform(InIt1 beg1, InIt1 end1, InIt2 beg2, OutIt out, BinOp op) + { + unsigned int lane = laneId(); + + InIt1 t1 = beg1 + lane; + InIt2 t2 = beg2 + lane; + for(; t1 < end1; t1 += STRIDE, t2 += STRIDE, out += STRIDE) + *out = op(*t1, *t2); + return out; + } + + template + static __device__ __forceinline__ T reduce(volatile T *ptr, BinOp op) + { + const unsigned int lane = laneId(); + + if (lane < 16) + { + T partial = ptr[lane]; + + ptr[lane] = partial = op(partial, ptr[lane + 16]); + ptr[lane] = partial = op(partial, ptr[lane + 8]); + ptr[lane] = partial = op(partial, ptr[lane + 4]); + ptr[lane] = partial = op(partial, ptr[lane + 2]); + ptr[lane] = partial = op(partial, ptr[lane + 1]); + } + + return *ptr; + } + + template + static __device__ __forceinline__ void yota(OutIt beg, OutIt end, T value) + { + unsigned int lane = laneId(); + value += lane; + + for(OutIt t = beg + lane; t < end; t += STRIDE, value += STRIDE) + *t = value; + } + }; +}}} // namespace cv { namespace cuda { namespace cudev + +//! @endcond + +#endif /* OPENCV_CUDA_DEVICE_WARP_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_reduce.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_reduce.hpp new file mode 100755 index 0000000..530303d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_reduce.hpp @@ -0,0 +1,76 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_WARP_REDUCE_HPP__ +#define OPENCV_CUDA_WARP_REDUCE_HPP__ + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ + template + __device__ __forceinline__ T warp_reduce(volatile T *ptr , const unsigned int tid = threadIdx.x) + { + const unsigned int lane = tid & 31; // index of thread in warp (0..31) + + if (lane < 16) + { + T partial = ptr[tid]; + + ptr[tid] = partial = partial + ptr[tid + 16]; + ptr[tid] = partial = partial + ptr[tid + 8]; + ptr[tid] = partial = partial + ptr[tid + 4]; + ptr[tid] = partial = partial + ptr[tid + 2]; + ptr[tid] = partial = partial + ptr[tid + 1]; + } + + return ptr[tid - lane]; + } +}}} // namespace cv { namespace cuda { namespace cudev { + +//! @endcond + +#endif /* OPENCV_CUDA_WARP_REDUCE_HPP__ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_shuffle.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_shuffle.hpp new file mode 100755 index 0000000..0da54ae --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda/warp_shuffle.hpp @@ -0,0 +1,162 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CUDA_WARP_SHUFFLE_HPP +#define OPENCV_CUDA_WARP_SHUFFLE_HPP + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +namespace cv { namespace cuda { namespace device +{ +#if __CUDACC_VER_MAJOR__ >= 9 +# define __shfl(x, y, z) __shfl_sync(0xFFFFFFFFU, x, y, z) +# define __shfl_up(x, y, z) __shfl_up_sync(0xFFFFFFFFU, x, y, z) +# define __shfl_down(x, y, z) __shfl_down_sync(0xFFFFFFFFU, x, y, z) +#endif + template + __device__ __forceinline__ T shfl(T val, int srcLane, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + return __shfl(val, srcLane, width); + #else + return T(); + #endif + } + __device__ __forceinline__ unsigned int shfl(unsigned int val, int srcLane, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + return (unsigned int) __shfl((int) val, srcLane, width); + #else + return 0; + #endif + } + __device__ __forceinline__ double shfl(double val, int srcLane, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + int lo = __double2loint(val); + int hi = __double2hiint(val); + + lo = __shfl(lo, srcLane, width); + hi = __shfl(hi, srcLane, width); + + return __hiloint2double(hi, lo); + #else + return 0.0; + #endif + } + + template + __device__ __forceinline__ T shfl_down(T val, unsigned int delta, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + return __shfl_down(val, delta, width); + #else + return T(); + #endif + } + __device__ __forceinline__ unsigned int shfl_down(unsigned int val, unsigned int delta, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + return (unsigned int) __shfl_down((int) val, delta, width); + #else + return 0; + #endif + } + __device__ __forceinline__ double shfl_down(double val, unsigned int delta, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + int lo = __double2loint(val); + int hi = __double2hiint(val); + + lo = __shfl_down(lo, delta, width); + hi = __shfl_down(hi, delta, width); + + return __hiloint2double(hi, lo); + #else + return 0.0; + #endif + } + + template + __device__ __forceinline__ T shfl_up(T val, unsigned int delta, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + return __shfl_up(val, delta, width); + #else + return T(); + #endif + } + __device__ __forceinline__ unsigned int shfl_up(unsigned int val, unsigned int delta, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + return (unsigned int) __shfl_up((int) val, delta, width); + #else + return 0; + #endif + } + __device__ __forceinline__ double shfl_up(double val, unsigned int delta, int width = warpSize) + { + #if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 300 + int lo = __double2loint(val); + int hi = __double2hiint(val); + + lo = __shfl_up(lo, delta, width); + hi = __shfl_up(hi, delta, width); + + return __hiloint2double(hi, lo); + #else + return 0.0; + #endif + } +}}} + +# undef __shfl +# undef __shfl_up +# undef __shfl_down + +//! @endcond + +#endif // OPENCV_CUDA_WARP_SHUFFLE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda_stream_accessor.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda_stream_accessor.hpp new file mode 100755 index 0000000..deaf356 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda_stream_accessor.hpp @@ -0,0 +1,86 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_CUDA_STREAM_ACCESSOR_HPP +#define OPENCV_CORE_CUDA_STREAM_ACCESSOR_HPP + +#ifndef __cplusplus +# error cuda_stream_accessor.hpp header must be compiled as C++ +#endif + +/** @file cuda_stream_accessor.hpp + * This is only header file that depends on CUDA Runtime API. All other headers are independent. + */ + +#include +#include "opencv2/core/cuda.hpp" + +namespace cv +{ + namespace cuda + { + +//! @addtogroup cudacore_struct +//! @{ + + /** @brief Class that enables getting cudaStream_t from cuda::Stream + */ + struct StreamAccessor + { + CV_EXPORTS static cudaStream_t getStream(const Stream& stream); + CV_EXPORTS static Stream wrapStream(cudaStream_t stream); + }; + + /** @brief Class that enables getting cudaEvent_t from cuda::Event + */ + struct EventAccessor + { + CV_EXPORTS static cudaEvent_t getEvent(const Event& event); + CV_EXPORTS static Event wrapEvent(cudaEvent_t event); + }; + +//! @} + + } +} + +#endif /* OPENCV_CORE_CUDA_STREAM_ACCESSOR_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cuda_types.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cuda_types.hpp new file mode 100755 index 0000000..45dc2ca --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cuda_types.hpp @@ -0,0 +1,144 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_CUDA_TYPES_HPP +#define OPENCV_CORE_CUDA_TYPES_HPP + +#ifndef __cplusplus +# error cuda_types.hpp header must be compiled as C++ +#endif + +#if defined(__OPENCV_BUILD) && defined(__clang__) +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif +#if defined(__OPENCV_BUILD) && defined(__GNUC__) && __GNUC__ >= 5 +#pragma GCC diagnostic ignored "-Wsuggest-override" +#endif + +/** @file + * @deprecated Use @ref cudev instead. + */ + +//! @cond IGNORED + +#ifdef __CUDACC__ + #define __CV_CUDA_HOST_DEVICE__ __host__ __device__ __forceinline__ +#else + #define __CV_CUDA_HOST_DEVICE__ +#endif + +namespace cv +{ + namespace cuda + { + + // Simple lightweight structures that encapsulates information about an image on device. + // It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile + + template struct DevPtr + { + typedef T elem_type; + typedef int index_type; + + enum { elem_size = sizeof(elem_type) }; + + T* data; + + __CV_CUDA_HOST_DEVICE__ DevPtr() : data(0) {} + __CV_CUDA_HOST_DEVICE__ DevPtr(T* data_) : data(data_) {} + + __CV_CUDA_HOST_DEVICE__ size_t elemSize() const { return elem_size; } + __CV_CUDA_HOST_DEVICE__ operator T*() { return data; } + __CV_CUDA_HOST_DEVICE__ operator const T*() const { return data; } + }; + + template struct PtrSz : public DevPtr + { + __CV_CUDA_HOST_DEVICE__ PtrSz() : size(0) {} + __CV_CUDA_HOST_DEVICE__ PtrSz(T* data_, size_t size_) : DevPtr(data_), size(size_) {} + + size_t size; + }; + + template struct PtrStep : public DevPtr + { + __CV_CUDA_HOST_DEVICE__ PtrStep() : step(0) {} + __CV_CUDA_HOST_DEVICE__ PtrStep(T* data_, size_t step_) : DevPtr(data_), step(step_) {} + + size_t step; + + __CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr::data + y * step); } + __CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr::data + y * step); } + + __CV_CUDA_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } + __CV_CUDA_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } + }; + + template struct PtrStepSz : public PtrStep + { + __CV_CUDA_HOST_DEVICE__ PtrStepSz() : cols(0), rows(0) {} + __CV_CUDA_HOST_DEVICE__ PtrStepSz(int rows_, int cols_, T* data_, size_t step_) + : PtrStep(data_, step_), cols(cols_), rows(rows_) {} + + template + explicit PtrStepSz(const PtrStepSz& d) : PtrStep((T*)d.data, d.step), cols(d.cols), rows(d.rows){} + + int cols; + int rows; + }; + + typedef PtrStepSz PtrStepSzb; + typedef PtrStepSz PtrStepSzus; + typedef PtrStepSz PtrStepSzf; + typedef PtrStepSz PtrStepSzi; + + typedef PtrStep PtrStepb; + typedef PtrStep PtrStepus; + typedef PtrStep PtrStepf; + typedef PtrStep PtrStepi; + + } +} + +//! @endcond + +#endif /* OPENCV_CORE_CUDA_TYPES_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_dispatch.h b/Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_dispatch.h new file mode 100755 index 0000000..483cc8f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_dispatch.h @@ -0,0 +1,321 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#if defined __OPENCV_BUILD \ + +#include "cv_cpu_config.h" +#include "cv_cpu_helper.h" + +#ifdef CV_CPU_DISPATCH_MODE +#define CV_CPU_OPTIMIZATION_NAMESPACE __CV_CAT(opt_, CV_CPU_DISPATCH_MODE) +#define CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN namespace __CV_CAT(opt_, CV_CPU_DISPATCH_MODE) { +#define CV_CPU_OPTIMIZATION_NAMESPACE_END } +#else +#define CV_CPU_OPTIMIZATION_NAMESPACE cpu_baseline +#define CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN namespace cpu_baseline { +#define CV_CPU_OPTIMIZATION_NAMESPACE_END } +#define CV_CPU_BASELINE_MODE 1 +#endif + + +#define __CV_CPU_DISPATCH_CHAIN_END(fn, args, mode, ...) /* done */ +#define __CV_CPU_DISPATCH(fn, args, mode, ...) __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) +#define __CV_CPU_DISPATCH_EXPAND(fn, args, ...) __CV_EXPAND(__CV_CPU_DISPATCH(fn, args, __VA_ARGS__)) +#define CV_CPU_DISPATCH(fn, args, ...) __CV_CPU_DISPATCH_EXPAND(fn, args, __VA_ARGS__, END) // expand macros + + +#if defined CV_ENABLE_INTRINSICS \ + && !defined CV_DISABLE_OPTIMIZATION \ + && !defined __CUDACC__ /* do not include SSE/AVX/NEON headers for NVCC compiler */ \ + +#ifdef CV_CPU_COMPILE_SSE2 +# include +# define CV_MMX 1 +# define CV_SSE 1 +# define CV_SSE2 1 +#endif +#ifdef CV_CPU_COMPILE_SSE3 +# include +# define CV_SSE3 1 +#endif +#ifdef CV_CPU_COMPILE_SSSE3 +# include +# define CV_SSSE3 1 +#endif +#ifdef CV_CPU_COMPILE_SSE4_1 +# include +# define CV_SSE4_1 1 +#endif +#ifdef CV_CPU_COMPILE_SSE4_2 +# include +# define CV_SSE4_2 1 +#endif +#ifdef CV_CPU_COMPILE_POPCNT +# ifdef _MSC_VER +# include +# if defined(_M_X64) +# define CV_POPCNT_U64 _mm_popcnt_u64 +# endif +# define CV_POPCNT_U32 _mm_popcnt_u32 +# else +# include +# if defined(__x86_64__) +# define CV_POPCNT_U64 __builtin_popcountll +# endif +# define CV_POPCNT_U32 __builtin_popcount +# endif +# define CV_POPCNT 1 +#endif +#ifdef CV_CPU_COMPILE_AVX +# include +# define CV_AVX 1 +#endif +#ifdef CV_CPU_COMPILE_FP16 +# if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) +# include +# else +# include +# endif +# define CV_FP16 1 +#endif +#ifdef CV_CPU_COMPILE_AVX2 +# include +# define CV_AVX2 1 +#endif +#ifdef CV_CPU_COMPILE_AVX_512F +# include +# define CV_AVX_512F 1 +#endif +#ifdef CV_CPU_COMPILE_AVX512_COMMON +# define CV_AVX512_COMMON 1 +# define CV_AVX_512CD 1 +#endif +#ifdef CV_CPU_COMPILE_AVX512_KNL +# define CV_AVX512_KNL 1 +# define CV_AVX_512ER 1 +# define CV_AVX_512PF 1 +#endif +#ifdef CV_CPU_COMPILE_AVX512_KNM +# define CV_AVX512_KNM 1 +# define CV_AVX_5124FMAPS 1 +# define CV_AVX_5124VNNIW 1 +# define CV_AVX_512VPOPCNTDQ 1 +#endif +#ifdef CV_CPU_COMPILE_AVX512_SKX +# define CV_AVX512_SKX 1 +# define CV_AVX_512VL 1 +# define CV_AVX_512BW 1 +# define CV_AVX_512DQ 1 +#endif +#ifdef CV_CPU_COMPILE_AVX512_CNL +# define CV_AVX512_CNL 1 +# define CV_AVX_512IFMA 1 +# define CV_AVX_512VBMI 1 +#endif +#ifdef CV_CPU_COMPILE_AVX512_CEL +# define CV_AVX512_CEL 1 +# define CV_AVX_512VNNI 1 +#endif +#ifdef CV_CPU_COMPILE_AVX512_ICL +# define CV_AVX512_ICL 1 +# define CV_AVX_512VBMI2 1 +# define CV_AVX_512BITALG 1 +# define CV_AVX_512VPOPCNTDQ 1 +#endif +#ifdef CV_CPU_COMPILE_FMA3 +# define CV_FMA3 1 +#endif + +#if defined _WIN32 && defined(_M_ARM) +# include +# include +# define CV_NEON 1 +#elif defined(__ARM_NEON__) || (defined (__ARM_NEON) && defined(__aarch64__)) +# include +# define CV_NEON 1 +#endif + +#if defined(__ARM_NEON__) || defined(__aarch64__) +# include +#endif + +#ifdef CV_CPU_COMPILE_VSX +# include +# undef vector +# undef pixel +# undef bool +# define CV_VSX 1 +#endif + +#ifdef CV_CPU_COMPILE_VSX3 +# define CV_VSX3 1 +#endif + +#endif // CV_ENABLE_INTRINSICS && !CV_DISABLE_OPTIMIZATION && !__CUDACC__ + +#if defined CV_CPU_COMPILE_AVX && !defined CV_CPU_BASELINE_COMPILE_AVX +struct VZeroUpperGuard { +#ifdef __GNUC__ + __attribute__((always_inline)) +#endif + inline VZeroUpperGuard() { _mm256_zeroupper(); } +#ifdef __GNUC__ + __attribute__((always_inline)) +#endif + inline ~VZeroUpperGuard() { _mm256_zeroupper(); } +}; +#define __CV_AVX_GUARD VZeroUpperGuard __vzeroupper_guard; CV_UNUSED(__vzeroupper_guard); +#endif + +#ifdef __CV_AVX_GUARD +#define CV_AVX_GUARD __CV_AVX_GUARD +#else +#define CV_AVX_GUARD +#endif + +#endif // __OPENCV_BUILD + + + +#if !defined __OPENCV_BUILD /* Compatibility code */ \ + && !defined __CUDACC__ /* do not include SSE/AVX/NEON headers for NVCC compiler */ +#if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2) +# include +# define CV_MMX 1 +# define CV_SSE 1 +# define CV_SSE2 1 +#elif defined _WIN32 && defined(_M_ARM) +# include +# include +# define CV_NEON 1 +#elif defined(__ARM_NEON__) || (defined (__ARM_NEON) && defined(__aarch64__)) +# include +# define CV_NEON 1 +#elif defined(__VSX__) && defined(__PPC64__) && defined(__LITTLE_ENDIAN__) +# include +# undef vector +# undef pixel +# undef bool +# define CV_VSX 1 +#endif + +#endif // !__OPENCV_BUILD && !__CUDACC (Compatibility code) + + + +#ifndef CV_MMX +# define CV_MMX 0 +#endif +#ifndef CV_SSE +# define CV_SSE 0 +#endif +#ifndef CV_SSE2 +# define CV_SSE2 0 +#endif +#ifndef CV_SSE3 +# define CV_SSE3 0 +#endif +#ifndef CV_SSSE3 +# define CV_SSSE3 0 +#endif +#ifndef CV_SSE4_1 +# define CV_SSE4_1 0 +#endif +#ifndef CV_SSE4_2 +# define CV_SSE4_2 0 +#endif +#ifndef CV_POPCNT +# define CV_POPCNT 0 +#endif +#ifndef CV_AVX +# define CV_AVX 0 +#endif +#ifndef CV_FP16 +# define CV_FP16 0 +#endif +#ifndef CV_AVX2 +# define CV_AVX2 0 +#endif +#ifndef CV_FMA3 +# define CV_FMA3 0 +#endif +#ifndef CV_AVX_512F +# define CV_AVX_512F 0 +#endif +#ifndef CV_AVX_512BW +# define CV_AVX_512BW 0 +#endif +#ifndef CV_AVX_512CD +# define CV_AVX_512CD 0 +#endif +#ifndef CV_AVX_512DQ +# define CV_AVX_512DQ 0 +#endif +#ifndef CV_AVX_512ER +# define CV_AVX_512ER 0 +#endif +#ifndef CV_AVX_512IFMA +# define CV_AVX_512IFMA 0 +#endif +#define CV_AVX_512IFMA512 CV_AVX_512IFMA // deprecated +#ifndef CV_AVX_512PF +# define CV_AVX_512PF 0 +#endif +#ifndef CV_AVX_512VBMI +# define CV_AVX_512VBMI 0 +#endif +#ifndef CV_AVX_512VL +# define CV_AVX_512VL 0 +#endif +#ifndef CV_AVX_5124FMAPS +# define CV_AVX_5124FMAPS 0 +#endif +#ifndef CV_AVX_5124VNNIW +# define CV_AVX_5124VNNIW 0 +#endif +#ifndef CV_AVX_512VPOPCNTDQ +# define CV_AVX_512VPOPCNTDQ 0 +#endif +#ifndef CV_AVX_512VNNI +# define CV_AVX_512VNNI 0 +#endif +#ifndef CV_AVX_512VBMI2 +# define CV_AVX_512VBMI2 0 +#endif +#ifndef CV_AVX_512BITALG +# define CV_AVX_512BITALG 0 +#endif +#ifndef CV_AVX512_COMMON +# define CV_AVX512_COMMON 0 +#endif +#ifndef CV_AVX512_KNL +# define CV_AVX512_KNL 0 +#endif +#ifndef CV_AVX512_KNM +# define CV_AVX512_KNM 0 +#endif +#ifndef CV_AVX512_SKX +# define CV_AVX512_SKX 0 +#endif +#ifndef CV_AVX512_CNL +# define CV_AVX512_CNL 0 +#endif +#ifndef CV_AVX512_CEL +# define CV_AVX512_CEL 0 +#endif +#ifndef CV_AVX512_ICL +# define CV_AVX512_ICL 0 +#endif + +#ifndef CV_NEON +# define CV_NEON 0 +#endif + +#ifndef CV_VSX +# define CV_VSX 0 +#endif + +#ifndef CV_VSX3 +# define CV_VSX3 0 +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_helper.h b/Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_helper.h new file mode 100755 index 0000000..90e0e9b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cv_cpu_helper.h @@ -0,0 +1,466 @@ +// AUTOGENERATED, DO NOT EDIT + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_SSE +# define CV_TRY_SSE 1 +# define CV_CPU_FORCE_SSE 1 +# define CV_CPU_HAS_SUPPORT_SSE 1 +# define CV_CPU_CALL_SSE(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_SSE_(fn, args) return (opt_SSE::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_SSE +# define CV_TRY_SSE 1 +# define CV_CPU_FORCE_SSE 0 +# define CV_CPU_HAS_SUPPORT_SSE (cv::checkHardwareSupport(CV_CPU_SSE)) +# define CV_CPU_CALL_SSE(fn, args) if (CV_CPU_HAS_SUPPORT_SSE) return (opt_SSE::fn args) +# define CV_CPU_CALL_SSE_(fn, args) if (CV_CPU_HAS_SUPPORT_SSE) return (opt_SSE::fn args) +#else +# define CV_TRY_SSE 0 +# define CV_CPU_FORCE_SSE 0 +# define CV_CPU_HAS_SUPPORT_SSE 0 +# define CV_CPU_CALL_SSE(fn, args) +# define CV_CPU_CALL_SSE_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_SSE(fn, args, mode, ...) CV_CPU_CALL_SSE(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_SSE2 +# define CV_TRY_SSE2 1 +# define CV_CPU_FORCE_SSE2 1 +# define CV_CPU_HAS_SUPPORT_SSE2 1 +# define CV_CPU_CALL_SSE2(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_SSE2_(fn, args) return (opt_SSE2::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_SSE2 +# define CV_TRY_SSE2 1 +# define CV_CPU_FORCE_SSE2 0 +# define CV_CPU_HAS_SUPPORT_SSE2 (cv::checkHardwareSupport(CV_CPU_SSE2)) +# define CV_CPU_CALL_SSE2(fn, args) if (CV_CPU_HAS_SUPPORT_SSE2) return (opt_SSE2::fn args) +# define CV_CPU_CALL_SSE2_(fn, args) if (CV_CPU_HAS_SUPPORT_SSE2) return (opt_SSE2::fn args) +#else +# define CV_TRY_SSE2 0 +# define CV_CPU_FORCE_SSE2 0 +# define CV_CPU_HAS_SUPPORT_SSE2 0 +# define CV_CPU_CALL_SSE2(fn, args) +# define CV_CPU_CALL_SSE2_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_SSE2(fn, args, mode, ...) CV_CPU_CALL_SSE2(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_SSE3 +# define CV_TRY_SSE3 1 +# define CV_CPU_FORCE_SSE3 1 +# define CV_CPU_HAS_SUPPORT_SSE3 1 +# define CV_CPU_CALL_SSE3(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_SSE3_(fn, args) return (opt_SSE3::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_SSE3 +# define CV_TRY_SSE3 1 +# define CV_CPU_FORCE_SSE3 0 +# define CV_CPU_HAS_SUPPORT_SSE3 (cv::checkHardwareSupport(CV_CPU_SSE3)) +# define CV_CPU_CALL_SSE3(fn, args) if (CV_CPU_HAS_SUPPORT_SSE3) return (opt_SSE3::fn args) +# define CV_CPU_CALL_SSE3_(fn, args) if (CV_CPU_HAS_SUPPORT_SSE3) return (opt_SSE3::fn args) +#else +# define CV_TRY_SSE3 0 +# define CV_CPU_FORCE_SSE3 0 +# define CV_CPU_HAS_SUPPORT_SSE3 0 +# define CV_CPU_CALL_SSE3(fn, args) +# define CV_CPU_CALL_SSE3_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_SSE3(fn, args, mode, ...) CV_CPU_CALL_SSE3(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_SSSE3 +# define CV_TRY_SSSE3 1 +# define CV_CPU_FORCE_SSSE3 1 +# define CV_CPU_HAS_SUPPORT_SSSE3 1 +# define CV_CPU_CALL_SSSE3(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_SSSE3_(fn, args) return (opt_SSSE3::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_SSSE3 +# define CV_TRY_SSSE3 1 +# define CV_CPU_FORCE_SSSE3 0 +# define CV_CPU_HAS_SUPPORT_SSSE3 (cv::checkHardwareSupport(CV_CPU_SSSE3)) +# define CV_CPU_CALL_SSSE3(fn, args) if (CV_CPU_HAS_SUPPORT_SSSE3) return (opt_SSSE3::fn args) +# define CV_CPU_CALL_SSSE3_(fn, args) if (CV_CPU_HAS_SUPPORT_SSSE3) return (opt_SSSE3::fn args) +#else +# define CV_TRY_SSSE3 0 +# define CV_CPU_FORCE_SSSE3 0 +# define CV_CPU_HAS_SUPPORT_SSSE3 0 +# define CV_CPU_CALL_SSSE3(fn, args) +# define CV_CPU_CALL_SSSE3_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_SSSE3(fn, args, mode, ...) CV_CPU_CALL_SSSE3(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_SSE4_1 +# define CV_TRY_SSE4_1 1 +# define CV_CPU_FORCE_SSE4_1 1 +# define CV_CPU_HAS_SUPPORT_SSE4_1 1 +# define CV_CPU_CALL_SSE4_1(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_SSE4_1_(fn, args) return (opt_SSE4_1::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_SSE4_1 +# define CV_TRY_SSE4_1 1 +# define CV_CPU_FORCE_SSE4_1 0 +# define CV_CPU_HAS_SUPPORT_SSE4_1 (cv::checkHardwareSupport(CV_CPU_SSE4_1)) +# define CV_CPU_CALL_SSE4_1(fn, args) if (CV_CPU_HAS_SUPPORT_SSE4_1) return (opt_SSE4_1::fn args) +# define CV_CPU_CALL_SSE4_1_(fn, args) if (CV_CPU_HAS_SUPPORT_SSE4_1) return (opt_SSE4_1::fn args) +#else +# define CV_TRY_SSE4_1 0 +# define CV_CPU_FORCE_SSE4_1 0 +# define CV_CPU_HAS_SUPPORT_SSE4_1 0 +# define CV_CPU_CALL_SSE4_1(fn, args) +# define CV_CPU_CALL_SSE4_1_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_SSE4_1(fn, args, mode, ...) CV_CPU_CALL_SSE4_1(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_SSE4_2 +# define CV_TRY_SSE4_2 1 +# define CV_CPU_FORCE_SSE4_2 1 +# define CV_CPU_HAS_SUPPORT_SSE4_2 1 +# define CV_CPU_CALL_SSE4_2(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_SSE4_2_(fn, args) return (opt_SSE4_2::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_SSE4_2 +# define CV_TRY_SSE4_2 1 +# define CV_CPU_FORCE_SSE4_2 0 +# define CV_CPU_HAS_SUPPORT_SSE4_2 (cv::checkHardwareSupport(CV_CPU_SSE4_2)) +# define CV_CPU_CALL_SSE4_2(fn, args) if (CV_CPU_HAS_SUPPORT_SSE4_2) return (opt_SSE4_2::fn args) +# define CV_CPU_CALL_SSE4_2_(fn, args) if (CV_CPU_HAS_SUPPORT_SSE4_2) return (opt_SSE4_2::fn args) +#else +# define CV_TRY_SSE4_2 0 +# define CV_CPU_FORCE_SSE4_2 0 +# define CV_CPU_HAS_SUPPORT_SSE4_2 0 +# define CV_CPU_CALL_SSE4_2(fn, args) +# define CV_CPU_CALL_SSE4_2_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_SSE4_2(fn, args, mode, ...) CV_CPU_CALL_SSE4_2(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_POPCNT +# define CV_TRY_POPCNT 1 +# define CV_CPU_FORCE_POPCNT 1 +# define CV_CPU_HAS_SUPPORT_POPCNT 1 +# define CV_CPU_CALL_POPCNT(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_POPCNT_(fn, args) return (opt_POPCNT::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_POPCNT +# define CV_TRY_POPCNT 1 +# define CV_CPU_FORCE_POPCNT 0 +# define CV_CPU_HAS_SUPPORT_POPCNT (cv::checkHardwareSupport(CV_CPU_POPCNT)) +# define CV_CPU_CALL_POPCNT(fn, args) if (CV_CPU_HAS_SUPPORT_POPCNT) return (opt_POPCNT::fn args) +# define CV_CPU_CALL_POPCNT_(fn, args) if (CV_CPU_HAS_SUPPORT_POPCNT) return (opt_POPCNT::fn args) +#else +# define CV_TRY_POPCNT 0 +# define CV_CPU_FORCE_POPCNT 0 +# define CV_CPU_HAS_SUPPORT_POPCNT 0 +# define CV_CPU_CALL_POPCNT(fn, args) +# define CV_CPU_CALL_POPCNT_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_POPCNT(fn, args, mode, ...) CV_CPU_CALL_POPCNT(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX +# define CV_TRY_AVX 1 +# define CV_CPU_FORCE_AVX 1 +# define CV_CPU_HAS_SUPPORT_AVX 1 +# define CV_CPU_CALL_AVX(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX_(fn, args) return (opt_AVX::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX +# define CV_TRY_AVX 1 +# define CV_CPU_FORCE_AVX 0 +# define CV_CPU_HAS_SUPPORT_AVX (cv::checkHardwareSupport(CV_CPU_AVX)) +# define CV_CPU_CALL_AVX(fn, args) if (CV_CPU_HAS_SUPPORT_AVX) return (opt_AVX::fn args) +# define CV_CPU_CALL_AVX_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX) return (opt_AVX::fn args) +#else +# define CV_TRY_AVX 0 +# define CV_CPU_FORCE_AVX 0 +# define CV_CPU_HAS_SUPPORT_AVX 0 +# define CV_CPU_CALL_AVX(fn, args) +# define CV_CPU_CALL_AVX_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX(fn, args, mode, ...) CV_CPU_CALL_AVX(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_FP16 +# define CV_TRY_FP16 1 +# define CV_CPU_FORCE_FP16 1 +# define CV_CPU_HAS_SUPPORT_FP16 1 +# define CV_CPU_CALL_FP16(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_FP16_(fn, args) return (opt_FP16::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_FP16 +# define CV_TRY_FP16 1 +# define CV_CPU_FORCE_FP16 0 +# define CV_CPU_HAS_SUPPORT_FP16 (cv::checkHardwareSupport(CV_CPU_FP16)) +# define CV_CPU_CALL_FP16(fn, args) if (CV_CPU_HAS_SUPPORT_FP16) return (opt_FP16::fn args) +# define CV_CPU_CALL_FP16_(fn, args) if (CV_CPU_HAS_SUPPORT_FP16) return (opt_FP16::fn args) +#else +# define CV_TRY_FP16 0 +# define CV_CPU_FORCE_FP16 0 +# define CV_CPU_HAS_SUPPORT_FP16 0 +# define CV_CPU_CALL_FP16(fn, args) +# define CV_CPU_CALL_FP16_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_FP16(fn, args, mode, ...) CV_CPU_CALL_FP16(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX2 +# define CV_TRY_AVX2 1 +# define CV_CPU_FORCE_AVX2 1 +# define CV_CPU_HAS_SUPPORT_AVX2 1 +# define CV_CPU_CALL_AVX2(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX2_(fn, args) return (opt_AVX2::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX2 +# define CV_TRY_AVX2 1 +# define CV_CPU_FORCE_AVX2 0 +# define CV_CPU_HAS_SUPPORT_AVX2 (cv::checkHardwareSupport(CV_CPU_AVX2)) +# define CV_CPU_CALL_AVX2(fn, args) if (CV_CPU_HAS_SUPPORT_AVX2) return (opt_AVX2::fn args) +# define CV_CPU_CALL_AVX2_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX2) return (opt_AVX2::fn args) +#else +# define CV_TRY_AVX2 0 +# define CV_CPU_FORCE_AVX2 0 +# define CV_CPU_HAS_SUPPORT_AVX2 0 +# define CV_CPU_CALL_AVX2(fn, args) +# define CV_CPU_CALL_AVX2_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX2(fn, args, mode, ...) CV_CPU_CALL_AVX2(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_FMA3 +# define CV_TRY_FMA3 1 +# define CV_CPU_FORCE_FMA3 1 +# define CV_CPU_HAS_SUPPORT_FMA3 1 +# define CV_CPU_CALL_FMA3(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_FMA3_(fn, args) return (opt_FMA3::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_FMA3 +# define CV_TRY_FMA3 1 +# define CV_CPU_FORCE_FMA3 0 +# define CV_CPU_HAS_SUPPORT_FMA3 (cv::checkHardwareSupport(CV_CPU_FMA3)) +# define CV_CPU_CALL_FMA3(fn, args) if (CV_CPU_HAS_SUPPORT_FMA3) return (opt_FMA3::fn args) +# define CV_CPU_CALL_FMA3_(fn, args) if (CV_CPU_HAS_SUPPORT_FMA3) return (opt_FMA3::fn args) +#else +# define CV_TRY_FMA3 0 +# define CV_CPU_FORCE_FMA3 0 +# define CV_CPU_HAS_SUPPORT_FMA3 0 +# define CV_CPU_CALL_FMA3(fn, args) +# define CV_CPU_CALL_FMA3_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_FMA3(fn, args, mode, ...) CV_CPU_CALL_FMA3(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX_512F +# define CV_TRY_AVX_512F 1 +# define CV_CPU_FORCE_AVX_512F 1 +# define CV_CPU_HAS_SUPPORT_AVX_512F 1 +# define CV_CPU_CALL_AVX_512F(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX_512F_(fn, args) return (opt_AVX_512F::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX_512F +# define CV_TRY_AVX_512F 1 +# define CV_CPU_FORCE_AVX_512F 0 +# define CV_CPU_HAS_SUPPORT_AVX_512F (cv::checkHardwareSupport(CV_CPU_AVX_512F)) +# define CV_CPU_CALL_AVX_512F(fn, args) if (CV_CPU_HAS_SUPPORT_AVX_512F) return (opt_AVX_512F::fn args) +# define CV_CPU_CALL_AVX_512F_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX_512F) return (opt_AVX_512F::fn args) +#else +# define CV_TRY_AVX_512F 0 +# define CV_CPU_FORCE_AVX_512F 0 +# define CV_CPU_HAS_SUPPORT_AVX_512F 0 +# define CV_CPU_CALL_AVX_512F(fn, args) +# define CV_CPU_CALL_AVX_512F_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX_512F(fn, args, mode, ...) CV_CPU_CALL_AVX_512F(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_COMMON +# define CV_TRY_AVX512_COMMON 1 +# define CV_CPU_FORCE_AVX512_COMMON 1 +# define CV_CPU_HAS_SUPPORT_AVX512_COMMON 1 +# define CV_CPU_CALL_AVX512_COMMON(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX512_COMMON_(fn, args) return (opt_AVX512_COMMON::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_COMMON +# define CV_TRY_AVX512_COMMON 1 +# define CV_CPU_FORCE_AVX512_COMMON 0 +# define CV_CPU_HAS_SUPPORT_AVX512_COMMON (cv::checkHardwareSupport(CV_CPU_AVX512_COMMON)) +# define CV_CPU_CALL_AVX512_COMMON(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_COMMON) return (opt_AVX512_COMMON::fn args) +# define CV_CPU_CALL_AVX512_COMMON_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_COMMON) return (opt_AVX512_COMMON::fn args) +#else +# define CV_TRY_AVX512_COMMON 0 +# define CV_CPU_FORCE_AVX512_COMMON 0 +# define CV_CPU_HAS_SUPPORT_AVX512_COMMON 0 +# define CV_CPU_CALL_AVX512_COMMON(fn, args) +# define CV_CPU_CALL_AVX512_COMMON_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX512_COMMON(fn, args, mode, ...) CV_CPU_CALL_AVX512_COMMON(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_KNL +# define CV_TRY_AVX512_KNL 1 +# define CV_CPU_FORCE_AVX512_KNL 1 +# define CV_CPU_HAS_SUPPORT_AVX512_KNL 1 +# define CV_CPU_CALL_AVX512_KNL(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX512_KNL_(fn, args) return (opt_AVX512_KNL::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_KNL +# define CV_TRY_AVX512_KNL 1 +# define CV_CPU_FORCE_AVX512_KNL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_KNL (cv::checkHardwareSupport(CV_CPU_AVX512_KNL)) +# define CV_CPU_CALL_AVX512_KNL(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_KNL) return (opt_AVX512_KNL::fn args) +# define CV_CPU_CALL_AVX512_KNL_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_KNL) return (opt_AVX512_KNL::fn args) +#else +# define CV_TRY_AVX512_KNL 0 +# define CV_CPU_FORCE_AVX512_KNL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_KNL 0 +# define CV_CPU_CALL_AVX512_KNL(fn, args) +# define CV_CPU_CALL_AVX512_KNL_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX512_KNL(fn, args, mode, ...) CV_CPU_CALL_AVX512_KNL(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_KNM +# define CV_TRY_AVX512_KNM 1 +# define CV_CPU_FORCE_AVX512_KNM 1 +# define CV_CPU_HAS_SUPPORT_AVX512_KNM 1 +# define CV_CPU_CALL_AVX512_KNM(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX512_KNM_(fn, args) return (opt_AVX512_KNM::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_KNM +# define CV_TRY_AVX512_KNM 1 +# define CV_CPU_FORCE_AVX512_KNM 0 +# define CV_CPU_HAS_SUPPORT_AVX512_KNM (cv::checkHardwareSupport(CV_CPU_AVX512_KNM)) +# define CV_CPU_CALL_AVX512_KNM(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_KNM) return (opt_AVX512_KNM::fn args) +# define CV_CPU_CALL_AVX512_KNM_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_KNM) return (opt_AVX512_KNM::fn args) +#else +# define CV_TRY_AVX512_KNM 0 +# define CV_CPU_FORCE_AVX512_KNM 0 +# define CV_CPU_HAS_SUPPORT_AVX512_KNM 0 +# define CV_CPU_CALL_AVX512_KNM(fn, args) +# define CV_CPU_CALL_AVX512_KNM_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX512_KNM(fn, args, mode, ...) CV_CPU_CALL_AVX512_KNM(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_SKX +# define CV_TRY_AVX512_SKX 1 +# define CV_CPU_FORCE_AVX512_SKX 1 +# define CV_CPU_HAS_SUPPORT_AVX512_SKX 1 +# define CV_CPU_CALL_AVX512_SKX(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX512_SKX_(fn, args) return (opt_AVX512_SKX::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_SKX +# define CV_TRY_AVX512_SKX 1 +# define CV_CPU_FORCE_AVX512_SKX 0 +# define CV_CPU_HAS_SUPPORT_AVX512_SKX (cv::checkHardwareSupport(CV_CPU_AVX512_SKX)) +# define CV_CPU_CALL_AVX512_SKX(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_SKX) return (opt_AVX512_SKX::fn args) +# define CV_CPU_CALL_AVX512_SKX_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_SKX) return (opt_AVX512_SKX::fn args) +#else +# define CV_TRY_AVX512_SKX 0 +# define CV_CPU_FORCE_AVX512_SKX 0 +# define CV_CPU_HAS_SUPPORT_AVX512_SKX 0 +# define CV_CPU_CALL_AVX512_SKX(fn, args) +# define CV_CPU_CALL_AVX512_SKX_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX512_SKX(fn, args, mode, ...) CV_CPU_CALL_AVX512_SKX(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_CNL +# define CV_TRY_AVX512_CNL 1 +# define CV_CPU_FORCE_AVX512_CNL 1 +# define CV_CPU_HAS_SUPPORT_AVX512_CNL 1 +# define CV_CPU_CALL_AVX512_CNL(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX512_CNL_(fn, args) return (opt_AVX512_CNL::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_CNL +# define CV_TRY_AVX512_CNL 1 +# define CV_CPU_FORCE_AVX512_CNL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_CNL (cv::checkHardwareSupport(CV_CPU_AVX512_CNL)) +# define CV_CPU_CALL_AVX512_CNL(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_CNL) return (opt_AVX512_CNL::fn args) +# define CV_CPU_CALL_AVX512_CNL_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_CNL) return (opt_AVX512_CNL::fn args) +#else +# define CV_TRY_AVX512_CNL 0 +# define CV_CPU_FORCE_AVX512_CNL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_CNL 0 +# define CV_CPU_CALL_AVX512_CNL(fn, args) +# define CV_CPU_CALL_AVX512_CNL_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX512_CNL(fn, args, mode, ...) CV_CPU_CALL_AVX512_CNL(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_CEL +# define CV_TRY_AVX512_CEL 1 +# define CV_CPU_FORCE_AVX512_CEL 1 +# define CV_CPU_HAS_SUPPORT_AVX512_CEL 1 +# define CV_CPU_CALL_AVX512_CEL(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX512_CEL_(fn, args) return (opt_AVX512_CEL::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_CEL +# define CV_TRY_AVX512_CEL 1 +# define CV_CPU_FORCE_AVX512_CEL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_CEL (cv::checkHardwareSupport(CV_CPU_AVX512_CEL)) +# define CV_CPU_CALL_AVX512_CEL(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_CEL) return (opt_AVX512_CEL::fn args) +# define CV_CPU_CALL_AVX512_CEL_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_CEL) return (opt_AVX512_CEL::fn args) +#else +# define CV_TRY_AVX512_CEL 0 +# define CV_CPU_FORCE_AVX512_CEL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_CEL 0 +# define CV_CPU_CALL_AVX512_CEL(fn, args) +# define CV_CPU_CALL_AVX512_CEL_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX512_CEL(fn, args, mode, ...) CV_CPU_CALL_AVX512_CEL(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_ICL +# define CV_TRY_AVX512_ICL 1 +# define CV_CPU_FORCE_AVX512_ICL 1 +# define CV_CPU_HAS_SUPPORT_AVX512_ICL 1 +# define CV_CPU_CALL_AVX512_ICL(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_AVX512_ICL_(fn, args) return (opt_AVX512_ICL::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_ICL +# define CV_TRY_AVX512_ICL 1 +# define CV_CPU_FORCE_AVX512_ICL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_ICL (cv::checkHardwareSupport(CV_CPU_AVX512_ICL)) +# define CV_CPU_CALL_AVX512_ICL(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_ICL) return (opt_AVX512_ICL::fn args) +# define CV_CPU_CALL_AVX512_ICL_(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_ICL) return (opt_AVX512_ICL::fn args) +#else +# define CV_TRY_AVX512_ICL 0 +# define CV_CPU_FORCE_AVX512_ICL 0 +# define CV_CPU_HAS_SUPPORT_AVX512_ICL 0 +# define CV_CPU_CALL_AVX512_ICL(fn, args) +# define CV_CPU_CALL_AVX512_ICL_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_AVX512_ICL(fn, args, mode, ...) CV_CPU_CALL_AVX512_ICL(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_NEON +# define CV_TRY_NEON 1 +# define CV_CPU_FORCE_NEON 1 +# define CV_CPU_HAS_SUPPORT_NEON 1 +# define CV_CPU_CALL_NEON(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_NEON_(fn, args) return (opt_NEON::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_NEON +# define CV_TRY_NEON 1 +# define CV_CPU_FORCE_NEON 0 +# define CV_CPU_HAS_SUPPORT_NEON (cv::checkHardwareSupport(CV_CPU_NEON)) +# define CV_CPU_CALL_NEON(fn, args) if (CV_CPU_HAS_SUPPORT_NEON) return (opt_NEON::fn args) +# define CV_CPU_CALL_NEON_(fn, args) if (CV_CPU_HAS_SUPPORT_NEON) return (opt_NEON::fn args) +#else +# define CV_TRY_NEON 0 +# define CV_CPU_FORCE_NEON 0 +# define CV_CPU_HAS_SUPPORT_NEON 0 +# define CV_CPU_CALL_NEON(fn, args) +# define CV_CPU_CALL_NEON_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_NEON(fn, args, mode, ...) CV_CPU_CALL_NEON(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_VSX +# define CV_TRY_VSX 1 +# define CV_CPU_FORCE_VSX 1 +# define CV_CPU_HAS_SUPPORT_VSX 1 +# define CV_CPU_CALL_VSX(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_VSX_(fn, args) return (opt_VSX::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_VSX +# define CV_TRY_VSX 1 +# define CV_CPU_FORCE_VSX 0 +# define CV_CPU_HAS_SUPPORT_VSX (cv::checkHardwareSupport(CV_CPU_VSX)) +# define CV_CPU_CALL_VSX(fn, args) if (CV_CPU_HAS_SUPPORT_VSX) return (opt_VSX::fn args) +# define CV_CPU_CALL_VSX_(fn, args) if (CV_CPU_HAS_SUPPORT_VSX) return (opt_VSX::fn args) +#else +# define CV_TRY_VSX 0 +# define CV_CPU_FORCE_VSX 0 +# define CV_CPU_HAS_SUPPORT_VSX 0 +# define CV_CPU_CALL_VSX(fn, args) +# define CV_CPU_CALL_VSX_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_VSX(fn, args, mode, ...) CV_CPU_CALL_VSX(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_VSX3 +# define CV_TRY_VSX3 1 +# define CV_CPU_FORCE_VSX3 1 +# define CV_CPU_HAS_SUPPORT_VSX3 1 +# define CV_CPU_CALL_VSX3(fn, args) return (cpu_baseline::fn args) +# define CV_CPU_CALL_VSX3_(fn, args) return (opt_VSX3::fn args) +#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_VSX3 +# define CV_TRY_VSX3 1 +# define CV_CPU_FORCE_VSX3 0 +# define CV_CPU_HAS_SUPPORT_VSX3 (cv::checkHardwareSupport(CV_CPU_VSX3)) +# define CV_CPU_CALL_VSX3(fn, args) if (CV_CPU_HAS_SUPPORT_VSX3) return (opt_VSX3::fn args) +# define CV_CPU_CALL_VSX3_(fn, args) if (CV_CPU_HAS_SUPPORT_VSX3) return (opt_VSX3::fn args) +#else +# define CV_TRY_VSX3 0 +# define CV_CPU_FORCE_VSX3 0 +# define CV_CPU_HAS_SUPPORT_VSX3 0 +# define CV_CPU_CALL_VSX3(fn, args) +# define CV_CPU_CALL_VSX3_(fn, args) +#endif +#define __CV_CPU_DISPATCH_CHAIN_VSX3(fn, args, mode, ...) CV_CPU_CALL_VSX3(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__)) + +#define CV_CPU_CALL_BASELINE(fn, args) return (cpu_baseline::fn args) +#define __CV_CPU_DISPATCH_CHAIN_BASELINE(fn, args, mode, ...) CV_CPU_CALL_BASELINE(fn, args) /* last in sequence */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cvdef.h b/Prj-Win/3rd/opencv/include/opencv2/core/cvdef.h new file mode 100755 index 0000000..ae5b096 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cvdef.h @@ -0,0 +1,881 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_CVDEF_H +#define OPENCV_CORE_CVDEF_H + +//! @addtogroup core_utils +//! @{ + +#if !defined CV_DOXYGEN && !defined CV_IGNORE_DEBUG_BUILD_GUARD +#if (defined(_MSC_VER) && (defined(DEBUG) || defined(_DEBUG))) || \ + (defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_DEBUG_PEDANTIC)) +// Guard to prevent using of binary incompatible binaries / runtimes +// https://github.com/opencv/opencv/pull/9161 +#define CV__DEBUG_NS_BEGIN namespace debug_build_guard { +#define CV__DEBUG_NS_END } +namespace cv { namespace debug_build_guard { } using namespace debug_build_guard; } +#endif +#endif + +#ifndef CV__DEBUG_NS_BEGIN +#define CV__DEBUG_NS_BEGIN +#define CV__DEBUG_NS_END +#endif + + +#ifdef __OPENCV_BUILD +#include "cvconfig.h" +#endif + +#ifndef __CV_EXPAND +#define __CV_EXPAND(x) x +#endif + +#ifndef __CV_CAT +#define __CV_CAT__(x, y) x ## y +#define __CV_CAT_(x, y) __CV_CAT__(x, y) +#define __CV_CAT(x, y) __CV_CAT_(x, y) +#endif + +#define __CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N +#define __CV_VA_NUM_ARGS(...) __CV_EXPAND(__CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) + +#if defined __GNUC__ +#define CV_Func __func__ +#elif defined _MSC_VER +#define CV_Func __FUNCTION__ +#else +#define CV_Func "" +#endif + +//! @cond IGNORED + +//////////////// static assert ///////////////// +#define CVAUX_CONCAT_EXP(a, b) a##b +#define CVAUX_CONCAT(a, b) CVAUX_CONCAT_EXP(a,b) + +#if defined(__clang__) +# ifndef __has_extension +# define __has_extension __has_feature /* compatibility, for older versions of clang */ +# endif +# if __has_extension(cxx_static_assert) +# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition) +# elif __has_extension(c_static_assert) +# define CV_StaticAssert(condition, reason) _Static_assert((condition), reason " " #condition) +# endif +#elif defined(__GNUC__) +# if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L) +# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition) +# endif +#elif defined(_MSC_VER) +# if _MSC_VER >= 1600 /* MSVC 10 */ +# define CV_StaticAssert(condition, reason) static_assert((condition), reason " " #condition) +# endif +#endif +#ifndef CV_StaticAssert +# if !defined(__clang__) && defined(__GNUC__) && (__GNUC__*100 + __GNUC_MINOR__ > 302) +# define CV_StaticAssert(condition, reason) ({ extern int __attribute__((error("CV_StaticAssert: " reason " " #condition))) CV_StaticAssert(); ((condition) ? 0 : CV_StaticAssert()); }) +# else + template struct CV_StaticAssert_failed; + template <> struct CV_StaticAssert_failed { enum { val = 1 }; }; + template struct CV_StaticAssert_test {}; +# define CV_StaticAssert(condition, reason)\ + typedef cv::CV_StaticAssert_test< sizeof(cv::CV_StaticAssert_failed< static_cast(condition) >) > CVAUX_CONCAT(CV_StaticAssert_failed_at_, __LINE__) +# endif +#endif + +// Suppress warning "-Wdeprecated-declarations" / C4996 +#if defined(_MSC_VER) + #define CV_DO_PRAGMA(x) __pragma(x) +#elif defined(__GNUC__) + #define CV_DO_PRAGMA(x) _Pragma (#x) +#else + #define CV_DO_PRAGMA(x) +#endif + +#ifdef _MSC_VER +#define CV_SUPPRESS_DEPRECATED_START \ + CV_DO_PRAGMA(warning(push)) \ + CV_DO_PRAGMA(warning(disable: 4996)) +#define CV_SUPPRESS_DEPRECATED_END CV_DO_PRAGMA(warning(pop)) +#elif defined (__clang__) || ((__GNUC__) && (__GNUC__*100 + __GNUC_MINOR__ > 405)) +#define CV_SUPPRESS_DEPRECATED_START \ + CV_DO_PRAGMA(GCC diagnostic push) \ + CV_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations") +#define CV_SUPPRESS_DEPRECATED_END CV_DO_PRAGMA(GCC diagnostic pop) +#else +#define CV_SUPPRESS_DEPRECATED_START +#define CV_SUPPRESS_DEPRECATED_END +#endif + +#define CV_UNUSED(name) (void)name + +//! @endcond + +// undef problematic defines sometimes defined by system headers (windows.h in particular) +#undef small +#undef min +#undef max +#undef abs +#undef Complex + +#include +#include "opencv2/core/hal/interface.h" + +#if defined __ICL +# define CV_ICC __ICL +#elif defined __ICC +# define CV_ICC __ICC +#elif defined __ECL +# define CV_ICC __ECL +#elif defined __ECC +# define CV_ICC __ECC +#elif defined __INTEL_COMPILER +# define CV_ICC __INTEL_COMPILER +#endif + +#ifndef CV_INLINE +# if defined __cplusplus +# define CV_INLINE static inline +# elif defined _MSC_VER +# define CV_INLINE __inline +# else +# define CV_INLINE static +# endif +#endif + +#ifndef CV_ALWAYS_INLINE +#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define CV_ALWAYS_INLINE inline __attribute__((always_inline)) +#elif defined(_MSC_VER) +#define CV_ALWAYS_INLINE __forceinline +#else +#define CV_ALWAYS_INLINE inline +#endif +#endif + +#if defined CV_DISABLE_OPTIMIZATION || (defined CV_ICC && !defined CV_ENABLE_UNROLLED) +# define CV_ENABLE_UNROLLED 0 +#else +# define CV_ENABLE_UNROLLED 1 +#endif + +#ifdef __GNUC__ +# define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x))) +#elif defined _MSC_VER +# define CV_DECL_ALIGNED(x) __declspec(align(x)) +#else +# define CV_DECL_ALIGNED(x) +#endif + +/* CPU features and intrinsics support */ +#define CV_CPU_NONE 0 +#define CV_CPU_MMX 1 +#define CV_CPU_SSE 2 +#define CV_CPU_SSE2 3 +#define CV_CPU_SSE3 4 +#define CV_CPU_SSSE3 5 +#define CV_CPU_SSE4_1 6 +#define CV_CPU_SSE4_2 7 +#define CV_CPU_POPCNT 8 +#define CV_CPU_FP16 9 +#define CV_CPU_AVX 10 +#define CV_CPU_AVX2 11 +#define CV_CPU_FMA3 12 + +#define CV_CPU_AVX_512F 13 +#define CV_CPU_AVX_512BW 14 +#define CV_CPU_AVX_512CD 15 +#define CV_CPU_AVX_512DQ 16 +#define CV_CPU_AVX_512ER 17 +#define CV_CPU_AVX_512IFMA512 18 // deprecated +#define CV_CPU_AVX_512IFMA 18 +#define CV_CPU_AVX_512PF 19 +#define CV_CPU_AVX_512VBMI 20 +#define CV_CPU_AVX_512VL 21 +#define CV_CPU_AVX_512VBMI2 22 +#define CV_CPU_AVX_512VNNI 23 +#define CV_CPU_AVX_512BITALG 24 +#define CV_CPU_AVX_512VPOPCNTDQ 25 +#define CV_CPU_AVX_5124VNNIW 26 +#define CV_CPU_AVX_5124FMAPS 27 + +#define CV_CPU_NEON 100 + +#define CV_CPU_VSX 200 +#define CV_CPU_VSX3 201 + +// CPU features groups +#define CV_CPU_AVX512_SKX 256 +#define CV_CPU_AVX512_COMMON 257 +#define CV_CPU_AVX512_KNL 258 +#define CV_CPU_AVX512_KNM 259 +#define CV_CPU_AVX512_CNL 260 +#define CV_CPU_AVX512_CEL 261 +#define CV_CPU_AVX512_ICL 262 + +// when adding to this list remember to update the following enum +#define CV_HARDWARE_MAX_FEATURE 512 + +/** @brief Available CPU features. +*/ +enum CpuFeatures { + CPU_MMX = 1, + CPU_SSE = 2, + CPU_SSE2 = 3, + CPU_SSE3 = 4, + CPU_SSSE3 = 5, + CPU_SSE4_1 = 6, + CPU_SSE4_2 = 7, + CPU_POPCNT = 8, + CPU_FP16 = 9, + CPU_AVX = 10, + CPU_AVX2 = 11, + CPU_FMA3 = 12, + + CPU_AVX_512F = 13, + CPU_AVX_512BW = 14, + CPU_AVX_512CD = 15, + CPU_AVX_512DQ = 16, + CPU_AVX_512ER = 17, + CPU_AVX_512IFMA512 = 18, // deprecated + CPU_AVX_512IFMA = 18, + CPU_AVX_512PF = 19, + CPU_AVX_512VBMI = 20, + CPU_AVX_512VL = 21, + CPU_AVX_512VBMI2 = 22, + CPU_AVX_512VNNI = 23, + CPU_AVX_512BITALG = 24, + CPU_AVX_512VPOPCNTDQ= 25, + CPU_AVX_5124VNNIW = 26, + CPU_AVX_5124FMAPS = 27, + + CPU_NEON = 100, + + CPU_VSX = 200, + CPU_VSX3 = 201, + + CPU_AVX512_SKX = 256, //!< Skylake-X with AVX-512F/CD/BW/DQ/VL + CPU_AVX512_COMMON = 257, //!< Common instructions AVX-512F/CD for all CPUs that support AVX-512 + CPU_AVX512_KNL = 258, //!< Knights Landing with AVX-512F/CD/ER/PF + CPU_AVX512_KNM = 259, //!< Knights Mill with AVX-512F/CD/ER/PF/4FMAPS/4VNNIW/VPOPCNTDQ + CPU_AVX512_CNL = 260, //!< Cannon Lake with AVX-512F/CD/BW/DQ/VL/IFMA/VBMI + CPU_AVX512_CEL = 261, //!< Cascade Lake with AVX-512F/CD/BW/DQ/VL/IFMA/VBMI/VNNI + CPU_AVX512_ICL = 262, //!< Ice Lake with AVX-512F/CD/BW/DQ/VL/IFMA/VBMI/VNNI/VBMI2/BITALG/VPOPCNTDQ + + CPU_MAX_FEATURE = 512 // see CV_HARDWARE_MAX_FEATURE +}; + + +#include "cv_cpu_dispatch.h" + + +/* fundamental constants */ +#define CV_PI 3.1415926535897932384626433832795 +#define CV_2PI 6.283185307179586476925286766559 +#define CV_LOG2 0.69314718055994530941723212145818 + +#if defined __ARM_FP16_FORMAT_IEEE \ + && !defined __CUDACC__ +# define CV_FP16_TYPE 1 +#else +# define CV_FP16_TYPE 0 +#endif + +typedef union Cv16suf +{ + short i; + ushort u; +#if CV_FP16_TYPE + __fp16 h; +#endif +} +Cv16suf; + +typedef union Cv32suf +{ + int i; + unsigned u; + float f; +} +Cv32suf; + +typedef union Cv64suf +{ + int64 i; + uint64 u; + double f; +} +Cv64suf; + +#define OPENCV_ABI_COMPATIBILITY 400 + +#ifdef __OPENCV_BUILD +# define DISABLE_OPENCV_3_COMPATIBILITY +# define OPENCV_DISABLE_DEPRECATED_COMPATIBILITY +#endif + +#ifndef CV_EXPORTS +# if (defined _WIN32 || defined WINCE || defined __CYGWIN__) && defined(CVAPI_EXPORTS) +# define CV_EXPORTS __declspec(dllexport) +# elif defined __GNUC__ && __GNUC__ >= 4 && (defined(CVAPI_EXPORTS) || defined(__APPLE__)) +# define CV_EXPORTS __attribute__ ((visibility ("default"))) +# endif +#endif + +#ifndef CV_EXPORTS +# define CV_EXPORTS +#endif + +#ifdef _MSC_VER +# define CV_EXPORTS_TEMPLATE +#else +# define CV_EXPORTS_TEMPLATE CV_EXPORTS +#endif + +#ifndef CV_DEPRECATED +# if defined(__GNUC__) +# define CV_DEPRECATED __attribute__ ((deprecated)) +# elif defined(_MSC_VER) +# define CV_DEPRECATED __declspec(deprecated) +# else +# define CV_DEPRECATED +# endif +#endif + +#ifndef CV_DEPRECATED_EXTERNAL +# if defined(__OPENCV_BUILD) +# define CV_DEPRECATED_EXTERNAL /* nothing */ +# else +# define CV_DEPRECATED_EXTERNAL CV_DEPRECATED +# endif +#endif + + +#ifndef CV_EXTERN_C +# ifdef __cplusplus +# define CV_EXTERN_C extern "C" +# else +# define CV_EXTERN_C +# endif +#endif + +/* special informative macros for wrapper generators */ +#define CV_EXPORTS_W CV_EXPORTS +#define CV_EXPORTS_W_SIMPLE CV_EXPORTS +#define CV_EXPORTS_AS(synonym) CV_EXPORTS +#define CV_EXPORTS_W_MAP CV_EXPORTS +#define CV_IN_OUT +#define CV_OUT +#define CV_PROP +#define CV_PROP_RW +#define CV_WRAP +#define CV_WRAP_AS(synonym) +#define CV_WRAP_MAPPABLE(mappable) +#define CV_WRAP_PHANTOM(phantom_header) +#define CV_WRAP_DEFAULT(val) + +/****************************************************************************************\ +* Matrix type (Mat) * +\****************************************************************************************/ + +#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT) +#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) +#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1) +#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK) +#define CV_MAT_CONT_FLAG_SHIFT 14 +#define CV_MAT_CONT_FLAG (1 << CV_MAT_CONT_FLAG_SHIFT) +#define CV_IS_MAT_CONT(flags) ((flags) & CV_MAT_CONT_FLAG) +#define CV_IS_CONT_MAT CV_IS_MAT_CONT +#define CV_SUBMAT_FLAG_SHIFT 15 +#define CV_SUBMAT_FLAG (1 << CV_SUBMAT_FLAG_SHIFT) +#define CV_IS_SUBMAT(flags) ((flags) & CV_MAT_SUBMAT_FLAG) + +/** Size of each channel item, + 0x28442211 = 0010 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */ +#define CV_ELEM_SIZE1(type) ((0x28442211 >> CV_MAT_DEPTH(type)*4) & 15) + +#define CV_ELEM_SIZE(type) (CV_MAT_CN(type)*CV_ELEM_SIZE1(type)) + +#ifndef MIN +# define MIN(a,b) ((a) > (b) ? (b) : (a)) +#endif + +#ifndef MAX +# define MAX(a,b) ((a) < (b) ? (b) : (a)) +#endif + +///////////////////////////////////////// Enum operators /////////////////////////////////////// + +/** + +Provides compatibility operators for both classical and C++11 enum classes, +as well as exposing the C++11 enum class members for backwards compatibility + +@code + // Provides operators required for flag enums + CV_ENUM_FLAGS(AccessFlag) + + // Exposes the listed members of the enum class AccessFlag to the current namespace + CV_ENUM_CLASS_EXPOSE(AccessFlag, ACCESS_READ [, ACCESS_WRITE [, ...] ]); +@endcode +*/ + +#define __CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST) \ +static const EnumType MEMBER_CONST = EnumType::MEMBER_CONST; \ + +#define __CV_ENUM_CLASS_EXPOSE_2(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_1(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_CLASS_EXPOSE_3(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_2(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_CLASS_EXPOSE_4(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_3(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_CLASS_EXPOSE_5(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_4(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_CLASS_EXPOSE_6(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_5(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_CLASS_EXPOSE_7(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_6(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_CLASS_EXPOSE_8(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_7(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_CLASS_EXPOSE_9(EnumType, MEMBER_CONST, ...) \ +__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \ +__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_8(EnumType, __VA_ARGS__)); \ + +#define __CV_ENUM_FLAGS_LOGICAL_NOT(EnumType) \ +static inline bool operator!(const EnumType& val) \ +{ \ + typedef std::underlying_type::type UnderlyingType; \ + return !static_cast(val); \ +} \ + +#define __CV_ENUM_FLAGS_LOGICAL_NOT_EQ(Arg1Type, Arg2Type) \ +static inline bool operator!=(const Arg1Type& a, const Arg2Type& b) \ +{ \ + return static_cast(a) != static_cast(b); \ +} \ + +#define __CV_ENUM_FLAGS_LOGICAL_EQ(Arg1Type, Arg2Type) \ +static inline bool operator==(const Arg1Type& a, const Arg2Type& b) \ +{ \ + return static_cast(a) == static_cast(b); \ +} \ + +#define __CV_ENUM_FLAGS_BITWISE_NOT(EnumType) \ +static inline EnumType operator~(const EnumType& val) \ +{ \ + typedef std::underlying_type::type UnderlyingType; \ + return static_cast(~static_cast(val)); \ +} \ + +#define __CV_ENUM_FLAGS_BITWISE_OR(EnumType, Arg1Type, Arg2Type) \ +static inline EnumType operator|(const Arg1Type& a, const Arg2Type& b) \ +{ \ + typedef std::underlying_type::type UnderlyingType; \ + return static_cast(static_cast(a) | static_cast(b)); \ +} \ + +#define __CV_ENUM_FLAGS_BITWISE_AND(EnumType, Arg1Type, Arg2Type) \ +static inline EnumType operator&(const Arg1Type& a, const Arg2Type& b) \ +{ \ + typedef std::underlying_type::type UnderlyingType; \ + return static_cast(static_cast(a) & static_cast(b)); \ +} \ + +#define __CV_ENUM_FLAGS_BITWISE_XOR(EnumType, Arg1Type, Arg2Type) \ +static inline EnumType operator^(const Arg1Type& a, const Arg2Type& b) \ +{ \ + typedef std::underlying_type::type UnderlyingType; \ + return static_cast(static_cast(a) ^ static_cast(b)); \ +} \ + +#define __CV_ENUM_FLAGS_BITWISE_OR_EQ(EnumType, Arg1Type) \ +static inline EnumType& operator|=(EnumType& _this, const Arg1Type& val) \ +{ \ + _this = static_cast(static_cast(_this) | static_cast(val)); \ + return _this; \ +} \ + +#define __CV_ENUM_FLAGS_BITWISE_AND_EQ(EnumType, Arg1Type) \ +static inline EnumType& operator&=(EnumType& _this, const Arg1Type& val) \ +{ \ + _this = static_cast(static_cast(_this) & static_cast(val)); \ + return _this; \ +} \ + +#define __CV_ENUM_FLAGS_BITWISE_XOR_EQ(EnumType, Arg1Type) \ +static inline EnumType& operator^=(EnumType& _this, const Arg1Type& val) \ +{ \ + _this = static_cast(static_cast(_this) ^ static_cast(val)); \ + return _this; \ +} \ + +#define CV_ENUM_CLASS_EXPOSE(EnumType, ...) \ +__CV_EXPAND(__CV_CAT(__CV_ENUM_CLASS_EXPOSE_, __CV_VA_NUM_ARGS(__VA_ARGS__))(EnumType, __VA_ARGS__)); \ + +#define CV_ENUM_FLAGS(EnumType) \ +__CV_ENUM_FLAGS_LOGICAL_NOT (EnumType) \ +__CV_ENUM_FLAGS_LOGICAL_EQ (EnumType, int) \ +__CV_ENUM_FLAGS_LOGICAL_NOT_EQ (EnumType, int) \ + \ +__CV_ENUM_FLAGS_BITWISE_NOT (EnumType) \ +__CV_ENUM_FLAGS_BITWISE_OR (EnumType, EnumType, EnumType) \ +__CV_ENUM_FLAGS_BITWISE_AND (EnumType, EnumType, EnumType) \ +__CV_ENUM_FLAGS_BITWISE_XOR (EnumType, EnumType, EnumType) \ + \ +__CV_ENUM_FLAGS_BITWISE_OR_EQ (EnumType, EnumType) \ +__CV_ENUM_FLAGS_BITWISE_AND_EQ (EnumType, EnumType) \ +__CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType) \ + +/****************************************************************************************\ +* static analysys * +\****************************************************************************************/ + +// In practice, some macro are not processed correctly (noreturn is not detected). +// We need to use simplified definition for them. +#ifndef CV_STATIC_ANALYSIS +# if defined(__KLOCWORK__) || defined(__clang_analyzer__) || defined(__COVERITY__) +# define CV_STATIC_ANALYSIS 1 +# endif +#else +# if defined(CV_STATIC_ANALYSIS) && !(__CV_CAT(1, CV_STATIC_ANALYSIS) == 1) // defined and not empty +# if 0 == CV_STATIC_ANALYSIS +# undef CV_STATIC_ANALYSIS +# endif +# endif +#endif + +/****************************************************************************************\ +* Thread sanitizer * +\****************************************************************************************/ +#ifndef CV_THREAD_SANITIZER +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) +# define CV_THREAD_SANITIZER +# endif +# endif +#endif + +/****************************************************************************************\ +* exchange-add operation for atomic operations on reference counters * +\****************************************************************************************/ + +#ifdef CV_XADD + // allow to use user-defined macro +#elif defined __GNUC__ || defined __clang__ +# if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ && !defined __EMSCRIPTEN__ && !defined(__CUDACC__) && !defined __INTEL_COMPILER +# ifdef __ATOMIC_ACQ_REL +# define CV_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), delta, __ATOMIC_ACQ_REL) +# else +# define CV_XADD(addr, delta) __atomic_fetch_add((_Atomic(int)*)(addr), delta, 4) +# endif +# else +# if defined __ATOMIC_ACQ_REL && !defined __clang__ + // version for gcc >= 4.7 +# define CV_XADD(addr, delta) (int)__atomic_fetch_add((unsigned*)(addr), (unsigned)(delta), __ATOMIC_ACQ_REL) +# else +# define CV_XADD(addr, delta) (int)__sync_fetch_and_add((unsigned*)(addr), (unsigned)(delta)) +# endif +# endif +#elif defined _MSC_VER && !defined RC_INVOKED +# include +# define CV_XADD(addr, delta) (int)_InterlockedExchangeAdd((long volatile*)addr, delta) +#else + CV_INLINE CV_XADD(int* addr, int delta) { int tmp = *addr; *addr += delta; return tmp; } +#endif + + +/****************************************************************************************\ +* CV_NORETURN attribute * +\****************************************************************************************/ + +#ifndef CV_NORETURN +# if defined(__GNUC__) +# define CV_NORETURN __attribute__((__noreturn__)) +# elif defined(_MSC_VER) && (_MSC_VER >= 1300) +# define CV_NORETURN __declspec(noreturn) +# else +# define CV_NORETURN /* nothing by default */ +# endif +#endif + + +/****************************************************************************************\ +* CV_NODISCARD attribute * +* encourages the compiler to issue a warning if the return value is discarded (C++17) * +\****************************************************************************************/ +#ifndef CV_NODISCARD +# if defined(__GNUC__) +# define CV_NODISCARD __attribute__((__warn_unused_result__)) // at least available with GCC 3.4 +# elif defined(__clang__) && defined(__has_attribute) +# if __has_attribute(__warn_unused_result__) +# define CV_NODISCARD __attribute__((__warn_unused_result__)) +# endif +# endif +#endif +#ifndef CV_NODISCARD +# define CV_NODISCARD /* nothing by default */ +#endif + + +/****************************************************************************************\ +* C++ 11 * +\****************************************************************************************/ +#ifndef CV_CXX11 +# if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) +# define CV_CXX11 1 +# endif +#else +# if CV_CXX11 == 0 +# undef CV_CXX11 +# endif +#endif +#ifndef CV_CXX11 +# error "OpenCV 4.x+ requires enabled C++11 support" +#endif + +#define CV_CXX_MOVE_SEMANTICS 1 +#define CV_CXX_STD_ARRAY 1 +#include +#ifndef CV_OVERRIDE +# define CV_OVERRIDE override +#endif +#ifndef CV_FINAL +# define CV_FINAL final +#endif + +#ifndef CV_NOEXCEPT +# if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/) +# define CV_NOEXCEPT noexcept +# endif +#endif +#ifndef CV_NOEXCEPT +# define CV_NOEXCEPT +#endif + +#ifndef CV_CONSTEXPR +# if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/) +# define CV_CONSTEXPR constexpr +# endif +#endif +#ifndef CV_CONSTEXPR +# define CV_CONSTEXPR +#endif + +// Integer types portatibility +#ifdef OPENCV_STDINT_HEADER +#include OPENCV_STDINT_HEADER +#elif defined(__cplusplus) +#if defined(_MSC_VER) && _MSC_VER < 1600 /* MSVS 2010 */ +namespace cv { +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +} +#elif defined(_MSC_VER) || __cplusplus >= 201103L +#include +namespace cv { +using std::int8_t; +using std::uint8_t; +using std::int16_t; +using std::uint16_t; +using std::int32_t; +using std::uint32_t; +using std::int64_t; +using std::uint64_t; +} +#else +#include +namespace cv { +typedef ::int8_t int8_t; +typedef ::uint8_t uint8_t; +typedef ::int16_t int16_t; +typedef ::uint16_t uint16_t; +typedef ::int32_t int32_t; +typedef ::uint32_t uint32_t; +typedef ::int64_t int64_t; +typedef ::uint64_t uint64_t; +} +#endif +#else // pure C +#include +#endif + +#ifdef __cplusplus +namespace cv +{ + +class float16_t +{ +public: +#if CV_FP16_TYPE + + float16_t() : h(0) {} + explicit float16_t(float x) { h = (__fp16)x; } + operator float() const { return (float)h; } + static float16_t fromBits(ushort w) + { + Cv16suf u; + u.u = w; + float16_t result; + result.h = u.h; + return result; + } + static float16_t zero() + { + float16_t result; + result.h = (__fp16)0; + return result; + } + ushort bits() const + { + Cv16suf u; + u.h = h; + return u.u; + } +protected: + __fp16 h; + +#else + float16_t() : w(0) {} + explicit float16_t(float x) + { + #if CV_AVX2 + __m128 v = _mm_load_ss(&x); + w = (ushort)_mm_cvtsi128_si32(_mm_cvtps_ph(v, 0)); + #else + Cv32suf in; + in.f = x; + unsigned sign = in.u & 0x80000000; + in.u ^= sign; + + if( in.u >= 0x47800000 ) + w = (ushort)(in.u > 0x7f800000 ? 0x7e00 : 0x7c00); + else + { + if (in.u < 0x38800000) + { + in.f += 0.5f; + w = (ushort)(in.u - 0x3f000000); + } + else + { + unsigned t = in.u + 0xc8000fff; + w = (ushort)((t + ((in.u >> 13) & 1)) >> 13); + } + } + + w = (ushort)(w | (sign >> 16)); + #endif + } + + operator float() const + { + #if CV_AVX2 + float f; + _mm_store_ss(&f, _mm_cvtph_ps(_mm_cvtsi32_si128(w))); + return f; + #else + Cv32suf out; + + unsigned t = ((w & 0x7fff) << 13) + 0x38000000; + unsigned sign = (w & 0x8000) << 16; + unsigned e = w & 0x7c00; + + out.u = t + (1 << 23); + out.u = (e >= 0x7c00 ? t + 0x38000000 : + e == 0 ? (static_cast(out.f -= 6.103515625e-05f), out.u) : t) | sign; + return out.f; + #endif + } + + static float16_t fromBits(ushort b) + { + float16_t result; + result.w = b; + return result; + } + static float16_t zero() + { + float16_t result; + result.w = (ushort)0; + return result; + } + ushort bits() const { return w; } +protected: + ushort w; + +#endif +}; + +} +#endif + +//! @} + +#ifndef __cplusplus +#include "opencv2/core/fast_math.hpp" // define cvRound(double) +#endif + +#endif // OPENCV_CORE_CVDEF_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cvstd.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cvstd.hpp new file mode 100755 index 0000000..6ce9e4b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cvstd.hpp @@ -0,0 +1,190 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_CVSTD_HPP +#define OPENCV_CORE_CVSTD_HPP + +#ifndef __cplusplus +# error cvstd.hpp header must be compiled as C++ +#endif + +#include "opencv2/core/cvdef.h" +#include +#include +#include + +#include + +// import useful primitives from stl +# include +# include +# include //for abs(int) +# include + +namespace cv +{ + static inline uchar abs(uchar a) { return a; } + static inline ushort abs(ushort a) { return a; } + static inline unsigned abs(unsigned a) { return a; } + static inline uint64 abs(uint64 a) { return a; } + + using std::min; + using std::max; + using std::abs; + using std::swap; + using std::sqrt; + using std::exp; + using std::pow; + using std::log; +} + +#include "cvstd_wrapper.hpp" + +namespace cv { + +//! @addtogroup core_utils +//! @{ + +//////////////////////////// memory management functions //////////////////////////// + +/** @brief Allocates an aligned memory buffer. + +The function allocates the buffer of the specified size and returns it. When the buffer size is 16 +bytes or more, the returned buffer is aligned to 16 bytes. +@param bufSize Allocated buffer size. + */ +CV_EXPORTS void* fastMalloc(size_t bufSize); + +/** @brief Deallocates a memory buffer. + +The function deallocates the buffer allocated with fastMalloc . If NULL pointer is passed, the +function does nothing. C version of the function clears the pointer *pptr* to avoid problems with +double memory deallocation. +@param ptr Pointer to the allocated buffer. + */ +CV_EXPORTS void fastFree(void* ptr); + +/*! + The STL-compliant memory Allocator based on cv::fastMalloc() and cv::fastFree() +*/ +template class Allocator +{ +public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + template class rebind { typedef Allocator other; }; + + explicit Allocator() {} + ~Allocator() {} + explicit Allocator(Allocator const&) {} + template + explicit Allocator(Allocator const&) {} + + // address + pointer address(reference r) { return &r; } + const_pointer address(const_reference r) { return &r; } + + pointer allocate(size_type count, const void* =0) { return reinterpret_cast(fastMalloc(count * sizeof (_Tp))); } + void deallocate(pointer p, size_type) { fastFree(p); } + + void construct(pointer p, const _Tp& v) { new(static_cast(p)) _Tp(v); } + void destroy(pointer p) { p->~_Tp(); } + + size_type max_size() const { return cv::max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); } +}; + +//! @} core_utils + +//! @endcond + +//! @addtogroup core_basic +//! @{ + +//////////////////////////////// string class //////////////////////////////// + +class CV_EXPORTS FileNode; //for string constructor from FileNode + +typedef std::string String; + +#ifndef OPENCV_DISABLE_STRING_LOWER_UPPER_CONVERSIONS + +//! @cond IGNORED +namespace details { +// std::tolower is int->int +static inline char char_tolower(char ch) +{ + return (char)std::tolower((int)ch); +} +// std::toupper is int->int +static inline char char_toupper(char ch) +{ + return (char)std::toupper((int)ch); +} +} // namespace details +//! @endcond + +static inline std::string toLowerCase(const std::string& str) +{ + std::string result(str); + std::transform(result.begin(), result.end(), result.begin(), details::char_tolower); + return result; +} + +static inline std::string toUpperCase(const std::string& str) +{ + std::string result(str); + std::transform(result.begin(), result.end(), result.begin(), details::char_toupper); + return result; +} + +#endif // OPENCV_DISABLE_STRING_LOWER_UPPER_CONVERSIONS + +//! @} core_basic +} // cv + +#endif //OPENCV_CORE_CVSTD_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cvstd.inl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cvstd.inl.hpp new file mode 100755 index 0000000..4a85bfd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cvstd.inl.hpp @@ -0,0 +1,196 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_CVSTDINL_HPP +#define OPENCV_CORE_CVSTDINL_HPP + +#include +#include + +//! @cond IGNORED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4127 ) +#endif + +namespace cv +{ + +template class DataType< std::complex<_Tp> > +{ +public: + typedef std::complex<_Tp> value_type; + typedef value_type work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + depth = DataType::depth, + channels = 2, + fmt = DataType::fmt + ((channels - 1) << 8), + type = CV_MAKETYPE(depth, channels) }; + + typedef Vec vec_type; +}; + +static inline +std::ostream& operator << (std::ostream& out, Ptr fmtd) +{ + fmtd->reset(); + for(const char* str = fmtd->next(); str; str = fmtd->next()) + out << str; + return out; +} + +static inline +std::ostream& operator << (std::ostream& out, const Mat& mtx) +{ + return out << Formatter::get()->format(mtx); +} + +static inline +std::ostream& operator << (std::ostream& out, const UMat& m) +{ + return out << m.getMat(ACCESS_READ); +} + +template static inline +std::ostream& operator << (std::ostream& out, const Complex<_Tp>& c) +{ + return out << "(" << c.re << "," << c.im << ")"; +} + +template static inline +std::ostream& operator << (std::ostream& out, const std::vector >& vec) +{ + return out << Formatter::get()->format(Mat(vec)); +} + + +template static inline +std::ostream& operator << (std::ostream& out, const std::vector >& vec) +{ + return out << Formatter::get()->format(Mat(vec)); +} + + +template static inline +std::ostream& operator << (std::ostream& out, const Matx<_Tp, m, n>& matx) +{ + return out << Formatter::get()->format(Mat(matx)); +} + +template static inline +std::ostream& operator << (std::ostream& out, const Point_<_Tp>& p) +{ + out << "[" << p.x << ", " << p.y << "]"; + return out; +} + +template static inline +std::ostream& operator << (std::ostream& out, const Point3_<_Tp>& p) +{ + out << "[" << p.x << ", " << p.y << ", " << p.z << "]"; + return out; +} + +template static inline +std::ostream& operator << (std::ostream& out, const Vec<_Tp, n>& vec) +{ + out << "["; + if (cv::traits::Depth<_Tp>::value <= CV_32S) + { + for (int i = 0; i < n - 1; ++i) { + out << (int)vec[i] << ", "; + } + out << (int)vec[n-1] << "]"; + } + else + { + for (int i = 0; i < n - 1; ++i) { + out << vec[i] << ", "; + } + out << vec[n-1] << "]"; + } + + return out; +} + +template static inline +std::ostream& operator << (std::ostream& out, const Size_<_Tp>& size) +{ + return out << "[" << size.width << " x " << size.height << "]"; +} + +template static inline +std::ostream& operator << (std::ostream& out, const Rect_<_Tp>& rect) +{ + return out << "[" << rect.width << " x " << rect.height << " from (" << rect.x << ", " << rect.y << ")]"; +} + +static inline std::ostream& operator << (std::ostream& out, const MatSize& msize) +{ + int i, dims = msize.dims(); + for( i = 0; i < dims; i++ ) + { + out << msize[i]; + if( i < dims-1 ) + out << " x "; + } + return out; +} + +static inline std::ostream &operator<< (std::ostream &s, cv::Range &r) +{ + return s << "[" << r.start << " : " << r.end << ")"; +} + +} // cv + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + +//! @endcond + +#endif // OPENCV_CORE_CVSTDINL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/cvstd_wrapper.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/cvstd_wrapper.hpp new file mode 100755 index 0000000..e2c2ea5 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/cvstd_wrapper.hpp @@ -0,0 +1,154 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_CVSTD_WRAPPER_HPP +#define OPENCV_CORE_CVSTD_WRAPPER_HPP + +#include "opencv2/core/cvdef.h" + +#include +#include // std::shared_ptr +#include // std::enable_if + +namespace cv { + +using std::nullptr_t; + +//! @addtogroup core_basic +//! @{ + +#ifdef CV_DOXYGEN + +template using Ptr = std::shared_ptr<_Tp>; // In ideal world it should look like this, but we need some compatibility workarounds below + +template static inline +Ptr<_Tp> makePtr(const A1&... a1) { return std::make_shared<_Tp>(a1...); } + +#else // cv::Ptr with compatibility workarounds + +// It should be defined for C-API types only. +// C++ types should use regular "delete" operator. +template struct DefaultDeleter; +#if 0 +{ + void operator()(Y* p) const; +}; +#endif + +namespace sfinae { +template +struct has_parenthesis_operator +{ +private: + template + static CV_CONSTEXPR std::true_type check(typename std::is_same().operator()(std::declval()...))>::type, Ret>::type*); + + template static CV_CONSTEXPR std::false_type check(...); + + typedef decltype(check(0)) type; + +public: +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/) + static CV_CONSTEXPR bool value = type::value; +#else + // support MSVS 2013 + static const int value = type::value; +#endif +}; +} // namespace sfinae + +template +struct has_custom_delete + : public std::false_type {}; + +// Force has_custom_delete to std::false_type when NVCC is compiling CUDA source files +#ifndef __CUDACC__ +template +struct has_custom_delete, void, T*>::value >::type > + : public std::true_type {}; +#endif + +template +struct Ptr : public std::shared_ptr +{ +#if 0 + using std::shared_ptr::shared_ptr; // GCC 5.x can't handle this +#else + inline Ptr() CV_NOEXCEPT : std::shared_ptr() {} + inline Ptr(nullptr_t) CV_NOEXCEPT : std::shared_ptr(nullptr) {} + template inline Ptr(Y* p, D d) : std::shared_ptr(p, d) {} + template inline Ptr(nullptr_t, D d) : std::shared_ptr(nullptr, d) {} + + template inline Ptr(const Ptr& r, T* ptr) CV_NOEXCEPT : std::shared_ptr(r, ptr) {} + + inline Ptr(const Ptr& o) CV_NOEXCEPT : std::shared_ptr(o) {} + inline Ptr(Ptr&& o) CV_NOEXCEPT : std::shared_ptr(std::move(o)) {} + + template inline Ptr(const Ptr& o) CV_NOEXCEPT : std::shared_ptr(o) {} + template inline Ptr(Ptr&& o) CV_NOEXCEPT : std::shared_ptr(std::move(o)) {} +#endif + inline Ptr(const std::shared_ptr& o) CV_NOEXCEPT : std::shared_ptr(o) {} + inline Ptr(std::shared_ptr&& o) CV_NOEXCEPT : std::shared_ptr(std::move(o)) {} + + // Overload with custom DefaultDeleter: Ptr(...) + template + inline Ptr(const std::true_type&, Y* ptr) : std::shared_ptr(ptr, DefaultDeleter()) {} + + // Overload without custom deleter: Ptr(...); + template + inline Ptr(const std::false_type&, Y* ptr) : std::shared_ptr(ptr) {} + + template + inline Ptr(Y* ptr) : Ptr(has_custom_delete(), ptr) {} + + // Overload with custom DefaultDeleter: Ptr(...) + template + inline void reset(const std::true_type&, Y* ptr) { std::shared_ptr::reset(ptr, DefaultDeleter()); } + + // Overload without custom deleter: Ptr(...); + template + inline void reset(const std::false_type&, Y* ptr) { std::shared_ptr::reset(ptr); } + + template + inline void reset(Y* ptr) { Ptr::reset(has_custom_delete(), ptr); } + + template + void reset(Y* ptr, Deleter d) { std::shared_ptr::reset(ptr, d); } + + void reset() CV_NOEXCEPT { std::shared_ptr::reset(); } + + Ptr& operator=(const Ptr& o) { std::shared_ptr::operator =(o); return *this; } + template inline Ptr& operator=(const Ptr& o) { std::shared_ptr::operator =(o); return *this; } + + T* operator->() const CV_NOEXCEPT { return std::shared_ptr::get();} + typename std::add_lvalue_reference::type operator*() const CV_NOEXCEPT { return *std::shared_ptr::get(); } + + // OpenCV 3.x methods (not a part of standard C++ library) + inline void release() { std::shared_ptr::reset(); } + inline operator T* () const { return std::shared_ptr::get(); } + inline bool empty() const { return std::shared_ptr::get() == nullptr; } + + template inline + Ptr staticCast() const CV_NOEXCEPT { return std::static_pointer_cast(*this); } + + template inline + Ptr constCast() const CV_NOEXCEPT { return std::const_pointer_cast(*this); } + + template inline + Ptr dynamicCast() const CV_NOEXCEPT { return std::dynamic_pointer_cast(*this); } +}; + +template static inline +Ptr<_Tp> makePtr(const A1&... a1) +{ + static_assert( !has_custom_delete<_Tp>::value, "Can't use this makePtr with custom DefaultDeleter"); + return (Ptr<_Tp>)std::make_shared<_Tp>(a1...); +} + +#endif // CV_DOXYGEN + +//! @} core_basic +} // cv + +#endif //OPENCV_CORE_CVSTD_WRAPPER_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/detail/async_promise.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/detail/async_promise.hpp new file mode 100755 index 0000000..6eb3fb5 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/detail/async_promise.hpp @@ -0,0 +1,71 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_ASYNC_PROMISE_HPP +#define OPENCV_CORE_ASYNC_PROMISE_HPP + +#include "../async.hpp" + +#include "exception_ptr.hpp" + +namespace cv { + +/** @addtogroup core_async +@{ +*/ + + +/** @brief Provides result of asynchronous operations + +*/ +class CV_EXPORTS AsyncPromise +{ +public: + ~AsyncPromise() CV_NOEXCEPT; + AsyncPromise() CV_NOEXCEPT; + explicit AsyncPromise(const AsyncPromise& o) CV_NOEXCEPT; + AsyncPromise& operator=(const AsyncPromise& o) CV_NOEXCEPT; + void release() CV_NOEXCEPT; + + /** Returns associated AsyncArray + @note Can be called once + */ + AsyncArray getArrayResult(); + + /** Stores asynchronous result. + @param[in] value result + */ + void setValue(InputArray value); + + // TODO "move" setters + +#if CV__EXCEPTION_PTR + /** Stores exception. + @param[in] exception exception to be raised in AsyncArray + */ + void setException(std::exception_ptr exception); +#endif + + /** Stores exception. + @param[in] exception exception to be raised in AsyncArray + */ + void setException(const cv::Exception& exception); + +#ifdef CV_CXX11 + explicit AsyncPromise(AsyncPromise&& o) { p = o.p; o.p = NULL; } + AsyncPromise& operator=(AsyncPromise&& o) CV_NOEXCEPT { std::swap(p, o.p); return *this; } +#endif + + + // PImpl + typedef struct AsyncArray::Impl Impl; friend struct AsyncArray::Impl; + inline void* _getImpl() const CV_NOEXCEPT { return p; } +protected: + Impl* p; +}; + + +//! @} +} // namespace +#endif // OPENCV_CORE_ASYNC_PROMISE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/detail/exception_ptr.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/detail/exception_ptr.hpp new file mode 100755 index 0000000..d98ffc4 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/detail/exception_ptr.hpp @@ -0,0 +1,27 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_DETAILS_EXCEPTION_PTR_H +#define OPENCV_CORE_DETAILS_EXCEPTION_PTR_H + +#ifndef CV__EXCEPTION_PTR +# if defined(__ANDROID__) && defined(ATOMIC_INT_LOCK_FREE) && ATOMIC_INT_LOCK_FREE < 2 +# define CV__EXCEPTION_PTR 0 // Not supported, details: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58938 +# elif defined(CV_CXX11) +# define CV__EXCEPTION_PTR 1 +# elif defined(_MSC_VER) +# define CV__EXCEPTION_PTR (_MSC_VER >= 1600) +# elif defined(__clang__) +# define CV__EXCEPTION_PTR 0 // C++11 only (see above) +# elif defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) +# define CV__EXCEPTION_PTR (__GXX_EXPERIMENTAL_CXX0X__ > 0) +# endif +#endif +#ifndef CV__EXCEPTION_PTR +# define CV__EXCEPTION_PTR 0 +#elif CV__EXCEPTION_PTR +# include // std::exception_ptr +#endif + +#endif // OPENCV_CORE_DETAILS_EXCEPTION_PTR_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/directx.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/directx.hpp new file mode 100755 index 0000000..056a85a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/directx.hpp @@ -0,0 +1,184 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors as is and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the copyright holders or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_DIRECTX_HPP +#define OPENCV_CORE_DIRECTX_HPP + +#include "mat.hpp" +#include "ocl.hpp" + +#if !defined(__d3d11_h__) +struct ID3D11Device; +struct ID3D11Texture2D; +#endif + +#if !defined(__d3d10_h__) +struct ID3D10Device; +struct ID3D10Texture2D; +#endif + +#if !defined(_D3D9_H_) +struct IDirect3DDevice9; +struct IDirect3DDevice9Ex; +struct IDirect3DSurface9; +#endif + + +namespace cv { namespace directx { + +namespace ocl { +using namespace cv::ocl; + +//! @addtogroup core_directx +// This section describes OpenCL and DirectX interoperability. +// +// To enable DirectX support, configure OpenCV using CMake with WITH_DIRECTX=ON . Note, DirectX is +// supported only on Windows. +// +// To use OpenCL functionality you should first initialize OpenCL context from DirectX resource. +// +//! @{ + +// TODO static functions in the Context class +//! @brief Creates OpenCL context from D3D11 device +// +//! @param pD3D11Device - pointer to D3D11 device +//! @return Returns reference to OpenCL Context +CV_EXPORTS Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device); + +//! @brief Creates OpenCL context from D3D10 device +// +//! @param pD3D10Device - pointer to D3D10 device +//! @return Returns reference to OpenCL Context +CV_EXPORTS Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device); + +//! @brief Creates OpenCL context from Direct3DDevice9Ex device +// +//! @param pDirect3DDevice9Ex - pointer to Direct3DDevice9Ex device +//! @return Returns reference to OpenCL Context +CV_EXPORTS Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex); + +//! @brief Creates OpenCL context from Direct3DDevice9 device +// +//! @param pDirect3DDevice9 - pointer to Direct3Device9 device +//! @return Returns reference to OpenCL Context +CV_EXPORTS Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9); + +//! @} + +} // namespace cv::directx::ocl + +//! @addtogroup core_directx +//! @{ + +//! @brief Converts InputArray to ID3D11Texture2D. If destination texture format is DXGI_FORMAT_NV12 then +//! input UMat expected to be in BGR format and data will be downsampled and color-converted to NV12. +// +//! @note Note: Destination texture must be allocated by application. Function does memory copy from src to +//! pD3D11Texture2D +// +//! @param src - source InputArray +//! @param pD3D11Texture2D - destination D3D11 texture +CV_EXPORTS void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D); + +//! @brief Converts ID3D11Texture2D to OutputArray. If input texture format is DXGI_FORMAT_NV12 then +//! data will be upsampled and color-converted to BGR format. +// +//! @note Note: Destination matrix will be re-allocated if it has not enough memory to match texture size. +//! function does memory copy from pD3D11Texture2D to dst +// +//! @param pD3D11Texture2D - source D3D11 texture +//! @param dst - destination OutputArray +CV_EXPORTS void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst); + +//! @brief Converts InputArray to ID3D10Texture2D +// +//! @note Note: function does memory copy from src to +//! pD3D10Texture2D +// +//! @param src - source InputArray +//! @param pD3D10Texture2D - destination D3D10 texture +CV_EXPORTS void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D); + +//! @brief Converts ID3D10Texture2D to OutputArray +// +//! @note Note: function does memory copy from pD3D10Texture2D +//! to dst +// +//! @param pD3D10Texture2D - source D3D10 texture +//! @param dst - destination OutputArray +CV_EXPORTS void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst); + +//! @brief Converts InputArray to IDirect3DSurface9 +// +//! @note Note: function does memory copy from src to +//! pDirect3DSurface9 +// +//! @param src - source InputArray +//! @param pDirect3DSurface9 - destination D3D10 texture +//! @param surfaceSharedHandle - shared handle +CV_EXPORTS void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle = NULL); + +//! @brief Converts IDirect3DSurface9 to OutputArray +// +//! @note Note: function does memory copy from pDirect3DSurface9 +//! to dst +// +//! @param pDirect3DSurface9 - source D3D10 texture +//! @param dst - destination OutputArray +//! @param surfaceSharedHandle - shared handle +CV_EXPORTS void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle = NULL); + +//! @brief Get OpenCV type from DirectX type +//! @param iDXGI_FORMAT - enum DXGI_FORMAT for D3D10/D3D11 +//! @return OpenCV type or -1 if there is no equivalent +CV_EXPORTS int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT); // enum DXGI_FORMAT for D3D10/D3D11 + +//! @brief Get OpenCV type from DirectX type +//! @param iD3DFORMAT - enum D3DTYPE for D3D9 +//! @return OpenCV type or -1 if there is no equivalent +CV_EXPORTS int getTypeFromD3DFORMAT(const int iD3DFORMAT); // enum D3DTYPE for D3D9 + +//! @} + +} } // namespace cv::directx + +#endif // OPENCV_CORE_DIRECTX_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/eigen.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/eigen.hpp new file mode 100755 index 0000000..741648e --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/eigen.hpp @@ -0,0 +1,280 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + + +#ifndef OPENCV_CORE_EIGEN_HPP +#define OPENCV_CORE_EIGEN_HPP + +#include "opencv2/core.hpp" + +#if defined _MSC_VER && _MSC_VER >= 1200 +#pragma warning( disable: 4714 ) //__forceinline is not inlined +#pragma warning( disable: 4127 ) //conditional expression is constant +#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data +#endif + +namespace cv +{ + +//! @addtogroup core_eigen +//! @{ + +template static inline +void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, OutputArray dst ) +{ + if( !(src.Flags & Eigen::RowMajorBit) ) + { + Mat _src(src.cols(), src.rows(), traits::Type<_Tp>::value, + (void*)src.data(), src.outerStride()*sizeof(_Tp)); + transpose(_src, dst); + } + else + { + Mat _src(src.rows(), src.cols(), traits::Type<_Tp>::value, + (void*)src.data(), src.outerStride()*sizeof(_Tp)); + _src.copyTo(dst); + } +} + +// Matx case +template static inline +void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, + Matx<_Tp, _rows, _cols>& dst ) +{ + if( !(src.Flags & Eigen::RowMajorBit) ) + { + dst = Matx<_Tp, _cols, _rows>(static_cast(src.data())).t(); + } + else + { + dst = Matx<_Tp, _rows, _cols>(static_cast(src.data())); + } +} + +template static inline +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst ) +{ + CV_DbgAssert(src.rows == _rows && src.cols == _cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else if( src.cols == src.rows ) + { + src.convertTo(_dst, _dst.type()); + transpose(_dst, _dst); + } + else + Mat(src.t()).convertTo(_dst, _dst.type()); + } + else + { + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + } +} + +// Matx case +template static inline +void cv2eigen( const Matx<_Tp, _rows, _cols>& src, + Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& dst ) +{ + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(_cols, _rows, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + transpose(src, _dst); + } + else + { + const Mat _dst(_rows, _cols, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + Mat(src).copyTo(_dst); + } +} + +template static inline +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst ) +{ + dst.resize(src.rows, src.cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else if( src.cols == src.rows ) + { + src.convertTo(_dst, _dst.type()); + transpose(_dst, _dst); + } + else + Mat(src.t()).convertTo(_dst, _dst.type()); + } + else + { + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + } +} + +// Matx case +template static inline +void cv2eigen( const Matx<_Tp, _rows, _cols>& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, Eigen::Dynamic>& dst ) +{ + dst.resize(_rows, _cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(_cols, _rows, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + transpose(src, _dst); + } + else + { + const Mat _dst(_rows, _cols, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + Mat(src).copyTo(_dst); + } +} + +template static inline +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst ) +{ + CV_Assert(src.cols == 1); + dst.resize(src.rows); + + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else + Mat(src.t()).convertTo(_dst, _dst.type()); + } + else + { + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + } +} + +// Matx case +template static inline +void cv2eigen( const Matx<_Tp, _rows, 1>& src, + Eigen::Matrix<_Tp, Eigen::Dynamic, 1>& dst ) +{ + dst.resize(_rows); + + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(1, _rows, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + transpose(src, _dst); + } + else + { + const Mat _dst(_rows, 1, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + src.copyTo(_dst); + } +} + + +template static inline +void cv2eigen( const Mat& src, + Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst ) +{ + CV_Assert(src.rows == 1); + dst.resize(src.cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + if( src.type() == _dst.type() ) + transpose(src, _dst); + else + Mat(src.t()).convertTo(_dst, _dst.type()); + } + else + { + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + src.convertTo(_dst, _dst.type()); + } +} + +//Matx +template static inline +void cv2eigen( const Matx<_Tp, 1, _cols>& src, + Eigen::Matrix<_Tp, 1, Eigen::Dynamic>& dst ) +{ + dst.resize(_cols); + if( !(dst.Flags & Eigen::RowMajorBit) ) + { + const Mat _dst(_cols, 1, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + transpose(src, _dst); + } + else + { + const Mat _dst(1, _cols, traits::Type<_Tp>::value, + dst.data(), (size_t)(dst.outerStride()*sizeof(_Tp))); + Mat(src).copyTo(_dst); + } +} + +//! @} + +} // cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/fast_math.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/fast_math.hpp new file mode 100755 index 0000000..065879b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/fast_math.hpp @@ -0,0 +1,261 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_FAST_MATH_HPP +#define OPENCV_CORE_FAST_MATH_HPP + +#include "opencv2/core/cvdef.h" + +#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \ + && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__) +#include +#endif + + +//! @addtogroup core_utils +//! @{ + +/****************************************************************************************\ +* fast math * +\****************************************************************************************/ + +#ifdef __cplusplus +# include +#else +# ifdef __BORLANDC__ +# include +# else +# include +# endif +#endif + +#if defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__ || defined __ARM_NEON__) && !defined __SOFTFP__ && !defined(__CUDACC__) + // 1. general scheme + #define ARM_ROUND(_value, _asm_string) \ + int res; \ + float temp; \ + CV_UNUSED(temp); \ + __asm__(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \ + return res + // 2. version for double + #ifdef __clang__ + #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]") + #else + #define ARM_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]") + #endif + // 3. version for float + #define ARM_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]") +#endif + +/** @brief Rounds floating-point number to the nearest integer + + @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the + result is not defined. + */ +CV_INLINE int +cvRound( double value ) +{ +#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \ + && defined __SSE2__ && !defined __APPLE__) || CV_SSE2) && !defined(__CUDACC__) + __m128d t = _mm_set_sd( value ); + return _mm_cvtsd_si32(t); +#elif defined _MSC_VER && defined _M_IX86 + int t; + __asm + { + fld value; + fistp t; + } + return t; +#elif defined CV_ICC || defined __GNUC__ +# if defined ARM_ROUND_DBL + ARM_ROUND_DBL(value); +# else + return (int)lrint(value); +# endif +#else + /* it's ok if round does not comply with IEEE754 standard; + the tests should allow +/-1 difference when the tested functions use round */ + return (int)(value + (value >= 0 ? 0.5 : -0.5)); +#endif +} + + +/** @brief Rounds floating-point number to the nearest integer not larger than the original. + + The function computes an integer i such that: + \f[i \le \texttt{value} < i+1\f] + @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the + result is not defined. + */ +CV_INLINE int cvFloor( double value ) +{ + int i = (int)value; + return i - (i > value); +} + +/** @brief Rounds floating-point number to the nearest integer not smaller than the original. + + The function computes an integer i such that: + \f[i \le \texttt{value} < i+1\f] + @param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the + result is not defined. + */ +CV_INLINE int cvCeil( double value ) +{ + int i = (int)value; + return i + (i < value); +} + +/** @brief Determines if the argument is Not A Number. + + @param value The input floating-point value + + The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0 + otherwise. */ +CV_INLINE int cvIsNaN( double value ) +{ + Cv64suf ieee754; + ieee754.f = value; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) + + ((unsigned)ieee754.u != 0) > 0x7ff00000; +} + +/** @brief Determines if the argument is Infinity. + + @param value The input floating-point value + + The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard) + and 0 otherwise. */ +CV_INLINE int cvIsInf( double value ) +{ + Cv64suf ieee754; + ieee754.f = value; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && + (unsigned)ieee754.u == 0; +} + +#ifdef __cplusplus + +/** @overload */ +CV_INLINE int cvRound(float value) +{ +#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ \ + && defined __SSE2__ && !defined __APPLE__) || CV_SSE2) && !defined(__CUDACC__) + __m128 t = _mm_set_ss( value ); + return _mm_cvtss_si32(t); +#elif defined _MSC_VER && defined _M_IX86 + int t; + __asm + { + fld value; + fistp t; + } + return t; +#elif defined CV_ICC || defined __GNUC__ +# if defined ARM_ROUND_FLT + ARM_ROUND_FLT(value); +# else + return (int)lrintf(value); +# endif +#else + /* it's ok if round does not comply with IEEE754 standard; + the tests should allow +/-1 difference when the tested functions use round */ + return (int)(value + (value >= 0 ? 0.5f : -0.5f)); +#endif +} + +/** @overload */ +CV_INLINE int cvRound( int value ) +{ + return value; +} + +/** @overload */ +CV_INLINE int cvFloor( float value ) +{ + int i = (int)value; + return i - (i > value); +} + +/** @overload */ +CV_INLINE int cvFloor( int value ) +{ + return value; +} + +/** @overload */ +CV_INLINE int cvCeil( float value ) +{ + int i = (int)value; + return i + (i < value); +} + +/** @overload */ +CV_INLINE int cvCeil( int value ) +{ + return value; +} + +/** @overload */ +CV_INLINE int cvIsNaN( float value ) +{ + Cv32suf ieee754; + ieee754.f = value; + return (ieee754.u & 0x7fffffff) > 0x7f800000; +} + +/** @overload */ +CV_INLINE int cvIsInf( float value ) +{ + Cv32suf ieee754; + ieee754.f = value; + return (ieee754.u & 0x7fffffff) == 0x7f800000; +} + +#endif // __cplusplus + +//! @} core_utils + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/hal.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/hal.hpp new file mode 100755 index 0000000..0d68078 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/hal.hpp @@ -0,0 +1,256 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HAL_HPP +#define OPENCV_HAL_HPP + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/cvstd.hpp" +#include "opencv2/core/hal/interface.h" + +namespace cv { namespace hal { + +//! @addtogroup core_hal_functions +//! @{ + +CV_EXPORTS int normHamming(const uchar* a, int n); +CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n); + +CV_EXPORTS int normHamming(const uchar* a, int n, int cellSize); +CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n, int cellSize); + +CV_EXPORTS int LU32f(float* A, size_t astep, int m, float* b, size_t bstep, int n); +CV_EXPORTS int LU64f(double* A, size_t astep, int m, double* b, size_t bstep, int n); +CV_EXPORTS bool Cholesky32f(float* A, size_t astep, int m, float* b, size_t bstep, int n); +CV_EXPORTS bool Cholesky64f(double* A, size_t astep, int m, double* b, size_t bstep, int n); +CV_EXPORTS void SVD32f(float* At, size_t astep, float* W, float* U, size_t ustep, float* Vt, size_t vstep, int m, int n, int flags); +CV_EXPORTS void SVD64f(double* At, size_t astep, double* W, double* U, size_t ustep, double* Vt, size_t vstep, int m, int n, int flags); +CV_EXPORTS int QR32f(float* A, size_t astep, int m, int n, int k, float* b, size_t bstep, float* hFactors); +CV_EXPORTS int QR64f(double* A, size_t astep, int m, int n, int k, double* b, size_t bstep, double* hFactors); + +CV_EXPORTS void gemm32f(const float* src1, size_t src1_step, const float* src2, size_t src2_step, + float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step, + int m_a, int n_a, int n_d, int flags); +CV_EXPORTS void gemm64f(const double* src1, size_t src1_step, const double* src2, size_t src2_step, + double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step, + int m_a, int n_a, int n_d, int flags); +CV_EXPORTS void gemm32fc(const float* src1, size_t src1_step, const float* src2, size_t src2_step, + float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step, + int m_a, int n_a, int n_d, int flags); +CV_EXPORTS void gemm64fc(const double* src1, size_t src1_step, const double* src2, size_t src2_step, + double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step, + int m_a, int n_a, int n_d, int flags); + +CV_EXPORTS int normL1_(const uchar* a, const uchar* b, int n); +CV_EXPORTS float normL1_(const float* a, const float* b, int n); +CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n); + +CV_EXPORTS void exp32f(const float* src, float* dst, int n); +CV_EXPORTS void exp64f(const double* src, double* dst, int n); +CV_EXPORTS void log32f(const float* src, float* dst, int n); +CV_EXPORTS void log64f(const double* src, double* dst, int n); + +CV_EXPORTS void fastAtan32f(const float* y, const float* x, float* dst, int n, bool angleInDegrees); +CV_EXPORTS void fastAtan64f(const double* y, const double* x, double* dst, int n, bool angleInDegrees); +CV_EXPORTS void magnitude32f(const float* x, const float* y, float* dst, int n); +CV_EXPORTS void magnitude64f(const double* x, const double* y, double* dst, int n); +CV_EXPORTS void sqrt32f(const float* src, float* dst, int len); +CV_EXPORTS void sqrt64f(const double* src, double* dst, int len); +CV_EXPORTS void invSqrt32f(const float* src, float* dst, int len); +CV_EXPORTS void invSqrt64f(const double* src, double* dst, int len); + +CV_EXPORTS void split8u(const uchar* src, uchar** dst, int len, int cn ); +CV_EXPORTS void split16u(const ushort* src, ushort** dst, int len, int cn ); +CV_EXPORTS void split32s(const int* src, int** dst, int len, int cn ); +CV_EXPORTS void split64s(const int64* src, int64** dst, int len, int cn ); + +CV_EXPORTS void merge8u(const uchar** src, uchar* dst, int len, int cn ); +CV_EXPORTS void merge16u(const ushort** src, ushort* dst, int len, int cn ); +CV_EXPORTS void merge32s(const int** src, int* dst, int len, int cn ); +CV_EXPORTS void merge64s(const int64** src, int64* dst, int len, int cn ); + +CV_EXPORTS void add8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void add8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void add16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void add16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void add32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void add32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void add64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* ); + +CV_EXPORTS void sub8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void sub8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void sub16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void sub16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void sub32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void sub32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void sub64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* ); + +CV_EXPORTS void max8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void max8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void max16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void max16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void max32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void max32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void max64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* ); + +CV_EXPORTS void min8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void min8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void min16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void min16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void min32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void min32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void min64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* ); + +CV_EXPORTS void absdiff8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void absdiff8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void absdiff16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void absdiff16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void absdiff32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void absdiff32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void absdiff64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* ); + +CV_EXPORTS void and8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void or8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void xor8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); +CV_EXPORTS void not8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* ); + +CV_EXPORTS void cmp8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop); +CV_EXPORTS void cmp8s(const schar* src1, size_t step1, const schar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop); +CV_EXPORTS void cmp16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop); +CV_EXPORTS void cmp16s(const short* src1, size_t step1, const short* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop); +CV_EXPORTS void cmp32s(const int* src1, size_t step1, const int* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop); +CV_EXPORTS void cmp32f(const float* src1, size_t step1, const float* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop); +CV_EXPORTS void cmp64f(const double* src1, size_t step1, const double* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop); + +CV_EXPORTS void mul8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void mul8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void mul16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void mul16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void mul32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void mul32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void mul64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scale); + +CV_EXPORTS void div8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void div8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void div16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void div16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void div32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void div32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void div64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scale); + +CV_EXPORTS void recip8u( const uchar *, size_t, const uchar * src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void recip8s( const schar *, size_t, const schar * src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void recip16u( const ushort *, size_t, const ushort * src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void recip16s( const short *, size_t, const short * src2, size_t step2, short* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void recip32s( const int *, size_t, const int * src2, size_t step2, int* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void recip32f( const float *, size_t, const float * src2, size_t step2, float* dst, size_t step, int width, int height, void* scale); +CV_EXPORTS void recip64f( const double *, size_t, const double * src2, size_t step2, double* dst, size_t step, int width, int height, void* scale); + +CV_EXPORTS void addWeighted8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _scalars ); +CV_EXPORTS void addWeighted8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scalars ); +CV_EXPORTS void addWeighted16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scalars ); +CV_EXPORTS void addWeighted16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scalars ); +CV_EXPORTS void addWeighted32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scalars ); +CV_EXPORTS void addWeighted32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scalars ); +CV_EXPORTS void addWeighted64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scalars ); + +CV_EXPORTS void cvt16f32f( const float16_t* src, float* dst, int len ); +CV_EXPORTS void cvt32f16f( const float* src, float16_t* dst, int len ); + +CV_EXPORTS void addRNGBias32f( float* arr, const float* scaleBiasPairs, int len ); +CV_EXPORTS void addRNGBias64f( double* arr, const double* scaleBiasPairs, int len ); + +struct CV_EXPORTS DFT1D +{ + static Ptr create(int len, int count, int depth, int flags, bool * useBuffer = 0); + virtual void apply(const uchar *src, uchar *dst) = 0; + virtual ~DFT1D() {} +}; + +struct CV_EXPORTS DFT2D +{ + static Ptr create(int width, int height, int depth, + int src_channels, int dst_channels, + int flags, int nonzero_rows = 0); + virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0; + virtual ~DFT2D() {} +}; + +struct CV_EXPORTS DCT2D +{ + static Ptr create(int width, int height, int depth, int flags); + virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0; + virtual ~DCT2D() {} +}; + +//! @} core_hal + +//============================================================================= +// for binary compatibility with 3.0 + +//! @cond IGNORED + +CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n); +CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n); +CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n); +CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n); + +CV_EXPORTS void exp(const float* src, float* dst, int n); +CV_EXPORTS void exp(const double* src, double* dst, int n); +CV_EXPORTS void log(const float* src, float* dst, int n); +CV_EXPORTS void log(const double* src, double* dst, int n); + +CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); +CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n); +CV_EXPORTS void magnitude(const double* x, const double* y, double* dst, int n); +CV_EXPORTS void sqrt(const float* src, float* dst, int len); +CV_EXPORTS void sqrt(const double* src, double* dst, int len); +CV_EXPORTS void invSqrt(const float* src, float* dst, int len); +CV_EXPORTS void invSqrt(const double* src, double* dst, int len); + +//! @endcond + +}} //cv::hal + +#endif //OPENCV_HAL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/interface.h b/Prj-Win/3rd/opencv/include/opencv2/core/hal/interface.h new file mode 100755 index 0000000..6f0a83d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/interface.h @@ -0,0 +1,190 @@ +#ifndef OPENCV_CORE_HAL_INTERFACE_H +#define OPENCV_CORE_HAL_INTERFACE_H + +//! @addtogroup core_hal_interface +//! @{ + +//! @name Return codes +//! @{ +#define CV_HAL_ERROR_OK 0 +#define CV_HAL_ERROR_NOT_IMPLEMENTED 1 +#define CV_HAL_ERROR_UNKNOWN -1 +//! @} + +#ifdef __cplusplus +#include +#else +#include +#include +#endif + +//! @name Data types +//! primitive types +//! - schar - signed 1 byte integer +//! - uchar - unsigned 1 byte integer +//! - short - signed 2 byte integer +//! - ushort - unsigned 2 byte integer +//! - int - signed 4 byte integer +//! - uint - unsigned 4 byte integer +//! - int64 - signed 8 byte integer +//! - uint64 - unsigned 8 byte integer +//! @{ +#if !defined _MSC_VER && !defined __BORLANDC__ +# if defined __cplusplus && __cplusplus >= 201103L && !defined __APPLE__ +# include +# ifdef __NEWLIB__ + typedef unsigned int uint; +# else + typedef std::uint32_t uint; +# endif +# else +# include + typedef uint32_t uint; +# endif +#else + typedef unsigned uint; +#endif + +typedef signed char schar; + +#ifndef __IPL_H__ + typedef unsigned char uchar; + typedef unsigned short ushort; +#endif + +#if defined _MSC_VER || defined __BORLANDC__ + typedef __int64 int64; + typedef unsigned __int64 uint64; +# define CV_BIG_INT(n) n##I64 +# define CV_BIG_UINT(n) n##UI64 +#else + typedef int64_t int64; + typedef uint64_t uint64; +# define CV_BIG_INT(n) n##LL +# define CV_BIG_UINT(n) n##ULL +#endif + +#define CV_USRTYPE1 (void)"CV_USRTYPE1 support has been dropped in OpenCV 4.0" + +#define CV_CN_MAX 512 +#define CV_CN_SHIFT 3 +#define CV_DEPTH_MAX (1 << CV_CN_SHIFT) + +#define CV_8U 0 +#define CV_8S 1 +#define CV_16U 2 +#define CV_16S 3 +#define CV_32S 4 +#define CV_32F 5 +#define CV_64F 6 +#define CV_16F 7 + +#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) +#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK) + +#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT)) +#define CV_MAKE_TYPE CV_MAKETYPE + +#define CV_8UC1 CV_MAKETYPE(CV_8U,1) +#define CV_8UC2 CV_MAKETYPE(CV_8U,2) +#define CV_8UC3 CV_MAKETYPE(CV_8U,3) +#define CV_8UC4 CV_MAKETYPE(CV_8U,4) +#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n)) + +#define CV_8SC1 CV_MAKETYPE(CV_8S,1) +#define CV_8SC2 CV_MAKETYPE(CV_8S,2) +#define CV_8SC3 CV_MAKETYPE(CV_8S,3) +#define CV_8SC4 CV_MAKETYPE(CV_8S,4) +#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n)) + +#define CV_16UC1 CV_MAKETYPE(CV_16U,1) +#define CV_16UC2 CV_MAKETYPE(CV_16U,2) +#define CV_16UC3 CV_MAKETYPE(CV_16U,3) +#define CV_16UC4 CV_MAKETYPE(CV_16U,4) +#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n)) + +#define CV_16SC1 CV_MAKETYPE(CV_16S,1) +#define CV_16SC2 CV_MAKETYPE(CV_16S,2) +#define CV_16SC3 CV_MAKETYPE(CV_16S,3) +#define CV_16SC4 CV_MAKETYPE(CV_16S,4) +#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n)) + +#define CV_32SC1 CV_MAKETYPE(CV_32S,1) +#define CV_32SC2 CV_MAKETYPE(CV_32S,2) +#define CV_32SC3 CV_MAKETYPE(CV_32S,3) +#define CV_32SC4 CV_MAKETYPE(CV_32S,4) +#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n)) + +#define CV_32FC1 CV_MAKETYPE(CV_32F,1) +#define CV_32FC2 CV_MAKETYPE(CV_32F,2) +#define CV_32FC3 CV_MAKETYPE(CV_32F,3) +#define CV_32FC4 CV_MAKETYPE(CV_32F,4) +#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n)) + +#define CV_64FC1 CV_MAKETYPE(CV_64F,1) +#define CV_64FC2 CV_MAKETYPE(CV_64F,2) +#define CV_64FC3 CV_MAKETYPE(CV_64F,3) +#define CV_64FC4 CV_MAKETYPE(CV_64F,4) +#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n)) + +#define CV_16FC1 CV_MAKETYPE(CV_16F,1) +#define CV_16FC2 CV_MAKETYPE(CV_16F,2) +#define CV_16FC3 CV_MAKETYPE(CV_16F,3) +#define CV_16FC4 CV_MAKETYPE(CV_16F,4) +#define CV_16FC(n) CV_MAKETYPE(CV_16F,(n)) +//! @} + +//! @name Comparison operation +//! @sa cv::CmpTypes +//! @{ +#define CV_HAL_CMP_EQ 0 +#define CV_HAL_CMP_GT 1 +#define CV_HAL_CMP_GE 2 +#define CV_HAL_CMP_LT 3 +#define CV_HAL_CMP_LE 4 +#define CV_HAL_CMP_NE 5 +//! @} + +//! @name Border processing modes +//! @sa cv::BorderTypes +//! @{ +#define CV_HAL_BORDER_CONSTANT 0 +#define CV_HAL_BORDER_REPLICATE 1 +#define CV_HAL_BORDER_REFLECT 2 +#define CV_HAL_BORDER_WRAP 3 +#define CV_HAL_BORDER_REFLECT_101 4 +#define CV_HAL_BORDER_TRANSPARENT 5 +#define CV_HAL_BORDER_ISOLATED 16 +//! @} + +//! @name DFT flags +//! @{ +#define CV_HAL_DFT_INVERSE 1 +#define CV_HAL_DFT_SCALE 2 +#define CV_HAL_DFT_ROWS 4 +#define CV_HAL_DFT_COMPLEX_OUTPUT 16 +#define CV_HAL_DFT_REAL_OUTPUT 32 +#define CV_HAL_DFT_TWO_STAGE 64 +#define CV_HAL_DFT_STAGE_COLS 128 +#define CV_HAL_DFT_IS_CONTINUOUS 512 +#define CV_HAL_DFT_IS_INPLACE 1024 +//! @} + +//! @name SVD flags +//! @{ +#define CV_HAL_SVD_NO_UV 1 +#define CV_HAL_SVD_SHORT_UV 2 +#define CV_HAL_SVD_MODIFY_A 4 +#define CV_HAL_SVD_FULL_UV 8 +//! @} + +//! @name Gemm flags +//! @{ +#define CV_HAL_GEMM_1_T 1 +#define CV_HAL_GEMM_2_T 2 +#define CV_HAL_GEMM_3_T 4 +//! @} + +//! @} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin.hpp new file mode 100755 index 0000000..a96cfbd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin.hpp @@ -0,0 +1,471 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HAL_INTRIN_HPP +#define OPENCV_HAL_INTRIN_HPP + +#include +#include +#include +#include "opencv2/core/cvdef.h" + +#define OPENCV_HAL_ADD(a, b) ((a) + (b)) +#define OPENCV_HAL_AND(a, b) ((a) & (b)) +#define OPENCV_HAL_NOP(a) (a) +#define OPENCV_HAL_1ST(a, b) (a) + +namespace { +inline unsigned int trailingZeros32(unsigned int value) { +#if defined(_MSC_VER) +#if (_MSC_VER < 1700) || defined(_M_ARM) + unsigned long index = 0; + _BitScanForward(&index, value); + return (unsigned int)index; +#elif defined(__clang__) + // clang-cl doesn't export _tzcnt_u32 for non BMI systems + return value ? __builtin_ctz(value) : 32; +#else + return _tzcnt_u32(value); +#endif +#elif defined(__GNUC__) || defined(__GNUG__) + return __builtin_ctz(value); +#elif defined(__ICC) || defined(__INTEL_COMPILER) + return _bit_scan_forward(value); +#elif defined(__clang__) + return llvm.cttz.i32(value, true); +#else + static const int MultiplyDeBruijnBitPosition[32] = { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; + return MultiplyDeBruijnBitPosition[((uint32_t)((value & -value) * 0x077CB531U)) >> 27]; +#endif +} +} + +// unlike HAL API, which is in cv::hal, +// we put intrinsics into cv namespace to make its +// access from within opencv code more accessible +namespace cv { + +namespace hal { + +enum StoreMode +{ + STORE_UNALIGNED = 0, + STORE_ALIGNED = 1, + STORE_ALIGNED_NOCACHE = 2 +}; + +} + +template struct V_TypeTraits +{ +}; + +#define CV_INTRIN_DEF_TYPE_TRAITS(type, int_type_, uint_type_, abs_type_, w_type_, q_type_, sum_type_, nlanes128_) \ + template<> struct V_TypeTraits \ + { \ + typedef type value_type; \ + typedef int_type_ int_type; \ + typedef abs_type_ abs_type; \ + typedef uint_type_ uint_type; \ + typedef w_type_ w_type; \ + typedef q_type_ q_type; \ + typedef sum_type_ sum_type; \ + enum { nlanes128 = nlanes128_ }; \ + \ + static inline int_type reinterpret_int(type x) \ + { \ + union { type l; int_type i; } v; \ + v.l = x; \ + return v.i; \ + } \ + \ + static inline type reinterpret_from_int(int_type x) \ + { \ + union { type l; int_type i; } v; \ + v.i = x; \ + return v.l; \ + } \ + } + +CV_INTRIN_DEF_TYPE_TRAITS(uchar, schar, uchar, uchar, ushort, unsigned, unsigned, 16); +CV_INTRIN_DEF_TYPE_TRAITS(schar, schar, uchar, uchar, short, int, int, 16); +CV_INTRIN_DEF_TYPE_TRAITS(ushort, short, ushort, ushort, unsigned, uint64, unsigned, 8); +CV_INTRIN_DEF_TYPE_TRAITS(short, short, ushort, ushort, int, int64, int, 8); +CV_INTRIN_DEF_TYPE_TRAITS(unsigned, int, unsigned, unsigned, uint64, void, unsigned, 4); +CV_INTRIN_DEF_TYPE_TRAITS(int, int, unsigned, unsigned, int64, void, int, 4); +CV_INTRIN_DEF_TYPE_TRAITS(float, int, unsigned, float, double, void, float, 4); +CV_INTRIN_DEF_TYPE_TRAITS(uint64, int64, uint64, uint64, void, void, uint64, 2); +CV_INTRIN_DEF_TYPE_TRAITS(int64, int64, uint64, uint64, void, void, int64, 2); +CV_INTRIN_DEF_TYPE_TRAITS(double, int64, uint64, double, void, void, double, 2); + +#ifndef CV_DOXYGEN + +#ifdef CV_CPU_DISPATCH_MODE + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE __CV_CAT(hal_, CV_CPU_DISPATCH_MODE) + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN namespace __CV_CAT(hal_, CV_CPU_DISPATCH_MODE) { + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END } +#else + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE hal_baseline + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN namespace hal_baseline { + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END } +#endif + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END +using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE; +#endif +} + +#ifdef CV_DOXYGEN +# undef CV_AVX2 +# undef CV_SSE2 +# undef CV_NEON +# undef CV_VSX +# undef CV_FP16 +#endif + +#if CV_SSE2 || CV_NEON || CV_VSX +#define CV__SIMD_FORWARD 128 +#include "opencv2/core/hal/intrin_forward.hpp" +#endif + +#if CV_SSE2 + +#include "opencv2/core/hal/intrin_sse_em.hpp" +#include "opencv2/core/hal/intrin_sse.hpp" + +#elif CV_NEON + +#include "opencv2/core/hal/intrin_neon.hpp" + +#elif CV_VSX + +#include "opencv2/core/hal/intrin_vsx.hpp" + +#else + +#define CV_SIMD128_CPP 1 +#include "opencv2/core/hal/intrin_cpp.hpp" + +#endif + +// AVX2 can be used together with SSE2, so +// we define those two sets of intrinsics at once. +// Most of the intrinsics do not conflict (the proper overloaded variant is +// resolved by the argument types, e.g. v_float32x4 ~ SSE2, v_float32x8 ~ AVX2), +// but some of AVX2 intrinsics get v256_ prefix instead of v_, e.g. v256_load() vs v_load(). +// Correspondingly, the wide intrinsics (which are mapped to the "widest" +// available instruction set) will get vx_ prefix +// (and will be mapped to v256_ counterparts) (e.g. vx_load() => v256_load()) +#if CV_AVX2 + +#define CV__SIMD_FORWARD 256 +#include "opencv2/core/hal/intrin_forward.hpp" +#include "opencv2/core/hal/intrin_avx.hpp" + +#endif + +// AVX512 can be used together with SSE2 and AVX2, so +// we define those sets of intrinsics at once. +// For some of AVX512 intrinsics get v512_ prefix instead of v_, e.g. v512_load() vs v_load(). +// Wide intrinsics will be mapped to v512_ counterparts in this case(e.g. vx_load() => v512_load()) +#if CV_AVX512_SKX + +#define CV__SIMD_FORWARD 512 +#include "opencv2/core/hal/intrin_forward.hpp" +#include "opencv2/core/hal/intrin_avx512.hpp" + +#endif + +//! @cond IGNORED + +namespace cv { + +#ifndef CV_DOXYGEN +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN +#endif + +#ifndef CV_SIMD128 +#define CV_SIMD128 0 +#endif + +#ifndef CV_SIMD128_64F +#define CV_SIMD128_64F 0 +#endif + +#ifndef CV_SIMD256 +#define CV_SIMD256 0 +#endif + +#ifndef CV_SIMD256_64F +#define CV_SIMD256_64F 0 +#endif + +#ifndef CV_SIMD512 +#define CV_SIMD512 0 +#endif + +#ifndef CV_SIMD512_64F +#define CV_SIMD512_64F 0 +#endif + +#ifndef CV_SIMD128_FP16 +#define CV_SIMD128_FP16 0 +#endif + +#ifndef CV_SIMD256_FP16 +#define CV_SIMD256_FP16 0 +#endif + +#ifndef CV_SIMD512_FP16 +#define CV_SIMD512_FP16 0 +#endif + +//================================================================================================== + +#define CV_INTRIN_DEFINE_WIDE_INTRIN(typ, vtyp, short_typ, prefix, loadsfx) \ + inline vtyp vx_setall_##short_typ(typ v) { return prefix##_setall_##short_typ(v); } \ + inline vtyp vx_setzero_##short_typ() { return prefix##_setzero_##short_typ(); } \ + inline vtyp vx_##loadsfx(const typ* ptr) { return prefix##_##loadsfx(ptr); } \ + inline vtyp vx_##loadsfx##_aligned(const typ* ptr) { return prefix##_##loadsfx##_aligned(ptr); } \ + inline vtyp vx_##loadsfx##_low(const typ* ptr) { return prefix##_##loadsfx##_low(ptr); } \ + inline vtyp vx_##loadsfx##_halves(const typ* ptr0, const typ* ptr1) { return prefix##_##loadsfx##_halves(ptr0, ptr1); } \ + inline void vx_store(typ* ptr, const vtyp& v) { return v_store(ptr, v); } \ + inline void vx_store_aligned(typ* ptr, const vtyp& v) { return v_store_aligned(ptr, v); } \ + inline vtyp vx_lut(const typ* ptr, const int* idx) { return prefix##_lut(ptr, idx); } \ + inline vtyp vx_lut_pairs(const typ* ptr, const int* idx) { return prefix##_lut_pairs(ptr, idx); } + +#define CV_INTRIN_DEFINE_WIDE_LUT_QUAD(typ, vtyp, prefix) \ + inline vtyp vx_lut_quads(const typ* ptr, const int* idx) { return prefix##_lut_quads(ptr, idx); } + +#define CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(typ, wtyp, prefix) \ + inline wtyp vx_load_expand(const typ* ptr) { return prefix##_load_expand(ptr); } + +#define CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND_Q(typ, qtyp, prefix) \ + inline qtyp vx_load_expand_q(const typ* ptr) { return prefix##_load_expand_q(ptr); } + +#define CV_INTRIN_DEFINE_WIDE_INTRIN_WITH_EXPAND(typ, vtyp, short_typ, wtyp, qtyp, prefix, loadsfx) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(typ, vtyp, short_typ, prefix, loadsfx) \ + CV_INTRIN_DEFINE_WIDE_LUT_QUAD(typ, vtyp, prefix) \ + CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(typ, wtyp, prefix) \ + CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND_Q(typ, qtyp, prefix) + +#define CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(prefix) \ + CV_INTRIN_DEFINE_WIDE_INTRIN_WITH_EXPAND(uchar, v_uint8, u8, v_uint16, v_uint32, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_INTRIN_WITH_EXPAND(schar, v_int8, s8, v_int16, v_int32, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(ushort, v_uint16, u16, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_LUT_QUAD(ushort, v_uint16, prefix) \ + CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(ushort, v_uint32, prefix) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(short, v_int16, s16, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_LUT_QUAD(short, v_int16, prefix) \ + CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(short, v_int32, prefix) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(int, v_int32, s32, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_LUT_QUAD(int, v_int32, prefix) \ + CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(int, v_int64, prefix) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(unsigned, v_uint32, u32, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_LUT_QUAD(unsigned, v_uint32, prefix) \ + CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(unsigned, v_uint64, prefix) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(float, v_float32, f32, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_LUT_QUAD(float, v_float32, prefix) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(int64, v_int64, s64, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_INTRIN(uint64, v_uint64, u64, prefix, load) \ + CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(float16_t, v_float32, prefix) + +template struct V_RegTraits +{ +}; + +#define CV_DEF_REG_TRAITS(prefix, _reg, lane_type, suffix, _u_reg, _w_reg, _q_reg, _int_reg, _round_reg) \ + template<> struct V_RegTraits<_reg> \ + { \ + typedef _reg reg; \ + typedef _u_reg u_reg; \ + typedef _w_reg w_reg; \ + typedef _q_reg q_reg; \ + typedef _int_reg int_reg; \ + typedef _round_reg round_reg; \ + } + +#if CV_SIMD128 || CV_SIMD128_CPP + CV_DEF_REG_TRAITS(v, v_uint8x16, uchar, u8, v_uint8x16, v_uint16x8, v_uint32x4, v_int8x16, void); + CV_DEF_REG_TRAITS(v, v_int8x16, schar, s8, v_uint8x16, v_int16x8, v_int32x4, v_int8x16, void); + CV_DEF_REG_TRAITS(v, v_uint16x8, ushort, u16, v_uint16x8, v_uint32x4, v_uint64x2, v_int16x8, void); + CV_DEF_REG_TRAITS(v, v_int16x8, short, s16, v_uint16x8, v_int32x4, v_int64x2, v_int16x8, void); + CV_DEF_REG_TRAITS(v, v_uint32x4, unsigned, u32, v_uint32x4, v_uint64x2, void, v_int32x4, void); + CV_DEF_REG_TRAITS(v, v_int32x4, int, s32, v_uint32x4, v_int64x2, void, v_int32x4, void); +#if CV_SIMD128_64F + CV_DEF_REG_TRAITS(v, v_float32x4, float, f32, v_float32x4, v_float64x2, void, v_int32x4, v_int32x4); +#else + CV_DEF_REG_TRAITS(v, v_float32x4, float, f32, v_float32x4, void, void, v_int32x4, v_int32x4); +#endif + CV_DEF_REG_TRAITS(v, v_uint64x2, uint64, u64, v_uint64x2, void, void, v_int64x2, void); + CV_DEF_REG_TRAITS(v, v_int64x2, int64, s64, v_uint64x2, void, void, v_int64x2, void); +#if CV_SIMD128_64F + CV_DEF_REG_TRAITS(v, v_float64x2, double, f64, v_float64x2, void, void, v_int64x2, v_int32x4); +#endif +#endif + +#if CV_SIMD256 + CV_DEF_REG_TRAITS(v256, v_uint8x32, uchar, u8, v_uint8x32, v_uint16x16, v_uint32x8, v_int8x32, void); + CV_DEF_REG_TRAITS(v256, v_int8x32, schar, s8, v_uint8x32, v_int16x16, v_int32x8, v_int8x32, void); + CV_DEF_REG_TRAITS(v256, v_uint16x16, ushort, u16, v_uint16x16, v_uint32x8, v_uint64x4, v_int16x16, void); + CV_DEF_REG_TRAITS(v256, v_int16x16, short, s16, v_uint16x16, v_int32x8, v_int64x4, v_int16x16, void); + CV_DEF_REG_TRAITS(v256, v_uint32x8, unsigned, u32, v_uint32x8, v_uint64x4, void, v_int32x8, void); + CV_DEF_REG_TRAITS(v256, v_int32x8, int, s32, v_uint32x8, v_int64x4, void, v_int32x8, void); + CV_DEF_REG_TRAITS(v256, v_float32x8, float, f32, v_float32x8, v_float64x4, void, v_int32x8, v_int32x8); + CV_DEF_REG_TRAITS(v256, v_uint64x4, uint64, u64, v_uint64x4, void, void, v_int64x4, void); + CV_DEF_REG_TRAITS(v256, v_int64x4, int64, s64, v_uint64x4, void, void, v_int64x4, void); + CV_DEF_REG_TRAITS(v256, v_float64x4, double, f64, v_float64x4, void, void, v_int64x4, v_int32x8); +#endif + +#if CV_SIMD512 + CV_DEF_REG_TRAITS(v512, v_uint8x64, uchar, u8, v_uint8x64, v_uint16x32, v_uint32x16, v_int8x64, void); + CV_DEF_REG_TRAITS(v512, v_int8x64, schar, s8, v_uint8x64, v_int16x32, v_int32x16, v_int8x64, void); + CV_DEF_REG_TRAITS(v512, v_uint16x32, ushort, u16, v_uint16x32, v_uint32x16, v_uint64x8, v_int16x32, void); + CV_DEF_REG_TRAITS(v512, v_int16x32, short, s16, v_uint16x32, v_int32x16, v_int64x8, v_int16x32, void); + CV_DEF_REG_TRAITS(v512, v_uint32x16, unsigned, u32, v_uint32x16, v_uint64x8, void, v_int32x16, void); + CV_DEF_REG_TRAITS(v512, v_int32x16, int, s32, v_uint32x16, v_int64x8, void, v_int32x16, void); + CV_DEF_REG_TRAITS(v512, v_float32x16, float, f32, v_float32x16, v_float64x8, void, v_int32x16, v_int32x16); + CV_DEF_REG_TRAITS(v512, v_uint64x8, uint64, u64, v_uint64x8, void, void, v_int64x8, void); + CV_DEF_REG_TRAITS(v512, v_int64x8, int64, s64, v_uint64x8, void, void, v_int64x8, void); + CV_DEF_REG_TRAITS(v512, v_float64x8, double, f64, v_float64x8, void, void, v_int64x8, v_int32x16); +#endif + +#if CV_SIMD512 && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 512) +#define CV__SIMD_NAMESPACE simd512 +namespace CV__SIMD_NAMESPACE { + #define CV_SIMD 1 + #define CV_SIMD_64F CV_SIMD512_64F + #define CV_SIMD_FP16 CV_SIMD512_FP16 + #define CV_SIMD_WIDTH 64 + typedef v_uint8x64 v_uint8; + typedef v_int8x64 v_int8; + typedef v_uint16x32 v_uint16; + typedef v_int16x32 v_int16; + typedef v_uint32x16 v_uint32; + typedef v_int32x16 v_int32; + typedef v_uint64x8 v_uint64; + typedef v_int64x8 v_int64; + typedef v_float32x16 v_float32; + CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v512) +#if CV_SIMD512_64F + typedef v_float64x8 v_float64; + CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v512, load) +#endif + inline void vx_cleanup() { v512_cleanup(); } +} // namespace +using namespace CV__SIMD_NAMESPACE; +#elif CV_SIMD256 && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 256) +#define CV__SIMD_NAMESPACE simd256 +namespace CV__SIMD_NAMESPACE { + #define CV_SIMD 1 + #define CV_SIMD_64F CV_SIMD256_64F + #define CV_SIMD_FP16 CV_SIMD256_FP16 + #define CV_SIMD_WIDTH 32 + typedef v_uint8x32 v_uint8; + typedef v_int8x32 v_int8; + typedef v_uint16x16 v_uint16; + typedef v_int16x16 v_int16; + typedef v_uint32x8 v_uint32; + typedef v_int32x8 v_int32; + typedef v_uint64x4 v_uint64; + typedef v_int64x4 v_int64; + typedef v_float32x8 v_float32; + CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v256) + #if CV_SIMD256_64F + typedef v_float64x4 v_float64; + CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v256, load) + #endif + inline void vx_cleanup() { v256_cleanup(); } +} // namespace +using namespace CV__SIMD_NAMESPACE; +#elif (CV_SIMD128 || CV_SIMD128_CPP) && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 128) +#define CV__SIMD_NAMESPACE simd128 +namespace CV__SIMD_NAMESPACE { + #define CV_SIMD CV_SIMD128 + #define CV_SIMD_64F CV_SIMD128_64F + #define CV_SIMD_WIDTH 16 + typedef v_uint8x16 v_uint8; + typedef v_int8x16 v_int8; + typedef v_uint16x8 v_uint16; + typedef v_int16x8 v_int16; + typedef v_uint32x4 v_uint32; + typedef v_int32x4 v_int32; + typedef v_uint64x2 v_uint64; + typedef v_int64x2 v_int64; + typedef v_float32x4 v_float32; + CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v) + #if CV_SIMD128_64F + typedef v_float64x2 v_float64; + CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v, load) + #endif + inline void vx_cleanup() { v_cleanup(); } +} // namespace +using namespace CV__SIMD_NAMESPACE; +#endif + +#ifndef CV_DOXYGEN +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END +#endif + +#ifndef CV_SIMD_64F +#define CV_SIMD_64F 0 +#endif + +#ifndef CV_SIMD_FP16 +#define CV_SIMD_FP16 0 //!< Defined to 1 on native support of operations with float16x8_t / float16x16_t (SIMD256) types +#endif + + +#ifndef CV_SIMD +#define CV_SIMD 0 +#endif + +} // cv:: + +//! @endcond + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx.hpp new file mode 100755 index 0000000..24e2a52 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx.hpp @@ -0,0 +1,2794 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#ifndef OPENCV_HAL_INTRIN_AVX_HPP +#define OPENCV_HAL_INTRIN_AVX_HPP + +#define CV_SIMD256 1 +#define CV_SIMD256_64F 1 +#define CV_SIMD256_FP16 0 // no native operations with FP16 type. Only load/store from float32x8 are available (if CV_FP16 == 1) + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +///////// Utils //////////// + +inline __m256i _v256_combine(const __m128i& lo, const __m128i& hi) +{ return _mm256_inserti128_si256(_mm256_castsi128_si256(lo), hi, 1); } + +inline __m256 _v256_combine(const __m128& lo, const __m128& hi) +{ return _mm256_insertf128_ps(_mm256_castps128_ps256(lo), hi, 1); } + +inline __m256d _v256_combine(const __m128d& lo, const __m128d& hi) +{ return _mm256_insertf128_pd(_mm256_castpd128_pd256(lo), hi, 1); } + +inline int _v_cvtsi256_si32(const __m256i& a) +{ return _mm_cvtsi128_si32(_mm256_castsi256_si128(a)); } + +inline __m256i _v256_shuffle_odd_64(const __m256i& v) +{ return _mm256_permute4x64_epi64(v, _MM_SHUFFLE(3, 1, 2, 0)); } + +inline __m256d _v256_shuffle_odd_64(const __m256d& v) +{ return _mm256_permute4x64_pd(v, _MM_SHUFFLE(3, 1, 2, 0)); } + +template +inline __m256i _v256_permute2x128(const __m256i& a, const __m256i& b) +{ return _mm256_permute2x128_si256(a, b, imm); } + +template +inline __m256 _v256_permute2x128(const __m256& a, const __m256& b) +{ return _mm256_permute2f128_ps(a, b, imm); } + +template +inline __m256d _v256_permute2x128(const __m256d& a, const __m256d& b) +{ return _mm256_permute2f128_pd(a, b, imm); } + +template +inline _Tpvec v256_permute2x128(const _Tpvec& a, const _Tpvec& b) +{ return _Tpvec(_v256_permute2x128(a.val, b.val)); } + +template +inline __m256i _v256_permute4x64(const __m256i& a) +{ return _mm256_permute4x64_epi64(a, imm); } + +template +inline __m256d _v256_permute4x64(const __m256d& a) +{ return _mm256_permute4x64_pd(a, imm); } + +template +inline _Tpvec v256_permute4x64(const _Tpvec& a) +{ return _Tpvec(_v256_permute4x64(a.val)); } + +inline __m128i _v256_extract_high(const __m256i& v) +{ return _mm256_extracti128_si256(v, 1); } + +inline __m128 _v256_extract_high(const __m256& v) +{ return _mm256_extractf128_ps(v, 1); } + +inline __m128d _v256_extract_high(const __m256d& v) +{ return _mm256_extractf128_pd(v, 1); } + +inline __m128i _v256_extract_low(const __m256i& v) +{ return _mm256_castsi256_si128(v); } + +inline __m128 _v256_extract_low(const __m256& v) +{ return _mm256_castps256_ps128(v); } + +inline __m128d _v256_extract_low(const __m256d& v) +{ return _mm256_castpd256_pd128(v); } + +inline __m256i _v256_packs_epu32(const __m256i& a, const __m256i& b) +{ + const __m256i m = _mm256_set1_epi32(65535); + __m256i am = _mm256_min_epu32(a, m); + __m256i bm = _mm256_min_epu32(b, m); + return _mm256_packus_epi32(am, bm); +} + +///////// Types //////////// + +struct v_uint8x32 +{ + typedef uchar lane_type; + enum { nlanes = 32 }; + __m256i val; + + explicit v_uint8x32(__m256i v) : val(v) {} + v_uint8x32(uchar v0, uchar v1, uchar v2, uchar v3, + uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, + uchar v12, uchar v13, uchar v14, uchar v15, + uchar v16, uchar v17, uchar v18, uchar v19, + uchar v20, uchar v21, uchar v22, uchar v23, + uchar v24, uchar v25, uchar v26, uchar v27, + uchar v28, uchar v29, uchar v30, uchar v31) + { + val = _mm256_setr_epi8((char)v0, (char)v1, (char)v2, (char)v3, + (char)v4, (char)v5, (char)v6 , (char)v7, (char)v8, (char)v9, + (char)v10, (char)v11, (char)v12, (char)v13, (char)v14, (char)v15, + (char)v16, (char)v17, (char)v18, (char)v19, (char)v20, (char)v21, + (char)v22, (char)v23, (char)v24, (char)v25, (char)v26, (char)v27, + (char)v28, (char)v29, (char)v30, (char)v31); + } + v_uint8x32() : val(_mm256_setzero_si256()) {} + uchar get0() const { return (uchar)_v_cvtsi256_si32(val); } +}; + +struct v_int8x32 +{ + typedef schar lane_type; + enum { nlanes = 32 }; + __m256i val; + + explicit v_int8x32(__m256i v) : val(v) {} + v_int8x32(schar v0, schar v1, schar v2, schar v3, + schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, + schar v12, schar v13, schar v14, schar v15, + schar v16, schar v17, schar v18, schar v19, + schar v20, schar v21, schar v22, schar v23, + schar v24, schar v25, schar v26, schar v27, + schar v28, schar v29, schar v30, schar v31) + { + val = _mm256_setr_epi8(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, + v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31); + } + v_int8x32() : val(_mm256_setzero_si256()) {} + schar get0() const { return (schar)_v_cvtsi256_si32(val); } +}; + +struct v_uint16x16 +{ + typedef ushort lane_type; + enum { nlanes = 16 }; + __m256i val; + + explicit v_uint16x16(__m256i v) : val(v) {} + v_uint16x16(ushort v0, ushort v1, ushort v2, ushort v3, + ushort v4, ushort v5, ushort v6, ushort v7, + ushort v8, ushort v9, ushort v10, ushort v11, + ushort v12, ushort v13, ushort v14, ushort v15) + { + val = _mm256_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3, + (short)v4, (short)v5, (short)v6, (short)v7, (short)v8, (short)v9, + (short)v10, (short)v11, (short)v12, (short)v13, (short)v14, (short)v15); + } + v_uint16x16() : val(_mm256_setzero_si256()) {} + ushort get0() const { return (ushort)_v_cvtsi256_si32(val); } +}; + +struct v_int16x16 +{ + typedef short lane_type; + enum { nlanes = 16 }; + __m256i val; + + explicit v_int16x16(__m256i v) : val(v) {} + v_int16x16(short v0, short v1, short v2, short v3, + short v4, short v5, short v6, short v7, + short v8, short v9, short v10, short v11, + short v12, short v13, short v14, short v15) + { + val = _mm256_setr_epi16(v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15); + } + v_int16x16() : val(_mm256_setzero_si256()) {} + short get0() const { return (short)_v_cvtsi256_si32(val); } +}; + +struct v_uint32x8 +{ + typedef unsigned lane_type; + enum { nlanes = 8 }; + __m256i val; + + explicit v_uint32x8(__m256i v) : val(v) {} + v_uint32x8(unsigned v0, unsigned v1, unsigned v2, unsigned v3, + unsigned v4, unsigned v5, unsigned v6, unsigned v7) + { + val = _mm256_setr_epi32((unsigned)v0, (unsigned)v1, (unsigned)v2, + (unsigned)v3, (unsigned)v4, (unsigned)v5, (unsigned)v6, (unsigned)v7); + } + v_uint32x8() : val(_mm256_setzero_si256()) {} + unsigned get0() const { return (unsigned)_v_cvtsi256_si32(val); } +}; + +struct v_int32x8 +{ + typedef int lane_type; + enum { nlanes = 8 }; + __m256i val; + + explicit v_int32x8(__m256i v) : val(v) {} + v_int32x8(int v0, int v1, int v2, int v3, + int v4, int v5, int v6, int v7) + { + val = _mm256_setr_epi32(v0, v1, v2, v3, v4, v5, v6, v7); + } + v_int32x8() : val(_mm256_setzero_si256()) {} + int get0() const { return _v_cvtsi256_si32(val); } +}; + +struct v_float32x8 +{ + typedef float lane_type; + enum { nlanes = 8 }; + __m256 val; + + explicit v_float32x8(__m256 v) : val(v) {} + v_float32x8(float v0, float v1, float v2, float v3, + float v4, float v5, float v6, float v7) + { + val = _mm256_setr_ps(v0, v1, v2, v3, v4, v5, v6, v7); + } + v_float32x8() : val(_mm256_setzero_ps()) {} + float get0() const { return _mm_cvtss_f32(_mm256_castps256_ps128(val)); } +}; + +struct v_uint64x4 +{ + typedef uint64 lane_type; + enum { nlanes = 4 }; + __m256i val; + + explicit v_uint64x4(__m256i v) : val(v) {} + v_uint64x4(uint64 v0, uint64 v1, uint64 v2, uint64 v3) + { val = _mm256_setr_epi64x((int64)v0, (int64)v1, (int64)v2, (int64)v3); } + v_uint64x4() : val(_mm256_setzero_si256()) {} + uint64 get0() const + { + #if defined __x86_64__ || defined _M_X64 + return (uint64)_mm_cvtsi128_si64(_mm256_castsi256_si128(val)); + #else + int a = _mm_cvtsi128_si32(_mm256_castsi256_si128(val)); + int b = _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_srli_epi64(val, 32))); + return (unsigned)a | ((uint64)(unsigned)b << 32); + #endif + } +}; + +struct v_int64x4 +{ + typedef int64 lane_type; + enum { nlanes = 4 }; + __m256i val; + + explicit v_int64x4(__m256i v) : val(v) {} + v_int64x4(int64 v0, int64 v1, int64 v2, int64 v3) + { val = _mm256_setr_epi64x(v0, v1, v2, v3); } + v_int64x4() : val(_mm256_setzero_si256()) {} + + int64 get0() const + { + #if defined __x86_64__ || defined _M_X64 + return (int64)_mm_cvtsi128_si64(_mm256_castsi256_si128(val)); + #else + int a = _mm_cvtsi128_si32(_mm256_castsi256_si128(val)); + int b = _mm_cvtsi128_si32(_mm256_castsi256_si128(_mm256_srli_epi64(val, 32))); + return (int64)((unsigned)a | ((uint64)(unsigned)b << 32)); + #endif + } +}; + +struct v_float64x4 +{ + typedef double lane_type; + enum { nlanes = 4 }; + __m256d val; + + explicit v_float64x4(__m256d v) : val(v) {} + v_float64x4(double v0, double v1, double v2, double v3) + { val = _mm256_setr_pd(v0, v1, v2, v3); } + v_float64x4() : val(_mm256_setzero_pd()) {} + double get0() const { return _mm_cvtsd_f64(_mm256_castpd256_pd128(val)); } +}; + +//////////////// Load and store operations /////////////// + +#define OPENCV_HAL_IMPL_AVX_LOADSTORE(_Tpvec, _Tp) \ + inline _Tpvec v256_load(const _Tp* ptr) \ + { return _Tpvec(_mm256_loadu_si256((const __m256i*)ptr)); } \ + inline _Tpvec v256_load_aligned(const _Tp* ptr) \ + { return _Tpvec(_mm256_load_si256((const __m256i*)ptr)); } \ + inline _Tpvec v256_load_low(const _Tp* ptr) \ + { \ + __m128i v128 = _mm_loadu_si128((const __m128i*)ptr); \ + return _Tpvec(_mm256_castsi128_si256(v128)); \ + } \ + inline _Tpvec v256_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ + { \ + __m128i vlo = _mm_loadu_si128((const __m128i*)ptr0); \ + __m128i vhi = _mm_loadu_si128((const __m128i*)ptr1); \ + return _Tpvec(_v256_combine(vlo, vhi)); \ + } \ + inline void v_store(_Tp* ptr, const _Tpvec& a) \ + { _mm256_storeu_si256((__m256i*)ptr, a.val); } \ + inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ + { _mm256_store_si256((__m256i*)ptr, a.val); } \ + inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ + { _mm256_stream_si256((__m256i*)ptr, a.val); } \ + inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode mode) \ + { \ + if( mode == hal::STORE_UNALIGNED ) \ + _mm256_storeu_si256((__m256i*)ptr, a.val); \ + else if( mode == hal::STORE_ALIGNED_NOCACHE ) \ + _mm256_stream_si256((__m256i*)ptr, a.val); \ + else \ + _mm256_store_si256((__m256i*)ptr, a.val); \ + } \ + inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ + { _mm_storeu_si128((__m128i*)ptr, _v256_extract_low(a.val)); } \ + inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ + { _mm_storeu_si128((__m128i*)ptr, _v256_extract_high(a.val)); } + +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_uint8x32, uchar) +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_int8x32, schar) +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_uint16x16, ushort) +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_int16x16, short) +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_uint32x8, unsigned) +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_int32x8, int) +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_uint64x4, uint64) +OPENCV_HAL_IMPL_AVX_LOADSTORE(v_int64x4, int64) + +#define OPENCV_HAL_IMPL_AVX_LOADSTORE_FLT(_Tpvec, _Tp, suffix, halfreg) \ + inline _Tpvec v256_load(const _Tp* ptr) \ + { return _Tpvec(_mm256_loadu_##suffix(ptr)); } \ + inline _Tpvec v256_load_aligned(const _Tp* ptr) \ + { return _Tpvec(_mm256_load_##suffix(ptr)); } \ + inline _Tpvec v256_load_low(const _Tp* ptr) \ + { \ + return _Tpvec(_mm256_cast##suffix##128_##suffix##256 \ + (_mm_loadu_##suffix(ptr))); \ + } \ + inline _Tpvec v256_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ + { \ + halfreg vlo = _mm_loadu_##suffix(ptr0); \ + halfreg vhi = _mm_loadu_##suffix(ptr1); \ + return _Tpvec(_v256_combine(vlo, vhi)); \ + } \ + inline void v_store(_Tp* ptr, const _Tpvec& a) \ + { _mm256_storeu_##suffix(ptr, a.val); } \ + inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ + { _mm256_store_##suffix(ptr, a.val); } \ + inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ + { _mm256_stream_##suffix(ptr, a.val); } \ + inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode mode) \ + { \ + if( mode == hal::STORE_UNALIGNED ) \ + _mm256_storeu_##suffix(ptr, a.val); \ + else if( mode == hal::STORE_ALIGNED_NOCACHE ) \ + _mm256_stream_##suffix(ptr, a.val); \ + else \ + _mm256_store_##suffix(ptr, a.val); \ + } \ + inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ + { _mm_storeu_##suffix(ptr, _v256_extract_low(a.val)); } \ + inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ + { _mm_storeu_##suffix(ptr, _v256_extract_high(a.val)); } + +OPENCV_HAL_IMPL_AVX_LOADSTORE_FLT(v_float32x8, float, ps, __m128) +OPENCV_HAL_IMPL_AVX_LOADSTORE_FLT(v_float64x4, double, pd, __m128d) + +#define OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, _Tpvecf, suffix, cast) \ + inline _Tpvec v_reinterpret_as_##suffix(const _Tpvecf& a) \ + { return _Tpvec(cast(a.val)); } + +#define OPENCV_HAL_IMPL_AVX_INIT(_Tpvec, _Tp, suffix, ssuffix, ctype_s) \ + inline _Tpvec v256_setzero_##suffix() \ + { return _Tpvec(_mm256_setzero_si256()); } \ + inline _Tpvec v256_setall_##suffix(_Tp v) \ + { return _Tpvec(_mm256_set1_##ssuffix((ctype_s)v)); } \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint8x32, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int8x32, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint16x16, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int16x16, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint32x8, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int32x8, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint64x4, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int64x4, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_float32x8, suffix, _mm256_castps_si256) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_float64x4, suffix, _mm256_castpd_si256) + +OPENCV_HAL_IMPL_AVX_INIT(v_uint8x32, uchar, u8, epi8, char) +OPENCV_HAL_IMPL_AVX_INIT(v_int8x32, schar, s8, epi8, char) +OPENCV_HAL_IMPL_AVX_INIT(v_uint16x16, ushort, u16, epi16, short) +OPENCV_HAL_IMPL_AVX_INIT(v_int16x16, short, s16, epi16, short) +OPENCV_HAL_IMPL_AVX_INIT(v_uint32x8, unsigned, u32, epi32, int) +OPENCV_HAL_IMPL_AVX_INIT(v_int32x8, int, s32, epi32, int) +OPENCV_HAL_IMPL_AVX_INIT(v_uint64x4, uint64, u64, epi64x, int64) +OPENCV_HAL_IMPL_AVX_INIT(v_int64x4, int64, s64, epi64x, int64) + +#define OPENCV_HAL_IMPL_AVX_INIT_FLT(_Tpvec, _Tp, suffix, zsuffix, cast) \ + inline _Tpvec v256_setzero_##suffix() \ + { return _Tpvec(_mm256_setzero_##zsuffix()); } \ + inline _Tpvec v256_setall_##suffix(_Tp v) \ + { return _Tpvec(_mm256_set1_##zsuffix(v)); } \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint8x32, suffix, cast) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int8x32, suffix, cast) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint16x16, suffix, cast) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int16x16, suffix, cast) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint32x8, suffix, cast) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int32x8, suffix, cast) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_uint64x4, suffix, cast) \ + OPENCV_HAL_IMPL_AVX_CAST(_Tpvec, v_int64x4, suffix, cast) + +OPENCV_HAL_IMPL_AVX_INIT_FLT(v_float32x8, float, f32, ps, _mm256_castsi256_ps) +OPENCV_HAL_IMPL_AVX_INIT_FLT(v_float64x4, double, f64, pd, _mm256_castsi256_pd) + +inline v_float32x8 v_reinterpret_as_f32(const v_float32x8& a) +{ return a; } +inline v_float32x8 v_reinterpret_as_f32(const v_float64x4& a) +{ return v_float32x8(_mm256_castpd_ps(a.val)); } + +inline v_float64x4 v_reinterpret_as_f64(const v_float64x4& a) +{ return a; } +inline v_float64x4 v_reinterpret_as_f64(const v_float32x8& a) +{ return v_float64x4(_mm256_castps_pd(a.val)); } + +/* Recombine */ +/*#define OPENCV_HAL_IMPL_AVX_COMBINE(_Tpvec, perm) \ + inline _Tpvec v_combine_low(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(perm(a.val, b.val, 0x20)); } \ + inline _Tpvec v_combine_high(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(perm(a.val, b.val, 0x31)); } \ + inline void v_recombine(const _Tpvec& a, const _Tpvec& b, \ + _Tpvec& c, _Tpvec& d) \ + { c = v_combine_low(a, b); d = v_combine_high(a, b); } + +#define OPENCV_HAL_IMPL_AVX_UNPACKS(_Tpvec, suffix) \ + OPENCV_HAL_IMPL_AVX_COMBINE(_Tpvec, _mm256_permute2x128_si256) \ + inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, \ + _Tpvec& b0, _Tpvec& b1) \ + { \ + __m256i v0 = _v256_shuffle_odd_64(a0.val); \ + __m256i v1 = _v256_shuffle_odd_64(a1.val); \ + b0.val = _mm256_unpacklo_##suffix(v0, v1); \ + b1.val = _mm256_unpackhi_##suffix(v0, v1); \ + } + +OPENCV_HAL_IMPL_AVX_UNPACKS(v_uint8x32, epi8) +OPENCV_HAL_IMPL_AVX_UNPACKS(v_int8x32, epi8) +OPENCV_HAL_IMPL_AVX_UNPACKS(v_uint16x16, epi16) +OPENCV_HAL_IMPL_AVX_UNPACKS(v_int16x16, epi16) +OPENCV_HAL_IMPL_AVX_UNPACKS(v_uint32x8, epi32) +OPENCV_HAL_IMPL_AVX_UNPACKS(v_int32x8, epi32) +OPENCV_HAL_IMPL_AVX_UNPACKS(v_uint64x4, epi64) +OPENCV_HAL_IMPL_AVX_UNPACKS(v_int64x4, epi64) +OPENCV_HAL_IMPL_AVX_COMBINE(v_float32x8, _mm256_permute2f128_ps) +OPENCV_HAL_IMPL_AVX_COMBINE(v_float64x4, _mm256_permute2f128_pd) + +inline void v_zip(const v_float32x8& a0, const v_float32x8& a1, v_float32x8& b0, v_float32x8& b1) +{ + __m256 v0 = _mm256_unpacklo_ps(a0.val, a1.val); + __m256 v1 = _mm256_unpackhi_ps(a0.val, a1.val); + v_recombine(v_float32x8(v0), v_float32x8(v1), b0, b1); +} + +inline void v_zip(const v_float64x4& a0, const v_float64x4& a1, v_float64x4& b0, v_float64x4& b1) +{ + __m256d v0 = _v_shuffle_odd_64(a0.val); + __m256d v1 = _v_shuffle_odd_64(a1.val); + b0.val = _mm256_unpacklo_pd(v0, v1); + b1.val = _mm256_unpackhi_pd(v0, v1); +}*/ + +//////////////// Variant Value reordering /////////////// + +// unpacks +#define OPENCV_HAL_IMPL_AVX_UNPACK(_Tpvec, suffix) \ + inline _Tpvec v256_unpacklo(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm256_unpacklo_##suffix(a.val, b.val)); } \ + inline _Tpvec v256_unpackhi(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm256_unpackhi_##suffix(a.val, b.val)); } + +OPENCV_HAL_IMPL_AVX_UNPACK(v_uint8x32, epi8) +OPENCV_HAL_IMPL_AVX_UNPACK(v_int8x32, epi8) +OPENCV_HAL_IMPL_AVX_UNPACK(v_uint16x16, epi16) +OPENCV_HAL_IMPL_AVX_UNPACK(v_int16x16, epi16) +OPENCV_HAL_IMPL_AVX_UNPACK(v_uint32x8, epi32) +OPENCV_HAL_IMPL_AVX_UNPACK(v_int32x8, epi32) +OPENCV_HAL_IMPL_AVX_UNPACK(v_uint64x4, epi64) +OPENCV_HAL_IMPL_AVX_UNPACK(v_int64x4, epi64) +OPENCV_HAL_IMPL_AVX_UNPACK(v_float32x8, ps) +OPENCV_HAL_IMPL_AVX_UNPACK(v_float64x4, pd) + +// blend +#define OPENCV_HAL_IMPL_AVX_BLEND(_Tpvec, suffix) \ + template \ + inline _Tpvec v256_blend(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm256_blend_##suffix(a.val, b.val, m)); } + +OPENCV_HAL_IMPL_AVX_BLEND(v_uint16x16, epi16) +OPENCV_HAL_IMPL_AVX_BLEND(v_int16x16, epi16) +OPENCV_HAL_IMPL_AVX_BLEND(v_uint32x8, epi32) +OPENCV_HAL_IMPL_AVX_BLEND(v_int32x8, epi32) +OPENCV_HAL_IMPL_AVX_BLEND(v_float32x8, ps) +OPENCV_HAL_IMPL_AVX_BLEND(v_float64x4, pd) + +template +inline v_uint64x4 v256_blend(const v_uint64x4& a, const v_uint64x4& b) +{ + enum {M0 = m}; + enum {M1 = (M0 | (M0 << 2)) & 0x33}; + enum {M2 = (M1 | (M1 << 1)) & 0x55}; + enum {MM = M2 | (M2 << 1)}; + return v_uint64x4(_mm256_blend_epi32(a.val, b.val, MM)); +} +template +inline v_int64x4 v256_blend(const v_int64x4& a, const v_int64x4& b) +{ return v_int64x4(v256_blend(v_uint64x4(a.val), v_uint64x4(b.val)).val); } + +// shuffle +// todo: emluate 64bit +#define OPENCV_HAL_IMPL_AVX_SHUFFLE(_Tpvec, intrin) \ + template \ + inline _Tpvec v256_shuffle(const _Tpvec& a) \ + { return _Tpvec(_mm256_##intrin(a.val, m)); } + +OPENCV_HAL_IMPL_AVX_SHUFFLE(v_uint32x8, shuffle_epi32) +OPENCV_HAL_IMPL_AVX_SHUFFLE(v_int32x8, shuffle_epi32) +OPENCV_HAL_IMPL_AVX_SHUFFLE(v_float32x8, permute_ps) +OPENCV_HAL_IMPL_AVX_SHUFFLE(v_float64x4, permute_pd) + +template +inline void v256_zip(const _Tpvec& a, const _Tpvec& b, _Tpvec& ab0, _Tpvec& ab1) +{ + ab0 = v256_unpacklo(a, b); + ab1 = v256_unpackhi(a, b); +} + +template +inline _Tpvec v256_combine_diagonal(const _Tpvec& a, const _Tpvec& b) +{ return _Tpvec(_mm256_blend_epi32(a.val, b.val, 0xf0)); } + +inline v_float32x8 v256_combine_diagonal(const v_float32x8& a, const v_float32x8& b) +{ return v256_blend<0xf0>(a, b); } + +inline v_float64x4 v256_combine_diagonal(const v_float64x4& a, const v_float64x4& b) +{ return v256_blend<0xc>(a, b); } + +template +inline _Tpvec v256_alignr_128(const _Tpvec& a, const _Tpvec& b) +{ return v256_permute2x128<0x21>(a, b); } + +template +inline _Tpvec v256_alignr_64(const _Tpvec& a, const _Tpvec& b) +{ return _Tpvec(_mm256_alignr_epi8(a.val, b.val, 8)); } +inline v_float64x4 v256_alignr_64(const v_float64x4& a, const v_float64x4& b) +{ return v_float64x4(_mm256_shuffle_pd(b.val, a.val, _MM_SHUFFLE(0, 0, 1, 1))); } +// todo: emulate float32 + +template +inline _Tpvec v256_swap_halves(const _Tpvec& a) +{ return v256_permute2x128<1>(a, a); } + +template +inline _Tpvec v256_reverse_64(const _Tpvec& a) +{ return v256_permute4x64<_MM_SHUFFLE(0, 1, 2, 3)>(a); } + +// ZIP +#define OPENCV_HAL_IMPL_AVX_ZIP(_Tpvec) \ + inline _Tpvec v_combine_low(const _Tpvec& a, const _Tpvec& b) \ + { return v256_permute2x128<0x20>(a, b); } \ + inline _Tpvec v_combine_high(const _Tpvec& a, const _Tpvec& b) \ + { return v256_permute2x128<0x31>(a, b); } \ + inline void v_recombine(const _Tpvec& a, const _Tpvec& b, \ + _Tpvec& c, _Tpvec& d) \ + { \ + _Tpvec a1b0 = v256_alignr_128(a, b); \ + c = v256_combine_diagonal(a, a1b0); \ + d = v256_combine_diagonal(a1b0, b); \ + } \ + inline void v_zip(const _Tpvec& a, const _Tpvec& b, \ + _Tpvec& ab0, _Tpvec& ab1) \ + { \ + _Tpvec ab0ab2, ab1ab3; \ + v256_zip(a, b, ab0ab2, ab1ab3); \ + v_recombine(ab0ab2, ab1ab3, ab0, ab1); \ + } + +OPENCV_HAL_IMPL_AVX_ZIP(v_uint8x32) +OPENCV_HAL_IMPL_AVX_ZIP(v_int8x32) +OPENCV_HAL_IMPL_AVX_ZIP(v_uint16x16) +OPENCV_HAL_IMPL_AVX_ZIP(v_int16x16) +OPENCV_HAL_IMPL_AVX_ZIP(v_uint32x8) +OPENCV_HAL_IMPL_AVX_ZIP(v_int32x8) +OPENCV_HAL_IMPL_AVX_ZIP(v_uint64x4) +OPENCV_HAL_IMPL_AVX_ZIP(v_int64x4) +OPENCV_HAL_IMPL_AVX_ZIP(v_float32x8) +OPENCV_HAL_IMPL_AVX_ZIP(v_float64x4) + +////////// Arithmetic, bitwise and comparison operations ///////// + +/* Element-wise binary and unary operations */ + +/** Arithmetics **/ +#define OPENCV_HAL_IMPL_AVX_BIN_OP(bin_op, _Tpvec, intrin) \ + inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(intrin(a.val, b.val)); } \ + inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ + { a.val = intrin(a.val, b.val); return a; } + +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint8x32, _mm256_adds_epu8) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint8x32, _mm256_subs_epu8) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int8x32, _mm256_adds_epi8) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int8x32, _mm256_subs_epi8) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint16x16, _mm256_adds_epu16) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint16x16, _mm256_subs_epu16) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int16x16, _mm256_adds_epi16) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int16x16, _mm256_subs_epi16) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint32x8, _mm256_add_epi32) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint32x8, _mm256_sub_epi32) +OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_uint32x8, _mm256_mullo_epi32) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int32x8, _mm256_add_epi32) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int32x8, _mm256_sub_epi32) +OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_int32x8, _mm256_mullo_epi32) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint64x4, _mm256_add_epi64) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint64x4, _mm256_sub_epi64) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int64x4, _mm256_add_epi64) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int64x4, _mm256_sub_epi64) + +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_float32x8, _mm256_add_ps) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_float32x8, _mm256_sub_ps) +OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_float32x8, _mm256_mul_ps) +OPENCV_HAL_IMPL_AVX_BIN_OP(/, v_float32x8, _mm256_div_ps) +OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_float64x4, _mm256_add_pd) +OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_float64x4, _mm256_sub_pd) +OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_float64x4, _mm256_mul_pd) +OPENCV_HAL_IMPL_AVX_BIN_OP(/, v_float64x4, _mm256_div_pd) + +// saturating multiply 8-bit, 16-bit +inline v_uint8x32 operator * (const v_uint8x32& a, const v_uint8x32& b) +{ + v_uint16x16 c, d; + v_mul_expand(a, b, c, d); + return v_pack(c, d); +} +inline v_int8x32 operator * (const v_int8x32& a, const v_int8x32& b) +{ + v_int16x16 c, d; + v_mul_expand(a, b, c, d); + return v_pack(c, d); +} +inline v_uint16x16 operator * (const v_uint16x16& a, const v_uint16x16& b) +{ + __m256i pl = _mm256_mullo_epi16(a.val, b.val); + __m256i ph = _mm256_mulhi_epu16(a.val, b.val); + __m256i p0 = _mm256_unpacklo_epi16(pl, ph); + __m256i p1 = _mm256_unpackhi_epi16(pl, ph); + return v_uint16x16(_v256_packs_epu32(p0, p1)); +} +inline v_int16x16 operator * (const v_int16x16& a, const v_int16x16& b) +{ + __m256i pl = _mm256_mullo_epi16(a.val, b.val); + __m256i ph = _mm256_mulhi_epi16(a.val, b.val); + __m256i p0 = _mm256_unpacklo_epi16(pl, ph); + __m256i p1 = _mm256_unpackhi_epi16(pl, ph); + return v_int16x16(_mm256_packs_epi32(p0, p1)); +} +inline v_uint8x32& operator *= (v_uint8x32& a, const v_uint8x32& b) +{ a = a * b; return a; } +inline v_int8x32& operator *= (v_int8x32& a, const v_int8x32& b) +{ a = a * b; return a; } +inline v_uint16x16& operator *= (v_uint16x16& a, const v_uint16x16& b) +{ a = a * b; return a; } +inline v_int16x16& operator *= (v_int16x16& a, const v_int16x16& b) +{ a = a * b; return a; } + +/** Non-saturating arithmetics **/ +#define OPENCV_HAL_IMPL_AVX_BIN_FUNC(func, _Tpvec, intrin) \ + inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(intrin(a.val, b.val)); } + +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint8x32, _mm256_add_epi8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int8x32, _mm256_add_epi8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint16x16, _mm256_add_epi16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int16x16, _mm256_add_epi16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint8x32, _mm256_sub_epi8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int8x32, _mm256_sub_epi8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint16x16, _mm256_sub_epi16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int16x16, _mm256_sub_epi16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_mul_wrap, v_uint16x16, _mm256_mullo_epi16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_mul_wrap, v_int16x16, _mm256_mullo_epi16) + +inline v_uint8x32 v_mul_wrap(const v_uint8x32& a, const v_uint8x32& b) +{ + __m256i ad = _mm256_srai_epi16(a.val, 8); + __m256i bd = _mm256_srai_epi16(b.val, 8); + __m256i p0 = _mm256_mullo_epi16(a.val, b.val); // even + __m256i p1 = _mm256_slli_epi16(_mm256_mullo_epi16(ad, bd), 8); // odd + + const __m256i b01 = _mm256_set1_epi32(0xFF00FF00); + return v_uint8x32(_mm256_blendv_epi8(p0, p1, b01)); +} +inline v_int8x32 v_mul_wrap(const v_int8x32& a, const v_int8x32& b) +{ + return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b))); +} + +// Multiply and expand +inline void v_mul_expand(const v_uint8x32& a, const v_uint8x32& b, + v_uint16x16& c, v_uint16x16& d) +{ + v_uint16x16 a0, a1, b0, b1; + v_expand(a, a0, a1); + v_expand(b, b0, b1); + c = v_mul_wrap(a0, b0); + d = v_mul_wrap(a1, b1); +} + +inline void v_mul_expand(const v_int8x32& a, const v_int8x32& b, + v_int16x16& c, v_int16x16& d) +{ + v_int16x16 a0, a1, b0, b1; + v_expand(a, a0, a1); + v_expand(b, b0, b1); + c = v_mul_wrap(a0, b0); + d = v_mul_wrap(a1, b1); +} + +inline void v_mul_expand(const v_int16x16& a, const v_int16x16& b, + v_int32x8& c, v_int32x8& d) +{ + v_int16x16 vhi = v_int16x16(_mm256_mulhi_epi16(a.val, b.val)); + + v_int16x16 v0, v1; + v_zip(v_mul_wrap(a, b), vhi, v0, v1); + + c = v_reinterpret_as_s32(v0); + d = v_reinterpret_as_s32(v1); +} + +inline void v_mul_expand(const v_uint16x16& a, const v_uint16x16& b, + v_uint32x8& c, v_uint32x8& d) +{ + v_uint16x16 vhi = v_uint16x16(_mm256_mulhi_epu16(a.val, b.val)); + + v_uint16x16 v0, v1; + v_zip(v_mul_wrap(a, b), vhi, v0, v1); + + c = v_reinterpret_as_u32(v0); + d = v_reinterpret_as_u32(v1); +} + +inline void v_mul_expand(const v_uint32x8& a, const v_uint32x8& b, + v_uint64x4& c, v_uint64x4& d) +{ + __m256i v0 = _mm256_mul_epu32(a.val, b.val); + __m256i v1 = _mm256_mul_epu32(_mm256_srli_epi64(a.val, 32), _mm256_srli_epi64(b.val, 32)); + v_zip(v_uint64x4(v0), v_uint64x4(v1), c, d); +} + +inline v_int16x16 v_mul_hi(const v_int16x16& a, const v_int16x16& b) { return v_int16x16(_mm256_mulhi_epi16(a.val, b.val)); } +inline v_uint16x16 v_mul_hi(const v_uint16x16& a, const v_uint16x16& b) { return v_uint16x16(_mm256_mulhi_epu16(a.val, b.val)); } + +/** Bitwise shifts **/ +#define OPENCV_HAL_IMPL_AVX_SHIFT_OP(_Tpuvec, _Tpsvec, suffix, srai) \ + inline _Tpuvec operator << (const _Tpuvec& a, int imm) \ + { return _Tpuvec(_mm256_slli_##suffix(a.val, imm)); } \ + inline _Tpsvec operator << (const _Tpsvec& a, int imm) \ + { return _Tpsvec(_mm256_slli_##suffix(a.val, imm)); } \ + inline _Tpuvec operator >> (const _Tpuvec& a, int imm) \ + { return _Tpuvec(_mm256_srli_##suffix(a.val, imm)); } \ + inline _Tpsvec operator >> (const _Tpsvec& a, int imm) \ + { return _Tpsvec(srai(a.val, imm)); } \ + template \ + inline _Tpuvec v_shl(const _Tpuvec& a) \ + { return _Tpuvec(_mm256_slli_##suffix(a.val, imm)); } \ + template \ + inline _Tpsvec v_shl(const _Tpsvec& a) \ + { return _Tpsvec(_mm256_slli_##suffix(a.val, imm)); } \ + template \ + inline _Tpuvec v_shr(const _Tpuvec& a) \ + { return _Tpuvec(_mm256_srli_##suffix(a.val, imm)); } \ + template \ + inline _Tpsvec v_shr(const _Tpsvec& a) \ + { return _Tpsvec(srai(a.val, imm)); } + +OPENCV_HAL_IMPL_AVX_SHIFT_OP(v_uint16x16, v_int16x16, epi16, _mm256_srai_epi16) +OPENCV_HAL_IMPL_AVX_SHIFT_OP(v_uint32x8, v_int32x8, epi32, _mm256_srai_epi32) + +inline __m256i _mm256_srai_epi64xx(const __m256i a, int imm) +{ + __m256i d = _mm256_set1_epi64x((int64)1 << 63); + __m256i r = _mm256_srli_epi64(_mm256_add_epi64(a, d), imm); + return _mm256_sub_epi64(r, _mm256_srli_epi64(d, imm)); +} +OPENCV_HAL_IMPL_AVX_SHIFT_OP(v_uint64x4, v_int64x4, epi64, _mm256_srai_epi64xx) + + +/** Bitwise logic **/ +#define OPENCV_HAL_IMPL_AVX_LOGIC_OP(_Tpvec, suffix, not_const) \ + OPENCV_HAL_IMPL_AVX_BIN_OP(&, _Tpvec, _mm256_and_##suffix) \ + OPENCV_HAL_IMPL_AVX_BIN_OP(|, _Tpvec, _mm256_or_##suffix) \ + OPENCV_HAL_IMPL_AVX_BIN_OP(^, _Tpvec, _mm256_xor_##suffix) \ + inline _Tpvec operator ~ (const _Tpvec& a) \ + { return _Tpvec(_mm256_xor_##suffix(a.val, not_const)); } + +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_uint8x32, si256, _mm256_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_int8x32, si256, _mm256_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_uint16x16, si256, _mm256_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_int16x16, si256, _mm256_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_uint32x8, si256, _mm256_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_int32x8, si256, _mm256_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_uint64x4, si256, _mm256_set1_epi64x(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_int64x4, si256, _mm256_set1_epi64x(-1)) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_float32x8, ps, _mm256_castsi256_ps(_mm256_set1_epi32(-1))) +OPENCV_HAL_IMPL_AVX_LOGIC_OP(v_float64x4, pd, _mm256_castsi256_pd(_mm256_set1_epi32(-1))) + +/** Select **/ +#define OPENCV_HAL_IMPL_AVX_SELECT(_Tpvec, suffix) \ + inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm256_blendv_##suffix(b.val, a.val, mask.val)); } + +OPENCV_HAL_IMPL_AVX_SELECT(v_uint8x32, epi8) +OPENCV_HAL_IMPL_AVX_SELECT(v_int8x32, epi8) +OPENCV_HAL_IMPL_AVX_SELECT(v_uint16x16, epi8) +OPENCV_HAL_IMPL_AVX_SELECT(v_int16x16, epi8) +OPENCV_HAL_IMPL_AVX_SELECT(v_uint32x8, epi8) +OPENCV_HAL_IMPL_AVX_SELECT(v_int32x8, epi8) +OPENCV_HAL_IMPL_AVX_SELECT(v_float32x8, ps) +OPENCV_HAL_IMPL_AVX_SELECT(v_float64x4, pd) + +/** Comparison **/ +#define OPENCV_HAL_IMPL_AVX_CMP_OP_OV(_Tpvec) \ + inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ + { return ~(a == b); } \ + inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \ + { return b > a; } \ + inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ + { return ~(a < b); } \ + inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \ + { return b >= a; } + +#define OPENCV_HAL_IMPL_AVX_CMP_OP_INT(_Tpuvec, _Tpsvec, suffix, sbit) \ + inline _Tpuvec operator == (const _Tpuvec& a, const _Tpuvec& b) \ + { return _Tpuvec(_mm256_cmpeq_##suffix(a.val, b.val)); } \ + inline _Tpuvec operator > (const _Tpuvec& a, const _Tpuvec& b) \ + { \ + __m256i smask = _mm256_set1_##suffix(sbit); \ + return _Tpuvec(_mm256_cmpgt_##suffix( \ + _mm256_xor_si256(a.val, smask), \ + _mm256_xor_si256(b.val, smask))); \ + } \ + inline _Tpsvec operator == (const _Tpsvec& a, const _Tpsvec& b) \ + { return _Tpsvec(_mm256_cmpeq_##suffix(a.val, b.val)); } \ + inline _Tpsvec operator > (const _Tpsvec& a, const _Tpsvec& b) \ + { return _Tpsvec(_mm256_cmpgt_##suffix(a.val, b.val)); } \ + OPENCV_HAL_IMPL_AVX_CMP_OP_OV(_Tpuvec) \ + OPENCV_HAL_IMPL_AVX_CMP_OP_OV(_Tpsvec) + +OPENCV_HAL_IMPL_AVX_CMP_OP_INT(v_uint8x32, v_int8x32, epi8, (char)-128) +OPENCV_HAL_IMPL_AVX_CMP_OP_INT(v_uint16x16, v_int16x16, epi16, (short)-32768) +OPENCV_HAL_IMPL_AVX_CMP_OP_INT(v_uint32x8, v_int32x8, epi32, (int)0x80000000) + +#define OPENCV_HAL_IMPL_AVX_CMP_OP_64BIT(_Tpvec) \ + inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm256_cmpeq_epi64(a.val, b.val)); } \ + inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ + { return ~(a == b); } + +OPENCV_HAL_IMPL_AVX_CMP_OP_64BIT(v_uint64x4) +OPENCV_HAL_IMPL_AVX_CMP_OP_64BIT(v_int64x4) + +#define OPENCV_HAL_IMPL_AVX_CMP_FLT(bin_op, imm8, _Tpvec, suffix) \ + inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm256_cmp_##suffix(a.val, b.val, imm8)); } + +#define OPENCV_HAL_IMPL_AVX_CMP_OP_FLT(_Tpvec, suffix) \ + OPENCV_HAL_IMPL_AVX_CMP_FLT(==, _CMP_EQ_OQ, _Tpvec, suffix) \ + OPENCV_HAL_IMPL_AVX_CMP_FLT(!=, _CMP_NEQ_OQ, _Tpvec, suffix) \ + OPENCV_HAL_IMPL_AVX_CMP_FLT(<, _CMP_LT_OQ, _Tpvec, suffix) \ + OPENCV_HAL_IMPL_AVX_CMP_FLT(>, _CMP_GT_OQ, _Tpvec, suffix) \ + OPENCV_HAL_IMPL_AVX_CMP_FLT(<=, _CMP_LE_OQ, _Tpvec, suffix) \ + OPENCV_HAL_IMPL_AVX_CMP_FLT(>=, _CMP_GE_OQ, _Tpvec, suffix) + +OPENCV_HAL_IMPL_AVX_CMP_OP_FLT(v_float32x8, ps) +OPENCV_HAL_IMPL_AVX_CMP_OP_FLT(v_float64x4, pd) + +inline v_float32x8 v_not_nan(const v_float32x8& a) +{ return v_float32x8(_mm256_cmp_ps(a.val, a.val, _CMP_ORD_Q)); } +inline v_float64x4 v_not_nan(const v_float64x4& a) +{ return v_float64x4(_mm256_cmp_pd(a.val, a.val, _CMP_ORD_Q)); } + +/** min/max **/ +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_uint8x32, _mm256_min_epu8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_uint8x32, _mm256_max_epu8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_int8x32, _mm256_min_epi8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_int8x32, _mm256_max_epi8) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_uint16x16, _mm256_min_epu16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_uint16x16, _mm256_max_epu16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_int16x16, _mm256_min_epi16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_int16x16, _mm256_max_epi16) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_uint32x8, _mm256_min_epu32) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_uint32x8, _mm256_max_epu32) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_int32x8, _mm256_min_epi32) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_int32x8, _mm256_max_epi32) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_float32x8, _mm256_min_ps) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_float32x8, _mm256_max_ps) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_min, v_float64x4, _mm256_min_pd) +OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_float64x4, _mm256_max_pd) + +/** Rotate **/ +template +inline v_uint8x32 v_rotate_left(const v_uint8x32& a, const v_uint8x32& b) +{ + enum {IMM_R = (16 - imm) & 0xFF}; + enum {IMM_R2 = (32 - imm) & 0xFF}; + + if (imm == 0) return a; + if (imm == 32) return b; + if (imm > 32) return v_uint8x32(); + + __m256i swap = _mm256_permute2x128_si256(a.val, b.val, 0x03); + if (imm == 16) return v_uint8x32(swap); + if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(a.val, swap, IMM_R)); + return v_uint8x32(_mm256_alignr_epi8(swap, b.val, IMM_R2)); // imm < 32 +} + +template +inline v_uint8x32 v_rotate_right(const v_uint8x32& a, const v_uint8x32& b) +{ + enum {IMM_L = (imm - 16) & 0xFF}; + + if (imm == 0) return a; + if (imm == 32) return b; + if (imm > 32) return v_uint8x32(); + + __m256i swap = _mm256_permute2x128_si256(a.val, b.val, 0x21); + if (imm == 16) return v_uint8x32(swap); + if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(swap, a.val, imm)); + return v_uint8x32(_mm256_alignr_epi8(b.val, swap, IMM_L)); +} + +template +inline v_uint8x32 v_rotate_left(const v_uint8x32& a) +{ + enum {IMM_L = (imm - 16) & 0xFF}; + enum {IMM_R = (16 - imm) & 0xFF}; + + if (imm == 0) return a; + if (imm > 32) return v_uint8x32(); + + // ESAC control[3] ? [127:0] = 0 + __m256i swapz = _mm256_permute2x128_si256(a.val, a.val, _MM_SHUFFLE(0, 0, 2, 0)); + if (imm == 16) return v_uint8x32(swapz); + if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(a.val, swapz, IMM_R)); + return v_uint8x32(_mm256_slli_si256(swapz, IMM_L)); +} + +template +inline v_uint8x32 v_rotate_right(const v_uint8x32& a) +{ + enum {IMM_L = (imm - 16) & 0xFF}; + + if (imm == 0) return a; + if (imm > 32) return v_uint8x32(); + + // ESAC control[3] ? [127:0] = 0 + __m256i swapz = _mm256_permute2x128_si256(a.val, a.val, _MM_SHUFFLE(2, 0, 0, 1)); + if (imm == 16) return v_uint8x32(swapz); + if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(swapz, a.val, imm)); + return v_uint8x32(_mm256_srli_si256(swapz, IMM_L)); +} + +#define OPENCV_HAL_IMPL_AVX_ROTATE_CAST(intrin, _Tpvec, cast) \ + template \ + inline _Tpvec intrin(const _Tpvec& a, const _Tpvec& b) \ + { \ + enum {IMMxW = imm * sizeof(typename _Tpvec::lane_type)}; \ + v_uint8x32 ret = intrin(v_reinterpret_as_u8(a), \ + v_reinterpret_as_u8(b)); \ + return _Tpvec(cast(ret.val)); \ + } \ + template \ + inline _Tpvec intrin(const _Tpvec& a) \ + { \ + enum {IMMxW = imm * sizeof(typename _Tpvec::lane_type)}; \ + v_uint8x32 ret = intrin(v_reinterpret_as_u8(a)); \ + return _Tpvec(cast(ret.val)); \ + } + +#define OPENCV_HAL_IMPL_AVX_ROTATE(_Tpvec) \ + OPENCV_HAL_IMPL_AVX_ROTATE_CAST(v_rotate_left, _Tpvec, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX_ROTATE_CAST(v_rotate_right, _Tpvec, OPENCV_HAL_NOP) + +OPENCV_HAL_IMPL_AVX_ROTATE(v_int8x32) +OPENCV_HAL_IMPL_AVX_ROTATE(v_uint16x16) +OPENCV_HAL_IMPL_AVX_ROTATE(v_int16x16) +OPENCV_HAL_IMPL_AVX_ROTATE(v_uint32x8) +OPENCV_HAL_IMPL_AVX_ROTATE(v_int32x8) +OPENCV_HAL_IMPL_AVX_ROTATE(v_uint64x4) +OPENCV_HAL_IMPL_AVX_ROTATE(v_int64x4) + +OPENCV_HAL_IMPL_AVX_ROTATE_CAST(v_rotate_left, v_float32x8, _mm256_castsi256_ps) +OPENCV_HAL_IMPL_AVX_ROTATE_CAST(v_rotate_right, v_float32x8, _mm256_castsi256_ps) +OPENCV_HAL_IMPL_AVX_ROTATE_CAST(v_rotate_left, v_float64x4, _mm256_castsi256_pd) +OPENCV_HAL_IMPL_AVX_ROTATE_CAST(v_rotate_right, v_float64x4, _mm256_castsi256_pd) + +////////// Reduce and mask ///////// + +/** Reduce **/ +inline unsigned v_reduce_sum(const v_uint8x32& a) +{ + __m256i half = _mm256_sad_epu8(a.val, _mm256_setzero_si256()); + __m128i quarter = _mm_add_epi32(_v256_extract_low(half), _v256_extract_high(half)); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(quarter, _mm_unpackhi_epi64(quarter, quarter))); +} +inline int v_reduce_sum(const v_int8x32& a) +{ + __m256i half = _mm256_sad_epu8(_mm256_xor_si256(a.val, _mm256_set1_epi8((schar)-128)), _mm256_setzero_si256()); + __m128i quarter = _mm_add_epi32(_v256_extract_low(half), _v256_extract_high(half)); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(quarter, _mm_unpackhi_epi64(quarter, quarter))) - 4096; +} +#define OPENCV_HAL_IMPL_AVX_REDUCE_32(_Tpvec, sctype, func, intrin) \ + inline sctype v_reduce_##func(const _Tpvec& a) \ + { \ + __m128i val = intrin(_v256_extract_low(a.val), _v256_extract_high(a.val)); \ + val = intrin(val, _mm_srli_si128(val,8)); \ + val = intrin(val, _mm_srli_si128(val,4)); \ + val = intrin(val, _mm_srli_si128(val,2)); \ + val = intrin(val, _mm_srli_si128(val,1)); \ + return (sctype)_mm_cvtsi128_si32(val); \ + } + +OPENCV_HAL_IMPL_AVX_REDUCE_32(v_uint8x32, uchar, min, _mm_min_epu8) +OPENCV_HAL_IMPL_AVX_REDUCE_32(v_int8x32, schar, min, _mm_min_epi8) +OPENCV_HAL_IMPL_AVX_REDUCE_32(v_uint8x32, uchar, max, _mm_max_epu8) +OPENCV_HAL_IMPL_AVX_REDUCE_32(v_int8x32, schar, max, _mm_max_epi8) + +#define OPENCV_HAL_IMPL_AVX_REDUCE_16(_Tpvec, sctype, func, intrin) \ + inline sctype v_reduce_##func(const _Tpvec& a) \ + { \ + __m128i v0 = _v256_extract_low(a.val); \ + __m128i v1 = _v256_extract_high(a.val); \ + v0 = intrin(v0, v1); \ + v0 = intrin(v0, _mm_srli_si128(v0, 8)); \ + v0 = intrin(v0, _mm_srli_si128(v0, 4)); \ + v0 = intrin(v0, _mm_srli_si128(v0, 2)); \ + return (sctype) _mm_cvtsi128_si32(v0); \ + } + +OPENCV_HAL_IMPL_AVX_REDUCE_16(v_uint16x16, ushort, min, _mm_min_epu16) +OPENCV_HAL_IMPL_AVX_REDUCE_16(v_int16x16, short, min, _mm_min_epi16) +OPENCV_HAL_IMPL_AVX_REDUCE_16(v_uint16x16, ushort, max, _mm_max_epu16) +OPENCV_HAL_IMPL_AVX_REDUCE_16(v_int16x16, short, max, _mm_max_epi16) + +#define OPENCV_HAL_IMPL_AVX_REDUCE_8(_Tpvec, sctype, func, intrin) \ + inline sctype v_reduce_##func(const _Tpvec& a) \ + { \ + __m128i v0 = _v256_extract_low(a.val); \ + __m128i v1 = _v256_extract_high(a.val); \ + v0 = intrin(v0, v1); \ + v0 = intrin(v0, _mm_srli_si128(v0, 8)); \ + v0 = intrin(v0, _mm_srli_si128(v0, 4)); \ + return (sctype) _mm_cvtsi128_si32(v0); \ + } + +OPENCV_HAL_IMPL_AVX_REDUCE_8(v_uint32x8, unsigned, min, _mm_min_epu32) +OPENCV_HAL_IMPL_AVX_REDUCE_8(v_int32x8, int, min, _mm_min_epi32) +OPENCV_HAL_IMPL_AVX_REDUCE_8(v_uint32x8, unsigned, max, _mm_max_epu32) +OPENCV_HAL_IMPL_AVX_REDUCE_8(v_int32x8, int, max, _mm_max_epi32) + +#define OPENCV_HAL_IMPL_AVX_REDUCE_FLT(func, intrin) \ + inline float v_reduce_##func(const v_float32x8& a) \ + { \ + __m128 v0 = _v256_extract_low(a.val); \ + __m128 v1 = _v256_extract_high(a.val); \ + v0 = intrin(v0, v1); \ + v0 = intrin(v0, _mm_permute_ps(v0, _MM_SHUFFLE(0, 0, 3, 2))); \ + v0 = intrin(v0, _mm_permute_ps(v0, _MM_SHUFFLE(0, 0, 0, 1))); \ + return _mm_cvtss_f32(v0); \ + } + +OPENCV_HAL_IMPL_AVX_REDUCE_FLT(min, _mm_min_ps) +OPENCV_HAL_IMPL_AVX_REDUCE_FLT(max, _mm_max_ps) + +inline int v_reduce_sum(const v_int32x8& a) +{ + __m256i s0 = _mm256_hadd_epi32(a.val, a.val); + s0 = _mm256_hadd_epi32(s0, s0); + + __m128i s1 = _v256_extract_high(s0); + s1 = _mm_add_epi32(_v256_extract_low(s0), s1); + + return _mm_cvtsi128_si32(s1); +} + +inline unsigned v_reduce_sum(const v_uint32x8& a) +{ return v_reduce_sum(v_reinterpret_as_s32(a)); } + +inline int v_reduce_sum(const v_int16x16& a) +{ return v_reduce_sum(v_expand_low(a) + v_expand_high(a)); } +inline unsigned v_reduce_sum(const v_uint16x16& a) +{ return v_reduce_sum(v_expand_low(a) + v_expand_high(a)); } + +inline float v_reduce_sum(const v_float32x8& a) +{ + __m256 s0 = _mm256_hadd_ps(a.val, a.val); + s0 = _mm256_hadd_ps(s0, s0); + + __m128 s1 = _v256_extract_high(s0); + s1 = _mm_add_ps(_v256_extract_low(s0), s1); + + return _mm_cvtss_f32(s1); +} + +inline uint64 v_reduce_sum(const v_uint64x4& a) +{ + uint64 CV_DECL_ALIGNED(32) idx[2]; + _mm_store_si128((__m128i*)idx, _mm_add_epi64(_v256_extract_low(a.val), _v256_extract_high(a.val))); + return idx[0] + idx[1]; +} +inline int64 v_reduce_sum(const v_int64x4& a) +{ + int64 CV_DECL_ALIGNED(32) idx[2]; + _mm_store_si128((__m128i*)idx, _mm_add_epi64(_v256_extract_low(a.val), _v256_extract_high(a.val))); + return idx[0] + idx[1]; +} +inline double v_reduce_sum(const v_float64x4& a) +{ + __m256d s0 = _mm256_hadd_pd(a.val, a.val); + return _mm_cvtsd_f64(_mm_add_pd(_v256_extract_low(s0), _v256_extract_high(s0))); +} + +inline v_float32x8 v_reduce_sum4(const v_float32x8& a, const v_float32x8& b, + const v_float32x8& c, const v_float32x8& d) +{ + __m256 ab = _mm256_hadd_ps(a.val, b.val); + __m256 cd = _mm256_hadd_ps(c.val, d.val); + return v_float32x8(_mm256_hadd_ps(ab, cd)); +} + +inline unsigned v_reduce_sad(const v_uint8x32& a, const v_uint8x32& b) +{ + __m256i half = _mm256_sad_epu8(a.val, b.val); + __m128i quarter = _mm_add_epi32(_v256_extract_low(half), _v256_extract_high(half)); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(quarter, _mm_unpackhi_epi64(quarter, quarter))); +} +inline unsigned v_reduce_sad(const v_int8x32& a, const v_int8x32& b) +{ + __m256i half = _mm256_set1_epi8(0x7f); + half = _mm256_sad_epu8(_mm256_add_epi8(a.val, half), _mm256_add_epi8(b.val, half)); + __m128i quarter = _mm_add_epi32(_v256_extract_low(half), _v256_extract_high(half)); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(quarter, _mm_unpackhi_epi64(quarter, quarter))); +} +inline unsigned v_reduce_sad(const v_uint16x16& a, const v_uint16x16& b) +{ + v_uint32x8 l, h; + v_expand(v_add_wrap(a - b, b - a), l, h); + return v_reduce_sum(l + h); +} +inline unsigned v_reduce_sad(const v_int16x16& a, const v_int16x16& b) +{ + v_uint32x8 l, h; + v_expand(v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b))), l, h); + return v_reduce_sum(l + h); +} +inline unsigned v_reduce_sad(const v_uint32x8& a, const v_uint32x8& b) +{ + return v_reduce_sum(v_max(a, b) - v_min(a, b)); +} +inline unsigned v_reduce_sad(const v_int32x8& a, const v_int32x8& b) +{ + v_int32x8 m = a < b; + return v_reduce_sum(v_reinterpret_as_u32(((a - b) ^ m) - m)); +} +inline float v_reduce_sad(const v_float32x8& a, const v_float32x8& b) +{ + return v_reduce_sum((a - b) & v_float32x8(_mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff)))); +} + +/** Popcount **/ +inline v_uint8x32 v_popcount(const v_uint8x32& a) +{ + __m256i _popcnt_table = _mm256_setr_epi8(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4); + __m256i _popcnt_mask = _mm256_set1_epi8(0x0F); + return v_uint8x32(_mm256_add_epi8(_mm256_shuffle_epi8(_popcnt_table, _mm256_and_si256( a.val , _popcnt_mask)), + _mm256_shuffle_epi8(_popcnt_table, _mm256_and_si256(_mm256_srli_epi16(a.val, 4), _popcnt_mask)))); +} +inline v_uint16x16 v_popcount(const v_uint16x16& a) +{ + v_uint8x32 p = v_popcount(v_reinterpret_as_u8(a)); + p += v_rotate_right<1>(p); + return v_reinterpret_as_u16(p) & v256_setall_u16(0x00ff); +} +inline v_uint32x8 v_popcount(const v_uint32x8& a) +{ + v_uint8x32 p = v_popcount(v_reinterpret_as_u8(a)); + p += v_rotate_right<1>(p); + p += v_rotate_right<2>(p); + return v_reinterpret_as_u32(p) & v256_setall_u32(0x000000ff); +} +inline v_uint64x4 v_popcount(const v_uint64x4& a) +{ + return v_uint64x4(_mm256_sad_epu8(v_popcount(v_reinterpret_as_u8(a)).val, _mm256_setzero_si256())); +} +inline v_uint8x32 v_popcount(const v_int8x32& a) +{ return v_popcount(v_reinterpret_as_u8(a)); } +inline v_uint16x16 v_popcount(const v_int16x16& a) +{ return v_popcount(v_reinterpret_as_u16(a)); } +inline v_uint32x8 v_popcount(const v_int32x8& a) +{ return v_popcount(v_reinterpret_as_u32(a)); } +inline v_uint64x4 v_popcount(const v_int64x4& a) +{ return v_popcount(v_reinterpret_as_u64(a)); } + +/** Mask **/ +inline int v_signmask(const v_int8x32& a) +{ return _mm256_movemask_epi8(a.val); } +inline int v_signmask(const v_uint8x32& a) +{ return v_signmask(v_reinterpret_as_s8(a)); } + +inline int v_signmask(const v_int16x16& a) +{ return v_signmask(v_pack(a, a)) & 0xFFFF; } +inline int v_signmask(const v_uint16x16& a) +{ return v_signmask(v_reinterpret_as_s16(a)); } + +inline int v_signmask(const v_int32x8& a) +{ + v_int16x16 a16 = v_pack(a, a); + return v_signmask(v_pack(a16, a16)) & 0xFF; +} +inline int v_signmask(const v_uint32x8& a) +{ return v_signmask(v_reinterpret_as_s32(a)); } + +inline int v_signmask(const v_float32x8& a) +{ return _mm256_movemask_ps(a.val); } +inline int v_signmask(const v_float64x4& a) +{ return _mm256_movemask_pd(a.val); } + +inline int v_scan_forward(const v_int8x32& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))); } +inline int v_scan_forward(const v_uint8x32& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))); } +inline int v_scan_forward(const v_int16x16& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 2; } +inline int v_scan_forward(const v_uint16x16& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 2; } +inline int v_scan_forward(const v_int32x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 4; } +inline int v_scan_forward(const v_uint32x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 4; } +inline int v_scan_forward(const v_float32x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 4; } +inline int v_scan_forward(const v_int64x4& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 8; } +inline int v_scan_forward(const v_uint64x4& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 8; } +inline int v_scan_forward(const v_float64x4& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 8; } + +/** Checks **/ +#define OPENCV_HAL_IMPL_AVX_CHECK(_Tpvec, and_op, allmask) \ + inline bool v_check_all(const _Tpvec& a) \ + { \ + int mask = v_signmask(v_reinterpret_as_s8(a)); \ + return and_op(mask, allmask) == allmask; \ + } \ + inline bool v_check_any(const _Tpvec& a) \ + { \ + int mask = v_signmask(v_reinterpret_as_s8(a)); \ + return and_op(mask, allmask) != 0; \ + } + +OPENCV_HAL_IMPL_AVX_CHECK(v_uint8x32, OPENCV_HAL_1ST, -1) +OPENCV_HAL_IMPL_AVX_CHECK(v_int8x32, OPENCV_HAL_1ST, -1) +OPENCV_HAL_IMPL_AVX_CHECK(v_uint16x16, OPENCV_HAL_AND, (int)0xaaaa) +OPENCV_HAL_IMPL_AVX_CHECK(v_int16x16, OPENCV_HAL_AND, (int)0xaaaa) +OPENCV_HAL_IMPL_AVX_CHECK(v_uint32x8, OPENCV_HAL_AND, (int)0x8888) +OPENCV_HAL_IMPL_AVX_CHECK(v_int32x8, OPENCV_HAL_AND, (int)0x8888) + +#define OPENCV_HAL_IMPL_AVX_CHECK_FLT(_Tpvec, allmask) \ + inline bool v_check_all(const _Tpvec& a) \ + { \ + int mask = v_signmask(a); \ + return mask == allmask; \ + } \ + inline bool v_check_any(const _Tpvec& a) \ + { \ + int mask = v_signmask(a); \ + return mask != 0; \ + } + +OPENCV_HAL_IMPL_AVX_CHECK_FLT(v_float32x8, 255) +OPENCV_HAL_IMPL_AVX_CHECK_FLT(v_float64x4, 15) + + +////////// Other math ///////// + +/** Some frequent operations **/ +#define OPENCV_HAL_IMPL_AVX_MULADD(_Tpvec, suffix) \ + inline _Tpvec v_fma(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm256_fmadd_##suffix(a.val, b.val, c.val)); } \ + inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm256_fmadd_##suffix(a.val, b.val, c.val)); } \ + inline _Tpvec v_sqrt(const _Tpvec& x) \ + { return _Tpvec(_mm256_sqrt_##suffix(x.val)); } \ + inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ + { return v_fma(a, a, b * b); } \ + inline _Tpvec v_magnitude(const _Tpvec& a, const _Tpvec& b) \ + { return v_sqrt(v_fma(a, a, b*b)); } + +OPENCV_HAL_IMPL_AVX_MULADD(v_float32x8, ps) +OPENCV_HAL_IMPL_AVX_MULADD(v_float64x4, pd) + +inline v_int32x8 v_fma(const v_int32x8& a, const v_int32x8& b, const v_int32x8& c) +{ + return a * b + c; +} + +inline v_int32x8 v_muladd(const v_int32x8& a, const v_int32x8& b, const v_int32x8& c) +{ + return v_fma(a, b, c); +} + +inline v_float32x8 v_invsqrt(const v_float32x8& x) +{ + v_float32x8 half = x * v256_setall_f32(0.5); + v_float32x8 t = v_float32x8(_mm256_rsqrt_ps(x.val)); + // todo: _mm256_fnmsub_ps + t *= v256_setall_f32(1.5) - ((t * t) * half); + return t; +} + +inline v_float64x4 v_invsqrt(const v_float64x4& x) +{ + return v256_setall_f64(1.) / v_sqrt(x); +} + +/** Absolute values **/ +#define OPENCV_HAL_IMPL_AVX_ABS(_Tpvec, suffix) \ + inline v_u##_Tpvec v_abs(const v_##_Tpvec& x) \ + { return v_u##_Tpvec(_mm256_abs_##suffix(x.val)); } + +OPENCV_HAL_IMPL_AVX_ABS(int8x32, epi8) +OPENCV_HAL_IMPL_AVX_ABS(int16x16, epi16) +OPENCV_HAL_IMPL_AVX_ABS(int32x8, epi32) + +inline v_float32x8 v_abs(const v_float32x8& x) +{ return x & v_float32x8(_mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff))); } +inline v_float64x4 v_abs(const v_float64x4& x) +{ return x & v_float64x4(_mm256_castsi256_pd(_mm256_srli_epi64(_mm256_set1_epi64x(-1), 1))); } + +/** Absolute difference **/ +inline v_uint8x32 v_absdiff(const v_uint8x32& a, const v_uint8x32& b) +{ return v_add_wrap(a - b, b - a); } +inline v_uint16x16 v_absdiff(const v_uint16x16& a, const v_uint16x16& b) +{ return v_add_wrap(a - b, b - a); } +inline v_uint32x8 v_absdiff(const v_uint32x8& a, const v_uint32x8& b) +{ return v_max(a, b) - v_min(a, b); } + +inline v_uint8x32 v_absdiff(const v_int8x32& a, const v_int8x32& b) +{ + v_int8x32 d = v_sub_wrap(a, b); + v_int8x32 m = a < b; + return v_reinterpret_as_u8(v_sub_wrap(d ^ m, m)); +} + +inline v_uint16x16 v_absdiff(const v_int16x16& a, const v_int16x16& b) +{ return v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b))); } + +inline v_uint32x8 v_absdiff(const v_int32x8& a, const v_int32x8& b) +{ + v_int32x8 d = a - b; + v_int32x8 m = a < b; + return v_reinterpret_as_u32((d ^ m) - m); +} + +inline v_float32x8 v_absdiff(const v_float32x8& a, const v_float32x8& b) +{ return v_abs(a - b); } + +inline v_float64x4 v_absdiff(const v_float64x4& a, const v_float64x4& b) +{ return v_abs(a - b); } + +/** Saturating absolute difference **/ +inline v_int8x32 v_absdiffs(const v_int8x32& a, const v_int8x32& b) +{ + v_int8x32 d = a - b; + v_int8x32 m = a < b; + return (d ^ m) - m; +} +inline v_int16x16 v_absdiffs(const v_int16x16& a, const v_int16x16& b) +{ return v_max(a, b) - v_min(a, b); } + +////////// Conversions ///////// + +/** Rounding **/ +inline v_int32x8 v_round(const v_float32x8& a) +{ return v_int32x8(_mm256_cvtps_epi32(a.val)); } + +inline v_int32x8 v_round(const v_float64x4& a) +{ return v_int32x8(_mm256_castsi128_si256(_mm256_cvtpd_epi32(a.val))); } + +inline v_int32x8 v_round(const v_float64x4& a, const v_float64x4& b) +{ + __m128i ai = _mm256_cvtpd_epi32(a.val), bi = _mm256_cvtpd_epi32(b.val); + return v_int32x8(_v256_combine(ai, bi)); +} + +inline v_int32x8 v_trunc(const v_float32x8& a) +{ return v_int32x8(_mm256_cvttps_epi32(a.val)); } + +inline v_int32x8 v_trunc(const v_float64x4& a) +{ return v_int32x8(_mm256_castsi128_si256(_mm256_cvttpd_epi32(a.val))); } + +inline v_int32x8 v_floor(const v_float32x8& a) +{ return v_int32x8(_mm256_cvttps_epi32(_mm256_floor_ps(a.val))); } + +inline v_int32x8 v_floor(const v_float64x4& a) +{ return v_trunc(v_float64x4(_mm256_floor_pd(a.val))); } + +inline v_int32x8 v_ceil(const v_float32x8& a) +{ return v_int32x8(_mm256_cvttps_epi32(_mm256_ceil_ps(a.val))); } + +inline v_int32x8 v_ceil(const v_float64x4& a) +{ return v_trunc(v_float64x4(_mm256_ceil_pd(a.val))); } + +/** To float **/ +inline v_float32x8 v_cvt_f32(const v_int32x8& a) +{ return v_float32x8(_mm256_cvtepi32_ps(a.val)); } + +inline v_float32x8 v_cvt_f32(const v_float64x4& a) +{ return v_float32x8(_mm256_castps128_ps256(_mm256_cvtpd_ps(a.val))); } + +inline v_float32x8 v_cvt_f32(const v_float64x4& a, const v_float64x4& b) +{ + __m128 af = _mm256_cvtpd_ps(a.val), bf = _mm256_cvtpd_ps(b.val); + return v_float32x8(_v256_combine(af, bf)); +} + +inline v_float64x4 v_cvt_f64(const v_int32x8& a) +{ return v_float64x4(_mm256_cvtepi32_pd(_v256_extract_low(a.val))); } + +inline v_float64x4 v_cvt_f64_high(const v_int32x8& a) +{ return v_float64x4(_mm256_cvtepi32_pd(_v256_extract_high(a.val))); } + +inline v_float64x4 v_cvt_f64(const v_float32x8& a) +{ return v_float64x4(_mm256_cvtps_pd(_v256_extract_low(a.val))); } + +inline v_float64x4 v_cvt_f64_high(const v_float32x8& a) +{ return v_float64x4(_mm256_cvtps_pd(_v256_extract_high(a.val))); } + +////////////// Lookup table access //////////////////// + +inline v_int8x32 v256_lut(const schar* tab, const int* idx) +{ + return v_int8x32(_mm256_setr_epi8(tab[idx[ 0]], tab[idx[ 1]], tab[idx[ 2]], tab[idx[ 3]], tab[idx[ 4]], tab[idx[ 5]], tab[idx[ 6]], tab[idx[ 7]], + tab[idx[ 8]], tab[idx[ 9]], tab[idx[10]], tab[idx[11]], tab[idx[12]], tab[idx[13]], tab[idx[14]], tab[idx[15]], + tab[idx[16]], tab[idx[17]], tab[idx[18]], tab[idx[19]], tab[idx[20]], tab[idx[21]], tab[idx[22]], tab[idx[23]], + tab[idx[24]], tab[idx[25]], tab[idx[26]], tab[idx[27]], tab[idx[28]], tab[idx[29]], tab[idx[30]], tab[idx[31]])); +} +inline v_int8x32 v256_lut_pairs(const schar* tab, const int* idx) +{ + return v_int8x32(_mm256_setr_epi16(*(const short*)(tab + idx[ 0]), *(const short*)(tab + idx[ 1]), *(const short*)(tab + idx[ 2]), *(const short*)(tab + idx[ 3]), + *(const short*)(tab + idx[ 4]), *(const short*)(tab + idx[ 5]), *(const short*)(tab + idx[ 6]), *(const short*)(tab + idx[ 7]), + *(const short*)(tab + idx[ 8]), *(const short*)(tab + idx[ 9]), *(const short*)(tab + idx[10]), *(const short*)(tab + idx[11]), + *(const short*)(tab + idx[12]), *(const short*)(tab + idx[13]), *(const short*)(tab + idx[14]), *(const short*)(tab + idx[15]))); +} +inline v_int8x32 v256_lut_quads(const schar* tab, const int* idx) +{ + return v_int8x32(_mm256_i32gather_epi32((const int*)tab, _mm256_loadu_si256((const __m256i*)idx), 1)); +} +inline v_uint8x32 v256_lut(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v256_lut((const schar *)tab, idx)); } +inline v_uint8x32 v256_lut_pairs(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v256_lut_pairs((const schar *)tab, idx)); } +inline v_uint8x32 v256_lut_quads(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v256_lut_quads((const schar *)tab, idx)); } + +inline v_int16x16 v256_lut(const short* tab, const int* idx) +{ + return v_int16x16(_mm256_setr_epi16(tab[idx[0]], tab[idx[1]], tab[idx[ 2]], tab[idx[ 3]], tab[idx[ 4]], tab[idx[ 5]], tab[idx[ 6]], tab[idx[ 7]], + tab[idx[8]], tab[idx[9]], tab[idx[10]], tab[idx[11]], tab[idx[12]], tab[idx[13]], tab[idx[14]], tab[idx[15]])); +} +inline v_int16x16 v256_lut_pairs(const short* tab, const int* idx) +{ + return v_int16x16(_mm256_i32gather_epi32((const int*)tab, _mm256_loadu_si256((const __m256i*)idx), 2)); +} +inline v_int16x16 v256_lut_quads(const short* tab, const int* idx) +{ +#if defined(__GNUC__) + return v_int16x16(_mm256_i32gather_epi64((const long long int*)tab, _mm_loadu_si128((const __m128i*)idx), 2));//Looks like intrinsic has wrong definition +#else + return v_int16x16(_mm256_i32gather_epi64((const int64*)tab, _mm_loadu_si128((const __m128i*)idx), 2)); +#endif +} +inline v_uint16x16 v256_lut(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v256_lut((const short *)tab, idx)); } +inline v_uint16x16 v256_lut_pairs(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v256_lut_pairs((const short *)tab, idx)); } +inline v_uint16x16 v256_lut_quads(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v256_lut_quads((const short *)tab, idx)); } + +inline v_int32x8 v256_lut(const int* tab, const int* idx) +{ + return v_int32x8(_mm256_i32gather_epi32(tab, _mm256_loadu_si256((const __m256i*)idx), 4)); +} +inline v_int32x8 v256_lut_pairs(const int* tab, const int* idx) +{ +#if defined(__GNUC__) + return v_int32x8(_mm256_i32gather_epi64((const long long int*)tab, _mm_loadu_si128((const __m128i*)idx), 4)); +#else + return v_int32x8(_mm256_i32gather_epi64((const int64*)tab, _mm_loadu_si128((const __m128i*)idx), 4)); +#endif +} +inline v_int32x8 v256_lut_quads(const int* tab, const int* idx) +{ + return v_int32x8(_v256_combine(_mm_loadu_si128((const __m128i*)(tab + idx[0])), _mm_loadu_si128((const __m128i*)(tab + idx[1])))); +} +inline v_uint32x8 v256_lut(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v256_lut((const int *)tab, idx)); } +inline v_uint32x8 v256_lut_pairs(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v256_lut_pairs((const int *)tab, idx)); } +inline v_uint32x8 v256_lut_quads(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v256_lut_quads((const int *)tab, idx)); } + +inline v_int64x4 v256_lut(const int64* tab, const int* idx) +{ +#if defined(__GNUC__) + return v_int64x4(_mm256_i32gather_epi64((const long long int*)tab, _mm_loadu_si128((const __m128i*)idx), 8)); +#else + return v_int64x4(_mm256_i32gather_epi64(tab, _mm_loadu_si128((const __m128i*)idx), 8)); +#endif +} +inline v_int64x4 v256_lut_pairs(const int64* tab, const int* idx) +{ + return v_int64x4(_v256_combine(_mm_loadu_si128((const __m128i*)(tab + idx[0])), _mm_loadu_si128((const __m128i*)(tab + idx[1])))); +} +inline v_uint64x4 v256_lut(const uint64* tab, const int* idx) { return v_reinterpret_as_u64(v256_lut((const int64 *)tab, idx)); } +inline v_uint64x4 v256_lut_pairs(const uint64* tab, const int* idx) { return v_reinterpret_as_u64(v256_lut_pairs((const int64 *)tab, idx)); } + +inline v_float32x8 v256_lut(const float* tab, const int* idx) +{ + return v_float32x8(_mm256_i32gather_ps(tab, _mm256_loadu_si256((const __m256i*)idx), 4)); +} +inline v_float32x8 v256_lut_pairs(const float* tab, const int* idx) { return v_reinterpret_as_f32(v256_lut_pairs((const int *)tab, idx)); } +inline v_float32x8 v256_lut_quads(const float* tab, const int* idx) { return v_reinterpret_as_f32(v256_lut_quads((const int *)tab, idx)); } + +inline v_float64x4 v256_lut(const double* tab, const int* idx) +{ + return v_float64x4(_mm256_i32gather_pd(tab, _mm_loadu_si128((const __m128i*)idx), 8)); +} +inline v_float64x4 v256_lut_pairs(const double* tab, const int* idx) { return v_float64x4(_v256_combine(_mm_loadu_pd(tab + idx[0]), _mm_loadu_pd(tab + idx[1]))); } + +inline v_int32x8 v_lut(const int* tab, const v_int32x8& idxvec) +{ + return v_int32x8(_mm256_i32gather_epi32(tab, idxvec.val, 4)); +} + +inline v_uint32x8 v_lut(const unsigned* tab, const v_int32x8& idxvec) +{ + return v_reinterpret_as_u32(v_lut((const int *)tab, idxvec)); +} + +inline v_float32x8 v_lut(const float* tab, const v_int32x8& idxvec) +{ + return v_float32x8(_mm256_i32gather_ps(tab, idxvec.val, 4)); +} + +inline v_float64x4 v_lut(const double* tab, const v_int32x8& idxvec) +{ + return v_float64x4(_mm256_i32gather_pd(tab, _mm256_castsi256_si128(idxvec.val), 8)); +} + +inline void v_lut_deinterleave(const float* tab, const v_int32x8& idxvec, v_float32x8& x, v_float32x8& y) +{ + int CV_DECL_ALIGNED(32) idx[8]; + v_store_aligned(idx, idxvec); + __m128 z = _mm_setzero_ps(); + __m128 xy01, xy45, xy23, xy67; + xy01 = _mm_loadl_pi(z, (const __m64*)(tab + idx[0])); + xy01 = _mm_loadh_pi(xy01, (const __m64*)(tab + idx[1])); + xy45 = _mm_loadl_pi(z, (const __m64*)(tab + idx[4])); + xy45 = _mm_loadh_pi(xy45, (const __m64*)(tab + idx[5])); + __m256 xy0145 = _v256_combine(xy01, xy45); + xy23 = _mm_loadl_pi(z, (const __m64*)(tab + idx[2])); + xy23 = _mm_loadh_pi(xy23, (const __m64*)(tab + idx[3])); + xy67 = _mm_loadl_pi(z, (const __m64*)(tab + idx[6])); + xy67 = _mm_loadh_pi(xy67, (const __m64*)(tab + idx[7])); + __m256 xy2367 = _v256_combine(xy23, xy67); + + __m256 xxyy0145 = _mm256_unpacklo_ps(xy0145, xy2367); + __m256 xxyy2367 = _mm256_unpackhi_ps(xy0145, xy2367); + + x = v_float32x8(_mm256_unpacklo_ps(xxyy0145, xxyy2367)); + y = v_float32x8(_mm256_unpackhi_ps(xxyy0145, xxyy2367)); +} + +inline void v_lut_deinterleave(const double* tab, const v_int32x8& idxvec, v_float64x4& x, v_float64x4& y) +{ + int CV_DECL_ALIGNED(32) idx[4]; + v_store_low(idx, idxvec); + __m128d xy0 = _mm_loadu_pd(tab + idx[0]); + __m128d xy2 = _mm_loadu_pd(tab + idx[2]); + __m128d xy1 = _mm_loadu_pd(tab + idx[1]); + __m128d xy3 = _mm_loadu_pd(tab + idx[3]); + __m256d xy02 = _v256_combine(xy0, xy2); + __m256d xy13 = _v256_combine(xy1, xy3); + + x = v_float64x4(_mm256_unpacklo_pd(xy02, xy13)); + y = v_float64x4(_mm256_unpackhi_pd(xy02, xy13)); +} + +inline v_int8x32 v_interleave_pairs(const v_int8x32& vec) +{ + return v_int8x32(_mm256_shuffle_epi8(vec.val, _mm256_set_epi64x(0x0f0d0e0c0b090a08, 0x0705060403010200, 0x0f0d0e0c0b090a08, 0x0705060403010200))); +} +inline v_uint8x32 v_interleave_pairs(const v_uint8x32& vec) { return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); } +inline v_int8x32 v_interleave_quads(const v_int8x32& vec) +{ + return v_int8x32(_mm256_shuffle_epi8(vec.val, _mm256_set_epi64x(0x0f0b0e0a0d090c08, 0x0703060205010400, 0x0f0b0e0a0d090c08, 0x0703060205010400))); +} +inline v_uint8x32 v_interleave_quads(const v_uint8x32& vec) { return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); } + +inline v_int16x16 v_interleave_pairs(const v_int16x16& vec) +{ + return v_int16x16(_mm256_shuffle_epi8(vec.val, _mm256_set_epi64x(0x0f0e0b0a0d0c0908, 0x0706030205040100, 0x0f0e0b0a0d0c0908, 0x0706030205040100))); +} +inline v_uint16x16 v_interleave_pairs(const v_uint16x16& vec) { return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); } +inline v_int16x16 v_interleave_quads(const v_int16x16& vec) +{ + return v_int16x16(_mm256_shuffle_epi8(vec.val, _mm256_set_epi64x(0x0f0e07060d0c0504, 0x0b0a030209080100, 0x0f0e07060d0c0504, 0x0b0a030209080100))); +} +inline v_uint16x16 v_interleave_quads(const v_uint16x16& vec) { return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); } + +inline v_int32x8 v_interleave_pairs(const v_int32x8& vec) +{ + return v_int32x8(_mm256_shuffle_epi32(vec.val, _MM_SHUFFLE(3, 1, 2, 0))); +} +inline v_uint32x8 v_interleave_pairs(const v_uint32x8& vec) { return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } +inline v_float32x8 v_interleave_pairs(const v_float32x8& vec) { return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } + +inline v_int8x32 v_pack_triplets(const v_int8x32& vec) +{ + return v_int8x32(_mm256_permutevar8x32_epi32(_mm256_shuffle_epi8(vec.val, _mm256_broadcastsi128_si256(_mm_set_epi64x(0xffffff0f0e0d0c0a, 0x0908060504020100))), + _mm256_set_epi64x(0x0000000700000007, 0x0000000600000005, 0x0000000400000002, 0x0000000100000000))); +} +inline v_uint8x32 v_pack_triplets(const v_uint8x32& vec) { return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); } + +inline v_int16x16 v_pack_triplets(const v_int16x16& vec) +{ + return v_int16x16(_mm256_permutevar8x32_epi32(_mm256_shuffle_epi8(vec.val, _mm256_broadcastsi128_si256(_mm_set_epi64x(0xffff0f0e0d0c0b0a, 0x0908050403020100))), + _mm256_set_epi64x(0x0000000700000007, 0x0000000600000005, 0x0000000400000002, 0x0000000100000000))); +} +inline v_uint16x16 v_pack_triplets(const v_uint16x16& vec) { return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); } + +inline v_int32x8 v_pack_triplets(const v_int32x8& vec) +{ + return v_int32x8(_mm256_permutevar8x32_epi32(vec.val, _mm256_set_epi64x(0x0000000700000007, 0x0000000600000005, 0x0000000400000002, 0x0000000100000000))); +} +inline v_uint32x8 v_pack_triplets(const v_uint32x8& vec) { return v_reinterpret_as_u32(v_pack_triplets(v_reinterpret_as_s32(vec))); } +inline v_float32x8 v_pack_triplets(const v_float32x8& vec) +{ + return v_float32x8(_mm256_permutevar8x32_ps(vec.val, _mm256_set_epi64x(0x0000000700000007, 0x0000000600000005, 0x0000000400000002, 0x0000000100000000))); +} + +////////// Matrix operations ///////// + +inline v_int32x8 v_dotprod(const v_int16x16& a, const v_int16x16& b) +{ return v_int32x8(_mm256_madd_epi16(a.val, b.val)); } + +inline v_int32x8 v_dotprod(const v_int16x16& a, const v_int16x16& b, const v_int32x8& c) +{ return v_dotprod(a, b) + c; } + +#define OPENCV_HAL_AVX_SPLAT2_PS(a, im) \ + v_float32x8(_mm256_permute_ps(a.val, _MM_SHUFFLE(im, im, im, im))) + +inline v_float32x8 v_matmul(const v_float32x8& v, const v_float32x8& m0, + const v_float32x8& m1, const v_float32x8& m2, + const v_float32x8& m3) +{ + v_float32x8 v04 = OPENCV_HAL_AVX_SPLAT2_PS(v, 0); + v_float32x8 v15 = OPENCV_HAL_AVX_SPLAT2_PS(v, 1); + v_float32x8 v26 = OPENCV_HAL_AVX_SPLAT2_PS(v, 2); + v_float32x8 v37 = OPENCV_HAL_AVX_SPLAT2_PS(v, 3); + return v_fma(v04, m0, v_fma(v15, m1, v_fma(v26, m2, v37 * m3))); +} + +inline v_float32x8 v_matmuladd(const v_float32x8& v, const v_float32x8& m0, + const v_float32x8& m1, const v_float32x8& m2, + const v_float32x8& a) +{ + v_float32x8 v04 = OPENCV_HAL_AVX_SPLAT2_PS(v, 0); + v_float32x8 v15 = OPENCV_HAL_AVX_SPLAT2_PS(v, 1); + v_float32x8 v26 = OPENCV_HAL_AVX_SPLAT2_PS(v, 2); + return v_fma(v04, m0, v_fma(v15, m1, v_fma(v26, m2, a))); +} + +#define OPENCV_HAL_IMPL_AVX_TRANSPOSE4x4(_Tpvec, suffix, cast_from, cast_to) \ + inline void v_transpose4x4(const _Tpvec& a0, const _Tpvec& a1, \ + const _Tpvec& a2, const _Tpvec& a3, \ + _Tpvec& b0, _Tpvec& b1, _Tpvec& b2, _Tpvec& b3) \ + { \ + __m256i t0 = cast_from(_mm256_unpacklo_##suffix(a0.val, a1.val)); \ + __m256i t1 = cast_from(_mm256_unpacklo_##suffix(a2.val, a3.val)); \ + __m256i t2 = cast_from(_mm256_unpackhi_##suffix(a0.val, a1.val)); \ + __m256i t3 = cast_from(_mm256_unpackhi_##suffix(a2.val, a3.val)); \ + b0.val = cast_to(_mm256_unpacklo_epi64(t0, t1)); \ + b1.val = cast_to(_mm256_unpackhi_epi64(t0, t1)); \ + b2.val = cast_to(_mm256_unpacklo_epi64(t2, t3)); \ + b3.val = cast_to(_mm256_unpackhi_epi64(t2, t3)); \ + } + +OPENCV_HAL_IMPL_AVX_TRANSPOSE4x4(v_uint32x8, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_AVX_TRANSPOSE4x4(v_int32x8, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_AVX_TRANSPOSE4x4(v_float32x8, ps, _mm256_castps_si256, _mm256_castsi256_ps) + +//////////////// Value reordering /////////////// + +/* Expand */ +#define OPENCV_HAL_IMPL_AVX_EXPAND(_Tpvec, _Tpwvec, _Tp, intrin) \ + inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \ + { \ + b0.val = intrin(_v256_extract_low(a.val)); \ + b1.val = intrin(_v256_extract_high(a.val)); \ + } \ + inline _Tpwvec v_expand_low(const _Tpvec& a) \ + { return _Tpwvec(intrin(_v256_extract_low(a.val))); } \ + inline _Tpwvec v_expand_high(const _Tpvec& a) \ + { return _Tpwvec(intrin(_v256_extract_high(a.val))); } \ + inline _Tpwvec v256_load_expand(const _Tp* ptr) \ + { \ + __m128i a = _mm_loadu_si128((const __m128i*)ptr); \ + return _Tpwvec(intrin(a)); \ + } + +OPENCV_HAL_IMPL_AVX_EXPAND(v_uint8x32, v_uint16x16, uchar, _mm256_cvtepu8_epi16) +OPENCV_HAL_IMPL_AVX_EXPAND(v_int8x32, v_int16x16, schar, _mm256_cvtepi8_epi16) +OPENCV_HAL_IMPL_AVX_EXPAND(v_uint16x16, v_uint32x8, ushort, _mm256_cvtepu16_epi32) +OPENCV_HAL_IMPL_AVX_EXPAND(v_int16x16, v_int32x8, short, _mm256_cvtepi16_epi32) +OPENCV_HAL_IMPL_AVX_EXPAND(v_uint32x8, v_uint64x4, unsigned, _mm256_cvtepu32_epi64) +OPENCV_HAL_IMPL_AVX_EXPAND(v_int32x8, v_int64x4, int, _mm256_cvtepi32_epi64) + +#define OPENCV_HAL_IMPL_AVX_EXPAND_Q(_Tpvec, _Tp, intrin) \ + inline _Tpvec v256_load_expand_q(const _Tp* ptr) \ + { \ + __m128i a = _mm_loadl_epi64((const __m128i*)ptr); \ + return _Tpvec(intrin(a)); \ + } + +OPENCV_HAL_IMPL_AVX_EXPAND_Q(v_uint32x8, uchar, _mm256_cvtepu8_epi32) +OPENCV_HAL_IMPL_AVX_EXPAND_Q(v_int32x8, schar, _mm256_cvtepi8_epi32) + +/* pack */ +// 16 +inline v_int8x32 v_pack(const v_int16x16& a, const v_int16x16& b) +{ return v_int8x32(_v256_shuffle_odd_64(_mm256_packs_epi16(a.val, b.val))); } + +inline v_uint8x32 v_pack(const v_uint16x16& a, const v_uint16x16& b) +{ + __m256i t = _mm256_set1_epi16(255); + __m256i a1 = _mm256_min_epu16(a.val, t); + __m256i b1 = _mm256_min_epu16(b.val, t); + return v_uint8x32(_v256_shuffle_odd_64(_mm256_packus_epi16(a1, b1))); +} + +inline v_uint8x32 v_pack_u(const v_int16x16& a, const v_int16x16& b) +{ + return v_uint8x32(_v256_shuffle_odd_64(_mm256_packus_epi16(a.val, b.val))); +} + +inline void v_pack_store(schar* ptr, const v_int16x16& a) +{ v_store_low(ptr, v_pack(a, a)); } + +inline void v_pack_store(uchar* ptr, const v_uint16x16& a) +{ + const __m256i m = _mm256_set1_epi16(255); + __m256i am = _mm256_min_epu16(a.val, m); + am = _v256_shuffle_odd_64(_mm256_packus_epi16(am, am)); + v_store_low(ptr, v_uint8x32(am)); +} + +inline void v_pack_u_store(uchar* ptr, const v_int16x16& a) +{ v_store_low(ptr, v_pack_u(a, a)); } + +template inline +v_uint8x32 v_rshr_pack(const v_uint16x16& a, const v_uint16x16& b) +{ + // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. + v_uint16x16 delta = v256_setall_u16((short)(1 << (n-1))); + return v_pack_u(v_reinterpret_as_s16((a + delta) >> n), + v_reinterpret_as_s16((b + delta) >> n)); +} + +template inline +void v_rshr_pack_store(uchar* ptr, const v_uint16x16& a) +{ + v_uint16x16 delta = v256_setall_u16((short)(1 << (n-1))); + v_pack_u_store(ptr, v_reinterpret_as_s16((a + delta) >> n)); +} + +template inline +v_uint8x32 v_rshr_pack_u(const v_int16x16& a, const v_int16x16& b) +{ + v_int16x16 delta = v256_setall_s16((short)(1 << (n-1))); + return v_pack_u((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_u_store(uchar* ptr, const v_int16x16& a) +{ + v_int16x16 delta = v256_setall_s16((short)(1 << (n-1))); + v_pack_u_store(ptr, (a + delta) >> n); +} + +template inline +v_int8x32 v_rshr_pack(const v_int16x16& a, const v_int16x16& b) +{ + v_int16x16 delta = v256_setall_s16((short)(1 << (n-1))); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(schar* ptr, const v_int16x16& a) +{ + v_int16x16 delta = v256_setall_s16((short)(1 << (n-1))); + v_pack_store(ptr, (a + delta) >> n); +} + +// 32 +inline v_int16x16 v_pack(const v_int32x8& a, const v_int32x8& b) +{ return v_int16x16(_v256_shuffle_odd_64(_mm256_packs_epi32(a.val, b.val))); } + +inline v_uint16x16 v_pack(const v_uint32x8& a, const v_uint32x8& b) +{ return v_uint16x16(_v256_shuffle_odd_64(_v256_packs_epu32(a.val, b.val))); } + +inline v_uint16x16 v_pack_u(const v_int32x8& a, const v_int32x8& b) +{ return v_uint16x16(_v256_shuffle_odd_64(_mm256_packus_epi32(a.val, b.val))); } + +inline void v_pack_store(short* ptr, const v_int32x8& a) +{ v_store_low(ptr, v_pack(a, a)); } + +inline void v_pack_store(ushort* ptr, const v_uint32x8& a) +{ + const __m256i m = _mm256_set1_epi32(65535); + __m256i am = _mm256_min_epu32(a.val, m); + am = _v256_shuffle_odd_64(_mm256_packus_epi32(am, am)); + v_store_low(ptr, v_uint16x16(am)); +} + +inline void v_pack_u_store(ushort* ptr, const v_int32x8& a) +{ v_store_low(ptr, v_pack_u(a, a)); } + + +template inline +v_uint16x16 v_rshr_pack(const v_uint32x8& a, const v_uint32x8& b) +{ + // we assume that n > 0, and so the shifted 32-bit values can be treated as signed numbers. + v_uint32x8 delta = v256_setall_u32(1 << (n-1)); + return v_pack_u(v_reinterpret_as_s32((a + delta) >> n), + v_reinterpret_as_s32((b + delta) >> n)); +} + +template inline +void v_rshr_pack_store(ushort* ptr, const v_uint32x8& a) +{ + v_uint32x8 delta = v256_setall_u32(1 << (n-1)); + v_pack_u_store(ptr, v_reinterpret_as_s32((a + delta) >> n)); +} + +template inline +v_uint16x16 v_rshr_pack_u(const v_int32x8& a, const v_int32x8& b) +{ + v_int32x8 delta = v256_setall_s32(1 << (n-1)); + return v_pack_u((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_u_store(ushort* ptr, const v_int32x8& a) +{ + v_int32x8 delta = v256_setall_s32(1 << (n-1)); + v_pack_u_store(ptr, (a + delta) >> n); +} + +template inline +v_int16x16 v_rshr_pack(const v_int32x8& a, const v_int32x8& b) +{ + v_int32x8 delta = v256_setall_s32(1 << (n-1)); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(short* ptr, const v_int32x8& a) +{ + v_int32x8 delta = v256_setall_s32(1 << (n-1)); + v_pack_store(ptr, (a + delta) >> n); +} + +// 64 +// Non-saturating pack +inline v_uint32x8 v_pack(const v_uint64x4& a, const v_uint64x4& b) +{ + __m256i a0 = _mm256_shuffle_epi32(a.val, _MM_SHUFFLE(0, 0, 2, 0)); + __m256i b0 = _mm256_shuffle_epi32(b.val, _MM_SHUFFLE(0, 0, 2, 0)); + __m256i ab = _mm256_unpacklo_epi64(a0, b0); // a0, a1, b0, b1, a2, a3, b2, b3 + return v_uint32x8(_v256_shuffle_odd_64(ab)); +} + +inline v_int32x8 v_pack(const v_int64x4& a, const v_int64x4& b) +{ return v_reinterpret_as_s32(v_pack(v_reinterpret_as_u64(a), v_reinterpret_as_u64(b))); } + +inline void v_pack_store(unsigned* ptr, const v_uint64x4& a) +{ + __m256i a0 = _mm256_shuffle_epi32(a.val, _MM_SHUFFLE(0, 0, 2, 0)); + v_store_low(ptr, v_uint32x8(_v256_shuffle_odd_64(a0))); +} + +inline void v_pack_store(int* ptr, const v_int64x4& b) +{ v_pack_store((unsigned*)ptr, v_reinterpret_as_u64(b)); } + +template inline +v_uint32x8 v_rshr_pack(const v_uint64x4& a, const v_uint64x4& b) +{ + v_uint64x4 delta = v256_setall_u64((uint64)1 << (n-1)); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(unsigned* ptr, const v_uint64x4& a) +{ + v_uint64x4 delta = v256_setall_u64((uint64)1 << (n-1)); + v_pack_store(ptr, (a + delta) >> n); +} + +template inline +v_int32x8 v_rshr_pack(const v_int64x4& a, const v_int64x4& b) +{ + v_int64x4 delta = v256_setall_s64((int64)1 << (n-1)); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(int* ptr, const v_int64x4& a) +{ + v_int64x4 delta = v256_setall_s64((int64)1 << (n-1)); + v_pack_store(ptr, (a + delta) >> n); +} + +// pack boolean +inline v_uint8x32 v_pack_b(const v_uint16x16& a, const v_uint16x16& b) +{ + __m256i ab = _mm256_packs_epi16(a.val, b.val); + return v_uint8x32(_v256_shuffle_odd_64(ab)); +} + +inline v_uint8x32 v_pack_b(const v_uint32x8& a, const v_uint32x8& b, + const v_uint32x8& c, const v_uint32x8& d) +{ + __m256i ab = _mm256_packs_epi32(a.val, b.val); + __m256i cd = _mm256_packs_epi32(c.val, d.val); + + __m256i abcd = _v256_shuffle_odd_64(_mm256_packs_epi16(ab, cd)); + return v_uint8x32(_mm256_shuffle_epi32(abcd, _MM_SHUFFLE(3, 1, 2, 0))); +} + +inline v_uint8x32 v_pack_b(const v_uint64x4& a, const v_uint64x4& b, const v_uint64x4& c, + const v_uint64x4& d, const v_uint64x4& e, const v_uint64x4& f, + const v_uint64x4& g, const v_uint64x4& h) +{ + __m256i ab = _mm256_packs_epi32(a.val, b.val); + __m256i cd = _mm256_packs_epi32(c.val, d.val); + __m256i ef = _mm256_packs_epi32(e.val, f.val); + __m256i gh = _mm256_packs_epi32(g.val, h.val); + + __m256i abcd = _mm256_packs_epi32(ab, cd); + __m256i efgh = _mm256_packs_epi32(ef, gh); + __m256i pkall = _v256_shuffle_odd_64(_mm256_packs_epi16(abcd, efgh)); + + __m256i rev = _mm256_alignr_epi8(pkall, pkall, 8); + return v_uint8x32(_mm256_unpacklo_epi16(pkall, rev)); +} + +/* Recombine */ +// its up there with load and store operations + +/* Extract */ +#define OPENCV_HAL_IMPL_AVX_EXTRACT(_Tpvec) \ + template \ + inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) \ + { return v_rotate_right(a, b); } + +OPENCV_HAL_IMPL_AVX_EXTRACT(v_uint8x32) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_int8x32) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_uint16x16) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_int16x16) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_uint32x8) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_int32x8) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_uint64x4) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_int64x4) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_float32x8) +OPENCV_HAL_IMPL_AVX_EXTRACT(v_float64x4) + + +///////////////////// load deinterleave ///////////////////////////// + +inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& a, v_uint8x32& b ) +{ + __m256i ab0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i ab1 = _mm256_loadu_si256((const __m256i*)(ptr + 32)); + + const __m256i sh = _mm256_setr_epi8(0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15, + 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15); + __m256i p0 = _mm256_shuffle_epi8(ab0, sh); + __m256i p1 = _mm256_shuffle_epi8(ab1, sh); + __m256i pl = _mm256_permute2x128_si256(p0, p1, 0 + 2*16); + __m256i ph = _mm256_permute2x128_si256(p0, p1, 1 + 3*16); + __m256i a0 = _mm256_unpacklo_epi64(pl, ph); + __m256i b0 = _mm256_unpackhi_epi64(pl, ph); + a = v_uint8x32(a0); + b = v_uint8x32(b0); +} + +inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& a, v_uint16x16& b ) +{ + __m256i ab0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i ab1 = _mm256_loadu_si256((const __m256i*)(ptr + 16)); + + const __m256i sh = _mm256_setr_epi8(0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15, + 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15); + __m256i p0 = _mm256_shuffle_epi8(ab0, sh); + __m256i p1 = _mm256_shuffle_epi8(ab1, sh); + __m256i pl = _mm256_permute2x128_si256(p0, p1, 0 + 2*16); + __m256i ph = _mm256_permute2x128_si256(p0, p1, 1 + 3*16); + __m256i a0 = _mm256_unpacklo_epi64(pl, ph); + __m256i b0 = _mm256_unpackhi_epi64(pl, ph); + a = v_uint16x16(a0); + b = v_uint16x16(b0); +} + +inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& a, v_uint32x8& b ) +{ + __m256i ab0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i ab1 = _mm256_loadu_si256((const __m256i*)(ptr + 8)); + + const int sh = 0+2*4+1*16+3*64; + __m256i p0 = _mm256_shuffle_epi32(ab0, sh); + __m256i p1 = _mm256_shuffle_epi32(ab1, sh); + __m256i pl = _mm256_permute2x128_si256(p0, p1, 0 + 2*16); + __m256i ph = _mm256_permute2x128_si256(p0, p1, 1 + 3*16); + __m256i a0 = _mm256_unpacklo_epi64(pl, ph); + __m256i b0 = _mm256_unpackhi_epi64(pl, ph); + a = v_uint32x8(a0); + b = v_uint32x8(b0); +} + +inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b ) +{ + __m256i ab0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i ab1 = _mm256_loadu_si256((const __m256i*)(ptr + 4)); + + __m256i pl = _mm256_permute2x128_si256(ab0, ab1, 0 + 2*16); + __m256i ph = _mm256_permute2x128_si256(ab0, ab1, 1 + 3*16); + __m256i a0 = _mm256_unpacklo_epi64(pl, ph); + __m256i b0 = _mm256_unpackhi_epi64(pl, ph); + a = v_uint64x4(a0); + b = v_uint64x4(b0); +} + +inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& a, v_uint8x32& b, v_uint8x32& c ) +{ + __m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 32)); + __m256i bgr2 = _mm256_loadu_si256((const __m256i*)(ptr + 64)); + + __m256i s02_low = _mm256_permute2x128_si256(bgr0, bgr2, 0 + 2*16); + __m256i s02_high = _mm256_permute2x128_si256(bgr0, bgr2, 1 + 3*16); + + const __m256i m0 = _mm256_setr_epi8(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, + 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0); + const __m256i m1 = _mm256_setr_epi8(0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, + -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1); + + __m256i b0 = _mm256_blendv_epi8(_mm256_blendv_epi8(s02_low, s02_high, m0), bgr1, m1); + __m256i g0 = _mm256_blendv_epi8(_mm256_blendv_epi8(s02_high, s02_low, m1), bgr1, m0); + __m256i r0 = _mm256_blendv_epi8(_mm256_blendv_epi8(bgr1, s02_low, m0), s02_high, m1); + + const __m256i + sh_b = _mm256_setr_epi8(0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13, + 0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13), + sh_g = _mm256_setr_epi8(1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, + 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14), + sh_r = _mm256_setr_epi8(2, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, + 2, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15); + b0 = _mm256_shuffle_epi8(b0, sh_b); + g0 = _mm256_shuffle_epi8(g0, sh_g); + r0 = _mm256_shuffle_epi8(r0, sh_r); + + a = v_uint8x32(b0); + b = v_uint8x32(g0); + c = v_uint8x32(r0); +} + +inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& a, v_uint16x16& b, v_uint16x16& c ) +{ + __m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 16)); + __m256i bgr2 = _mm256_loadu_si256((const __m256i*)(ptr + 32)); + + __m256i s02_low = _mm256_permute2x128_si256(bgr0, bgr2, 0 + 2*16); + __m256i s02_high = _mm256_permute2x128_si256(bgr0, bgr2, 1 + 3*16); + + const __m256i m0 = _mm256_setr_epi8(0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, + 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0); + const __m256i m1 = _mm256_setr_epi8(0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, + -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0); + __m256i b0 = _mm256_blendv_epi8(_mm256_blendv_epi8(s02_low, s02_high, m0), bgr1, m1); + __m256i g0 = _mm256_blendv_epi8(_mm256_blendv_epi8(bgr1, s02_low, m0), s02_high, m1); + __m256i r0 = _mm256_blendv_epi8(_mm256_blendv_epi8(s02_high, s02_low, m1), bgr1, m0); + const __m256i sh_b = _mm256_setr_epi8(0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, + 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11); + const __m256i sh_g = _mm256_setr_epi8(2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 0, 1, 6, 7, 12, 13, + 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 0, 1, 6, 7, 12, 13); + const __m256i sh_r = _mm256_setr_epi8(4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, + 4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15); + b0 = _mm256_shuffle_epi8(b0, sh_b); + g0 = _mm256_shuffle_epi8(g0, sh_g); + r0 = _mm256_shuffle_epi8(r0, sh_r); + + a = v_uint16x16(b0); + b = v_uint16x16(g0); + c = v_uint16x16(r0); +} + +inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& a, v_uint32x8& b, v_uint32x8& c ) +{ + __m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 8)); + __m256i bgr2 = _mm256_loadu_si256((const __m256i*)(ptr + 16)); + + __m256i s02_low = _mm256_permute2x128_si256(bgr0, bgr2, 0 + 2*16); + __m256i s02_high = _mm256_permute2x128_si256(bgr0, bgr2, 1 + 3*16); + + __m256i b0 = _mm256_blend_epi32(_mm256_blend_epi32(s02_low, s02_high, 0x24), bgr1, 0x92); + __m256i g0 = _mm256_blend_epi32(_mm256_blend_epi32(s02_high, s02_low, 0x92), bgr1, 0x24); + __m256i r0 = _mm256_blend_epi32(_mm256_blend_epi32(bgr1, s02_low, 0x24), s02_high, 0x92); + + b0 = _mm256_shuffle_epi32(b0, 0x6c); + g0 = _mm256_shuffle_epi32(g0, 0xb1); + r0 = _mm256_shuffle_epi32(r0, 0xc6); + + a = v_uint32x8(b0); + b = v_uint32x8(g0); + c = v_uint32x8(r0); +} + +inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b, v_uint64x4& c ) +{ + __m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 4)); + __m256i bgr2 = _mm256_loadu_si256((const __m256i*)(ptr + 8)); + + __m256i s01 = _mm256_blend_epi32(bgr0, bgr1, 0xf0); + __m256i s12 = _mm256_blend_epi32(bgr1, bgr2, 0xf0); + __m256i s20r = _mm256_permute4x64_epi64(_mm256_blend_epi32(bgr2, bgr0, 0xf0), 0x1b); + __m256i b0 = _mm256_unpacklo_epi64(s01, s20r); + __m256i g0 = _mm256_alignr_epi8(s12, s01, 8); + __m256i r0 = _mm256_unpackhi_epi64(s20r, s12); + + a = v_uint64x4(b0); + b = v_uint64x4(g0); + c = v_uint64x4(r0); +} + +inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& a, v_uint8x32& b, v_uint8x32& c, v_uint8x32& d ) +{ + __m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 32)); + __m256i bgr2 = _mm256_loadu_si256((const __m256i*)(ptr + 64)); + __m256i bgr3 = _mm256_loadu_si256((const __m256i*)(ptr + 96)); + const __m256i sh = _mm256_setr_epi8(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, + 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15); + + __m256i p0 = _mm256_shuffle_epi8(bgr0, sh); + __m256i p1 = _mm256_shuffle_epi8(bgr1, sh); + __m256i p2 = _mm256_shuffle_epi8(bgr2, sh); + __m256i p3 = _mm256_shuffle_epi8(bgr3, sh); + + __m256i p01l = _mm256_unpacklo_epi32(p0, p1); + __m256i p01h = _mm256_unpackhi_epi32(p0, p1); + __m256i p23l = _mm256_unpacklo_epi32(p2, p3); + __m256i p23h = _mm256_unpackhi_epi32(p2, p3); + + __m256i pll = _mm256_permute2x128_si256(p01l, p23l, 0 + 2*16); + __m256i plh = _mm256_permute2x128_si256(p01l, p23l, 1 + 3*16); + __m256i phl = _mm256_permute2x128_si256(p01h, p23h, 0 + 2*16); + __m256i phh = _mm256_permute2x128_si256(p01h, p23h, 1 + 3*16); + + __m256i b0 = _mm256_unpacklo_epi32(pll, plh); + __m256i g0 = _mm256_unpackhi_epi32(pll, plh); + __m256i r0 = _mm256_unpacklo_epi32(phl, phh); + __m256i a0 = _mm256_unpackhi_epi32(phl, phh); + + a = v_uint8x32(b0); + b = v_uint8x32(g0); + c = v_uint8x32(r0); + d = v_uint8x32(a0); +} + +inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& a, v_uint16x16& b, v_uint16x16& c, v_uint16x16& d ) +{ + __m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 16)); + __m256i bgr2 = _mm256_loadu_si256((const __m256i*)(ptr + 32)); + __m256i bgr3 = _mm256_loadu_si256((const __m256i*)(ptr + 48)); + const __m256i sh = _mm256_setr_epi8(0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15, + 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15); + __m256i p0 = _mm256_shuffle_epi8(bgr0, sh); + __m256i p1 = _mm256_shuffle_epi8(bgr1, sh); + __m256i p2 = _mm256_shuffle_epi8(bgr2, sh); + __m256i p3 = _mm256_shuffle_epi8(bgr3, sh); + + __m256i p01l = _mm256_unpacklo_epi32(p0, p1); + __m256i p01h = _mm256_unpackhi_epi32(p0, p1); + __m256i p23l = _mm256_unpacklo_epi32(p2, p3); + __m256i p23h = _mm256_unpackhi_epi32(p2, p3); + + __m256i pll = _mm256_permute2x128_si256(p01l, p23l, 0 + 2*16); + __m256i plh = _mm256_permute2x128_si256(p01l, p23l, 1 + 3*16); + __m256i phl = _mm256_permute2x128_si256(p01h, p23h, 0 + 2*16); + __m256i phh = _mm256_permute2x128_si256(p01h, p23h, 1 + 3*16); + + __m256i b0 = _mm256_unpacklo_epi32(pll, plh); + __m256i g0 = _mm256_unpackhi_epi32(pll, plh); + __m256i r0 = _mm256_unpacklo_epi32(phl, phh); + __m256i a0 = _mm256_unpackhi_epi32(phl, phh); + + a = v_uint16x16(b0); + b = v_uint16x16(g0); + c = v_uint16x16(r0); + d = v_uint16x16(a0); +} + +inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& a, v_uint32x8& b, v_uint32x8& c, v_uint32x8& d ) +{ + __m256i p0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i p1 = _mm256_loadu_si256((const __m256i*)(ptr + 8)); + __m256i p2 = _mm256_loadu_si256((const __m256i*)(ptr + 16)); + __m256i p3 = _mm256_loadu_si256((const __m256i*)(ptr + 24)); + + __m256i p01l = _mm256_unpacklo_epi32(p0, p1); + __m256i p01h = _mm256_unpackhi_epi32(p0, p1); + __m256i p23l = _mm256_unpacklo_epi32(p2, p3); + __m256i p23h = _mm256_unpackhi_epi32(p2, p3); + + __m256i pll = _mm256_permute2x128_si256(p01l, p23l, 0 + 2*16); + __m256i plh = _mm256_permute2x128_si256(p01l, p23l, 1 + 3*16); + __m256i phl = _mm256_permute2x128_si256(p01h, p23h, 0 + 2*16); + __m256i phh = _mm256_permute2x128_si256(p01h, p23h, 1 + 3*16); + + __m256i b0 = _mm256_unpacklo_epi32(pll, plh); + __m256i g0 = _mm256_unpackhi_epi32(pll, plh); + __m256i r0 = _mm256_unpacklo_epi32(phl, phh); + __m256i a0 = _mm256_unpackhi_epi32(phl, phh); + + a = v_uint32x8(b0); + b = v_uint32x8(g0); + c = v_uint32x8(r0); + d = v_uint32x8(a0); +} + +inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b, v_uint64x4& c, v_uint64x4& d ) +{ + __m256i bgra0 = _mm256_loadu_si256((const __m256i*)ptr); + __m256i bgra1 = _mm256_loadu_si256((const __m256i*)(ptr + 4)); + __m256i bgra2 = _mm256_loadu_si256((const __m256i*)(ptr + 8)); + __m256i bgra3 = _mm256_loadu_si256((const __m256i*)(ptr + 12)); + + __m256i l02 = _mm256_permute2x128_si256(bgra0, bgra2, 0 + 2*16); + __m256i h02 = _mm256_permute2x128_si256(bgra0, bgra2, 1 + 3*16); + __m256i l13 = _mm256_permute2x128_si256(bgra1, bgra3, 0 + 2*16); + __m256i h13 = _mm256_permute2x128_si256(bgra1, bgra3, 1 + 3*16); + + __m256i b0 = _mm256_unpacklo_epi64(l02, l13); + __m256i g0 = _mm256_unpackhi_epi64(l02, l13); + __m256i r0 = _mm256_unpacklo_epi64(h02, h13); + __m256i a0 = _mm256_unpackhi_epi64(h02, h13); + + a = v_uint64x4(b0); + b = v_uint64x4(g0); + c = v_uint64x4(r0); + d = v_uint64x4(a0); +} + +///////////////////////////// store interleave ///////////////////////////////////// + +inline void v_store_interleave( uchar* ptr, const v_uint8x32& x, const v_uint8x32& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i xy_l = _mm256_unpacklo_epi8(x.val, y.val); + __m256i xy_h = _mm256_unpackhi_epi8(x.val, y.val); + + __m256i xy0 = _mm256_permute2x128_si256(xy_l, xy_h, 0 + 2*16); + __m256i xy1 = _mm256_permute2x128_si256(xy_l, xy_h, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, xy0); + _mm256_stream_si256((__m256i*)(ptr + 32), xy1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, xy0); + _mm256_store_si256((__m256i*)(ptr + 32), xy1); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, xy0); + _mm256_storeu_si256((__m256i*)(ptr + 32), xy1); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x16& x, const v_uint16x16& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i xy_l = _mm256_unpacklo_epi16(x.val, y.val); + __m256i xy_h = _mm256_unpackhi_epi16(x.val, y.val); + + __m256i xy0 = _mm256_permute2x128_si256(xy_l, xy_h, 0 + 2*16); + __m256i xy1 = _mm256_permute2x128_si256(xy_l, xy_h, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, xy0); + _mm256_stream_si256((__m256i*)(ptr + 16), xy1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, xy0); + _mm256_store_si256((__m256i*)(ptr + 16), xy1); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, xy0); + _mm256_storeu_si256((__m256i*)(ptr + 16), xy1); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x8& x, const v_uint32x8& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i xy_l = _mm256_unpacklo_epi32(x.val, y.val); + __m256i xy_h = _mm256_unpackhi_epi32(x.val, y.val); + + __m256i xy0 = _mm256_permute2x128_si256(xy_l, xy_h, 0 + 2*16); + __m256i xy1 = _mm256_permute2x128_si256(xy_l, xy_h, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, xy0); + _mm256_stream_si256((__m256i*)(ptr + 8), xy1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, xy0); + _mm256_store_si256((__m256i*)(ptr + 8), xy1); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, xy0); + _mm256_storeu_si256((__m256i*)(ptr + 8), xy1); + } +} + +inline void v_store_interleave( uint64* ptr, const v_uint64x4& x, const v_uint64x4& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i xy_l = _mm256_unpacklo_epi64(x.val, y.val); + __m256i xy_h = _mm256_unpackhi_epi64(x.val, y.val); + + __m256i xy0 = _mm256_permute2x128_si256(xy_l, xy_h, 0 + 2*16); + __m256i xy1 = _mm256_permute2x128_si256(xy_l, xy_h, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, xy0); + _mm256_stream_si256((__m256i*)(ptr + 4), xy1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, xy0); + _mm256_store_si256((__m256i*)(ptr + 4), xy1); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, xy0); + _mm256_storeu_si256((__m256i*)(ptr + 4), xy1); + } +} + +inline void v_store_interleave( uchar* ptr, const v_uint8x32& a, const v_uint8x32& b, const v_uint8x32& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + const __m256i sh_b = _mm256_setr_epi8( + 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10, 5, + 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10, 5); + const __m256i sh_g = _mm256_setr_epi8( + 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10, + 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10); + const __m256i sh_r = _mm256_setr_epi8( + 10, 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, + 10, 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15); + + __m256i b0 = _mm256_shuffle_epi8(a.val, sh_b); + __m256i g0 = _mm256_shuffle_epi8(b.val, sh_g); + __m256i r0 = _mm256_shuffle_epi8(c.val, sh_r); + + const __m256i m0 = _mm256_setr_epi8(0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, + 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0); + const __m256i m1 = _mm256_setr_epi8(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, + 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0); + + __m256i p0 = _mm256_blendv_epi8(_mm256_blendv_epi8(b0, g0, m0), r0, m1); + __m256i p1 = _mm256_blendv_epi8(_mm256_blendv_epi8(g0, r0, m0), b0, m1); + __m256i p2 = _mm256_blendv_epi8(_mm256_blendv_epi8(r0, b0, m0), g0, m1); + + __m256i bgr0 = _mm256_permute2x128_si256(p0, p1, 0 + 2*16); + __m256i bgr1 = _mm256_permute2x128_si256(p2, p0, 0 + 3*16); + __m256i bgr2 = _mm256_permute2x128_si256(p1, p2, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgr0); + _mm256_stream_si256((__m256i*)(ptr + 32), bgr1); + _mm256_stream_si256((__m256i*)(ptr + 64), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgr0); + _mm256_store_si256((__m256i*)(ptr + 32), bgr1); + _mm256_store_si256((__m256i*)(ptr + 64), bgr2); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgr0); + _mm256_storeu_si256((__m256i*)(ptr + 32), bgr1); + _mm256_storeu_si256((__m256i*)(ptr + 64), bgr2); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x16& a, const v_uint16x16& b, const v_uint16x16& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + const __m256i sh_b = _mm256_setr_epi8( + 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, + 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11); + const __m256i sh_g = _mm256_setr_epi8( + 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, + 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5); + const __m256i sh_r = _mm256_setr_epi8( + 4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, + 4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15); + + __m256i b0 = _mm256_shuffle_epi8(a.val, sh_b); + __m256i g0 = _mm256_shuffle_epi8(b.val, sh_g); + __m256i r0 = _mm256_shuffle_epi8(c.val, sh_r); + + const __m256i m0 = _mm256_setr_epi8(0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, + 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0); + const __m256i m1 = _mm256_setr_epi8(0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, + -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0); + + __m256i p0 = _mm256_blendv_epi8(_mm256_blendv_epi8(b0, g0, m0), r0, m1); + __m256i p1 = _mm256_blendv_epi8(_mm256_blendv_epi8(g0, r0, m0), b0, m1); + __m256i p2 = _mm256_blendv_epi8(_mm256_blendv_epi8(r0, b0, m0), g0, m1); + + __m256i bgr0 = _mm256_permute2x128_si256(p0, p2, 0 + 2*16); + //__m256i bgr1 = p1; + __m256i bgr2 = _mm256_permute2x128_si256(p0, p2, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgr0); + _mm256_stream_si256((__m256i*)(ptr + 16), p1); + _mm256_stream_si256((__m256i*)(ptr + 32), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgr0); + _mm256_store_si256((__m256i*)(ptr + 16), p1); + _mm256_store_si256((__m256i*)(ptr + 32), bgr2); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgr0); + _mm256_storeu_si256((__m256i*)(ptr + 16), p1); + _mm256_storeu_si256((__m256i*)(ptr + 32), bgr2); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x8& a, const v_uint32x8& b, const v_uint32x8& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i b0 = _mm256_shuffle_epi32(a.val, 0x6c); + __m256i g0 = _mm256_shuffle_epi32(b.val, 0xb1); + __m256i r0 = _mm256_shuffle_epi32(c.val, 0xc6); + + __m256i p0 = _mm256_blend_epi32(_mm256_blend_epi32(b0, g0, 0x92), r0, 0x24); + __m256i p1 = _mm256_blend_epi32(_mm256_blend_epi32(g0, r0, 0x92), b0, 0x24); + __m256i p2 = _mm256_blend_epi32(_mm256_blend_epi32(r0, b0, 0x92), g0, 0x24); + + __m256i bgr0 = _mm256_permute2x128_si256(p0, p1, 0 + 2*16); + //__m256i bgr1 = p2; + __m256i bgr2 = _mm256_permute2x128_si256(p0, p1, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgr0); + _mm256_stream_si256((__m256i*)(ptr + 8), p2); + _mm256_stream_si256((__m256i*)(ptr + 16), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgr0); + _mm256_store_si256((__m256i*)(ptr + 8), p2); + _mm256_store_si256((__m256i*)(ptr + 16), bgr2); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgr0); + _mm256_storeu_si256((__m256i*)(ptr + 8), p2); + _mm256_storeu_si256((__m256i*)(ptr + 16), bgr2); + } +} + +inline void v_store_interleave( uint64* ptr, const v_uint64x4& a, const v_uint64x4& b, const v_uint64x4& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i s01 = _mm256_unpacklo_epi64(a.val, b.val); + __m256i s12 = _mm256_unpackhi_epi64(b.val, c.val); + __m256i s20 = _mm256_blend_epi32(c.val, a.val, 0xcc); + + __m256i bgr0 = _mm256_permute2x128_si256(s01, s20, 0 + 2*16); + __m256i bgr1 = _mm256_blend_epi32(s01, s12, 0x0f); + __m256i bgr2 = _mm256_permute2x128_si256(s20, s12, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgr0); + _mm256_stream_si256((__m256i*)(ptr + 4), bgr1); + _mm256_stream_si256((__m256i*)(ptr + 8), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgr0); + _mm256_store_si256((__m256i*)(ptr + 4), bgr1); + _mm256_store_si256((__m256i*)(ptr + 8), bgr2); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgr0); + _mm256_storeu_si256((__m256i*)(ptr + 4), bgr1); + _mm256_storeu_si256((__m256i*)(ptr + 8), bgr2); + } +} + +inline void v_store_interleave( uchar* ptr, const v_uint8x32& a, const v_uint8x32& b, + const v_uint8x32& c, const v_uint8x32& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i bg0 = _mm256_unpacklo_epi8(a.val, b.val); + __m256i bg1 = _mm256_unpackhi_epi8(a.val, b.val); + __m256i ra0 = _mm256_unpacklo_epi8(c.val, d.val); + __m256i ra1 = _mm256_unpackhi_epi8(c.val, d.val); + + __m256i bgra0_ = _mm256_unpacklo_epi16(bg0, ra0); + __m256i bgra1_ = _mm256_unpackhi_epi16(bg0, ra0); + __m256i bgra2_ = _mm256_unpacklo_epi16(bg1, ra1); + __m256i bgra3_ = _mm256_unpackhi_epi16(bg1, ra1); + + __m256i bgra0 = _mm256_permute2x128_si256(bgra0_, bgra1_, 0 + 2*16); + __m256i bgra2 = _mm256_permute2x128_si256(bgra0_, bgra1_, 1 + 3*16); + __m256i bgra1 = _mm256_permute2x128_si256(bgra2_, bgra3_, 0 + 2*16); + __m256i bgra3 = _mm256_permute2x128_si256(bgra2_, bgra3_, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgra0); + _mm256_stream_si256((__m256i*)(ptr + 32), bgra1); + _mm256_stream_si256((__m256i*)(ptr + 64), bgra2); + _mm256_stream_si256((__m256i*)(ptr + 96), bgra3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgra0); + _mm256_store_si256((__m256i*)(ptr + 32), bgra1); + _mm256_store_si256((__m256i*)(ptr + 64), bgra2); + _mm256_store_si256((__m256i*)(ptr + 96), bgra3); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgra0); + _mm256_storeu_si256((__m256i*)(ptr + 32), bgra1); + _mm256_storeu_si256((__m256i*)(ptr + 64), bgra2); + _mm256_storeu_si256((__m256i*)(ptr + 96), bgra3); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x16& a, const v_uint16x16& b, + const v_uint16x16& c, const v_uint16x16& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i bg0 = _mm256_unpacklo_epi16(a.val, b.val); + __m256i bg1 = _mm256_unpackhi_epi16(a.val, b.val); + __m256i ra0 = _mm256_unpacklo_epi16(c.val, d.val); + __m256i ra1 = _mm256_unpackhi_epi16(c.val, d.val); + + __m256i bgra0_ = _mm256_unpacklo_epi32(bg0, ra0); + __m256i bgra1_ = _mm256_unpackhi_epi32(bg0, ra0); + __m256i bgra2_ = _mm256_unpacklo_epi32(bg1, ra1); + __m256i bgra3_ = _mm256_unpackhi_epi32(bg1, ra1); + + __m256i bgra0 = _mm256_permute2x128_si256(bgra0_, bgra1_, 0 + 2*16); + __m256i bgra2 = _mm256_permute2x128_si256(bgra0_, bgra1_, 1 + 3*16); + __m256i bgra1 = _mm256_permute2x128_si256(bgra2_, bgra3_, 0 + 2*16); + __m256i bgra3 = _mm256_permute2x128_si256(bgra2_, bgra3_, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgra0); + _mm256_stream_si256((__m256i*)(ptr + 16), bgra1); + _mm256_stream_si256((__m256i*)(ptr + 32), bgra2); + _mm256_stream_si256((__m256i*)(ptr + 48), bgra3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgra0); + _mm256_store_si256((__m256i*)(ptr + 16), bgra1); + _mm256_store_si256((__m256i*)(ptr + 32), bgra2); + _mm256_store_si256((__m256i*)(ptr + 48), bgra3); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgra0); + _mm256_storeu_si256((__m256i*)(ptr + 16), bgra1); + _mm256_storeu_si256((__m256i*)(ptr + 32), bgra2); + _mm256_storeu_si256((__m256i*)(ptr + 48), bgra3); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x8& a, const v_uint32x8& b, + const v_uint32x8& c, const v_uint32x8& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i bg0 = _mm256_unpacklo_epi32(a.val, b.val); + __m256i bg1 = _mm256_unpackhi_epi32(a.val, b.val); + __m256i ra0 = _mm256_unpacklo_epi32(c.val, d.val); + __m256i ra1 = _mm256_unpackhi_epi32(c.val, d.val); + + __m256i bgra0_ = _mm256_unpacklo_epi64(bg0, ra0); + __m256i bgra1_ = _mm256_unpackhi_epi64(bg0, ra0); + __m256i bgra2_ = _mm256_unpacklo_epi64(bg1, ra1); + __m256i bgra3_ = _mm256_unpackhi_epi64(bg1, ra1); + + __m256i bgra0 = _mm256_permute2x128_si256(bgra0_, bgra1_, 0 + 2*16); + __m256i bgra2 = _mm256_permute2x128_si256(bgra0_, bgra1_, 1 + 3*16); + __m256i bgra1 = _mm256_permute2x128_si256(bgra2_, bgra3_, 0 + 2*16); + __m256i bgra3 = _mm256_permute2x128_si256(bgra2_, bgra3_, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgra0); + _mm256_stream_si256((__m256i*)(ptr + 8), bgra1); + _mm256_stream_si256((__m256i*)(ptr + 16), bgra2); + _mm256_stream_si256((__m256i*)(ptr + 24), bgra3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgra0); + _mm256_store_si256((__m256i*)(ptr + 8), bgra1); + _mm256_store_si256((__m256i*)(ptr + 16), bgra2); + _mm256_store_si256((__m256i*)(ptr + 24), bgra3); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgra0); + _mm256_storeu_si256((__m256i*)(ptr + 8), bgra1); + _mm256_storeu_si256((__m256i*)(ptr + 16), bgra2); + _mm256_storeu_si256((__m256i*)(ptr + 24), bgra3); + } +} + +inline void v_store_interleave( uint64* ptr, const v_uint64x4& a, const v_uint64x4& b, + const v_uint64x4& c, const v_uint64x4& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m256i bg0 = _mm256_unpacklo_epi64(a.val, b.val); + __m256i bg1 = _mm256_unpackhi_epi64(a.val, b.val); + __m256i ra0 = _mm256_unpacklo_epi64(c.val, d.val); + __m256i ra1 = _mm256_unpackhi_epi64(c.val, d.val); + + __m256i bgra0 = _mm256_permute2x128_si256(bg0, ra0, 0 + 2*16); + __m256i bgra1 = _mm256_permute2x128_si256(bg1, ra1, 0 + 2*16); + __m256i bgra2 = _mm256_permute2x128_si256(bg0, ra0, 1 + 3*16); + __m256i bgra3 = _mm256_permute2x128_si256(bg1, ra1, 1 + 3*16); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm256_stream_si256((__m256i*)ptr, bgra0); + _mm256_stream_si256((__m256i*)(ptr + 4), bgra1); + _mm256_stream_si256((__m256i*)(ptr + 8), bgra2); + _mm256_stream_si256((__m256i*)(ptr + 12), bgra3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm256_store_si256((__m256i*)ptr, bgra0); + _mm256_store_si256((__m256i*)(ptr + 4), bgra1); + _mm256_store_si256((__m256i*)(ptr + 8), bgra2); + _mm256_store_si256((__m256i*)(ptr + 12), bgra3); + } + else + { + _mm256_storeu_si256((__m256i*)ptr, bgra0); + _mm256_storeu_si256((__m256i*)(ptr + 4), bgra1); + _mm256_storeu_si256((__m256i*)(ptr + 8), bgra2); + _mm256_storeu_si256((__m256i*)(ptr + 12), bgra3); + } +} + +#define OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(_Tpvec0, _Tp0, suffix0, _Tpvec1, _Tp1, suffix1) \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0 ) \ +{ \ + _Tpvec1 a1, b1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ +} \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0, _Tpvec0& c0 ) \ +{ \ + _Tpvec1 a1, b1, c1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1, c1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ + c0 = v_reinterpret_as_##suffix0(c1); \ +} \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0, _Tpvec0& c0, _Tpvec0& d0 ) \ +{ \ + _Tpvec1 a1, b1, c1, d1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1, c1, d1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ + c0 = v_reinterpret_as_##suffix0(c1); \ + d0 = v_reinterpret_as_##suffix0(d1); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, \ + hal::StoreMode mode=hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, mode); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, const _Tpvec0& c0, \ + hal::StoreMode mode=hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + _Tpvec1 c1 = v_reinterpret_as_##suffix1(c0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, c1, mode); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, \ + const _Tpvec0& c0, const _Tpvec0& d0, \ + hal::StoreMode mode=hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + _Tpvec1 c1 = v_reinterpret_as_##suffix1(c0); \ + _Tpvec1 d1 = v_reinterpret_as_##suffix1(d0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, c1, d1, mode); \ +} + +OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(v_int8x32, schar, s8, v_uint8x32, uchar, u8) +OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(v_int16x16, short, s16, v_uint16x16, ushort, u16) +OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(v_int32x8, int, s32, v_uint32x8, unsigned, u32) +OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(v_float32x8, float, f32, v_uint32x8, unsigned, u32) +OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(v_int64x4, int64, s64, v_uint64x4, uint64, u64) +OPENCV_HAL_IMPL_AVX_LOADSTORE_INTERLEAVE(v_float64x4, double, f64, v_uint64x4, uint64, u64) + +// FP16 +inline v_float32x8 v256_load_expand(const float16_t* ptr) +{ + return v_float32x8(_mm256_cvtph_ps(_mm_loadu_si128((const __m128i*)ptr))); +} + +inline void v_pack_store(float16_t* ptr, const v_float32x8& a) +{ + __m128i ah = _mm256_cvtps_ph(a.val, 0); + _mm_storeu_si128((__m128i*)ptr, ah); +} + +inline void v256_cleanup() { _mm256_zeroall(); } + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} // cv:: + +#endif // OPENCV_HAL_INTRIN_AVX_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx512.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx512.hpp new file mode 100755 index 0000000..d4edf0c --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_avx512.hpp @@ -0,0 +1,2781 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#ifndef OPENCV_HAL_INTRIN_AVX512_HPP +#define OPENCV_HAL_INTRIN_AVX512_HPP + +#if defined(_MSC_VER) && (_MSC_VER < 1920/*MSVS2019*/) +# pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned +# pragma warning(disable:4309) // 'argument': truncation of constant value +# pragma warning(disable:4310) // cast truncates constant value +#endif + +#define CVT_ROUND_MODES_IMPLEMENTED 0 + +#define CV_SIMD512 1 +#define CV_SIMD512_64F 1 +#define CV_SIMD512_FP16 0 // no native operations with FP16 type. Only load/store from float32x8 are available (if CV_FP16 == 1) + +#define _v512_set_epu64(a7, a6, a5, a4, a3, a2, a1, a0) _mm512_set_epi64((int64)(a7),(int64)(a6),(int64)(a5),(int64)(a4),(int64)(a3),(int64)(a2),(int64)(a1),(int64)(a0)) +#define _v512_set_epu32(a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0) \ + _mm512_set_epi64(((int64)(a15)<<32)|(int64)(a14), ((int64)(a13)<<32)|(int64)(a12), ((int64)(a11)<<32)|(int64)(a10), ((int64)( a9)<<32)|(int64)( a8), \ + ((int64)( a7)<<32)|(int64)( a6), ((int64)( a5)<<32)|(int64)( a4), ((int64)( a3)<<32)|(int64)( a2), ((int64)( a1)<<32)|(int64)( a0)) +#define _v512_set_epu16(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, \ + a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0) \ + _v512_set_epu32(((unsigned)(a31)<<16)|(unsigned)(a30), ((unsigned)(a29)<<16)|(unsigned)(a28), ((unsigned)(a27)<<16)|(unsigned)(a26), ((unsigned)(a25)<<16)|(unsigned)(a24), \ + ((unsigned)(a23)<<16)|(unsigned)(a22), ((unsigned)(a21)<<16)|(unsigned)(a20), ((unsigned)(a19)<<16)|(unsigned)(a18), ((unsigned)(a17)<<16)|(unsigned)(a16), \ + ((unsigned)(a15)<<16)|(unsigned)(a14), ((unsigned)(a13)<<16)|(unsigned)(a12), ((unsigned)(a11)<<16)|(unsigned)(a10), ((unsigned)( a9)<<16)|(unsigned)( a8), \ + ((unsigned)( a7)<<16)|(unsigned)( a6), ((unsigned)( a5)<<16)|(unsigned)( a4), ((unsigned)( a3)<<16)|(unsigned)( a2), ((unsigned)( a1)<<16)|(unsigned)( a0)) +#define _v512_set_epu8(a63, a62, a61, a60, a59, a58, a57, a56, a55, a54, a53, a52, a51, a50, a49, a48, \ + a47, a46, a45, a44, a43, a42, a41, a40, a39, a38, a37, a36, a35, a34, a33, a32, \ + a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, \ + a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0) \ + _v512_set_epu32(((unsigned)(a63)<<24)|((unsigned)(a62)<<16)|((unsigned)(a61)<<8)|(unsigned)(a60),((unsigned)(a59)<<24)|((unsigned)(a58)<<16)|((unsigned)(a57)<<8)|(unsigned)(a56), \ + ((unsigned)(a55)<<24)|((unsigned)(a54)<<16)|((unsigned)(a53)<<8)|(unsigned)(a52),((unsigned)(a51)<<24)|((unsigned)(a50)<<16)|((unsigned)(a49)<<8)|(unsigned)(a48), \ + ((unsigned)(a47)<<24)|((unsigned)(a46)<<16)|((unsigned)(a45)<<8)|(unsigned)(a44),((unsigned)(a43)<<24)|((unsigned)(a42)<<16)|((unsigned)(a41)<<8)|(unsigned)(a40), \ + ((unsigned)(a39)<<24)|((unsigned)(a38)<<16)|((unsigned)(a37)<<8)|(unsigned)(a36),((unsigned)(a35)<<24)|((unsigned)(a34)<<16)|((unsigned)(a33)<<8)|(unsigned)(a32), \ + ((unsigned)(a31)<<24)|((unsigned)(a30)<<16)|((unsigned)(a29)<<8)|(unsigned)(a28),((unsigned)(a27)<<24)|((unsigned)(a26)<<16)|((unsigned)(a25)<<8)|(unsigned)(a24), \ + ((unsigned)(a23)<<24)|((unsigned)(a22)<<16)|((unsigned)(a21)<<8)|(unsigned)(a20),((unsigned)(a19)<<24)|((unsigned)(a18)<<16)|((unsigned)(a17)<<8)|(unsigned)(a16), \ + ((unsigned)(a15)<<24)|((unsigned)(a14)<<16)|((unsigned)(a13)<<8)|(unsigned)(a12),((unsigned)(a11)<<24)|((unsigned)(a10)<<16)|((unsigned)( a9)<<8)|(unsigned)( a8), \ + ((unsigned)( a7)<<24)|((unsigned)( a6)<<16)|((unsigned)( a5)<<8)|(unsigned)( a4),((unsigned)( a3)<<24)|((unsigned)( a2)<<16)|((unsigned)( a1)<<8)|(unsigned)( a0)) +#define _v512_set_epi8(a63, a62, a61, a60, a59, a58, a57, a56, a55, a54, a53, a52, a51, a50, a49, a48, \ + a47, a46, a45, a44, a43, a42, a41, a40, a39, a38, a37, a36, a35, a34, a33, a32, \ + a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, \ + a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0) \ + _v512_set_epu8((uchar)(a63), (uchar)(a62), (uchar)(a61), (uchar)(a60), (uchar)(a59), (uchar)(a58), (uchar)(a57), (uchar)(a56), \ + (uchar)(a55), (uchar)(a54), (uchar)(a53), (uchar)(a52), (uchar)(a51), (uchar)(a50), (uchar)(a49), (uchar)(a48), \ + (uchar)(a47), (uchar)(a46), (uchar)(a45), (uchar)(a44), (uchar)(a43), (uchar)(a42), (uchar)(a41), (uchar)(a40), \ + (uchar)(a39), (uchar)(a38), (uchar)(a37), (uchar)(a36), (uchar)(a35), (uchar)(a34), (uchar)(a33), (uchar)(a32), \ + (uchar)(a31), (uchar)(a30), (uchar)(a29), (uchar)(a28), (uchar)(a27), (uchar)(a26), (uchar)(a25), (uchar)(a24), \ + (uchar)(a23), (uchar)(a22), (uchar)(a21), (uchar)(a20), (uchar)(a19), (uchar)(a18), (uchar)(a17), (uchar)(a16), \ + (uchar)(a15), (uchar)(a14), (uchar)(a13), (uchar)(a12), (uchar)(a11), (uchar)(a10), (uchar)( a9), (uchar)( a8), \ + (uchar)( a7), (uchar)( a6), (uchar)( a5), (uchar)( a4), (uchar)( a3), (uchar)( a2), (uchar)( a1), (uchar)( a0)) + +#ifndef _mm512_cvtpd_pslo +#ifdef _mm512_zextsi256_si512 +#define _mm512_cvtpd_pslo(a) _mm512_zextps256_ps512(_mm512_cvtpd_ps(a)) +#else +//if preferred way to extend with zeros is unavailable +#define _mm512_cvtpd_pslo(a) _mm512_castps256_ps512(_mm512_cvtpd_ps(a)) +#endif +#endif +///////// Utils //////////// + +namespace +{ + +inline __m512i _v512_combine(const __m256i& lo, const __m256i& hi) +{ return _mm512_inserti32x8(_mm512_castsi256_si512(lo), hi, 1); } + +inline __m512 _v512_combine(const __m256& lo, const __m256& hi) +{ return _mm512_insertf32x8(_mm512_castps256_ps512(lo), hi, 1); } + +inline __m512d _v512_combine(const __m256d& lo, const __m256d& hi) +{ return _mm512_insertf64x4(_mm512_castpd256_pd512(lo), hi, 1); } + +inline int _v_cvtsi512_si32(const __m512i& a) +{ return _mm_cvtsi128_si32(_mm512_castsi512_si128(a)); } + +inline __m256i _v512_extract_high(const __m512i& v) +{ return _mm512_extracti32x8_epi32(v, 1); } + +inline __m256 _v512_extract_high(const __m512& v) +{ return _mm512_extractf32x8_ps(v, 1); } + +inline __m256d _v512_extract_high(const __m512d& v) +{ return _mm512_extractf64x4_pd(v, 1); } + +inline __m256i _v512_extract_low(const __m512i& v) +{ return _mm512_castsi512_si256(v); } + +inline __m256 _v512_extract_low(const __m512& v) +{ return _mm512_castps512_ps256(v); } + +inline __m256d _v512_extract_low(const __m512d& v) +{ return _mm512_castpd512_pd256(v); } + +inline __m512i _v512_insert(const __m512i& a, const __m256i& b) +{ return _mm512_inserti32x8(a, b, 0); } + +inline __m512 _v512_insert(const __m512& a, const __m256& b) +{ return _mm512_insertf32x8(a, b, 0); } + +inline __m512d _v512_insert(const __m512d& a, const __m256d& b) +{ return _mm512_insertf64x4(a, b, 0); } + +} + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +///////// Types //////////// + +struct v_uint8x64 +{ + typedef uchar lane_type; + enum { nlanes = 64 }; + __m512i val; + + explicit v_uint8x64(__m512i v) : val(v) {} + v_uint8x64(uchar v0, uchar v1, uchar v2, uchar v3, + uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, + uchar v12, uchar v13, uchar v14, uchar v15, + uchar v16, uchar v17, uchar v18, uchar v19, + uchar v20, uchar v21, uchar v22, uchar v23, + uchar v24, uchar v25, uchar v26, uchar v27, + uchar v28, uchar v29, uchar v30, uchar v31, + uchar v32, uchar v33, uchar v34, uchar v35, + uchar v36, uchar v37, uchar v38, uchar v39, + uchar v40, uchar v41, uchar v42, uchar v43, + uchar v44, uchar v45, uchar v46, uchar v47, + uchar v48, uchar v49, uchar v50, uchar v51, + uchar v52, uchar v53, uchar v54, uchar v55, + uchar v56, uchar v57, uchar v58, uchar v59, + uchar v60, uchar v61, uchar v62, uchar v63) + { + val = _v512_set_epu8(v63, v62, v61, v60, v59, v58, v57, v56, v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0); + } + v_uint8x64() : val(_mm512_setzero_si512()) {} + uchar get0() const { return (uchar)_v_cvtsi512_si32(val); } +}; + +struct v_int8x64 +{ + typedef schar lane_type; + enum { nlanes = 64 }; + __m512i val; + + explicit v_int8x64(__m512i v) : val(v) {} + v_int8x64(schar v0, schar v1, schar v2, schar v3, + schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, + schar v12, schar v13, schar v14, schar v15, + schar v16, schar v17, schar v18, schar v19, + schar v20, schar v21, schar v22, schar v23, + schar v24, schar v25, schar v26, schar v27, + schar v28, schar v29, schar v30, schar v31, + schar v32, schar v33, schar v34, schar v35, + schar v36, schar v37, schar v38, schar v39, + schar v40, schar v41, schar v42, schar v43, + schar v44, schar v45, schar v46, schar v47, + schar v48, schar v49, schar v50, schar v51, + schar v52, schar v53, schar v54, schar v55, + schar v56, schar v57, schar v58, schar v59, + schar v60, schar v61, schar v62, schar v63) + { + val = _v512_set_epi8(v63, v62, v61, v60, v59, v58, v57, v56, v55, v54, v53, v52, v51, v50, v49, v48, + v47, v46, v45, v44, v43, v42, v41, v40, v39, v38, v37, v36, v35, v34, v33, v32, + v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0); + } + v_int8x64() : val(_mm512_setzero_si512()) {} + schar get0() const { return (schar)_v_cvtsi512_si32(val); } +}; + +struct v_uint16x32 +{ + typedef ushort lane_type; + enum { nlanes = 32 }; + __m512i val; + + explicit v_uint16x32(__m512i v) : val(v) {} + v_uint16x32(ushort v0, ushort v1, ushort v2, ushort v3, + ushort v4, ushort v5, ushort v6, ushort v7, + ushort v8, ushort v9, ushort v10, ushort v11, + ushort v12, ushort v13, ushort v14, ushort v15, + ushort v16, ushort v17, ushort v18, ushort v19, + ushort v20, ushort v21, ushort v22, ushort v23, + ushort v24, ushort v25, ushort v26, ushort v27, + ushort v28, ushort v29, ushort v30, ushort v31) + { + val = _v512_set_epu16(v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, + v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0); + } + v_uint16x32() : val(_mm512_setzero_si512()) {} + ushort get0() const { return (ushort)_v_cvtsi512_si32(val); } +}; + +struct v_int16x32 +{ + typedef short lane_type; + enum { nlanes = 32 }; + __m512i val; + + explicit v_int16x32(__m512i v) : val(v) {} + v_int16x32(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7, + short v8, short v9, short v10, short v11, short v12, short v13, short v14, short v15, + short v16, short v17, short v18, short v19, short v20, short v21, short v22, short v23, + short v24, short v25, short v26, short v27, short v28, short v29, short v30, short v31) + { + val = _v512_set_epu16((ushort)v31, (ushort)v30, (ushort)v29, (ushort)v28, (ushort)v27, (ushort)v26, (ushort)v25, (ushort)v24, + (ushort)v23, (ushort)v22, (ushort)v21, (ushort)v20, (ushort)v19, (ushort)v18, (ushort)v17, (ushort)v16, + (ushort)v15, (ushort)v14, (ushort)v13, (ushort)v12, (ushort)v11, (ushort)v10, (ushort)v9 , (ushort)v8, + (ushort)v7 , (ushort)v6 , (ushort)v5 , (ushort)v4 , (ushort)v3 , (ushort)v2 , (ushort)v1 , (ushort)v0); + } + v_int16x32() : val(_mm512_setzero_si512()) {} + short get0() const { return (short)_v_cvtsi512_si32(val); } +}; + +struct v_uint32x16 +{ + typedef unsigned lane_type; + enum { nlanes = 16 }; + __m512i val; + + explicit v_uint32x16(__m512i v) : val(v) {} + v_uint32x16(unsigned v0, unsigned v1, unsigned v2, unsigned v3, + unsigned v4, unsigned v5, unsigned v6, unsigned v7, + unsigned v8, unsigned v9, unsigned v10, unsigned v11, + unsigned v12, unsigned v13, unsigned v14, unsigned v15) + { + val = _mm512_setr_epi32((int)v0, (int)v1, (int)v2, (int)v3, (int)v4, (int)v5, (int)v6, (int)v7, + (int)v8, (int)v9, (int)v10, (int)v11, (int)v12, (int)v13, (int)v14, (int)v15); + } + v_uint32x16() : val(_mm512_setzero_si512()) {} + unsigned get0() const { return (unsigned)_v_cvtsi512_si32(val); } +}; + +struct v_int32x16 +{ + typedef int lane_type; + enum { nlanes = 16 }; + __m512i val; + + explicit v_int32x16(__m512i v) : val(v) {} + v_int32x16(int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7, + int v8, int v9, int v10, int v11, int v12, int v13, int v14, int v15) + { + val = _mm512_setr_epi32(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); + } + v_int32x16() : val(_mm512_setzero_si512()) {} + int get0() const { return _v_cvtsi512_si32(val); } +}; + +struct v_float32x16 +{ + typedef float lane_type; + enum { nlanes = 16 }; + __m512 val; + + explicit v_float32x16(__m512 v) : val(v) {} + v_float32x16(float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, + float v8, float v9, float v10, float v11, float v12, float v13, float v14, float v15) + { + val = _mm512_setr_ps(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); + } + v_float32x16() : val(_mm512_setzero_ps()) {} + float get0() const { return _mm_cvtss_f32(_mm512_castps512_ps128(val)); } +}; + +struct v_uint64x8 +{ + typedef uint64 lane_type; + enum { nlanes = 8 }; + __m512i val; + + explicit v_uint64x8(__m512i v) : val(v) {} + v_uint64x8(uint64 v0, uint64 v1, uint64 v2, uint64 v3, uint64 v4, uint64 v5, uint64 v6, uint64 v7) + { val = _mm512_setr_epi64((int64)v0, (int64)v1, (int64)v2, (int64)v3, (int64)v4, (int64)v5, (int64)v6, (int64)v7); } + v_uint64x8() : val(_mm512_setzero_si512()) {} + uint64 get0() const + { + #if defined __x86_64__ || defined _M_X64 + return (uint64)_mm_cvtsi128_si64(_mm512_castsi512_si128(val)); + #else + int a = _mm_cvtsi128_si32(_mm512_castsi512_si128(val)); + int b = _mm_cvtsi128_si32(_mm512_castsi512_si128(_mm512_srli_epi64(val, 32))); + return (unsigned)a | ((uint64)(unsigned)b << 32); + #endif + } +}; + +struct v_int64x8 +{ + typedef int64 lane_type; + enum { nlanes = 8 }; + __m512i val; + + explicit v_int64x8(__m512i v) : val(v) {} + v_int64x8(int64 v0, int64 v1, int64 v2, int64 v3, int64 v4, int64 v5, int64 v6, int64 v7) + { val = _mm512_setr_epi64(v0, v1, v2, v3, v4, v5, v6, v7); } + v_int64x8() : val(_mm512_setzero_si512()) {} + + int64 get0() const + { + #if defined __x86_64__ || defined _M_X64 + return (int64)_mm_cvtsi128_si64(_mm512_castsi512_si128(val)); + #else + int a = _mm_cvtsi128_si32(_mm512_castsi512_si128(val)); + int b = _mm_cvtsi128_si32(_mm512_castsi512_si128(_mm512_srli_epi64(val, 32))); + return (int64)((unsigned)a | ((uint64)(unsigned)b << 32)); + #endif + } +}; + +struct v_float64x8 +{ + typedef double lane_type; + enum { nlanes = 8 }; + __m512d val; + + explicit v_float64x8(__m512d v) : val(v) {} + v_float64x8(double v0, double v1, double v2, double v3, double v4, double v5, double v6, double v7) + { val = _mm512_setr_pd(v0, v1, v2, v3, v4, v5, v6, v7); } + v_float64x8() : val(_mm512_setzero_pd()) {} + double get0() const { return _mm_cvtsd_f64(_mm512_castpd512_pd128(val)); } +}; + +//////////////// Load and store operations /////////////// + +#define OPENCV_HAL_IMPL_AVX512_LOADSTORE(_Tpvec, _Tp) \ + inline _Tpvec v512_load(const _Tp* ptr) \ + { return _Tpvec(_mm512_loadu_si512((const __m512i*)ptr)); } \ + inline _Tpvec v512_load_aligned(const _Tp* ptr) \ + { return _Tpvec(_mm512_load_si512((const __m512i*)ptr)); } \ + inline _Tpvec v512_load_low(const _Tp* ptr) \ + { \ + __m256i v256 = _mm256_loadu_si256((const __m256i*)ptr); \ + return _Tpvec(_mm512_castsi256_si512(v256)); \ + } \ + inline _Tpvec v512_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ + { \ + __m256i vlo = _mm256_loadu_si256((const __m256i*)ptr0); \ + __m256i vhi = _mm256_loadu_si256((const __m256i*)ptr1); \ + return _Tpvec(_v512_combine(vlo, vhi)); \ + } \ + inline void v_store(_Tp* ptr, const _Tpvec& a) \ + { _mm512_storeu_si512((__m512i*)ptr, a.val); } \ + inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ + { _mm512_store_si512((__m512i*)ptr, a.val); } \ + inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ + { _mm512_stream_si512((__m512i*)ptr, a.val); } \ + inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode mode) \ + { \ + if( mode == hal::STORE_UNALIGNED ) \ + _mm512_storeu_si512((__m512i*)ptr, a.val); \ + else if( mode == hal::STORE_ALIGNED_NOCACHE ) \ + _mm512_stream_si512((__m512i*)ptr, a.val); \ + else \ + _mm512_store_si512((__m512i*)ptr, a.val); \ + } \ + inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ + { _mm256_storeu_si256((__m256i*)ptr, _v512_extract_low(a.val)); } \ + inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ + { _mm256_storeu_si256((__m256i*)ptr, _v512_extract_high(a.val)); } + +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_uint8x64, uchar) +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_int8x64, schar) +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_uint16x32, ushort) +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_int16x32, short) +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_uint32x16, unsigned) +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_int32x16, int) +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_uint64x8, uint64) +OPENCV_HAL_IMPL_AVX512_LOADSTORE(v_int64x8, int64) + +#define OPENCV_HAL_IMPL_AVX512_LOADSTORE_FLT(_Tpvec, _Tp, suffix, halfreg) \ + inline _Tpvec v512_load(const _Tp* ptr) \ + { return _Tpvec(_mm512_loadu_##suffix(ptr)); } \ + inline _Tpvec v512_load_aligned(const _Tp* ptr) \ + { return _Tpvec(_mm512_load_##suffix(ptr)); } \ + inline _Tpvec v512_load_low(const _Tp* ptr) \ + { \ + return _Tpvec(_mm512_cast##suffix##256_##suffix##512 \ + (_mm256_loadu_##suffix(ptr))); \ + } \ + inline _Tpvec v512_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ + { \ + halfreg vlo = _mm256_loadu_##suffix(ptr0); \ + halfreg vhi = _mm256_loadu_##suffix(ptr1); \ + return _Tpvec(_v512_combine(vlo, vhi)); \ + } \ + inline void v_store(_Tp* ptr, const _Tpvec& a) \ + { _mm512_storeu_##suffix(ptr, a.val); } \ + inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ + { _mm512_store_##suffix(ptr, a.val); } \ + inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ + { _mm512_stream_##suffix(ptr, a.val); } \ + inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode mode) \ + { \ + if( mode == hal::STORE_UNALIGNED ) \ + _mm512_storeu_##suffix(ptr, a.val); \ + else if( mode == hal::STORE_ALIGNED_NOCACHE ) \ + _mm512_stream_##suffix(ptr, a.val); \ + else \ + _mm512_store_##suffix(ptr, a.val); \ + } \ + inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ + { _mm256_storeu_##suffix(ptr, _v512_extract_low(a.val)); } \ + inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ + { _mm256_storeu_##suffix(ptr, _v512_extract_high(a.val)); } + +OPENCV_HAL_IMPL_AVX512_LOADSTORE_FLT(v_float32x16, float, ps, __m256) +OPENCV_HAL_IMPL_AVX512_LOADSTORE_FLT(v_float64x8, double, pd, __m256d) + +#define OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, _Tpvecf, suffix, cast) \ + inline _Tpvec v_reinterpret_as_##suffix(const _Tpvecf& a) \ + { return _Tpvec(cast(a.val)); } + +#define OPENCV_HAL_IMPL_AVX512_INIT(_Tpvec, _Tp, suffix, ssuffix, ctype_s) \ + inline _Tpvec v512_setzero_##suffix() \ + { return _Tpvec(_mm512_setzero_si512()); } \ + inline _Tpvec v512_setall_##suffix(_Tp v) \ + { return _Tpvec(_mm512_set1_##ssuffix((ctype_s)v)); } \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint8x64, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int8x64, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint16x32, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int16x32, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint32x16, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int32x16, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint64x8, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int64x8, suffix, OPENCV_HAL_NOP) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_float32x16, suffix, _mm512_castps_si512) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_float64x8, suffix, _mm512_castpd_si512) + +OPENCV_HAL_IMPL_AVX512_INIT(v_uint8x64, uchar, u8, epi8, char) +OPENCV_HAL_IMPL_AVX512_INIT(v_int8x64, schar, s8, epi8, char) +OPENCV_HAL_IMPL_AVX512_INIT(v_uint16x32, ushort, u16, epi16, short) +OPENCV_HAL_IMPL_AVX512_INIT(v_int16x32, short, s16, epi16, short) +OPENCV_HAL_IMPL_AVX512_INIT(v_uint32x16, unsigned, u32, epi32, int) +OPENCV_HAL_IMPL_AVX512_INIT(v_int32x16, int, s32, epi32, int) +OPENCV_HAL_IMPL_AVX512_INIT(v_uint64x8, uint64, u64, epi64, int64) +OPENCV_HAL_IMPL_AVX512_INIT(v_int64x8, int64, s64, epi64, int64) + +#define OPENCV_HAL_IMPL_AVX512_INIT_FLT(_Tpvec, _Tp, suffix, zsuffix, cast) \ + inline _Tpvec v512_setzero_##suffix() \ + { return _Tpvec(_mm512_setzero_##zsuffix()); } \ + inline _Tpvec v512_setall_##suffix(_Tp v) \ + { return _Tpvec(_mm512_set1_##zsuffix(v)); } \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint8x64, suffix, cast) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int8x64, suffix, cast) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint16x32, suffix, cast) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int16x32, suffix, cast) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint32x16, suffix, cast) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int32x16, suffix, cast) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_uint64x8, suffix, cast) \ + OPENCV_HAL_IMPL_AVX512_CAST(_Tpvec, v_int64x8, suffix, cast) + +OPENCV_HAL_IMPL_AVX512_INIT_FLT(v_float32x16, float, f32, ps, _mm512_castsi512_ps) +OPENCV_HAL_IMPL_AVX512_INIT_FLT(v_float64x8, double, f64, pd, _mm512_castsi512_pd) + +inline v_float32x16 v_reinterpret_as_f32(const v_float32x16& a) +{ return a; } +inline v_float32x16 v_reinterpret_as_f32(const v_float64x8& a) +{ return v_float32x16(_mm512_castpd_ps(a.val)); } + +inline v_float64x8 v_reinterpret_as_f64(const v_float64x8& a) +{ return a; } +inline v_float64x8 v_reinterpret_as_f64(const v_float32x16& a) +{ return v_float64x8(_mm512_castps_pd(a.val)); } + +// FP16 +inline v_float32x16 v512_load_expand(const float16_t* ptr) +{ + return v_float32x16(_mm512_cvtph_ps(_mm256_loadu_si256((const __m256i*)ptr))); +} + +inline void v_pack_store(float16_t* ptr, const v_float32x16& a) +{ + __m256i ah = _mm512_cvtps_ph(a.val, 0); + _mm256_storeu_si256((__m256i*)ptr, ah); +} + +/* Recombine & ZIP */ +inline void v_zip(const v_int8x64& a, const v_int8x64& b, v_int8x64& ab0, v_int8x64& ab1) +{ +#if CV_AVX_512VBMI + __m512i mask0 = _v512_set_epu8( 95, 31, 94, 30, 93, 29, 92, 28, 91, 27, 90, 26, 89, 25, 88, 24, + 87, 23, 86, 22, 85, 21, 84, 20, 83, 19, 82, 18, 81, 17, 80, 16, + 79, 15, 78, 14, 77, 13, 76, 12, 75, 11, 74, 10, 73, 9, 72, 8, + 71, 7, 70, 6, 69, 5, 68, 4, 67, 3, 66, 2, 65, 1, 64, 0); + ab0 = v_int8x64(_mm512_permutex2var_epi8(a.val, mask0, b.val)); + __m512i mask1 = _v512_set_epu8(127, 63, 126, 62, 125, 61, 124, 60, 123, 59, 122, 58, 121, 57, 120, 56, + 119, 55, 118, 54, 117, 53, 116, 52, 115, 51, 114, 50, 113, 49, 112, 48, + 111, 47, 110, 46, 109, 45, 108, 44, 107, 43, 106, 42, 105, 41, 104, 40, + 103, 39, 102, 38, 101, 37, 100, 36, 99, 35, 98, 34, 97, 33, 96, 32); + ab1 = v_int8x64(_mm512_permutex2var_epi8(a.val, mask1, b.val)); +#else + __m512i low = _mm512_unpacklo_epi8(a.val, b.val); + __m512i high = _mm512_unpackhi_epi8(a.val, b.val); + ab0 = v_int8x64(_mm512_permutex2var_epi64(low, _v512_set_epu64(11, 10, 3, 2, 9, 8, 1, 0), high)); + ab1 = v_int8x64(_mm512_permutex2var_epi64(low, _v512_set_epu64(15, 14, 7, 6, 13, 12, 5, 4), high)); +#endif +} +inline void v_zip(const v_int16x32& a, const v_int16x32& b, v_int16x32& ab0, v_int16x32& ab1) +{ + __m512i mask0 = _v512_set_epu16(47, 15, 46, 14, 45, 13, 44, 12, 43, 11, 42, 10, 41, 9, 40, 8, + 39, 7, 38, 6, 37, 5, 36, 4, 35, 3, 34, 2, 33, 1, 32, 0); + ab0 = v_int16x32(_mm512_permutex2var_epi16(a.val, mask0, b.val)); + __m512i mask1 = _v512_set_epu16(63, 31, 62, 30, 61, 29, 60, 28, 59, 27, 58, 26, 57, 25, 56, 24, + 55, 23, 54, 22, 53, 21, 52, 20, 51, 19, 50, 18, 49, 17, 48, 16); + ab1 = v_int16x32(_mm512_permutex2var_epi16(a.val, mask1, b.val)); +} +inline void v_zip(const v_int32x16& a, const v_int32x16& b, v_int32x16& ab0, v_int32x16& ab1) +{ + __m512i mask0 = _v512_set_epu32(23, 7, 22, 6, 21, 5, 20, 4, 19, 3, 18, 2, 17, 1, 16, 0); + ab0 = v_int32x16(_mm512_permutex2var_epi32(a.val, mask0, b.val)); + __m512i mask1 = _v512_set_epu32(31, 15, 30, 14, 29, 13, 28, 12, 27, 11, 26, 10, 25, 9, 24, 8); + ab1 = v_int32x16(_mm512_permutex2var_epi32(a.val, mask1, b.val)); +} +inline void v_zip(const v_int64x8& a, const v_int64x8& b, v_int64x8& ab0, v_int64x8& ab1) +{ + __m512i mask0 = _v512_set_epu64(11, 3, 10, 2, 9, 1, 8, 0); + ab0 = v_int64x8(_mm512_permutex2var_epi64(a.val, mask0, b.val)); + __m512i mask1 = _v512_set_epu64(15, 7, 14, 6, 13, 5, 12, 4); + ab1 = v_int64x8(_mm512_permutex2var_epi64(a.val, mask1, b.val)); +} + +inline void v_zip(const v_uint8x64& a, const v_uint8x64& b, v_uint8x64& ab0, v_uint8x64& ab1) +{ + v_int8x64 i0, i1; + v_zip(v_reinterpret_as_s8(a), v_reinterpret_as_s8(b), i0, i1); + ab0 = v_reinterpret_as_u8(i0); + ab1 = v_reinterpret_as_u8(i1); +} +inline void v_zip(const v_uint16x32& a, const v_uint16x32& b, v_uint16x32& ab0, v_uint16x32& ab1) +{ + v_int16x32 i0, i1; + v_zip(v_reinterpret_as_s16(a), v_reinterpret_as_s16(b), i0, i1); + ab0 = v_reinterpret_as_u16(i0); + ab1 = v_reinterpret_as_u16(i1); +} +inline void v_zip(const v_uint32x16& a, const v_uint32x16& b, v_uint32x16& ab0, v_uint32x16& ab1) +{ + v_int32x16 i0, i1; + v_zip(v_reinterpret_as_s32(a), v_reinterpret_as_s32(b), i0, i1); + ab0 = v_reinterpret_as_u32(i0); + ab1 = v_reinterpret_as_u32(i1); +} +inline void v_zip(const v_uint64x8& a, const v_uint64x8& b, v_uint64x8& ab0, v_uint64x8& ab1) +{ + v_int64x8 i0, i1; + v_zip(v_reinterpret_as_s64(a), v_reinterpret_as_s64(b), i0, i1); + ab0 = v_reinterpret_as_u64(i0); + ab1 = v_reinterpret_as_u64(i1); +} +inline void v_zip(const v_float32x16& a, const v_float32x16& b, v_float32x16& ab0, v_float32x16& ab1) +{ + v_int32x16 i0, i1; + v_zip(v_reinterpret_as_s32(a), v_reinterpret_as_s32(b), i0, i1); + ab0 = v_reinterpret_as_f32(i0); + ab1 = v_reinterpret_as_f32(i1); +} +inline void v_zip(const v_float64x8& a, const v_float64x8& b, v_float64x8& ab0, v_float64x8& ab1) +{ + v_int64x8 i0, i1; + v_zip(v_reinterpret_as_s64(a), v_reinterpret_as_s64(b), i0, i1); + ab0 = v_reinterpret_as_f64(i0); + ab1 = v_reinterpret_as_f64(i1); +} + +#define OPENCV_HAL_IMPL_AVX512_COMBINE(_Tpvec, suffix) \ + inline _Tpvec v_combine_low(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_v512_combine(_v512_extract_low(a.val), _v512_extract_low(b.val))); } \ + inline _Tpvec v_combine_high(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_v512_insert(b.val, _v512_extract_high(a.val))); } \ + inline void v_recombine(const _Tpvec& a, const _Tpvec& b, \ + _Tpvec& c, _Tpvec& d) \ + { \ + c.val = _v512_combine(_v512_extract_low(a.val),_v512_extract_low(b.val)); \ + d.val = _v512_insert(b.val,_v512_extract_high(a.val)); \ + } + + +OPENCV_HAL_IMPL_AVX512_COMBINE(v_uint8x64, epi8) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_int8x64, epi8) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_uint16x32, epi16) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_int16x32, epi16) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_uint32x16, epi32) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_int32x16, epi32) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_uint64x8, epi64) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_int64x8, epi64) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_float32x16, ps) +OPENCV_HAL_IMPL_AVX512_COMBINE(v_float64x8, pd) + +////////// Arithmetic, bitwise and comparison operations ///////// + +/* Element-wise binary and unary operations */ + +/** Non-saturating arithmetics **/ +#define OPENCV_HAL_IMPL_AVX512_BIN_FUNC(func, _Tpvec, intrin) \ + inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(intrin(a.val, b.val)); } + +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_add_wrap, v_uint8x64, _mm512_add_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_add_wrap, v_int8x64, _mm512_add_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_add_wrap, v_uint16x32, _mm512_add_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_add_wrap, v_int16x32, _mm512_add_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_sub_wrap, v_uint8x64, _mm512_sub_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_sub_wrap, v_int8x64, _mm512_sub_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_sub_wrap, v_uint16x32, _mm512_sub_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_sub_wrap, v_int16x32, _mm512_sub_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_mul_wrap, v_uint16x32, _mm512_mullo_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_mul_wrap, v_int16x32, _mm512_mullo_epi16) + +inline v_uint8x64 v_mul_wrap(const v_uint8x64& a, const v_uint8x64& b) +{ + __m512i ad = _mm512_srai_epi16(a.val, 8); + __m512i bd = _mm512_srai_epi16(b.val, 8); + __m512i p0 = _mm512_mullo_epi16(a.val, b.val); // even + __m512i p1 = _mm512_slli_epi16(_mm512_mullo_epi16(ad, bd), 8); // odd + return v_uint8x64(_mm512_mask_blend_epi8(0xAAAAAAAAAAAAAAAA, p0, p1)); +} +inline v_int8x64 v_mul_wrap(const v_int8x64& a, const v_int8x64& b) +{ + return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b))); +} + +#define OPENCV_HAL_IMPL_AVX512_BIN_OP(bin_op, _Tpvec, intrin) \ + inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(intrin(a.val, b.val)); } \ + inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ + { a.val = intrin(a.val, b.val); return a; } + +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_uint32x16, _mm512_add_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_uint32x16, _mm512_sub_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_int32x16, _mm512_add_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_int32x16, _mm512_sub_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_uint64x8, _mm512_add_epi64) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_uint64x8, _mm512_sub_epi64) +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_int64x8, _mm512_add_epi64) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_int64x8, _mm512_sub_epi64) + +OPENCV_HAL_IMPL_AVX512_BIN_OP(*, v_uint32x16, _mm512_mullo_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_OP(*, v_int32x16, _mm512_mullo_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_OP(*, v_uint64x8, _mm512_mullo_epi64) +OPENCV_HAL_IMPL_AVX512_BIN_OP(*, v_int64x8, _mm512_mullo_epi64) + +/** Saturating arithmetics **/ +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_uint8x64, _mm512_adds_epu8) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_uint8x64, _mm512_subs_epu8) +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_int8x64, _mm512_adds_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_int8x64, _mm512_subs_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_uint16x32, _mm512_adds_epu16) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_uint16x32, _mm512_subs_epu16) +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_int16x32, _mm512_adds_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_int16x32, _mm512_subs_epi16) + +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_float32x16, _mm512_add_ps) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_float32x16, _mm512_sub_ps) +OPENCV_HAL_IMPL_AVX512_BIN_OP(*, v_float32x16, _mm512_mul_ps) +OPENCV_HAL_IMPL_AVX512_BIN_OP(/, v_float32x16, _mm512_div_ps) +OPENCV_HAL_IMPL_AVX512_BIN_OP(+, v_float64x8, _mm512_add_pd) +OPENCV_HAL_IMPL_AVX512_BIN_OP(-, v_float64x8, _mm512_sub_pd) +OPENCV_HAL_IMPL_AVX512_BIN_OP(*, v_float64x8, _mm512_mul_pd) +OPENCV_HAL_IMPL_AVX512_BIN_OP(/, v_float64x8, _mm512_div_pd) + +// saturating multiply +inline v_uint8x64 operator * (const v_uint8x64& a, const v_uint8x64& b) +{ + v_uint16x32 c, d; + v_mul_expand(a, b, c, d); + return v_pack(c, d); +} +inline v_int8x64 operator * (const v_int8x64& a, const v_int8x64& b) +{ + v_int16x32 c, d; + v_mul_expand(a, b, c, d); + return v_pack(c, d); +} +inline v_uint16x32 operator * (const v_uint16x32& a, const v_uint16x32& b) +{ + __m512i pl = _mm512_mullo_epi16(a.val, b.val); + __m512i ph = _mm512_mulhi_epu16(a.val, b.val); + __m512i p0 = _mm512_unpacklo_epi16(pl, ph); + __m512i p1 = _mm512_unpackhi_epi16(pl, ph); + + const __m512i m = _mm512_set1_epi32(65535); + return v_uint16x32(_mm512_packus_epi32(_mm512_min_epu32(p0, m), _mm512_min_epu32(p1, m))); +} +inline v_int16x32 operator * (const v_int16x32& a, const v_int16x32& b) +{ + __m512i pl = _mm512_mullo_epi16(a.val, b.val); + __m512i ph = _mm512_mulhi_epi16(a.val, b.val); + __m512i p0 = _mm512_unpacklo_epi16(pl, ph); + __m512i p1 = _mm512_unpackhi_epi16(pl, ph); + return v_int16x32(_mm512_packs_epi32(p0, p1)); +} + +inline v_uint8x64& operator *= (v_uint8x64& a, const v_uint8x64& b) +{ a = a * b; return a; } +inline v_int8x64& operator *= (v_int8x64& a, const v_int8x64& b) +{ a = a * b; return a; } +inline v_uint16x32& operator *= (v_uint16x32& a, const v_uint16x32& b) +{ a = a * b; return a; } +inline v_int16x32& operator *= (v_int16x32& a, const v_int16x32& b) +{ a = a * b; return a; } + +inline v_int16x32 v_mul_hi(const v_int16x32& a, const v_int16x32& b) { return v_int16x32(_mm512_mulhi_epi16(a.val, b.val)); } +inline v_uint16x32 v_mul_hi(const v_uint16x32& a, const v_uint16x32& b) { return v_uint16x32(_mm512_mulhi_epu16(a.val, b.val)); } + +// Multiply and expand +inline void v_mul_expand(const v_uint8x64& a, const v_uint8x64& b, + v_uint16x32& c, v_uint16x32& d) +{ + v_uint16x32 a0, a1, b0, b1; + v_expand(a, a0, a1); + v_expand(b, b0, b1); + c = v_mul_wrap(a0, b0); + d = v_mul_wrap(a1, b1); +} + +inline void v_mul_expand(const v_int8x64& a, const v_int8x64& b, + v_int16x32& c, v_int16x32& d) +{ + v_int16x32 a0, a1, b0, b1; + v_expand(a, a0, a1); + v_expand(b, b0, b1); + c = v_mul_wrap(a0, b0); + d = v_mul_wrap(a1, b1); +} + +inline void v_mul_expand(const v_int16x32& a, const v_int16x32& b, + v_int32x16& c, v_int32x16& d) +{ + v_int16x32 v0, v1; + v_zip(v_mul_wrap(a, b), v_mul_hi(a, b), v0, v1); + + c = v_reinterpret_as_s32(v0); + d = v_reinterpret_as_s32(v1); +} + +inline void v_mul_expand(const v_uint16x32& a, const v_uint16x32& b, + v_uint32x16& c, v_uint32x16& d) +{ + v_uint16x32 v0, v1; + v_zip(v_mul_wrap(a, b), v_mul_hi(a, b), v0, v1); + + c = v_reinterpret_as_u32(v0); + d = v_reinterpret_as_u32(v1); +} + +inline void v_mul_expand(const v_uint32x16& a, const v_uint32x16& b, + v_uint64x8& c, v_uint64x8& d) +{ + v_zip(v_uint64x8(_mm512_mul_epu32(a.val, b.val)), + v_uint64x8(_mm512_mul_epu32(_mm512_srli_epi64(a.val, 32), _mm512_srli_epi64(b.val, 32))), c, d); +} + +inline void v_mul_expand(const v_int32x16& a, const v_int32x16& b, + v_int64x8& c, v_int64x8& d) +{ + v_zip(v_int64x8(_mm512_mul_epi32(a.val, b.val)), + v_int64x8(_mm512_mul_epi32(_mm512_srli_epi64(a.val, 32), _mm512_srli_epi64(b.val, 32))), c, d); +} + +/** Bitwise shifts **/ +#define OPENCV_HAL_IMPL_AVX512_SHIFT_OP(_Tpuvec, _Tpsvec, suffix) \ + inline _Tpuvec operator << (const _Tpuvec& a, int imm) \ + { return _Tpuvec(_mm512_slli_##suffix(a.val, imm)); } \ + inline _Tpsvec operator << (const _Tpsvec& a, int imm) \ + { return _Tpsvec(_mm512_slli_##suffix(a.val, imm)); } \ + inline _Tpuvec operator >> (const _Tpuvec& a, int imm) \ + { return _Tpuvec(_mm512_srli_##suffix(a.val, imm)); } \ + inline _Tpsvec operator >> (const _Tpsvec& a, int imm) \ + { return _Tpsvec(_mm512_srai_##suffix(a.val, imm)); } \ + template \ + inline _Tpuvec v_shl(const _Tpuvec& a) \ + { return _Tpuvec(_mm512_slli_##suffix(a.val, imm)); } \ + template \ + inline _Tpsvec v_shl(const _Tpsvec& a) \ + { return _Tpsvec(_mm512_slli_##suffix(a.val, imm)); } \ + template \ + inline _Tpuvec v_shr(const _Tpuvec& a) \ + { return _Tpuvec(_mm512_srli_##suffix(a.val, imm)); } \ + template \ + inline _Tpsvec v_shr(const _Tpsvec& a) \ + { return _Tpsvec(_mm512_srai_##suffix(a.val, imm)); } + +OPENCV_HAL_IMPL_AVX512_SHIFT_OP(v_uint16x32, v_int16x32, epi16) +OPENCV_HAL_IMPL_AVX512_SHIFT_OP(v_uint32x16, v_int32x16, epi32) +OPENCV_HAL_IMPL_AVX512_SHIFT_OP(v_uint64x8, v_int64x8, epi64) + + +/** Bitwise logic **/ +#define OPENCV_HAL_IMPL_AVX512_LOGIC_OP(_Tpvec, suffix, not_const) \ + OPENCV_HAL_IMPL_AVX512_BIN_OP(&, _Tpvec, _mm512_and_##suffix) \ + OPENCV_HAL_IMPL_AVX512_BIN_OP(|, _Tpvec, _mm512_or_##suffix) \ + OPENCV_HAL_IMPL_AVX512_BIN_OP(^, _Tpvec, _mm512_xor_##suffix) \ + inline _Tpvec operator ~ (const _Tpvec& a) \ + { return _Tpvec(_mm512_xor_##suffix(a.val, not_const)); } + +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_uint8x64, si512, _mm512_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_int8x64, si512, _mm512_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_uint16x32, si512, _mm512_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_int16x32, si512, _mm512_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_uint32x16, si512, _mm512_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_int32x16, si512, _mm512_set1_epi32(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_uint64x8, si512, _mm512_set1_epi64(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_int64x8, si512, _mm512_set1_epi64(-1)) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_float32x16, ps, _mm512_castsi512_ps(_mm512_set1_epi32(-1))) +OPENCV_HAL_IMPL_AVX512_LOGIC_OP(v_float64x8, pd, _mm512_castsi512_pd(_mm512_set1_epi32(-1))) + +/** Select **/ +#define OPENCV_HAL_IMPL_AVX512_SELECT(_Tpvec, suffix, zsuf) \ + inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm512_mask_blend_##suffix(_mm512_cmp_##suffix##_mask(mask.val, _mm512_setzero_##zsuf(), _MM_CMPINT_EQ), a.val, b.val)); } + +OPENCV_HAL_IMPL_AVX512_SELECT(v_uint8x64, epi8, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_int8x64, epi8, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_uint16x32, epi16, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_int16x32, epi16, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_uint32x16, epi32, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_int32x16, epi32, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_uint64x8, epi64, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_int64x8, epi64, si512) +OPENCV_HAL_IMPL_AVX512_SELECT(v_float32x16, ps, ps) +OPENCV_HAL_IMPL_AVX512_SELECT(v_float64x8, pd, pd) + +/** Comparison **/ +#define OPENCV_HAL_IMPL_AVX512_CMP_INT(bin_op, imm8, _Tpvec, sufcmp, sufset, tval) \ + inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm512_maskz_set1_##sufset(_mm512_cmp_##sufcmp##_mask(a.val, b.val, imm8), tval)); } + +#define OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(_Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_INT(==, _MM_CMPINT_EQ, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_INT(!=, _MM_CMPINT_NE, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_INT(<, _MM_CMPINT_LT, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_INT(>, _MM_CMPINT_NLE, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_INT(<=, _MM_CMPINT_LE, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_INT(>=, _MM_CMPINT_NLT, _Tpvec, sufcmp, sufset, tval) + +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_uint8x64, epu8, epi8, (char)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_int8x64, epi8, epi8, (char)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_uint16x32, epu16, epi16, (short)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_int16x32, epi16, epi16, (short)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_uint32x16, epu32, epi32, (int)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_int32x16, epi32, epi32, (int)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_uint64x8, epu64, epi64, (int64)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_INT(v_int64x8, epi64, epi64, (int64)-1) + +#define OPENCV_HAL_IMPL_AVX512_CMP_FLT(bin_op, imm8, _Tpvec, sufcmp, sufset, tval) \ + inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ + { return _Tpvec(_mm512_castsi512_##sufcmp(_mm512_maskz_set1_##sufset(_mm512_cmp_##sufcmp##_mask(a.val, b.val, imm8), tval))); } + +#define OPENCV_HAL_IMPL_AVX512_CMP_OP_FLT(_Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_FLT(==, _CMP_EQ_OQ, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_FLT(!=, _CMP_NEQ_OQ, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_FLT(<, _CMP_LT_OQ, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_FLT(>, _CMP_GT_OQ, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_FLT(<=, _CMP_LE_OQ, _Tpvec, sufcmp, sufset, tval) \ + OPENCV_HAL_IMPL_AVX512_CMP_FLT(>=, _CMP_GE_OQ, _Tpvec, sufcmp, sufset, tval) + +OPENCV_HAL_IMPL_AVX512_CMP_OP_FLT(v_float32x16, ps, epi32, (int)-1) +OPENCV_HAL_IMPL_AVX512_CMP_OP_FLT(v_float64x8, pd, epi64, (int64)-1) + +inline v_float32x16 v_not_nan(const v_float32x16& a) +{ return v_float32x16(_mm512_castsi512_ps(_mm512_maskz_set1_epi32(_mm512_cmp_ps_mask(a.val, a.val, _CMP_ORD_Q), (int)-1))); } +inline v_float64x8 v_not_nan(const v_float64x8& a) +{ return v_float64x8(_mm512_castsi512_pd(_mm512_maskz_set1_epi64(_mm512_cmp_pd_mask(a.val, a.val, _CMP_ORD_Q), (int64)-1))); } + +/** min/max **/ +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_uint8x64, _mm512_min_epu8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_uint8x64, _mm512_max_epu8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_int8x64, _mm512_min_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_int8x64, _mm512_max_epi8) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_uint16x32, _mm512_min_epu16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_uint16x32, _mm512_max_epu16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_int16x32, _mm512_min_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_int16x32, _mm512_max_epi16) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_uint32x16, _mm512_min_epu32) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_uint32x16, _mm512_max_epu32) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_int32x16, _mm512_min_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_int32x16, _mm512_max_epi32) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_uint64x8, _mm512_min_epu64) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_uint64x8, _mm512_max_epu64) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_int64x8, _mm512_min_epi64) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_int64x8, _mm512_max_epi64) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_float32x16, _mm512_min_ps) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_float32x16, _mm512_max_ps) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_min, v_float64x8, _mm512_min_pd) +OPENCV_HAL_IMPL_AVX512_BIN_FUNC(v_max, v_float64x8, _mm512_max_pd) + +/** Rotate **/ +namespace { + template + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64&, const v_int8x64&) { return v_int8x64(); }}; + template + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64& a, const v_int8x64& b) + { + return v_int8x64(_mm512_or_si512(_mm512_srli_epi32(_mm512_alignr_epi32(b.val, a.val, imm32 ), imm4 *8), + _mm512_slli_epi32(_mm512_alignr_epi32(b.val, a.val, imm32 + 1), (4-imm4)*8))); + }}; + template + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64& a, const v_int8x64& b) + { + return v_int8x64(_mm512_or_si512(_mm512_srli_epi32(_mm512_alignr_epi32(b.val, a.val, 15), imm4 *8), + _mm512_slli_epi32( b.val, (4-imm4)*8))); + }}; + template + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64&, const v_int8x64& b) + { + return v_int8x64(_mm512_or_si512(_mm512_srli_epi32(_mm512_alignr_epi32(_mm512_setzero_si512(), b.val, imm32 - 16), imm4 *8), + _mm512_slli_epi32(_mm512_alignr_epi32(_mm512_setzero_si512(), b.val, imm32 - 15), (4-imm4)*8))); + }}; + template + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64&, const v_int8x64& b) + { return v_int8x64(_mm512_srli_epi32(_mm512_alignr_epi32(_mm512_setzero_si512(), b.val, 15), imm4*8)); }}; + template + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64& a, const v_int8x64& b) + { return v_int8x64(_mm512_alignr_epi32(b.val, a.val, imm32)); }}; + template<> + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64& a, const v_int8x64&) { return a; }}; + template + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64&, const v_int8x64& b) + { return v_int8x64(_mm512_alignr_epi32(_mm512_setzero_si512(), b.val, imm32 - 16)); }}; + template<> + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64&, const v_int8x64& b) { return b; }}; + template<> + struct _v_rotate_right { static inline v_int8x64 eval(const v_int8x64&, const v_int8x64&) { return v_int8x64(); }}; +} +template inline v_int8x64 v_rotate_right(const v_int8x64& a, const v_int8x64& b) +{ + return imm >= 128 ? v_int8x64() : +#if CV_AVX_512VBMI + v_int8x64(_mm512_permutex2var_epi8(a.val, + _v512_set_epu8(0x3f + imm, 0x3e + imm, 0x3d + imm, 0x3c + imm, 0x3b + imm, 0x3a + imm, 0x39 + imm, 0x38 + imm, + 0x37 + imm, 0x36 + imm, 0x35 + imm, 0x34 + imm, 0x33 + imm, 0x32 + imm, 0x31 + imm, 0x30 + imm, + 0x2f + imm, 0x2e + imm, 0x2d + imm, 0x2c + imm, 0x2b + imm, 0x2a + imm, 0x29 + imm, 0x28 + imm, + 0x27 + imm, 0x26 + imm, 0x25 + imm, 0x24 + imm, 0x23 + imm, 0x22 + imm, 0x21 + imm, 0x20 + imm, + 0x1f + imm, 0x1e + imm, 0x1d + imm, 0x1c + imm, 0x1b + imm, 0x1a + imm, 0x19 + imm, 0x18 + imm, + 0x17 + imm, 0x16 + imm, 0x15 + imm, 0x14 + imm, 0x13 + imm, 0x12 + imm, 0x11 + imm, 0x10 + imm, + 0x0f + imm, 0x0e + imm, 0x0d + imm, 0x0c + imm, 0x0b + imm, 0x0a + imm, 0x09 + imm, 0x08 + imm, + 0x07 + imm, 0x06 + imm, 0x05 + imm, 0x04 + imm, 0x03 + imm, 0x02 + imm, 0x01 + imm, 0x00 + imm), b.val)); +#else + _v_rotate_right 15), imm/4>::eval(a, b); +#endif +} +template +inline v_int8x64 v_rotate_left(const v_int8x64& a, const v_int8x64& b) +{ + if (imm == 0) return a; + if (imm == 64) return b; + if (imm >= 128) return v_int8x64(); +#if CV_AVX_512VBMI + return v_int8x64(_mm512_permutex2var_epi8(b.val, + _v512_set_epi8(0x7f - imm,0x7e - imm,0x7d - imm,0x7c - imm,0x7b - imm,0x7a - imm,0x79 - imm,0x78 - imm, + 0x77 - imm,0x76 - imm,0x75 - imm,0x74 - imm,0x73 - imm,0x72 - imm,0x71 - imm,0x70 - imm, + 0x6f - imm,0x6e - imm,0x6d - imm,0x6c - imm,0x6b - imm,0x6a - imm,0x69 - imm,0x68 - imm, + 0x67 - imm,0x66 - imm,0x65 - imm,0x64 - imm,0x63 - imm,0x62 - imm,0x61 - imm,0x60 - imm, + 0x5f - imm,0x5e - imm,0x5d - imm,0x5c - imm,0x5b - imm,0x5a - imm,0x59 - imm,0x58 - imm, + 0x57 - imm,0x56 - imm,0x55 - imm,0x54 - imm,0x53 - imm,0x52 - imm,0x51 - imm,0x50 - imm, + 0x4f - imm,0x4e - imm,0x4d - imm,0x4c - imm,0x4b - imm,0x4a - imm,0x49 - imm,0x48 - imm, + 0x47 - imm,0x46 - imm,0x45 - imm,0x44 - imm,0x43 - imm,0x42 - imm,0x41 - imm,0x40 - imm), a.val)); +#else + return imm < 64 ? v_rotate_right<64 - imm>(b, a) : v_rotate_right<128 - imm>(v512_setzero_s8(), b); +#endif +} +template +inline v_int8x64 v_rotate_right(const v_int8x64& a) +{ + if (imm == 0) return a; + if (imm >= 64) return v_int8x64(); +#if CV_AVX_512VBMI + return v_int8x64(_mm512_maskz_permutexvar_epi8(0xFFFFFFFFFFFFFFFF >> imm, + _v512_set_epu8(0x3f + imm,0x3e + imm,0x3d + imm,0x3c + imm,0x3b + imm,0x3a + imm,0x39 + imm,0x38 + imm, + 0x37 + imm,0x36 + imm,0x35 + imm,0x34 + imm,0x33 + imm,0x32 + imm,0x31 + imm,0x30 + imm, + 0x2f + imm,0x2e + imm,0x2d + imm,0x2c + imm,0x2b + imm,0x2a + imm,0x29 + imm,0x28 + imm, + 0x27 + imm,0x26 + imm,0x25 + imm,0x24 + imm,0x23 + imm,0x22 + imm,0x21 + imm,0x20 + imm, + 0x1f + imm,0x1e + imm,0x1d + imm,0x1c + imm,0x1b + imm,0x1a + imm,0x19 + imm,0x18 + imm, + 0x17 + imm,0x16 + imm,0x15 + imm,0x14 + imm,0x13 + imm,0x12 + imm,0x11 + imm,0x10 + imm, + 0x0f + imm,0x0e + imm,0x0d + imm,0x0c + imm,0x0b + imm,0x0a + imm,0x09 + imm,0x08 + imm, + 0x07 + imm,0x06 + imm,0x05 + imm,0x04 + imm,0x03 + imm,0x02 + imm,0x01 + imm,0x00 + imm), a.val)); +#else + return v_rotate_right(a, v512_setzero_s8()); +#endif +} +template +inline v_int8x64 v_rotate_left(const v_int8x64& a) +{ + if (imm == 0) return a; + if (imm >= 64) return v_int8x64(); +#if CV_AVX_512VBMI + return v_int8x64(_mm512_maskz_permutexvar_epi8(0xFFFFFFFFFFFFFFFF << imm, + _v512_set_epi8(0x3f - imm,0x3e - imm,0x3d - imm,0x3c - imm,0x3b - imm,0x3a - imm,0x39 - imm,0x38 - imm, + 0x37 - imm,0x36 - imm,0x35 - imm,0x34 - imm,0x33 - imm,0x32 - imm,0x31 - imm,0x30 - imm, + 0x2f - imm,0x2e - imm,0x2d - imm,0x2c - imm,0x2b - imm,0x2a - imm,0x29 - imm,0x28 - imm, + 0x27 - imm,0x26 - imm,0x25 - imm,0x24 - imm,0x23 - imm,0x22 - imm,0x21 - imm,0x20 - imm, + 0x1f - imm,0x1e - imm,0x1d - imm,0x1c - imm,0x1b - imm,0x1a - imm,0x19 - imm,0x18 - imm, + 0x17 - imm,0x16 - imm,0x15 - imm,0x14 - imm,0x13 - imm,0x12 - imm,0x11 - imm,0x10 - imm, + 0x0f - imm,0x0e - imm,0x0d - imm,0x0c - imm,0x0b - imm,0x0a - imm,0x09 - imm,0x08 - imm, + 0x07 - imm,0x06 - imm,0x05 - imm,0x04 - imm,0x03 - imm,0x02 - imm,0x01 - imm,0x00 - imm), a.val)); +#else + return v_rotate_right<64 - imm>(v512_setzero_s8(), a); +#endif +} + +#define OPENCV_HAL_IMPL_AVX512_ROTATE_PM(_Tpvec, suffix) \ +template inline _Tpvec v_rotate_left(const _Tpvec& a, const _Tpvec& b) \ +{ return v_reinterpret_as_##suffix(v_rotate_left(v_reinterpret_as_s8(a), v_reinterpret_as_s8(b))); } \ +template inline _Tpvec v_rotate_right(const _Tpvec& a, const _Tpvec& b) \ +{ return v_reinterpret_as_##suffix(v_rotate_right(v_reinterpret_as_s8(a), v_reinterpret_as_s8(b))); } \ +template inline _Tpvec v_rotate_left(const _Tpvec& a) \ +{ return v_reinterpret_as_##suffix(v_rotate_left(v_reinterpret_as_s8(a))); } \ +template inline _Tpvec v_rotate_right(const _Tpvec& a) \ +{ return v_reinterpret_as_##suffix(v_rotate_right(v_reinterpret_as_s8(a))); } + +#define OPENCV_HAL_IMPL_AVX512_ROTATE_EC(_Tpvec, suffix) \ +template \ +inline _Tpvec v_rotate_left(const _Tpvec& a, const _Tpvec& b) \ +{ \ + enum { SHIFT2 = (_Tpvec::nlanes - imm) }; \ + enum { MASK = ((1 << _Tpvec::nlanes) - 1) }; \ + if (imm == 0) return a; \ + if (imm == _Tpvec::nlanes) return b; \ + if (imm >= 2*_Tpvec::nlanes) return _Tpvec(); \ + return _Tpvec(_mm512_mask_expand_##suffix(_mm512_maskz_compress_##suffix((MASK << SHIFT2)&MASK, b.val), (MASK << (imm))&MASK, a.val)); \ +} \ +template \ +inline _Tpvec v_rotate_right(const _Tpvec& a, const _Tpvec& b) \ +{ \ + enum { SHIFT2 = (_Tpvec::nlanes - imm) }; \ + enum { MASK = ((1 << _Tpvec::nlanes) - 1) }; \ + if (imm == 0) return a; \ + if (imm == _Tpvec::nlanes) return b; \ + if (imm >= 2*_Tpvec::nlanes) return _Tpvec(); \ + return _Tpvec(_mm512_mask_expand_##suffix(_mm512_maskz_compress_##suffix((MASK << (imm))&MASK, a.val), (MASK << SHIFT2)&MASK, b.val)); \ +} \ +template \ +inline _Tpvec v_rotate_left(const _Tpvec& a) \ +{ \ + if (imm == 0) return a; \ + if (imm >= _Tpvec::nlanes) return _Tpvec(); \ + return _Tpvec(_mm512_maskz_expand_##suffix((1 << _Tpvec::nlanes) - (1 << (imm)), a.val)); \ +} \ +template \ +inline _Tpvec v_rotate_right(const _Tpvec& a) \ +{ \ + if (imm == 0) return a; \ + if (imm >= _Tpvec::nlanes) return _Tpvec(); \ + return _Tpvec(_mm512_maskz_compress_##suffix((1 << _Tpvec::nlanes) - (1 << (imm)), a.val)); \ +} + +OPENCV_HAL_IMPL_AVX512_ROTATE_PM(v_uint8x64, u8) +OPENCV_HAL_IMPL_AVX512_ROTATE_PM(v_uint16x32, u16) +OPENCV_HAL_IMPL_AVX512_ROTATE_PM(v_int16x32, s16) +OPENCV_HAL_IMPL_AVX512_ROTATE_EC(v_uint32x16, epi32) +OPENCV_HAL_IMPL_AVX512_ROTATE_EC(v_int32x16, epi32) +OPENCV_HAL_IMPL_AVX512_ROTATE_EC(v_uint64x8, epi64) +OPENCV_HAL_IMPL_AVX512_ROTATE_EC(v_int64x8, epi64) +OPENCV_HAL_IMPL_AVX512_ROTATE_EC(v_float32x16, ps) +OPENCV_HAL_IMPL_AVX512_ROTATE_EC(v_float64x8, pd) + +////////// Reduce ///////// + +/** Reduce **/ +#define OPENCV_HAL_IMPL_AVX512_REDUCE_ADD64(a, b) a + b +#define OPENCV_HAL_IMPL_AVX512_REDUCE_8(sctype, func, _Tpvec, ifunc, scop) \ + inline sctype v_reduce_##func(const _Tpvec& a) \ + { __m256i half = _mm256_##ifunc(_v512_extract_low(a.val), _v512_extract_high(a.val)); \ + sctype CV_DECL_ALIGNED(64) idx[2]; \ + _mm_store_si128((__m128i*)idx, _mm_##ifunc(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1))); \ + return scop(idx[0], idx[1]); } +OPENCV_HAL_IMPL_AVX512_REDUCE_8(uint64, min, v_uint64x8, min_epu64, min) +OPENCV_HAL_IMPL_AVX512_REDUCE_8(uint64, max, v_uint64x8, max_epu64, max) +OPENCV_HAL_IMPL_AVX512_REDUCE_8(uint64, sum, v_uint64x8, add_epi64, OPENCV_HAL_IMPL_AVX512_REDUCE_ADD64) +OPENCV_HAL_IMPL_AVX512_REDUCE_8(int64, min, v_int64x8, min_epi64, min) +OPENCV_HAL_IMPL_AVX512_REDUCE_8(int64, max, v_int64x8, max_epi64, max) +OPENCV_HAL_IMPL_AVX512_REDUCE_8(int64, sum, v_int64x8, add_epi64, OPENCV_HAL_IMPL_AVX512_REDUCE_ADD64) + +#define OPENCV_HAL_IMPL_AVX512_REDUCE_8F(func, ifunc, scop) \ + inline double v_reduce_##func(const v_float64x8& a) \ + { __m256d half = _mm256_##ifunc(_v512_extract_low(a.val), _v512_extract_high(a.val)); \ + double CV_DECL_ALIGNED(64) idx[2]; \ + _mm_store_pd(idx, _mm_##ifunc(_mm256_castpd256_pd128(half), _mm256_extractf128_pd(half, 1))); \ + return scop(idx[0], idx[1]); } +OPENCV_HAL_IMPL_AVX512_REDUCE_8F(min, min_pd, min) +OPENCV_HAL_IMPL_AVX512_REDUCE_8F(max, max_pd, max) +OPENCV_HAL_IMPL_AVX512_REDUCE_8F(sum, add_pd, OPENCV_HAL_IMPL_AVX512_REDUCE_ADD64) + +#define OPENCV_HAL_IMPL_AVX512_REDUCE_16(sctype, func, _Tpvec, ifunc) \ + inline sctype v_reduce_##func(const _Tpvec& a) \ + { __m256i half = _mm256_##ifunc(_v512_extract_low(a.val), _v512_extract_high(a.val)); \ + __m128i quarter = _mm_##ifunc(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 8)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 4)); \ + return (sctype)_mm_cvtsi128_si32(quarter); } +OPENCV_HAL_IMPL_AVX512_REDUCE_16(uint, min, v_uint32x16, min_epu32) +OPENCV_HAL_IMPL_AVX512_REDUCE_16(uint, max, v_uint32x16, max_epu32) +OPENCV_HAL_IMPL_AVX512_REDUCE_16(int, min, v_int32x16, min_epi32) +OPENCV_HAL_IMPL_AVX512_REDUCE_16(int, max, v_int32x16, max_epi32) + +#define OPENCV_HAL_IMPL_AVX512_REDUCE_16F(func, ifunc) \ + inline float v_reduce_##func(const v_float32x16& a) \ + { __m256 half = _mm256_##ifunc(_v512_extract_low(a.val), _v512_extract_high(a.val)); \ + __m128 quarter = _mm_##ifunc(_mm256_castps256_ps128(half), _mm256_extractf128_ps(half, 1)); \ + quarter = _mm_##ifunc(quarter, _mm_permute_ps(quarter, _MM_SHUFFLE(0, 0, 3, 2))); \ + quarter = _mm_##ifunc(quarter, _mm_permute_ps(quarter, _MM_SHUFFLE(0, 0, 0, 1))); \ + return _mm_cvtss_f32(quarter); } +OPENCV_HAL_IMPL_AVX512_REDUCE_16F(min, min_ps) +OPENCV_HAL_IMPL_AVX512_REDUCE_16F(max, max_ps) + +inline float v_reduce_sum(const v_float32x16& a) +{ + __m256 half = _mm256_add_ps(_v512_extract_low(a.val), _v512_extract_high(a.val)); + __m128 quarter = _mm_add_ps(_mm256_castps256_ps128(half), _mm256_extractf128_ps(half, 1)); + quarter = _mm_hadd_ps(quarter, quarter); + return _mm_cvtss_f32(_mm_hadd_ps(quarter, quarter)); +} +inline int v_reduce_sum(const v_int32x16& a) +{ + __m256i half = _mm256_add_epi32(_v512_extract_low(a.val), _v512_extract_high(a.val)); + __m128i quarter = _mm_add_epi32(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1)); + quarter = _mm_hadd_epi32(quarter, quarter); + return _mm_cvtsi128_si32(_mm_hadd_epi32(quarter, quarter)); +} +inline uint v_reduce_sum(const v_uint32x16& a) +{ return (uint)v_reduce_sum(v_reinterpret_as_s32(a)); } + +#define OPENCV_HAL_IMPL_AVX512_REDUCE_32(sctype, func, _Tpvec, ifunc) \ + inline sctype v_reduce_##func(const _Tpvec& a) \ + { __m256i half = _mm256_##ifunc(_v512_extract_low(a.val), _v512_extract_high(a.val)); \ + __m128i quarter = _mm_##ifunc(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 8)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 4)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 2)); \ + return (sctype)_mm_cvtsi128_si32(quarter); } +OPENCV_HAL_IMPL_AVX512_REDUCE_32(ushort, min, v_uint16x32, min_epu16) +OPENCV_HAL_IMPL_AVX512_REDUCE_32(ushort, max, v_uint16x32, max_epu16) +OPENCV_HAL_IMPL_AVX512_REDUCE_32(short, min, v_int16x32, min_epi16) +OPENCV_HAL_IMPL_AVX512_REDUCE_32(short, max, v_int16x32, max_epi16) + +inline int v_reduce_sum(const v_int16x32& a) +{ return v_reduce_sum(v_expand_low(a) + v_expand_high(a)); } +inline uint v_reduce_sum(const v_uint16x32& a) +{ return v_reduce_sum(v_expand_low(a) + v_expand_high(a)); } + +#define OPENCV_HAL_IMPL_AVX512_REDUCE_64(sctype, func, _Tpvec, ifunc) \ + inline sctype v_reduce_##func(const _Tpvec& a) \ + { __m256i half = _mm256_##ifunc(_v512_extract_low(a.val), _v512_extract_high(a.val)); \ + __m128i quarter = _mm_##ifunc(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 8)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 4)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 2)); \ + quarter = _mm_##ifunc(quarter, _mm_srli_si128(quarter, 1)); \ + return (sctype)_mm_cvtsi128_si32(quarter); } +OPENCV_HAL_IMPL_AVX512_REDUCE_64(uchar, min, v_uint8x64, min_epu8) +OPENCV_HAL_IMPL_AVX512_REDUCE_64(uchar, max, v_uint8x64, max_epu8) +OPENCV_HAL_IMPL_AVX512_REDUCE_64(schar, min, v_int8x64, min_epi8) +OPENCV_HAL_IMPL_AVX512_REDUCE_64(schar, max, v_int8x64, max_epi8) + +#define OPENCV_HAL_IMPL_AVX512_REDUCE_64_SUM(sctype, _Tpvec, suffix) \ + inline sctype v_reduce_sum(const _Tpvec& a) \ + { __m512i a16 = _mm512_add_epi16(_mm512_cvt##suffix##_epi16(_v512_extract_low(a.val)), \ + _mm512_cvt##suffix##_epi16(_v512_extract_high(a.val))); \ + a16 = _mm512_cvtepi16_epi32(_mm256_add_epi16(_v512_extract_low(a16), _v512_extract_high(a16))); \ + __m256i a8 = _mm256_add_epi32(_v512_extract_low(a16), _v512_extract_high(a16)); \ + __m128i a4 = _mm_add_epi32(_mm256_castsi256_si128(a8), _mm256_extracti128_si256(a8, 1)); \ + a4 = _mm_hadd_epi32(a4, a4); \ + return (sctype)_mm_cvtsi128_si32(_mm_hadd_epi32(a4, a4)); } +OPENCV_HAL_IMPL_AVX512_REDUCE_64_SUM(uint, v_uint8x64, epu8) +OPENCV_HAL_IMPL_AVX512_REDUCE_64_SUM(int, v_int8x64, epi8) + +inline v_float32x16 v_reduce_sum4(const v_float32x16& a, const v_float32x16& b, + const v_float32x16& c, const v_float32x16& d) +{ + __m256 abl = _mm256_hadd_ps(_v512_extract_low(a.val), _v512_extract_low(b.val)); + __m256 abh = _mm256_hadd_ps(_v512_extract_high(a.val), _v512_extract_high(b.val)); + __m256 cdl = _mm256_hadd_ps(_v512_extract_low(c.val), _v512_extract_low(d.val)); + __m256 cdh = _mm256_hadd_ps(_v512_extract_high(c.val), _v512_extract_high(d.val)); + return v_float32x16(_v512_combine(_mm256_hadd_ps(abl, cdl), _mm256_hadd_ps(abh, cdh))); +} + +inline unsigned v_reduce_sad(const v_uint8x64& a, const v_uint8x64& b) +{ + __m512i val = _mm512_sad_epu8(a.val, b.val); + __m256i half = _mm256_add_epi32(_v512_extract_low(val), _v512_extract_high(val)); + __m128i quarter = _mm_add_epi32(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1)); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(quarter, _mm_unpackhi_epi64(quarter, quarter))); +} +inline unsigned v_reduce_sad(const v_int8x64& a, const v_int8x64& b) +{ + __m512i val = _mm512_set1_epi8(-128); + val = _mm512_sad_epu8(_mm512_add_epi8(a.val, val), _mm512_add_epi8(b.val, val)); + __m256i half = _mm256_add_epi32(_v512_extract_low(val), _v512_extract_high(val)); + __m128i quarter = _mm_add_epi32(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1)); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(quarter, _mm_unpackhi_epi64(quarter, quarter))); +} +inline unsigned v_reduce_sad(const v_uint16x32& a, const v_uint16x32& b) +{ return v_reduce_sum(v_add_wrap(a - b, b - a)); } +inline unsigned v_reduce_sad(const v_int16x32& a, const v_int16x32& b) +{ return v_reduce_sum(v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b)))); } +inline unsigned v_reduce_sad(const v_uint32x16& a, const v_uint32x16& b) +{ return v_reduce_sum(v_max(a, b) - v_min(a, b)); } +inline unsigned v_reduce_sad(const v_int32x16& a, const v_int32x16& b) +{ return v_reduce_sum(v_reinterpret_as_u32(v_max(a, b) - v_min(a, b))); } +inline float v_reduce_sad(const v_float32x16& a, const v_float32x16& b) +{ return v_reduce_sum((a - b) & v_float32x16(_mm512_castsi512_ps(_mm512_set1_epi32(0x7fffffff)))); } +inline double v_reduce_sad(const v_float64x8& a, const v_float64x8& b) +{ return v_reduce_sum((a - b) & v_float64x8(_mm512_castsi512_pd(_mm512_set1_epi64(0x7fffffffffffffff)))); } + +/** Popcount **/ +inline v_uint8x64 v_popcount(const v_int8x64& a) +{ +#if CV_AVX_512BITALG + return v_uint8x64(_mm512_popcnt_epi8(a.val)); +#elif CV_AVX_512VBMI + __m512i _popcnt_table0 = _v512_set_epu8(7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, + 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1, + 4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0); + __m512i _popcnt_table1 = _v512_set_epu8(7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 6, 5, 5, 4, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 3, 2, + 5, 4, 4, 3, 4, 3, 3, 2, 4, 3, 3, 2, 3, 2, 2, 1); + return v_uint8x64(_mm512_sub_epi8(_mm512_permutex2var_epi8(_popcnt_table0, a.val, _popcnt_table1), _mm512_movm_epi8(_mm512_movepi8_mask(a.val)))); +#else + __m512i _popcnt_table = _mm512_set4_epi32(0x04030302, 0x03020201, 0x03020201, 0x02010100); + __m512i _popcnt_mask = _mm512_set1_epi8(0x0F); + + return v_uint8x64(_mm512_add_epi8(_mm512_shuffle_epi8(_popcnt_table, _mm512_and_si512( a.val, _popcnt_mask)), + _mm512_shuffle_epi8(_popcnt_table, _mm512_and_si512(_mm512_srli_epi16(a.val, 4), _popcnt_mask)))); +#endif +} +inline v_uint16x32 v_popcount(const v_int16x32& a) +{ +#if CV_AVX_512BITALG + return v_uint16x32(_mm512_popcnt_epi16(a.val)); +#elif CV_AVX_512VPOPCNTDQ + __m512i zero = _mm512_setzero_si512(); + return v_uint16x32(_mm512_packs_epi32(_mm512_popcnt_epi32(_mm512_unpacklo_epi16(a.val, zero)), + _mm512_popcnt_epi32(_mm512_unpackhi_epi16(a.val, zero)))); +#else + v_uint8x64 p = v_popcount(v_reinterpret_as_s8(a)); + p += v_rotate_right<1>(p); + return v_reinterpret_as_u16(p) & v512_setall_u16(0x00ff); +#endif +} +inline v_uint32x16 v_popcount(const v_int32x16& a) +{ +#if CV_AVX_512VPOPCNTDQ + return v_uint32x16(_mm512_popcnt_epi32(a.val)); +#else + v_uint8x64 p = v_popcount(v_reinterpret_as_s8(a)); + p += v_rotate_right<1>(p); + p += v_rotate_right<2>(p); + return v_reinterpret_as_u32(p) & v512_setall_u32(0x000000ff); +#endif +} +inline v_uint64x8 v_popcount(const v_int64x8& a) +{ +#if CV_AVX_512VPOPCNTDQ + return v_uint64x8(_mm512_popcnt_epi64(a.val)); +#else + return v_uint64x8(_mm512_sad_epu8(v_popcount(v_reinterpret_as_s8(a)).val, _mm512_setzero_si512())); +#endif +} + + +inline v_uint8x64 v_popcount(const v_uint8x64& a) { return v_popcount(v_reinterpret_as_s8 (a)); } +inline v_uint16x32 v_popcount(const v_uint16x32& a) { return v_popcount(v_reinterpret_as_s16(a)); } +inline v_uint32x16 v_popcount(const v_uint32x16& a) { return v_popcount(v_reinterpret_as_s32(a)); } +inline v_uint64x8 v_popcount(const v_uint64x8& a) { return v_popcount(v_reinterpret_as_s64(a)); } + + +////////// Other math ///////// + +/** Some frequent operations **/ +#define OPENCV_HAL_IMPL_AVX512_MULADD(_Tpvec, suffix) \ + inline _Tpvec v_fma(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm512_fmadd_##suffix(a.val, b.val, c.val)); } \ + inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm512_fmadd_##suffix(a.val, b.val, c.val)); } \ + inline _Tpvec v_sqrt(const _Tpvec& x) \ + { return _Tpvec(_mm512_sqrt_##suffix(x.val)); } \ + inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ + { return v_fma(a, a, b * b); } \ + inline _Tpvec v_magnitude(const _Tpvec& a, const _Tpvec& b) \ + { return v_sqrt(v_fma(a, a, b * b)); } + +OPENCV_HAL_IMPL_AVX512_MULADD(v_float32x16, ps) +OPENCV_HAL_IMPL_AVX512_MULADD(v_float64x8, pd) + +inline v_int32x16 v_fma(const v_int32x16& a, const v_int32x16& b, const v_int32x16& c) +{ return a * b + c; } +inline v_int32x16 v_muladd(const v_int32x16& a, const v_int32x16& b, const v_int32x16& c) +{ return v_fma(a, b, c); } + +inline v_float32x16 v_invsqrt(const v_float32x16& x) +{ +#if CV_AVX_512ER + return v_float32x16(_mm512_rsqrt28_ps(x.val)); +#else + v_float32x16 half = x * v512_setall_f32(0.5); + v_float32x16 t = v_float32x16(_mm512_rsqrt14_ps(x.val)); + t *= v512_setall_f32(1.5) - ((t * t) * half); + return t; +#endif +} + +inline v_float64x8 v_invsqrt(const v_float64x8& x) +{ +#if CV_AVX_512ER + return v_float64x8(_mm512_rsqrt28_pd(x.val)); +#else + return v512_setall_f64(1.) / v_sqrt(x); +// v_float64x8 half = x * v512_setall_f64(0.5); +// v_float64x8 t = v_float64x8(_mm512_rsqrt14_pd(x.val)); +// t *= v512_setall_f64(1.5) - ((t * t) * half); +// t *= v512_setall_f64(1.5) - ((t * t) * half); +// return t; +#endif +} + +/** Absolute values **/ +#define OPENCV_HAL_IMPL_AVX512_ABS(_Tpvec, _Tpuvec, suffix) \ + inline _Tpuvec v_abs(const _Tpvec& x) \ + { return _Tpuvec(_mm512_abs_##suffix(x.val)); } + +OPENCV_HAL_IMPL_AVX512_ABS(v_int8x64, v_uint8x64, epi8) +OPENCV_HAL_IMPL_AVX512_ABS(v_int16x32, v_uint16x32, epi16) +OPENCV_HAL_IMPL_AVX512_ABS(v_int32x16, v_uint32x16, epi32) +OPENCV_HAL_IMPL_AVX512_ABS(v_int64x8, v_uint64x8, epi64) + +inline v_float32x16 v_abs(const v_float32x16& x) +{ +#ifdef _mm512_abs_pd + return v_float32x16(_mm512_abs_ps(x.val)); +#else + return v_float32x16(_mm512_castsi512_ps(_mm512_and_si512(_mm512_castps_si512(x.val), + _v512_set_epu64(0x7FFFFFFF7FFFFFFF, 0x7FFFFFFF7FFFFFFF, 0x7FFFFFFF7FFFFFFF, 0x7FFFFFFF7FFFFFFF, + 0x7FFFFFFF7FFFFFFF, 0x7FFFFFFF7FFFFFFF, 0x7FFFFFFF7FFFFFFF, 0x7FFFFFFF7FFFFFFF)))); +#endif +} + +inline v_float64x8 v_abs(const v_float64x8& x) +{ +#ifdef _mm512_abs_pd + #if defined __GNUC__ && (__GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ <= 3) || (__GNUC__ == 8 && __GNUC_MINOR__ <= 2)) + // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87476 + return v_float64x8(_mm512_abs_pd(_mm512_castpd_ps(x.val))); + #else + return v_float64x8(_mm512_abs_pd(x.val)); + #endif +#else + return v_float64x8(_mm512_castsi512_pd(_mm512_and_si512(_mm512_castpd_si512(x.val), + _v512_set_epu64(0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, + 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF)))); +#endif +} + +/** Absolute difference **/ +inline v_uint8x64 v_absdiff(const v_uint8x64& a, const v_uint8x64& b) +{ return v_add_wrap(a - b, b - a); } +inline v_uint16x32 v_absdiff(const v_uint16x32& a, const v_uint16x32& b) +{ return v_add_wrap(a - b, b - a); } +inline v_uint32x16 v_absdiff(const v_uint32x16& a, const v_uint32x16& b) +{ return v_max(a, b) - v_min(a, b); } + +inline v_uint8x64 v_absdiff(const v_int8x64& a, const v_int8x64& b) +{ + v_int8x64 d = v_sub_wrap(a, b); + v_int8x64 m = a < b; + return v_reinterpret_as_u8(v_sub_wrap(d ^ m, m)); +} + +inline v_uint16x32 v_absdiff(const v_int16x32& a, const v_int16x32& b) +{ return v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b))); } + +inline v_uint32x16 v_absdiff(const v_int32x16& a, const v_int32x16& b) +{ + v_int32x16 d = a - b; + v_int32x16 m = a < b; + return v_reinterpret_as_u32((d ^ m) - m); +} + +inline v_float32x16 v_absdiff(const v_float32x16& a, const v_float32x16& b) +{ return v_abs(a - b); } + +inline v_float64x8 v_absdiff(const v_float64x8& a, const v_float64x8& b) +{ return v_abs(a - b); } + +/** Saturating absolute difference **/ +inline v_int8x64 v_absdiffs(const v_int8x64& a, const v_int8x64& b) +{ + v_int8x64 d = a - b; + v_int8x64 m = a < b; + return (d ^ m) - m; +} +inline v_int16x32 v_absdiffs(const v_int16x32& a, const v_int16x32& b) +{ return v_max(a, b) - v_min(a, b); } + +////////// Conversions ///////// + +/** Rounding **/ +inline v_int32x16 v_round(const v_float32x16& a) +{ return v_int32x16(_mm512_cvtps_epi32(a.val)); } + +inline v_int32x16 v_round(const v_float64x8& a) +{ return v_int32x16(_mm512_castsi256_si512(_mm512_cvtpd_epi32(a.val))); } + +inline v_int32x16 v_round(const v_float64x8& a, const v_float64x8& b) +{ return v_int32x16(_v512_combine(_mm512_cvtpd_epi32(a.val), _mm512_cvtpd_epi32(b.val))); } + +inline v_int32x16 v_trunc(const v_float32x16& a) +{ return v_int32x16(_mm512_cvttps_epi32(a.val)); } + +inline v_int32x16 v_trunc(const v_float64x8& a) +{ return v_int32x16(_mm512_castsi256_si512(_mm512_cvttpd_epi32(a.val))); } + +#if CVT_ROUND_MODES_IMPLEMENTED +inline v_int32x16 v_floor(const v_float32x16& a) +{ return v_int32x16(_mm512_cvt_roundps_epi32(a.val, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC)); } + +inline v_int32x16 v_floor(const v_float64x8& a) +{ return v_int32x16(_mm512_castsi256_si512(_mm512_cvt_roundpd_epi32(a.val, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC))); } + +inline v_int32x16 v_ceil(const v_float32x16& a) +{ return v_int32x16(_mm512_cvt_roundps_epi32(a.val, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC)); } + +inline v_int32x16 v_ceil(const v_float64x8& a) +{ return v_int32x16(_mm512_castsi256_si512(_mm512_cvt_roundpd_epi32(a.val, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC))); } +#else +inline v_int32x16 v_floor(const v_float32x16& a) +{ return v_int32x16(_mm512_cvtps_epi32(_mm512_roundscale_ps(a.val, 1))); } + +inline v_int32x16 v_floor(const v_float64x8& a) +{ return v_int32x16(_mm512_castsi256_si512(_mm512_cvtpd_epi32(_mm512_roundscale_pd(a.val, 1)))); } + +inline v_int32x16 v_ceil(const v_float32x16& a) +{ return v_int32x16(_mm512_cvtps_epi32(_mm512_roundscale_ps(a.val, 2))); } + +inline v_int32x16 v_ceil(const v_float64x8& a) +{ return v_int32x16(_mm512_castsi256_si512(_mm512_cvtpd_epi32(_mm512_roundscale_pd(a.val, 2)))); } +#endif + +/** To float **/ +inline v_float32x16 v_cvt_f32(const v_int32x16& a) +{ return v_float32x16(_mm512_cvtepi32_ps(a.val)); } + +inline v_float32x16 v_cvt_f32(const v_float64x8& a) +{ return v_float32x16(_mm512_cvtpd_pslo(a.val)); } + +inline v_float32x16 v_cvt_f32(const v_float64x8& a, const v_float64x8& b) +{ return v_float32x16(_v512_combine(_mm512_cvtpd_ps(a.val), _mm512_cvtpd_ps(b.val))); } + +inline v_float64x8 v_cvt_f64(const v_int32x16& a) +{ return v_float64x8(_mm512_cvtepi32_pd(_v512_extract_low(a.val))); } + +inline v_float64x8 v_cvt_f64_high(const v_int32x16& a) +{ return v_float64x8(_mm512_cvtepi32_pd(_v512_extract_high(a.val))); } + +inline v_float64x8 v_cvt_f64(const v_float32x16& a) +{ return v_float64x8(_mm512_cvtps_pd(_v512_extract_low(a.val))); } + +inline v_float64x8 v_cvt_f64_high(const v_float32x16& a) +{ return v_float64x8(_mm512_cvtps_pd(_v512_extract_high(a.val))); } + +////////////// Lookup table access //////////////////// + +inline v_int8x64 v512_lut(const schar* tab, const int* idx) +{ + __m128i p0 = _mm512_cvtepi32_epi8(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx ), (const int *)tab, 1)); + __m128i p1 = _mm512_cvtepi32_epi8(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx + 1), (const int *)tab, 1)); + __m128i p2 = _mm512_cvtepi32_epi8(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx + 2), (const int *)tab, 1)); + __m128i p3 = _mm512_cvtepi32_epi8(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx + 3), (const int *)tab, 1)); + return v_int8x64(_mm512_inserti32x4(_mm512_inserti32x4(_mm512_inserti32x4(_mm512_castsi128_si512(p0), p1, 1), p2, 2), p3, 3)); +} +inline v_int8x64 v512_lut_pairs(const schar* tab, const int* idx) +{ + __m256i p0 = _mm512_cvtepi32_epi16(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx ), (const int *)tab, 1)); + __m256i p1 = _mm512_cvtepi32_epi16(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx + 1), (const int *)tab, 1)); + return v_int8x64(_v512_combine(p0, p1)); +} +inline v_int8x64 v512_lut_quads(const schar* tab, const int* idx) +{ + return v_int8x64(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx), (const int *)tab, 1)); +} +inline v_uint8x64 v512_lut(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v512_lut((const schar *)tab, idx)); } +inline v_uint8x64 v512_lut_pairs(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v512_lut_pairs((const schar *)tab, idx)); } +inline v_uint8x64 v512_lut_quads(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v512_lut_quads((const schar *)tab, idx)); } + +inline v_int16x32 v512_lut(const short* tab, const int* idx) +{ + __m256i p0 = _mm512_cvtepi32_epi16(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx ), (const int *)tab, 2)); + __m256i p1 = _mm512_cvtepi32_epi16(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx + 1), (const int *)tab, 2)); + return v_int16x32(_v512_combine(p0, p1)); +} +inline v_int16x32 v512_lut_pairs(const short* tab, const int* idx) +{ + return v_int16x32(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx), (const int *)tab, 2)); +} +inline v_int16x32 v512_lut_quads(const short* tab, const int* idx) +{ +#if defined(__GNUC__) + return v_int16x32(_mm512_i32gather_epi64(_mm256_loadu_si256((const __m256i*)idx), (const long long int*)tab, 2)); +#else + return v_int16x32(_mm512_i32gather_epi64(_mm256_loadu_si256((const __m256i*)idx), (const int64*)tab, 2)); +#endif +} +inline v_uint16x32 v512_lut(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v512_lut((const short *)tab, idx)); } +inline v_uint16x32 v512_lut_pairs(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v512_lut_pairs((const short *)tab, idx)); } +inline v_uint16x32 v512_lut_quads(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v512_lut_quads((const short *)tab, idx)); } + +inline v_int32x16 v512_lut(const int* tab, const int* idx) +{ + return v_int32x16(_mm512_i32gather_epi32(_mm512_loadu_si512((const __m512i*)idx), tab, 4)); +} +inline v_int32x16 v512_lut_pairs(const int* tab, const int* idx) +{ +#if defined(__GNUC__) + return v_int32x16(_mm512_i32gather_epi64(_mm256_loadu_si256((const __m256i*)idx), (const long long int*)tab, 4)); +#else + return v_int32x16(_mm512_i32gather_epi64(_mm256_loadu_si256((const __m256i*)idx), (const int64*)tab, 4)); +#endif +} +inline v_int32x16 v512_lut_quads(const int* tab, const int* idx) +{ + return v_int32x16(_mm512_inserti32x4(_mm512_inserti32x4(_mm512_inserti32x4(_mm512_castsi128_si512( + _mm_loadu_si128((const __m128i*)(tab + idx[0]))), + _mm_loadu_si128((const __m128i*)(tab + idx[1])), 1), + _mm_loadu_si128((const __m128i*)(tab + idx[2])), 2), + _mm_loadu_si128((const __m128i*)(tab + idx[3])), 3)); +} +inline v_uint32x16 v512_lut(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v512_lut((const int *)tab, idx)); } +inline v_uint32x16 v512_lut_pairs(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v512_lut_pairs((const int *)tab, idx)); } +inline v_uint32x16 v512_lut_quads(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v512_lut_quads((const int *)tab, idx)); } + +inline v_int64x8 v512_lut(const int64* tab, const int* idx) +{ +#if defined(__GNUC__) + return v_int64x8(_mm512_i32gather_epi64(_mm256_loadu_si256((const __m256i*)idx), (const long long int*)tab, 8)); +#else + return v_int64x8(_mm512_i32gather_epi64(_mm256_loadu_si256((const __m256i*)idx), tab , 8)); +#endif +} +inline v_int64x8 v512_lut_pairs(const int64* tab, const int* idx) +{ + return v_int64x8(_mm512_inserti32x4(_mm512_inserti32x4(_mm512_inserti32x4(_mm512_castsi128_si512( + _mm_loadu_si128((const __m128i*)(tab + idx[0]))), + _mm_loadu_si128((const __m128i*)(tab + idx[1])), 1), + _mm_loadu_si128((const __m128i*)(tab + idx[2])), 2), + _mm_loadu_si128((const __m128i*)(tab + idx[3])), 3)); +} +inline v_uint64x8 v512_lut(const uint64* tab, const int* idx) { return v_reinterpret_as_u64(v512_lut((const int64 *)tab, idx)); } +inline v_uint64x8 v512_lut_pairs(const uint64* tab, const int* idx) { return v_reinterpret_as_u64(v512_lut_pairs((const int64 *)tab, idx)); } + +inline v_float32x16 v512_lut(const float* tab, const int* idx) +{ + return v_float32x16(_mm512_i32gather_ps(_mm512_loadu_si512((const __m512i*)idx), tab, 4)); +} +inline v_float32x16 v512_lut_pairs(const float* tab, const int* idx) { return v_reinterpret_as_f32(v512_lut_pairs((const int *)tab, idx)); } +inline v_float32x16 v512_lut_quads(const float* tab, const int* idx) { return v_reinterpret_as_f32(v512_lut_quads((const int *)tab, idx)); } + +inline v_float64x8 v512_lut(const double* tab, const int* idx) +{ + return v_float64x8(_mm512_i32gather_pd(_mm256_loadu_si256((const __m256i*)idx), tab, 8)); +} +inline v_float64x8 v512_lut_pairs(const double* tab, const int* idx) +{ + return v_float64x8(_mm512_insertf64x2(_mm512_insertf64x2(_mm512_insertf64x2(_mm512_castpd128_pd512( + _mm_loadu_pd(tab + idx[0])), + _mm_loadu_pd(tab + idx[1]), 1), + _mm_loadu_pd(tab + idx[2]), 2), + _mm_loadu_pd(tab + idx[3]), 3)); +} + +inline v_int32x16 v_lut(const int* tab, const v_int32x16& idxvec) +{ + return v_int32x16(_mm512_i32gather_epi32(idxvec.val, tab, 4)); +} + +inline v_uint32x16 v_lut(const unsigned* tab, const v_int32x16& idxvec) +{ + return v_reinterpret_as_u32(v_lut((const int *)tab, idxvec)); +} + +inline v_float32x16 v_lut(const float* tab, const v_int32x16& idxvec) +{ + return v_float32x16(_mm512_i32gather_ps(idxvec.val, tab, 4)); +} + +inline v_float64x8 v_lut(const double* tab, const v_int32x16& idxvec) +{ + return v_float64x8(_mm512_i32gather_pd(_v512_extract_low(idxvec.val), tab, 8)); +} + +inline void v_lut_deinterleave(const float* tab, const v_int32x16& idxvec, v_float32x16& x, v_float32x16& y) +{ + x.val = _mm512_i32gather_ps(idxvec.val, tab, 4); + y.val = _mm512_i32gather_ps(idxvec.val, &tab[1], 4); +} + +inline void v_lut_deinterleave(const double* tab, const v_int32x16& idxvec, v_float64x8& x, v_float64x8& y) +{ + x.val = _mm512_i32gather_pd(_v512_extract_low(idxvec.val), tab, 8); + y.val = _mm512_i32gather_pd(_v512_extract_low(idxvec.val), &tab[1], 8); +} + +inline v_int8x64 v_interleave_pairs(const v_int8x64& vec) +{ + return v_int8x64(_mm512_shuffle_epi8(vec.val, _mm512_set4_epi32(0x0f0d0e0c, 0x0b090a08, 0x07050604, 0x03010200))); +} +inline v_uint8x64 v_interleave_pairs(const v_uint8x64& vec) { return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); } +inline v_int8x64 v_interleave_quads(const v_int8x64& vec) +{ + return v_int8x64(_mm512_shuffle_epi8(vec.val, _mm512_set4_epi32(0x0f0b0e0a, 0x0d090c08, 0x07030602, 0x05010400))); +} +inline v_uint8x64 v_interleave_quads(const v_uint8x64& vec) { return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); } + +inline v_int16x32 v_interleave_pairs(const v_int16x32& vec) +{ + return v_int16x32(_mm512_shuffle_epi8(vec.val, _mm512_set4_epi32(0x0f0e0b0a, 0x0d0c0908, 0x07060302, 0x05040100))); +} +inline v_uint16x32 v_interleave_pairs(const v_uint16x32& vec) { return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); } +inline v_int16x32 v_interleave_quads(const v_int16x32& vec) +{ + return v_int16x32(_mm512_shuffle_epi8(vec.val, _mm512_set4_epi32(0x0f0e0706, 0x0d0c0504, 0x0b0a0302, 0x09080100))); +} +inline v_uint16x32 v_interleave_quads(const v_uint16x32& vec) { return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); } + +inline v_int32x16 v_interleave_pairs(const v_int32x16& vec) +{ + return v_int32x16(_mm512_shuffle_epi32(vec.val, _MM_PERM_ACBD)); +} +inline v_uint32x16 v_interleave_pairs(const v_uint32x16& vec) { return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } +inline v_float32x16 v_interleave_pairs(const v_float32x16& vec) { return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } + +inline v_int8x64 v_pack_triplets(const v_int8x64& vec) +{ + return v_int8x64(_mm512_permutexvar_epi32(_v512_set_epu64(0x0000000f0000000f, 0x0000000f0000000f, 0x0000000e0000000d, 0x0000000c0000000a, + 0x0000000900000008, 0x0000000600000005, 0x0000000400000002, 0x0000000100000000), + _mm512_shuffle_epi8(vec.val, _mm512_set4_epi32(0xffffff0f, 0x0e0d0c0a, 0x09080605, 0x04020100)))); +} +inline v_uint8x64 v_pack_triplets(const v_uint8x64& vec) { return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); } + +inline v_int16x32 v_pack_triplets(const v_int16x32& vec) +{ + return v_int16x32(_mm512_permutexvar_epi16(_v512_set_epu64(0x001f001f001f001f, 0x001f001f001f001f, 0x001e001d001c001a, 0x0019001800160015, + 0x0014001200110010, 0x000e000d000c000a, 0x0009000800060005, 0x0004000200010000), vec.val)); +} +inline v_uint16x32 v_pack_triplets(const v_uint16x32& vec) { return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); } + +inline v_int32x16 v_pack_triplets(const v_int32x16& vec) +{ + return v_int32x16(_mm512_permutexvar_epi32(_v512_set_epu64(0x0000000f0000000f, 0x0000000f0000000f, 0x0000000e0000000d, 0x0000000c0000000a, + 0x0000000900000008, 0x0000000600000005, 0x0000000400000002, 0x0000000100000000), vec.val)); +} +inline v_uint32x16 v_pack_triplets(const v_uint32x16& vec) { return v_reinterpret_as_u32(v_pack_triplets(v_reinterpret_as_s32(vec))); } +inline v_float32x16 v_pack_triplets(const v_float32x16& vec) +{ + return v_float32x16(_mm512_permutexvar_ps(_v512_set_epu64(0x0000000f0000000f, 0x0000000f0000000f, 0x0000000e0000000d, 0x0000000c0000000a, + 0x0000000900000008, 0x0000000600000005, 0x0000000400000002, 0x0000000100000000), vec.val)); +} + +////////// Matrix operations ///////// + +inline v_int32x16 v_dotprod(const v_int16x32& a, const v_int16x32& b) +{ return v_int32x16(_mm512_madd_epi16(a.val, b.val)); } + +inline v_int32x16 v_dotprod(const v_int16x32& a, const v_int16x32& b, const v_int32x16& c) +{ return v_dotprod(a, b) + c; } + +#define OPENCV_HAL_AVX512_SPLAT2_PS(a, im) \ + v_float32x16(_mm512_permute_ps(a.val, _MM_SHUFFLE(im, im, im, im))) + +inline v_float32x16 v_matmul(const v_float32x16& v, + const v_float32x16& m0, const v_float32x16& m1, + const v_float32x16& m2, const v_float32x16& m3) +{ + v_float32x16 v04 = OPENCV_HAL_AVX512_SPLAT2_PS(v, 0); + v_float32x16 v15 = OPENCV_HAL_AVX512_SPLAT2_PS(v, 1); + v_float32x16 v26 = OPENCV_HAL_AVX512_SPLAT2_PS(v, 2); + v_float32x16 v37 = OPENCV_HAL_AVX512_SPLAT2_PS(v, 3); + return v_fma(v04, m0, v_fma(v15, m1, v_fma(v26, m2, v37 * m3))); +} + +inline v_float32x16 v_matmuladd(const v_float32x16& v, + const v_float32x16& m0, const v_float32x16& m1, + const v_float32x16& m2, const v_float32x16& a) +{ + v_float32x16 v04 = OPENCV_HAL_AVX512_SPLAT2_PS(v, 0); + v_float32x16 v15 = OPENCV_HAL_AVX512_SPLAT2_PS(v, 1); + v_float32x16 v26 = OPENCV_HAL_AVX512_SPLAT2_PS(v, 2); + return v_fma(v04, m0, v_fma(v15, m1, v_fma(v26, m2, a))); +} + +#define OPENCV_HAL_IMPL_AVX512_TRANSPOSE4x4(_Tpvec, suffix, cast_from, cast_to) \ + inline void v_transpose4x4(const _Tpvec& a0, const _Tpvec& a1, \ + const _Tpvec& a2, const _Tpvec& a3, \ + _Tpvec& b0, _Tpvec& b1, _Tpvec& b2, _Tpvec& b3) \ + { \ + __m512i t0 = cast_from(_mm512_unpacklo_##suffix(a0.val, a1.val)); \ + __m512i t1 = cast_from(_mm512_unpacklo_##suffix(a2.val, a3.val)); \ + __m512i t2 = cast_from(_mm512_unpackhi_##suffix(a0.val, a1.val)); \ + __m512i t3 = cast_from(_mm512_unpackhi_##suffix(a2.val, a3.val)); \ + b0.val = cast_to(_mm512_unpacklo_epi64(t0, t1)); \ + b1.val = cast_to(_mm512_unpackhi_epi64(t0, t1)); \ + b2.val = cast_to(_mm512_unpacklo_epi64(t2, t3)); \ + b3.val = cast_to(_mm512_unpackhi_epi64(t2, t3)); \ + } + +OPENCV_HAL_IMPL_AVX512_TRANSPOSE4x4(v_uint32x16, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_AVX512_TRANSPOSE4x4(v_int32x16, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_AVX512_TRANSPOSE4x4(v_float32x16, ps, _mm512_castps_si512, _mm512_castsi512_ps) + +//////////////// Value reordering /////////////// + +/* Expand */ +#define OPENCV_HAL_IMPL_AVX512_EXPAND(_Tpvec, _Tpwvec, _Tp, intrin) \ + inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \ + { \ + b0.val = intrin(_v512_extract_low(a.val)); \ + b1.val = intrin(_v512_extract_high(a.val)); \ + } \ + inline _Tpwvec v_expand_low(const _Tpvec& a) \ + { return _Tpwvec(intrin(_v512_extract_low(a.val))); } \ + inline _Tpwvec v_expand_high(const _Tpvec& a) \ + { return _Tpwvec(intrin(_v512_extract_high(a.val))); } \ + inline _Tpwvec v512_load_expand(const _Tp* ptr) \ + { \ + __m256i a = _mm256_loadu_si256((const __m256i*)ptr); \ + return _Tpwvec(intrin(a)); \ + } + +OPENCV_HAL_IMPL_AVX512_EXPAND(v_uint8x64, v_uint16x32, uchar, _mm512_cvtepu8_epi16) +OPENCV_HAL_IMPL_AVX512_EXPAND(v_int8x64, v_int16x32, schar, _mm512_cvtepi8_epi16) +OPENCV_HAL_IMPL_AVX512_EXPAND(v_uint16x32, v_uint32x16, ushort, _mm512_cvtepu16_epi32) +OPENCV_HAL_IMPL_AVX512_EXPAND(v_int16x32, v_int32x16, short, _mm512_cvtepi16_epi32) +OPENCV_HAL_IMPL_AVX512_EXPAND(v_uint32x16, v_uint64x8, unsigned, _mm512_cvtepu32_epi64) +OPENCV_HAL_IMPL_AVX512_EXPAND(v_int32x16, v_int64x8, int, _mm512_cvtepi32_epi64) + +#define OPENCV_HAL_IMPL_AVX512_EXPAND_Q(_Tpvec, _Tp, intrin) \ + inline _Tpvec v512_load_expand_q(const _Tp* ptr) \ + { \ + __m128i a = _mm_loadu_si128((const __m128i*)ptr); \ + return _Tpvec(intrin(a)); \ + } + +OPENCV_HAL_IMPL_AVX512_EXPAND_Q(v_uint32x16, uchar, _mm512_cvtepu8_epi32) +OPENCV_HAL_IMPL_AVX512_EXPAND_Q(v_int32x16, schar, _mm512_cvtepi8_epi32) + +/* pack */ +// 16 +inline v_int8x64 v_pack(const v_int16x32& a, const v_int16x32& b) +{ return v_int8x64(_mm512_permutexvar_epi64(_v512_set_epu64(7, 5, 3, 1, 6, 4, 2, 0), _mm512_packs_epi16(a.val, b.val))); } + +inline v_uint8x64 v_pack(const v_uint16x32& a, const v_uint16x32& b) +{ + const __m512i t = _mm512_set1_epi16(255); + return v_uint8x64(_v512_combine(_mm512_cvtepi16_epi8(_mm512_min_epu16(a.val, t)), _mm512_cvtepi16_epi8(_mm512_min_epu16(b.val, t)))); +} + +inline v_uint8x64 v_pack_u(const v_int16x32& a, const v_int16x32& b) +{ + return v_uint8x64(_mm512_permutexvar_epi64(_v512_set_epu64(7, 5, 3, 1, 6, 4, 2, 0), _mm512_packus_epi16(a.val, b.val))); +} + +inline void v_pack_store(schar* ptr, const v_int16x32& a) +{ v_store_low(ptr, v_pack(a, a)); } + +inline void v_pack_store(uchar* ptr, const v_uint16x32& a) +{ + const __m512i m = _mm512_set1_epi16(255); + _mm256_storeu_si256((__m256i*)ptr, _mm512_cvtepi16_epi8(_mm512_min_epu16(a.val, m))); +} + +inline void v_pack_u_store(uchar* ptr, const v_int16x32& a) +{ v_store_low(ptr, v_pack_u(a, a)); } + +template inline +v_uint8x64 v_rshr_pack(const v_uint16x32& a, const v_uint16x32& b) +{ + // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. + v_uint16x32 delta = v512_setall_u16((short)(1 << (n-1))); + return v_pack_u(v_reinterpret_as_s16((a + delta) >> n), + v_reinterpret_as_s16((b + delta) >> n)); +} + +template inline +void v_rshr_pack_store(uchar* ptr, const v_uint16x32& a) +{ + v_uint16x32 delta = v512_setall_u16((short)(1 << (n-1))); + v_pack_u_store(ptr, v_reinterpret_as_s16((a + delta) >> n)); +} + +template inline +v_uint8x64 v_rshr_pack_u(const v_int16x32& a, const v_int16x32& b) +{ + v_int16x32 delta = v512_setall_s16((short)(1 << (n-1))); + return v_pack_u((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_u_store(uchar* ptr, const v_int16x32& a) +{ + v_int16x32 delta = v512_setall_s16((short)(1 << (n-1))); + v_pack_u_store(ptr, (a + delta) >> n); +} + +template inline +v_int8x64 v_rshr_pack(const v_int16x32& a, const v_int16x32& b) +{ + v_int16x32 delta = v512_setall_s16((short)(1 << (n-1))); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(schar* ptr, const v_int16x32& a) +{ + v_int16x32 delta = v512_setall_s16((short)(1 << (n-1))); + v_pack_store(ptr, (a + delta) >> n); +} + +// 32 +inline v_int16x32 v_pack(const v_int32x16& a, const v_int32x16& b) +{ return v_int16x32(_mm512_permutexvar_epi64(_v512_set_epu64(7, 5, 3, 1, 6, 4, 2, 0), _mm512_packs_epi32(a.val, b.val))); } + +inline v_uint16x32 v_pack(const v_uint32x16& a, const v_uint32x16& b) +{ + const __m512i m = _mm512_set1_epi32(65535); + return v_uint16x32(_v512_combine(_mm512_cvtepi32_epi16(_mm512_min_epu32(a.val, m)), _mm512_cvtepi32_epi16(_mm512_min_epu32(b.val, m)))); +} + +inline v_uint16x32 v_pack_u(const v_int32x16& a, const v_int32x16& b) +{ return v_uint16x32(_mm512_permutexvar_epi64(_v512_set_epu64(7, 5, 3, 1, 6, 4, 2, 0), _mm512_packus_epi32(a.val, b.val))); } + +inline void v_pack_store(short* ptr, const v_int32x16& a) +{ v_store_low(ptr, v_pack(a, a)); } + +inline void v_pack_store(ushort* ptr, const v_uint32x16& a) +{ + const __m512i m = _mm512_set1_epi32(65535); + _mm256_storeu_si256((__m256i*)ptr, _mm512_cvtepi32_epi16(_mm512_min_epu32(a.val, m))); +} + +inline void v_pack_u_store(ushort* ptr, const v_int32x16& a) +{ v_store_low(ptr, v_pack_u(a, a)); } + + +template inline +v_uint16x32 v_rshr_pack(const v_uint32x16& a, const v_uint32x16& b) +{ + v_uint32x16 delta = v512_setall_u32(1 << (n-1)); + return v_pack_u(v_reinterpret_as_s32((a + delta) >> n), + v_reinterpret_as_s32((b + delta) >> n)); +} + +template inline +void v_rshr_pack_store(ushort* ptr, const v_uint32x16& a) +{ + v_uint32x16 delta = v512_setall_u32(1 << (n-1)); + v_pack_u_store(ptr, v_reinterpret_as_s32((a + delta) >> n)); +} + +template inline +v_uint16x32 v_rshr_pack_u(const v_int32x16& a, const v_int32x16& b) +{ + v_int32x16 delta = v512_setall_s32(1 << (n-1)); + return v_pack_u((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_u_store(ushort* ptr, const v_int32x16& a) +{ + v_int32x16 delta = v512_setall_s32(1 << (n-1)); + v_pack_u_store(ptr, (a + delta) >> n); +} + +template inline +v_int16x32 v_rshr_pack(const v_int32x16& a, const v_int32x16& b) +{ + v_int32x16 delta = v512_setall_s32(1 << (n-1)); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(short* ptr, const v_int32x16& a) +{ + v_int32x16 delta = v512_setall_s32(1 << (n-1)); + v_pack_store(ptr, (a + delta) >> n); +} + +// 64 +// Non-saturating pack +inline v_uint32x16 v_pack(const v_uint64x8& a, const v_uint64x8& b) +{ return v_uint32x16(_v512_combine(_mm512_cvtepi64_epi32(a.val), _mm512_cvtepi64_epi32(b.val))); } + +inline v_int32x16 v_pack(const v_int64x8& a, const v_int64x8& b) +{ return v_reinterpret_as_s32(v_pack(v_reinterpret_as_u64(a), v_reinterpret_as_u64(b))); } + +inline void v_pack_store(unsigned* ptr, const v_uint64x8& a) +{ _mm256_storeu_si256((__m256i*)ptr, _mm512_cvtepi64_epi32(a.val)); } + +inline void v_pack_store(int* ptr, const v_int64x8& b) +{ v_pack_store((unsigned*)ptr, v_reinterpret_as_u64(b)); } + +template inline +v_uint32x16 v_rshr_pack(const v_uint64x8& a, const v_uint64x8& b) +{ + v_uint64x8 delta = v512_setall_u64((uint64)1 << (n-1)); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(unsigned* ptr, const v_uint64x8& a) +{ + v_uint64x8 delta = v512_setall_u64((uint64)1 << (n-1)); + v_pack_store(ptr, (a + delta) >> n); +} + +template inline +v_int32x16 v_rshr_pack(const v_int64x8& a, const v_int64x8& b) +{ + v_int64x8 delta = v512_setall_s64((int64)1 << (n-1)); + return v_pack((a + delta) >> n, (b + delta) >> n); +} + +template inline +void v_rshr_pack_store(int* ptr, const v_int64x8& a) +{ + v_int64x8 delta = v512_setall_s64((int64)1 << (n-1)); + v_pack_store(ptr, (a + delta) >> n); +} + +// pack boolean +inline v_uint8x64 v_pack_b(const v_uint16x32& a, const v_uint16x32& b) +{ return v_uint8x64(_mm512_permutexvar_epi64(_v512_set_epu64(7, 5, 3, 1, 6, 4, 2, 0), _mm512_packs_epi16(a.val, b.val))); } + +inline v_uint8x64 v_pack_b(const v_uint32x16& a, const v_uint32x16& b, + const v_uint32x16& c, const v_uint32x16& d) +{ + __m512i ab = _mm512_packs_epi32(a.val, b.val); + __m512i cd = _mm512_packs_epi32(c.val, d.val); + + return v_uint8x64(_mm512_permutexvar_epi32(_v512_set_epu32(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0), _mm512_packs_epi16(ab, cd))); +} + +inline v_uint8x64 v_pack_b(const v_uint64x8& a, const v_uint64x8& b, const v_uint64x8& c, + const v_uint64x8& d, const v_uint64x8& e, const v_uint64x8& f, + const v_uint64x8& g, const v_uint64x8& h) +{ + __m512i ab = _mm512_packs_epi32(a.val, b.val); + __m512i cd = _mm512_packs_epi32(c.val, d.val); + __m512i ef = _mm512_packs_epi32(e.val, f.val); + __m512i gh = _mm512_packs_epi32(g.val, h.val); + + __m512i abcd = _mm512_packs_epi32(ab, cd); + __m512i efgh = _mm512_packs_epi32(ef, gh); + + return v_uint8x64(_mm512_permutexvar_epi16(_v512_set_epu16(31, 23, 15, 7, 30, 22, 14, 6, 29, 21, 13, 5, 28, 20, 12, 4, + 27, 19, 11, 3, 26, 18, 10, 2, 25, 17, 9, 1, 24, 16, 8, 0), _mm512_packs_epi16(abcd, efgh))); +} + +/* Recombine */ +// its up there with load and store operations + +/* Extract */ +#define OPENCV_HAL_IMPL_AVX512_EXTRACT(_Tpvec) \ + template \ + inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) \ + { return v_rotate_right(a, b); } + +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_uint8x64) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_int8x64) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_uint16x32) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_int16x32) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_uint32x16) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_int32x16) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_uint64x8) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_int64x8) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_float32x16) +OPENCV_HAL_IMPL_AVX512_EXTRACT(v_float64x8) + + +///////////////////// load deinterleave ///////////////////////////// + +inline void v_load_deinterleave( const uchar* ptr, v_uint8x64& a, v_uint8x64& b ) +{ + __m512i ab0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i ab1 = _mm512_loadu_si512((const __m512i*)(ptr + 64)); +#if CV_AVX_512VBMI + __m512i mask0 = _v512_set_epu8(126, 124, 122, 120, 118, 116, 114, 112, 110, 108, 106, 104, 102, 100, 98, 96, + 94, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, + 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, + 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu8(127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 99, 97, + 95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65, + 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1); + a = v_uint8x64(_mm512_permutex2var_epi8(ab0, mask0, ab1)); + b = v_uint8x64(_mm512_permutex2var_epi8(ab0, mask1, ab1)); +#else + __m512i mask0 = _mm512_set4_epi32(0x0f0d0b09, 0x07050301, 0x0e0c0a08, 0x06040200); + __m512i a0b0 = _mm512_shuffle_epi8(ab0, mask0); + __m512i a1b1 = _mm512_shuffle_epi8(ab1, mask0); + __m512i mask1 = _v512_set_epu64(14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask2 = _v512_set_epu64(15, 13, 11, 9, 7, 5, 3, 1); + a = v_uint8x64(_mm512_permutex2var_epi64(a0b0, mask1, a1b1)); + b = v_uint8x64(_mm512_permutex2var_epi64(a0b0, mask2, a1b1)); +#endif +} + +inline void v_load_deinterleave( const ushort* ptr, v_uint16x32& a, v_uint16x32& b ) +{ + __m512i ab0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i ab1 = _mm512_loadu_si512((const __m512i*)(ptr + 32)); + __m512i mask0 = _v512_set_epu16(62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, + 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu16(63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1); + a = v_uint16x32(_mm512_permutex2var_epi16(ab0, mask0, ab1)); + b = v_uint16x32(_mm512_permutex2var_epi16(ab0, mask1, ab1)); +} + +inline void v_load_deinterleave( const unsigned* ptr, v_uint32x16& a, v_uint32x16& b ) +{ + __m512i ab0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i ab1 = _mm512_loadu_si512((const __m512i*)(ptr + 16)); + __m512i mask0 = _v512_set_epu32(30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu32(31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1); + a = v_uint32x16(_mm512_permutex2var_epi32(ab0, mask0, ab1)); + b = v_uint32x16(_mm512_permutex2var_epi32(ab0, mask1, ab1)); +} + +inline void v_load_deinterleave( const uint64* ptr, v_uint64x8& a, v_uint64x8& b ) +{ + __m512i ab0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i ab1 = _mm512_loadu_si512((const __m512i*)(ptr + 8)); + __m512i mask0 = _v512_set_epu64(14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu64(15, 13, 11, 9, 7, 5, 3, 1); + a = v_uint64x8(_mm512_permutex2var_epi64(ab0, mask0, ab1)); + b = v_uint64x8(_mm512_permutex2var_epi64(ab0, mask1, ab1)); +} + +inline void v_load_deinterleave( const uchar* ptr, v_uint8x64& a, v_uint8x64& b, v_uint8x64& c ) +{ + __m512i bgr0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgr1 = _mm512_loadu_si512((const __m512i*)(ptr + 64)); + __m512i bgr2 = _mm512_loadu_si512((const __m512i*)(ptr + 128)); + +#if CV_AVX_512VBMI2 + __m512i mask0 = _v512_set_epu8(126, 123, 120, 117, 114, 111, 108, 105, 102, 99, 96, 93, 90, 87, 84, 81, + 78, 75, 72, 69, 66, 63, 60, 57, 54, 51, 48, 45, 42, 39, 36, 33, + 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0, 62, 59, 56, 53, 50, + 47, 44, 41, 38, 35, 32, 29, 26, 23, 20, 17, 14, 11, 8, 5, 2); + __m512i r0b01 = _mm512_permutex2var_epi8(bgr0, mask0, bgr1); + __m512i b1g12 = _mm512_permutex2var_epi8(bgr1, mask0, bgr2); + __m512i r12b2 = _mm512_permutex2var_epi8(bgr1, + _v512_set_epu8(125, 122, 119, 116, 113, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, + 77, 74, 71, 68, 65, 127, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, + 94, 91, 88, 85, 82, 79, 76, 73, 70, 67, 64, 61, 58, 55, 52, 49, + 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 13, 10, 7, 4, 1), bgr2); + a = v_uint8x64(_mm512_mask_compress_epi8(r12b2, 0xffffffffffe00000, r0b01)); + b = v_uint8x64(_mm512_mask_compress_epi8(b1g12, 0x2492492492492492, bgr0)); + c = v_uint8x64(_mm512_mask_expand_epi8(r0b01, 0xffffffffffe00000, r12b2)); +#elif CV_AVX_512VBMI + __m512i b0g0b1 = _mm512_mask_blend_epi8(0xb6db6db6db6db6db, bgr1, bgr0); + __m512i g1r1g2 = _mm512_mask_blend_epi8(0xb6db6db6db6db6db, bgr2, bgr1); + __m512i r2b2r0 = _mm512_mask_blend_epi8(0xb6db6db6db6db6db, bgr0, bgr2); + a = v_uint8x64(_mm512_permutex2var_epi8(b0g0b1, _v512_set_epu8(125, 122, 119, 116, 113, 110, 107, 104, 101, 98, 95, 92, 89, 86, 83, 80, + 77, 74, 71, 68, 65, 63, 61, 60, 58, 57, 55, 54, 52, 51, 49, 48, + 46, 45, 43, 42, 40, 39, 37, 36, 34, 33, 31, 30, 28, 27, 25, 24, + 23, 21, 20, 18, 17, 15, 14, 12, 11, 9, 8, 6, 5, 3, 2, 0), bgr2)); + b = v_uint8x64(_mm512_permutex2var_epi8(g1r1g2, _v512_set_epu8( 63, 61, 60, 58, 57, 55, 54, 52, 51, 49, 48, 46, 45, 43, 42, 40, + 39, 37, 36, 34, 33, 31, 30, 28, 27, 25, 24, 23, 21, 20, 18, 17, + 15, 14, 12, 11, 9, 8, 6, 5, 3, 2, 0, 126, 123, 120, 117, 114, + 111, 108, 105, 102, 99, 96, 93, 90, 87, 84, 81, 78, 75, 72, 69, 66), bgr0)); + c = v_uint8x64(_mm512_permutex2var_epi8(r2b2r0, _v512_set_epu8( 63, 60, 57, 54, 51, 48, 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, + 15, 12, 9, 6, 3, 0, 125, 122, 119, 116, 113, 110, 107, 104, 101, 98, + 95, 92, 89, 86, 83, 80, 77, 74, 71, 68, 65, 62, 59, 56, 53, 50, + 47, 44, 41, 38, 35, 32, 29, 26, 23, 20, 17, 14, 11, 8, 5, 2), bgr1)); +#else + __m512i mask0 = _v512_set_epu16(61, 58, 55, 52, 49, 46, 43, 40, 37, 34, 63, 60, 57, 54, 51, 48, + 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0); + __m512i b01g1 = _mm512_permutex2var_epi16(bgr0, mask0, bgr1); + __m512i r12b2 = _mm512_permutex2var_epi16(bgr1, mask0, bgr2); + __m512i g20r0 = _mm512_permutex2var_epi16(bgr2, mask0, bgr0); + + __m512i b0g0 = _mm512_mask_blend_epi32(0xf800, b01g1, r12b2); + __m512i r0b1 = _mm512_permutex2var_epi16(bgr1, _v512_set_epu16(42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 29, 26, 23, 20, 17, + 14, 11, 8, 5, 2, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43), g20r0); + __m512i g1r1 = _mm512_alignr_epi32(r12b2, g20r0, 11); + a = v_uint8x64(_mm512_mask_blend_epi8(0xAAAAAAAAAAAAAAAA, b0g0, r0b1)); + c = v_uint8x64(_mm512_mask_blend_epi8(0xAAAAAAAAAAAAAAAA, r0b1, g1r1)); + b = v_uint8x64(_mm512_shuffle_epi8(_mm512_mask_blend_epi8(0xAAAAAAAAAAAAAAAA, g1r1, b0g0), _mm512_set4_epi32(0x0e0f0c0d, 0x0a0b0809, 0x06070405, 0x02030001))); +#endif +} + +inline void v_load_deinterleave( const ushort* ptr, v_uint16x32& a, v_uint16x32& b, v_uint16x32& c ) +{ + __m512i bgr0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgr1 = _mm512_loadu_si512((const __m512i*)(ptr + 32)); + __m512i bgr2 = _mm512_loadu_si512((const __m512i*)(ptr + 64)); + + __m512i mask0 = _v512_set_epu16(61, 58, 55, 52, 49, 46, 43, 40, 37, 34, 63, 60, 57, 54, 51, 48, + 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0); + __m512i b01g1 = _mm512_permutex2var_epi16(bgr0, mask0, bgr1); + __m512i r12b2 = _mm512_permutex2var_epi16(bgr1, mask0, bgr2); + __m512i g20r0 = _mm512_permutex2var_epi16(bgr2, mask0, bgr0); + + a = v_uint16x32(_mm512_mask_blend_epi32(0xf800, b01g1, r12b2)); + b = v_uint16x32(_mm512_permutex2var_epi16(bgr1, _v512_set_epu16(42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 29, 26, 23, 20, 17, + 14, 11, 8, 5, 2, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43), g20r0)); + c = v_uint16x32(_mm512_alignr_epi32(r12b2, g20r0, 11)); +} + +inline void v_load_deinterleave( const unsigned* ptr, v_uint32x16& a, v_uint32x16& b, v_uint32x16& c ) +{ + __m512i bgr0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgr1 = _mm512_loadu_si512((const __m512i*)(ptr + 16)); + __m512i bgr2 = _mm512_loadu_si512((const __m512i*)(ptr + 32)); + + __m512i mask0 = _v512_set_epu32(29, 26, 23, 20, 17, 30, 27, 24, 21, 18, 15, 12, 9, 6, 3, 0); + __m512i b01r1 = _mm512_permutex2var_epi32(bgr0, mask0, bgr1); + __m512i g12b2 = _mm512_permutex2var_epi32(bgr1, mask0, bgr2); + __m512i r20g0 = _mm512_permutex2var_epi32(bgr2, mask0, bgr0); + + a = v_uint32x16(_mm512_mask_blend_epi32(0xf800, b01r1, g12b2)); + b = v_uint32x16(_mm512_alignr_epi32(g12b2, r20g0, 11)); + c = v_uint32x16(_mm512_permutex2var_epi32(bgr1, _v512_set_epu32(21, 20, 19, 18, 17, 16, 13, 10, 7, 4, 1, 26, 25, 24, 23, 22), r20g0)); +} + +inline void v_load_deinterleave( const uint64* ptr, v_uint64x8& a, v_uint64x8& b, v_uint64x8& c ) +{ + __m512i bgr0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgr1 = _mm512_loadu_si512((const __m512i*)(ptr + 8)); + __m512i bgr2 = _mm512_loadu_si512((const __m512i*)(ptr + 16)); + + __m512i mask0 = _v512_set_epu64(13, 10, 15, 12, 9, 6, 3, 0); + __m512i b01g1 = _mm512_permutex2var_epi64(bgr0, mask0, bgr1); + __m512i r12b2 = _mm512_permutex2var_epi64(bgr1, mask0, bgr2); + __m512i g20r0 = _mm512_permutex2var_epi64(bgr2, mask0, bgr0); + + a = v_uint64x8(_mm512_mask_blend_epi64(0xc0, b01g1, r12b2)); + c = v_uint64x8(_mm512_alignr_epi64(r12b2, g20r0, 6)); + b = v_uint64x8(_mm512_permutex2var_epi64(bgr1, _v512_set_epu64(10, 9, 8, 5, 2, 13, 12, 11), g20r0)); +} + +inline void v_load_deinterleave( const uchar* ptr, v_uint8x64& a, v_uint8x64& b, v_uint8x64& c, v_uint8x64& d ) +{ + __m512i bgra0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgra1 = _mm512_loadu_si512((const __m512i*)(ptr + 64)); + __m512i bgra2 = _mm512_loadu_si512((const __m512i*)(ptr + 128)); + __m512i bgra3 = _mm512_loadu_si512((const __m512i*)(ptr + 192)); + +#if CV_AVX_512VBMI + __m512i mask0 = _v512_set_epu8(126, 124, 122, 120, 118, 116, 114, 112, 110, 108, 106, 104, 102, 100, 98, 96, + 94, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, + 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, + 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu8(127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 99, 97, + 95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65, + 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1); + + __m512i br01 = _mm512_permutex2var_epi8(bgra0, mask0, bgra1); + __m512i ga01 = _mm512_permutex2var_epi8(bgra0, mask1, bgra1); + __m512i br23 = _mm512_permutex2var_epi8(bgra2, mask0, bgra3); + __m512i ga23 = _mm512_permutex2var_epi8(bgra2, mask1, bgra3); + + a = v_uint8x64(_mm512_permutex2var_epi8(br01, mask0, br23)); + c = v_uint8x64(_mm512_permutex2var_epi8(br01, mask1, br23)); + b = v_uint8x64(_mm512_permutex2var_epi8(ga01, mask0, ga23)); + d = v_uint8x64(_mm512_permutex2var_epi8(ga01, mask1, ga23)); +#else + __m512i mask = _mm512_set4_epi32(0x0f0b0703, 0x0e0a0602, 0x0d090501, 0x0c080400); + __m512i b0g0r0a0 = _mm512_shuffle_epi8(bgra0, mask); + __m512i b1g1r1a1 = _mm512_shuffle_epi8(bgra1, mask); + __m512i b2g2r2a2 = _mm512_shuffle_epi8(bgra2, mask); + __m512i b3g3r3a3 = _mm512_shuffle_epi8(bgra3, mask); + + __m512i mask0 = _v512_set_epu32(30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu32(31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1); + + __m512i br01 = _mm512_permutex2var_epi32(b0g0r0a0, mask0, b1g1r1a1); + __m512i ga01 = _mm512_permutex2var_epi32(b0g0r0a0, mask1, b1g1r1a1); + __m512i br23 = _mm512_permutex2var_epi32(b2g2r2a2, mask0, b3g3r3a3); + __m512i ga23 = _mm512_permutex2var_epi32(b2g2r2a2, mask1, b3g3r3a3); + + a = v_uint8x64(_mm512_permutex2var_epi32(br01, mask0, br23)); + c = v_uint8x64(_mm512_permutex2var_epi32(br01, mask1, br23)); + b = v_uint8x64(_mm512_permutex2var_epi32(ga01, mask0, ga23)); + d = v_uint8x64(_mm512_permutex2var_epi32(ga01, mask1, ga23)); +#endif +} + +inline void v_load_deinterleave( const ushort* ptr, v_uint16x32& a, v_uint16x32& b, v_uint16x32& c, v_uint16x32& d ) +{ + __m512i bgra0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgra1 = _mm512_loadu_si512((const __m512i*)(ptr + 32)); + __m512i bgra2 = _mm512_loadu_si512((const __m512i*)(ptr + 64)); + __m512i bgra3 = _mm512_loadu_si512((const __m512i*)(ptr + 96)); + + __m512i mask0 = _v512_set_epu16(62, 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, + 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu16(63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, + 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1); + + __m512i br01 = _mm512_permutex2var_epi16(bgra0, mask0, bgra1); + __m512i ga01 = _mm512_permutex2var_epi16(bgra0, mask1, bgra1); + __m512i br23 = _mm512_permutex2var_epi16(bgra2, mask0, bgra3); + __m512i ga23 = _mm512_permutex2var_epi16(bgra2, mask1, bgra3); + + a = v_uint16x32(_mm512_permutex2var_epi16(br01, mask0, br23)); + c = v_uint16x32(_mm512_permutex2var_epi16(br01, mask1, br23)); + b = v_uint16x32(_mm512_permutex2var_epi16(ga01, mask0, ga23)); + d = v_uint16x32(_mm512_permutex2var_epi16(ga01, mask1, ga23)); +} + +inline void v_load_deinterleave( const unsigned* ptr, v_uint32x16& a, v_uint32x16& b, v_uint32x16& c, v_uint32x16& d ) +{ + __m512i bgra0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgra1 = _mm512_loadu_si512((const __m512i*)(ptr + 16)); + __m512i bgra2 = _mm512_loadu_si512((const __m512i*)(ptr + 32)); + __m512i bgra3 = _mm512_loadu_si512((const __m512i*)(ptr + 48)); + + __m512i mask0 = _v512_set_epu32(30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu32(31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1); + + __m512i br01 = _mm512_permutex2var_epi32(bgra0, mask0, bgra1); + __m512i ga01 = _mm512_permutex2var_epi32(bgra0, mask1, bgra1); + __m512i br23 = _mm512_permutex2var_epi32(bgra2, mask0, bgra3); + __m512i ga23 = _mm512_permutex2var_epi32(bgra2, mask1, bgra3); + + a = v_uint32x16(_mm512_permutex2var_epi32(br01, mask0, br23)); + c = v_uint32x16(_mm512_permutex2var_epi32(br01, mask1, br23)); + b = v_uint32x16(_mm512_permutex2var_epi32(ga01, mask0, ga23)); + d = v_uint32x16(_mm512_permutex2var_epi32(ga01, mask1, ga23)); +} + +inline void v_load_deinterleave( const uint64* ptr, v_uint64x8& a, v_uint64x8& b, v_uint64x8& c, v_uint64x8& d ) +{ + __m512i bgra0 = _mm512_loadu_si512((const __m512i*)ptr); + __m512i bgra1 = _mm512_loadu_si512((const __m512i*)(ptr + 8)); + __m512i bgra2 = _mm512_loadu_si512((const __m512i*)(ptr + 16)); + __m512i bgra3 = _mm512_loadu_si512((const __m512i*)(ptr + 24)); + + __m512i mask0 = _v512_set_epu64(14, 12, 10, 8, 6, 4, 2, 0); + __m512i mask1 = _v512_set_epu64(15, 13, 11, 9, 7, 5, 3, 1); + + __m512i br01 = _mm512_permutex2var_epi64(bgra0, mask0, bgra1); + __m512i ga01 = _mm512_permutex2var_epi64(bgra0, mask1, bgra1); + __m512i br23 = _mm512_permutex2var_epi64(bgra2, mask0, bgra3); + __m512i ga23 = _mm512_permutex2var_epi64(bgra2, mask1, bgra3); + + a = v_uint64x8(_mm512_permutex2var_epi64(br01, mask0, br23)); + c = v_uint64x8(_mm512_permutex2var_epi64(br01, mask1, br23)); + b = v_uint64x8(_mm512_permutex2var_epi64(ga01, mask0, ga23)); + d = v_uint64x8(_mm512_permutex2var_epi64(ga01, mask1, ga23)); +} + +///////////////////////////// store interleave ///////////////////////////////////// + +inline void v_store_interleave( uchar* ptr, const v_uint8x64& x, const v_uint8x64& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint8x64 low, high; + v_zip(x, y, low, high); + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, low.val); + _mm512_stream_si512((__m512i*)(ptr + 64), high.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, low.val); + _mm512_store_si512((__m512i*)(ptr + 64), high.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, low.val); + _mm512_storeu_si512((__m512i*)(ptr + 64), high.val); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x32& x, const v_uint16x32& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint16x32 low, high; + v_zip(x, y, low, high); + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, low.val); + _mm512_stream_si512((__m512i*)(ptr + 32), high.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, low.val); + _mm512_store_si512((__m512i*)(ptr + 32), high.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, low.val); + _mm512_storeu_si512((__m512i*)(ptr + 32), high.val); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x16& x, const v_uint32x16& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint32x16 low, high; + v_zip(x, y, low, high); + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, low.val); + _mm512_stream_si512((__m512i*)(ptr + 16), high.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, low.val); + _mm512_store_si512((__m512i*)(ptr + 16), high.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, low.val); + _mm512_storeu_si512((__m512i*)(ptr + 16), high.val); + } +} + +inline void v_store_interleave( uint64* ptr, const v_uint64x8& x, const v_uint64x8& y, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint64x8 low, high; + v_zip(x, y, low, high); + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, low.val); + _mm512_stream_si512((__m512i*)(ptr + 8), high.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, low.val); + _mm512_store_si512((__m512i*)(ptr + 8), high.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, low.val); + _mm512_storeu_si512((__m512i*)(ptr + 8), high.val); + } +} + +inline void v_store_interleave( uchar* ptr, const v_uint8x64& a, const v_uint8x64& b, const v_uint8x64& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ +#if CV_AVX_512VBMI + __m512i mask0 = _v512_set_epu8(127, 84, 20, 126, 83, 19, 125, 82, 18, 124, 81, 17, 123, 80, 16, 122, + 79, 15, 121, 78, 14, 120, 77, 13, 119, 76, 12, 118, 75, 11, 117, 74, + 10, 116, 73, 9, 115, 72, 8, 114, 71, 7, 113, 70, 6, 112, 69, 5, + 111, 68, 4, 110, 67, 3, 109, 66, 2, 108, 65, 1, 107, 64, 0, 106); + __m512i mask1 = _v512_set_epu8( 21, 42, 105, 20, 41, 104, 19, 40, 103, 18, 39, 102, 17, 38, 101, 16, + 37, 100, 15, 36, 99, 14, 35, 98, 13, 34, 97, 12, 33, 96, 11, 32, + 95, 10, 31, 94, 9, 30, 93, 8, 29, 92, 7, 28, 91, 6, 27, 90, + 5, 26, 89, 4, 25, 88, 3, 24, 87, 2, 23, 86, 1, 22, 85, 0); + __m512i mask2 = _v512_set_epu8(106, 127, 63, 105, 126, 62, 104, 125, 61, 103, 124, 60, 102, 123, 59, 101, + 122, 58, 100, 121, 57, 99, 120, 56, 98, 119, 55, 97, 118, 54, 96, 117, + 53, 95, 116, 52, 94, 115, 51, 93, 114, 50, 92, 113, 49, 91, 112, 48, + 90, 111, 47, 89, 110, 46, 88, 109, 45, 87, 108, 44, 86, 107, 43, 85); + __m512i r2g0r0 = _mm512_permutex2var_epi8(b.val, mask0, c.val); + __m512i b0r1b1 = _mm512_permutex2var_epi8(a.val, mask1, c.val); + __m512i g1b2g2 = _mm512_permutex2var_epi8(a.val, mask2, b.val); + + __m512i bgr0 = _mm512_mask_blend_epi8(0x9249249249249249, r2g0r0, b0r1b1); + __m512i bgr1 = _mm512_mask_blend_epi8(0x9249249249249249, b0r1b1, g1b2g2); + __m512i bgr2 = _mm512_mask_blend_epi8(0x9249249249249249, g1b2g2, r2g0r0); +#else + __m512i g1g0 = _mm512_shuffle_epi8(b.val, _mm512_set4_epi32(0x0e0f0c0d, 0x0a0b0809, 0x06070405, 0x02030001)); + __m512i b0g0 = _mm512_mask_blend_epi8(0xAAAAAAAAAAAAAAAA, a.val, g1g0); + __m512i r0b1 = _mm512_mask_blend_epi8(0xAAAAAAAAAAAAAAAA, c.val, a.val); + __m512i g1r1 = _mm512_mask_blend_epi8(0xAAAAAAAAAAAAAAAA, g1g0, c.val); + + __m512i mask0 = _v512_set_epu16(42, 10, 31, 41, 9, 30, 40, 8, 29, 39, 7, 28, 38, 6, 27, 37, + 5, 26, 36, 4, 25, 35, 3, 24, 34, 2, 23, 33, 1, 22, 32, 0); + __m512i mask1 = _v512_set_epu16(21, 52, 41, 20, 51, 40, 19, 50, 39, 18, 49, 38, 17, 48, 37, 16, + 47, 36, 15, 46, 35, 14, 45, 34, 13, 44, 33, 12, 43, 32, 11, 42); + __m512i mask2 = _v512_set_epu16(63, 31, 20, 62, 30, 19, 61, 29, 18, 60, 28, 17, 59, 27, 16, 58, + 26, 15, 57, 25, 14, 56, 24, 13, 55, 23, 12, 54, 22, 11, 53, 21); + __m512i b0g0b2 = _mm512_permutex2var_epi16(b0g0, mask0, r0b1); + __m512i r1b1r0 = _mm512_permutex2var_epi16(b0g0, mask1, g1r1); + __m512i g2r2g1 = _mm512_permutex2var_epi16(r0b1, mask2, g1r1); + + __m512i bgr0 = _mm512_mask_blend_epi16(0x24924924, b0g0b2, r1b1r0); + __m512i bgr1 = _mm512_mask_blend_epi16(0x24924924, r1b1r0, g2r2g1); + __m512i bgr2 = _mm512_mask_blend_epi16(0x24924924, g2r2g1, b0g0b2); +#endif + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgr0); + _mm512_stream_si512((__m512i*)(ptr + 64), bgr1); + _mm512_stream_si512((__m512i*)(ptr + 128), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgr0); + _mm512_store_si512((__m512i*)(ptr + 64), bgr1); + _mm512_store_si512((__m512i*)(ptr + 128), bgr2); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgr0); + _mm512_storeu_si512((__m512i*)(ptr + 64), bgr1); + _mm512_storeu_si512((__m512i*)(ptr + 128), bgr2); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x32& a, const v_uint16x32& b, const v_uint16x32& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m512i mask0 = _v512_set_epu16(42, 10, 31, 41, 9, 30, 40, 8, 29, 39, 7, 28, 38, 6, 27, 37, + 5, 26, 36, 4, 25, 35, 3, 24, 34, 2, 23, 33, 1, 22, 32, 0); + __m512i mask1 = _v512_set_epu16(21, 52, 41, 20, 51, 40, 19, 50, 39, 18, 49, 38, 17, 48, 37, 16, + 47, 36, 15, 46, 35, 14, 45, 34, 13, 44, 33, 12, 43, 32, 11, 42); + __m512i mask2 = _v512_set_epu16(63, 31, 20, 62, 30, 19, 61, 29, 18, 60, 28, 17, 59, 27, 16, 58, + 26, 15, 57, 25, 14, 56, 24, 13, 55, 23, 12, 54, 22, 11, 53, 21); + __m512i b0g0b2 = _mm512_permutex2var_epi16(a.val, mask0, b.val); + __m512i r1b1r0 = _mm512_permutex2var_epi16(a.val, mask1, c.val); + __m512i g2r2g1 = _mm512_permutex2var_epi16(b.val, mask2, c.val); + + __m512i bgr0 = _mm512_mask_blend_epi16(0x24924924, b0g0b2, r1b1r0); + __m512i bgr1 = _mm512_mask_blend_epi16(0x24924924, r1b1r0, g2r2g1); + __m512i bgr2 = _mm512_mask_blend_epi16(0x24924924, g2r2g1, b0g0b2); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgr0); + _mm512_stream_si512((__m512i*)(ptr + 32), bgr1); + _mm512_stream_si512((__m512i*)(ptr + 64), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgr0); + _mm512_store_si512((__m512i*)(ptr + 32), bgr1); + _mm512_store_si512((__m512i*)(ptr + 64), bgr2); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgr0); + _mm512_storeu_si512((__m512i*)(ptr + 32), bgr1); + _mm512_storeu_si512((__m512i*)(ptr + 64), bgr2); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x16& a, const v_uint32x16& b, const v_uint32x16& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m512i mask0 = _v512_set_epu32(26, 31, 15, 25, 30, 14, 24, 29, 13, 23, 28, 12, 22, 27, 11, 21); + __m512i mask1 = _v512_set_epu32(31, 10, 25, 30, 9, 24, 29, 8, 23, 28, 7, 22, 27, 6, 21, 26); + __m512i g1b2g2 = _mm512_permutex2var_epi32(a.val, mask0, b.val); + __m512i r2r1b1 = _mm512_permutex2var_epi32(a.val, mask1, c.val); + + __m512i bgr0 = _mm512_mask_expand_epi32(_mm512_mask_expand_epi32(_mm512_maskz_expand_epi32(0x9249, a.val), 0x2492, b.val), 0x4924, c.val); + __m512i bgr1 = _mm512_mask_blend_epi32(0x9249, r2r1b1, g1b2g2); + __m512i bgr2 = _mm512_mask_blend_epi32(0x9249, g1b2g2, r2r1b1); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgr0); + _mm512_stream_si512((__m512i*)(ptr + 16), bgr1); + _mm512_stream_si512((__m512i*)(ptr + 32), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgr0); + _mm512_store_si512((__m512i*)(ptr + 16), bgr1); + _mm512_store_si512((__m512i*)(ptr + 32), bgr2); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgr0); + _mm512_storeu_si512((__m512i*)(ptr + 16), bgr1); + _mm512_storeu_si512((__m512i*)(ptr + 32), bgr2); + } +} + +inline void v_store_interleave( uint64* ptr, const v_uint64x8& a, const v_uint64x8& b, const v_uint64x8& c, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + __m512i mask0 = _v512_set_epu64( 5, 12, 7, 4, 11, 6, 3, 10); + __m512i mask1 = _v512_set_epu64(15, 7, 4, 14, 6, 3, 13, 5); + __m512i r1b1b2 = _mm512_permutex2var_epi64(a.val, mask0, c.val); + __m512i g2r2g1 = _mm512_permutex2var_epi64(b.val, mask1, c.val); + + __m512i bgr0 = _mm512_mask_expand_epi64(_mm512_mask_expand_epi64(_mm512_maskz_expand_epi64(0x49, a.val), 0x92, b.val), 0x24, c.val); + __m512i bgr1 = _mm512_mask_blend_epi64(0xdb, g2r2g1, r1b1b2); + __m512i bgr2 = _mm512_mask_blend_epi64(0xdb, r1b1b2, g2r2g1); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgr0); + _mm512_stream_si512((__m512i*)(ptr + 8), bgr1); + _mm512_stream_si512((__m512i*)(ptr + 16), bgr2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgr0); + _mm512_store_si512((__m512i*)(ptr + 8), bgr1); + _mm512_store_si512((__m512i*)(ptr + 16), bgr2); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgr0); + _mm512_storeu_si512((__m512i*)(ptr + 8), bgr1); + _mm512_storeu_si512((__m512i*)(ptr + 16), bgr2); + } +} + +inline void v_store_interleave( uchar* ptr, const v_uint8x64& a, const v_uint8x64& b, + const v_uint8x64& c, const v_uint8x64& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint8x64 br01, br23, ga01, ga23; + v_zip(a, c, br01, br23); + v_zip(b, d, ga01, ga23); + v_uint8x64 bgra0, bgra1, bgra2, bgra3; + v_zip(br01, ga01, bgra0, bgra1); + v_zip(br23, ga23, bgra2, bgra3); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgra0.val); + _mm512_stream_si512((__m512i*)(ptr + 64), bgra1.val); + _mm512_stream_si512((__m512i*)(ptr + 128), bgra2.val); + _mm512_stream_si512((__m512i*)(ptr + 192), bgra3.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgra0.val); + _mm512_store_si512((__m512i*)(ptr + 64), bgra1.val); + _mm512_store_si512((__m512i*)(ptr + 128), bgra2.val); + _mm512_store_si512((__m512i*)(ptr + 192), bgra3.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgra0.val); + _mm512_storeu_si512((__m512i*)(ptr + 64), bgra1.val); + _mm512_storeu_si512((__m512i*)(ptr + 128), bgra2.val); + _mm512_storeu_si512((__m512i*)(ptr + 192), bgra3.val); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x32& a, const v_uint16x32& b, + const v_uint16x32& c, const v_uint16x32& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint16x32 br01, br23, ga01, ga23; + v_zip(a, c, br01, br23); + v_zip(b, d, ga01, ga23); + v_uint16x32 bgra0, bgra1, bgra2, bgra3; + v_zip(br01, ga01, bgra0, bgra1); + v_zip(br23, ga23, bgra2, bgra3); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgra0.val); + _mm512_stream_si512((__m512i*)(ptr + 32), bgra1.val); + _mm512_stream_si512((__m512i*)(ptr + 64), bgra2.val); + _mm512_stream_si512((__m512i*)(ptr + 96), bgra3.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgra0.val); + _mm512_store_si512((__m512i*)(ptr + 32), bgra1.val); + _mm512_store_si512((__m512i*)(ptr + 64), bgra2.val); + _mm512_store_si512((__m512i*)(ptr + 96), bgra3.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgra0.val); + _mm512_storeu_si512((__m512i*)(ptr + 32), bgra1.val); + _mm512_storeu_si512((__m512i*)(ptr + 64), bgra2.val); + _mm512_storeu_si512((__m512i*)(ptr + 96), bgra3.val); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x16& a, const v_uint32x16& b, + const v_uint32x16& c, const v_uint32x16& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint32x16 br01, br23, ga01, ga23; + v_zip(a, c, br01, br23); + v_zip(b, d, ga01, ga23); + v_uint32x16 bgra0, bgra1, bgra2, bgra3; + v_zip(br01, ga01, bgra0, bgra1); + v_zip(br23, ga23, bgra2, bgra3); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgra0.val); + _mm512_stream_si512((__m512i*)(ptr + 16), bgra1.val); + _mm512_stream_si512((__m512i*)(ptr + 32), bgra2.val); + _mm512_stream_si512((__m512i*)(ptr + 48), bgra3.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgra0.val); + _mm512_store_si512((__m512i*)(ptr + 16), bgra1.val); + _mm512_store_si512((__m512i*)(ptr + 32), bgra2.val); + _mm512_store_si512((__m512i*)(ptr + 48), bgra3.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgra0.val); + _mm512_storeu_si512((__m512i*)(ptr + 16), bgra1.val); + _mm512_storeu_si512((__m512i*)(ptr + 32), bgra2.val); + _mm512_storeu_si512((__m512i*)(ptr + 48), bgra3.val); + } +} + +inline void v_store_interleave( uint64* ptr, const v_uint64x8& a, const v_uint64x8& b, + const v_uint64x8& c, const v_uint64x8& d, + hal::StoreMode mode=hal::STORE_UNALIGNED ) +{ + v_uint64x8 br01, br23, ga01, ga23; + v_zip(a, c, br01, br23); + v_zip(b, d, ga01, ga23); + v_uint64x8 bgra0, bgra1, bgra2, bgra3; + v_zip(br01, ga01, bgra0, bgra1); + v_zip(br23, ga23, bgra2, bgra3); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm512_stream_si512((__m512i*)ptr, bgra0.val); + _mm512_stream_si512((__m512i*)(ptr + 8), bgra1.val); + _mm512_stream_si512((__m512i*)(ptr + 16), bgra2.val); + _mm512_stream_si512((__m512i*)(ptr + 24), bgra3.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm512_store_si512((__m512i*)ptr, bgra0.val); + _mm512_store_si512((__m512i*)(ptr + 8), bgra1.val); + _mm512_store_si512((__m512i*)(ptr + 16), bgra2.val); + _mm512_store_si512((__m512i*)(ptr + 24), bgra3.val); + } + else + { + _mm512_storeu_si512((__m512i*)ptr, bgra0.val); + _mm512_storeu_si512((__m512i*)(ptr + 8), bgra1.val); + _mm512_storeu_si512((__m512i*)(ptr + 16), bgra2.val); + _mm512_storeu_si512((__m512i*)(ptr + 24), bgra3.val); + } +} + +#define OPENCV_HAL_IMPL_AVX512_LOADSTORE_INTERLEAVE(_Tpvec0, _Tp0, suffix0, _Tpvec1, _Tp1, suffix1) \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0 ) \ +{ \ + _Tpvec1 a1, b1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ +} \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0, _Tpvec0& c0 ) \ +{ \ + _Tpvec1 a1, b1, c1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1, c1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ + c0 = v_reinterpret_as_##suffix0(c1); \ +} \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0, _Tpvec0& c0, _Tpvec0& d0 ) \ +{ \ + _Tpvec1 a1, b1, c1, d1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1, c1, d1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ + c0 = v_reinterpret_as_##suffix0(c1); \ + d0 = v_reinterpret_as_##suffix0(d1); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, \ + hal::StoreMode mode=hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, mode); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, const _Tpvec0& c0, \ + hal::StoreMode mode=hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + _Tpvec1 c1 = v_reinterpret_as_##suffix1(c0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, c1, mode); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, \ + const _Tpvec0& c0, const _Tpvec0& d0, \ + hal::StoreMode mode=hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + _Tpvec1 c1 = v_reinterpret_as_##suffix1(c0); \ + _Tpvec1 d1 = v_reinterpret_as_##suffix1(d0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, c1, d1, mode); \ +} + +OPENCV_HAL_IMPL_AVX512_LOADSTORE_INTERLEAVE(v_int8x64, schar, s8, v_uint8x64, uchar, u8) +OPENCV_HAL_IMPL_AVX512_LOADSTORE_INTERLEAVE(v_int16x32, short, s16, v_uint16x32, ushort, u16) +OPENCV_HAL_IMPL_AVX512_LOADSTORE_INTERLEAVE(v_int32x16, int, s32, v_uint32x16, unsigned, u32) +OPENCV_HAL_IMPL_AVX512_LOADSTORE_INTERLEAVE(v_float32x16, float, f32, v_uint32x16, unsigned, u32) +OPENCV_HAL_IMPL_AVX512_LOADSTORE_INTERLEAVE(v_int64x8, int64, s64, v_uint64x8, uint64, u64) +OPENCV_HAL_IMPL_AVX512_LOADSTORE_INTERLEAVE(v_float64x8, double, f64, v_uint64x8, uint64, u64) + +////////// Mask and checks ///////// + +/** Mask **/ +inline int64 v_signmask(const v_int8x64& a) { return (int64)_mm512_movepi8_mask(a.val); } +inline int v_signmask(const v_int16x32& a) { return (int)_mm512_cmp_epi16_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_LT); } +inline int v_signmask(const v_int32x16& a) { return (int)_mm512_cmp_epi32_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_LT); } +inline int v_signmask(const v_int64x8& a) { return (int)_mm512_cmp_epi64_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_LT); } + +inline int64 v_signmask(const v_uint8x64& a) { return v_signmask(v_reinterpret_as_s8(a)); } +inline int v_signmask(const v_uint16x32& a) { return v_signmask(v_reinterpret_as_s16(a)); } +inline int v_signmask(const v_uint32x16& a) { return v_signmask(v_reinterpret_as_s32(a)); } +inline int v_signmask(const v_uint64x8& a) { return v_signmask(v_reinterpret_as_s64(a)); } +inline int v_signmask(const v_float32x16& a) { return v_signmask(v_reinterpret_as_s32(a)); } +inline int v_signmask(const v_float64x8& a) { return v_signmask(v_reinterpret_as_s64(a)); } + +/** Checks **/ +inline bool v_check_all(const v_int8x64& a) { return !(bool)_mm512_cmp_epi8_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_NLT); } +inline bool v_check_any(const v_int8x64& a) { return (bool)_mm512_movepi8_mask(a.val); } +inline bool v_check_all(const v_int16x32& a) { return !(bool)_mm512_cmp_epi16_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_NLT); } +inline bool v_check_any(const v_int16x32& a) { return (bool)_mm512_cmp_epi16_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_LT); } +inline bool v_check_all(const v_int32x16& a) { return !(bool)_mm512_cmp_epi32_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_NLT); } +inline bool v_check_any(const v_int32x16& a) { return (bool)_mm512_cmp_epi32_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_LT); } +inline bool v_check_all(const v_int64x8& a) { return !(bool)_mm512_cmp_epi64_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_NLT); } +inline bool v_check_any(const v_int64x8& a) { return (bool)_mm512_cmp_epi64_mask(a.val, _mm512_setzero_si512(), _MM_CMPINT_LT); } + +inline bool v_check_all(const v_float32x16& a) { return v_check_all(v_reinterpret_as_s32(a)); } +inline bool v_check_any(const v_float32x16& a) { return v_check_any(v_reinterpret_as_s32(a)); } +inline bool v_check_all(const v_float64x8& a) { return v_check_all(v_reinterpret_as_s64(a)); } +inline bool v_check_any(const v_float64x8& a) { return v_check_any(v_reinterpret_as_s64(a)); } +inline bool v_check_all(const v_uint8x64& a) { return v_check_all(v_reinterpret_as_s8(a)); } +inline bool v_check_all(const v_uint16x32& a) { return v_check_all(v_reinterpret_as_s16(a)); } +inline bool v_check_all(const v_uint32x16& a) { return v_check_all(v_reinterpret_as_s32(a)); } +inline bool v_check_all(const v_uint64x8& a) { return v_check_all(v_reinterpret_as_s64(a)); } +inline bool v_check_any(const v_uint8x64& a) { return v_check_any(v_reinterpret_as_s8(a)); } +inline bool v_check_any(const v_uint16x32& a) { return v_check_any(v_reinterpret_as_s16(a)); } +inline bool v_check_any(const v_uint32x16& a) { return v_check_any(v_reinterpret_as_s32(a)); } +inline bool v_check_any(const v_uint64x8& a) { return v_check_any(v_reinterpret_as_s64(a)); } + +inline int v_scan_forward(const v_int8x64& a) +{ + int64 mask = _mm512_movepi8_mask(a.val); + int mask32 = (int)mask; + return mask != 0 ? mask32 != 0 ? trailingZeros32(mask32) : 32 + trailingZeros32((int)(mask >> 32)) : 0; +} +inline int v_scan_forward(const v_uint8x64& a) { return v_scan_forward(v_reinterpret_as_s8(a)); } +inline int v_scan_forward(const v_int16x32& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))); } +inline int v_scan_forward(const v_uint16x32& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))); } +inline int v_scan_forward(const v_int32x16& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))) / 2; } +inline int v_scan_forward(const v_uint32x16& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))) / 2; } +inline int v_scan_forward(const v_float32x16& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))) / 2; } +inline int v_scan_forward(const v_int64x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))) / 4; } +inline int v_scan_forward(const v_uint64x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))) / 4; } +inline int v_scan_forward(const v_float64x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s16(a))) / 4; } + +inline void v512_cleanup() { _mm256_zeroall(); } + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} // cv:: + +#endif // OPENCV_HAL_INTRIN_AVX_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_cpp.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_cpp.hpp new file mode 100755 index 0000000..884de80 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_cpp.hpp @@ -0,0 +1,2383 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HAL_INTRIN_CPP_HPP +#define OPENCV_HAL_INTRIN_CPP_HPP + +#include +#include +#include +#include "opencv2/core/saturate.hpp" + +namespace cv +{ + +#ifndef CV_DOXYGEN +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN +#endif + +/** @addtogroup core_hal_intrin + +"Universal intrinsics" is a types and functions set intended to simplify vectorization of code on +different platforms. Currently there are two supported SIMD extensions: __SSE/SSE2__ on x86 +architectures and __NEON__ on ARM architectures, both allow working with 128 bit registers +containing packed values of different types. In case when there is no SIMD extension available +during compilation, fallback C++ implementation of intrinsics will be chosen and code will work as +expected although it could be slower. + +### Types + +There are several types representing 128-bit register as a vector of packed values, each type is +implemented as a structure based on a one SIMD register. + +- cv::v_uint8x16 and cv::v_int8x16: sixteen 8-bit integer values (unsigned/signed) - char +- cv::v_uint16x8 and cv::v_int16x8: eight 16-bit integer values (unsigned/signed) - short +- cv::v_uint32x4 and cv::v_int32x4: four 32-bit integer values (unsgined/signed) - int +- cv::v_uint64x2 and cv::v_int64x2: two 64-bit integer values (unsigned/signed) - int64 +- cv::v_float32x4: four 32-bit floating point values (signed) - float +- cv::v_float64x2: two 64-bit floating point valies (signed) - double + +@note +cv::v_float64x2 is not implemented in NEON variant, if you want to use this type, don't forget to +check the CV_SIMD128_64F preprocessor definition: +@code +#if CV_SIMD128_64F +//... +#endif +@endcode + +### Load and store operations + +These operations allow to set contents of the register explicitly or by loading it from some memory +block and to save contents of the register to memory block. + +- Constructors: +@ref v_reg::v_reg(const _Tp *ptr) "from memory", +@ref v_reg::v_reg(_Tp s0, _Tp s1) "from two values", ... +- Other create methods: +@ref v_setall_s8, @ref v_setall_u8, ..., +@ref v_setzero_u8, @ref v_setzero_s8, ... +- Memory operations: +@ref v_load, @ref v_load_aligned, @ref v_load_low, @ref v_load_halves, +@ref v_store, @ref v_store_aligned, +@ref v_store_high, @ref v_store_low + +### Value reordering + +These operations allow to reorder or recombine elements in one or multiple vectors. + +- Interleave, deinterleave (2, 3 and 4 channels): @ref v_load_deinterleave, @ref v_store_interleave +- Expand: @ref v_load_expand, @ref v_load_expand_q, @ref v_expand, @ref v_expand_low, @ref v_expand_high +- Pack: @ref v_pack, @ref v_pack_u, @ref v_pack_b, @ref v_rshr_pack, @ref v_rshr_pack_u, +@ref v_pack_store, @ref v_pack_u_store, @ref v_rshr_pack_store, @ref v_rshr_pack_u_store +- Recombine: @ref v_zip, @ref v_recombine, @ref v_combine_low, @ref v_combine_high +- Extract: @ref v_extract + + +### Arithmetic, bitwise and comparison operations + +Element-wise binary and unary operations. + +- Arithmetics: +@ref operator +(const v_reg &a, const v_reg &b) "+", +@ref operator -(const v_reg &a, const v_reg &b) "-", +@ref operator *(const v_reg &a, const v_reg &b) "*", +@ref operator /(const v_reg &a, const v_reg &b) "/", +@ref v_mul_expand + +- Non-saturating arithmetics: @ref v_add_wrap, @ref v_sub_wrap + +- Bitwise shifts: +@ref operator <<(const v_reg &a, int s) "<<", +@ref operator >>(const v_reg &a, int s) ">>", +@ref v_shl, @ref v_shr + +- Bitwise logic: +@ref operator&(const v_reg &a, const v_reg &b) "&", +@ref operator |(const v_reg &a, const v_reg &b) "|", +@ref operator ^(const v_reg &a, const v_reg &b) "^", +@ref operator ~(const v_reg &a) "~" + +- Comparison: +@ref operator >(const v_reg &a, const v_reg &b) ">", +@ref operator >=(const v_reg &a, const v_reg &b) ">=", +@ref operator <(const v_reg &a, const v_reg &b) "<", +@ref operator <=(const v_reg &a, const v_reg &b) "<=", +@ref operator==(const v_reg &a, const v_reg &b) "==", +@ref operator !=(const v_reg &a, const v_reg &b) "!=" + +- min/max: @ref v_min, @ref v_max + +### Reduce and mask + +Most of these operations return only one value. + +- Reduce: @ref v_reduce_min, @ref v_reduce_max, @ref v_reduce_sum, @ref v_popcount +- Mask: @ref v_signmask, @ref v_check_all, @ref v_check_any, @ref v_select + +### Other math + +- Some frequent operations: @ref v_sqrt, @ref v_invsqrt, @ref v_magnitude, @ref v_sqr_magnitude +- Absolute values: @ref v_abs, @ref v_absdiff, @ref v_absdiffs + +### Conversions + +Different type conversions and casts: + +- Rounding: @ref v_round, @ref v_floor, @ref v_ceil, @ref v_trunc, +- To float: @ref v_cvt_f32, @ref v_cvt_f64 +- Reinterpret: @ref v_reinterpret_as_u8, @ref v_reinterpret_as_s8, ... + +### Matrix operations + +In these operations vectors represent matrix rows/columns: @ref v_dotprod, @ref v_matmul, @ref v_transpose4x4 + +### Usability + +Most operations are implemented only for some subset of the available types, following matrices +shows the applicability of different operations to the types. + +Regular integers: + +| Operations\\Types | uint 8x16 | int 8x16 | uint 16x8 | int 16x8 | uint 32x4 | int 32x4 | +|-------------------|:-:|:-:|:-:|:-:|:-:|:-:| +|load, store | x | x | x | x | x | x | +|interleave | x | x | x | x | x | x | +|expand | x | x | x | x | x | x | +|expand_low | x | x | x | x | x | x | +|expand_high | x | x | x | x | x | x | +|expand_q | x | x | | | | | +|add, sub | x | x | x | x | x | x | +|add_wrap, sub_wrap | x | x | x | x | | | +|mul_wrap | x | x | x | x | | | +|mul | x | x | x | x | x | x | +|mul_expand | x | x | x | x | x | | +|compare | x | x | x | x | x | x | +|shift | | | x | x | x | x | +|dotprod | | | | x | | | +|logical | x | x | x | x | x | x | +|min, max | x | x | x | x | x | x | +|absdiff | x | x | x | x | x | x | +|absdiffs | | x | | x | | | +|reduce | | | | | x | x | +|mask | x | x | x | x | x | x | +|pack | x | x | x | x | x | x | +|pack_u | x | | x | | | | +|pack_b | x | | | | | | +|unpack | x | x | x | x | x | x | +|extract | x | x | x | x | x | x | +|rotate (lanes) | x | x | x | x | x | x | +|cvt_flt32 | | | | | | x | +|cvt_flt64 | | | | | | x | +|transpose4x4 | | | | | x | x | + +Big integers: + +| Operations\\Types | uint 64x2 | int 64x2 | +|-------------------|:-:|:-:| +|load, store | x | x | +|add, sub | x | x | +|shift | x | x | +|logical | x | x | +|extract | x | x | +|rotate (lanes) | x | x | + +Floating point: + +| Operations\\Types | float 32x4 | float 64x2 | +|-------------------|:-:|:-:| +|load, store | x | x | +|interleave | x | | +|add, sub | x | x | +|mul | x | x | +|div | x | x | +|compare | x | x | +|min, max | x | x | +|absdiff | x | x | +|reduce | x | | +|mask | x | x | +|unpack | x | x | +|cvt_flt32 | | x | +|cvt_flt64 | x | | +|sqrt, abs | x | x | +|float math | x | x | +|transpose4x4 | x | | +|extract | x | x | +|rotate (lanes) | x | x | + + @{ */ + +template struct v_reg +{ +//! @cond IGNORED + typedef _Tp lane_type; + enum { nlanes = n }; +// !@endcond + + /** @brief Constructor + + Initializes register with data from memory + @param ptr pointer to memory block with data for register */ + explicit v_reg(const _Tp* ptr) { for( int i = 0; i < n; i++ ) s[i] = ptr[i]; } + + /** @brief Constructor + + Initializes register with two 64-bit values */ + v_reg(_Tp s0, _Tp s1) { s[0] = s0; s[1] = s1; } + + /** @brief Constructor + + Initializes register with four 32-bit values */ + v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3) { s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; } + + /** @brief Constructor + + Initializes register with eight 16-bit values */ + v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3, + _Tp s4, _Tp s5, _Tp s6, _Tp s7) + { + s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; + s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7; + } + + /** @brief Constructor + + Initializes register with sixteen 8-bit values */ + v_reg(_Tp s0, _Tp s1, _Tp s2, _Tp s3, + _Tp s4, _Tp s5, _Tp s6, _Tp s7, + _Tp s8, _Tp s9, _Tp s10, _Tp s11, + _Tp s12, _Tp s13, _Tp s14, _Tp s15) + { + s[0] = s0; s[1] = s1; s[2] = s2; s[3] = s3; + s[4] = s4; s[5] = s5; s[6] = s6; s[7] = s7; + s[8] = s8; s[9] = s9; s[10] = s10; s[11] = s11; + s[12] = s12; s[13] = s13; s[14] = s14; s[15] = s15; + } + + /** @brief Default constructor + + Does not initialize anything*/ + v_reg() {} + + /** @brief Copy constructor */ + v_reg(const v_reg<_Tp, n> & r) + { + for( int i = 0; i < n; i++ ) + s[i] = r.s[i]; + } + /** @brief Access first value + + Returns value of the first lane according to register type, for example: + @code{.cpp} + v_int32x4 r(1, 2, 3, 4); + int v = r.get0(); // returns 1 + v_uint64x2 r(1, 2); + uint64_t v = r.get0(); // returns 1 + @endcode + */ + _Tp get0() const { return s[0]; } + +//! @cond IGNORED + _Tp get(const int i) const { return s[i]; } + v_reg<_Tp, n> high() const + { + v_reg<_Tp, n> c; + int i; + for( i = 0; i < n/2; i++ ) + { + c.s[i] = s[i+(n/2)]; + c.s[i+(n/2)] = 0; + } + return c; + } + + static v_reg<_Tp, n> zero() + { + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = (_Tp)0; + return c; + } + + static v_reg<_Tp, n> all(_Tp s) + { + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = s; + return c; + } + + template v_reg<_Tp2, n2> reinterpret_as() const + { + size_t bytes = std::min(sizeof(_Tp2)*n2, sizeof(_Tp)*n); + v_reg<_Tp2, n2> c; + std::memcpy(&c.s[0], &s[0], bytes); + return c; + } + + _Tp s[n]; +//! @endcond +}; + +/** @brief Sixteen 8-bit unsigned integer values */ +typedef v_reg v_uint8x16; +/** @brief Sixteen 8-bit signed integer values */ +typedef v_reg v_int8x16; +/** @brief Eight 16-bit unsigned integer values */ +typedef v_reg v_uint16x8; +/** @brief Eight 16-bit signed integer values */ +typedef v_reg v_int16x8; +/** @brief Four 32-bit unsigned integer values */ +typedef v_reg v_uint32x4; +/** @brief Four 32-bit signed integer values */ +typedef v_reg v_int32x4; +/** @brief Four 32-bit floating point values (single precision) */ +typedef v_reg v_float32x4; +/** @brief Two 64-bit floating point values (double precision) */ +typedef v_reg v_float64x2; +/** @brief Two 64-bit unsigned integer values */ +typedef v_reg v_uint64x2; +/** @brief Two 64-bit signed integer values */ +typedef v_reg v_int64x2; + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_BIN_OP(bin_op) \ +template inline v_reg<_Tp, n> \ + operator bin_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ + return c; \ +} \ +template inline v_reg<_Tp, n>& \ + operator bin_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + for( int i = 0; i < n; i++ ) \ + a.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ + return a; \ +} + +/** @brief Add values + +For all types. */ +OPENCV_HAL_IMPL_BIN_OP(+) + +/** @brief Subtract values + +For all types. */ +OPENCV_HAL_IMPL_BIN_OP(-) + +/** @brief Multiply values + +For 16- and 32-bit integer types and floating types. */ +OPENCV_HAL_IMPL_BIN_OP(*) + +/** @brief Divide values + +For floating types only. */ +OPENCV_HAL_IMPL_BIN_OP(/) + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_BIT_OP(bit_op) \ +template inline v_reg<_Tp, n> operator bit_op \ + (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + typedef typename V_TypeTraits<_Tp>::int_type itype; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)(V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \ + V_TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \ + return c; \ +} \ +template inline v_reg<_Tp, n>& operator \ + bit_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + typedef typename V_TypeTraits<_Tp>::int_type itype; \ + for( int i = 0; i < n; i++ ) \ + a.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)(V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) bit_op \ + V_TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \ + return a; \ +} + +/** @brief Bitwise AND + +Only for integer types. */ +OPENCV_HAL_IMPL_BIT_OP(&) + +/** @brief Bitwise OR + +Only for integer types. */ +OPENCV_HAL_IMPL_BIT_OP(|) + +/** @brief Bitwise XOR + +Only for integer types.*/ +OPENCV_HAL_IMPL_BIT_OP(^) + +/** @brief Bitwise NOT + +Only for integer types.*/ +template inline v_reg<_Tp, n> operator ~ (const v_reg<_Tp, n>& a) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int(~V_TypeTraits<_Tp>::reinterpret_int(a.s[i])); + } + return c; +} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_MATH_FUNC(func, cfunc, _Tp2) \ +template inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a) \ +{ \ + v_reg<_Tp2, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = cfunc(a.s[i]); \ + return c; \ +} + +/** @brief Square root of elements + +Only for floating point types.*/ +OPENCV_HAL_IMPL_MATH_FUNC(v_sqrt, std::sqrt, _Tp) + +//! @cond IGNORED +OPENCV_HAL_IMPL_MATH_FUNC(v_sin, std::sin, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_cos, std::cos, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_exp, std::exp, _Tp) +OPENCV_HAL_IMPL_MATH_FUNC(v_log, std::log, _Tp) +//! @endcond + +/** @brief Absolute value of elements + +Only for floating point types.*/ +OPENCV_HAL_IMPL_MATH_FUNC(v_abs, (typename V_TypeTraits<_Tp>::abs_type)std::abs, + typename V_TypeTraits<_Tp>::abs_type) + +/** @brief Round elements + +Only for floating point types.*/ +OPENCV_HAL_IMPL_MATH_FUNC(v_round, cvRound, int) + +/** @brief Floor elements + +Only for floating point types.*/ +OPENCV_HAL_IMPL_MATH_FUNC(v_floor, cvFloor, int) + +/** @brief Ceil elements + +Only for floating point types.*/ +OPENCV_HAL_IMPL_MATH_FUNC(v_ceil, cvCeil, int) + +/** @brief Truncate elements + +Only for floating point types.*/ +OPENCV_HAL_IMPL_MATH_FUNC(v_trunc, int, int) + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_MINMAX_FUNC(func, cfunc) \ +template inline v_reg<_Tp, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = cfunc(a.s[i], b.s[i]); \ + return c; \ +} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(func, cfunc) \ +template inline _Tp func(const v_reg<_Tp, n>& a) \ +{ \ + _Tp c = a.s[0]; \ + for( int i = 1; i < n; i++ ) \ + c = cfunc(c, a.s[i]); \ + return c; \ +} + +/** @brief Choose min values for each pair + +Scheme: +@code +{A1 A2 ...} +{B1 B2 ...} +-------------- +{min(A1,B1) min(A2,B2) ...} +@endcode +For all types except 64-bit integer. */ +OPENCV_HAL_IMPL_MINMAX_FUNC(v_min, std::min) + +/** @brief Choose max values for each pair + +Scheme: +@code +{A1 A2 ...} +{B1 B2 ...} +-------------- +{max(A1,B1) max(A2,B2) ...} +@endcode +For all types except 64-bit integer. */ +OPENCV_HAL_IMPL_MINMAX_FUNC(v_max, std::max) + +/** @brief Find one min value + +Scheme: +@code +{A1 A2 A3 ...} => min(A1,A2,A3,...) +@endcode +For 32-bit integer and 32-bit floating point types. */ +OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(v_reduce_min, std::min) + +/** @brief Find one max value + +Scheme: +@code +{A1 A2 A3 ...} => max(A1,A2,A3,...) +@endcode +For 32-bit integer and 32-bit floating point types. */ +OPENCV_HAL_IMPL_REDUCE_MINMAX_FUNC(v_reduce_max, std::max) + +static const unsigned char popCountTable[] = +{ + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, +}; +/** @brief Count the 1 bits in the vector lanes and return result as corresponding unsigned type + +Scheme: +@code +{A1 A2 A3 ...} => {popcount(A1), popcount(A2), popcount(A3), ...} +@endcode +For all integer types. */ +template +inline v_reg::abs_type, n> v_popcount(const v_reg<_Tp, n>& a) +{ + v_reg::abs_type, n> b = v_reg::abs_type, n>::zero(); + for (int i = 0; i < (int)(n*sizeof(_Tp)); i++) + b.s[i/sizeof(_Tp)] += popCountTable[v_reinterpret_as_u8(a).s[i]]; + return b; +} + + +//! @cond IGNORED +template +inline void v_minmax( const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + v_reg<_Tp, n>& minval, v_reg<_Tp, n>& maxval ) +{ + for( int i = 0; i < n; i++ ) + { + minval.s[i] = std::min(a.s[i], b.s[i]); + maxval.s[i] = std::max(a.s[i], b.s[i]); + } +} +//! @endcond + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_CMP_OP(cmp_op) \ +template \ +inline v_reg<_Tp, n> operator cmp_op(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + typedef typename V_TypeTraits<_Tp>::int_type itype; \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int((itype)-(int)(a.s[i] cmp_op b.s[i])); \ + return c; \ +} + +/** @brief Less-than comparison + +For all types except 64-bit integer values. */ +OPENCV_HAL_IMPL_CMP_OP(<) + +/** @brief Greater-than comparison + +For all types except 64-bit integer values. */ +OPENCV_HAL_IMPL_CMP_OP(>) + +/** @brief Less-than or equal comparison + +For all types except 64-bit integer values. */ +OPENCV_HAL_IMPL_CMP_OP(<=) + +/** @brief Greater-than or equal comparison + +For all types except 64-bit integer values. */ +OPENCV_HAL_IMPL_CMP_OP(>=) + +/** @brief Equal comparison + +For all types except 64-bit integer values. */ +OPENCV_HAL_IMPL_CMP_OP(==) + +/** @brief Not equal comparison + +For all types except 64-bit integer values. */ +OPENCV_HAL_IMPL_CMP_OP(!=) + +template +inline v_reg v_not_nan(const v_reg& a) +{ + typedef typename V_TypeTraits::int_type itype; + v_reg c; + for (int i = 0; i < n; i++) + c.s[i] = V_TypeTraits::reinterpret_from_int((itype)-(int)(a.s[i] == a.s[i])); + return c; +} +template +inline v_reg v_not_nan(const v_reg& a) +{ + typedef typename V_TypeTraits::int_type itype; + v_reg c; + for (int i = 0; i < n; i++) + c.s[i] = V_TypeTraits::reinterpret_from_int((itype)-(int)(a.s[i] == a.s[i])); + return c; +} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_ARITHM_OP(func, bin_op, cast_op, _Tp2) \ +template \ +inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + typedef _Tp2 rtype; \ + v_reg c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = cast_op(a.s[i] bin_op b.s[i]); \ + return c; \ +} + +/** @brief Add values without saturation + +For 8- and 16-bit integer values. */ +OPENCV_HAL_IMPL_ARITHM_OP(v_add_wrap, +, (_Tp), _Tp) + +/** @brief Subtract values without saturation + +For 8- and 16-bit integer values. */ +OPENCV_HAL_IMPL_ARITHM_OP(v_sub_wrap, -, (_Tp), _Tp) + +/** @brief Multiply values without saturation + +For 8- and 16-bit integer values. */ +OPENCV_HAL_IMPL_ARITHM_OP(v_mul_wrap, *, (_Tp), _Tp) + +//! @cond IGNORED +template inline T _absdiff(T a, T b) +{ + return a > b ? a - b : b - a; +} +//! @endcond + +/** @brief Absolute difference + +Returns \f$ |a - b| \f$ converted to corresponding unsigned type. +Example: +@code{.cpp} +v_int32x4 a, b; // {1, 2, 3, 4} and {4, 3, 2, 1} +v_uint32x4 c = v_absdiff(a, b); // result is {3, 1, 1, 3} +@endcode +For 8-, 16-, 32-bit integer source types. */ +template +inline v_reg::abs_type, n> v_absdiff(const v_reg<_Tp, n>& a, const v_reg<_Tp, n> & b) +{ + typedef typename V_TypeTraits<_Tp>::abs_type rtype; + v_reg c; + const rtype mask = (rtype)(std::numeric_limits<_Tp>::is_signed ? (1 << (sizeof(rtype)*8 - 1)) : 0); + for( int i = 0; i < n; i++ ) + { + rtype ua = a.s[i] ^ mask; + rtype ub = b.s[i] ^ mask; + c.s[i] = _absdiff(ua, ub); + } + return c; +} + +/** @overload + +For 32-bit floating point values */ +inline v_float32x4 v_absdiff(const v_float32x4& a, const v_float32x4& b) +{ + v_float32x4 c; + for( int i = 0; i < c.nlanes; i++ ) + c.s[i] = _absdiff(a.s[i], b.s[i]); + return c; +} + +/** @overload + +For 64-bit floating point values */ +inline v_float64x2 v_absdiff(const v_float64x2& a, const v_float64x2& b) +{ + v_float64x2 c; + for( int i = 0; i < c.nlanes; i++ ) + c.s[i] = _absdiff(a.s[i], b.s[i]); + return c; +} + +/** @brief Saturating absolute difference + +Returns \f$ saturate(|a - b|) \f$ . +For 8-, 16-bit signed integer source types. */ +template +inline v_reg<_Tp, n> v_absdiffs(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++) + c.s[i] = saturate_cast<_Tp>(std::abs(a.s[i] - b.s[i])); + return c; +} + +/** @brief Inversed square root + +Returns \f$ 1/sqrt(a) \f$ +For floating point types only. */ +template +inline v_reg<_Tp, n> v_invsqrt(const v_reg<_Tp, n>& a) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = 1.f/std::sqrt(a.s[i]); + return c; +} + +/** @brief Magnitude + +Returns \f$ sqrt(a^2 + b^2) \f$ +For floating point types only. */ +template +inline v_reg<_Tp, n> v_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = std::sqrt(a.s[i]*a.s[i] + b.s[i]*b.s[i]); + return c; +} + +/** @brief Square of the magnitude + +Returns \f$ a^2 + b^2 \f$ +For floating point types only. */ +template +inline v_reg<_Tp, n> v_sqr_magnitude(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = a.s[i]*a.s[i] + b.s[i]*b.s[i]; + return c; +} + +/** @brief Multiply and add + + Returns \f$ a*b + c \f$ + For floating point types and signed 32bit int only. */ +template +inline v_reg<_Tp, n> v_fma(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + const v_reg<_Tp, n>& c) +{ + v_reg<_Tp, n> d; + for( int i = 0; i < n; i++ ) + d.s[i] = a.s[i]*b.s[i] + c.s[i]; + return d; +} + +/** @brief A synonym for v_fma */ +template +inline v_reg<_Tp, n> v_muladd(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + const v_reg<_Tp, n>& c) +{ + return v_fma(a, b, c); +} + +/** @brief Dot product of elements + +Multiply values in two registers and sum adjacent result pairs. +Scheme: +@code + {A1 A2 ...} // 16-bit +x {B1 B2 ...} // 16-bit +------------- +{A1B1+A2B2 ...} // 32-bit +@endcode +Implemented only for 16-bit signed source type (v_int16x8). +*/ +template inline v_reg::w_type, n/2> + v_dotprod(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + typedef typename V_TypeTraits<_Tp>::w_type w_type; + v_reg c; + for( int i = 0; i < (n/2); i++ ) + c.s[i] = (w_type)a.s[i*2]*b.s[i*2] + (w_type)a.s[i*2+1]*b.s[i*2+1]; + return c; +} + +/** @brief Dot product of elements + +Same as cv::v_dotprod, but add a third element to the sum of adjacent pairs. +Scheme: +@code + {A1 A2 ...} // 16-bit +x {B1 B2 ...} // 16-bit +------------- + {A1B1+A2B2+C1 ...} // 32-bit + +@endcode +Implemented only for 16-bit signed source type (v_int16x8). +*/ +template inline v_reg::w_type, n/2> + v_dotprod(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, const v_reg::w_type, n / 2>& c) +{ + typedef typename V_TypeTraits<_Tp>::w_type w_type; + v_reg s; + for( int i = 0; i < (n/2); i++ ) + s.s[i] = (w_type)a.s[i*2]*b.s[i*2] + (w_type)a.s[i*2+1]*b.s[i*2+1] + c.s[i]; + return s; +} + +/** @brief Multiply and expand + +Multiply values two registers and store results in two registers with wider pack type. +Scheme: +@code + {A B C D} // 32-bit +x {E F G H} // 32-bit +--------------- +{AE BF} // 64-bit + {CG DH} // 64-bit +@endcode +Example: +@code{.cpp} +v_uint32x4 a, b; // {1,2,3,4} and {2,2,2,2} +v_uint64x2 c, d; // results +v_mul_expand(a, b, c, d); // c, d = {2,4}, {6, 8} +@endcode +Implemented only for 16- and unsigned 32-bit source types (v_int16x8, v_uint16x8, v_uint32x4). +*/ +template inline void v_mul_expand(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + v_reg::w_type, n/2>& c, + v_reg::w_type, n/2>& d) +{ + typedef typename V_TypeTraits<_Tp>::w_type w_type; + for( int i = 0; i < (n/2); i++ ) + { + c.s[i] = (w_type)a.s[i]*b.s[i]; + d.s[i] = (w_type)a.s[i+(n/2)]*b.s[i+(n/2)]; + } +} + +/** @brief Multiply and extract high part + +Multiply values two registers and store high part of the results. +Implemented only for 16-bit source types (v_int16x8, v_uint16x8). Returns \f$ a*b >> 16 \f$ +*/ +template inline v_reg<_Tp, n> v_mul_hi(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + typedef typename V_TypeTraits<_Tp>::w_type w_type; + v_reg<_Tp, n> c; + for (int i = 0; i < n; i++) + c.s[i] = (_Tp)(((w_type)a.s[i] * b.s[i]) >> sizeof(_Tp)*8); + return c; +} + +//! @cond IGNORED +template inline void v_hsum(const v_reg<_Tp, n>& a, + v_reg::w_type, n/2>& c) +{ + typedef typename V_TypeTraits<_Tp>::w_type w_type; + for( int i = 0; i < (n/2); i++ ) + { + c.s[i] = (w_type)a.s[i*2] + a.s[i*2+1]; + } +} +//! @endcond + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_SHIFT_OP(shift_op) \ +template inline v_reg<_Tp, n> operator shift_op(const v_reg<_Tp, n>& a, int imm) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = (_Tp)(a.s[i] shift_op imm); \ + return c; \ +} + +/** @brief Bitwise shift left + +For 16-, 32- and 64-bit integer values. */ +OPENCV_HAL_IMPL_SHIFT_OP(<< ) + +/** @brief Bitwise shift right + +For 16-, 32- and 64-bit integer values. */ +OPENCV_HAL_IMPL_SHIFT_OP(>> ) + +/** @brief Element shift left among vector + +For all type */ +#define OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(suffix,opA,opB) \ +template inline v_reg<_Tp, n> v_rotate_##suffix(const v_reg<_Tp, n>& a) \ +{ \ + v_reg<_Tp, n> b; \ + for (int i = 0; i < n; i++) \ + { \ + int sIndex = i opA imm; \ + if (0 <= sIndex && sIndex < n) \ + { \ + b.s[i] = a.s[sIndex]; \ + } \ + else \ + { \ + b.s[i] = 0; \ + } \ + } \ + return b; \ +} \ +template inline v_reg<_Tp, n> v_rotate_##suffix(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + for (int i = 0; i < n; i++) \ + { \ + int aIndex = i opA imm; \ + int bIndex = i opA imm opB n; \ + if (0 <= bIndex && bIndex < n) \ + { \ + c.s[i] = b.s[bIndex]; \ + } \ + else if (0 <= aIndex && aIndex < n) \ + { \ + c.s[i] = a.s[aIndex]; \ + } \ + else \ + { \ + c.s[i] = 0; \ + } \ + } \ + return c; \ +} + +OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(left, -, +) +OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(right, +, -) + +/** @brief Sum packed values + +Scheme: +@code +{A1 A2 A3 ...} => sum{A1,A2,A3,...} +@endcode +For 32-bit integer and 32-bit floating point types.*/ +template inline typename V_TypeTraits<_Tp>::sum_type v_reduce_sum(const v_reg<_Tp, n>& a) +{ + typename V_TypeTraits<_Tp>::sum_type c = a.s[0]; + for( int i = 1; i < n; i++ ) + c += a.s[i]; + return c; +} + +/** @brief Sums all elements of each input vector, returns the vector of sums + + Scheme: + @code + result[0] = a[0] + a[1] + a[2] + a[3] + result[1] = b[0] + b[1] + b[2] + b[3] + result[2] = c[0] + c[1] + c[2] + c[3] + result[3] = d[0] + d[1] + d[2] + d[3] + @endcode +*/ +inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b, + const v_float32x4& c, const v_float32x4& d) +{ + v_float32x4 r; + r.s[0] = a.s[0] + a.s[1] + a.s[2] + a.s[3]; + r.s[1] = b.s[0] + b.s[1] + b.s[2] + b.s[3]; + r.s[2] = c.s[0] + c.s[1] + c.s[2] + c.s[3]; + r.s[3] = d.s[0] + d.s[1] + d.s[2] + d.s[3]; + return r; +} + +/** @brief Sum absolute differences of values + +Scheme: +@code +{A1 A2 A3 ...} {B1 B2 B3 ...} => sum{ABS(A1-B1),abs(A2-B2),abs(A3-B3),...} +@endcode +For all types except 64-bit types.*/ +template inline typename V_TypeTraits< typename V_TypeTraits<_Tp>::abs_type >::sum_type v_reduce_sad(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + typename V_TypeTraits< typename V_TypeTraits<_Tp>::abs_type >::sum_type c = _absdiff(a.s[0], b.s[0]); + for (int i = 1; i < n; i++) + c += _absdiff(a.s[i], b.s[i]); + return c; +} + +/** @brief Get negative values mask +@deprecated v_signmask depends on a lane count heavily and therefore isn't universal enough + +Returned value is a bit mask with bits set to 1 on places corresponding to negative packed values indexes. +Example: +@code{.cpp} +v_int32x4 r; // set to {-1, -1, 1, 1} +int mask = v_signmask(r); // mask = 3 <== 00000000 00000000 00000000 00000011 +@endcode +For all types except 64-bit. */ +template inline int v_signmask(const v_reg<_Tp, n>& a) +{ + int mask = 0; + for( int i = 0; i < n; i++ ) + mask |= (V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0) << i; + return mask; +} + +/** @brief Get first negative lane index + +Returned value is an index of first negative lane (undefined for input of all positive values) +Example: +@code{.cpp} +v_int32x4 r; // set to {0, 0, -1, -1} +int idx = v_heading_zeros(r); // idx = 2 +@endcode +*/ +template inline int v_scan_forward(const v_reg<_Tp, n>& a) +{ + for (int i = 0; i < n; i++) + if(V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0) + return i; + return 0; +} + +/** @brief Check if all packed values are less than zero + +Unsigned values will be casted to signed: `uchar 254 => char -2`. +For all types except 64-bit. */ +template inline bool v_check_all(const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + if( V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) >= 0 ) + return false; + return true; +} + +/** @brief Check if any of packed values is less than zero + +Unsigned values will be casted to signed: `uchar 254 => char -2`. +For all types except 64-bit. */ +template inline bool v_check_any(const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + if( V_TypeTraits<_Tp>::reinterpret_int(a.s[i]) < 0 ) + return true; + return false; +} + +/** @brief Per-element select (blend operation) + +Return value will be built by combining values _a_ and _b_ using the following scheme: + result[i] = mask[i] ? a[i] : b[i]; + +@note: _mask_ element values are restricted to these values: +- 0: select element from _b_ +- 0xff/0xffff/etc: select element from _a_ +(fully compatible with bitwise-based operator) +*/ +template inline v_reg<_Tp, n> v_select(const v_reg<_Tp, n>& mask, + const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + typedef V_TypeTraits<_Tp> Traits; + typedef typename Traits::int_type int_type; + v_reg<_Tp, n> c; + for( int i = 0; i < n; i++ ) + { + int_type m = Traits::reinterpret_int(mask.s[i]); + CV_DbgAssert(m == 0 || m == (~(int_type)0)); // restrict mask values: 0 or 0xff/0xffff/etc + c.s[i] = m ? a.s[i] : b.s[i]; + } + return c; +} + +/** @brief Expand values to the wider pack type + +Copy contents of register to two registers with 2x wider pack type. +Scheme: +@code + int32x4 int64x2 int64x2 +{A B C D} ==> {A B} , {C D} +@endcode */ +template inline void v_expand(const v_reg<_Tp, n>& a, + v_reg::w_type, n/2>& b0, + v_reg::w_type, n/2>& b1) +{ + for( int i = 0; i < (n/2); i++ ) + { + b0.s[i] = a.s[i]; + b1.s[i] = a.s[i+(n/2)]; + } +} + +/** @brief Expand lower values to the wider pack type + +Same as cv::v_expand, but return lower half of the vector. + +Scheme: +@code + int32x4 int64x2 +{A B C D} ==> {A B} +@endcode */ +template +inline v_reg::w_type, n/2> +v_expand_low(const v_reg<_Tp, n>& a) +{ + v_reg::w_type, n/2> b; + for( int i = 0; i < (n/2); i++ ) + b.s[i] = a.s[i]; + return b; +} + +/** @brief Expand higher values to the wider pack type + +Same as cv::v_expand_low, but expand higher half of the vector instead. + +Scheme: +@code + int32x4 int64x2 +{A B C D} ==> {C D} +@endcode */ +template +inline v_reg::w_type, n/2> +v_expand_high(const v_reg<_Tp, n>& a) +{ + v_reg::w_type, n/2> b; + for( int i = 0; i < (n/2); i++ ) + b.s[i] = a.s[i+(n/2)]; + return b; +} + +//! @cond IGNORED +template inline v_reg::int_type, n> + v_reinterpret_as_int(const v_reg<_Tp, n>& a) +{ + v_reg::int_type, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = V_TypeTraits<_Tp>::reinterpret_int(a.s[i]); + return c; +} + +template inline v_reg::uint_type, n> + v_reinterpret_as_uint(const v_reg<_Tp, n>& a) +{ + v_reg::uint_type, n> c; + for( int i = 0; i < n; i++ ) + c.s[i] = V_TypeTraits<_Tp>::reinterpret_uint(a.s[i]); + return c; +} +//! @endcond + +/** @brief Interleave two vectors + +Scheme: +@code + {A1 A2 A3 A4} + {B1 B2 B3 B4} +--------------- + {A1 B1 A2 B2} and {A3 B3 A4 B4} +@endcode +For all types except 64-bit. +*/ +template inline void v_zip( const v_reg<_Tp, n>& a0, const v_reg<_Tp, n>& a1, + v_reg<_Tp, n>& b0, v_reg<_Tp, n>& b1 ) +{ + int i; + for( i = 0; i < n/2; i++ ) + { + b0.s[i*2] = a0.s[i]; + b0.s[i*2+1] = a1.s[i]; + } + for( ; i < n; i++ ) + { + b1.s[i*2-n] = a0.s[i]; + b1.s[i*2-n+1] = a1.s[i]; + } +} + +/** @brief Load register contents from memory + +@param ptr pointer to memory block with data +@return register object + +@note Returned type will be detected from passed pointer type, for example uchar ==> cv::v_uint8x16, int ==> cv::v_int32x4, etc. + */ +template +inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load(const _Tp* ptr) +{ + return v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128>(ptr); +} + +/** @brief Load register contents from memory (aligned) + +similar to cv::v_load, but source memory block should be aligned (to 16-byte boundary) + */ +template +inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load_aligned(const _Tp* ptr) +{ + return v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128>(ptr); +} + +/** @brief Load 64-bits of data to lower part (high part is undefined). + +@param ptr memory block containing data for first half (0..n/2) + +@code{.cpp} +int lo[2] = { 1, 2 }; +v_int32x4 r = v_load_low(lo); +@endcode + */ +template +inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load_low(const _Tp* ptr) +{ + v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c; + for( int i = 0; i < c.nlanes/2; i++ ) + { + c.s[i] = ptr[i]; + } + return c; +} + +/** @brief Load register contents from two memory blocks + +@param loptr memory block containing data for first half (0..n/2) +@param hiptr memory block containing data for second half (n/2..n) + +@code{.cpp} +int lo[2] = { 1, 2 }, hi[2] = { 3, 4 }; +v_int32x4 r = v_load_halves(lo, hi); +@endcode + */ +template +inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load_halves(const _Tp* loptr, const _Tp* hiptr) +{ + v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c; + for( int i = 0; i < c.nlanes/2; i++ ) + { + c.s[i] = loptr[i]; + c.s[i+c.nlanes/2] = hiptr[i]; + } + return c; +} + +/** @brief Load register contents from memory with double expand + +Same as cv::v_load, but result pack type will be 2x wider than memory type. + +@code{.cpp} +short buf[4] = {1, 2, 3, 4}; // type is int16 +v_int32x4 r = v_load_expand(buf); // r = {1, 2, 3, 4} - type is int32 +@endcode +For 8-, 16-, 32-bit integer source types. */ +template +inline v_reg::w_type, V_TypeTraits<_Tp>::nlanes128 / 2> +v_load_expand(const _Tp* ptr) +{ + typedef typename V_TypeTraits<_Tp>::w_type w_type; + v_reg::nlanes128> c; + for( int i = 0; i < c.nlanes; i++ ) + { + c.s[i] = ptr[i]; + } + return c; +} + +/** @brief Load register contents from memory with quad expand + +Same as cv::v_load_expand, but result type is 4 times wider than source. +@code{.cpp} +char buf[4] = {1, 2, 3, 4}; // type is int8 +v_int32x4 r = v_load_q(buf); // r = {1, 2, 3, 4} - type is int32 +@endcode +For 8-bit integer source types. */ +template +inline v_reg::q_type, V_TypeTraits<_Tp>::nlanes128 / 4> +v_load_expand_q(const _Tp* ptr) +{ + typedef typename V_TypeTraits<_Tp>::q_type q_type; + v_reg::nlanes128> c; + for( int i = 0; i < c.nlanes; i++ ) + { + c.s[i] = ptr[i]; + } + return c; +} + +/** @brief Load and deinterleave (2 channels) + +Load data from memory deinterleave and store to 2 registers. +Scheme: +@code +{A1 B1 A2 B2 ...} ==> {A1 A2 ...}, {B1 B2 ...} +@endcode +For all types except 64-bit. */ +template inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a, + v_reg<_Tp, n>& b) +{ + int i, i2; + for( i = i2 = 0; i < n; i++, i2 += 2 ) + { + a.s[i] = ptr[i2]; + b.s[i] = ptr[i2+1]; + } +} + +/** @brief Load and deinterleave (3 channels) + +Load data from memory deinterleave and store to 3 registers. +Scheme: +@code +{A1 B1 C1 A2 B2 C2 ...} ==> {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...} +@endcode +For all types except 64-bit. */ +template inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a, + v_reg<_Tp, n>& b, v_reg<_Tp, n>& c) +{ + int i, i3; + for( i = i3 = 0; i < n; i++, i3 += 3 ) + { + a.s[i] = ptr[i3]; + b.s[i] = ptr[i3+1]; + c.s[i] = ptr[i3+2]; + } +} + +/** @brief Load and deinterleave (4 channels) + +Load data from memory deinterleave and store to 4 registers. +Scheme: +@code +{A1 B1 C1 D1 A2 B2 C2 D2 ...} ==> {A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}, {D1 D2 ...} +@endcode +For all types except 64-bit. */ +template +inline void v_load_deinterleave(const _Tp* ptr, v_reg<_Tp, n>& a, + v_reg<_Tp, n>& b, v_reg<_Tp, n>& c, + v_reg<_Tp, n>& d) +{ + int i, i4; + for( i = i4 = 0; i < n; i++, i4 += 4 ) + { + a.s[i] = ptr[i4]; + b.s[i] = ptr[i4+1]; + c.s[i] = ptr[i4+2]; + d.s[i] = ptr[i4+3]; + } +} + +/** @brief Interleave and store (2 channels) + +Interleave and store data from 2 registers to memory. +Scheme: +@code +{A1 A2 ...}, {B1 B2 ...} ==> {A1 B1 A2 B2 ...} +@endcode +For all types except 64-bit. */ +template +inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a, + const v_reg<_Tp, n>& b, + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) +{ + int i, i2; + for( i = i2 = 0; i < n; i++, i2 += 2 ) + { + ptr[i2] = a.s[i]; + ptr[i2+1] = b.s[i]; + } +} + +/** @brief Interleave and store (3 channels) + +Interleave and store data from 3 registers to memory. +Scheme: +@code +{A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...} ==> {A1 B1 C1 A2 B2 C2 ...} +@endcode +For all types except 64-bit. */ +template +inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a, + const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c, + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) +{ + int i, i3; + for( i = i3 = 0; i < n; i++, i3 += 3 ) + { + ptr[i3] = a.s[i]; + ptr[i3+1] = b.s[i]; + ptr[i3+2] = c.s[i]; + } +} + +/** @brief Interleave and store (4 channels) + +Interleave and store data from 4 registers to memory. +Scheme: +@code +{A1 A2 ...}, {B1 B2 ...}, {C1 C2 ...}, {D1 D2 ...} ==> {A1 B1 C1 D1 A2 B2 C2 D2 ...} +@endcode +For all types except 64-bit. */ +template inline void v_store_interleave( _Tp* ptr, const v_reg<_Tp, n>& a, + const v_reg<_Tp, n>& b, const v_reg<_Tp, n>& c, + const v_reg<_Tp, n>& d, + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) +{ + int i, i4; + for( i = i4 = 0; i < n; i++, i4 += 4 ) + { + ptr[i4] = a.s[i]; + ptr[i4+1] = b.s[i]; + ptr[i4+2] = c.s[i]; + ptr[i4+3] = d.s[i]; + } +} + +/** @brief Store data to memory + +Store register contents to memory. +Scheme: +@code + REG {A B C D} ==> MEM {A B C D} +@endcode +Pointer can be unaligned. */ +template +inline void v_store(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + ptr[i] = a.s[i]; +} + +/** @brief Store data to memory (lower half) + +Store lower half of register contents to memory. +Scheme: +@code + REG {A B C D} ==> MEM {A B} +@endcode */ +template +inline void v_store_low(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < (n/2); i++ ) + ptr[i] = a.s[i]; +} + +/** @brief Store data to memory (higher half) + +Store higher half of register contents to memory. +Scheme: +@code + REG {A B C D} ==> MEM {C D} +@endcode */ +template +inline void v_store_high(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < (n/2); i++ ) + ptr[i] = a.s[i+(n/2)]; +} + +/** @brief Store data to memory (aligned) + +Store register contents to memory. +Scheme: +@code + REG {A B C D} ==> MEM {A B C D} +@endcode +Pointer __should__ be aligned by 16-byte boundary. */ +template +inline void v_store_aligned(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + ptr[i] = a.s[i]; +} + +template +inline void v_store_aligned_nocache(_Tp* ptr, const v_reg<_Tp, n>& a) +{ + for( int i = 0; i < n; i++ ) + ptr[i] = a.s[i]; +} + +template +inline void v_store_aligned(_Tp* ptr, const v_reg<_Tp, n>& a, hal::StoreMode /*mode*/) +{ + for( int i = 0; i < n; i++ ) + ptr[i] = a.s[i]; +} + +/** @brief Combine vector from first elements of two vectors + +Scheme: +@code + {A1 A2 A3 A4} + {B1 B2 B3 B4} +--------------- + {A1 A2 B1 B2} +@endcode +For all types except 64-bit. */ +template +inline v_reg<_Tp, n> v_combine_low(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < (n/2); i++ ) + { + c.s[i] = a.s[i]; + c.s[i+(n/2)] = b.s[i]; + } + return c; +} + +/** @brief Combine vector from last elements of two vectors + +Scheme: +@code + {A1 A2 A3 A4} + {B1 B2 B3 B4} +--------------- + {A3 A4 B3 B4} +@endcode +For all types except 64-bit. */ +template +inline v_reg<_Tp, n> v_combine_high(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> c; + for( int i = 0; i < (n/2); i++ ) + { + c.s[i] = a.s[i+(n/2)]; + c.s[i+(n/2)] = b.s[i+(n/2)]; + } + return c; +} + +/** @brief Combine two vectors from lower and higher parts of two other vectors + +@code{.cpp} +low = cv::v_combine_low(a, b); +high = cv::v_combine_high(a, b); +@endcode */ +template +inline void v_recombine(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b, + v_reg<_Tp, n>& low, v_reg<_Tp, n>& high) +{ + for( int i = 0; i < (n/2); i++ ) + { + low.s[i] = a.s[i]; + low.s[i+(n/2)] = b.s[i]; + high.s[i] = a.s[i+(n/2)]; + high.s[i+(n/2)] = b.s[i+(n/2)]; + } +} + +/** @brief Vector extract + +Scheme: +@code + {A1 A2 A3 A4} + {B1 B2 B3 B4} +======================== +shift = 1 {A2 A3 A4 B1} +shift = 2 {A3 A4 B1 B2} +shift = 3 {A4 B1 B2 B3} +@endcode +Restriction: 0 <= shift < nlanes + +Usage: +@code +v_int32x4 a, b, c; +c = v_extract<2>(a, b); +@endcode +For all types. */ +template +inline v_reg<_Tp, n> v_extract(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + v_reg<_Tp, n> r; + const int shift = n - s; + int i = 0; + for (; i < shift; ++i) + r.s[i] = a.s[i+s]; + for (; i < n; ++i) + r.s[i] = b.s[i-shift]; + return r; +} + +/** @brief Round + +Rounds each value. Input type is float vector ==> output type is int vector.*/ +template inline v_reg v_round(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = cvRound(a.s[i]); + return c; +} + +/** @overload */ +template inline v_reg v_round(const v_reg& a, const v_reg& b) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvRound(a.s[i]); + c.s[i+n] = cvRound(b.s[i]); + } + return c; +} + +/** @brief Floor + +Floor each value. Input type is float vector ==> output type is int vector.*/ +template inline v_reg v_floor(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = cvFloor(a.s[i]); + return c; +} + +/** @brief Ceil + +Ceil each value. Input type is float vector ==> output type is int vector.*/ +template inline v_reg v_ceil(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = cvCeil(a.s[i]); + return c; +} + +/** @brief Trunc + +Truncate each value. Input type is float vector ==> output type is int vector.*/ +template inline v_reg v_trunc(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (int)(a.s[i]); + return c; +} + +/** @overload */ +template inline v_reg v_round(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvRound(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +/** @overload */ +template inline v_reg v_floor(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvFloor(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +/** @overload */ +template inline v_reg v_ceil(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvCeil(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +/** @overload */ +template inline v_reg v_trunc(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = cvCeil(a.s[i]); + c.s[i+n] = 0; + } + return c; +} + +/** @brief Convert to float + +Supported input type is cv::v_int32x4. */ +template inline v_reg v_cvt_f32(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (float)a.s[i]; + return c; +} + +template inline v_reg v_cvt_f32(const v_reg& a, const v_reg& b) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = (float)a.s[i]; + c.s[i+n] = (float)b.s[i]; + } + return c; +} + +/** @brief Convert to double + +Supported input type is cv::v_int32x4. */ +template inline v_reg v_cvt_f64(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (double)a.s[i]; + return c; +} + +/** @brief Convert to double + +Supported input type is cv::v_float32x4. */ +template inline v_reg v_cvt_f64(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (double)a.s[i]; + return c; +} + +template inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_lut(const _Tp* tab, const int* idx) +{ + v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c; + for (int i = 0; i < V_TypeTraits<_Tp>::nlanes128; i++) + c.s[i] = tab[idx[i]]; + return c; +} +template inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_lut_pairs(const _Tp* tab, const int* idx) +{ + v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c; + for (int i = 0; i < V_TypeTraits<_Tp>::nlanes128; i++) + c.s[i] = tab[idx[i / 2] + i % 2]; + return c; +} +template inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_lut_quads(const _Tp* tab, const int* idx) +{ + v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c; + for (int i = 0; i < V_TypeTraits<_Tp>::nlanes128; i++) + c.s[i] = tab[idx[i / 4] + i % 4]; + return c; +} + +template inline v_reg v_lut(const int* tab, const v_reg& idx) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = tab[idx.s[i]]; + return c; +} + +template inline v_reg v_lut(const unsigned* tab, const v_reg& idx) +{ + v_reg c; + for (int i = 0; i < n; i++) + c.s[i] = tab[idx.s[i]]; + return c; +} + +template inline v_reg v_lut(const float* tab, const v_reg& idx) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = tab[idx.s[i]]; + return c; +} + +template inline v_reg v_lut(const double* tab, const v_reg& idx) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = tab[idx.s[i]]; + return c; +} + +template inline void v_lut_deinterleave(const float* tab, const v_reg& idx, + v_reg& x, v_reg& y) +{ + for( int i = 0; i < n; i++ ) + { + int j = idx.s[i]; + x.s[i] = tab[j]; + y.s[i] = tab[j+1]; + } +} + +template inline void v_lut_deinterleave(const double* tab, const v_reg& idx, + v_reg& x, v_reg& y) +{ + for( int i = 0; i < n; i++ ) + { + int j = idx.s[i]; + x.s[i] = tab[j]; + y.s[i] = tab[j+1]; + } +} + +template inline v_reg<_Tp, n> v_interleave_pairs(const v_reg<_Tp, n>& vec) +{ + v_reg c; + for (int i = 0; i < n/4; i++) + { + c.s[4*i ] = vec.s[4*i ]; + c.s[4*i+1] = vec.s[4*i+2]; + c.s[4*i+2] = vec.s[4*i+1]; + c.s[4*i+3] = vec.s[4*i+3]; + } + return c; +} + +template inline v_reg<_Tp, n> v_interleave_quads(const v_reg<_Tp, n>& vec) +{ + v_reg c; + for (int i = 0; i < n/8; i++) + { + c.s[8*i ] = vec.s[8*i ]; + c.s[8*i+1] = vec.s[8*i+4]; + c.s[8*i+2] = vec.s[8*i+1]; + c.s[8*i+3] = vec.s[8*i+5]; + c.s[8*i+4] = vec.s[8*i+2]; + c.s[8*i+5] = vec.s[8*i+6]; + c.s[8*i+6] = vec.s[8*i+3]; + c.s[8*i+7] = vec.s[8*i+7]; + } + return c; +} + +template inline v_reg<_Tp, n> v_pack_triplets(const v_reg<_Tp, n>& vec) +{ + v_reg c; + for (int i = 0; i < n/4; i++) + { + c.s[3*i ] = vec.s[4*i ]; + c.s[3*i+1] = vec.s[4*i+1]; + c.s[3*i+2] = vec.s[4*i+2]; + } + return c; +} + +/** @brief Transpose 4x4 matrix + +Scheme: +@code +a0 {A1 A2 A3 A4} +a1 {B1 B2 B3 B4} +a2 {C1 C2 C3 C4} +a3 {D1 D2 D3 D4} +=============== +b0 {A1 B1 C1 D1} +b1 {A2 B2 C2 D2} +b2 {A3 B3 C3 D3} +b3 {A4 B4 C4 D4} +@endcode +*/ +template +inline void v_transpose4x4( v_reg<_Tp, 4>& a0, const v_reg<_Tp, 4>& a1, + const v_reg<_Tp, 4>& a2, const v_reg<_Tp, 4>& a3, + v_reg<_Tp, 4>& b0, v_reg<_Tp, 4>& b1, + v_reg<_Tp, 4>& b2, v_reg<_Tp, 4>& b3 ) +{ + b0 = v_reg<_Tp, 4>(a0.s[0], a1.s[0], a2.s[0], a3.s[0]); + b1 = v_reg<_Tp, 4>(a0.s[1], a1.s[1], a2.s[1], a3.s[1]); + b2 = v_reg<_Tp, 4>(a0.s[2], a1.s[2], a2.s[2], a3.s[2]); + b3 = v_reg<_Tp, 4>(a0.s[3], a1.s[3], a2.s[3], a3.s[3]); +} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_INIT_ZERO(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_setzero_##suffix() { return _Tpvec::zero(); } + +//! @name Init with zero +//! @{ +//! @brief Create new vector with zero elements +OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_int8x16, schar, s8) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_int16x8, short, s16) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_int32x4, int, s32) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_float32x4, float, f32) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_float64x2, double, f64) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_uint64x2, uint64, u64) +OPENCV_HAL_IMPL_C_INIT_ZERO(v_int64x2, int64, s64) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_INIT_VAL(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_setall_##suffix(_Tp val) { return _Tpvec::all(val); } + +//! @name Init with value +//! @{ +//! @brief Create new vector with elements set to a specific value +OPENCV_HAL_IMPL_C_INIT_VAL(v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_C_INIT_VAL(v_int8x16, schar, s8) +OPENCV_HAL_IMPL_C_INIT_VAL(v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_C_INIT_VAL(v_int16x8, short, s16) +OPENCV_HAL_IMPL_C_INIT_VAL(v_uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_C_INIT_VAL(v_int32x4, int, s32) +OPENCV_HAL_IMPL_C_INIT_VAL(v_float32x4, float, f32) +OPENCV_HAL_IMPL_C_INIT_VAL(v_float64x2, double, f64) +OPENCV_HAL_IMPL_C_INIT_VAL(v_uint64x2, uint64, u64) +OPENCV_HAL_IMPL_C_INIT_VAL(v_int64x2, int64, s64) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_REINTERPRET(_Tpvec, _Tp, suffix) \ +template inline _Tpvec \ + v_reinterpret_as_##suffix(const v_reg<_Tp0, n0>& a) \ +{ return a.template reinterpret_as<_Tp, _Tpvec::nlanes>(); } + +//! @name Reinterpret +//! @{ +//! @brief Convert vector to different type without modifying underlying data. +OPENCV_HAL_IMPL_C_REINTERPRET(v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_C_REINTERPRET(v_int8x16, schar, s8) +OPENCV_HAL_IMPL_C_REINTERPRET(v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_C_REINTERPRET(v_int16x8, short, s16) +OPENCV_HAL_IMPL_C_REINTERPRET(v_uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_C_REINTERPRET(v_int32x4, int, s32) +OPENCV_HAL_IMPL_C_REINTERPRET(v_float32x4, float, f32) +OPENCV_HAL_IMPL_C_REINTERPRET(v_float64x2, double, f64) +OPENCV_HAL_IMPL_C_REINTERPRET(v_uint64x2, uint64, u64) +OPENCV_HAL_IMPL_C_REINTERPRET(v_int64x2, int64, s64) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_SHIFTL(_Tpvec, _Tp) \ +template inline _Tpvec v_shl(const _Tpvec& a) \ +{ return a << n; } + +//! @name Left shift +//! @{ +//! @brief Shift left +OPENCV_HAL_IMPL_C_SHIFTL(v_uint16x8, ushort) +OPENCV_HAL_IMPL_C_SHIFTL(v_int16x8, short) +OPENCV_HAL_IMPL_C_SHIFTL(v_uint32x4, unsigned) +OPENCV_HAL_IMPL_C_SHIFTL(v_int32x4, int) +OPENCV_HAL_IMPL_C_SHIFTL(v_uint64x2, uint64) +OPENCV_HAL_IMPL_C_SHIFTL(v_int64x2, int64) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_SHIFTR(_Tpvec, _Tp) \ +template inline _Tpvec v_shr(const _Tpvec& a) \ +{ return a >> n; } + +//! @name Right shift +//! @{ +//! @brief Shift right +OPENCV_HAL_IMPL_C_SHIFTR(v_uint16x8, ushort) +OPENCV_HAL_IMPL_C_SHIFTR(v_int16x8, short) +OPENCV_HAL_IMPL_C_SHIFTR(v_uint32x4, unsigned) +OPENCV_HAL_IMPL_C_SHIFTR(v_int32x4, int) +OPENCV_HAL_IMPL_C_SHIFTR(v_uint64x2, uint64) +OPENCV_HAL_IMPL_C_SHIFTR(v_int64x2, int64) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_RSHIFTR(_Tpvec, _Tp) \ +template inline _Tpvec v_rshr(const _Tpvec& a) \ +{ \ + _Tpvec c; \ + for( int i = 0; i < _Tpvec::nlanes; i++ ) \ + c.s[i] = (_Tp)((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \ + return c; \ +} + +//! @name Rounding shift +//! @{ +//! @brief Rounding shift right +OPENCV_HAL_IMPL_C_RSHIFTR(v_uint16x8, ushort) +OPENCV_HAL_IMPL_C_RSHIFTR(v_int16x8, short) +OPENCV_HAL_IMPL_C_RSHIFTR(v_uint32x4, unsigned) +OPENCV_HAL_IMPL_C_RSHIFTR(v_int32x4, int) +OPENCV_HAL_IMPL_C_RSHIFTR(v_uint64x2, uint64) +OPENCV_HAL_IMPL_C_RSHIFTR(v_int64x2, int64) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_PACK(_Tpvec, _Tpnvec, _Tpn, pack_suffix, cast) \ +inline _Tpnvec v_##pack_suffix(const _Tpvec& a, const _Tpvec& b) \ +{ \ + _Tpnvec c; \ + for( int i = 0; i < _Tpvec::nlanes; i++ ) \ + { \ + c.s[i] = cast<_Tpn>(a.s[i]); \ + c.s[i+_Tpvec::nlanes] = cast<_Tpn>(b.s[i]); \ + } \ + return c; \ +} + +//! @name Pack +//! @{ +//! @brief Pack values from two vectors to one +//! +//! Return vector type have twice more elements than input vector types. Variant with _u_ suffix also +//! converts to corresponding unsigned type. +//! +//! - pack: for 16-, 32- and 64-bit integer input types +//! - pack_u: for 16- and 32-bit signed integer input types +//! +//! @note All variants except 64-bit use saturation. +OPENCV_HAL_IMPL_C_PACK(v_uint16x8, v_uint8x16, uchar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK(v_int16x8, v_int8x16, schar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK(v_uint32x4, v_uint16x8, ushort, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK(v_int32x4, v_int16x8, short, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK(v_uint64x2, v_uint32x4, unsigned, pack, static_cast) +OPENCV_HAL_IMPL_C_PACK(v_int64x2, v_int32x4, int, pack, static_cast) +OPENCV_HAL_IMPL_C_PACK(v_int16x8, v_uint8x16, uchar, pack_u, saturate_cast) +OPENCV_HAL_IMPL_C_PACK(v_int32x4, v_uint16x8, ushort, pack_u, saturate_cast) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_RSHR_PACK(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix, cast) \ +template inline _Tpnvec v_rshr_##pack_suffix(const _Tpvec& a, const _Tpvec& b) \ +{ \ + _Tpnvec c; \ + for( int i = 0; i < _Tpvec::nlanes; i++ ) \ + { \ + c.s[i] = cast<_Tpn>((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \ + c.s[i+_Tpvec::nlanes] = cast<_Tpn>((b.s[i] + ((_Tp)1 << (n - 1))) >> n); \ + } \ + return c; \ +} + +//! @name Pack with rounding shift +//! @{ +//! @brief Pack values from two vectors to one with rounding shift +//! +//! Values from the input vectors will be shifted right by _n_ bits with rounding, converted to narrower +//! type and returned in the result vector. Variant with _u_ suffix converts to unsigned type. +//! +//! - pack: for 16-, 32- and 64-bit integer input types +//! - pack_u: for 16- and 32-bit signed integer input types +//! +//! @note All variants except 64-bit use saturation. +OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint16x8, ushort, v_uint8x16, uchar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK(v_int16x8, short, v_int8x16, schar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint32x4, unsigned, v_uint16x8, ushort, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK(v_int32x4, int, v_int16x8, short, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK(v_uint64x2, uint64, v_uint32x4, unsigned, pack, static_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK(v_int64x2, int64, v_int32x4, int, pack, static_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK(v_int16x8, short, v_uint8x16, uchar, pack_u, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK(v_int32x4, int, v_uint16x8, ushort, pack_u, saturate_cast) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_PACK_STORE(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix, cast) \ +inline void v_##pack_suffix##_store(_Tpn* ptr, const _Tpvec& a) \ +{ \ + for( int i = 0; i < _Tpvec::nlanes; i++ ) \ + ptr[i] = cast<_Tpn>(a.s[i]); \ +} + +//! @name Pack and store +//! @{ +//! @brief Store values from the input vector into memory with pack +//! +//! Values will be stored into memory with conversion to narrower type. +//! Variant with _u_ suffix converts to corresponding unsigned type. +//! +//! - pack: for 16-, 32- and 64-bit integer input types +//! - pack_u: for 16- and 32-bit signed integer input types +//! +//! @note All variants except 64-bit use saturation. +OPENCV_HAL_IMPL_C_PACK_STORE(v_uint16x8, ushort, v_uint8x16, uchar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK_STORE(v_int16x8, short, v_int8x16, schar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK_STORE(v_uint32x4, unsigned, v_uint16x8, ushort, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK_STORE(v_int32x4, int, v_int16x8, short, pack, saturate_cast) +OPENCV_HAL_IMPL_C_PACK_STORE(v_uint64x2, uint64, v_uint32x4, unsigned, pack, static_cast) +OPENCV_HAL_IMPL_C_PACK_STORE(v_int64x2, int64, v_int32x4, int, pack, static_cast) +OPENCV_HAL_IMPL_C_PACK_STORE(v_int16x8, short, v_uint8x16, uchar, pack_u, saturate_cast) +OPENCV_HAL_IMPL_C_PACK_STORE(v_int32x4, int, v_uint16x8, ushort, pack_u, saturate_cast) +//! @} + +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(_Tpvec, _Tp, _Tpnvec, _Tpn, pack_suffix, cast) \ +template inline void v_rshr_##pack_suffix##_store(_Tpn* ptr, const _Tpvec& a) \ +{ \ + for( int i = 0; i < _Tpvec::nlanes; i++ ) \ + ptr[i] = cast<_Tpn>((a.s[i] + ((_Tp)1 << (n - 1))) >> n); \ +} + +//! @name Pack and store with rounding shift +//! @{ +//! @brief Store values from the input vector into memory with pack +//! +//! Values will be shifted _n_ bits right with rounding, converted to narrower type and stored into +//! memory. Variant with _u_ suffix converts to unsigned type. +//! +//! - pack: for 16-, 32- and 64-bit integer input types +//! - pack_u: for 16- and 32-bit signed integer input types +//! +//! @note All variants except 64-bit use saturation. +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint16x8, ushort, v_uint8x16, uchar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int16x8, short, v_int8x16, schar, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint32x4, unsigned, v_uint16x8, ushort, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int32x4, int, v_int16x8, short, pack, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_uint64x2, uint64, v_uint32x4, unsigned, pack, static_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int64x2, int64, v_int32x4, int, pack, static_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int16x8, short, v_uint8x16, uchar, pack_u, saturate_cast) +OPENCV_HAL_IMPL_C_RSHR_PACK_STORE(v_int32x4, int, v_uint16x8, ushort, pack_u, saturate_cast) +//! @} + +//! @cond IGNORED +template +inline void _pack_b(_Tpm* mptr, const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) +{ + for (int i = 0; i < n; ++i) + { + mptr[i] = (_Tpm)a.s[i]; + mptr[i + n] = (_Tpm)b.s[i]; + } +} +//! @endcond + +//! @name Pack boolean values +//! @{ +//! @brief Pack boolean values from multiple vectors to one unsigned 8-bit integer vector +//! +//! @note Must provide valid boolean values to guarantee same result for all architectures. + +/** @brief +//! For 16-bit boolean values + +Scheme: +@code +a {0xFFFF 0 0 0xFFFF 0 0xFFFF 0xFFFF 0} +b {0xFFFF 0 0xFFFF 0 0 0xFFFF 0 0xFFFF} +=============== +{ + 0xFF 0 0 0xFF 0 0xFF 0xFF 0 + 0xFF 0 0xFF 0 0 0xFF 0 0xFF +} +@endcode */ + +inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b) +{ + v_uint8x16 mask; + _pack_b(mask.s, a, b); + return mask; +} + +/** @overload +For 32-bit boolean values + +Scheme: +@code +a {0xFFFF.. 0 0 0xFFFF..} +b {0 0xFFFF.. 0xFFFF.. 0} +c {0xFFFF.. 0 0xFFFF.. 0} +d {0 0xFFFF.. 0 0xFFFF..} +=============== +{ + 0xFF 0 0 0xFF 0 0xFF 0xFF 0 + 0xFF 0 0xFF 0 0 0xFF 0 0xFF +} +@endcode */ + +inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b, + const v_uint32x4& c, const v_uint32x4& d) +{ + v_uint8x16 mask; + _pack_b(mask.s, a, b); + _pack_b(mask.s + 8, c, d); + return mask; +} + +/** @overload +For 64-bit boolean values + +Scheme: +@code +a {0xFFFF.. 0} +b {0 0xFFFF..} +c {0xFFFF.. 0} +d {0 0xFFFF..} + +e {0xFFFF.. 0} +f {0xFFFF.. 0} +g {0 0xFFFF..} +h {0 0xFFFF..} +=============== +{ + 0xFF 0 0 0xFF 0xFF 0 0 0xFF + 0xFF 0 0xFF 0 0 0xFF 0 0xFF +} +@endcode */ +inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c, + const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f, + const v_uint64x2& g, const v_uint64x2& h) +{ + v_uint8x16 mask; + _pack_b(mask.s, a, b); + _pack_b(mask.s + 4, c, d); + _pack_b(mask.s + 8, e, f); + _pack_b(mask.s + 12, g, h); + return mask; +} +//! @} + +/** @brief Matrix multiplication + +Scheme: +@code +{A0 A1 A2 A3} |V0| +{B0 B1 B2 B3} |V1| +{C0 C1 C2 C3} |V2| +{D0 D1 D2 D3} x |V3| +==================== +{R0 R1 R2 R3}, where: +R0 = A0V0 + A1V1 + A2V2 + A3V3, +R1 = B0V0 + B1V1 + B2V2 + B3V3 +... +@endcode +*/ +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + return v_float32x4(v.s[0]*m0.s[0] + v.s[1]*m1.s[0] + v.s[2]*m2.s[0] + v.s[3]*m3.s[0], + v.s[0]*m0.s[1] + v.s[1]*m1.s[1] + v.s[2]*m2.s[1] + v.s[3]*m3.s[1], + v.s[0]*m0.s[2] + v.s[1]*m1.s[2] + v.s[2]*m2.s[2] + v.s[3]*m3.s[2], + v.s[0]*m0.s[3] + v.s[1]*m1.s[3] + v.s[2]*m2.s[3] + v.s[3]*m3.s[3]); +} + +/** @brief Matrix multiplication and add + +Scheme: +@code +{A0 A1 A2 } |V0| |D0| +{B0 B1 B2 } |V1| |D1| +{C0 C1 C2 } x |V2| + |D2| +==================== +{R0 R1 R2 R3}, where: +R0 = A0V0 + A1V1 + A2V2 + D0, +R1 = B0V0 + B1V1 + B2V2 + D1 +... +@endcode +*/ +inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + return v_float32x4(v.s[0]*m0.s[0] + v.s[1]*m1.s[0] + v.s[2]*m2.s[0] + m3.s[0], + v.s[0]*m0.s[1] + v.s[1]*m1.s[1] + v.s[2]*m2.s[1] + m3.s[1], + v.s[0]*m0.s[2] + v.s[1]*m1.s[2] + v.s[2]*m2.s[2] + m3.s[2], + v.s[0]*m0.s[3] + v.s[1]*m1.s[3] + v.s[2]*m2.s[3] + m3.s[3]); +} + +////// FP16 support /////// + +inline v_reg::nlanes128> +v_load_expand(const float16_t* ptr) +{ + v_reg::nlanes128> v; + for( int i = 0; i < v.nlanes; i++ ) + { + v.s[i] = ptr[i]; + } + return v; +} + +inline void +v_pack_store(float16_t* ptr, v_reg::nlanes128>& v) +{ + for( int i = 0; i < v.nlanes; i++ ) + { + ptr[i] = float16_t(v.s[i]); + } +} + +inline void v_cleanup() {} + +//! @} + +#ifndef CV_DOXYGEN +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END +#endif +} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_forward.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_forward.hpp new file mode 100755 index 0000000..6873633 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_forward.hpp @@ -0,0 +1,181 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#ifndef CV__SIMD_FORWARD +#error "Need to pre-define forward width" +#endif + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +/** Types **/ +#if CV__SIMD_FORWARD == 1024 +// [todo] 1024 +#error "1024-long ops not implemented yet" +#elif CV__SIMD_FORWARD == 512 +// 512 +#define __CV_VX(fun) v512_##fun +#define __CV_V_UINT8 v_uint8x64 +#define __CV_V_INT8 v_int8x64 +#define __CV_V_UINT16 v_uint16x32 +#define __CV_V_INT16 v_int16x32 +#define __CV_V_UINT32 v_uint32x16 +#define __CV_V_INT32 v_int32x16 +#define __CV_V_UINT64 v_uint64x8 +#define __CV_V_INT64 v_int64x8 +#define __CV_V_FLOAT32 v_float32x16 +#define __CV_V_FLOAT64 v_float64x8 +struct v_uint8x64; +struct v_int8x64; +struct v_uint16x32; +struct v_int16x32; +struct v_uint32x16; +struct v_int32x16; +struct v_uint64x8; +struct v_int64x8; +struct v_float32x16; +struct v_float64x8; +#elif CV__SIMD_FORWARD == 256 +// 256 +#define __CV_VX(fun) v256_##fun +#define __CV_V_UINT8 v_uint8x32 +#define __CV_V_INT8 v_int8x32 +#define __CV_V_UINT16 v_uint16x16 +#define __CV_V_INT16 v_int16x16 +#define __CV_V_UINT32 v_uint32x8 +#define __CV_V_INT32 v_int32x8 +#define __CV_V_UINT64 v_uint64x4 +#define __CV_V_INT64 v_int64x4 +#define __CV_V_FLOAT32 v_float32x8 +#define __CV_V_FLOAT64 v_float64x4 +struct v_uint8x32; +struct v_int8x32; +struct v_uint16x16; +struct v_int16x16; +struct v_uint32x8; +struct v_int32x8; +struct v_uint64x4; +struct v_int64x4; +struct v_float32x8; +struct v_float64x4; +#else +// 128 +#define __CV_VX(fun) v_##fun +#define __CV_V_UINT8 v_uint8x16 +#define __CV_V_INT8 v_int8x16 +#define __CV_V_UINT16 v_uint16x8 +#define __CV_V_INT16 v_int16x8 +#define __CV_V_UINT32 v_uint32x4 +#define __CV_V_INT32 v_int32x4 +#define __CV_V_UINT64 v_uint64x2 +#define __CV_V_INT64 v_int64x2 +#define __CV_V_FLOAT32 v_float32x4 +#define __CV_V_FLOAT64 v_float64x2 +struct v_uint8x16; +struct v_int8x16; +struct v_uint16x8; +struct v_int16x8; +struct v_uint32x4; +struct v_int32x4; +struct v_uint64x2; +struct v_int64x2; +struct v_float32x4; +struct v_float64x2; +#endif + +/** Value reordering **/ + +// Expansion +void v_expand(const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&); +void v_expand(const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&); +void v_expand(const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&); +void v_expand(const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&); +void v_expand(const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&); +void v_expand(const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&); +// Low Expansion +__CV_V_UINT16 v_expand_low(const __CV_V_UINT8&); +__CV_V_INT16 v_expand_low(const __CV_V_INT8&); +__CV_V_UINT32 v_expand_low(const __CV_V_UINT16&); +__CV_V_INT32 v_expand_low(const __CV_V_INT16&); +__CV_V_UINT64 v_expand_low(const __CV_V_UINT32&); +__CV_V_INT64 v_expand_low(const __CV_V_INT32&); +// High Expansion +__CV_V_UINT16 v_expand_high(const __CV_V_UINT8&); +__CV_V_INT16 v_expand_high(const __CV_V_INT8&); +__CV_V_UINT32 v_expand_high(const __CV_V_UINT16&); +__CV_V_INT32 v_expand_high(const __CV_V_INT16&); +__CV_V_UINT64 v_expand_high(const __CV_V_UINT32&); +__CV_V_INT64 v_expand_high(const __CV_V_INT32&); +// Load & Low Expansion +__CV_V_UINT16 __CV_VX(load_expand)(const uchar*); +__CV_V_INT16 __CV_VX(load_expand)(const schar*); +__CV_V_UINT32 __CV_VX(load_expand)(const ushort*); +__CV_V_INT32 __CV_VX(load_expand)(const short*); +__CV_V_UINT64 __CV_VX(load_expand)(const uint*); +__CV_V_INT64 __CV_VX(load_expand)(const int*); +// Load lower 8-bit and expand into 32-bit +__CV_V_UINT32 __CV_VX(load_expand_q)(const uchar*); +__CV_V_INT32 __CV_VX(load_expand_q)(const schar*); + +// Saturating Pack +__CV_V_UINT8 v_pack(const __CV_V_UINT16&, const __CV_V_UINT16&); +__CV_V_INT8 v_pack(const __CV_V_INT16&, const __CV_V_INT16&); +__CV_V_UINT16 v_pack(const __CV_V_UINT32&, const __CV_V_UINT32&); +__CV_V_INT16 v_pack(const __CV_V_INT32&, const __CV_V_INT32&); +// Non-saturating Pack +__CV_V_UINT32 v_pack(const __CV_V_UINT64&, const __CV_V_UINT64&); +__CV_V_INT32 v_pack(const __CV_V_INT64&, const __CV_V_INT64&); +// Pack signed integers with unsigned saturation +__CV_V_UINT8 v_pack_u(const __CV_V_INT16&, const __CV_V_INT16&); +__CV_V_UINT16 v_pack_u(const __CV_V_INT32&, const __CV_V_INT32&); + +/** Arithmetic, bitwise and comparison operations **/ + +// Non-saturating multiply +#if CV_VSX +template +Tvec v_mul_wrap(const Tvec& a, const Tvec& b); +#else +__CV_V_UINT8 v_mul_wrap(const __CV_V_UINT8&, const __CV_V_UINT8&); +__CV_V_INT8 v_mul_wrap(const __CV_V_INT8&, const __CV_V_INT8&); +__CV_V_UINT16 v_mul_wrap(const __CV_V_UINT16&, const __CV_V_UINT16&); +__CV_V_INT16 v_mul_wrap(const __CV_V_INT16&, const __CV_V_INT16&); +#endif + +// Multiply and expand +#if CV_VSX +template +void v_mul_expand(const Tvec& a, const Tvec& b, Twvec& c, Twvec& d); +#else +void v_mul_expand(const __CV_V_UINT8&, const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&); +void v_mul_expand(const __CV_V_INT8&, const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&); +void v_mul_expand(const __CV_V_UINT16&, const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&); +void v_mul_expand(const __CV_V_INT16&, const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&); +void v_mul_expand(const __CV_V_UINT32&, const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&); +void v_mul_expand(const __CV_V_INT32&, const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&); +#endif + +/** Cleanup **/ +#undef CV__SIMD_FORWARD +#undef __CV_VX +#undef __CV_V_UINT8 +#undef __CV_V_INT8 +#undef __CV_V_UINT16 +#undef __CV_V_INT16 +#undef __CV_V_UINT32 +#undef __CV_V_INT32 +#undef __CV_V_UINT64 +#undef __CV_V_INT64 +#undef __CV_V_FLOAT32 +#undef __CV_V_FLOAT64 + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} // cv:: \ No newline at end of file diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_neon.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_neon.hpp new file mode 100755 index 0000000..5617bc2 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_neon.hpp @@ -0,0 +1,1948 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HAL_INTRIN_NEON_HPP +#define OPENCV_HAL_INTRIN_NEON_HPP + +#include +#include "opencv2/core/utility.hpp" + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +#define CV_SIMD128 1 +#if defined(__aarch64__) +#define CV_SIMD128_64F 1 +#else +#define CV_SIMD128_64F 0 +#endif + +#if CV_SIMD128_64F +#define OPENCV_HAL_IMPL_NEON_REINTERPRET(_Tpv, suffix) \ +template static inline \ +_Tpv vreinterpretq_##suffix##_f64(T a) { return (_Tpv) a; } \ +template static inline \ +float64x2_t vreinterpretq_f64_##suffix(T a) { return (float64x2_t) a; } +OPENCV_HAL_IMPL_NEON_REINTERPRET(uint8x16_t, u8) +OPENCV_HAL_IMPL_NEON_REINTERPRET(int8x16_t, s8) +OPENCV_HAL_IMPL_NEON_REINTERPRET(uint16x8_t, u16) +OPENCV_HAL_IMPL_NEON_REINTERPRET(int16x8_t, s16) +OPENCV_HAL_IMPL_NEON_REINTERPRET(uint32x4_t, u32) +OPENCV_HAL_IMPL_NEON_REINTERPRET(int32x4_t, s32) +OPENCV_HAL_IMPL_NEON_REINTERPRET(uint64x2_t, u64) +OPENCV_HAL_IMPL_NEON_REINTERPRET(int64x2_t, s64) +OPENCV_HAL_IMPL_NEON_REINTERPRET(float32x4_t, f32) +#endif + +struct v_uint8x16 +{ + typedef uchar lane_type; + enum { nlanes = 16 }; + + v_uint8x16() {} + explicit v_uint8x16(uint8x16_t v) : val(v) {} + v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15) + { + uchar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15}; + val = vld1q_u8(v); + } + uchar get0() const + { + return vgetq_lane_u8(val, 0); + } + + uint8x16_t val; +}; + +struct v_int8x16 +{ + typedef schar lane_type; + enum { nlanes = 16 }; + + v_int8x16() {} + explicit v_int8x16(int8x16_t v) : val(v) {} + v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15) + { + schar v[] = {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15}; + val = vld1q_s8(v); + } + schar get0() const + { + return vgetq_lane_s8(val, 0); + } + + int8x16_t val; +}; + +struct v_uint16x8 +{ + typedef ushort lane_type; + enum { nlanes = 8 }; + + v_uint16x8() {} + explicit v_uint16x8(uint16x8_t v) : val(v) {} + v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7) + { + ushort v[] = {v0, v1, v2, v3, v4, v5, v6, v7}; + val = vld1q_u16(v); + } + ushort get0() const + { + return vgetq_lane_u16(val, 0); + } + + uint16x8_t val; +}; + +struct v_int16x8 +{ + typedef short lane_type; + enum { nlanes = 8 }; + + v_int16x8() {} + explicit v_int16x8(int16x8_t v) : val(v) {} + v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7) + { + short v[] = {v0, v1, v2, v3, v4, v5, v6, v7}; + val = vld1q_s16(v); + } + short get0() const + { + return vgetq_lane_s16(val, 0); + } + + int16x8_t val; +}; + +struct v_uint32x4 +{ + typedef unsigned lane_type; + enum { nlanes = 4 }; + + v_uint32x4() {} + explicit v_uint32x4(uint32x4_t v) : val(v) {} + v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) + { + unsigned v[] = {v0, v1, v2, v3}; + val = vld1q_u32(v); + } + unsigned get0() const + { + return vgetq_lane_u32(val, 0); + } + + uint32x4_t val; +}; + +struct v_int32x4 +{ + typedef int lane_type; + enum { nlanes = 4 }; + + v_int32x4() {} + explicit v_int32x4(int32x4_t v) : val(v) {} + v_int32x4(int v0, int v1, int v2, int v3) + { + int v[] = {v0, v1, v2, v3}; + val = vld1q_s32(v); + } + int get0() const + { + return vgetq_lane_s32(val, 0); + } + int32x4_t val; +}; + +struct v_float32x4 +{ + typedef float lane_type; + enum { nlanes = 4 }; + + v_float32x4() {} + explicit v_float32x4(float32x4_t v) : val(v) {} + v_float32x4(float v0, float v1, float v2, float v3) + { + float v[] = {v0, v1, v2, v3}; + val = vld1q_f32(v); + } + float get0() const + { + return vgetq_lane_f32(val, 0); + } + float32x4_t val; +}; + +struct v_uint64x2 +{ + typedef uint64 lane_type; + enum { nlanes = 2 }; + + v_uint64x2() {} + explicit v_uint64x2(uint64x2_t v) : val(v) {} + v_uint64x2(uint64 v0, uint64 v1) + { + uint64 v[] = {v0, v1}; + val = vld1q_u64(v); + } + uint64 get0() const + { + return vgetq_lane_u64(val, 0); + } + uint64x2_t val; +}; + +struct v_int64x2 +{ + typedef int64 lane_type; + enum { nlanes = 2 }; + + v_int64x2() {} + explicit v_int64x2(int64x2_t v) : val(v) {} + v_int64x2(int64 v0, int64 v1) + { + int64 v[] = {v0, v1}; + val = vld1q_s64(v); + } + int64 get0() const + { + return vgetq_lane_s64(val, 0); + } + int64x2_t val; +}; + +#if CV_SIMD128_64F +struct v_float64x2 +{ + typedef double lane_type; + enum { nlanes = 2 }; + + v_float64x2() {} + explicit v_float64x2(float64x2_t v) : val(v) {} + v_float64x2(double v0, double v1) + { + double v[] = {v0, v1}; + val = vld1q_f64(v); + } + double get0() const + { + return vgetq_lane_f64(val, 0); + } + float64x2_t val; +}; +#endif + +#define OPENCV_HAL_IMPL_NEON_INIT(_Tpv, _Tp, suffix) \ +inline v_##_Tpv v_setzero_##suffix() { return v_##_Tpv(vdupq_n_##suffix((_Tp)0)); } \ +inline v_##_Tpv v_setall_##suffix(_Tp v) { return v_##_Tpv(vdupq_n_##suffix(v)); } \ +inline _Tpv##_t vreinterpretq_##suffix##_##suffix(_Tpv##_t v) { return v; } \ +inline v_uint8x16 v_reinterpret_as_u8(const v_##_Tpv& v) { return v_uint8x16(vreinterpretq_u8_##suffix(v.val)); } \ +inline v_int8x16 v_reinterpret_as_s8(const v_##_Tpv& v) { return v_int8x16(vreinterpretq_s8_##suffix(v.val)); } \ +inline v_uint16x8 v_reinterpret_as_u16(const v_##_Tpv& v) { return v_uint16x8(vreinterpretq_u16_##suffix(v.val)); } \ +inline v_int16x8 v_reinterpret_as_s16(const v_##_Tpv& v) { return v_int16x8(vreinterpretq_s16_##suffix(v.val)); } \ +inline v_uint32x4 v_reinterpret_as_u32(const v_##_Tpv& v) { return v_uint32x4(vreinterpretq_u32_##suffix(v.val)); } \ +inline v_int32x4 v_reinterpret_as_s32(const v_##_Tpv& v) { return v_int32x4(vreinterpretq_s32_##suffix(v.val)); } \ +inline v_uint64x2 v_reinterpret_as_u64(const v_##_Tpv& v) { return v_uint64x2(vreinterpretq_u64_##suffix(v.val)); } \ +inline v_int64x2 v_reinterpret_as_s64(const v_##_Tpv& v) { return v_int64x2(vreinterpretq_s64_##suffix(v.val)); } \ +inline v_float32x4 v_reinterpret_as_f32(const v_##_Tpv& v) { return v_float32x4(vreinterpretq_f32_##suffix(v.val)); } + +OPENCV_HAL_IMPL_NEON_INIT(uint8x16, uchar, u8) +OPENCV_HAL_IMPL_NEON_INIT(int8x16, schar, s8) +OPENCV_HAL_IMPL_NEON_INIT(uint16x8, ushort, u16) +OPENCV_HAL_IMPL_NEON_INIT(int16x8, short, s16) +OPENCV_HAL_IMPL_NEON_INIT(uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_NEON_INIT(int32x4, int, s32) +OPENCV_HAL_IMPL_NEON_INIT(uint64x2, uint64, u64) +OPENCV_HAL_IMPL_NEON_INIT(int64x2, int64, s64) +OPENCV_HAL_IMPL_NEON_INIT(float32x4, float, f32) +#if CV_SIMD128_64F +#define OPENCV_HAL_IMPL_NEON_INIT_64(_Tpv, suffix) \ +inline v_float64x2 v_reinterpret_as_f64(const v_##_Tpv& v) { return v_float64x2(vreinterpretq_f64_##suffix(v.val)); } +OPENCV_HAL_IMPL_NEON_INIT(float64x2, double, f64) +OPENCV_HAL_IMPL_NEON_INIT_64(uint8x16, u8) +OPENCV_HAL_IMPL_NEON_INIT_64(int8x16, s8) +OPENCV_HAL_IMPL_NEON_INIT_64(uint16x8, u16) +OPENCV_HAL_IMPL_NEON_INIT_64(int16x8, s16) +OPENCV_HAL_IMPL_NEON_INIT_64(uint32x4, u32) +OPENCV_HAL_IMPL_NEON_INIT_64(int32x4, s32) +OPENCV_HAL_IMPL_NEON_INIT_64(uint64x2, u64) +OPENCV_HAL_IMPL_NEON_INIT_64(int64x2, s64) +OPENCV_HAL_IMPL_NEON_INIT_64(float32x4, f32) +OPENCV_HAL_IMPL_NEON_INIT_64(float64x2, f64) +#endif + +#define OPENCV_HAL_IMPL_NEON_PACK(_Tpvec, _Tp, hreg, suffix, _Tpwvec, pack, mov, rshr) \ +inline _Tpvec v_##pack(const _Tpwvec& a, const _Tpwvec& b) \ +{ \ + hreg a1 = mov(a.val), b1 = mov(b.val); \ + return _Tpvec(vcombine_##suffix(a1, b1)); \ +} \ +inline void v_##pack##_store(_Tp* ptr, const _Tpwvec& a) \ +{ \ + hreg a1 = mov(a.val); \ + vst1_##suffix(ptr, a1); \ +} \ +template inline \ +_Tpvec v_rshr_##pack(const _Tpwvec& a, const _Tpwvec& b) \ +{ \ + hreg a1 = rshr(a.val, n); \ + hreg b1 = rshr(b.val, n); \ + return _Tpvec(vcombine_##suffix(a1, b1)); \ +} \ +template inline \ +void v_rshr_##pack##_store(_Tp* ptr, const _Tpwvec& a) \ +{ \ + hreg a1 = rshr(a.val, n); \ + vst1_##suffix(ptr, a1); \ +} + +OPENCV_HAL_IMPL_NEON_PACK(v_uint8x16, uchar, uint8x8_t, u8, v_uint16x8, pack, vqmovn_u16, vqrshrn_n_u16) +OPENCV_HAL_IMPL_NEON_PACK(v_int8x16, schar, int8x8_t, s8, v_int16x8, pack, vqmovn_s16, vqrshrn_n_s16) +OPENCV_HAL_IMPL_NEON_PACK(v_uint16x8, ushort, uint16x4_t, u16, v_uint32x4, pack, vqmovn_u32, vqrshrn_n_u32) +OPENCV_HAL_IMPL_NEON_PACK(v_int16x8, short, int16x4_t, s16, v_int32x4, pack, vqmovn_s32, vqrshrn_n_s32) +OPENCV_HAL_IMPL_NEON_PACK(v_uint32x4, unsigned, uint32x2_t, u32, v_uint64x2, pack, vmovn_u64, vrshrn_n_u64) +OPENCV_HAL_IMPL_NEON_PACK(v_int32x4, int, int32x2_t, s32, v_int64x2, pack, vmovn_s64, vrshrn_n_s64) + +OPENCV_HAL_IMPL_NEON_PACK(v_uint8x16, uchar, uint8x8_t, u8, v_int16x8, pack_u, vqmovun_s16, vqrshrun_n_s16) +OPENCV_HAL_IMPL_NEON_PACK(v_uint16x8, ushort, uint16x4_t, u16, v_int32x4, pack_u, vqmovun_s32, vqrshrun_n_s32) + +// pack boolean +inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b) +{ + uint8x16_t ab = vcombine_u8(vmovn_u16(a.val), vmovn_u16(b.val)); + return v_uint8x16(ab); +} + +inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b, + const v_uint32x4& c, const v_uint32x4& d) +{ + uint16x8_t nab = vcombine_u16(vmovn_u32(a.val), vmovn_u32(b.val)); + uint16x8_t ncd = vcombine_u16(vmovn_u32(c.val), vmovn_u32(d.val)); + return v_uint8x16(vcombine_u8(vmovn_u16(nab), vmovn_u16(ncd))); +} + +inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c, + const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f, + const v_uint64x2& g, const v_uint64x2& h) +{ + uint32x4_t ab = vcombine_u32(vmovn_u64(a.val), vmovn_u64(b.val)); + uint32x4_t cd = vcombine_u32(vmovn_u64(c.val), vmovn_u64(d.val)); + uint32x4_t ef = vcombine_u32(vmovn_u64(e.val), vmovn_u64(f.val)); + uint32x4_t gh = vcombine_u32(vmovn_u64(g.val), vmovn_u64(h.val)); + + uint16x8_t abcd = vcombine_u16(vmovn_u32(ab), vmovn_u32(cd)); + uint16x8_t efgh = vcombine_u16(vmovn_u32(ef), vmovn_u32(gh)); + return v_uint8x16(vcombine_u8(vmovn_u16(abcd), vmovn_u16(efgh))); +} + +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + float32x2_t vl = vget_low_f32(v.val), vh = vget_high_f32(v.val); + float32x4_t res = vmulq_lane_f32(m0.val, vl, 0); + res = vmlaq_lane_f32(res, m1.val, vl, 1); + res = vmlaq_lane_f32(res, m2.val, vh, 0); + res = vmlaq_lane_f32(res, m3.val, vh, 1); + return v_float32x4(res); +} + +inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& a) +{ + float32x2_t vl = vget_low_f32(v.val), vh = vget_high_f32(v.val); + float32x4_t res = vmulq_lane_f32(m0.val, vl, 0); + res = vmlaq_lane_f32(res, m1.val, vl, 1); + res = vmlaq_lane_f32(res, m2.val, vh, 0); + res = vaddq_f32(res, a.val); + return v_float32x4(res); +} + +#define OPENCV_HAL_IMPL_NEON_BIN_OP(bin_op, _Tpvec, intrin) \ +inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} \ +inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ +{ \ + a.val = intrin(a.val, b.val); \ + return a; \ +} + +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint8x16, vqaddq_u8) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint8x16, vqsubq_u8) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int8x16, vqaddq_s8) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int8x16, vqsubq_s8) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint16x8, vqaddq_u16) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint16x8, vqsubq_u16) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int16x8, vqaddq_s16) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int16x8, vqsubq_s16) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int32x4, vaddq_s32) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int32x4, vsubq_s32) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_int32x4, vmulq_s32) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint32x4, vaddq_u32) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint32x4, vsubq_u32) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_uint32x4, vmulq_u32) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_float32x4, vaddq_f32) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_float32x4, vsubq_f32) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_float32x4, vmulq_f32) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_int64x2, vaddq_s64) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_int64x2, vsubq_s64) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_uint64x2, vaddq_u64) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_uint64x2, vsubq_u64) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_BIN_OP(/, v_float32x4, vdivq_f32) +OPENCV_HAL_IMPL_NEON_BIN_OP(+, v_float64x2, vaddq_f64) +OPENCV_HAL_IMPL_NEON_BIN_OP(-, v_float64x2, vsubq_f64) +OPENCV_HAL_IMPL_NEON_BIN_OP(*, v_float64x2, vmulq_f64) +OPENCV_HAL_IMPL_NEON_BIN_OP(/, v_float64x2, vdivq_f64) +#else +inline v_float32x4 operator / (const v_float32x4& a, const v_float32x4& b) +{ + float32x4_t reciprocal = vrecpeq_f32(b.val); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + return v_float32x4(vmulq_f32(a.val, reciprocal)); +} +inline v_float32x4& operator /= (v_float32x4& a, const v_float32x4& b) +{ + float32x4_t reciprocal = vrecpeq_f32(b.val); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(b.val, reciprocal), reciprocal); + a.val = vmulq_f32(a.val, reciprocal); + return a; +} +#endif + +// saturating multiply 8-bit, 16-bit +#define OPENCV_HAL_IMPL_NEON_MUL_SAT(_Tpvec, _Tpwvec) \ + inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \ + { \ + _Tpwvec c, d; \ + v_mul_expand(a, b, c, d); \ + return v_pack(c, d); \ + } \ + inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \ + { a = a * b; return a; } + +OPENCV_HAL_IMPL_NEON_MUL_SAT(v_int8x16, v_int16x8) +OPENCV_HAL_IMPL_NEON_MUL_SAT(v_uint8x16, v_uint16x8) +OPENCV_HAL_IMPL_NEON_MUL_SAT(v_int16x8, v_int32x4) +OPENCV_HAL_IMPL_NEON_MUL_SAT(v_uint16x8, v_uint32x4) + +// Multiply and expand +inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b, + v_int16x8& c, v_int16x8& d) +{ + c.val = vmull_s8(vget_low_s8(a.val), vget_low_s8(b.val)); + d.val = vmull_s8(vget_high_s8(a.val), vget_high_s8(b.val)); +} + +inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b, + v_uint16x8& c, v_uint16x8& d) +{ + c.val = vmull_u8(vget_low_u8(a.val), vget_low_u8(b.val)); + d.val = vmull_u8(vget_high_u8(a.val), vget_high_u8(b.val)); +} + +inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b, + v_int32x4& c, v_int32x4& d) +{ + c.val = vmull_s16(vget_low_s16(a.val), vget_low_s16(b.val)); + d.val = vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val)); +} + +inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b, + v_uint32x4& c, v_uint32x4& d) +{ + c.val = vmull_u16(vget_low_u16(a.val), vget_low_u16(b.val)); + d.val = vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val)); +} + +inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, + v_uint64x2& c, v_uint64x2& d) +{ + c.val = vmull_u32(vget_low_u32(a.val), vget_low_u32(b.val)); + d.val = vmull_u32(vget_high_u32(a.val), vget_high_u32(b.val)); +} + +inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b) +{ + return v_int16x8(vcombine_s16( + vshrn_n_s32(vmull_s16( vget_low_s16(a.val), vget_low_s16(b.val)), 16), + vshrn_n_s32(vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val)), 16) + )); +} +inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b) +{ + return v_uint16x8(vcombine_u16( + vshrn_n_u32(vmull_u16( vget_low_u16(a.val), vget_low_u16(b.val)), 16), + vshrn_n_u32(vmull_u16(vget_high_u16(a.val), vget_high_u16(b.val)), 16) + )); +} + +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b) +{ + int32x4_t c = vmull_s16(vget_low_s16(a.val), vget_low_s16(b.val)); + int32x4_t d = vmull_s16(vget_high_s16(a.val), vget_high_s16(b.val)); + int32x4x2_t cd = vuzpq_s32(c, d); + return v_int32x4(vaddq_s32(cd.val[0], cd.val[1])); +} + +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c) +{ + v_int32x4 s = v_dotprod(a, b); + return v_int32x4(vaddq_s32(s.val , c.val)); +} + +#define OPENCV_HAL_IMPL_NEON_LOGIC_OP(_Tpvec, suffix) \ + OPENCV_HAL_IMPL_NEON_BIN_OP(&, _Tpvec, vandq_##suffix) \ + OPENCV_HAL_IMPL_NEON_BIN_OP(|, _Tpvec, vorrq_##suffix) \ + OPENCV_HAL_IMPL_NEON_BIN_OP(^, _Tpvec, veorq_##suffix) \ + inline _Tpvec operator ~ (const _Tpvec& a) \ + { \ + return _Tpvec(vreinterpretq_##suffix##_u8(vmvnq_u8(vreinterpretq_u8_##suffix(a.val)))); \ + } + +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint8x16, u8) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int8x16, s8) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint16x8, u16) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int16x8, s16) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint32x4, u32) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int32x4, s32) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_uint64x2, u64) +OPENCV_HAL_IMPL_NEON_LOGIC_OP(v_int64x2, s64) + +#define OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(bin_op, intrin) \ +inline v_float32x4 operator bin_op (const v_float32x4& a, const v_float32x4& b) \ +{ \ + return v_float32x4(vreinterpretq_f32_s32(intrin(vreinterpretq_s32_f32(a.val), vreinterpretq_s32_f32(b.val)))); \ +} \ +inline v_float32x4& operator bin_op##= (v_float32x4& a, const v_float32x4& b) \ +{ \ + a.val = vreinterpretq_f32_s32(intrin(vreinterpretq_s32_f32(a.val), vreinterpretq_s32_f32(b.val))); \ + return a; \ +} + +OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(&, vandq_s32) +OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(|, vorrq_s32) +OPENCV_HAL_IMPL_NEON_FLT_BIT_OP(^, veorq_s32) + +inline v_float32x4 operator ~ (const v_float32x4& a) +{ + return v_float32x4(vreinterpretq_f32_s32(vmvnq_s32(vreinterpretq_s32_f32(a.val)))); +} + +#if CV_SIMD128_64F +inline v_float32x4 v_sqrt(const v_float32x4& x) +{ + return v_float32x4(vsqrtq_f32(x.val)); +} + +inline v_float32x4 v_invsqrt(const v_float32x4& x) +{ + v_float32x4 one = v_setall_f32(1.0f); + return one / v_sqrt(x); +} +#else +inline v_float32x4 v_sqrt(const v_float32x4& x) +{ + float32x4_t x1 = vmaxq_f32(x.val, vdupq_n_f32(FLT_MIN)); + float32x4_t e = vrsqrteq_f32(x1); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + return v_float32x4(vmulq_f32(x.val, e)); +} + +inline v_float32x4 v_invsqrt(const v_float32x4& x) +{ + float32x4_t e = vrsqrteq_f32(x.val); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x.val, e), e), e); + return v_float32x4(e); +} +#endif + +#define OPENCV_HAL_IMPL_NEON_ABS(_Tpuvec, _Tpsvec, usuffix, ssuffix) \ +inline _Tpuvec v_abs(const _Tpsvec& a) { return v_reinterpret_as_##usuffix(_Tpsvec(vabsq_##ssuffix(a.val))); } + +OPENCV_HAL_IMPL_NEON_ABS(v_uint8x16, v_int8x16, u8, s8) +OPENCV_HAL_IMPL_NEON_ABS(v_uint16x8, v_int16x8, u16, s16) +OPENCV_HAL_IMPL_NEON_ABS(v_uint32x4, v_int32x4, u32, s32) + +inline v_float32x4 v_abs(v_float32x4 x) +{ return v_float32x4(vabsq_f32(x.val)); } + +#if CV_SIMD128_64F +#define OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(bin_op, intrin) \ +inline v_float64x2 operator bin_op (const v_float64x2& a, const v_float64x2& b) \ +{ \ + return v_float64x2(vreinterpretq_f64_s64(intrin(vreinterpretq_s64_f64(a.val), vreinterpretq_s64_f64(b.val)))); \ +} \ +inline v_float64x2& operator bin_op##= (v_float64x2& a, const v_float64x2& b) \ +{ \ + a.val = vreinterpretq_f64_s64(intrin(vreinterpretq_s64_f64(a.val), vreinterpretq_s64_f64(b.val))); \ + return a; \ +} + +OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(&, vandq_s64) +OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(|, vorrq_s64) +OPENCV_HAL_IMPL_NEON_DBL_BIT_OP(^, veorq_s64) + +inline v_float64x2 operator ~ (const v_float64x2& a) +{ + return v_float64x2(vreinterpretq_f64_s32(vmvnq_s32(vreinterpretq_s32_f64(a.val)))); +} + +inline v_float64x2 v_sqrt(const v_float64x2& x) +{ + return v_float64x2(vsqrtq_f64(x.val)); +} + +inline v_float64x2 v_invsqrt(const v_float64x2& x) +{ + v_float64x2 one = v_setall_f64(1.0f); + return one / v_sqrt(x); +} + +inline v_float64x2 v_abs(v_float64x2 x) +{ return v_float64x2(vabsq_f64(x.val)); } +#endif + +// TODO: exp, log, sin, cos + +#define OPENCV_HAL_IMPL_NEON_BIN_FUNC(_Tpvec, func, intrin) \ +inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} + +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_min, vminq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_max, vmaxq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_min, vminq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_max, vmaxq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_min, vminq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_max, vmaxq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_min, vminq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_max, vmaxq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_min, vminq_u32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_max, vmaxq_u32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int32x4, v_min, vminq_s32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int32x4, v_max, vmaxq_s32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_min, vminq_f32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_max, vmaxq_f32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_min, vminq_f64) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_max, vmaxq_f64) +#endif + +#if CV_SIMD128_64F +inline int64x2_t vmvnq_s64(int64x2_t a) +{ + int64x2_t vx = vreinterpretq_s64_u32(vdupq_n_u32(0xFFFFFFFF)); + return veorq_s64(a, vx); +} +inline uint64x2_t vmvnq_u64(uint64x2_t a) +{ + uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF)); + return veorq_u64(a, vx); +} +#endif +#define OPENCV_HAL_IMPL_NEON_INT_CMP_OP(_Tpvec, cast, suffix, not_suffix) \ +inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vceqq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vmvnq_##not_suffix(vceqq_##suffix(a.val, b.val)))); } \ +inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcltq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcgtq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcleq_##suffix(a.val, b.val))); } \ +inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(cast(vcgeq_##suffix(a.val, b.val))); } + +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint8x16, OPENCV_HAL_NOP, u8, u8) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int8x16, vreinterpretq_s8_u8, s8, u8) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint16x8, OPENCV_HAL_NOP, u16, u16) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, vreinterpretq_s16_u16, s16, u16) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint32x4, OPENCV_HAL_NOP, u32, u32) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, vreinterpretq_s32_u32, s32, u32) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float32x4, vreinterpretq_f32_u32, f32, u32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64) +OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float64x2, vreinterpretq_f64_u64, f64, u64) +#endif + +inline v_float32x4 v_not_nan(const v_float32x4& a) +{ return v_float32x4(vreinterpretq_f32_u32(vceqq_f32(a.val, a.val))); } +#if CV_SIMD128_64F +inline v_float64x2 v_not_nan(const v_float64x2& a) +{ return v_float64x2(vreinterpretq_f64_u64(vceqq_f64(a.val, a.val))); } +#endif + +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_add_wrap, vaddq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_add_wrap, vaddq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_add_wrap, vaddq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_add_wrap, vaddq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_sub_wrap, vsubq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_sub_wrap, vsubq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_sub_wrap, vsubq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_sub_wrap, vsubq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_mul_wrap, vmulq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_mul_wrap, vmulq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_mul_wrap, vmulq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_mul_wrap, vmulq_s16) + +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_absdiff, vabdq_u8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_absdiff, vabdq_u16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint32x4, v_absdiff, vabdq_u32) +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float32x4, v_absdiff, vabdq_f32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_absdiff, vabdq_f64) +#endif + +/** Saturating absolute difference **/ +inline v_int8x16 v_absdiffs(const v_int8x16& a, const v_int8x16& b) +{ return v_int8x16(vqabsq_s8(vqsubq_s8(a.val, b.val))); } +inline v_int16x8 v_absdiffs(const v_int16x8& a, const v_int16x8& b) +{ return v_int16x8(vqabsq_s16(vqsubq_s16(a.val, b.val))); } + +#define OPENCV_HAL_IMPL_NEON_BIN_FUNC2(_Tpvec, _Tpvec2, cast, func, intrin) \ +inline _Tpvec2 func(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec2(cast(intrin(a.val, b.val))); \ +} + +OPENCV_HAL_IMPL_NEON_BIN_FUNC2(v_int8x16, v_uint8x16, vreinterpretq_u8_s8, v_absdiff, vabdq_s8) +OPENCV_HAL_IMPL_NEON_BIN_FUNC2(v_int16x8, v_uint16x8, vreinterpretq_u16_s16, v_absdiff, vabdq_s16) +OPENCV_HAL_IMPL_NEON_BIN_FUNC2(v_int32x4, v_uint32x4, vreinterpretq_u32_s32, v_absdiff, vabdq_s32) + +inline v_float32x4 v_magnitude(const v_float32x4& a, const v_float32x4& b) +{ + v_float32x4 x(vmlaq_f32(vmulq_f32(a.val, a.val), b.val, b.val)); + return v_sqrt(x); +} + +inline v_float32x4 v_sqr_magnitude(const v_float32x4& a, const v_float32x4& b) +{ + return v_float32x4(vmlaq_f32(vmulq_f32(a.val, a.val), b.val, b.val)); +} + +inline v_float32x4 v_fma(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c) +{ +#if CV_SIMD128_64F + // ARMv8, which adds support for 64-bit floating-point (so CV_SIMD128_64F is defined), + // also adds FMA support both for single- and double-precision floating-point vectors + return v_float32x4(vfmaq_f32(c.val, a.val, b.val)); +#else + return v_float32x4(vmlaq_f32(c.val, a.val, b.val)); +#endif +} + +inline v_int32x4 v_fma(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c) +{ + return v_int32x4(vmlaq_s32(c.val, a.val, b.val)); +} + +inline v_float32x4 v_muladd(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c) +{ + return v_fma(a, b, c); +} + +inline v_int32x4 v_muladd(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c) +{ + return v_fma(a, b, c); +} + +#if CV_SIMD128_64F +inline v_float64x2 v_magnitude(const v_float64x2& a, const v_float64x2& b) +{ + v_float64x2 x(vaddq_f64(vmulq_f64(a.val, a.val), vmulq_f64(b.val, b.val))); + return v_sqrt(x); +} + +inline v_float64x2 v_sqr_magnitude(const v_float64x2& a, const v_float64x2& b) +{ + return v_float64x2(vaddq_f64(vmulq_f64(a.val, a.val), vmulq_f64(b.val, b.val))); +} + +inline v_float64x2 v_fma(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c) +{ + return v_float64x2(vfmaq_f64(c.val, a.val, b.val)); +} + +inline v_float64x2 v_muladd(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c) +{ + return v_fma(a, b, c); +} +#endif + +// trade efficiency for convenience +#define OPENCV_HAL_IMPL_NEON_SHIFT_OP(_Tpvec, suffix, _Tps, ssuffix) \ +inline _Tpvec operator << (const _Tpvec& a, int n) \ +{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##ssuffix((_Tps)n))); } \ +inline _Tpvec operator >> (const _Tpvec& a, int n) \ +{ return _Tpvec(vshlq_##suffix(a.val, vdupq_n_##ssuffix((_Tps)-n))); } \ +template inline _Tpvec v_shl(const _Tpvec& a) \ +{ return _Tpvec(vshlq_n_##suffix(a.val, n)); } \ +template inline _Tpvec v_shr(const _Tpvec& a) \ +{ return _Tpvec(vshrq_n_##suffix(a.val, n)); } \ +template inline _Tpvec v_rshr(const _Tpvec& a) \ +{ return _Tpvec(vrshrq_n_##suffix(a.val, n)); } + +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint8x16, u8, schar, s8) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int8x16, s8, schar, s8) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint16x8, u16, short, s16) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int16x8, s16, short, s16) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint32x4, u32, int, s32) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int32x4, s32, int, s32) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_uint64x2, u64, int64, s64) +OPENCV_HAL_IMPL_NEON_SHIFT_OP(v_int64x2, s64, int64, s64) + +#define OPENCV_HAL_IMPL_NEON_ROTATE_OP(_Tpvec, suffix) \ +template inline _Tpvec v_rotate_right(const _Tpvec& a) \ +{ return _Tpvec(vextq_##suffix(a.val, vdupq_n_##suffix(0), n)); } \ +template inline _Tpvec v_rotate_left(const _Tpvec& a) \ +{ return _Tpvec(vextq_##suffix(vdupq_n_##suffix(0), a.val, _Tpvec::nlanes - n)); } \ +template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a) \ +{ return a; } \ +template inline _Tpvec v_rotate_right(const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vextq_##suffix(a.val, b.val, n)); } \ +template inline _Tpvec v_rotate_left(const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vextq_##suffix(b.val, a.val, _Tpvec::nlanes - n)); } \ +template<> inline _Tpvec v_rotate_left<0>(const _Tpvec& a, const _Tpvec& b) \ +{ CV_UNUSED(b); return a; } + +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_uint8x16, u8) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_int8x16, s8) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_uint16x8, u16) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_int16x8, s16) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_uint32x4, u32) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_int32x4, s32) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_float32x4, f32) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_uint64x2, u64) +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_int64x2, s64) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_ROTATE_OP(v_float64x2, f64) +#endif + +#if defined(__clang__) && defined(__aarch64__) +// avoid LD2 instruction. details: https://github.com/opencv/opencv/issues/14863 +#define OPENCV_HAL_IMPL_NEON_LOAD_LOW_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ \ +typedef uint64 CV_DECL_ALIGNED(1) unaligned_uint64; \ +uint64 v = *(unaligned_uint64*)ptr; \ +return _Tpvec(v_reinterpret_as_##suffix(v_uint64x2(v, (uint64)123456))); \ +} +#else +#define OPENCV_HAL_IMPL_NEON_LOAD_LOW_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr), vdup_n_##suffix((_Tp)0))); } +#endif + +#define OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec(vld1q_##suffix(ptr)); } \ +inline _Tpvec v_load_aligned(const _Tp* ptr) \ +{ return _Tpvec(vld1q_##suffix(ptr)); } \ +OPENCV_HAL_IMPL_NEON_LOAD_LOW_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr0), vld1_##suffix(ptr1))); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ vst1q_##suffix(ptr, a.val); } \ +inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ +{ vst1q_##suffix(ptr, a.val); } \ +inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ +{ vst1q_##suffix(ptr, a.val); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode /*mode*/) \ +{ vst1q_##suffix(ptr, a.val); } \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ vst1_##suffix(ptr, vget_low_##suffix(a.val)); } \ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ vst1_##suffix(ptr, vget_high_##suffix(a.val)); } + +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int8x16, schar, s8) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int16x8, short, s16) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int32x4, int, s32) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_uint64x2, uint64, u64) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_int64x2, int64, s64) +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_float32x4, float, f32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_LOADSTORE_OP(v_float64x2, double, f64) +#endif + +inline unsigned v_reduce_sum(const v_uint8x16& a) +{ + uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(a.val)); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline int v_reduce_sum(const v_int8x16& a) +{ + int32x4_t t0 = vpaddlq_s16(vpaddlq_s8(a.val)); + int32x2_t t1 = vpadd_s32(vget_low_s32(t0), vget_high_s32(t0)); + return vget_lane_s32(vpadd_s32(t1, t1), 0); +} +inline unsigned v_reduce_sum(const v_uint16x8& a) +{ + uint32x4_t t0 = vpaddlq_u16(a.val); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline int v_reduce_sum(const v_int16x8& a) +{ + int32x4_t t0 = vpaddlq_s16(a.val); + int32x2_t t1 = vpadd_s32(vget_low_s32(t0), vget_high_s32(t0)); + return vget_lane_s32(vpadd_s32(t1, t1), 0); +} + +#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + _Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \ + a0 = vp##vectorfunc##_##suffix(a0, a0); \ + return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, a0),0); \ +} + +OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, unsigned int, max, max, u16) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, unsigned int, min, min, u16) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, int, max, max, s16) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, int, min, min, s16) + +#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + _Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \ + return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, vget_high_##suffix(a.val)),0); \ +} + +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, sum, add, u32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, max, max, u32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_uint32x4, uint32x2, unsigned, min, min, u32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int32x2, int, sum, add, s32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int32x2, int, max, max, s32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_int32x4, int32x2, int, min, min, s32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, sum, add, f32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, max, max, f32) +OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, min, min, f32) + +inline uint64 v_reduce_sum(const v_uint64x2& a) +{ return vget_lane_u64(vadd_u64(vget_low_u64(a.val), vget_high_u64(a.val)),0); } +inline int64 v_reduce_sum(const v_int64x2& a) +{ return vget_lane_s64(vadd_s64(vget_low_s64(a.val), vget_high_s64(a.val)),0); } +#if CV_SIMD128_64F +inline double v_reduce_sum(const v_float64x2& a) +{ + return vgetq_lane_f64(a.val, 0) + vgetq_lane_f64(a.val, 1); +} +#endif + +inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b, + const v_float32x4& c, const v_float32x4& d) +{ + float32x4x2_t ab = vtrnq_f32(a.val, b.val); + float32x4x2_t cd = vtrnq_f32(c.val, d.val); + + float32x4_t u0 = vaddq_f32(ab.val[0], ab.val[1]); // a0+a1 b0+b1 a2+a3 b2+b3 + float32x4_t u1 = vaddq_f32(cd.val[0], cd.val[1]); // c0+c1 d0+d1 c2+c3 d2+d3 + + float32x4_t v0 = vcombine_f32(vget_low_f32(u0), vget_low_f32(u1)); + float32x4_t v1 = vcombine_f32(vget_high_f32(u0), vget_high_f32(u1)); + + return v_float32x4(vaddq_f32(v0, v1)); +} + +inline unsigned v_reduce_sad(const v_uint8x16& a, const v_uint8x16& b) +{ + uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(vabdq_u8(a.val, b.val))); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline unsigned v_reduce_sad(const v_int8x16& a, const v_int8x16& b) +{ + uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(vreinterpretq_u8_s8(vabdq_s8(a.val, b.val)))); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline unsigned v_reduce_sad(const v_uint16x8& a, const v_uint16x8& b) +{ + uint32x4_t t0 = vpaddlq_u16(vabdq_u16(a.val, b.val)); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline unsigned v_reduce_sad(const v_int16x8& a, const v_int16x8& b) +{ + uint32x4_t t0 = vpaddlq_u16(vreinterpretq_u16_s16(vabdq_s16(a.val, b.val))); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline unsigned v_reduce_sad(const v_uint32x4& a, const v_uint32x4& b) +{ + uint32x4_t t0 = vabdq_u32(a.val, b.val); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline unsigned v_reduce_sad(const v_int32x4& a, const v_int32x4& b) +{ + uint32x4_t t0 = vreinterpretq_u32_s32(vabdq_s32(a.val, b.val)); + uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); + return vget_lane_u32(vpadd_u32(t1, t1), 0); +} +inline float v_reduce_sad(const v_float32x4& a, const v_float32x4& b) +{ + float32x4_t t0 = vabdq_f32(a.val, b.val); + float32x2_t t1 = vpadd_f32(vget_low_f32(t0), vget_high_f32(t0)); + return vget_lane_f32(vpadd_f32(t1, t1), 0); +} + +inline v_uint8x16 v_popcount(const v_uint8x16& a) +{ return v_uint8x16(vcntq_u8(a.val)); } +inline v_uint8x16 v_popcount(const v_int8x16& a) +{ return v_uint8x16(vcntq_u8(vreinterpretq_u8_s8(a.val))); } +inline v_uint16x8 v_popcount(const v_uint16x8& a) +{ return v_uint16x8(vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u16(a.val)))); } +inline v_uint16x8 v_popcount(const v_int16x8& a) +{ return v_uint16x8(vpaddlq_u8(vcntq_u8(vreinterpretq_u8_s16(a.val)))); } +inline v_uint32x4 v_popcount(const v_uint32x4& a) +{ return v_uint32x4(vpaddlq_u16(vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u32(a.val))))); } +inline v_uint32x4 v_popcount(const v_int32x4& a) +{ return v_uint32x4(vpaddlq_u16(vpaddlq_u8(vcntq_u8(vreinterpretq_u8_s32(a.val))))); } +inline v_uint64x2 v_popcount(const v_uint64x2& a) +{ return v_uint64x2(vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(a.val)))))); } +inline v_uint64x2 v_popcount(const v_int64x2& a) +{ return v_uint64x2(vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vcntq_u8(vreinterpretq_u8_s64(a.val)))))); } + +inline int v_signmask(const v_uint8x16& a) +{ + int8x8_t m0 = vcreate_s8(CV_BIG_UINT(0x0706050403020100)); + uint8x16_t v0 = vshlq_u8(vshrq_n_u8(a.val, 7), vcombine_s8(m0, m0)); + uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(v0))); + return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 8); +} +inline int v_signmask(const v_int8x16& a) +{ return v_signmask(v_reinterpret_as_u8(a)); } + +inline int v_signmask(const v_uint16x8& a) +{ + int16x4_t m0 = vcreate_s16(CV_BIG_UINT(0x0003000200010000)); + uint16x8_t v0 = vshlq_u16(vshrq_n_u16(a.val, 15), vcombine_s16(m0, m0)); + uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(v0)); + return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 4); +} +inline int v_signmask(const v_int16x8& a) +{ return v_signmask(v_reinterpret_as_u16(a)); } + +inline int v_signmask(const v_uint32x4& a) +{ + int32x2_t m0 = vcreate_s32(CV_BIG_UINT(0x0000000100000000)); + uint32x4_t v0 = vshlq_u32(vshrq_n_u32(a.val, 31), vcombine_s32(m0, m0)); + uint64x2_t v1 = vpaddlq_u32(v0); + return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 2); +} +inline int v_signmask(const v_int32x4& a) +{ return v_signmask(v_reinterpret_as_u32(a)); } +inline int v_signmask(const v_float32x4& a) +{ return v_signmask(v_reinterpret_as_u32(a)); } +inline int v_signmask(const v_uint64x2& a) +{ + int64x1_t m0 = vdup_n_s64(0); + uint64x2_t v0 = vshlq_u64(vshrq_n_u64(a.val, 63), vcombine_s64(m0, m0)); + return (int)vgetq_lane_u64(v0, 0) + ((int)vgetq_lane_u64(v0, 1) << 1); +} +inline int v_signmask(const v_int64x2& a) +{ return v_signmask(v_reinterpret_as_u64(a)); } +#if CV_SIMD128_64F +inline int v_signmask(const v_float64x2& a) +{ return v_signmask(v_reinterpret_as_u64(a)); } +#endif + +inline int v_scan_forward(const v_int8x16& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint8x16& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_int16x8& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint16x8& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_int32x4& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint32x4& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_float32x4& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_int64x2& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint64x2& a) { return trailingZeros32(v_signmask(a)); } +#if CV_SIMD128_64F +inline int v_scan_forward(const v_float64x2& a) { return trailingZeros32(v_signmask(a)); } +#endif + +#define OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(_Tpvec, suffix, shift) \ +inline bool v_check_all(const v_##_Tpvec& a) \ +{ \ + _Tpvec##_t v0 = vshrq_n_##suffix(vmvnq_##suffix(a.val), shift); \ + uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ + return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) == 0; \ +} \ +inline bool v_check_any(const v_##_Tpvec& a) \ +{ \ + _Tpvec##_t v0 = vshrq_n_##suffix(a.val, shift); \ + uint64x2_t v1 = vreinterpretq_u64_##suffix(v0); \ + return (vgetq_lane_u64(v1, 0) | vgetq_lane_u64(v1, 1)) != 0; \ +} + +OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint8x16, u8, 7) +OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint16x8, u16, 15) +OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint32x4, u32, 31) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_CHECK_ALLANY(uint64x2, u64, 63) +#endif + +inline bool v_check_all(const v_int8x16& a) +{ return v_check_all(v_reinterpret_as_u8(a)); } +inline bool v_check_all(const v_int16x8& a) +{ return v_check_all(v_reinterpret_as_u16(a)); } +inline bool v_check_all(const v_int32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } +inline bool v_check_all(const v_float32x4& a) +{ return v_check_all(v_reinterpret_as_u32(a)); } + +inline bool v_check_any(const v_int8x16& a) +{ return v_check_any(v_reinterpret_as_u8(a)); } +inline bool v_check_any(const v_int16x8& a) +{ return v_check_any(v_reinterpret_as_u16(a)); } +inline bool v_check_any(const v_int32x4& a) +{ return v_check_any(v_reinterpret_as_u32(a)); } +inline bool v_check_any(const v_float32x4& a) +{ return v_check_any(v_reinterpret_as_u32(a)); } + +#if CV_SIMD128_64F +inline bool v_check_all(const v_int64x2& a) +{ return v_check_all(v_reinterpret_as_u64(a)); } +inline bool v_check_all(const v_float64x2& a) +{ return v_check_all(v_reinterpret_as_u64(a)); } +inline bool v_check_any(const v_int64x2& a) +{ return v_check_any(v_reinterpret_as_u64(a)); } +inline bool v_check_any(const v_float64x2& a) +{ return v_check_any(v_reinterpret_as_u64(a)); } +#endif + +#define OPENCV_HAL_IMPL_NEON_SELECT(_Tpvec, suffix, usuffix) \ +inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(vbslq_##suffix(vreinterpretq_##usuffix##_##suffix(mask.val), a.val, b.val)); \ +} + +OPENCV_HAL_IMPL_NEON_SELECT(v_uint8x16, u8, u8) +OPENCV_HAL_IMPL_NEON_SELECT(v_int8x16, s8, u8) +OPENCV_HAL_IMPL_NEON_SELECT(v_uint16x8, u16, u16) +OPENCV_HAL_IMPL_NEON_SELECT(v_int16x8, s16, u16) +OPENCV_HAL_IMPL_NEON_SELECT(v_uint32x4, u32, u32) +OPENCV_HAL_IMPL_NEON_SELECT(v_int32x4, s32, u32) +OPENCV_HAL_IMPL_NEON_SELECT(v_float32x4, f32, u32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_SELECT(v_float64x2, f64, u64) +#endif + +#define OPENCV_HAL_IMPL_NEON_EXPAND(_Tpvec, _Tpwvec, _Tp, suffix) \ +inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \ +{ \ + b0.val = vmovl_##suffix(vget_low_##suffix(a.val)); \ + b1.val = vmovl_##suffix(vget_high_##suffix(a.val)); \ +} \ +inline _Tpwvec v_expand_low(const _Tpvec& a) \ +{ \ + return _Tpwvec(vmovl_##suffix(vget_low_##suffix(a.val))); \ +} \ +inline _Tpwvec v_expand_high(const _Tpvec& a) \ +{ \ + return _Tpwvec(vmovl_##suffix(vget_high_##suffix(a.val))); \ +} \ +inline _Tpwvec v_load_expand(const _Tp* ptr) \ +{ \ + return _Tpwvec(vmovl_##suffix(vld1_##suffix(ptr))); \ +} + +OPENCV_HAL_IMPL_NEON_EXPAND(v_uint8x16, v_uint16x8, uchar, u8) +OPENCV_HAL_IMPL_NEON_EXPAND(v_int8x16, v_int16x8, schar, s8) +OPENCV_HAL_IMPL_NEON_EXPAND(v_uint16x8, v_uint32x4, ushort, u16) +OPENCV_HAL_IMPL_NEON_EXPAND(v_int16x8, v_int32x4, short, s16) +OPENCV_HAL_IMPL_NEON_EXPAND(v_uint32x4, v_uint64x2, uint, u32) +OPENCV_HAL_IMPL_NEON_EXPAND(v_int32x4, v_int64x2, int, s32) + +inline v_uint32x4 v_load_expand_q(const uchar* ptr) +{ + typedef unsigned int CV_DECL_ALIGNED(1) unaligned_uint; + uint8x8_t v0 = vcreate_u8(*(unaligned_uint*)ptr); + uint16x4_t v1 = vget_low_u16(vmovl_u8(v0)); + return v_uint32x4(vmovl_u16(v1)); +} + +inline v_int32x4 v_load_expand_q(const schar* ptr) +{ + typedef unsigned int CV_DECL_ALIGNED(1) unaligned_uint; + int8x8_t v0 = vcreate_s8(*(unaligned_uint*)ptr); + int16x4_t v1 = vget_low_s16(vmovl_s8(v0)); + return v_int32x4(vmovl_s16(v1)); +} + +#if defined(__aarch64__) +#define OPENCV_HAL_IMPL_NEON_UNPACKS(_Tpvec, suffix) \ +inline void v_zip(const v_##_Tpvec& a0, const v_##_Tpvec& a1, v_##_Tpvec& b0, v_##_Tpvec& b1) \ +{ \ + b0.val = vzip1q_##suffix(a0.val, a1.val); \ + b1.val = vzip2q_##suffix(a0.val, a1.val); \ +} \ +inline v_##_Tpvec v_combine_low(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + return v_##_Tpvec(vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val))); \ +} \ +inline v_##_Tpvec v_combine_high(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + return v_##_Tpvec(vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val))); \ +} \ +inline void v_recombine(const v_##_Tpvec& a, const v_##_Tpvec& b, v_##_Tpvec& c, v_##_Tpvec& d) \ +{ \ + c.val = vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val)); \ + d.val = vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val)); \ +} +#else +#define OPENCV_HAL_IMPL_NEON_UNPACKS(_Tpvec, suffix) \ +inline void v_zip(const v_##_Tpvec& a0, const v_##_Tpvec& a1, v_##_Tpvec& b0, v_##_Tpvec& b1) \ +{ \ + _Tpvec##x2_t p = vzipq_##suffix(a0.val, a1.val); \ + b0.val = p.val[0]; \ + b1.val = p.val[1]; \ +} \ +inline v_##_Tpvec v_combine_low(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + return v_##_Tpvec(vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val))); \ +} \ +inline v_##_Tpvec v_combine_high(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + return v_##_Tpvec(vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val))); \ +} \ +inline void v_recombine(const v_##_Tpvec& a, const v_##_Tpvec& b, v_##_Tpvec& c, v_##_Tpvec& d) \ +{ \ + c.val = vcombine_##suffix(vget_low_##suffix(a.val), vget_low_##suffix(b.val)); \ + d.val = vcombine_##suffix(vget_high_##suffix(a.val), vget_high_##suffix(b.val)); \ +} +#endif + +OPENCV_HAL_IMPL_NEON_UNPACKS(uint8x16, u8) +OPENCV_HAL_IMPL_NEON_UNPACKS(int8x16, s8) +OPENCV_HAL_IMPL_NEON_UNPACKS(uint16x8, u16) +OPENCV_HAL_IMPL_NEON_UNPACKS(int16x8, s16) +OPENCV_HAL_IMPL_NEON_UNPACKS(uint32x4, u32) +OPENCV_HAL_IMPL_NEON_UNPACKS(int32x4, s32) +OPENCV_HAL_IMPL_NEON_UNPACKS(float32x4, f32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_UNPACKS(float64x2, f64) +#endif + +#define OPENCV_HAL_IMPL_NEON_EXTRACT(_Tpvec, suffix) \ +template \ +inline v_##_Tpvec v_extract(const v_##_Tpvec& a, const v_##_Tpvec& b) \ +{ \ + return v_##_Tpvec(vextq_##suffix(a.val, b.val, s)); \ +} + +OPENCV_HAL_IMPL_NEON_EXTRACT(uint8x16, u8) +OPENCV_HAL_IMPL_NEON_EXTRACT(int8x16, s8) +OPENCV_HAL_IMPL_NEON_EXTRACT(uint16x8, u16) +OPENCV_HAL_IMPL_NEON_EXTRACT(int16x8, s16) +OPENCV_HAL_IMPL_NEON_EXTRACT(uint32x4, u32) +OPENCV_HAL_IMPL_NEON_EXTRACT(int32x4, s32) +OPENCV_HAL_IMPL_NEON_EXTRACT(uint64x2, u64) +OPENCV_HAL_IMPL_NEON_EXTRACT(int64x2, s64) +OPENCV_HAL_IMPL_NEON_EXTRACT(float32x4, f32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_EXTRACT(float64x2, f64) +#endif + +#if CV_SIMD128_64F +inline v_int32x4 v_round(const v_float32x4& a) +{ + float32x4_t a_ = a.val; + int32x4_t result; + __asm__ ("fcvtns %0.4s, %1.4s" + : "=w"(result) + : "w"(a_) + : /* No clobbers */); + return v_int32x4(result); +} +#else +inline v_int32x4 v_round(const v_float32x4& a) +{ + static const int32x4_t v_sign = vdupq_n_s32(1 << 31), + v_05 = vreinterpretq_s32_f32(vdupq_n_f32(0.5f)); + + int32x4_t v_addition = vorrq_s32(v_05, vandq_s32(v_sign, vreinterpretq_s32_f32(a.val))); + return v_int32x4(vcvtq_s32_f32(vaddq_f32(a.val, vreinterpretq_f32_s32(v_addition)))); +} +#endif +inline v_int32x4 v_floor(const v_float32x4& a) +{ + int32x4_t a1 = vcvtq_s32_f32(a.val); + uint32x4_t mask = vcgtq_f32(vcvtq_f32_s32(a1), a.val); + return v_int32x4(vaddq_s32(a1, vreinterpretq_s32_u32(mask))); +} + +inline v_int32x4 v_ceil(const v_float32x4& a) +{ + int32x4_t a1 = vcvtq_s32_f32(a.val); + uint32x4_t mask = vcgtq_f32(a.val, vcvtq_f32_s32(a1)); + return v_int32x4(vsubq_s32(a1, vreinterpretq_s32_u32(mask))); +} + +inline v_int32x4 v_trunc(const v_float32x4& a) +{ return v_int32x4(vcvtq_s32_f32(a.val)); } + +#if CV_SIMD128_64F +inline v_int32x4 v_round(const v_float64x2& a) +{ + static const int32x2_t zero = vdup_n_s32(0); + return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), zero)); +} + +inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b) +{ + return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), vmovn_s64(vcvtaq_s64_f64(b.val)))); +} + +inline v_int32x4 v_floor(const v_float64x2& a) +{ + static const int32x2_t zero = vdup_n_s32(0); + int64x2_t a1 = vcvtq_s64_f64(a.val); + uint64x2_t mask = vcgtq_f64(vcvtq_f64_s64(a1), a.val); + a1 = vaddq_s64(a1, vreinterpretq_s64_u64(mask)); + return v_int32x4(vcombine_s32(vmovn_s64(a1), zero)); +} + +inline v_int32x4 v_ceil(const v_float64x2& a) +{ + static const int32x2_t zero = vdup_n_s32(0); + int64x2_t a1 = vcvtq_s64_f64(a.val); + uint64x2_t mask = vcgtq_f64(a.val, vcvtq_f64_s64(a1)); + a1 = vsubq_s64(a1, vreinterpretq_s64_u64(mask)); + return v_int32x4(vcombine_s32(vmovn_s64(a1), zero)); +} + +inline v_int32x4 v_trunc(const v_float64x2& a) +{ + static const int32x2_t zero = vdup_n_s32(0); + return v_int32x4(vcombine_s32(vmovn_s64(vcvtaq_s64_f64(a.val)), zero)); +} +#endif + +#define OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(_Tpvec, suffix) \ +inline void v_transpose4x4(const v_##_Tpvec& a0, const v_##_Tpvec& a1, \ + const v_##_Tpvec& a2, const v_##_Tpvec& a3, \ + v_##_Tpvec& b0, v_##_Tpvec& b1, \ + v_##_Tpvec& b2, v_##_Tpvec& b3) \ +{ \ + /* m00 m01 m02 m03 */ \ + /* m10 m11 m12 m13 */ \ + /* m20 m21 m22 m23 */ \ + /* m30 m31 m32 m33 */ \ + _Tpvec##x2_t t0 = vtrnq_##suffix(a0.val, a1.val); \ + _Tpvec##x2_t t1 = vtrnq_##suffix(a2.val, a3.val); \ + /* m00 m10 m02 m12 */ \ + /* m01 m11 m03 m13 */ \ + /* m20 m30 m22 m32 */ \ + /* m21 m31 m23 m33 */ \ + b0.val = vcombine_##suffix(vget_low_##suffix(t0.val[0]), vget_low_##suffix(t1.val[0])); \ + b1.val = vcombine_##suffix(vget_low_##suffix(t0.val[1]), vget_low_##suffix(t1.val[1])); \ + b2.val = vcombine_##suffix(vget_high_##suffix(t0.val[0]), vget_high_##suffix(t1.val[0])); \ + b3.val = vcombine_##suffix(vget_high_##suffix(t0.val[1]), vget_high_##suffix(t1.val[1])); \ +} + +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(uint32x4, u32) +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(int32x4, s32) +OPENCV_HAL_IMPL_NEON_TRANSPOSE4x4(float32x4, f32) + +#define OPENCV_HAL_IMPL_NEON_INTERLEAVED(_Tpvec, _Tp, suffix) \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b) \ +{ \ + _Tpvec##x2_t v = vld2q_##suffix(ptr); \ + a.val = v.val[0]; \ + b.val = v.val[1]; \ +} \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, v_##_Tpvec& c) \ +{ \ + _Tpvec##x3_t v = vld3q_##suffix(ptr); \ + a.val = v.val[0]; \ + b.val = v.val[1]; \ + c.val = v.val[2]; \ +} \ +inline void v_load_deinterleave(const _Tp* ptr, v_##_Tpvec& a, v_##_Tpvec& b, \ + v_##_Tpvec& c, v_##_Tpvec& d) \ +{ \ + _Tpvec##x4_t v = vld4q_##suffix(ptr); \ + a.val = v.val[0]; \ + b.val = v.val[1]; \ + c.val = v.val[2]; \ + d.val = v.val[3]; \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + _Tpvec##x2_t v; \ + v.val[0] = a.val; \ + v.val[1] = b.val; \ + vst2q_##suffix(ptr, v); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \ + const v_##_Tpvec& c, hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + _Tpvec##x3_t v; \ + v.val[0] = a.val; \ + v.val[1] = b.val; \ + v.val[2] = c.val; \ + vst3q_##suffix(ptr, v); \ +} \ +inline void v_store_interleave( _Tp* ptr, const v_##_Tpvec& a, const v_##_Tpvec& b, \ + const v_##_Tpvec& c, const v_##_Tpvec& d, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec##x4_t v; \ + v.val[0] = a.val; \ + v.val[1] = b.val; \ + v.val[2] = c.val; \ + v.val[3] = d.val; \ + vst4q_##suffix(ptr, v); \ +} + +#define OPENCV_HAL_IMPL_NEON_INTERLEAVED_INT64(tp, suffix) \ +inline void v_load_deinterleave( const tp* ptr, v_##tp##x2& a, v_##tp##x2& b ) \ +{ \ + tp##x1_t a0 = vld1_##suffix(ptr); \ + tp##x1_t b0 = vld1_##suffix(ptr + 1); \ + tp##x1_t a1 = vld1_##suffix(ptr + 2); \ + tp##x1_t b1 = vld1_##suffix(ptr + 3); \ + a = v_##tp##x2(vcombine_##suffix(a0, a1)); \ + b = v_##tp##x2(vcombine_##suffix(b0, b1)); \ +} \ + \ +inline void v_load_deinterleave( const tp* ptr, v_##tp##x2& a, \ + v_##tp##x2& b, v_##tp##x2& c ) \ +{ \ + tp##x1_t a0 = vld1_##suffix(ptr); \ + tp##x1_t b0 = vld1_##suffix(ptr + 1); \ + tp##x1_t c0 = vld1_##suffix(ptr + 2); \ + tp##x1_t a1 = vld1_##suffix(ptr + 3); \ + tp##x1_t b1 = vld1_##suffix(ptr + 4); \ + tp##x1_t c1 = vld1_##suffix(ptr + 5); \ + a = v_##tp##x2(vcombine_##suffix(a0, a1)); \ + b = v_##tp##x2(vcombine_##suffix(b0, b1)); \ + c = v_##tp##x2(vcombine_##suffix(c0, c1)); \ +} \ + \ +inline void v_load_deinterleave( const tp* ptr, v_##tp##x2& a, v_##tp##x2& b, \ + v_##tp##x2& c, v_##tp##x2& d ) \ +{ \ + tp##x1_t a0 = vld1_##suffix(ptr); \ + tp##x1_t b0 = vld1_##suffix(ptr + 1); \ + tp##x1_t c0 = vld1_##suffix(ptr + 2); \ + tp##x1_t d0 = vld1_##suffix(ptr + 3); \ + tp##x1_t a1 = vld1_##suffix(ptr + 4); \ + tp##x1_t b1 = vld1_##suffix(ptr + 5); \ + tp##x1_t c1 = vld1_##suffix(ptr + 6); \ + tp##x1_t d1 = vld1_##suffix(ptr + 7); \ + a = v_##tp##x2(vcombine_##suffix(a0, a1)); \ + b = v_##tp##x2(vcombine_##suffix(b0, b1)); \ + c = v_##tp##x2(vcombine_##suffix(c0, c1)); \ + d = v_##tp##x2(vcombine_##suffix(d0, d1)); \ +} \ + \ +inline void v_store_interleave( tp* ptr, const v_##tp##x2& a, const v_##tp##x2& b, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + vst1_##suffix(ptr, vget_low_##suffix(a.val)); \ + vst1_##suffix(ptr + 1, vget_low_##suffix(b.val)); \ + vst1_##suffix(ptr + 2, vget_high_##suffix(a.val)); \ + vst1_##suffix(ptr + 3, vget_high_##suffix(b.val)); \ +} \ + \ +inline void v_store_interleave( tp* ptr, const v_##tp##x2& a, \ + const v_##tp##x2& b, const v_##tp##x2& c, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + vst1_##suffix(ptr, vget_low_##suffix(a.val)); \ + vst1_##suffix(ptr + 1, vget_low_##suffix(b.val)); \ + vst1_##suffix(ptr + 2, vget_low_##suffix(c.val)); \ + vst1_##suffix(ptr + 3, vget_high_##suffix(a.val)); \ + vst1_##suffix(ptr + 4, vget_high_##suffix(b.val)); \ + vst1_##suffix(ptr + 5, vget_high_##suffix(c.val)); \ +} \ + \ +inline void v_store_interleave( tp* ptr, const v_##tp##x2& a, const v_##tp##x2& b, \ + const v_##tp##x2& c, const v_##tp##x2& d, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ \ + vst1_##suffix(ptr, vget_low_##suffix(a.val)); \ + vst1_##suffix(ptr + 1, vget_low_##suffix(b.val)); \ + vst1_##suffix(ptr + 2, vget_low_##suffix(c.val)); \ + vst1_##suffix(ptr + 3, vget_low_##suffix(d.val)); \ + vst1_##suffix(ptr + 4, vget_high_##suffix(a.val)); \ + vst1_##suffix(ptr + 5, vget_high_##suffix(b.val)); \ + vst1_##suffix(ptr + 6, vget_high_##suffix(c.val)); \ + vst1_##suffix(ptr + 7, vget_high_##suffix(d.val)); \ +} + +OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint8x16, uchar, u8) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(int8x16, schar, s8) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint16x8, ushort, u16) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(int16x8, short, s16) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(int32x4, int, s32) +OPENCV_HAL_IMPL_NEON_INTERLEAVED(float32x4, float, f32) +#if CV_SIMD128_64F +OPENCV_HAL_IMPL_NEON_INTERLEAVED(float64x2, double, f64) +#endif + +OPENCV_HAL_IMPL_NEON_INTERLEAVED_INT64(int64, s64) +OPENCV_HAL_IMPL_NEON_INTERLEAVED_INT64(uint64, u64) + +inline v_float32x4 v_cvt_f32(const v_int32x4& a) +{ + return v_float32x4(vcvtq_f32_s32(a.val)); +} + +#if CV_SIMD128_64F +inline v_float32x4 v_cvt_f32(const v_float64x2& a) +{ + float32x2_t zero = vdup_n_f32(0.0f); + return v_float32x4(vcombine_f32(vcvt_f32_f64(a.val), zero)); +} + +inline v_float32x4 v_cvt_f32(const v_float64x2& a, const v_float64x2& b) +{ + return v_float32x4(vcombine_f32(vcvt_f32_f64(a.val), vcvt_f32_f64(b.val))); +} + +inline v_float64x2 v_cvt_f64(const v_int32x4& a) +{ + return v_float64x2(vcvt_f64_f32(vcvt_f32_s32(vget_low_s32(a.val)))); +} + +inline v_float64x2 v_cvt_f64_high(const v_int32x4& a) +{ + return v_float64x2(vcvt_f64_f32(vcvt_f32_s32(vget_high_s32(a.val)))); +} + +inline v_float64x2 v_cvt_f64(const v_float32x4& a) +{ + return v_float64x2(vcvt_f64_f32(vget_low_f32(a.val))); +} + +inline v_float64x2 v_cvt_f64_high(const v_float32x4& a) +{ + return v_float64x2(vcvt_f64_f32(vget_high_f32(a.val))); +} +#endif + +////////////// Lookup table access //////////////////// + +inline v_int8x16 v_lut(const schar* tab, const int* idx) +{ + schar CV_DECL_ALIGNED(32) elems[16] = + { + tab[idx[ 0]], + tab[idx[ 1]], + tab[idx[ 2]], + tab[idx[ 3]], + tab[idx[ 4]], + tab[idx[ 5]], + tab[idx[ 6]], + tab[idx[ 7]], + tab[idx[ 8]], + tab[idx[ 9]], + tab[idx[10]], + tab[idx[11]], + tab[idx[12]], + tab[idx[13]], + tab[idx[14]], + tab[idx[15]] + }; + return v_int8x16(vld1q_s8(elems)); +} +inline v_int8x16 v_lut_pairs(const schar* tab, const int* idx) +{ + schar CV_DECL_ALIGNED(32) elems[16] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[1]], + tab[idx[1] + 1], + tab[idx[2]], + tab[idx[2] + 1], + tab[idx[3]], + tab[idx[3] + 1], + tab[idx[4]], + tab[idx[4] + 1], + tab[idx[5]], + tab[idx[5] + 1], + tab[idx[6]], + tab[idx[6] + 1], + tab[idx[7]], + tab[idx[7] + 1] + }; + return v_int8x16(vld1q_s8(elems)); +} +inline v_int8x16 v_lut_quads(const schar* tab, const int* idx) +{ + schar CV_DECL_ALIGNED(32) elems[16] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[0] + 2], + tab[idx[0] + 3], + tab[idx[1]], + tab[idx[1] + 1], + tab[idx[1] + 2], + tab[idx[1] + 3], + tab[idx[2]], + tab[idx[2] + 1], + tab[idx[2] + 2], + tab[idx[2] + 3], + tab[idx[3]], + tab[idx[3] + 1], + tab[idx[3] + 2], + tab[idx[3] + 3] + }; + return v_int8x16(vld1q_s8(elems)); +} +inline v_uint8x16 v_lut(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut((schar*)tab, idx)); } +inline v_uint8x16 v_lut_pairs(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_pairs((schar*)tab, idx)); } +inline v_uint8x16 v_lut_quads(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_quads((schar*)tab, idx)); } + +inline v_int16x8 v_lut(const short* tab, const int* idx) +{ + short CV_DECL_ALIGNED(32) elems[8] = + { + tab[idx[0]], + tab[idx[1]], + tab[idx[2]], + tab[idx[3]], + tab[idx[4]], + tab[idx[5]], + tab[idx[6]], + tab[idx[7]] + }; + return v_int16x8(vld1q_s16(elems)); +} +inline v_int16x8 v_lut_pairs(const short* tab, const int* idx) +{ + short CV_DECL_ALIGNED(32) elems[8] = + { + tab[idx[0]], + tab[idx[0] + 1], + tab[idx[1]], + tab[idx[1] + 1], + tab[idx[2]], + tab[idx[2] + 1], + tab[idx[3]], + tab[idx[3] + 1] + }; + return v_int16x8(vld1q_s16(elems)); +} +inline v_int16x8 v_lut_quads(const short* tab, const int* idx) +{ + return v_int16x8(vcombine_s16(vld1_s16(tab + idx[0]), vld1_s16(tab + idx[1]))); +} +inline v_uint16x8 v_lut(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut((short*)tab, idx)); } +inline v_uint16x8 v_lut_pairs(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_pairs((short*)tab, idx)); } +inline v_uint16x8 v_lut_quads(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_quads((short*)tab, idx)); } + +inline v_int32x4 v_lut(const int* tab, const int* idx) +{ + int CV_DECL_ALIGNED(32) elems[4] = + { + tab[idx[0]], + tab[idx[1]], + tab[idx[2]], + tab[idx[3]] + }; + return v_int32x4(vld1q_s32(elems)); +} +inline v_int32x4 v_lut_pairs(const int* tab, const int* idx) +{ + return v_int32x4(vcombine_s32(vld1_s32(tab + idx[0]), vld1_s32(tab + idx[1]))); +} +inline v_int32x4 v_lut_quads(const int* tab, const int* idx) +{ + return v_int32x4(vld1q_s32(tab + idx[0])); +} +inline v_uint32x4 v_lut(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut((int*)tab, idx)); } +inline v_uint32x4 v_lut_pairs(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_pairs((int*)tab, idx)); } +inline v_uint32x4 v_lut_quads(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_quads((int*)tab, idx)); } + +inline v_int64x2 v_lut(const int64_t* tab, const int* idx) +{ + return v_int64x2(vcombine_s64(vcreate_s64(tab[idx[0]]), vcreate_s64(tab[idx[1]]))); +} +inline v_int64x2 v_lut_pairs(const int64_t* tab, const int* idx) +{ + return v_int64x2(vld1q_s64(tab + idx[0])); +} +inline v_uint64x2 v_lut(const uint64_t* tab, const int* idx) { return v_reinterpret_as_u64(v_lut((const int64_t *)tab, idx)); } +inline v_uint64x2 v_lut_pairs(const uint64_t* tab, const int* idx) { return v_reinterpret_as_u64(v_lut_pairs((const int64_t *)tab, idx)); } + +inline v_float32x4 v_lut(const float* tab, const int* idx) +{ + float CV_DECL_ALIGNED(32) elems[4] = + { + tab[idx[0]], + tab[idx[1]], + tab[idx[2]], + tab[idx[3]] + }; + return v_float32x4(vld1q_f32(elems)); +} +inline v_float32x4 v_lut_pairs(const float* tab, const int* idx) +{ + uint64 CV_DECL_ALIGNED(32) elems[2] = + { + *(uint64*)(tab + idx[0]), + *(uint64*)(tab + idx[1]) + }; + return v_float32x4(vreinterpretq_f32_u64(vld1q_u64(elems))); +} +inline v_float32x4 v_lut_quads(const float* tab, const int* idx) +{ + return v_float32x4(vld1q_f32(tab + idx[0])); +} + +inline v_int32x4 v_lut(const int* tab, const v_int32x4& idxvec) +{ + int CV_DECL_ALIGNED(32) elems[4] = + { + tab[vgetq_lane_s32(idxvec.val, 0)], + tab[vgetq_lane_s32(idxvec.val, 1)], + tab[vgetq_lane_s32(idxvec.val, 2)], + tab[vgetq_lane_s32(idxvec.val, 3)] + }; + return v_int32x4(vld1q_s32(elems)); +} + +inline v_uint32x4 v_lut(const unsigned* tab, const v_int32x4& idxvec) +{ + unsigned CV_DECL_ALIGNED(32) elems[4] = + { + tab[vgetq_lane_s32(idxvec.val, 0)], + tab[vgetq_lane_s32(idxvec.val, 1)], + tab[vgetq_lane_s32(idxvec.val, 2)], + tab[vgetq_lane_s32(idxvec.val, 3)] + }; + return v_uint32x4(vld1q_u32(elems)); +} + +inline v_float32x4 v_lut(const float* tab, const v_int32x4& idxvec) +{ + float CV_DECL_ALIGNED(32) elems[4] = + { + tab[vgetq_lane_s32(idxvec.val, 0)], + tab[vgetq_lane_s32(idxvec.val, 1)], + tab[vgetq_lane_s32(idxvec.val, 2)], + tab[vgetq_lane_s32(idxvec.val, 3)] + }; + return v_float32x4(vld1q_f32(elems)); +} + +inline void v_lut_deinterleave(const float* tab, const v_int32x4& idxvec, v_float32x4& x, v_float32x4& y) +{ + /*int CV_DECL_ALIGNED(32) idx[4]; + v_store(idx, idxvec); + + float32x4_t xy02 = vcombine_f32(vld1_f32(tab + idx[0]), vld1_f32(tab + idx[2])); + float32x4_t xy13 = vcombine_f32(vld1_f32(tab + idx[1]), vld1_f32(tab + idx[3])); + + float32x4x2_t xxyy = vuzpq_f32(xy02, xy13); + x = v_float32x4(xxyy.val[0]); + y = v_float32x4(xxyy.val[1]);*/ + int CV_DECL_ALIGNED(32) idx[4]; + v_store_aligned(idx, idxvec); + + x = v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]); + y = v_float32x4(tab[idx[0]+1], tab[idx[1]+1], tab[idx[2]+1], tab[idx[3]+1]); +} + +inline v_int8x16 v_interleave_pairs(const v_int8x16& vec) +{ + return v_int8x16(vcombine_s8(vtbl1_s8(vget_low_s8(vec.val), vcreate_s8(0x0705060403010200)), vtbl1_s8(vget_high_s8(vec.val), vcreate_s8(0x0705060403010200)))); +} +inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); } +inline v_int8x16 v_interleave_quads(const v_int8x16& vec) +{ + return v_int8x16(vcombine_s8(vtbl1_s8(vget_low_s8(vec.val), vcreate_s8(0x0703060205010400)), vtbl1_s8(vget_high_s8(vec.val), vcreate_s8(0x0703060205010400)))); +} +inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); } + +inline v_int16x8 v_interleave_pairs(const v_int16x8& vec) +{ + return v_int16x8(vreinterpretq_s16_s8(vcombine_s8(vtbl1_s8(vget_low_s8(vreinterpretq_s8_s16(vec.val)), vcreate_s8(0x0706030205040100)), vtbl1_s8(vget_high_s8(vreinterpretq_s8_s16(vec.val)), vcreate_s8(0x0706030205040100))))); +} +inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); } +inline v_int16x8 v_interleave_quads(const v_int16x8& vec) +{ + int16x4x2_t res = vzip_s16(vget_low_s16(vec.val), vget_high_s16(vec.val)); + return v_int16x8(vcombine_s16(res.val[0], res.val[1])); +} +inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_interleave_pairs(const v_int32x4& vec) +{ + int32x2x2_t res = vzip_s32(vget_low_s32(vec.val), vget_high_s32(vec.val)); + return v_int32x4(vcombine_s32(res.val[0], res.val[1])); +} +inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec) { return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } +inline v_float32x4 v_interleave_pairs(const v_float32x4& vec) { return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } + +inline v_int8x16 v_pack_triplets(const v_int8x16& vec) +{ + return v_int8x16(vextq_s8(vcombine_s8(vtbl1_s8(vget_low_s8(vec.val), vcreate_s8(0x0605040201000000)), vtbl1_s8(vget_high_s8(vec.val), vcreate_s8(0x0807060504020100))), vdupq_n_s8(0), 2)); +} +inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); } + +inline v_int16x8 v_pack_triplets(const v_int16x8& vec) +{ + return v_int16x8(vreinterpretq_s16_s8(vextq_s8(vcombine_s8(vtbl1_s8(vget_low_s8(vreinterpretq_s8_s16(vec.val)), vcreate_s8(0x0504030201000000)), vget_high_s8(vreinterpretq_s8_s16(vec.val))), vdupq_n_s8(0), 2))); +} +inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_pack_triplets(const v_int32x4& vec) { return vec; } +inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) { return vec; } +inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; } + +#if CV_SIMD128_64F +inline v_float64x2 v_lut(const double* tab, const int* idx) +{ + double CV_DECL_ALIGNED(32) elems[2] = + { + tab[idx[0]], + tab[idx[1]] + }; + return v_float64x2(vld1q_f64(elems)); +} + +inline v_float64x2 v_lut_pairs(const double* tab, const int* idx) +{ + return v_float64x2(vld1q_f64(tab + idx[0])); +} + +inline v_float64x2 v_lut(const double* tab, const v_int32x4& idxvec) +{ + double CV_DECL_ALIGNED(32) elems[2] = + { + tab[vgetq_lane_s32(idxvec.val, 0)], + tab[vgetq_lane_s32(idxvec.val, 1)], + }; + return v_float64x2(vld1q_f64(elems)); +} + +inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_float64x2& x, v_float64x2& y) +{ + int CV_DECL_ALIGNED(32) idx[4]; + v_store_aligned(idx, idxvec); + + x = v_float64x2(tab[idx[0]], tab[idx[1]]); + y = v_float64x2(tab[idx[0]+1], tab[idx[1]+1]); +} +#endif + +////// FP16 support /////// +#if CV_FP16 +inline v_float32x4 v_load_expand(const float16_t* ptr) +{ + float16x4_t v = + #ifndef vld1_f16 // APPLE compiler defines vld1_f16 as macro + (float16x4_t)vld1_s16((const short*)ptr); + #else + vld1_f16((const __fp16*)ptr); + #endif + return v_float32x4(vcvt_f32_f16(v)); +} + +inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +{ + float16x4_t hv = vcvt_f16_f32(v.val); + + #ifndef vst1_f16 // APPLE compiler defines vst1_f16 as macro + vst1_s16((short*)ptr, (int16x4_t)hv); + #else + vst1_f16((__fp16*)ptr, hv); + #endif +} +#else +inline v_float32x4 v_load_expand(const float16_t* ptr) +{ + const int N = 4; + float buf[N]; + for( int i = 0; i < N; i++ ) buf[i] = (float)ptr[i]; + return v_load(buf); +} + +inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +{ + const int N = 4; + float buf[N]; + v_store(buf, v); + for( int i = 0; i < N; i++ ) ptr[i] = float16_t(buf[i]); +} +#endif + +inline void v_cleanup() {} + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse.hpp new file mode 100755 index 0000000..e172d45 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse.hpp @@ -0,0 +1,3063 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HAL_SSE_HPP +#define OPENCV_HAL_SSE_HPP + +#include +#include "opencv2/core/utility.hpp" + +#define CV_SIMD128 1 +#define CV_SIMD128_64F 1 +#define CV_SIMD128_FP16 0 // no native operations with FP16 type. + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +///////// Types //////////// + +struct v_uint8x16 +{ + typedef uchar lane_type; + typedef __m128i vector_type; + enum { nlanes = 16 }; + + v_uint8x16() : val(_mm_setzero_si128()) {} + explicit v_uint8x16(__m128i v) : val(v) {} + v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15) + { + val = _mm_setr_epi8((char)v0, (char)v1, (char)v2, (char)v3, + (char)v4, (char)v5, (char)v6, (char)v7, + (char)v8, (char)v9, (char)v10, (char)v11, + (char)v12, (char)v13, (char)v14, (char)v15); + } + uchar get0() const + { + return (uchar)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_int8x16 +{ + typedef schar lane_type; + typedef __m128i vector_type; + enum { nlanes = 16 }; + + v_int8x16() : val(_mm_setzero_si128()) {} + explicit v_int8x16(__m128i v) : val(v) {} + v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15) + { + val = _mm_setr_epi8((char)v0, (char)v1, (char)v2, (char)v3, + (char)v4, (char)v5, (char)v6, (char)v7, + (char)v8, (char)v9, (char)v10, (char)v11, + (char)v12, (char)v13, (char)v14, (char)v15); + } + schar get0() const + { + return (schar)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_uint16x8 +{ + typedef ushort lane_type; + typedef __m128i vector_type; + enum { nlanes = 8 }; + + v_uint16x8() : val(_mm_setzero_si128()) {} + explicit v_uint16x8(__m128i v) : val(v) {} + v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7) + { + val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3, + (short)v4, (short)v5, (short)v6, (short)v7); + } + ushort get0() const + { + return (ushort)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_int16x8 +{ + typedef short lane_type; + typedef __m128i vector_type; + enum { nlanes = 8 }; + + v_int16x8() : val(_mm_setzero_si128()) {} + explicit v_int16x8(__m128i v) : val(v) {} + v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7) + { + val = _mm_setr_epi16((short)v0, (short)v1, (short)v2, (short)v3, + (short)v4, (short)v5, (short)v6, (short)v7); + } + short get0() const + { + return (short)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_uint32x4 +{ + typedef unsigned lane_type; + typedef __m128i vector_type; + enum { nlanes = 4 }; + + v_uint32x4() : val(_mm_setzero_si128()) {} + explicit v_uint32x4(__m128i v) : val(v) {} + v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) + { + val = _mm_setr_epi32((int)v0, (int)v1, (int)v2, (int)v3); + } + unsigned get0() const + { + return (unsigned)_mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_int32x4 +{ + typedef int lane_type; + typedef __m128i vector_type; + enum { nlanes = 4 }; + + v_int32x4() : val(_mm_setzero_si128()) {} + explicit v_int32x4(__m128i v) : val(v) {} + v_int32x4(int v0, int v1, int v2, int v3) + { + val = _mm_setr_epi32(v0, v1, v2, v3); + } + int get0() const + { + return _mm_cvtsi128_si32(val); + } + + __m128i val; +}; + +struct v_float32x4 +{ + typedef float lane_type; + typedef __m128 vector_type; + enum { nlanes = 4 }; + + v_float32x4() : val(_mm_setzero_ps()) {} + explicit v_float32x4(__m128 v) : val(v) {} + v_float32x4(float v0, float v1, float v2, float v3) + { + val = _mm_setr_ps(v0, v1, v2, v3); + } + float get0() const + { + return _mm_cvtss_f32(val); + } + + __m128 val; +}; + +struct v_uint64x2 +{ + typedef uint64 lane_type; + typedef __m128i vector_type; + enum { nlanes = 2 }; + + v_uint64x2() : val(_mm_setzero_si128()) {} + explicit v_uint64x2(__m128i v) : val(v) {} + v_uint64x2(uint64 v0, uint64 v1) + { + val = _mm_setr_epi32((int)v0, (int)(v0 >> 32), (int)v1, (int)(v1 >> 32)); + } + uint64 get0() const + { + int a = _mm_cvtsi128_si32(val); + int b = _mm_cvtsi128_si32(_mm_srli_epi64(val, 32)); + return (unsigned)a | ((uint64)(unsigned)b << 32); + } + + __m128i val; +}; + +struct v_int64x2 +{ + typedef int64 lane_type; + typedef __m128i vector_type; + enum { nlanes = 2 }; + + v_int64x2() : val(_mm_setzero_si128()) {} + explicit v_int64x2(__m128i v) : val(v) {} + v_int64x2(int64 v0, int64 v1) + { + val = _mm_setr_epi32((int)v0, (int)(v0 >> 32), (int)v1, (int)(v1 >> 32)); + } + int64 get0() const + { + int a = _mm_cvtsi128_si32(val); + int b = _mm_cvtsi128_si32(_mm_srli_epi64(val, 32)); + return (int64)((unsigned)a | ((uint64)(unsigned)b << 32)); + } + + __m128i val; +}; + +struct v_float64x2 +{ + typedef double lane_type; + typedef __m128d vector_type; + enum { nlanes = 2 }; + + v_float64x2() : val(_mm_setzero_pd()) {} + explicit v_float64x2(__m128d v) : val(v) {} + v_float64x2(double v0, double v1) + { + val = _mm_setr_pd(v0, v1); + } + double get0() const + { + return _mm_cvtsd_f64(val); + } + + __m128d val; +}; + +namespace hal_sse_internal +{ + template + to_sse_type v_sse_reinterpret_as(const from_sse_type& val); + +#define OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(to_sse_type, from_sse_type, sse_cast_intrin) \ + template<> inline \ + to_sse_type v_sse_reinterpret_as(const from_sse_type& a) \ + { return sse_cast_intrin(a); } + + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128i, __m128i, OPENCV_HAL_NOP) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128i, __m128, _mm_castps_si128) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128i, __m128d, _mm_castpd_si128) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128, __m128i, _mm_castsi128_ps) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128, __m128, OPENCV_HAL_NOP) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128, __m128d, _mm_castpd_ps) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128d, __m128i, _mm_castsi128_pd) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128d, __m128, _mm_castps_pd) + OPENCV_HAL_IMPL_SSE_REINTERPRET_RAW(__m128d, __m128d, OPENCV_HAL_NOP) +} + +#define OPENCV_HAL_IMPL_SSE_INITVEC(_Tpvec, _Tp, suffix, zsuffix, ssuffix, _Tps, cast) \ +inline _Tpvec v_setzero_##suffix() { return _Tpvec(_mm_setzero_##zsuffix()); } \ +inline _Tpvec v_setall_##suffix(_Tp v) { return _Tpvec(_mm_set1_##ssuffix((_Tps)v)); } \ +template inline _Tpvec v_reinterpret_as_##suffix(const _Tpvec0& a) \ +{ return _Tpvec(cast(a.val)); } + +OPENCV_HAL_IMPL_SSE_INITVEC(v_uint8x16, uchar, u8, si128, epi8, schar, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_INITVEC(v_int8x16, schar, s8, si128, epi8, schar, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_INITVEC(v_uint16x8, ushort, u16, si128, epi16, short, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_INITVEC(v_int16x8, short, s16, si128, epi16, short, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_INITVEC(v_uint32x4, unsigned, u32, si128, epi32, int, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_INITVEC(v_int32x4, int, s32, si128, epi32, int, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_INITVEC(v_float32x4, float, f32, ps, ps, float, _mm_castsi128_ps) +OPENCV_HAL_IMPL_SSE_INITVEC(v_float64x2, double, f64, pd, pd, double, _mm_castsi128_pd) + +inline v_uint64x2 v_setzero_u64() { return v_uint64x2(_mm_setzero_si128()); } +inline v_int64x2 v_setzero_s64() { return v_int64x2(_mm_setzero_si128()); } +inline v_uint64x2 v_setall_u64(uint64 val) { return v_uint64x2(val, val); } +inline v_int64x2 v_setall_s64(int64 val) { return v_int64x2(val, val); } + +template inline +v_uint64x2 v_reinterpret_as_u64(const _Tpvec& a) { return v_uint64x2(a.val); } +template inline +v_int64x2 v_reinterpret_as_s64(const _Tpvec& a) { return v_int64x2(a.val); } +inline v_float32x4 v_reinterpret_as_f32(const v_uint64x2& a) +{ return v_float32x4(_mm_castsi128_ps(a.val)); } +inline v_float32x4 v_reinterpret_as_f32(const v_int64x2& a) +{ return v_float32x4(_mm_castsi128_ps(a.val)); } +inline v_float64x2 v_reinterpret_as_f64(const v_uint64x2& a) +{ return v_float64x2(_mm_castsi128_pd(a.val)); } +inline v_float64x2 v_reinterpret_as_f64(const v_int64x2& a) +{ return v_float64x2(_mm_castsi128_pd(a.val)); } + +#define OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(_Tpvec, suffix) \ +inline _Tpvec v_reinterpret_as_##suffix(const v_float32x4& a) \ +{ return _Tpvec(_mm_castps_si128(a.val)); } \ +inline _Tpvec v_reinterpret_as_##suffix(const v_float64x2& a) \ +{ return _Tpvec(_mm_castpd_si128(a.val)); } + +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint8x16, u8) +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int8x16, s8) +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint16x8, u16) +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int16x8, s16) +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint32x4, u32) +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int32x4, s32) +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_uint64x2, u64) +OPENCV_HAL_IMPL_SSE_INIT_FROM_FLT(v_int64x2, s64) + +inline v_float32x4 v_reinterpret_as_f32(const v_float32x4& a) {return a; } +inline v_float64x2 v_reinterpret_as_f64(const v_float64x2& a) {return a; } +inline v_float32x4 v_reinterpret_as_f32(const v_float64x2& a) {return v_float32x4(_mm_castpd_ps(a.val)); } +inline v_float64x2 v_reinterpret_as_f64(const v_float32x4& a) {return v_float64x2(_mm_castps_pd(a.val)); } + +//////////////// PACK /////////////// +inline v_uint8x16 v_pack(const v_uint16x8& a, const v_uint16x8& b) +{ + __m128i delta = _mm_set1_epi16(255); + return v_uint8x16(_mm_packus_epi16(_mm_subs_epu16(a.val, _mm_subs_epu16(a.val, delta)), + _mm_subs_epu16(b.val, _mm_subs_epu16(b.val, delta)))); +} + +inline void v_pack_store(uchar* ptr, const v_uint16x8& a) +{ + __m128i delta = _mm_set1_epi16(255); + __m128i a1 = _mm_subs_epu16(a.val, _mm_subs_epu16(a.val, delta)); + _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a1, a1)); +} + +inline v_uint8x16 v_pack_u(const v_int16x8& a, const v_int16x8& b) +{ return v_uint8x16(_mm_packus_epi16(a.val, b.val)); } + +inline void v_pack_u_store(uchar* ptr, const v_int16x8& a) +{ _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a.val, a.val)); } + +template inline +v_uint8x16 v_rshr_pack(const v_uint16x8& a, const v_uint16x8& b) +{ + // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + return v_uint8x16(_mm_packus_epi16(_mm_srli_epi16(_mm_adds_epu16(a.val, delta), n), + _mm_srli_epi16(_mm_adds_epu16(b.val, delta), n))); +} + +template inline +void v_rshr_pack_store(uchar* ptr, const v_uint16x8& a) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + __m128i a1 = _mm_srli_epi16(_mm_adds_epu16(a.val, delta), n); + _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a1, a1)); +} + +template inline +v_uint8x16 v_rshr_pack_u(const v_int16x8& a, const v_int16x8& b) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + return v_uint8x16(_mm_packus_epi16(_mm_srai_epi16(_mm_adds_epi16(a.val, delta), n), + _mm_srai_epi16(_mm_adds_epi16(b.val, delta), n))); +} + +template inline +void v_rshr_pack_u_store(uchar* ptr, const v_int16x8& a) +{ + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + __m128i a1 = _mm_srai_epi16(_mm_adds_epi16(a.val, delta), n); + _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi16(a1, a1)); +} + +inline v_int8x16 v_pack(const v_int16x8& a, const v_int16x8& b) +{ return v_int8x16(_mm_packs_epi16(a.val, b.val)); } + +inline void v_pack_store(schar* ptr, const v_int16x8& a) +{ _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi16(a.val, a.val)); } + +template inline +v_int8x16 v_rshr_pack(const v_int16x8& a, const v_int16x8& b) +{ + // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + return v_int8x16(_mm_packs_epi16(_mm_srai_epi16(_mm_adds_epi16(a.val, delta), n), + _mm_srai_epi16(_mm_adds_epi16(b.val, delta), n))); +} +template inline +void v_rshr_pack_store(schar* ptr, const v_int16x8& a) +{ + // we assume that n > 0, and so the shifted 16-bit values can be treated as signed numbers. + __m128i delta = _mm_set1_epi16((short)(1 << (n-1))); + __m128i a1 = _mm_srai_epi16(_mm_adds_epi16(a.val, delta), n); + _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi16(a1, a1)); +} + + +// byte-wise "mask ? a : b" +inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b) +{ +#if CV_SSE4_1 + return _mm_blendv_epi8(b, a, mask); +#else + return _mm_xor_si128(b, _mm_and_si128(_mm_xor_si128(a, b), mask)); +#endif +} + +inline v_uint16x8 v_pack(const v_uint32x4& a, const v_uint32x4& b) +{ return v_uint16x8(_v128_packs_epu32(a.val, b.val)); } + +inline void v_pack_store(ushort* ptr, const v_uint32x4& a) +{ + __m128i z = _mm_setzero_si128(), maxval32 = _mm_set1_epi32(65535), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, a.val), maxval32, a.val), delta32); + __m128i r = _mm_packs_epi32(a1, a1); + _mm_storel_epi64((__m128i*)ptr, _mm_sub_epi16(r, _mm_set1_epi16(-32768))); +} + +template inline +v_uint16x8 v_rshr_pack(const v_uint32x4& a, const v_uint32x4& b) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i b1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(b.val, delta), n), delta32); + return v_uint16x8(_mm_sub_epi16(_mm_packs_epi32(a1, b1), _mm_set1_epi16(-32768))); +} + +template inline +void v_rshr_pack_store(ushort* ptr, const v_uint32x4& a) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srli_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768)); + _mm_storel_epi64((__m128i*)ptr, a2); +} + +inline v_uint16x8 v_pack_u(const v_int32x4& a, const v_int32x4& b) +{ +#if CV_SSE4_1 + return v_uint16x8(_mm_packus_epi32(a.val, b.val)); +#else + __m128i delta32 = _mm_set1_epi32(32768); + + // preliminary saturate negative values to zero + __m128i a1 = _mm_and_si128(a.val, _mm_cmpgt_epi32(a.val, _mm_set1_epi32(0))); + __m128i b1 = _mm_and_si128(b.val, _mm_cmpgt_epi32(b.val, _mm_set1_epi32(0))); + + __m128i r = _mm_packs_epi32(_mm_sub_epi32(a1, delta32), _mm_sub_epi32(b1, delta32)); + return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768))); +#endif +} + +inline void v_pack_u_store(ushort* ptr, const v_int32x4& a) +{ +#if CV_SSE4_1 + _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi32(a.val, a.val)); +#else + __m128i delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(a.val, delta32); + __m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768)); + _mm_storel_epi64((__m128i*)ptr, r); +#endif +} + +template inline +v_uint16x8 v_rshr_pack_u(const v_int32x4& a, const v_int32x4& b) +{ +#if CV_SSE4_1 + __m128i delta = _mm_set1_epi32(1 << (n - 1)); + return v_uint16x8(_mm_packus_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), + _mm_srai_epi32(_mm_add_epi32(b.val, delta), n))); +#else + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768)); + __m128i b1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(b.val, delta), n), delta32); + __m128i b2 = _mm_sub_epi16(_mm_packs_epi32(b1, b1), _mm_set1_epi16(-32768)); + return v_uint16x8(_mm_unpacklo_epi64(a2, b2)); +#endif +} + +template inline +void v_rshr_pack_u_store(ushort* ptr, const v_int32x4& a) +{ +#if CV_SSE4_1 + __m128i delta = _mm_set1_epi32(1 << (n - 1)); + __m128i a1 = _mm_srai_epi32(_mm_add_epi32(a.val, delta), n); + _mm_storel_epi64((__m128i*)ptr, _mm_packus_epi32(a1, a1)); +#else + __m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768); + __m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32); + __m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768)); + _mm_storel_epi64((__m128i*)ptr, a2); +#endif +} + +inline v_int16x8 v_pack(const v_int32x4& a, const v_int32x4& b) +{ return v_int16x8(_mm_packs_epi32(a.val, b.val)); } + +inline void v_pack_store(short* ptr, const v_int32x4& a) +{ + _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a.val, a.val)); +} + +template inline +v_int16x8 v_rshr_pack(const v_int32x4& a, const v_int32x4& b) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)); + return v_int16x8(_mm_packs_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), + _mm_srai_epi32(_mm_add_epi32(b.val, delta), n))); +} + +template inline +void v_rshr_pack_store(short* ptr, const v_int32x4& a) +{ + __m128i delta = _mm_set1_epi32(1 << (n-1)); + __m128i a1 = _mm_srai_epi32(_mm_add_epi32(a.val, delta), n); + _mm_storel_epi64((__m128i*)ptr, _mm_packs_epi32(a1, a1)); +} + + +// [a0 0 | b0 0] [a1 0 | b1 0] +inline v_uint32x4 v_pack(const v_uint64x2& a, const v_uint64x2& b) +{ + __m128i v0 = _mm_unpacklo_epi32(a.val, b.val); // a0 a1 0 0 + __m128i v1 = _mm_unpackhi_epi32(a.val, b.val); // b0 b1 0 0 + return v_uint32x4(_mm_unpacklo_epi32(v0, v1)); +} + +inline void v_pack_store(unsigned* ptr, const v_uint64x2& a) +{ + __m128i a1 = _mm_shuffle_epi32(a.val, _MM_SHUFFLE(0, 2, 2, 0)); + _mm_storel_epi64((__m128i*)ptr, a1); +} + +// [a0 0 | b0 0] [a1 0 | b1 0] +inline v_int32x4 v_pack(const v_int64x2& a, const v_int64x2& b) +{ + __m128i v0 = _mm_unpacklo_epi32(a.val, b.val); // a0 a1 0 0 + __m128i v1 = _mm_unpackhi_epi32(a.val, b.val); // b0 b1 0 0 + return v_int32x4(_mm_unpacklo_epi32(v0, v1)); +} + +inline void v_pack_store(int* ptr, const v_int64x2& a) +{ + __m128i a1 = _mm_shuffle_epi32(a.val, _MM_SHUFFLE(0, 2, 2, 0)); + _mm_storel_epi64((__m128i*)ptr, a1); +} + +template inline +v_uint32x4 v_rshr_pack(const v_uint64x2& a, const v_uint64x2& b) +{ + uint64 delta = (uint64)1 << (n-1); + v_uint64x2 delta2(delta, delta); + __m128i a1 = _mm_srli_epi64(_mm_add_epi64(a.val, delta2.val), n); + __m128i b1 = _mm_srli_epi64(_mm_add_epi64(b.val, delta2.val), n); + __m128i v0 = _mm_unpacklo_epi32(a1, b1); // a0 a1 0 0 + __m128i v1 = _mm_unpackhi_epi32(a1, b1); // b0 b1 0 0 + return v_uint32x4(_mm_unpacklo_epi32(v0, v1)); +} + +template inline +void v_rshr_pack_store(unsigned* ptr, const v_uint64x2& a) +{ + uint64 delta = (uint64)1 << (n-1); + v_uint64x2 delta2(delta, delta); + __m128i a1 = _mm_srli_epi64(_mm_add_epi64(a.val, delta2.val), n); + __m128i a2 = _mm_shuffle_epi32(a1, _MM_SHUFFLE(0, 2, 2, 0)); + _mm_storel_epi64((__m128i*)ptr, a2); +} + +inline __m128i v_sign_epi64(__m128i a) +{ + return _mm_shuffle_epi32(_mm_srai_epi32(a, 31), _MM_SHUFFLE(3, 3, 1, 1)); // x m0 | x m1 +} + +inline __m128i v_srai_epi64(__m128i a, int imm) +{ + __m128i smask = v_sign_epi64(a); + return _mm_xor_si128(_mm_srli_epi64(_mm_xor_si128(a, smask), imm), smask); +} + +template inline +v_int32x4 v_rshr_pack(const v_int64x2& a, const v_int64x2& b) +{ + int64 delta = (int64)1 << (n-1); + v_int64x2 delta2(delta, delta); + __m128i a1 = v_srai_epi64(_mm_add_epi64(a.val, delta2.val), n); + __m128i b1 = v_srai_epi64(_mm_add_epi64(b.val, delta2.val), n); + __m128i v0 = _mm_unpacklo_epi32(a1, b1); // a0 a1 0 0 + __m128i v1 = _mm_unpackhi_epi32(a1, b1); // b0 b1 0 0 + return v_int32x4(_mm_unpacklo_epi32(v0, v1)); +} + +template inline +void v_rshr_pack_store(int* ptr, const v_int64x2& a) +{ + int64 delta = (int64)1 << (n-1); + v_int64x2 delta2(delta, delta); + __m128i a1 = v_srai_epi64(_mm_add_epi64(a.val, delta2.val), n); + __m128i a2 = _mm_shuffle_epi32(a1, _MM_SHUFFLE(0, 2, 2, 0)); + _mm_storel_epi64((__m128i*)ptr, a2); +} + +// pack boolean +inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b) +{ + __m128i ab = _mm_packs_epi16(a.val, b.val); + return v_uint8x16(ab); +} + +inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b, + const v_uint32x4& c, const v_uint32x4& d) +{ + __m128i ab = _mm_packs_epi32(a.val, b.val); + __m128i cd = _mm_packs_epi32(c.val, d.val); + return v_uint8x16(_mm_packs_epi16(ab, cd)); +} + +inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c, + const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f, + const v_uint64x2& g, const v_uint64x2& h) +{ + __m128i ab = _mm_packs_epi32(a.val, b.val); + __m128i cd = _mm_packs_epi32(c.val, d.val); + __m128i ef = _mm_packs_epi32(e.val, f.val); + __m128i gh = _mm_packs_epi32(g.val, h.val); + + __m128i abcd = _mm_packs_epi32(ab, cd); + __m128i efgh = _mm_packs_epi32(ef, gh); + return v_uint8x16(_mm_packs_epi16(abcd, efgh)); +} + +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + __m128 v0 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(0, 0, 0, 0)), m0.val); + __m128 v1 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(1, 1, 1, 1)), m1.val); + __m128 v2 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(2, 2, 2, 2)), m2.val); + __m128 v3 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(3, 3, 3, 3)), m3.val); + + return v_float32x4(_mm_add_ps(_mm_add_ps(v0, v1), _mm_add_ps(v2, v3))); +} + +inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& a) +{ + __m128 v0 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(0, 0, 0, 0)), m0.val); + __m128 v1 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(1, 1, 1, 1)), m1.val); + __m128 v2 = _mm_mul_ps(_mm_shuffle_ps(v.val, v.val, _MM_SHUFFLE(2, 2, 2, 2)), m2.val); + + return v_float32x4(_mm_add_ps(_mm_add_ps(v0, v1), _mm_add_ps(v2, a.val))); +} + +#define OPENCV_HAL_IMPL_SSE_BIN_OP(bin_op, _Tpvec, intrin) \ + inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ + { \ + return _Tpvec(intrin(a.val, b.val)); \ + } \ + inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ + { \ + a.val = intrin(a.val, b.val); \ + return a; \ + } + +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint8x16, _mm_adds_epu8) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint8x16, _mm_subs_epu8) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int8x16, _mm_adds_epi8) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int8x16, _mm_subs_epi8) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint16x8, _mm_adds_epu16) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint16x8, _mm_subs_epu16) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int16x8, _mm_adds_epi16) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int16x8, _mm_subs_epi16) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint32x4, _mm_add_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint32x4, _mm_sub_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_uint32x4, _v128_mullo_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int32x4, _mm_add_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int32x4, _mm_sub_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_int32x4, _v128_mullo_epi32) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float32x4, _mm_add_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float32x4, _mm_sub_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float32x4, _mm_mul_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(/, v_float32x4, _mm_div_ps) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float64x2, _mm_add_pd) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float64x2, _mm_sub_pd) +OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float64x2, _mm_mul_pd) +OPENCV_HAL_IMPL_SSE_BIN_OP(/, v_float64x2, _mm_div_pd) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_uint64x2, _mm_add_epi64) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_uint64x2, _mm_sub_epi64) +OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int64x2, _mm_add_epi64) +OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int64x2, _mm_sub_epi64) + +// saturating multiply 8-bit, 16-bit +#define OPENCV_HAL_IMPL_SSE_MUL_SAT(_Tpvec, _Tpwvec) \ + inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \ + { \ + _Tpwvec c, d; \ + v_mul_expand(a, b, c, d); \ + return v_pack(c, d); \ + } \ + inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \ + { a = a * b; return a; } + +OPENCV_HAL_IMPL_SSE_MUL_SAT(v_uint8x16, v_uint16x8) +OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int8x16, v_int16x8) +OPENCV_HAL_IMPL_SSE_MUL_SAT(v_uint16x8, v_uint32x4) +OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int16x8, v_int32x4) + +// Multiply and expand +inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b, + v_uint16x8& c, v_uint16x8& d) +{ + v_uint16x8 a0, a1, b0, b1; + v_expand(a, a0, a1); + v_expand(b, b0, b1); + c = v_mul_wrap(a0, b0); + d = v_mul_wrap(a1, b1); +} + +inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b, + v_int16x8& c, v_int16x8& d) +{ + v_int16x8 a0, a1, b0, b1; + v_expand(a, a0, a1); + v_expand(b, b0, b1); + c = v_mul_wrap(a0, b0); + d = v_mul_wrap(a1, b1); +} + +inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b, + v_int32x4& c, v_int32x4& d) +{ + __m128i v0 = _mm_mullo_epi16(a.val, b.val); + __m128i v1 = _mm_mulhi_epi16(a.val, b.val); + c.val = _mm_unpacklo_epi16(v0, v1); + d.val = _mm_unpackhi_epi16(v0, v1); +} + +inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b, + v_uint32x4& c, v_uint32x4& d) +{ + __m128i v0 = _mm_mullo_epi16(a.val, b.val); + __m128i v1 = _mm_mulhi_epu16(a.val, b.val); + c.val = _mm_unpacklo_epi16(v0, v1); + d.val = _mm_unpackhi_epi16(v0, v1); +} + +inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, + v_uint64x2& c, v_uint64x2& d) +{ + __m128i c0 = _mm_mul_epu32(a.val, b.val); + __m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a.val, 32), _mm_srli_epi64(b.val, 32)); + c.val = _mm_unpacklo_epi64(c0, c1); + d.val = _mm_unpackhi_epi64(c0, c1); +} + +inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b) { return v_int16x8(_mm_mulhi_epi16(a.val, b.val)); } +inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b) { return v_uint16x8(_mm_mulhi_epu16(a.val, b.val)); } + +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b) +{ + return v_int32x4(_mm_madd_epi16(a.val, b.val)); +} + +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c) +{ + return v_int32x4(_mm_add_epi32(_mm_madd_epi16(a.val, b.val), c.val)); +} + +#define OPENCV_HAL_IMPL_SSE_LOGIC_OP(_Tpvec, suffix, not_const) \ + OPENCV_HAL_IMPL_SSE_BIN_OP(&, _Tpvec, _mm_and_##suffix) \ + OPENCV_HAL_IMPL_SSE_BIN_OP(|, _Tpvec, _mm_or_##suffix) \ + OPENCV_HAL_IMPL_SSE_BIN_OP(^, _Tpvec, _mm_xor_##suffix) \ + inline _Tpvec operator ~ (const _Tpvec& a) \ + { \ + return _Tpvec(_mm_xor_##suffix(a.val, not_const)); \ + } + +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint8x16, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int8x16, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint16x8, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int16x8, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint32x4, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int32x4, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_uint64x2, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_int64x2, si128, _mm_set1_epi32(-1)) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float32x4, ps, _mm_castsi128_ps(_mm_set1_epi32(-1))) +OPENCV_HAL_IMPL_SSE_LOGIC_OP(v_float64x2, pd, _mm_castsi128_pd(_mm_set1_epi32(-1))) + +inline v_float32x4 v_sqrt(const v_float32x4& x) +{ return v_float32x4(_mm_sqrt_ps(x.val)); } + +inline v_float32x4 v_invsqrt(const v_float32x4& x) +{ + const __m128 _0_5 = _mm_set1_ps(0.5f), _1_5 = _mm_set1_ps(1.5f); + __m128 t = x.val; + __m128 h = _mm_mul_ps(t, _0_5); + t = _mm_rsqrt_ps(t); + t = _mm_mul_ps(t, _mm_sub_ps(_1_5, _mm_mul_ps(_mm_mul_ps(t, t), h))); + return v_float32x4(t); +} + +inline v_float64x2 v_sqrt(const v_float64x2& x) +{ return v_float64x2(_mm_sqrt_pd(x.val)); } + +inline v_float64x2 v_invsqrt(const v_float64x2& x) +{ + const __m128d v_1 = _mm_set1_pd(1.); + return v_float64x2(_mm_div_pd(v_1, _mm_sqrt_pd(x.val))); +} + +#define OPENCV_HAL_IMPL_SSE_ABS_INT_FUNC(_Tpuvec, _Tpsvec, func, suffix, subWidth) \ +inline _Tpuvec v_abs(const _Tpsvec& x) \ +{ return _Tpuvec(_mm_##func##_ep##suffix(x.val, _mm_sub_ep##subWidth(_mm_setzero_si128(), x.val))); } + +OPENCV_HAL_IMPL_SSE_ABS_INT_FUNC(v_uint8x16, v_int8x16, min, u8, i8) +OPENCV_HAL_IMPL_SSE_ABS_INT_FUNC(v_uint16x8, v_int16x8, max, i16, i16) +inline v_uint32x4 v_abs(const v_int32x4& x) +{ + __m128i s = _mm_srli_epi32(x.val, 31); + __m128i f = _mm_srai_epi32(x.val, 31); + return v_uint32x4(_mm_add_epi32(_mm_xor_si128(x.val, f), s)); +} +inline v_float32x4 v_abs(const v_float32x4& x) +{ return v_float32x4(_mm_and_ps(x.val, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)))); } +inline v_float64x2 v_abs(const v_float64x2& x) +{ + return v_float64x2(_mm_and_pd(x.val, + _mm_castsi128_pd(_mm_srli_epi64(_mm_set1_epi32(-1), 1)))); +} + +// TODO: exp, log, sin, cos + +#define OPENCV_HAL_IMPL_SSE_BIN_FUNC(_Tpvec, func, intrin) \ +inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(intrin(a.val, b.val)); \ +} + +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_min, _mm_min_epu8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_max, _mm_max_epu8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_min, _mm_min_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_max, _mm_max_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float32x4, v_min, _mm_min_ps) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float32x4, v_max, _mm_max_ps) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float64x2, v_min, _mm_min_pd) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_float64x2, v_max, _mm_max_pd) + +inline v_int8x16 v_min(const v_int8x16& a, const v_int8x16& b) +{ +#if CV_SSE4_1 + return v_int8x16(_mm_min_epi8(a.val, b.val)); +#else + __m128i delta = _mm_set1_epi8((char)-128); + return v_int8x16(_mm_xor_si128(delta, _mm_min_epu8(_mm_xor_si128(a.val, delta), + _mm_xor_si128(b.val, delta)))); +#endif +} +inline v_int8x16 v_max(const v_int8x16& a, const v_int8x16& b) +{ +#if CV_SSE4_1 + return v_int8x16(_mm_max_epi8(a.val, b.val)); +#else + __m128i delta = _mm_set1_epi8((char)-128); + return v_int8x16(_mm_xor_si128(delta, _mm_max_epu8(_mm_xor_si128(a.val, delta), + _mm_xor_si128(b.val, delta)))); +#endif +} +inline v_uint16x8 v_min(const v_uint16x8& a, const v_uint16x8& b) +{ +#if CV_SSE4_1 + return v_uint16x8(_mm_min_epu16(a.val, b.val)); +#else + return v_uint16x8(_mm_subs_epu16(a.val, _mm_subs_epu16(a.val, b.val))); +#endif +} +inline v_uint16x8 v_max(const v_uint16x8& a, const v_uint16x8& b) +{ +#if CV_SSE4_1 + return v_uint16x8(_mm_max_epu16(a.val, b.val)); +#else + return v_uint16x8(_mm_adds_epu16(_mm_subs_epu16(a.val, b.val), b.val)); +#endif +} +inline v_uint32x4 v_min(const v_uint32x4& a, const v_uint32x4& b) +{ +#if CV_SSE4_1 + return v_uint32x4(_mm_min_epu32(a.val, b.val)); +#else + __m128i delta = _mm_set1_epi32((int)0x80000000); + __m128i mask = _mm_cmpgt_epi32(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta)); + return v_uint32x4(v_select_si128(mask, b.val, a.val)); +#endif +} +inline v_uint32x4 v_max(const v_uint32x4& a, const v_uint32x4& b) +{ +#if CV_SSE4_1 + return v_uint32x4(_mm_max_epu32(a.val, b.val)); +#else + __m128i delta = _mm_set1_epi32((int)0x80000000); + __m128i mask = _mm_cmpgt_epi32(_mm_xor_si128(a.val, delta), _mm_xor_si128(b.val, delta)); + return v_uint32x4(v_select_si128(mask, a.val, b.val)); +#endif +} +inline v_int32x4 v_min(const v_int32x4& a, const v_int32x4& b) +{ +#if CV_SSE4_1 + return v_int32x4(_mm_min_epi32(a.val, b.val)); +#else + return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), b.val, a.val)); +#endif +} +inline v_int32x4 v_max(const v_int32x4& a, const v_int32x4& b) +{ +#if CV_SSE4_1 + return v_int32x4(_mm_max_epi32(a.val, b.val)); +#else + return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), a.val, b.val)); +#endif +} + +#define OPENCV_HAL_IMPL_SSE_INT_CMP_OP(_Tpuvec, _Tpsvec, suffix, sbit) \ +inline _Tpuvec operator == (const _Tpuvec& a, const _Tpuvec& b) \ +{ return _Tpuvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ +inline _Tpuvec operator != (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpuvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \ +} \ +inline _Tpsvec operator == (const _Tpsvec& a, const _Tpsvec& b) \ +{ return _Tpsvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ +inline _Tpsvec operator != (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpsvec(_mm_xor_si128(_mm_cmpeq_##suffix(a.val, b.val), not_mask)); \ +} \ +inline _Tpuvec operator < (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask))); \ +} \ +inline _Tpuvec operator > (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + return _Tpuvec(_mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask))); \ +} \ +inline _Tpuvec operator <= (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + __m128i not_mask = _mm_set1_epi32(-1); \ + __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(a.val, smask), _mm_xor_si128(b.val, smask)); \ + return _Tpuvec(_mm_xor_si128(res, not_mask)); \ +} \ +inline _Tpuvec operator >= (const _Tpuvec& a, const _Tpuvec& b) \ +{ \ + __m128i smask = _mm_set1_##suffix(sbit); \ + __m128i not_mask = _mm_set1_epi32(-1); \ + __m128i res = _mm_cmpgt_##suffix(_mm_xor_si128(b.val, smask), _mm_xor_si128(a.val, smask)); \ + return _Tpuvec(_mm_xor_si128(res, not_mask)); \ +} \ +inline _Tpsvec operator < (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + return _Tpsvec(_mm_cmpgt_##suffix(b.val, a.val)); \ +} \ +inline _Tpsvec operator > (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + return _Tpsvec(_mm_cmpgt_##suffix(a.val, b.val)); \ +} \ +inline _Tpsvec operator <= (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(a.val, b.val), not_mask)); \ +} \ +inline _Tpsvec operator >= (const _Tpsvec& a, const _Tpsvec& b) \ +{ \ + __m128i not_mask = _mm_set1_epi32(-1); \ + return _Tpsvec(_mm_xor_si128(_mm_cmpgt_##suffix(b.val, a.val), not_mask)); \ +} + +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint8x16, v_int8x16, epi8, (char)-128) +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint16x8, v_int16x8, epi16, (short)-32768) +OPENCV_HAL_IMPL_SSE_INT_CMP_OP(v_uint32x4, v_int32x4, epi32, (int)0x80000000) + +#define OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(_Tpvec, suffix) \ +inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpeq_##suffix(a.val, b.val)); } \ +inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpneq_##suffix(a.val, b.val)); } \ +inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmplt_##suffix(a.val, b.val)); } \ +inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpgt_##suffix(a.val, b.val)); } \ +inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmple_##suffix(a.val, b.val)); } \ +inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(_mm_cmpge_##suffix(a.val, b.val)); } + +OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(v_float32x4, ps) +OPENCV_HAL_IMPL_SSE_FLT_CMP_OP(v_float64x2, pd) + +#define OPENCV_HAL_IMPL_SSE_64BIT_CMP_OP(_Tpvec, cast) \ +inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ +{ return cast(v_reinterpret_as_f64(a) == v_reinterpret_as_f64(b)); } \ +inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ +{ return cast(v_reinterpret_as_f64(a) != v_reinterpret_as_f64(b)); } + +OPENCV_HAL_IMPL_SSE_64BIT_CMP_OP(v_uint64x2, v_reinterpret_as_u64) +OPENCV_HAL_IMPL_SSE_64BIT_CMP_OP(v_int64x2, v_reinterpret_as_s64) + +inline v_float32x4 v_not_nan(const v_float32x4& a) +{ return v_float32x4(_mm_cmpord_ps(a.val, a.val)); } +inline v_float64x2 v_not_nan(const v_float64x2& a) +{ return v_float64x2(_mm_cmpord_pd(a.val, a.val)); } + +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_add_wrap, _mm_add_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_add_wrap, _mm_add_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_add_wrap, _mm_add_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_add_wrap, _mm_add_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_sub_wrap, _mm_sub_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_sub_wrap, _mm_sub_epi8) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_sub_wrap, _mm_sub_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_sub_wrap, _mm_sub_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_mul_wrap, _mm_mullo_epi16) +OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_mul_wrap, _mm_mullo_epi16) + +inline v_uint8x16 v_mul_wrap(const v_uint8x16& a, const v_uint8x16& b) +{ + __m128i ad = _mm_srai_epi16(a.val, 8); + __m128i bd = _mm_srai_epi16(b.val, 8); + __m128i p0 = _mm_mullo_epi16(a.val, b.val); // even + __m128i p1 = _mm_slli_epi16(_mm_mullo_epi16(ad, bd), 8); // odd + const __m128i b01 = _mm_set1_epi32(0xFF00FF00); + return v_uint8x16(_v128_blendv_epi8(p0, p1, b01)); +} +inline v_int8x16 v_mul_wrap(const v_int8x16& a, const v_int8x16& b) +{ + return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b))); +} + +/** Absolute difference **/ + +inline v_uint8x16 v_absdiff(const v_uint8x16& a, const v_uint8x16& b) +{ return v_add_wrap(a - b, b - a); } +inline v_uint16x8 v_absdiff(const v_uint16x8& a, const v_uint16x8& b) +{ return v_add_wrap(a - b, b - a); } +inline v_uint32x4 v_absdiff(const v_uint32x4& a, const v_uint32x4& b) +{ return v_max(a, b) - v_min(a, b); } + +inline v_uint8x16 v_absdiff(const v_int8x16& a, const v_int8x16& b) +{ + v_int8x16 d = v_sub_wrap(a, b); + v_int8x16 m = a < b; + return v_reinterpret_as_u8(v_sub_wrap(d ^ m, m)); +} +inline v_uint16x8 v_absdiff(const v_int16x8& a, const v_int16x8& b) +{ + return v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b))); +} +inline v_uint32x4 v_absdiff(const v_int32x4& a, const v_int32x4& b) +{ + v_int32x4 d = a - b; + v_int32x4 m = a < b; + return v_reinterpret_as_u32((d ^ m) - m); +} + +/** Saturating absolute difference **/ +inline v_int8x16 v_absdiffs(const v_int8x16& a, const v_int8x16& b) +{ + v_int8x16 d = a - b; + v_int8x16 m = a < b; + return (d ^ m) - m; + } +inline v_int16x8 v_absdiffs(const v_int16x8& a, const v_int16x8& b) +{ return v_max(a, b) - v_min(a, b); } + + +inline v_int32x4 v_fma(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c) +{ + return a * b + c; +} + +inline v_int32x4 v_muladd(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c) +{ + return v_fma(a, b, c); +} + +inline v_float32x4 v_fma(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c) +{ +#if CV_FMA3 + return v_float32x4(_mm_fmadd_ps(a.val, b.val, c.val)); +#else + return v_float32x4(_mm_add_ps(_mm_mul_ps(a.val, b.val), c.val)); +#endif +} + +inline v_float64x2 v_fma(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c) +{ +#if CV_FMA3 + return v_float64x2(_mm_fmadd_pd(a.val, b.val, c.val)); +#else + return v_float64x2(_mm_add_pd(_mm_mul_pd(a.val, b.val), c.val)); +#endif +} + +#define OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(_Tpvec, _Tp, _Tpreg, suffix, absmask_vec) \ +inline _Tpvec v_absdiff(const _Tpvec& a, const _Tpvec& b) \ +{ \ + _Tpreg absmask = _mm_castsi128_##suffix(absmask_vec); \ + return _Tpvec(_mm_and_##suffix(_mm_sub_##suffix(a.val, b.val), absmask)); \ +} \ +inline _Tpvec v_magnitude(const _Tpvec& a, const _Tpvec& b) \ +{ \ + _Tpvec res = v_fma(a, a, b*b); \ + return _Tpvec(_mm_sqrt_##suffix(res.val)); \ +} \ +inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ +{ \ + return v_fma(a, a, b*b); \ +} \ +inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ +{ \ + return v_fma(a, b, c); \ +} + +OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(v_float32x4, float, __m128, ps, _mm_set1_epi32((int)0x7fffffff)) +OPENCV_HAL_IMPL_SSE_MISC_FLT_OP(v_float64x2, double, __m128d, pd, _mm_srli_epi64(_mm_set1_epi32(-1), 1)) + +#define OPENCV_HAL_IMPL_SSE_SHIFT_OP(_Tpuvec, _Tpsvec, suffix, srai) \ +inline _Tpuvec operator << (const _Tpuvec& a, int imm) \ +{ \ + return _Tpuvec(_mm_slli_##suffix(a.val, imm)); \ +} \ +inline _Tpsvec operator << (const _Tpsvec& a, int imm) \ +{ \ + return _Tpsvec(_mm_slli_##suffix(a.val, imm)); \ +} \ +inline _Tpuvec operator >> (const _Tpuvec& a, int imm) \ +{ \ + return _Tpuvec(_mm_srli_##suffix(a.val, imm)); \ +} \ +inline _Tpsvec operator >> (const _Tpsvec& a, int imm) \ +{ \ + return _Tpsvec(srai(a.val, imm)); \ +} \ +template \ +inline _Tpuvec v_shl(const _Tpuvec& a) \ +{ \ + return _Tpuvec(_mm_slli_##suffix(a.val, imm)); \ +} \ +template \ +inline _Tpsvec v_shl(const _Tpsvec& a) \ +{ \ + return _Tpsvec(_mm_slli_##suffix(a.val, imm)); \ +} \ +template \ +inline _Tpuvec v_shr(const _Tpuvec& a) \ +{ \ + return _Tpuvec(_mm_srli_##suffix(a.val, imm)); \ +} \ +template \ +inline _Tpsvec v_shr(const _Tpsvec& a) \ +{ \ + return _Tpsvec(srai(a.val, imm)); \ +} + +OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint16x8, v_int16x8, epi16, _mm_srai_epi16) +OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint32x4, v_int32x4, epi32, _mm_srai_epi32) +OPENCV_HAL_IMPL_SSE_SHIFT_OP(v_uint64x2, v_int64x2, epi64, v_srai_epi64) + +namespace hal_sse_internal +{ + template 16)), + bool is_first = (imm == 0), + bool is_half = (imm == 8), + bool is_second = (imm == 16), + bool is_other = (((imm > 0) && (imm < 8)) || ((imm > 8) && (imm < 16)))> + class v_sse_palignr_u8_class; + + template + class v_sse_palignr_u8_class; + + template + class v_sse_palignr_u8_class + { + public: + inline __m128i operator()(const __m128i& a, const __m128i&) const + { + return a; + } + }; + + template + class v_sse_palignr_u8_class + { + public: + inline __m128i operator()(const __m128i& a, const __m128i& b) const + { + return _mm_unpacklo_epi64(_mm_unpackhi_epi64(a, a), b); + } + }; + + template + class v_sse_palignr_u8_class + { + public: + inline __m128i operator()(const __m128i&, const __m128i& b) const + { + return b; + } + }; + + template + class v_sse_palignr_u8_class + { +#if CV_SSSE3 + public: + inline __m128i operator()(const __m128i& a, const __m128i& b) const + { + return _mm_alignr_epi8(b, a, imm); + } +#else + public: + inline __m128i operator()(const __m128i& a, const __m128i& b) const + { + enum { imm2 = (sizeof(__m128i) - imm) }; + return _mm_or_si128(_mm_srli_si128(a, imm), _mm_slli_si128(b, imm2)); + } +#endif + }; + + template + inline __m128i v_sse_palignr_u8(const __m128i& a, const __m128i& b) + { + CV_StaticAssert((imm >= 0) && (imm <= 16), "Invalid imm for v_sse_palignr_u8."); + return v_sse_palignr_u8_class()(a, b); + } +} + +template +inline _Tpvec v_rotate_right(const _Tpvec &a) +{ + using namespace hal_sse_internal; + enum { imm2 = (imm * sizeof(typename _Tpvec::lane_type)) }; + return _Tpvec(v_sse_reinterpret_as( + _mm_srli_si128( + v_sse_reinterpret_as<__m128i>(a.val), imm2))); +} + +template +inline _Tpvec v_rotate_left(const _Tpvec &a) +{ + using namespace hal_sse_internal; + enum { imm2 = (imm * sizeof(typename _Tpvec::lane_type)) }; + return _Tpvec(v_sse_reinterpret_as( + _mm_slli_si128( + v_sse_reinterpret_as<__m128i>(a.val), imm2))); +} + +template +inline _Tpvec v_rotate_right(const _Tpvec &a, const _Tpvec &b) +{ + using namespace hal_sse_internal; + enum { imm2 = (imm * sizeof(typename _Tpvec::lane_type)) }; + return _Tpvec(v_sse_reinterpret_as( + v_sse_palignr_u8( + v_sse_reinterpret_as<__m128i>(a.val), + v_sse_reinterpret_as<__m128i>(b.val)))); +} + +template +inline _Tpvec v_rotate_left(const _Tpvec &a, const _Tpvec &b) +{ + using namespace hal_sse_internal; + enum { imm2 = ((_Tpvec::nlanes - imm) * sizeof(typename _Tpvec::lane_type)) }; + return _Tpvec(v_sse_reinterpret_as( + v_sse_palignr_u8( + v_sse_reinterpret_as<__m128i>(b.val), + v_sse_reinterpret_as<__m128i>(a.val)))); +} + +#define OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(_Tpvec, _Tp) \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec(_mm_loadu_si128((const __m128i*)ptr)); } \ +inline _Tpvec v_load_aligned(const _Tp* ptr) \ +{ return _Tpvec(_mm_load_si128((const __m128i*)ptr)); } \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ return _Tpvec(_mm_loadl_epi64((const __m128i*)ptr)); } \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ \ + return _Tpvec(_mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*)ptr0), \ + _mm_loadl_epi64((const __m128i*)ptr1))); \ +} \ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storeu_si128((__m128i*)ptr, a.val); } \ +inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ +{ _mm_store_si128((__m128i*)ptr, a.val); } \ +inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ +{ _mm_stream_si128((__m128i*)ptr, a.val); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode mode) \ +{ \ + if( mode == hal::STORE_UNALIGNED ) \ + _mm_storeu_si128((__m128i*)ptr, a.val); \ + else if( mode == hal::STORE_ALIGNED_NOCACHE ) \ + _mm_stream_si128((__m128i*)ptr, a.val); \ + else \ + _mm_store_si128((__m128i*)ptr, a.val); \ +} \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storel_epi64((__m128i*)ptr, a.val); } \ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storel_epi64((__m128i*)ptr, _mm_unpackhi_epi64(a.val, a.val)); } + +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint8x16, uchar) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int8x16, schar) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint16x8, ushort) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int16x8, short) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint32x4, unsigned) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int32x4, int) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_uint64x2, uint64) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INT_OP(v_int64x2, int64) + +#define OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(_Tpvec, _Tp, suffix) \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec(_mm_loadu_##suffix(ptr)); } \ +inline _Tpvec v_load_aligned(const _Tp* ptr) \ +{ return _Tpvec(_mm_load_##suffix(ptr)); } \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ return _Tpvec(_mm_castsi128_##suffix(_mm_loadl_epi64((const __m128i*)ptr))); } \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ \ + return _Tpvec(_mm_castsi128_##suffix( \ + _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i*)ptr0), \ + _mm_loadl_epi64((const __m128i*)ptr1)))); \ +} \ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storeu_##suffix(ptr, a.val); } \ +inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ +{ _mm_store_##suffix(ptr, a.val); } \ +inline void v_store_aligned_nocache(_Tp* ptr, const _Tpvec& a) \ +{ _mm_stream_##suffix(ptr, a.val); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode mode) \ +{ \ + if( mode == hal::STORE_UNALIGNED ) \ + _mm_storeu_##suffix(ptr, a.val); \ + else if( mode == hal::STORE_ALIGNED_NOCACHE ) \ + _mm_stream_##suffix(ptr, a.val); \ + else \ + _mm_store_##suffix(ptr, a.val); \ +} \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ _mm_storel_epi64((__m128i*)ptr, _mm_cast##suffix##_si128(a.val)); } \ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ \ + __m128i a1 = _mm_cast##suffix##_si128(a.val); \ + _mm_storel_epi64((__m128i*)ptr, _mm_unpackhi_epi64(a1, a1)); \ +} + +OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(v_float32x4, float, ps) +OPENCV_HAL_IMPL_SSE_LOADSTORE_FLT_OP(v_float64x2, double, pd) + +inline unsigned v_reduce_sum(const v_uint8x16& a) +{ + __m128i half = _mm_sad_epu8(a.val, _mm_setzero_si128()); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(half, _mm_unpackhi_epi64(half, half))); +} +inline int v_reduce_sum(const v_int8x16& a) +{ + __m128i half = _mm_set1_epi8((schar)-128); + half = _mm_sad_epu8(_mm_xor_si128(a.val, half), _mm_setzero_si128()); + return _mm_cvtsi128_si32(_mm_add_epi32(half, _mm_unpackhi_epi64(half, half))) - 2048; +} +#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_16(func) \ +inline schar v_reduce_##func(const v_int8x16& a) \ +{ \ + __m128i val = a.val; \ + __m128i smask = _mm_set1_epi8((schar)-128); \ + val = _mm_xor_si128(val, smask); \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,8)); \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,4)); \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,2)); \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,1)); \ + return (schar)_mm_cvtsi128_si32(val) ^ (schar)-128; \ +} \ +inline uchar v_reduce_##func(const v_uint8x16& a) \ +{ \ + __m128i val = a.val; \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,8)); \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,4)); \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,2)); \ + val = _mm_##func##_epu8(val, _mm_srli_si128(val,1)); \ + return (uchar)_mm_cvtsi128_si32(val); \ +} +OPENCV_HAL_IMPL_SSE_REDUCE_OP_16(max) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_16(min) + +#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_8(_Tpvec, scalartype, func, suffix, sbit) \ +inline scalartype v_reduce_##func(const v_##_Tpvec& a) \ +{ \ + __m128i val = a.val; \ + val = _mm_##func##_##suffix(val, _mm_srli_si128(val,8)); \ + val = _mm_##func##_##suffix(val, _mm_srli_si128(val,4)); \ + val = _mm_##func##_##suffix(val, _mm_srli_si128(val,2)); \ + return (scalartype)_mm_cvtsi128_si32(val); \ +} \ +inline unsigned scalartype v_reduce_##func(const v_u##_Tpvec& a) \ +{ \ + __m128i val = a.val; \ + __m128i smask = _mm_set1_epi16(sbit); \ + val = _mm_xor_si128(val, smask); \ + val = _mm_##func##_##suffix(val, _mm_srli_si128(val,8)); \ + val = _mm_##func##_##suffix(val, _mm_srli_si128(val,4)); \ + val = _mm_##func##_##suffix(val, _mm_srli_si128(val,2)); \ + return (unsigned scalartype)(_mm_cvtsi128_si32(val) ^ sbit); \ +} +OPENCV_HAL_IMPL_SSE_REDUCE_OP_8(int16x8, short, max, epi16, (short)-32768) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_8(int16x8, short, min, epi16, (short)-32768) + +#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_4_SUM(_Tpvec, scalartype, regtype, suffix, cast_from, cast_to, extract) \ +inline scalartype v_reduce_sum(const _Tpvec& a) \ +{ \ + regtype val = a.val; \ + val = _mm_add_##suffix(val, cast_to(_mm_srli_si128(cast_from(val), 8))); \ + val = _mm_add_##suffix(val, cast_to(_mm_srli_si128(cast_from(val), 4))); \ + return (scalartype)_mm_cvt##extract(val); \ +} + +#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(_Tpvec, scalartype, func, scalar_func) \ +inline scalartype v_reduce_##func(const _Tpvec& a) \ +{ \ + scalartype CV_DECL_ALIGNED(16) buf[4]; \ + v_store_aligned(buf, a); \ + scalartype s0 = scalar_func(buf[0], buf[1]); \ + scalartype s1 = scalar_func(buf[2], buf[3]); \ + return scalar_func(s0, s1); \ +} + +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4_SUM(v_uint32x4, unsigned, __m128i, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP, si128_si32) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4_SUM(v_int32x4, int, __m128i, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP, si128_si32) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4_SUM(v_float32x4, float, __m128, ps, _mm_castps_si128, _mm_castsi128_ps, ss_f32) + +inline int v_reduce_sum(const v_int16x8& a) +{ return v_reduce_sum(v_expand_low(a) + v_expand_high(a)); } +inline unsigned v_reduce_sum(const v_uint16x8& a) +{ return v_reduce_sum(v_expand_low(a) + v_expand_high(a)); } + +inline uint64 v_reduce_sum(const v_uint64x2& a) +{ + uint64 CV_DECL_ALIGNED(32) idx[2]; + v_store_aligned(idx, a); + return idx[0] + idx[1]; +} +inline int64 v_reduce_sum(const v_int64x2& a) +{ + int64 CV_DECL_ALIGNED(32) idx[2]; + v_store_aligned(idx, a); + return idx[0] + idx[1]; +} +inline double v_reduce_sum(const v_float64x2& a) +{ + double CV_DECL_ALIGNED(32) idx[2]; + v_store_aligned(idx, a); + return idx[0] + idx[1]; +} + +inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b, + const v_float32x4& c, const v_float32x4& d) +{ +#if CV_SSE3 + __m128 ab = _mm_hadd_ps(a.val, b.val); + __m128 cd = _mm_hadd_ps(c.val, d.val); + return v_float32x4(_mm_hadd_ps(ab, cd)); +#else + __m128 ac = _mm_add_ps(_mm_unpacklo_ps(a.val, c.val), _mm_unpackhi_ps(a.val, c.val)); + __m128 bd = _mm_add_ps(_mm_unpacklo_ps(b.val, d.val), _mm_unpackhi_ps(b.val, d.val)); + return v_float32x4(_mm_add_ps(_mm_unpacklo_ps(ac, bd), _mm_unpackhi_ps(ac, bd))); +#endif +} + +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, max, std::max) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_uint32x4, unsigned, min, std::min) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, max, std::max) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_int32x4, int, min, std::min) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, max, std::max) +OPENCV_HAL_IMPL_SSE_REDUCE_OP_4(v_float32x4, float, min, std::min) + +inline unsigned v_reduce_sad(const v_uint8x16& a, const v_uint8x16& b) +{ + __m128i half = _mm_sad_epu8(a.val, b.val); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(half, _mm_unpackhi_epi64(half, half))); +} +inline unsigned v_reduce_sad(const v_int8x16& a, const v_int8x16& b) +{ + __m128i half = _mm_set1_epi8(0x7f); + half = _mm_sad_epu8(_mm_add_epi8(a.val, half), _mm_add_epi8(b.val, half)); + return (unsigned)_mm_cvtsi128_si32(_mm_add_epi32(half, _mm_unpackhi_epi64(half, half))); +} +inline unsigned v_reduce_sad(const v_uint16x8& a, const v_uint16x8& b) +{ + v_uint32x4 l, h; + v_expand(v_absdiff(a, b), l, h); + return v_reduce_sum(l + h); +} +inline unsigned v_reduce_sad(const v_int16x8& a, const v_int16x8& b) +{ + v_uint32x4 l, h; + v_expand(v_absdiff(a, b), l, h); + return v_reduce_sum(l + h); +} +inline unsigned v_reduce_sad(const v_uint32x4& a, const v_uint32x4& b) +{ + return v_reduce_sum(v_absdiff(a, b)); +} +inline unsigned v_reduce_sad(const v_int32x4& a, const v_int32x4& b) +{ + return v_reduce_sum(v_absdiff(a, b)); +} +inline float v_reduce_sad(const v_float32x4& a, const v_float32x4& b) +{ + return v_reduce_sum(v_absdiff(a, b)); +} + +inline v_uint8x16 v_popcount(const v_uint8x16& a) +{ + __m128i m1 = _mm_set1_epi32(0x55555555); + __m128i m2 = _mm_set1_epi32(0x33333333); + __m128i m4 = _mm_set1_epi32(0x0f0f0f0f); + __m128i p = a.val; + p = _mm_add_epi32(_mm_and_si128(_mm_srli_epi32(p, 1), m1), _mm_and_si128(p, m1)); + p = _mm_add_epi32(_mm_and_si128(_mm_srli_epi32(p, 2), m2), _mm_and_si128(p, m2)); + p = _mm_add_epi32(_mm_and_si128(_mm_srli_epi32(p, 4), m4), _mm_and_si128(p, m4)); + return v_uint8x16(p); +} +inline v_uint16x8 v_popcount(const v_uint16x8& a) +{ + v_uint8x16 p = v_popcount(v_reinterpret_as_u8(a)); + p += v_rotate_right<1>(p); + return v_reinterpret_as_u16(p) & v_setall_u16(0x00ff); +} +inline v_uint32x4 v_popcount(const v_uint32x4& a) +{ + v_uint8x16 p = v_popcount(v_reinterpret_as_u8(a)); + p += v_rotate_right<1>(p); + p += v_rotate_right<2>(p); + return v_reinterpret_as_u32(p) & v_setall_u32(0x000000ff); +} +inline v_uint64x2 v_popcount(const v_uint64x2& a) +{ + return v_uint64x2(_mm_sad_epu8(v_popcount(v_reinterpret_as_u8(a)).val, _mm_setzero_si128())); +} +inline v_uint8x16 v_popcount(const v_int8x16& a) +{ return v_popcount(v_reinterpret_as_u8(a)); } +inline v_uint16x8 v_popcount(const v_int16x8& a) +{ return v_popcount(v_reinterpret_as_u16(a)); } +inline v_uint32x4 v_popcount(const v_int32x4& a) +{ return v_popcount(v_reinterpret_as_u32(a)); } +inline v_uint64x2 v_popcount(const v_int64x2& a) +{ return v_popcount(v_reinterpret_as_u64(a)); } + +#define OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(_Tpvec, suffix, pack_op, and_op, signmask, allmask) \ +inline int v_signmask(const _Tpvec& a) \ +{ \ + return and_op(_mm_movemask_##suffix(pack_op(a.val)), signmask); \ +} \ +inline bool v_check_all(const _Tpvec& a) \ +{ return and_op(_mm_movemask_##suffix(a.val), allmask) == allmask; } \ +inline bool v_check_any(const _Tpvec& a) \ +{ return and_op(_mm_movemask_##suffix(a.val), allmask) != 0; } + +#define OPENCV_HAL_PACKS(a) _mm_packs_epi16(a, a) +inline __m128i v_packq_epi32(__m128i a) +{ + __m128i b = _mm_packs_epi32(a, a); + return _mm_packs_epi16(b, b); +} + +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 65535, 65535) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 65535, 65535) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint16x8, epi8, OPENCV_HAL_PACKS, OPENCV_HAL_AND, 255, (int)0xaaaa) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int16x8, epi8, OPENCV_HAL_PACKS, OPENCV_HAL_AND, 255, (int)0xaaaa) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_uint32x4, epi8, v_packq_epi32, OPENCV_HAL_AND, 15, (int)0x8888) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_int32x4, epi8, v_packq_epi32, OPENCV_HAL_AND, 15, (int)0x8888) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float32x4, ps, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 15, 15) +OPENCV_HAL_IMPL_SSE_CHECK_SIGNS(v_float64x2, pd, OPENCV_HAL_NOP, OPENCV_HAL_1ST, 3, 3) + +inline int v_scan_forward(const v_int8x16& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))); } +inline int v_scan_forward(const v_uint8x16& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))); } +inline int v_scan_forward(const v_int16x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 2; } +inline int v_scan_forward(const v_uint16x8& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 2; } +inline int v_scan_forward(const v_int32x4& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 4; } +inline int v_scan_forward(const v_uint32x4& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 4; } +inline int v_scan_forward(const v_float32x4& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 4; } +inline int v_scan_forward(const v_int64x2& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 8; } +inline int v_scan_forward(const v_uint64x2& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 8; } +inline int v_scan_forward(const v_float64x2& a) { return trailingZeros32(v_signmask(v_reinterpret_as_s8(a))) / 8; } + +#if CV_SSE4_1 +#define OPENCV_HAL_IMPL_SSE_SELECT(_Tpvec, cast_ret, cast, suffix) \ +inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(cast_ret(_mm_blendv_##suffix(cast(b.val), cast(a.val), cast(mask.val)))); \ +} + +OPENCV_HAL_IMPL_SSE_SELECT(v_uint8x16, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8) +OPENCV_HAL_IMPL_SSE_SELECT(v_int8x16, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8) +OPENCV_HAL_IMPL_SSE_SELECT(v_uint16x8, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8) +OPENCV_HAL_IMPL_SSE_SELECT(v_int16x8, OPENCV_HAL_NOP, OPENCV_HAL_NOP, epi8) +OPENCV_HAL_IMPL_SSE_SELECT(v_uint32x4, _mm_castps_si128, _mm_castsi128_ps, ps) +OPENCV_HAL_IMPL_SSE_SELECT(v_int32x4, _mm_castps_si128, _mm_castsi128_ps, ps) +// OPENCV_HAL_IMPL_SSE_SELECT(v_uint64x2, TBD, TBD, pd) +// OPENCV_HAL_IMPL_SSE_SELECT(v_int64x2, TBD, TBD, ps) +OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, OPENCV_HAL_NOP, OPENCV_HAL_NOP, ps) +OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, OPENCV_HAL_NOP, OPENCV_HAL_NOP, pd) + +#else // CV_SSE4_1 + +#define OPENCV_HAL_IMPL_SSE_SELECT(_Tpvec, suffix) \ +inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ +{ \ + return _Tpvec(_mm_xor_##suffix(b.val, _mm_and_##suffix(_mm_xor_##suffix(b.val, a.val), mask.val))); \ +} + +OPENCV_HAL_IMPL_SSE_SELECT(v_uint8x16, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_int8x16, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_uint16x8, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_int16x8, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_uint32x4, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_int32x4, si128) +// OPENCV_HAL_IMPL_SSE_SELECT(v_uint64x2, si128) +// OPENCV_HAL_IMPL_SSE_SELECT(v_int64x2, si128) +OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, ps) +OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, pd) +#endif + +/* Expand */ +#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpvec, _Tpwvec, _Tp, intrin) \ + inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \ + { \ + b0.val = intrin(a.val); \ + b1.val = __CV_CAT(intrin, _high)(a.val); \ + } \ + inline _Tpwvec v_expand_low(const _Tpvec& a) \ + { return _Tpwvec(intrin(a.val)); } \ + inline _Tpwvec v_expand_high(const _Tpvec& a) \ + { return _Tpwvec(__CV_CAT(intrin, _high)(a.val)); } \ + inline _Tpwvec v_load_expand(const _Tp* ptr) \ + { \ + __m128i a = _mm_loadl_epi64((const __m128i*)ptr); \ + return _Tpwvec(intrin(a)); \ + } + +OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, _v128_cvtepu8_epi16) +OPENCV_HAL_IMPL_SSE_EXPAND(v_int8x16, v_int16x8, schar, _v128_cvtepi8_epi16) +OPENCV_HAL_IMPL_SSE_EXPAND(v_uint16x8, v_uint32x4, ushort, _v128_cvtepu16_epi32) +OPENCV_HAL_IMPL_SSE_EXPAND(v_int16x8, v_int32x4, short, _v128_cvtepi16_epi32) +OPENCV_HAL_IMPL_SSE_EXPAND(v_uint32x4, v_uint64x2, unsigned, _v128_cvtepu32_epi64) +OPENCV_HAL_IMPL_SSE_EXPAND(v_int32x4, v_int64x2, int, _v128_cvtepi32_epi64) + +#define OPENCV_HAL_IMPL_SSE_EXPAND_Q(_Tpvec, _Tp, intrin) \ + inline _Tpvec v_load_expand_q(const _Tp* ptr) \ + { \ + __m128i a = _mm_cvtsi32_si128(*(const int*)ptr); \ + return _Tpvec(intrin(a)); \ + } + +OPENCV_HAL_IMPL_SSE_EXPAND_Q(v_uint32x4, uchar, _v128_cvtepu8_epi32) +OPENCV_HAL_IMPL_SSE_EXPAND_Q(v_int32x4, schar, _v128_cvtepi8_epi32) + +#define OPENCV_HAL_IMPL_SSE_UNPACKS(_Tpvec, suffix, cast_from, cast_to) \ +inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, _Tpvec& b0, _Tpvec& b1) \ +{ \ + b0.val = _mm_unpacklo_##suffix(a0.val, a1.val); \ + b1.val = _mm_unpackhi_##suffix(a0.val, a1.val); \ +} \ +inline _Tpvec v_combine_low(const _Tpvec& a, const _Tpvec& b) \ +{ \ + __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \ + return _Tpvec(cast_to(_mm_unpacklo_epi64(a1, b1))); \ +} \ +inline _Tpvec v_combine_high(const _Tpvec& a, const _Tpvec& b) \ +{ \ + __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \ + return _Tpvec(cast_to(_mm_unpackhi_epi64(a1, b1))); \ +} \ +inline void v_recombine(const _Tpvec& a, const _Tpvec& b, _Tpvec& c, _Tpvec& d) \ +{ \ + __m128i a1 = cast_from(a.val), b1 = cast_from(b.val); \ + c.val = cast_to(_mm_unpacklo_epi64(a1, b1)); \ + d.val = cast_to(_mm_unpackhi_epi64(a1, b1)); \ +} + +OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_int8x16, epi8, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint16x8, epi16, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_int16x8, epi16, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_uint32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_int32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_float32x4, ps, _mm_castps_si128, _mm_castsi128_ps) +OPENCV_HAL_IMPL_SSE_UNPACKS(v_float64x2, pd, _mm_castpd_si128, _mm_castsi128_pd) + +template +inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) +{ + return v_rotate_right(a, b); +} + +inline v_int32x4 v_round(const v_float32x4& a) +{ return v_int32x4(_mm_cvtps_epi32(a.val)); } + +inline v_int32x4 v_floor(const v_float32x4& a) +{ + __m128i a1 = _mm_cvtps_epi32(a.val); + __m128i mask = _mm_castps_si128(_mm_cmpgt_ps(_mm_cvtepi32_ps(a1), a.val)); + return v_int32x4(_mm_add_epi32(a1, mask)); +} + +inline v_int32x4 v_ceil(const v_float32x4& a) +{ + __m128i a1 = _mm_cvtps_epi32(a.val); + __m128i mask = _mm_castps_si128(_mm_cmpgt_ps(a.val, _mm_cvtepi32_ps(a1))); + return v_int32x4(_mm_sub_epi32(a1, mask)); +} + +inline v_int32x4 v_trunc(const v_float32x4& a) +{ return v_int32x4(_mm_cvttps_epi32(a.val)); } + +inline v_int32x4 v_round(const v_float64x2& a) +{ return v_int32x4(_mm_cvtpd_epi32(a.val)); } + +inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b) +{ + __m128i ai = _mm_cvtpd_epi32(a.val), bi = _mm_cvtpd_epi32(b.val); + return v_int32x4(_mm_unpacklo_epi64(ai, bi)); +} + +inline v_int32x4 v_floor(const v_float64x2& a) +{ + __m128i a1 = _mm_cvtpd_epi32(a.val); + __m128i mask = _mm_castpd_si128(_mm_cmpgt_pd(_mm_cvtepi32_pd(a1), a.val)); + mask = _mm_srli_si128(_mm_slli_si128(mask, 4), 8); // m0 m0 m1 m1 => m0 m1 0 0 + return v_int32x4(_mm_add_epi32(a1, mask)); +} + +inline v_int32x4 v_ceil(const v_float64x2& a) +{ + __m128i a1 = _mm_cvtpd_epi32(a.val); + __m128i mask = _mm_castpd_si128(_mm_cmpgt_pd(a.val, _mm_cvtepi32_pd(a1))); + mask = _mm_srli_si128(_mm_slli_si128(mask, 4), 8); // m0 m0 m1 m1 => m0 m1 0 0 + return v_int32x4(_mm_sub_epi32(a1, mask)); +} + +inline v_int32x4 v_trunc(const v_float64x2& a) +{ return v_int32x4(_mm_cvttpd_epi32(a.val)); } + +#define OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(_Tpvec, suffix, cast_from, cast_to) \ +inline void v_transpose4x4(const _Tpvec& a0, const _Tpvec& a1, \ + const _Tpvec& a2, const _Tpvec& a3, \ + _Tpvec& b0, _Tpvec& b1, \ + _Tpvec& b2, _Tpvec& b3) \ +{ \ + __m128i t0 = cast_from(_mm_unpacklo_##suffix(a0.val, a1.val)); \ + __m128i t1 = cast_from(_mm_unpacklo_##suffix(a2.val, a3.val)); \ + __m128i t2 = cast_from(_mm_unpackhi_##suffix(a0.val, a1.val)); \ + __m128i t3 = cast_from(_mm_unpackhi_##suffix(a2.val, a3.val)); \ +\ + b0.val = cast_to(_mm_unpacklo_epi64(t0, t1)); \ + b1.val = cast_to(_mm_unpackhi_epi64(t0, t1)); \ + b2.val = cast_to(_mm_unpacklo_epi64(t2, t3)); \ + b3.val = cast_to(_mm_unpackhi_epi64(t2, t3)); \ +} + +OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_uint32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_int32x4, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP) +OPENCV_HAL_IMPL_SSE_TRANSPOSE4x4(v_float32x4, ps, _mm_castps_si128, _mm_castsi128_ps) + +// load deinterleave +inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b) +{ + __m128i t00 = _mm_loadu_si128((const __m128i*)ptr); + __m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 16)); + + __m128i t10 = _mm_unpacklo_epi8(t00, t01); + __m128i t11 = _mm_unpackhi_epi8(t00, t01); + + __m128i t20 = _mm_unpacklo_epi8(t10, t11); + __m128i t21 = _mm_unpackhi_epi8(t10, t11); + + __m128i t30 = _mm_unpacklo_epi8(t20, t21); + __m128i t31 = _mm_unpackhi_epi8(t20, t21); + + a.val = _mm_unpacklo_epi8(t30, t31); + b.val = _mm_unpackhi_epi8(t30, t31); +} + +inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, v_uint8x16& c) +{ +#if CV_SSE4_1 + const __m128i m0 = _mm_setr_epi8(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0); + const __m128i m1 = _mm_setr_epi8(0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0); + __m128i s0 = _mm_loadu_si128((const __m128i*)ptr); + __m128i s1 = _mm_loadu_si128((const __m128i*)(ptr + 16)); + __m128i s2 = _mm_loadu_si128((const __m128i*)(ptr + 32)); + __m128i a0 = _mm_blendv_epi8(_mm_blendv_epi8(s0, s1, m0), s2, m1); + __m128i b0 = _mm_blendv_epi8(_mm_blendv_epi8(s1, s2, m0), s0, m1); + __m128i c0 = _mm_blendv_epi8(_mm_blendv_epi8(s2, s0, m0), s1, m1); + const __m128i sh_b = _mm_setr_epi8(0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14, 1, 4, 7, 10, 13); + const __m128i sh_g = _mm_setr_epi8(1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, 5, 8, 11, 14); + const __m128i sh_r = _mm_setr_epi8(2, 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15); + a0 = _mm_shuffle_epi8(a0, sh_b); + b0 = _mm_shuffle_epi8(b0, sh_g); + c0 = _mm_shuffle_epi8(c0, sh_r); + a.val = a0; + b.val = b0; + c.val = c0; +#elif CV_SSSE3 + const __m128i m0 = _mm_setr_epi8(0, 3, 6, 9, 12, 15, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14); + const __m128i m1 = _mm_alignr_epi8(m0, m0, 11); + const __m128i m2 = _mm_alignr_epi8(m0, m0, 6); + + __m128i t0 = _mm_loadu_si128((const __m128i*)ptr); + __m128i t1 = _mm_loadu_si128((const __m128i*)(ptr + 16)); + __m128i t2 = _mm_loadu_si128((const __m128i*)(ptr + 32)); + + __m128i s0 = _mm_shuffle_epi8(t0, m0); + __m128i s1 = _mm_shuffle_epi8(t1, m1); + __m128i s2 = _mm_shuffle_epi8(t2, m2); + + t0 = _mm_alignr_epi8(s1, _mm_slli_si128(s0, 10), 5); + a.val = _mm_alignr_epi8(s2, t0, 5); + + t1 = _mm_alignr_epi8(_mm_srli_si128(s1, 5), _mm_slli_si128(s0, 5), 6); + b.val = _mm_alignr_epi8(_mm_srli_si128(s2, 5), t1, 5); + + t2 = _mm_alignr_epi8(_mm_srli_si128(s2, 10), s1, 11); + c.val = _mm_alignr_epi8(t2, s0, 11); +#else + __m128i t00 = _mm_loadu_si128((const __m128i*)ptr); + __m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 16)); + __m128i t02 = _mm_loadu_si128((const __m128i*)(ptr + 32)); + + __m128i t10 = _mm_unpacklo_epi8(t00, _mm_unpackhi_epi64(t01, t01)); + __m128i t11 = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t00, t00), t02); + __m128i t12 = _mm_unpacklo_epi8(t01, _mm_unpackhi_epi64(t02, t02)); + + __m128i t20 = _mm_unpacklo_epi8(t10, _mm_unpackhi_epi64(t11, t11)); + __m128i t21 = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t10, t10), t12); + __m128i t22 = _mm_unpacklo_epi8(t11, _mm_unpackhi_epi64(t12, t12)); + + __m128i t30 = _mm_unpacklo_epi8(t20, _mm_unpackhi_epi64(t21, t21)); + __m128i t31 = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t20, t20), t22); + __m128i t32 = _mm_unpacklo_epi8(t21, _mm_unpackhi_epi64(t22, t22)); + + a.val = _mm_unpacklo_epi8(t30, _mm_unpackhi_epi64(t31, t31)); + b.val = _mm_unpacklo_epi8(_mm_unpackhi_epi64(t30, t30), t32); + c.val = _mm_unpacklo_epi8(t31, _mm_unpackhi_epi64(t32, t32)); +#endif +} + +inline void v_load_deinterleave(const uchar* ptr, v_uint8x16& a, v_uint8x16& b, v_uint8x16& c, v_uint8x16& d) +{ + __m128i u0 = _mm_loadu_si128((const __m128i*)ptr); // a0 b0 c0 d0 a1 b1 c1 d1 ... + __m128i u1 = _mm_loadu_si128((const __m128i*)(ptr + 16)); // a4 b4 c4 d4 ... + __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 32)); // a8 b8 c8 d8 ... + __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 48)); // a12 b12 c12 d12 ... + + __m128i v0 = _mm_unpacklo_epi8(u0, u2); // a0 a8 b0 b8 ... + __m128i v1 = _mm_unpackhi_epi8(u0, u2); // a2 a10 b2 b10 ... + __m128i v2 = _mm_unpacklo_epi8(u1, u3); // a4 a12 b4 b12 ... + __m128i v3 = _mm_unpackhi_epi8(u1, u3); // a6 a14 b6 b14 ... + + u0 = _mm_unpacklo_epi8(v0, v2); // a0 a4 a8 a12 ... + u1 = _mm_unpacklo_epi8(v1, v3); // a2 a6 a10 a14 ... + u2 = _mm_unpackhi_epi8(v0, v2); // a1 a5 a9 a13 ... + u3 = _mm_unpackhi_epi8(v1, v3); // a3 a7 a11 a15 ... + + v0 = _mm_unpacklo_epi8(u0, u1); // a0 a2 a4 a6 ... + v1 = _mm_unpacklo_epi8(u2, u3); // a1 a3 a5 a7 ... + v2 = _mm_unpackhi_epi8(u0, u1); // c0 c2 c4 c6 ... + v3 = _mm_unpackhi_epi8(u2, u3); // c1 c3 c5 c7 ... + + a.val = _mm_unpacklo_epi8(v0, v1); + b.val = _mm_unpackhi_epi8(v0, v1); + c.val = _mm_unpacklo_epi8(v2, v3); + d.val = _mm_unpackhi_epi8(v2, v3); +} + +inline void v_load_deinterleave(const ushort* ptr, v_uint16x8& a, v_uint16x8& b) +{ + __m128i v0 = _mm_loadu_si128((__m128i*)(ptr)); // a0 b0 a1 b1 a2 b2 a3 b3 + __m128i v1 = _mm_loadu_si128((__m128i*)(ptr + 8)); // a4 b4 a5 b5 a6 b6 a7 b7 + + __m128i v2 = _mm_unpacklo_epi16(v0, v1); // a0 a4 b0 b4 a1 a5 b1 b5 + __m128i v3 = _mm_unpackhi_epi16(v0, v1); // a2 a6 b2 b6 a3 a7 b3 b7 + __m128i v4 = _mm_unpacklo_epi16(v2, v3); // a0 a2 a4 a6 b0 b2 b4 b6 + __m128i v5 = _mm_unpackhi_epi16(v2, v3); // a1 a3 a5 a7 b1 b3 b5 b7 + + a.val = _mm_unpacklo_epi16(v4, v5); // a0 a1 a2 a3 a4 a5 a6 a7 + b.val = _mm_unpackhi_epi16(v4, v5); // b0 b1 ab b3 b4 b5 b6 b7 +} + +inline void v_load_deinterleave(const ushort* ptr, v_uint16x8& a, v_uint16x8& b, v_uint16x8& c) +{ +#if CV_SSE4_1 + __m128i v0 = _mm_loadu_si128((__m128i*)(ptr)); + __m128i v1 = _mm_loadu_si128((__m128i*)(ptr + 8)); + __m128i v2 = _mm_loadu_si128((__m128i*)(ptr + 16)); + __m128i a0 = _mm_blend_epi16(_mm_blend_epi16(v0, v1, 0x92), v2, 0x24); + __m128i b0 = _mm_blend_epi16(_mm_blend_epi16(v2, v0, 0x92), v1, 0x24); + __m128i c0 = _mm_blend_epi16(_mm_blend_epi16(v1, v2, 0x92), v0, 0x24); + + const __m128i sh_a = _mm_setr_epi8(0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11); + const __m128i sh_b = _mm_setr_epi8(2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 0, 1, 6, 7, 12, 13); + const __m128i sh_c = _mm_setr_epi8(4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15); + a0 = _mm_shuffle_epi8(a0, sh_a); + b0 = _mm_shuffle_epi8(b0, sh_b); + c0 = _mm_shuffle_epi8(c0, sh_c); + + a.val = a0; + b.val = b0; + c.val = c0; +#else + __m128i t00 = _mm_loadu_si128((const __m128i*)ptr); + __m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 8)); + __m128i t02 = _mm_loadu_si128((const __m128i*)(ptr + 16)); + + __m128i t10 = _mm_unpacklo_epi16(t00, _mm_unpackhi_epi64(t01, t01)); + __m128i t11 = _mm_unpacklo_epi16(_mm_unpackhi_epi64(t00, t00), t02); + __m128i t12 = _mm_unpacklo_epi16(t01, _mm_unpackhi_epi64(t02, t02)); + + __m128i t20 = _mm_unpacklo_epi16(t10, _mm_unpackhi_epi64(t11, t11)); + __m128i t21 = _mm_unpacklo_epi16(_mm_unpackhi_epi64(t10, t10), t12); + __m128i t22 = _mm_unpacklo_epi16(t11, _mm_unpackhi_epi64(t12, t12)); + + a.val = _mm_unpacklo_epi16(t20, _mm_unpackhi_epi64(t21, t21)); + b.val = _mm_unpacklo_epi16(_mm_unpackhi_epi64(t20, t20), t22); + c.val = _mm_unpacklo_epi16(t21, _mm_unpackhi_epi64(t22, t22)); +#endif +} + +inline void v_load_deinterleave(const ushort* ptr, v_uint16x8& a, v_uint16x8& b, v_uint16x8& c, v_uint16x8& d) +{ + __m128i u0 = _mm_loadu_si128((const __m128i*)ptr); // a0 b0 c0 d0 a1 b1 c1 d1 + __m128i u1 = _mm_loadu_si128((const __m128i*)(ptr + 8)); // a2 b2 c2 d2 ... + __m128i u2 = _mm_loadu_si128((const __m128i*)(ptr + 16)); // a4 b4 c4 d4 ... + __m128i u3 = _mm_loadu_si128((const __m128i*)(ptr + 24)); // a6 b6 c6 d6 ... + + __m128i v0 = _mm_unpacklo_epi16(u0, u2); // a0 a4 b0 b4 ... + __m128i v1 = _mm_unpackhi_epi16(u0, u2); // a1 a5 b1 b5 ... + __m128i v2 = _mm_unpacklo_epi16(u1, u3); // a2 a6 b2 b6 ... + __m128i v3 = _mm_unpackhi_epi16(u1, u3); // a3 a7 b3 b7 ... + + u0 = _mm_unpacklo_epi16(v0, v2); // a0 a2 a4 a6 ... + u1 = _mm_unpacklo_epi16(v1, v3); // a1 a3 a5 a7 ... + u2 = _mm_unpackhi_epi16(v0, v2); // c0 c2 c4 c6 ... + u3 = _mm_unpackhi_epi16(v1, v3); // c1 c3 c5 c7 ... + + a.val = _mm_unpacklo_epi16(u0, u1); + b.val = _mm_unpackhi_epi16(u0, u1); + c.val = _mm_unpacklo_epi16(u2, u3); + d.val = _mm_unpackhi_epi16(u2, u3); +} + +inline void v_load_deinterleave(const unsigned* ptr, v_uint32x4& a, v_uint32x4& b) +{ + __m128i v0 = _mm_loadu_si128((__m128i*)(ptr)); // a0 b0 a1 b1 + __m128i v1 = _mm_loadu_si128((__m128i*)(ptr + 4)); // a2 b2 a3 b3 + + __m128i v2 = _mm_unpacklo_epi32(v0, v1); // a0 a2 b0 b2 + __m128i v3 = _mm_unpackhi_epi32(v0, v1); // a1 a3 b1 b3 + + a.val = _mm_unpacklo_epi32(v2, v3); // a0 a1 a2 a3 + b.val = _mm_unpackhi_epi32(v2, v3); // b0 b1 ab b3 +} + +inline void v_load_deinterleave(const unsigned* ptr, v_uint32x4& a, v_uint32x4& b, v_uint32x4& c) +{ + __m128i t00 = _mm_loadu_si128((const __m128i*)ptr); + __m128i t01 = _mm_loadu_si128((const __m128i*)(ptr + 4)); + __m128i t02 = _mm_loadu_si128((const __m128i*)(ptr + 8)); + + __m128i t10 = _mm_unpacklo_epi32(t00, _mm_unpackhi_epi64(t01, t01)); + __m128i t11 = _mm_unpacklo_epi32(_mm_unpackhi_epi64(t00, t00), t02); + __m128i t12 = _mm_unpacklo_epi32(t01, _mm_unpackhi_epi64(t02, t02)); + + a.val = _mm_unpacklo_epi32(t10, _mm_unpackhi_epi64(t11, t11)); + b.val = _mm_unpacklo_epi32(_mm_unpackhi_epi64(t10, t10), t12); + c.val = _mm_unpacklo_epi32(t11, _mm_unpackhi_epi64(t12, t12)); +} + +inline void v_load_deinterleave(const unsigned* ptr, v_uint32x4& a, v_uint32x4& b, v_uint32x4& c, v_uint32x4& d) +{ + v_uint32x4 s0(_mm_loadu_si128((const __m128i*)ptr)); // a0 b0 c0 d0 + v_uint32x4 s1(_mm_loadu_si128((const __m128i*)(ptr + 4))); // a1 b1 c1 d1 + v_uint32x4 s2(_mm_loadu_si128((const __m128i*)(ptr + 8))); // a2 b2 c2 d2 + v_uint32x4 s3(_mm_loadu_si128((const __m128i*)(ptr + 12))); // a3 b3 c3 d3 + + v_transpose4x4(s0, s1, s2, s3, a, b, c, d); +} + +inline void v_load_deinterleave(const float* ptr, v_float32x4& a, v_float32x4& b) +{ + __m128 u0 = _mm_loadu_ps(ptr); // a0 b0 a1 b1 + __m128 u1 = _mm_loadu_ps((ptr + 4)); // a2 b2 a3 b3 + + a.val = _mm_shuffle_ps(u0, u1, _MM_SHUFFLE(2, 0, 2, 0)); // a0 a1 a2 a3 + b.val = _mm_shuffle_ps(u0, u1, _MM_SHUFFLE(3, 1, 3, 1)); // b0 b1 ab b3 +} + +inline void v_load_deinterleave(const float* ptr, v_float32x4& a, v_float32x4& b, v_float32x4& c) +{ + __m128 t0 = _mm_loadu_ps(ptr + 0); + __m128 t1 = _mm_loadu_ps(ptr + 4); + __m128 t2 = _mm_loadu_ps(ptr + 8); + + __m128 at12 = _mm_shuffle_ps(t1, t2, _MM_SHUFFLE(0, 1, 0, 2)); + a.val = _mm_shuffle_ps(t0, at12, _MM_SHUFFLE(2, 0, 3, 0)); + + __m128 bt01 = _mm_shuffle_ps(t0, t1, _MM_SHUFFLE(0, 0, 0, 1)); + __m128 bt12 = _mm_shuffle_ps(t1, t2, _MM_SHUFFLE(0, 2, 0, 3)); + b.val = _mm_shuffle_ps(bt01, bt12, _MM_SHUFFLE(2, 0, 2, 0)); + + __m128 ct01 = _mm_shuffle_ps(t0, t1, _MM_SHUFFLE(0, 1, 0, 2)); + c.val = _mm_shuffle_ps(ct01, t2, _MM_SHUFFLE(3, 0, 2, 0)); +} + +inline void v_load_deinterleave(const float* ptr, v_float32x4& a, v_float32x4& b, v_float32x4& c, v_float32x4& d) +{ + __m128 t0 = _mm_loadu_ps(ptr + 0); + __m128 t1 = _mm_loadu_ps(ptr + 4); + __m128 t2 = _mm_loadu_ps(ptr + 8); + __m128 t3 = _mm_loadu_ps(ptr + 12); + __m128 t02lo = _mm_unpacklo_ps(t0, t2); + __m128 t13lo = _mm_unpacklo_ps(t1, t3); + __m128 t02hi = _mm_unpackhi_ps(t0, t2); + __m128 t13hi = _mm_unpackhi_ps(t1, t3); + a.val = _mm_unpacklo_ps(t02lo, t13lo); + b.val = _mm_unpackhi_ps(t02lo, t13lo); + c.val = _mm_unpacklo_ps(t02hi, t13hi); + d.val = _mm_unpackhi_ps(t02hi, t13hi); +} + +inline void v_load_deinterleave(const uint64 *ptr, v_uint64x2& a, v_uint64x2& b) +{ + __m128i t0 = _mm_loadu_si128((const __m128i*)ptr); + __m128i t1 = _mm_loadu_si128((const __m128i*)(ptr + 2)); + + a = v_uint64x2(_mm_unpacklo_epi64(t0, t1)); + b = v_uint64x2(_mm_unpackhi_epi64(t0, t1)); +} + +inline void v_load_deinterleave(const uint64 *ptr, v_uint64x2& a, v_uint64x2& b, v_uint64x2& c) +{ + __m128i t0 = _mm_loadu_si128((const __m128i*)ptr); // a0, b0 + __m128i t1 = _mm_loadu_si128((const __m128i*)(ptr + 2)); // c0, a1 + __m128i t2 = _mm_loadu_si128((const __m128i*)(ptr + 4)); // b1, c1 + + t1 = _mm_shuffle_epi32(t1, 0x4e); // a1, c0 + + a = v_uint64x2(_mm_unpacklo_epi64(t0, t1)); + b = v_uint64x2(_mm_unpacklo_epi64(_mm_unpackhi_epi64(t0, t0), t2)); + c = v_uint64x2(_mm_unpackhi_epi64(t1, t2)); +} + +inline void v_load_deinterleave(const uint64 *ptr, v_uint64x2& a, + v_uint64x2& b, v_uint64x2& c, v_uint64x2& d) +{ + __m128i t0 = _mm_loadu_si128((const __m128i*)ptr); // a0 b0 + __m128i t1 = _mm_loadu_si128((const __m128i*)(ptr + 2)); // c0 d0 + __m128i t2 = _mm_loadu_si128((const __m128i*)(ptr + 4)); // a1 b1 + __m128i t3 = _mm_loadu_si128((const __m128i*)(ptr + 6)); // c1 d1 + + a = v_uint64x2(_mm_unpacklo_epi64(t0, t2)); + b = v_uint64x2(_mm_unpackhi_epi64(t0, t2)); + c = v_uint64x2(_mm_unpacklo_epi64(t1, t3)); + d = v_uint64x2(_mm_unpackhi_epi64(t1, t3)); +} + +// store interleave + +inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128i v0 = _mm_unpacklo_epi8(a.val, b.val); + __m128i v1 = _mm_unpackhi_epi8(a.val, b.val); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 16), v1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 16), v1); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 16), v1); + } +} + +inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b, + const v_uint8x16& c, hal::StoreMode mode = hal::STORE_UNALIGNED) +{ +#if CV_SSE4_1 + const __m128i sh_a = _mm_setr_epi8(0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10, 5); + const __m128i sh_b = _mm_setr_epi8(5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15, 10); + const __m128i sh_c = _mm_setr_epi8(10, 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15); + __m128i a0 = _mm_shuffle_epi8(a.val, sh_a); + __m128i b0 = _mm_shuffle_epi8(b.val, sh_b); + __m128i c0 = _mm_shuffle_epi8(c.val, sh_c); + + const __m128i m0 = _mm_setr_epi8(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0); + const __m128i m1 = _mm_setr_epi8(0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0); + __m128i v0 = _mm_blendv_epi8(_mm_blendv_epi8(a0, b0, m1), c0, m0); + __m128i v1 = _mm_blendv_epi8(_mm_blendv_epi8(b0, c0, m1), a0, m0); + __m128i v2 = _mm_blendv_epi8(_mm_blendv_epi8(c0, a0, m1), b0, m0); +#elif CV_SSSE3 + const __m128i m0 = _mm_setr_epi8(0, 6, 11, 1, 7, 12, 2, 8, 13, 3, 9, 14, 4, 10, 15, 5); + const __m128i m1 = _mm_setr_epi8(5, 11, 0, 6, 12, 1, 7, 13, 2, 8, 14, 3, 9, 15, 4, 10); + const __m128i m2 = _mm_setr_epi8(10, 0, 5, 11, 1, 6, 12, 2, 7, 13, 3, 8, 14, 4, 9, 15); + + __m128i t0 = _mm_alignr_epi8(b.val, _mm_slli_si128(a.val, 10), 5); + t0 = _mm_alignr_epi8(c.val, t0, 5); + __m128i v0 = _mm_shuffle_epi8(t0, m0); + + __m128i t1 = _mm_alignr_epi8(_mm_srli_si128(b.val, 5), _mm_slli_si128(a.val, 5), 6); + t1 = _mm_alignr_epi8(_mm_srli_si128(c.val, 5), t1, 5); + __m128i v1 = _mm_shuffle_epi8(t1, m1); + + __m128i t2 = _mm_alignr_epi8(_mm_srli_si128(c.val, 10), b.val, 11); + t2 = _mm_alignr_epi8(t2, a.val, 11); + __m128i v2 = _mm_shuffle_epi8(t2, m2); +#else + __m128i z = _mm_setzero_si128(); + __m128i ab0 = _mm_unpacklo_epi8(a.val, b.val); + __m128i ab1 = _mm_unpackhi_epi8(a.val, b.val); + __m128i c0 = _mm_unpacklo_epi8(c.val, z); + __m128i c1 = _mm_unpackhi_epi8(c.val, z); + + __m128i p00 = _mm_unpacklo_epi16(ab0, c0); + __m128i p01 = _mm_unpackhi_epi16(ab0, c0); + __m128i p02 = _mm_unpacklo_epi16(ab1, c1); + __m128i p03 = _mm_unpackhi_epi16(ab1, c1); + + __m128i p10 = _mm_unpacklo_epi32(p00, p01); + __m128i p11 = _mm_unpackhi_epi32(p00, p01); + __m128i p12 = _mm_unpacklo_epi32(p02, p03); + __m128i p13 = _mm_unpackhi_epi32(p02, p03); + + __m128i p20 = _mm_unpacklo_epi64(p10, p11); + __m128i p21 = _mm_unpackhi_epi64(p10, p11); + __m128i p22 = _mm_unpacklo_epi64(p12, p13); + __m128i p23 = _mm_unpackhi_epi64(p12, p13); + + p20 = _mm_slli_si128(p20, 1); + p22 = _mm_slli_si128(p22, 1); + + __m128i p30 = _mm_slli_epi64(_mm_unpacklo_epi32(p20, p21), 8); + __m128i p31 = _mm_srli_epi64(_mm_unpackhi_epi32(p20, p21), 8); + __m128i p32 = _mm_slli_epi64(_mm_unpacklo_epi32(p22, p23), 8); + __m128i p33 = _mm_srli_epi64(_mm_unpackhi_epi32(p22, p23), 8); + + __m128i p40 = _mm_unpacklo_epi64(p30, p31); + __m128i p41 = _mm_unpackhi_epi64(p30, p31); + __m128i p42 = _mm_unpacklo_epi64(p32, p33); + __m128i p43 = _mm_unpackhi_epi64(p32, p33); + + __m128i v0 = _mm_or_si128(_mm_srli_si128(p40, 2), _mm_slli_si128(p41, 10)); + __m128i v1 = _mm_or_si128(_mm_srli_si128(p41, 6), _mm_slli_si128(p42, 6)); + __m128i v2 = _mm_or_si128(_mm_srli_si128(p42, 10), _mm_slli_si128(p43, 2)); +#endif + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 16), v1); + _mm_stream_si128((__m128i*)(ptr + 32), v2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 16), v1); + _mm_store_si128((__m128i*)(ptr + 32), v2); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 16), v1); + _mm_storeu_si128((__m128i*)(ptr + 32), v2); + } +} + +inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b, + const v_uint8x16& c, const v_uint8x16& d, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + // a0 a1 a2 a3 .... + // b0 b1 b2 b3 .... + // c0 c1 c2 c3 .... + // d0 d1 d2 d3 .... + __m128i u0 = _mm_unpacklo_epi8(a.val, c.val); // a0 c0 a1 c1 ... + __m128i u1 = _mm_unpackhi_epi8(a.val, c.val); // a8 c8 a9 c9 ... + __m128i u2 = _mm_unpacklo_epi8(b.val, d.val); // b0 d0 b1 d1 ... + __m128i u3 = _mm_unpackhi_epi8(b.val, d.val); // b8 d8 b9 d9 ... + + __m128i v0 = _mm_unpacklo_epi8(u0, u2); // a0 b0 c0 d0 ... + __m128i v1 = _mm_unpackhi_epi8(u0, u2); // a4 b4 c4 d4 ... + __m128i v2 = _mm_unpacklo_epi8(u1, u3); // a8 b8 c8 d8 ... + __m128i v3 = _mm_unpackhi_epi8(u1, u3); // a12 b12 c12 d12 ... + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 16), v1); + _mm_stream_si128((__m128i*)(ptr + 32), v2); + _mm_stream_si128((__m128i*)(ptr + 48), v3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 16), v1); + _mm_store_si128((__m128i*)(ptr + 32), v2); + _mm_store_si128((__m128i*)(ptr + 48), v3); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 16), v1); + _mm_storeu_si128((__m128i*)(ptr + 32), v2); + _mm_storeu_si128((__m128i*)(ptr + 48), v3); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x8& a, const v_uint16x8& b, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128i v0 = _mm_unpacklo_epi16(a.val, b.val); + __m128i v1 = _mm_unpackhi_epi16(a.val, b.val); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 8), v1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 8), v1); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 8), v1); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x8& a, + const v_uint16x8& b, const v_uint16x8& c, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ +#if CV_SSE4_1 + const __m128i sh_a = _mm_setr_epi8(0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11); + const __m128i sh_b = _mm_setr_epi8(10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5); + const __m128i sh_c = _mm_setr_epi8(4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15); + __m128i a0 = _mm_shuffle_epi8(a.val, sh_a); + __m128i b0 = _mm_shuffle_epi8(b.val, sh_b); + __m128i c0 = _mm_shuffle_epi8(c.val, sh_c); + + __m128i v0 = _mm_blend_epi16(_mm_blend_epi16(a0, b0, 0x92), c0, 0x24); + __m128i v1 = _mm_blend_epi16(_mm_blend_epi16(c0, a0, 0x92), b0, 0x24); + __m128i v2 = _mm_blend_epi16(_mm_blend_epi16(b0, c0, 0x92), a0, 0x24); +#else + __m128i z = _mm_setzero_si128(); + __m128i ab0 = _mm_unpacklo_epi16(a.val, b.val); + __m128i ab1 = _mm_unpackhi_epi16(a.val, b.val); + __m128i c0 = _mm_unpacklo_epi16(c.val, z); + __m128i c1 = _mm_unpackhi_epi16(c.val, z); + + __m128i p10 = _mm_unpacklo_epi32(ab0, c0); + __m128i p11 = _mm_unpackhi_epi32(ab0, c0); + __m128i p12 = _mm_unpacklo_epi32(ab1, c1); + __m128i p13 = _mm_unpackhi_epi32(ab1, c1); + + __m128i p20 = _mm_unpacklo_epi64(p10, p11); + __m128i p21 = _mm_unpackhi_epi64(p10, p11); + __m128i p22 = _mm_unpacklo_epi64(p12, p13); + __m128i p23 = _mm_unpackhi_epi64(p12, p13); + + p20 = _mm_slli_si128(p20, 2); + p22 = _mm_slli_si128(p22, 2); + + __m128i p30 = _mm_unpacklo_epi64(p20, p21); + __m128i p31 = _mm_unpackhi_epi64(p20, p21); + __m128i p32 = _mm_unpacklo_epi64(p22, p23); + __m128i p33 = _mm_unpackhi_epi64(p22, p23); + + __m128i v0 = _mm_or_si128(_mm_srli_si128(p30, 2), _mm_slli_si128(p31, 10)); + __m128i v1 = _mm_or_si128(_mm_srli_si128(p31, 6), _mm_slli_si128(p32, 6)); + __m128i v2 = _mm_or_si128(_mm_srli_si128(p32, 10), _mm_slli_si128(p33, 2)); +#endif + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 8), v1); + _mm_stream_si128((__m128i*)(ptr + 16), v2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 8), v1); + _mm_store_si128((__m128i*)(ptr + 16), v2); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 8), v1); + _mm_storeu_si128((__m128i*)(ptr + 16), v2); + } +} + +inline void v_store_interleave( ushort* ptr, const v_uint16x8& a, const v_uint16x8& b, + const v_uint16x8& c, const v_uint16x8& d, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + // a0 a1 a2 a3 .... + // b0 b1 b2 b3 .... + // c0 c1 c2 c3 .... + // d0 d1 d2 d3 .... + __m128i u0 = _mm_unpacklo_epi16(a.val, c.val); // a0 c0 a1 c1 ... + __m128i u1 = _mm_unpackhi_epi16(a.val, c.val); // a4 c4 a5 c5 ... + __m128i u2 = _mm_unpacklo_epi16(b.val, d.val); // b0 d0 b1 d1 ... + __m128i u3 = _mm_unpackhi_epi16(b.val, d.val); // b4 d4 b5 d5 ... + + __m128i v0 = _mm_unpacklo_epi16(u0, u2); // a0 b0 c0 d0 ... + __m128i v1 = _mm_unpackhi_epi16(u0, u2); // a2 b2 c2 d2 ... + __m128i v2 = _mm_unpacklo_epi16(u1, u3); // a4 b4 c4 d4 ... + __m128i v3 = _mm_unpackhi_epi16(u1, u3); // a6 b6 c6 d6 ... + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 8), v1); + _mm_stream_si128((__m128i*)(ptr + 16), v2); + _mm_stream_si128((__m128i*)(ptr + 24), v3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 8), v1); + _mm_store_si128((__m128i*)(ptr + 16), v2); + _mm_store_si128((__m128i*)(ptr + 24), v3); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 8), v1); + _mm_storeu_si128((__m128i*)(ptr + 16), v2); + _mm_storeu_si128((__m128i*)(ptr + 24), v3); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x4& a, const v_uint32x4& b, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128i v0 = _mm_unpacklo_epi32(a.val, b.val); + __m128i v1 = _mm_unpackhi_epi32(a.val, b.val); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 4), v1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 4), v1); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 4), v1); + } +} + +inline void v_store_interleave( unsigned* ptr, const v_uint32x4& a, const v_uint32x4& b, + const v_uint32x4& c, hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + v_uint32x4 z = v_setzero_u32(), u0, u1, u2, u3; + v_transpose4x4(a, b, c, z, u0, u1, u2, u3); + + __m128i v0 = _mm_or_si128(u0.val, _mm_slli_si128(u1.val, 12)); + __m128i v1 = _mm_or_si128(_mm_srli_si128(u1.val, 4), _mm_slli_si128(u2.val, 8)); + __m128i v2 = _mm_or_si128(_mm_srli_si128(u2.val, 8), _mm_slli_si128(u3.val, 4)); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 4), v1); + _mm_stream_si128((__m128i*)(ptr + 8), v2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 4), v1); + _mm_store_si128((__m128i*)(ptr + 8), v2); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 4), v1); + _mm_storeu_si128((__m128i*)(ptr + 8), v2); + } +} + +inline void v_store_interleave(unsigned* ptr, const v_uint32x4& a, const v_uint32x4& b, + const v_uint32x4& c, const v_uint32x4& d, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + v_uint32x4 v0, v1, v2, v3; + v_transpose4x4(a, b, c, d, v0, v1, v2, v3); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0.val); + _mm_stream_si128((__m128i*)(ptr + 4), v1.val); + _mm_stream_si128((__m128i*)(ptr + 8), v2.val); + _mm_stream_si128((__m128i*)(ptr + 12), v3.val); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0.val); + _mm_store_si128((__m128i*)(ptr + 4), v1.val); + _mm_store_si128((__m128i*)(ptr + 8), v2.val); + _mm_store_si128((__m128i*)(ptr + 12), v3.val); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0.val); + _mm_storeu_si128((__m128i*)(ptr + 4), v1.val); + _mm_storeu_si128((__m128i*)(ptr + 8), v2.val); + _mm_storeu_si128((__m128i*)(ptr + 12), v3.val); + } +} + +// 2-channel, float only +inline void v_store_interleave(float* ptr, const v_float32x4& a, const v_float32x4& b, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128 v0 = _mm_unpacklo_ps(a.val, b.val); // a0 b0 a1 b1 + __m128 v1 = _mm_unpackhi_ps(a.val, b.val); // a2 b2 a3 b3 + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_ps(ptr, v0); + _mm_stream_ps(ptr + 4, v1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_ps(ptr, v0); + _mm_store_ps(ptr + 4, v1); + } + else + { + _mm_storeu_ps(ptr, v0); + _mm_storeu_ps(ptr + 4, v1); + } +} + +inline void v_store_interleave(float* ptr, const v_float32x4& a, const v_float32x4& b, + const v_float32x4& c, hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128 u0 = _mm_shuffle_ps(a.val, b.val, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 u1 = _mm_shuffle_ps(c.val, a.val, _MM_SHUFFLE(1, 1, 0, 0)); + __m128 v0 = _mm_shuffle_ps(u0, u1, _MM_SHUFFLE(2, 0, 2, 0)); + __m128 u2 = _mm_shuffle_ps(b.val, c.val, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 u3 = _mm_shuffle_ps(a.val, b.val, _MM_SHUFFLE(2, 2, 2, 2)); + __m128 v1 = _mm_shuffle_ps(u2, u3, _MM_SHUFFLE(2, 0, 2, 0)); + __m128 u4 = _mm_shuffle_ps(c.val, a.val, _MM_SHUFFLE(3, 3, 2, 2)); + __m128 u5 = _mm_shuffle_ps(b.val, c.val, _MM_SHUFFLE(3, 3, 3, 3)); + __m128 v2 = _mm_shuffle_ps(u4, u5, _MM_SHUFFLE(2, 0, 2, 0)); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_ps(ptr, v0); + _mm_stream_ps(ptr + 4, v1); + _mm_stream_ps(ptr + 8, v2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_ps(ptr, v0); + _mm_store_ps(ptr + 4, v1); + _mm_store_ps(ptr + 8, v2); + } + else + { + _mm_storeu_ps(ptr, v0); + _mm_storeu_ps(ptr + 4, v1); + _mm_storeu_ps(ptr + 8, v2); + } +} + +inline void v_store_interleave(float* ptr, const v_float32x4& a, const v_float32x4& b, + const v_float32x4& c, const v_float32x4& d, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128 u0 = _mm_unpacklo_ps(a.val, c.val); + __m128 u1 = _mm_unpacklo_ps(b.val, d.val); + __m128 u2 = _mm_unpackhi_ps(a.val, c.val); + __m128 u3 = _mm_unpackhi_ps(b.val, d.val); + __m128 v0 = _mm_unpacklo_ps(u0, u1); + __m128 v2 = _mm_unpacklo_ps(u2, u3); + __m128 v1 = _mm_unpackhi_ps(u0, u1); + __m128 v3 = _mm_unpackhi_ps(u2, u3); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_ps(ptr, v0); + _mm_stream_ps(ptr + 4, v1); + _mm_stream_ps(ptr + 8, v2); + _mm_stream_ps(ptr + 12, v3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_ps(ptr, v0); + _mm_store_ps(ptr + 4, v1); + _mm_store_ps(ptr + 8, v2); + _mm_store_ps(ptr + 12, v3); + } + else + { + _mm_storeu_ps(ptr, v0); + _mm_storeu_ps(ptr + 4, v1); + _mm_storeu_ps(ptr + 8, v2); + _mm_storeu_ps(ptr + 12, v3); + } +} + +inline void v_store_interleave(uint64 *ptr, const v_uint64x2& a, const v_uint64x2& b, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128i v0 = _mm_unpacklo_epi64(a.val, b.val); + __m128i v1 = _mm_unpackhi_epi64(a.val, b.val); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 2), v1); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 2), v1); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 2), v1); + } +} + +inline void v_store_interleave(uint64 *ptr, const v_uint64x2& a, const v_uint64x2& b, + const v_uint64x2& c, hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128i v0 = _mm_unpacklo_epi64(a.val, b.val); + __m128i v1 = _mm_unpacklo_epi64(c.val, _mm_unpackhi_epi64(a.val, a.val)); + __m128i v2 = _mm_unpackhi_epi64(b.val, c.val); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 2), v1); + _mm_stream_si128((__m128i*)(ptr + 4), v2); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 2), v1); + _mm_store_si128((__m128i*)(ptr + 4), v2); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 2), v1); + _mm_storeu_si128((__m128i*)(ptr + 4), v2); + } +} + +inline void v_store_interleave(uint64 *ptr, const v_uint64x2& a, const v_uint64x2& b, + const v_uint64x2& c, const v_uint64x2& d, + hal::StoreMode mode = hal::STORE_UNALIGNED) +{ + __m128i v0 = _mm_unpacklo_epi64(a.val, b.val); + __m128i v1 = _mm_unpacklo_epi64(c.val, d.val); + __m128i v2 = _mm_unpackhi_epi64(a.val, b.val); + __m128i v3 = _mm_unpackhi_epi64(c.val, d.val); + + if( mode == hal::STORE_ALIGNED_NOCACHE ) + { + _mm_stream_si128((__m128i*)(ptr), v0); + _mm_stream_si128((__m128i*)(ptr + 2), v1); + _mm_stream_si128((__m128i*)(ptr + 4), v2); + _mm_stream_si128((__m128i*)(ptr + 6), v3); + } + else if( mode == hal::STORE_ALIGNED ) + { + _mm_store_si128((__m128i*)(ptr), v0); + _mm_store_si128((__m128i*)(ptr + 2), v1); + _mm_store_si128((__m128i*)(ptr + 4), v2); + _mm_store_si128((__m128i*)(ptr + 6), v3); + } + else + { + _mm_storeu_si128((__m128i*)(ptr), v0); + _mm_storeu_si128((__m128i*)(ptr + 2), v1); + _mm_storeu_si128((__m128i*)(ptr + 4), v2); + _mm_storeu_si128((__m128i*)(ptr + 6), v3); + } +} + +#define OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(_Tpvec0, _Tp0, suffix0, _Tpvec1, _Tp1, suffix1) \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0 ) \ +{ \ + _Tpvec1 a1, b1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ +} \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0, _Tpvec0& c0 ) \ +{ \ + _Tpvec1 a1, b1, c1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1, c1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ + c0 = v_reinterpret_as_##suffix0(c1); \ +} \ +inline void v_load_deinterleave( const _Tp0* ptr, _Tpvec0& a0, _Tpvec0& b0, _Tpvec0& c0, _Tpvec0& d0 ) \ +{ \ + _Tpvec1 a1, b1, c1, d1; \ + v_load_deinterleave((const _Tp1*)ptr, a1, b1, c1, d1); \ + a0 = v_reinterpret_as_##suffix0(a1); \ + b0 = v_reinterpret_as_##suffix0(b1); \ + c0 = v_reinterpret_as_##suffix0(c1); \ + d0 = v_reinterpret_as_##suffix0(d1); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, \ + hal::StoreMode mode = hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, mode); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, \ + const _Tpvec0& c0, hal::StoreMode mode = hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + _Tpvec1 c1 = v_reinterpret_as_##suffix1(c0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, c1, mode); \ +} \ +inline void v_store_interleave( _Tp0* ptr, const _Tpvec0& a0, const _Tpvec0& b0, \ + const _Tpvec0& c0, const _Tpvec0& d0, \ + hal::StoreMode mode = hal::STORE_UNALIGNED ) \ +{ \ + _Tpvec1 a1 = v_reinterpret_as_##suffix1(a0); \ + _Tpvec1 b1 = v_reinterpret_as_##suffix1(b0); \ + _Tpvec1 c1 = v_reinterpret_as_##suffix1(c0); \ + _Tpvec1 d1 = v_reinterpret_as_##suffix1(d0); \ + v_store_interleave((_Tp1*)ptr, a1, b1, c1, d1, mode); \ +} + +OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_int8x16, schar, s8, v_uint8x16, uchar, u8) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_int16x8, short, s16, v_uint16x8, ushort, u16) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_int32x4, int, s32, v_uint32x4, unsigned, u32) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_int64x2, int64, s64, v_uint64x2, uint64, u64) +OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(v_float64x2, double, f64, v_uint64x2, uint64, u64) + +inline v_float32x4 v_cvt_f32(const v_int32x4& a) +{ + return v_float32x4(_mm_cvtepi32_ps(a.val)); +} + +inline v_float32x4 v_cvt_f32(const v_float64x2& a) +{ + return v_float32x4(_mm_cvtpd_ps(a.val)); +} + +inline v_float32x4 v_cvt_f32(const v_float64x2& a, const v_float64x2& b) +{ + return v_float32x4(_mm_movelh_ps(_mm_cvtpd_ps(a.val), _mm_cvtpd_ps(b.val))); +} + +inline v_float64x2 v_cvt_f64(const v_int32x4& a) +{ + return v_float64x2(_mm_cvtepi32_pd(a.val)); +} + +inline v_float64x2 v_cvt_f64_high(const v_int32x4& a) +{ + return v_float64x2(_mm_cvtepi32_pd(_mm_srli_si128(a.val,8))); +} + +inline v_float64x2 v_cvt_f64(const v_float32x4& a) +{ + return v_float64x2(_mm_cvtps_pd(a.val)); +} + +inline v_float64x2 v_cvt_f64_high(const v_float32x4& a) +{ + return v_float64x2(_mm_cvtps_pd(_mm_movehl_ps(a.val, a.val))); +} + +////////////// Lookup table access //////////////////// + +inline v_int8x16 v_lut(const schar* tab, const int* idx) +{ +#if defined(_MSC_VER) + return v_int8x16(_mm_setr_epi8(tab[idx[0]], tab[idx[1]], tab[idx[ 2]], tab[idx[ 3]], tab[idx[ 4]], tab[idx[ 5]], tab[idx[ 6]], tab[idx[ 7]], + tab[idx[8]], tab[idx[9]], tab[idx[10]], tab[idx[11]], tab[idx[12]], tab[idx[13]], tab[idx[14]], tab[idx[15]])); +#else + return v_int8x16(_mm_setr_epi64( + _mm_setr_pi8(tab[idx[0]], tab[idx[1]], tab[idx[ 2]], tab[idx[ 3]], tab[idx[ 4]], tab[idx[ 5]], tab[idx[ 6]], tab[idx[ 7]]), + _mm_setr_pi8(tab[idx[8]], tab[idx[9]], tab[idx[10]], tab[idx[11]], tab[idx[12]], tab[idx[13]], tab[idx[14]], tab[idx[15]]) + )); +#endif +} +inline v_int8x16 v_lut_pairs(const schar* tab, const int* idx) +{ +#if defined(_MSC_VER) + return v_int8x16(_mm_setr_epi16(*(const short*)(tab + idx[0]), *(const short*)(tab + idx[1]), *(const short*)(tab + idx[2]), *(const short*)(tab + idx[3]), + *(const short*)(tab + idx[4]), *(const short*)(tab + idx[5]), *(const short*)(tab + idx[6]), *(const short*)(tab + idx[7]))); +#else + return v_int8x16(_mm_setr_epi64( + _mm_setr_pi16(*(const short*)(tab + idx[0]), *(const short*)(tab + idx[1]), *(const short*)(tab + idx[2]), *(const short*)(tab + idx[3])), + _mm_setr_pi16(*(const short*)(tab + idx[4]), *(const short*)(tab + idx[5]), *(const short*)(tab + idx[6]), *(const short*)(tab + idx[7])) + )); +#endif +} +inline v_int8x16 v_lut_quads(const schar* tab, const int* idx) +{ +#if defined(_MSC_VER) + return v_int8x16(_mm_setr_epi32(*(const int*)(tab + idx[0]), *(const int*)(tab + idx[1]), + *(const int*)(tab + idx[2]), *(const int*)(tab + idx[3]))); +#else + return v_int8x16(_mm_setr_epi64( + _mm_setr_pi32(*(const int*)(tab + idx[0]), *(const int*)(tab + idx[1])), + _mm_setr_pi32(*(const int*)(tab + idx[2]), *(const int*)(tab + idx[3])) + )); +#endif +} +inline v_uint8x16 v_lut(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut((const schar *)tab, idx)); } +inline v_uint8x16 v_lut_pairs(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_pairs((const schar *)tab, idx)); } +inline v_uint8x16 v_lut_quads(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_quads((const schar *)tab, idx)); } + +inline v_int16x8 v_lut(const short* tab, const int* idx) +{ +#if defined(_MSC_VER) + return v_int16x8(_mm_setr_epi16(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]], + tab[idx[4]], tab[idx[5]], tab[idx[6]], tab[idx[7]])); +#else + return v_int16x8(_mm_setr_epi64( + _mm_setr_pi16(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]), + _mm_setr_pi16(tab[idx[4]], tab[idx[5]], tab[idx[6]], tab[idx[7]]) + )); +#endif +} +inline v_int16x8 v_lut_pairs(const short* tab, const int* idx) +{ +#if defined(_MSC_VER) + return v_int16x8(_mm_setr_epi32(*(const int*)(tab + idx[0]), *(const int*)(tab + idx[1]), + *(const int*)(tab + idx[2]), *(const int*)(tab + idx[3]))); +#else + return v_int16x8(_mm_setr_epi64( + _mm_setr_pi32(*(const int*)(tab + idx[0]), *(const int*)(tab + idx[1])), + _mm_setr_pi32(*(const int*)(tab + idx[2]), *(const int*)(tab + idx[3])) + )); +#endif +} +inline v_int16x8 v_lut_quads(const short* tab, const int* idx) +{ + return v_int16x8(_mm_set_epi64x(*(const int64_t*)(tab + idx[1]), *(const int64_t*)(tab + idx[0]))); +} +inline v_uint16x8 v_lut(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut((const short *)tab, idx)); } +inline v_uint16x8 v_lut_pairs(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_pairs((const short *)tab, idx)); } +inline v_uint16x8 v_lut_quads(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_quads((const short *)tab, idx)); } + +inline v_int32x4 v_lut(const int* tab, const int* idx) +{ +#if defined(_MSC_VER) + return v_int32x4(_mm_setr_epi32(tab[idx[0]], tab[idx[1]], + tab[idx[2]], tab[idx[3]])); +#else + return v_int32x4(_mm_setr_epi64( + _mm_setr_pi32(tab[idx[0]], tab[idx[1]]), + _mm_setr_pi32(tab[idx[2]], tab[idx[3]]) + )); +#endif +} +inline v_int32x4 v_lut_pairs(const int* tab, const int* idx) +{ + return v_int32x4(_mm_set_epi64x(*(const int64_t*)(tab + idx[1]), *(const int64_t*)(tab + idx[0]))); +} +inline v_int32x4 v_lut_quads(const int* tab, const int* idx) +{ + return v_int32x4(_mm_loadu_si128((const __m128i*)(tab + idx[0]))); +} +inline v_uint32x4 v_lut(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut((const int *)tab, idx)); } +inline v_uint32x4 v_lut_pairs(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_pairs((const int *)tab, idx)); } +inline v_uint32x4 v_lut_quads(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_quads((const int *)tab, idx)); } + +inline v_int64x2 v_lut(const int64_t* tab, const int* idx) +{ + return v_int64x2(_mm_set_epi64x(tab[idx[1]], tab[idx[0]])); +} +inline v_int64x2 v_lut_pairs(const int64_t* tab, const int* idx) +{ + return v_int64x2(_mm_loadu_si128((const __m128i*)(tab + idx[0]))); +} +inline v_uint64x2 v_lut(const uint64_t* tab, const int* idx) { return v_reinterpret_as_u64(v_lut((const int64_t *)tab, idx)); } +inline v_uint64x2 v_lut_pairs(const uint64_t* tab, const int* idx) { return v_reinterpret_as_u64(v_lut_pairs((const int64_t *)tab, idx)); } + +inline v_float32x4 v_lut(const float* tab, const int* idx) +{ + return v_float32x4(_mm_setr_ps(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]])); +} +inline v_float32x4 v_lut_pairs(const float* tab, const int* idx) { return v_reinterpret_as_f32(v_lut_pairs((const int *)tab, idx)); } +inline v_float32x4 v_lut_quads(const float* tab, const int* idx) { return v_reinterpret_as_f32(v_lut_quads((const int *)tab, idx)); } + +inline v_float64x2 v_lut(const double* tab, const int* idx) +{ + return v_float64x2(_mm_setr_pd(tab[idx[0]], tab[idx[1]])); +} +inline v_float64x2 v_lut_pairs(const double* tab, const int* idx) { return v_float64x2(_mm_castsi128_pd(_mm_loadu_si128((const __m128i*)(tab + idx[0])))); } + +inline v_int32x4 v_lut(const int* tab, const v_int32x4& idxvec) +{ + int CV_DECL_ALIGNED(32) idx[4]; + v_store_aligned(idx, idxvec); + return v_int32x4(_mm_setr_epi32(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]])); +} + +inline v_uint32x4 v_lut(const unsigned* tab, const v_int32x4& idxvec) +{ + return v_reinterpret_as_u32(v_lut((const int *)tab, idxvec)); +} + +inline v_float32x4 v_lut(const float* tab, const v_int32x4& idxvec) +{ + int CV_DECL_ALIGNED(32) idx[4]; + v_store_aligned(idx, idxvec); + return v_float32x4(_mm_setr_ps(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]])); +} + +inline v_float64x2 v_lut(const double* tab, const v_int32x4& idxvec) +{ + int idx[2]; + v_store_low(idx, idxvec); + return v_float64x2(_mm_setr_pd(tab[idx[0]], tab[idx[1]])); +} + +// loads pairs from the table and deinterleaves them, e.g. returns: +// x = (tab[idxvec[0], tab[idxvec[1]], tab[idxvec[2]], tab[idxvec[3]]), +// y = (tab[idxvec[0]+1], tab[idxvec[1]+1], tab[idxvec[2]+1], tab[idxvec[3]+1]) +// note that the indices are float's indices, not the float-pair indices. +// in theory, this function can be used to implement bilinear interpolation, +// when idxvec are the offsets within the image. +inline void v_lut_deinterleave(const float* tab, const v_int32x4& idxvec, v_float32x4& x, v_float32x4& y) +{ + int CV_DECL_ALIGNED(32) idx[4]; + v_store_aligned(idx, idxvec); + __m128 z = _mm_setzero_ps(); + __m128 xy01 = _mm_loadl_pi(z, (__m64*)(tab + idx[0])); + __m128 xy23 = _mm_loadl_pi(z, (__m64*)(tab + idx[2])); + xy01 = _mm_loadh_pi(xy01, (__m64*)(tab + idx[1])); + xy23 = _mm_loadh_pi(xy23, (__m64*)(tab + idx[3])); + __m128 xxyy02 = _mm_unpacklo_ps(xy01, xy23); + __m128 xxyy13 = _mm_unpackhi_ps(xy01, xy23); + x = v_float32x4(_mm_unpacklo_ps(xxyy02, xxyy13)); + y = v_float32x4(_mm_unpackhi_ps(xxyy02, xxyy13)); +} + +inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_float64x2& x, v_float64x2& y) +{ + int idx[2]; + v_store_low(idx, idxvec); + __m128d xy0 = _mm_loadu_pd(tab + idx[0]); + __m128d xy1 = _mm_loadu_pd(tab + idx[1]); + x = v_float64x2(_mm_unpacklo_pd(xy0, xy1)); + y = v_float64x2(_mm_unpackhi_pd(xy0, xy1)); +} + +inline v_int8x16 v_interleave_pairs(const v_int8x16& vec) +{ +#if CV_SSSE3 + return v_int8x16(_mm_shuffle_epi8(vec.val, _mm_set_epi64x(0x0f0d0e0c0b090a08, 0x0705060403010200))); +#else + __m128i a = _mm_shufflelo_epi16(vec.val, _MM_SHUFFLE(3, 1, 2, 0)); + a = _mm_shufflehi_epi16(a, _MM_SHUFFLE(3, 1, 2, 0)); + a = _mm_shuffle_epi32(a, _MM_SHUFFLE(3, 1, 2, 0)); + return v_int8x16(_mm_unpacklo_epi8(a, _mm_unpackhi_epi64(a, a))); +#endif +} +inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); } +inline v_int8x16 v_interleave_quads(const v_int8x16& vec) +{ +#if CV_SSSE3 + return v_int8x16(_mm_shuffle_epi8(vec.val, _mm_set_epi64x(0x0f0b0e0a0d090c08, 0x0703060205010400))); +#else + __m128i a = _mm_shuffle_epi32(vec.val, _MM_SHUFFLE(3, 1, 2, 0)); + return v_int8x16(_mm_unpacklo_epi8(a, _mm_unpackhi_epi64(a, a))); +#endif +} +inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); } + +inline v_int16x8 v_interleave_pairs(const v_int16x8& vec) +{ +#if CV_SSSE3 + return v_int16x8(_mm_shuffle_epi8(vec.val, _mm_set_epi64x(0x0f0e0b0a0d0c0908, 0x0706030205040100))); +#else + __m128i a = _mm_shufflelo_epi16(vec.val, _MM_SHUFFLE(3, 1, 2, 0)); + return v_int16x8(_mm_shufflehi_epi16(a, _MM_SHUFFLE(3, 1, 2, 0))); +#endif +} +inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); } +inline v_int16x8 v_interleave_quads(const v_int16x8& vec) +{ +#if CV_SSSE3 + return v_int16x8(_mm_shuffle_epi8(vec.val, _mm_set_epi64x(0x0f0e07060d0c0504, 0x0b0a030209080100))); +#else + return v_int16x8(_mm_unpacklo_epi16(vec.val, _mm_unpackhi_epi64(vec.val, vec.val))); +#endif +} +inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_interleave_pairs(const v_int32x4& vec) +{ + return v_int32x4(_mm_shuffle_epi32(vec.val, _MM_SHUFFLE(3, 1, 2, 0))); +} +inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec) { return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } +inline v_float32x4 v_interleave_pairs(const v_float32x4& vec) { return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } + +inline v_int8x16 v_pack_triplets(const v_int8x16& vec) +{ +#if CV_SSSE3 + return v_int8x16(_mm_shuffle_epi8(vec.val, _mm_set_epi64x(0xffffff0f0e0d0c0a, 0x0908060504020100))); +#else + __m128i mask = _mm_set1_epi64x(0x00000000FFFFFFFF); + __m128i a = _mm_srli_si128(_mm_or_si128(_mm_andnot_si128(mask, vec.val), _mm_and_si128(mask, _mm_sll_epi32(vec.val, _mm_set_epi64x(0, 8)))), 1); + return v_int8x16(_mm_srli_si128(_mm_shufflelo_epi16(a, _MM_SHUFFLE(2, 1, 0, 3)), 2)); +#endif +} +inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); } + +inline v_int16x8 v_pack_triplets(const v_int16x8& vec) +{ +#if CV_SSSE3 + return v_int16x8(_mm_shuffle_epi8(vec.val, _mm_set_epi64x(0xffff0f0e0d0c0b0a, 0x0908050403020100))); +#else + return v_int16x8(_mm_srli_si128(_mm_shufflelo_epi16(vec.val, _MM_SHUFFLE(2, 1, 0, 3)), 2)); +#endif +} +inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_pack_triplets(const v_int32x4& vec) { return vec; } +inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) { return vec; } +inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; } + +////////////// FP16 support /////////////////////////// + +inline v_float32x4 v_load_expand(const float16_t* ptr) +{ +#if CV_FP16 + return v_float32x4(_mm_cvtph_ps(_mm_loadu_si128((const __m128i*)ptr))); +#else + const __m128i z = _mm_setzero_si128(), delta = _mm_set1_epi32(0x38000000); + const __m128i signmask = _mm_set1_epi32(0x80000000), maxexp = _mm_set1_epi32(0x7c000000); + const __m128 deltaf = _mm_castsi128_ps(_mm_set1_epi32(0x38800000)); + __m128i bits = _mm_unpacklo_epi16(z, _mm_loadl_epi64((const __m128i*)ptr)); // h << 16 + __m128i e = _mm_and_si128(bits, maxexp), sign = _mm_and_si128(bits, signmask); + __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_xor_si128(bits, sign), 3), delta); // ((h & 0x7fff) << 13) + delta + __m128i zt = _mm_castps_si128(_mm_sub_ps(_mm_castsi128_ps(_mm_add_epi32(t, _mm_set1_epi32(1 << 23))), deltaf)); + + t = _mm_add_epi32(t, _mm_and_si128(delta, _mm_cmpeq_epi32(maxexp, e))); + __m128i zmask = _mm_cmpeq_epi32(e, z); + __m128i ft = v_select_si128(zmask, zt, t); + return v_float32x4(_mm_castsi128_ps(_mm_or_si128(ft, sign))); +#endif +} + +inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +{ +#if CV_FP16 + __m128i fp16_value = _mm_cvtps_ph(v.val, 0); + _mm_storel_epi64((__m128i*)ptr, fp16_value); +#else + const __m128i signmask = _mm_set1_epi32(0x80000000); + const __m128i rval = _mm_set1_epi32(0x3f000000); + + __m128i t = _mm_castps_si128(v.val); + __m128i sign = _mm_srai_epi32(_mm_and_si128(t, signmask), 16); + t = _mm_andnot_si128(signmask, t); + + __m128i finitemask = _mm_cmpgt_epi32(_mm_set1_epi32(0x47800000), t); + __m128i isnan = _mm_cmpgt_epi32(t, _mm_set1_epi32(0x7f800000)); + __m128i naninf = v_select_si128(isnan, _mm_set1_epi32(0x7e00), _mm_set1_epi32(0x7c00)); + __m128i tinymask = _mm_cmpgt_epi32(_mm_set1_epi32(0x38800000), t); + __m128i tt = _mm_castps_si128(_mm_add_ps(_mm_castsi128_ps(t), _mm_castsi128_ps(rval))); + tt = _mm_sub_epi32(tt, rval); + __m128i odd = _mm_and_si128(_mm_srli_epi32(t, 13), _mm_set1_epi32(1)); + __m128i nt = _mm_add_epi32(t, _mm_set1_epi32(0xc8000fff)); + nt = _mm_srli_epi32(_mm_add_epi32(nt, odd), 13); + t = v_select_si128(tinymask, tt, nt); + t = v_select_si128(finitemask, t, naninf); + t = _mm_or_si128(t, sign); + t = _mm_packs_epi32(t, t); + _mm_storel_epi64((__m128i*)ptr, t); +#endif +} + +inline void v_cleanup() {} + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse_em.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse_em.hpp new file mode 100755 index 0000000..be27668 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_sse_em.hpp @@ -0,0 +1,167 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#ifndef OPENCV_HAL_INTRIN_SSE_EM_HPP +#define OPENCV_HAL_INTRIN_SSE_EM_HPP + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +#define OPENCV_HAL_SSE_WRAP_1(fun, tp) \ + inline tp _v128_##fun(const tp& a) \ + { return _mm_##fun(a); } + +#define OPENCV_HAL_SSE_WRAP_2(fun, tp) \ + inline tp _v128_##fun(const tp& a, const tp& b) \ + { return _mm_##fun(a, b); } + +#define OPENCV_HAL_SSE_WRAP_3(fun, tp) \ + inline tp _v128_##fun(const tp& a, const tp& b, const tp& c) \ + { return _mm_##fun(a, b, c); } + +///////////////////////////// XOP ///////////////////////////// + +// [todo] define CV_XOP +#if 1 // CV_XOP +inline __m128i _v128_comgt_epu32(const __m128i& a, const __m128i& b) +{ + const __m128i delta = _mm_set1_epi32((int)0x80000000); + return _mm_cmpgt_epi32(_mm_xor_si128(a, delta), _mm_xor_si128(b, delta)); +} +// wrapping XOP +#else +OPENCV_HAL_SSE_WRAP_2(_v128_comgt_epu32, __m128i) +#endif // !CV_XOP + +///////////////////////////// SSE4.1 ///////////////////////////// + +#if !CV_SSE4_1 + +/** Swizzle **/ +inline __m128i _v128_blendv_epi8(const __m128i& a, const __m128i& b, const __m128i& mask) +{ return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(b, a), mask)); } + +/** Convert **/ +// 8 >> 16 +inline __m128i _v128_cvtepu8_epi16(const __m128i& a) +{ + const __m128i z = _mm_setzero_si128(); + return _mm_unpacklo_epi8(a, z); +} +inline __m128i _v128_cvtepi8_epi16(const __m128i& a) +{ return _mm_srai_epi16(_mm_unpacklo_epi8(a, a), 8); } +// 8 >> 32 +inline __m128i _v128_cvtepu8_epi32(const __m128i& a) +{ + const __m128i z = _mm_setzero_si128(); + return _mm_unpacklo_epi16(_mm_unpacklo_epi8(a, z), z); +} +inline __m128i _v128_cvtepi8_epi32(const __m128i& a) +{ + __m128i r = _mm_unpacklo_epi8(a, a); + r = _mm_unpacklo_epi8(r, r); + return _mm_srai_epi32(r, 24); +} +// 16 >> 32 +inline __m128i _v128_cvtepu16_epi32(const __m128i& a) +{ + const __m128i z = _mm_setzero_si128(); + return _mm_unpacklo_epi16(a, z); +} +inline __m128i _v128_cvtepi16_epi32(const __m128i& a) +{ return _mm_srai_epi32(_mm_unpacklo_epi16(a, a), 16); } +// 32 >> 64 +inline __m128i _v128_cvtepu32_epi64(const __m128i& a) +{ + const __m128i z = _mm_setzero_si128(); + return _mm_unpacklo_epi32(a, z); +} +inline __m128i _v128_cvtepi32_epi64(const __m128i& a) +{ return _mm_unpacklo_epi32(a, _mm_srai_epi32(a, 31)); } + +/** Arithmetic **/ +inline __m128i _v128_mullo_epi32(const __m128i& a, const __m128i& b) +{ + __m128i c0 = _mm_mul_epu32(a, b); + __m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a, 32), _mm_srli_epi64(b, 32)); + __m128i d0 = _mm_unpacklo_epi32(c0, c1); + __m128i d1 = _mm_unpackhi_epi32(c0, c1); + return _mm_unpacklo_epi64(d0, d1); +} + +/** Math **/ +inline __m128i _v128_min_epu32(const __m128i& a, const __m128i& b) +{ return _v128_blendv_epi8(a, b, _v128_comgt_epu32(a, b)); } + +// wrapping SSE4.1 +#else +OPENCV_HAL_SSE_WRAP_1(cvtepu8_epi16, __m128i) +OPENCV_HAL_SSE_WRAP_1(cvtepi8_epi16, __m128i) +OPENCV_HAL_SSE_WRAP_1(cvtepu8_epi32, __m128i) +OPENCV_HAL_SSE_WRAP_1(cvtepi8_epi32, __m128i) +OPENCV_HAL_SSE_WRAP_1(cvtepu16_epi32, __m128i) +OPENCV_HAL_SSE_WRAP_1(cvtepi16_epi32, __m128i) +OPENCV_HAL_SSE_WRAP_1(cvtepu32_epi64, __m128i) +OPENCV_HAL_SSE_WRAP_1(cvtepi32_epi64, __m128i) +OPENCV_HAL_SSE_WRAP_2(min_epu32, __m128i) +OPENCV_HAL_SSE_WRAP_2(mullo_epi32, __m128i) +OPENCV_HAL_SSE_WRAP_3(blendv_epi8, __m128i) +#endif // !CV_SSE4_1 + +///////////////////////////// Revolutionary ///////////////////////////// + +/** Convert **/ +// 16 << 8 +inline __m128i _v128_cvtepu8_epi16_high(const __m128i& a) +{ + const __m128i z = _mm_setzero_si128(); + return _mm_unpackhi_epi8(a, z); +} +inline __m128i _v128_cvtepi8_epi16_high(const __m128i& a) +{ return _mm_srai_epi16(_mm_unpackhi_epi8(a, a), 8); } +// 32 << 16 +inline __m128i _v128_cvtepu16_epi32_high(const __m128i& a) +{ + const __m128i z = _mm_setzero_si128(); + return _mm_unpackhi_epi16(a, z); +} +inline __m128i _v128_cvtepi16_epi32_high(const __m128i& a) +{ return _mm_srai_epi32(_mm_unpackhi_epi16(a, a), 16); } +// 64 << 32 +inline __m128i _v128_cvtepu32_epi64_high(const __m128i& a) +{ + const __m128i z = _mm_setzero_si128(); + return _mm_unpackhi_epi32(a, z); +} +inline __m128i _v128_cvtepi32_epi64_high(const __m128i& a) +{ return _mm_unpackhi_epi32(a, _mm_srai_epi32(a, 31)); } + +/** Miscellaneous **/ +inline __m128i _v128_packs_epu32(const __m128i& a, const __m128i& b) +{ + const __m128i m = _mm_set1_epi32(65535); + __m128i am = _v128_min_epu32(a, m); + __m128i bm = _v128_min_epu32(b, m); +#if CV_SSE4_1 + return _mm_packus_epi32(am, bm); +#else + const __m128i d = _mm_set1_epi32(32768), nd = _mm_set1_epi16(-32768); + am = _mm_sub_epi32(am, d); + bm = _mm_sub_epi32(bm, d); + am = _mm_packs_epi32(am, bm); + return _mm_sub_epi16(am, nd); +#endif +} + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} // cv:: + +#endif // OPENCV_HAL_INTRIN_SSE_EM_HPP \ No newline at end of file diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_vsx.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_vsx.hpp new file mode 100755 index 0000000..a4d2c29 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/hal/intrin_vsx.hpp @@ -0,0 +1,1375 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#ifndef OPENCV_HAL_VSX_HPP +#define OPENCV_HAL_VSX_HPP + +#include +#include "opencv2/core/utility.hpp" + +#define CV_SIMD128 1 +#define CV_SIMD128_64F 1 + +namespace cv +{ + +//! @cond IGNORED + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN + +///////// Types //////////// + +struct v_uint8x16 +{ + typedef uchar lane_type; + enum { nlanes = 16 }; + vec_uchar16 val; + + explicit v_uint8x16(const vec_uchar16& v) : val(v) + {} + v_uint8x16() : val(vec_uchar16_z) + {} + v_uint8x16(vec_bchar16 v) : val(vec_uchar16_c(v)) + {} + v_uint8x16(uchar v0, uchar v1, uchar v2, uchar v3, uchar v4, uchar v5, uchar v6, uchar v7, + uchar v8, uchar v9, uchar v10, uchar v11, uchar v12, uchar v13, uchar v14, uchar v15) + : val(vec_uchar16_set(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)) + {} + uchar get0() const + { return vec_extract(val, 0); } +}; + +struct v_int8x16 +{ + typedef schar lane_type; + enum { nlanes = 16 }; + vec_char16 val; + + explicit v_int8x16(const vec_char16& v) : val(v) + {} + v_int8x16() : val(vec_char16_z) + {} + v_int8x16(vec_bchar16 v) : val(vec_char16_c(v)) + {} + v_int8x16(schar v0, schar v1, schar v2, schar v3, schar v4, schar v5, schar v6, schar v7, + schar v8, schar v9, schar v10, schar v11, schar v12, schar v13, schar v14, schar v15) + : val(vec_char16_set(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)) + {} + schar get0() const + { return vec_extract(val, 0); } +}; + +struct v_uint16x8 +{ + typedef ushort lane_type; + enum { nlanes = 8 }; + vec_ushort8 val; + + explicit v_uint16x8(const vec_ushort8& v) : val(v) + {} + v_uint16x8() : val(vec_ushort8_z) + {} + v_uint16x8(vec_bshort8 v) : val(vec_ushort8_c(v)) + {} + v_uint16x8(ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5, ushort v6, ushort v7) + : val(vec_ushort8_set(v0, v1, v2, v3, v4, v5, v6, v7)) + {} + ushort get0() const + { return vec_extract(val, 0); } +}; + +struct v_int16x8 +{ + typedef short lane_type; + enum { nlanes = 8 }; + vec_short8 val; + + explicit v_int16x8(const vec_short8& v) : val(v) + {} + v_int16x8() : val(vec_short8_z) + {} + v_int16x8(vec_bshort8 v) : val(vec_short8_c(v)) + {} + v_int16x8(short v0, short v1, short v2, short v3, short v4, short v5, short v6, short v7) + : val(vec_short8_set(v0, v1, v2, v3, v4, v5, v6, v7)) + {} + short get0() const + { return vec_extract(val, 0); } +}; + +struct v_uint32x4 +{ + typedef unsigned lane_type; + enum { nlanes = 4 }; + vec_uint4 val; + + explicit v_uint32x4(const vec_uint4& v) : val(v) + {} + v_uint32x4() : val(vec_uint4_z) + {} + v_uint32x4(vec_bint4 v) : val(vec_uint4_c(v)) + {} + v_uint32x4(unsigned v0, unsigned v1, unsigned v2, unsigned v3) : val(vec_uint4_set(v0, v1, v2, v3)) + {} + uint get0() const + { return vec_extract(val, 0); } +}; + +struct v_int32x4 +{ + typedef int lane_type; + enum { nlanes = 4 }; + vec_int4 val; + + explicit v_int32x4(const vec_int4& v) : val(v) + {} + v_int32x4() : val(vec_int4_z) + {} + v_int32x4(vec_bint4 v) : val(vec_int4_c(v)) + {} + v_int32x4(int v0, int v1, int v2, int v3) : val(vec_int4_set(v0, v1, v2, v3)) + {} + int get0() const + { return vec_extract(val, 0); } +}; + +struct v_float32x4 +{ + typedef float lane_type; + enum { nlanes = 4 }; + vec_float4 val; + + explicit v_float32x4(const vec_float4& v) : val(v) + {} + v_float32x4() : val(vec_float4_z) + {} + v_float32x4(vec_bint4 v) : val(vec_float4_c(v)) + {} + v_float32x4(float v0, float v1, float v2, float v3) : val(vec_float4_set(v0, v1, v2, v3)) + {} + float get0() const + { return vec_extract(val, 0); } +}; + +struct v_uint64x2 +{ + typedef uint64 lane_type; + enum { nlanes = 2 }; + vec_udword2 val; + + explicit v_uint64x2(const vec_udword2& v) : val(v) + {} + v_uint64x2() : val(vec_udword2_z) + {} + v_uint64x2(vec_bdword2 v) : val(vec_udword2_c(v)) + {} + v_uint64x2(uint64 v0, uint64 v1) : val(vec_udword2_set(v0, v1)) + {} + uint64 get0() const + { return vec_extract(val, 0); } +}; + +struct v_int64x2 +{ + typedef int64 lane_type; + enum { nlanes = 2 }; + vec_dword2 val; + + explicit v_int64x2(const vec_dword2& v) : val(v) + {} + v_int64x2() : val(vec_dword2_z) + {} + v_int64x2(vec_bdword2 v) : val(vec_dword2_c(v)) + {} + v_int64x2(int64 v0, int64 v1) : val(vec_dword2_set(v0, v1)) + {} + int64 get0() const + { return vec_extract(val, 0); } +}; + +struct v_float64x2 +{ + typedef double lane_type; + enum { nlanes = 2 }; + vec_double2 val; + + explicit v_float64x2(const vec_double2& v) : val(v) + {} + v_float64x2() : val(vec_double2_z) + {} + v_float64x2(vec_bdword2 v) : val(vec_double2_c(v)) + {} + v_float64x2(double v0, double v1) : val(vec_double2_set(v0, v1)) + {} + double get0() const + { return vec_extract(val, 0); } +}; + +//////////////// Load and store operations /////////////// + +/* + * clang-5 aborted during parse "vec_xxx_c" only if it's + * inside a function template which is defined by preprocessor macro. + * + * if vec_xxx_c defined as C++ cast, clang-5 will pass it +*/ +#define OPENCV_HAL_IMPL_VSX_INITVEC(_Tpvec, _Tp, suffix, cast) \ +inline _Tpvec v_setzero_##suffix() { return _Tpvec(); } \ +inline _Tpvec v_setall_##suffix(_Tp v) { return _Tpvec(vec_splats((_Tp)v));} \ +template inline _Tpvec v_reinterpret_as_##suffix(const _Tpvec0 &a) \ +{ return _Tpvec((cast)a.val); } + +OPENCV_HAL_IMPL_VSX_INITVEC(v_uint8x16, uchar, u8, vec_uchar16) +OPENCV_HAL_IMPL_VSX_INITVEC(v_int8x16, schar, s8, vec_char16) +OPENCV_HAL_IMPL_VSX_INITVEC(v_uint16x8, ushort, u16, vec_ushort8) +OPENCV_HAL_IMPL_VSX_INITVEC(v_int16x8, short, s16, vec_short8) +OPENCV_HAL_IMPL_VSX_INITVEC(v_uint32x4, uint, u32, vec_uint4) +OPENCV_HAL_IMPL_VSX_INITVEC(v_int32x4, int, s32, vec_int4) +OPENCV_HAL_IMPL_VSX_INITVEC(v_uint64x2, uint64, u64, vec_udword2) +OPENCV_HAL_IMPL_VSX_INITVEC(v_int64x2, int64, s64, vec_dword2) +OPENCV_HAL_IMPL_VSX_INITVEC(v_float32x4, float, f32, vec_float4) +OPENCV_HAL_IMPL_VSX_INITVEC(v_float64x2, double, f64, vec_double2) + +#define OPENCV_HAL_IMPL_VSX_LOADSTORE_C(_Tpvec, _Tp, ld, ld_a, st, st_a) \ +inline _Tpvec v_load(const _Tp* ptr) \ +{ return _Tpvec(ld(0, ptr)); } \ +inline _Tpvec v_load_aligned(VSX_UNUSED(const _Tp* ptr)) \ +{ return _Tpvec(ld_a(0, ptr)); } \ +inline _Tpvec v_load_low(const _Tp* ptr) \ +{ return _Tpvec(vec_ld_l8(ptr)); } \ +inline _Tpvec v_load_halves(const _Tp* ptr0, const _Tp* ptr1) \ +{ return _Tpvec(vec_mergesqh(vec_ld_l8(ptr0), vec_ld_l8(ptr1))); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a) \ +{ st(a.val, 0, ptr); } \ +inline void v_store_aligned(VSX_UNUSED(_Tp* ptr), const _Tpvec& a) \ +{ st_a(a.val, 0, ptr); } \ +inline void v_store_aligned_nocache(VSX_UNUSED(_Tp* ptr), const _Tpvec& a) \ +{ st_a(a.val, 0, ptr); } \ +inline void v_store(_Tp* ptr, const _Tpvec& a, hal::StoreMode mode) \ +{ if(mode == hal::STORE_UNALIGNED) st(a.val, 0, ptr); else st_a(a.val, 0, ptr); } \ +inline void v_store_low(_Tp* ptr, const _Tpvec& a) \ +{ vec_st_l8(a.val, ptr); } \ +inline void v_store_high(_Tp* ptr, const _Tpvec& a) \ +{ vec_st_h8(a.val, ptr); } + +// working around gcc bug for aligned ld/st +// if runtime check for vec_ld/st fail we failback to unaligned ld/st +// https://github.com/opencv/opencv/issues/13211 +#ifdef CV_COMPILER_VSX_BROKEN_ALIGNED + #define OPENCV_HAL_IMPL_VSX_LOADSTORE(_Tpvec, _Tp) \ + OPENCV_HAL_IMPL_VSX_LOADSTORE_C(_Tpvec, _Tp, vsx_ld, vsx_ld, vsx_st, vsx_st) +#else + #define OPENCV_HAL_IMPL_VSX_LOADSTORE(_Tpvec, _Tp) \ + OPENCV_HAL_IMPL_VSX_LOADSTORE_C(_Tpvec, _Tp, vsx_ld, vec_ld, vsx_st, vec_st) +#endif + +OPENCV_HAL_IMPL_VSX_LOADSTORE(v_uint8x16, uchar) +OPENCV_HAL_IMPL_VSX_LOADSTORE(v_int8x16, schar) +OPENCV_HAL_IMPL_VSX_LOADSTORE(v_uint16x8, ushort) +OPENCV_HAL_IMPL_VSX_LOADSTORE(v_int16x8, short) +OPENCV_HAL_IMPL_VSX_LOADSTORE(v_uint32x4, uint) +OPENCV_HAL_IMPL_VSX_LOADSTORE(v_int32x4, int) +OPENCV_HAL_IMPL_VSX_LOADSTORE(v_float32x4, float) + +OPENCV_HAL_IMPL_VSX_LOADSTORE_C(v_float64x2, double, vsx_ld, vsx_ld, vsx_st, vsx_st) +OPENCV_HAL_IMPL_VSX_LOADSTORE_C(v_uint64x2, uint64, vsx_ld2, vsx_ld2, vsx_st2, vsx_st2) +OPENCV_HAL_IMPL_VSX_LOADSTORE_C(v_int64x2, int64, vsx_ld2, vsx_ld2, vsx_st2, vsx_st2) + +//////////////// Value reordering /////////////// + +/* de&interleave */ +#define OPENCV_HAL_IMPL_VSX_INTERLEAVE(_Tp, _Tpvec) \ +inline void v_load_deinterleave(const _Tp* ptr, _Tpvec& a, _Tpvec& b) \ +{ vec_ld_deinterleave(ptr, a.val, b.val);} \ +inline void v_load_deinterleave(const _Tp* ptr, _Tpvec& a, \ + _Tpvec& b, _Tpvec& c) \ +{ vec_ld_deinterleave(ptr, a.val, b.val, c.val); } \ +inline void v_load_deinterleave(const _Tp* ptr, _Tpvec& a, _Tpvec& b, \ + _Tpvec& c, _Tpvec& d) \ +{ vec_ld_deinterleave(ptr, a.val, b.val, c.val, d.val); } \ +inline void v_store_interleave(_Tp* ptr, const _Tpvec& a, const _Tpvec& b, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ vec_st_interleave(a.val, b.val, ptr); } \ +inline void v_store_interleave(_Tp* ptr, const _Tpvec& a, \ + const _Tpvec& b, const _Tpvec& c, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ vec_st_interleave(a.val, b.val, c.val, ptr); } \ +inline void v_store_interleave(_Tp* ptr, const _Tpvec& a, const _Tpvec& b, \ + const _Tpvec& c, const _Tpvec& d, \ + hal::StoreMode /*mode*/=hal::STORE_UNALIGNED) \ +{ vec_st_interleave(a.val, b.val, c.val, d.val, ptr); } + +OPENCV_HAL_IMPL_VSX_INTERLEAVE(uchar, v_uint8x16) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(schar, v_int8x16) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(ushort, v_uint16x8) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(short, v_int16x8) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(uint, v_uint32x4) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(int, v_int32x4) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(float, v_float32x4) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(double, v_float64x2) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(int64, v_int64x2) +OPENCV_HAL_IMPL_VSX_INTERLEAVE(uint64, v_uint64x2) + +/* Expand */ +#define OPENCV_HAL_IMPL_VSX_EXPAND(_Tpvec, _Tpwvec, _Tp, fl, fh) \ +inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \ +{ \ + b0.val = fh(a.val); \ + b1.val = fl(a.val); \ +} \ +inline _Tpwvec v_expand_low(const _Tpvec& a) \ +{ return _Tpwvec(fh(a.val)); } \ +inline _Tpwvec v_expand_high(const _Tpvec& a) \ +{ return _Tpwvec(fl(a.val)); } \ +inline _Tpwvec v_load_expand(const _Tp* ptr) \ +{ return _Tpwvec(fh(vec_ld_l8(ptr))); } + +OPENCV_HAL_IMPL_VSX_EXPAND(v_uint8x16, v_uint16x8, uchar, vec_unpacklu, vec_unpackhu) +OPENCV_HAL_IMPL_VSX_EXPAND(v_int8x16, v_int16x8, schar, vec_unpackl, vec_unpackh) +OPENCV_HAL_IMPL_VSX_EXPAND(v_uint16x8, v_uint32x4, ushort, vec_unpacklu, vec_unpackhu) +OPENCV_HAL_IMPL_VSX_EXPAND(v_int16x8, v_int32x4, short, vec_unpackl, vec_unpackh) +OPENCV_HAL_IMPL_VSX_EXPAND(v_uint32x4, v_uint64x2, uint, vec_unpacklu, vec_unpackhu) +OPENCV_HAL_IMPL_VSX_EXPAND(v_int32x4, v_int64x2, int, vec_unpackl, vec_unpackh) + +inline v_uint32x4 v_load_expand_q(const uchar* ptr) +{ return v_uint32x4(vec_uint4_set(ptr[0], ptr[1], ptr[2], ptr[3])); } + +inline v_int32x4 v_load_expand_q(const schar* ptr) +{ return v_int32x4(vec_int4_set(ptr[0], ptr[1], ptr[2], ptr[3])); } + +/* pack */ +#define OPENCV_HAL_IMPL_VSX_PACK(_Tpvec, _Tp, _Tpwvec, _Tpvn, _Tpdel, sfnc, pkfnc, addfnc, pack) \ +inline _Tpvec v_##pack(const _Tpwvec& a, const _Tpwvec& b) \ +{ \ + return _Tpvec(pkfnc(a.val, b.val)); \ +} \ +inline void v_##pack##_store(_Tp* ptr, const _Tpwvec& a) \ +{ \ + vec_st_l8(pkfnc(a.val, a.val), ptr); \ +} \ +template \ +inline _Tpvec v_rshr_##pack(const _Tpwvec& a, const _Tpwvec& b) \ +{ \ + const __vector _Tpvn vn = vec_splats((_Tpvn)n); \ + const __vector _Tpdel delta = vec_splats((_Tpdel)((_Tpdel)1 << (n-1))); \ + return _Tpvec(pkfnc(sfnc(addfnc(a.val, delta), vn), sfnc(addfnc(b.val, delta), vn))); \ +} \ +template \ +inline void v_rshr_##pack##_store(_Tp* ptr, const _Tpwvec& a) \ +{ \ + const __vector _Tpvn vn = vec_splats((_Tpvn)n); \ + const __vector _Tpdel delta = vec_splats((_Tpdel)((_Tpdel)1 << (n-1))); \ + vec_st_l8(pkfnc(sfnc(addfnc(a.val, delta), vn), delta), ptr); \ +} + +OPENCV_HAL_IMPL_VSX_PACK(v_uint8x16, uchar, v_uint16x8, unsigned short, unsigned short, + vec_sr, vec_packs, vec_adds, pack) +OPENCV_HAL_IMPL_VSX_PACK(v_int8x16, schar, v_int16x8, unsigned short, short, + vec_sra, vec_packs, vec_adds, pack) + +OPENCV_HAL_IMPL_VSX_PACK(v_uint16x8, ushort, v_uint32x4, unsigned int, unsigned int, + vec_sr, vec_packs, vec_add, pack) +OPENCV_HAL_IMPL_VSX_PACK(v_int16x8, short, v_int32x4, unsigned int, int, + vec_sra, vec_packs, vec_add, pack) + +OPENCV_HAL_IMPL_VSX_PACK(v_uint32x4, uint, v_uint64x2, unsigned long long, unsigned long long, + vec_sr, vec_pack, vec_add, pack) +OPENCV_HAL_IMPL_VSX_PACK(v_int32x4, int, v_int64x2, unsigned long long, long long, + vec_sra, vec_pack, vec_add, pack) + +OPENCV_HAL_IMPL_VSX_PACK(v_uint8x16, uchar, v_int16x8, unsigned short, short, + vec_sra, vec_packsu, vec_adds, pack_u) +OPENCV_HAL_IMPL_VSX_PACK(v_uint16x8, ushort, v_int32x4, unsigned int, int, + vec_sra, vec_packsu, vec_add, pack_u) +// Following variant is not implemented on other platforms: +//OPENCV_HAL_IMPL_VSX_PACK(v_uint32x4, uint, v_int64x2, unsigned long long, long long, +// vec_sra, vec_packsu, vec_add, pack_u) + +// pack boolean +inline v_uint8x16 v_pack_b(const v_uint16x8& a, const v_uint16x8& b) +{ + vec_uchar16 ab = vec_pack(a.val, b.val); + return v_uint8x16(ab); +} + +inline v_uint8x16 v_pack_b(const v_uint32x4& a, const v_uint32x4& b, + const v_uint32x4& c, const v_uint32x4& d) +{ + vec_ushort8 ab = vec_pack(a.val, b.val); + vec_ushort8 cd = vec_pack(c.val, d.val); + return v_uint8x16(vec_pack(ab, cd)); +} + +inline v_uint8x16 v_pack_b(const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c, + const v_uint64x2& d, const v_uint64x2& e, const v_uint64x2& f, + const v_uint64x2& g, const v_uint64x2& h) +{ + vec_uint4 ab = vec_pack(a.val, b.val); + vec_uint4 cd = vec_pack(c.val, d.val); + vec_uint4 ef = vec_pack(e.val, f.val); + vec_uint4 gh = vec_pack(g.val, h.val); + + vec_ushort8 abcd = vec_pack(ab, cd); + vec_ushort8 efgh = vec_pack(ef, gh); + return v_uint8x16(vec_pack(abcd, efgh)); +} + +/* Recombine */ +template +inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, _Tpvec& b0, _Tpvec& b1) +{ + b0.val = vec_mergeh(a0.val, a1.val); + b1.val = vec_mergel(a0.val, a1.val); +} + +template +inline _Tpvec v_combine_high(const _Tpvec& a, const _Tpvec& b) +{ return _Tpvec(vec_mergesql(a.val, b.val)); } + +template +inline _Tpvec v_combine_low(const _Tpvec& a, const _Tpvec& b) +{ return _Tpvec(vec_mergesqh(a.val, b.val)); } + +template +inline void v_recombine(const _Tpvec& a, const _Tpvec& b, _Tpvec& c, _Tpvec& d) +{ + c.val = vec_mergesqh(a.val, b.val); + d.val = vec_mergesql(a.val, b.val); +} + +////////// Arithmetic, bitwise and comparison operations ///////// + +/* Element-wise binary and unary operations */ +/** Arithmetics **/ +#define OPENCV_HAL_IMPL_VSX_BIN_OP(bin_op, _Tpvec, intrin) \ +inline _Tpvec operator bin_op (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(intrin(a.val, b.val)); } \ +inline _Tpvec& operator bin_op##= (_Tpvec& a, const _Tpvec& b) \ +{ a.val = intrin(a.val, b.val); return a; } + +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_uint8x16, vec_adds) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_uint8x16, vec_subs) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_int8x16, vec_adds) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_int8x16, vec_subs) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_uint16x8, vec_adds) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_uint16x8, vec_subs) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_int16x8, vec_adds) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_int16x8, vec_subs) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_uint32x4, vec_add) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_uint32x4, vec_sub) +OPENCV_HAL_IMPL_VSX_BIN_OP(*, v_uint32x4, vec_mul) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_int32x4, vec_add) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_int32x4, vec_sub) +OPENCV_HAL_IMPL_VSX_BIN_OP(*, v_int32x4, vec_mul) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_float32x4, vec_add) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_float32x4, vec_sub) +OPENCV_HAL_IMPL_VSX_BIN_OP(*, v_float32x4, vec_mul) +OPENCV_HAL_IMPL_VSX_BIN_OP(/, v_float32x4, vec_div) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_float64x2, vec_add) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_float64x2, vec_sub) +OPENCV_HAL_IMPL_VSX_BIN_OP(*, v_float64x2, vec_mul) +OPENCV_HAL_IMPL_VSX_BIN_OP(/, v_float64x2, vec_div) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_uint64x2, vec_add) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_uint64x2, vec_sub) +OPENCV_HAL_IMPL_VSX_BIN_OP(+, v_int64x2, vec_add) +OPENCV_HAL_IMPL_VSX_BIN_OP(-, v_int64x2, vec_sub) + +// saturating multiply +#define OPENCV_HAL_IMPL_VSX_MUL_SAT(_Tpvec, _Tpwvec) \ + inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \ + { \ + _Tpwvec c, d; \ + v_mul_expand(a, b, c, d); \ + return v_pack(c, d); \ + } \ + inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \ + { a = a * b; return a; } + +OPENCV_HAL_IMPL_VSX_MUL_SAT(v_int8x16, v_int16x8) +OPENCV_HAL_IMPL_VSX_MUL_SAT(v_uint8x16, v_uint16x8) +OPENCV_HAL_IMPL_VSX_MUL_SAT(v_int16x8, v_int32x4) +OPENCV_HAL_IMPL_VSX_MUL_SAT(v_uint16x8, v_uint32x4) + +template +inline void v_mul_expand(const Tvec& a, const Tvec& b, Twvec& c, Twvec& d) +{ + Twvec p0 = Twvec(vec_mule(a.val, b.val)); + Twvec p1 = Twvec(vec_mulo(a.val, b.val)); + v_zip(p0, p1, c, d); +} + +inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, v_uint64x2& c, v_uint64x2& d) +{ + c.val = vec_mul(vec_unpackhu(a.val), vec_unpackhu(b.val)); + d.val = vec_mul(vec_unpacklu(a.val), vec_unpacklu(b.val)); +} + +inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b) +{ + vec_int4 p0 = vec_mule(a.val, b.val); + vec_int4 p1 = vec_mulo(a.val, b.val); + static const vec_uchar16 perm = {2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31}; + return v_int16x8(vec_perm(vec_short8_c(p0), vec_short8_c(p1), perm)); +} +inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b) +{ + vec_uint4 p0 = vec_mule(a.val, b.val); + vec_uint4 p1 = vec_mulo(a.val, b.val); + static const vec_uchar16 perm = {2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31}; + return v_uint16x8(vec_perm(vec_ushort8_c(p0), vec_ushort8_c(p1), perm)); +} + +/** Non-saturating arithmetics **/ +#define OPENCV_HAL_IMPL_VSX_BIN_FUNC(func, intrin) \ +template \ +inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(intrin(a.val, b.val)); } + +OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_add_wrap, vec_add) +OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_sub_wrap, vec_sub) +OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_mul_wrap, vec_mul) + +/** Bitwise shifts **/ +#define OPENCV_HAL_IMPL_VSX_SHIFT_OP(_Tpvec, shr, splfunc) \ +inline _Tpvec operator << (const _Tpvec& a, int imm) \ +{ return _Tpvec(vec_sl(a.val, splfunc(imm))); } \ +inline _Tpvec operator >> (const _Tpvec& a, int imm) \ +{ return _Tpvec(shr(a.val, splfunc(imm))); } \ +template inline _Tpvec v_shl(const _Tpvec& a) \ +{ return _Tpvec(vec_sl(a.val, splfunc(imm))); } \ +template inline _Tpvec v_shr(const _Tpvec& a) \ +{ return _Tpvec(shr(a.val, splfunc(imm))); } + +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_uint8x16, vec_sr, vec_uchar16_sp) +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_uint16x8, vec_sr, vec_ushort8_sp) +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_uint32x4, vec_sr, vec_uint4_sp) +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_uint64x2, vec_sr, vec_udword2_sp) +// algebraic right shift +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_int8x16, vec_sra, vec_uchar16_sp) +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_int16x8, vec_sra, vec_ushort8_sp) +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_int32x4, vec_sra, vec_uint4_sp) +OPENCV_HAL_IMPL_VSX_SHIFT_OP(v_int64x2, vec_sra, vec_udword2_sp) + +/** Bitwise logic **/ +#define OPENCV_HAL_IMPL_VSX_LOGIC_OP(_Tpvec) \ +OPENCV_HAL_IMPL_VSX_BIN_OP(&, _Tpvec, vec_and) \ +OPENCV_HAL_IMPL_VSX_BIN_OP(|, _Tpvec, vec_or) \ +OPENCV_HAL_IMPL_VSX_BIN_OP(^, _Tpvec, vec_xor) \ +inline _Tpvec operator ~ (const _Tpvec& a) \ +{ return _Tpvec(vec_not(a.val)); } + +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_uint8x16) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_int8x16) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_uint16x8) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_int16x8) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_uint32x4) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_int32x4) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_uint64x2) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_int64x2) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_float32x4) +OPENCV_HAL_IMPL_VSX_LOGIC_OP(v_float64x2) + +/** Bitwise select **/ +#define OPENCV_HAL_IMPL_VSX_SELECT(_Tpvec, cast) \ +inline _Tpvec v_select(const _Tpvec& mask, const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_sel(b.val, a.val, cast(mask.val))); } + +OPENCV_HAL_IMPL_VSX_SELECT(v_uint8x16, vec_bchar16_c) +OPENCV_HAL_IMPL_VSX_SELECT(v_int8x16, vec_bchar16_c) +OPENCV_HAL_IMPL_VSX_SELECT(v_uint16x8, vec_bshort8_c) +OPENCV_HAL_IMPL_VSX_SELECT(v_int16x8, vec_bshort8_c) +OPENCV_HAL_IMPL_VSX_SELECT(v_uint32x4, vec_bint4_c) +OPENCV_HAL_IMPL_VSX_SELECT(v_int32x4, vec_bint4_c) +OPENCV_HAL_IMPL_VSX_SELECT(v_float32x4, vec_bint4_c) +OPENCV_HAL_IMPL_VSX_SELECT(v_float64x2, vec_bdword2_c) + +/** Comparison **/ +#define OPENCV_HAL_IMPL_VSX_INT_CMP_OP(_Tpvec) \ +inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_cmpeq(a.val, b.val)); } \ +inline _Tpvec operator != (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_cmpne(a.val, b.val)); } \ +inline _Tpvec operator < (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_cmplt(a.val, b.val)); } \ +inline _Tpvec operator > (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_cmpgt(a.val, b.val)); } \ +inline _Tpvec operator <= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_cmple(a.val, b.val)); } \ +inline _Tpvec operator >= (const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_cmpge(a.val, b.val)); } + +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_uint8x16) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_int8x16) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_uint16x8) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_int16x8) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_uint32x4) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_int32x4) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_float32x4) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_float64x2) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_uint64x2) +OPENCV_HAL_IMPL_VSX_INT_CMP_OP(v_int64x2) + +inline v_float32x4 v_not_nan(const v_float32x4& a) +{ return v_float32x4(vec_cmpeq(a.val, a.val)); } +inline v_float64x2 v_not_nan(const v_float64x2& a) +{ return v_float64x2(vec_cmpeq(a.val, a.val)); } + +/** min/max **/ +OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_min, vec_min) +OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_max, vec_max) + +/** Rotate **/ +#define OPENCV_IMPL_VSX_ROTATE(_Tpvec, suffix, shf, cast) \ +template \ +inline _Tpvec v_rotate_##suffix(const _Tpvec& a) \ +{ \ + const int wd = imm * sizeof(typename _Tpvec::lane_type); \ + if (wd > 15) \ + return _Tpvec(); \ + return _Tpvec((cast)shf(vec_uchar16_c(a.val), vec_uchar16_sp(wd << 3))); \ +} + +#define OPENCV_IMPL_VSX_ROTATE_LR(_Tpvec, cast) \ +OPENCV_IMPL_VSX_ROTATE(_Tpvec, left, vec_slo, cast) \ +OPENCV_IMPL_VSX_ROTATE(_Tpvec, right, vec_sro, cast) + +OPENCV_IMPL_VSX_ROTATE_LR(v_uint8x16, vec_uchar16) +OPENCV_IMPL_VSX_ROTATE_LR(v_int8x16, vec_char16) +OPENCV_IMPL_VSX_ROTATE_LR(v_uint16x8, vec_ushort8) +OPENCV_IMPL_VSX_ROTATE_LR(v_int16x8, vec_short8) +OPENCV_IMPL_VSX_ROTATE_LR(v_uint32x4, vec_uint4) +OPENCV_IMPL_VSX_ROTATE_LR(v_int32x4, vec_int4) +OPENCV_IMPL_VSX_ROTATE_LR(v_float32x4, vec_float4) +OPENCV_IMPL_VSX_ROTATE_LR(v_uint64x2, vec_udword2) +OPENCV_IMPL_VSX_ROTATE_LR(v_int64x2, vec_dword2) +OPENCV_IMPL_VSX_ROTATE_LR(v_float64x2, vec_double2) + +template +inline _Tpvec v_rotate_right(const _Tpvec& a, const _Tpvec& b) +{ + enum { CV_SHIFT = 16 - imm * (sizeof(typename _Tpvec::lane_type)) }; + if (CV_SHIFT == 16) + return a; +#ifdef __IBMCPP__ + return _Tpvec(vec_sld(b.val, a.val, CV_SHIFT & 15)); +#else + return _Tpvec(vec_sld(b.val, a.val, CV_SHIFT)); +#endif +} + +template +inline _Tpvec v_rotate_left(const _Tpvec& a, const _Tpvec& b) +{ + enum { CV_SHIFT = imm * (sizeof(typename _Tpvec::lane_type)) }; + if (CV_SHIFT == 16) + return b; + return _Tpvec(vec_sld(a.val, b.val, CV_SHIFT)); +} + +#define OPENCV_IMPL_VSX_ROTATE_64_2RG(_Tpvec, suffix, rg1, rg2) \ +template \ +inline _Tpvec v_rotate_##suffix(const _Tpvec& a, const _Tpvec& b) \ +{ \ + if (imm == 1) \ + return _Tpvec(vec_permi(rg1.val, rg2.val, 2)); \ + return imm ? b : a; \ +} + +#define OPENCV_IMPL_VSX_ROTATE_64_2RG_LR(_Tpvec) \ +OPENCV_IMPL_VSX_ROTATE_64_2RG(_Tpvec, left, b, a) \ +OPENCV_IMPL_VSX_ROTATE_64_2RG(_Tpvec, right, a, b) + +OPENCV_IMPL_VSX_ROTATE_64_2RG_LR(v_float64x2) +OPENCV_IMPL_VSX_ROTATE_64_2RG_LR(v_uint64x2) +OPENCV_IMPL_VSX_ROTATE_64_2RG_LR(v_int64x2) + +/* Extract */ +template +inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) +{ return v_rotate_right(a, b); } + +////////// Reduce and mask ///////// + +/** Reduce **/ +inline uint v_reduce_sum(const v_uint8x16& a) +{ + const vec_uint4 zero4 = vec_uint4_z; + vec_uint4 sum4 = vec_sum4s(a.val, zero4); + return (uint)vec_extract(vec_sums(vec_int4_c(sum4), vec_int4_c(zero4)), 3); +} +inline int v_reduce_sum(const v_int8x16& a) +{ + const vec_int4 zero4 = vec_int4_z; + vec_int4 sum4 = vec_sum4s(a.val, zero4); + return (int)vec_extract(vec_sums(sum4, zero4), 3); +} +inline int v_reduce_sum(const v_int16x8& a) +{ + const vec_int4 zero = vec_int4_z; + return saturate_cast(vec_extract(vec_sums(vec_sum4s(a.val, zero), zero), 3)); +} +inline uint v_reduce_sum(const v_uint16x8& a) +{ + const vec_int4 v4 = vec_int4_c(vec_unpackhu(vec_adds(a.val, vec_sld(a.val, a.val, 8)))); + return saturate_cast(vec_extract(vec_sums(v4, vec_int4_z), 3)); +} + +#define OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(_Tpvec, _Tpvec2, scalartype, suffix, func) \ +inline scalartype v_reduce_##suffix(const _Tpvec& a) \ +{ \ + const _Tpvec2 rs = func(a.val, vec_sld(a.val, a.val, 8)); \ + return vec_extract(func(rs, vec_sld(rs, rs, 4)), 0); \ +} +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_uint32x4, vec_uint4, uint, sum, vec_add) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_uint32x4, vec_uint4, uint, max, vec_max) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_uint32x4, vec_uint4, uint, min, vec_min) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_int32x4, vec_int4, int, sum, vec_add) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_int32x4, vec_int4, int, max, vec_max) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_int32x4, vec_int4, int, min, vec_min) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_float32x4, vec_float4, float, sum, vec_add) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_float32x4, vec_float4, float, max, vec_max) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_float32x4, vec_float4, float, min, vec_min) + +inline uint64 v_reduce_sum(const v_uint64x2& a) +{ + return vec_extract(vec_add(a.val, vec_permi(a.val, a.val, 3)), 0); +} +inline int64 v_reduce_sum(const v_int64x2& a) +{ + return vec_extract(vec_add(a.val, vec_permi(a.val, a.val, 3)), 0); +} +inline double v_reduce_sum(const v_float64x2& a) +{ + return vec_extract(vec_add(a.val, vec_permi(a.val, a.val, 3)), 0); +} + +#define OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(_Tpvec, _Tpvec2, scalartype, suffix, func) \ +inline scalartype v_reduce_##suffix(const _Tpvec& a) \ +{ \ + _Tpvec2 rs = func(a.val, vec_sld(a.val, a.val, 8)); \ + rs = func(rs, vec_sld(rs, rs, 4)); \ + return vec_extract(func(rs, vec_sld(rs, rs, 2)), 0); \ +} +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_uint16x8, vec_ushort8, ushort, max, vec_max) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_uint16x8, vec_ushort8, ushort, min, vec_min) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_int16x8, vec_short8, short, max, vec_max) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_int16x8, vec_short8, short, min, vec_min) + +#define OPENCV_HAL_IMPL_VSX_REDUCE_OP_16(_Tpvec, _Tpvec2, scalartype, suffix, func) \ +inline scalartype v_reduce_##suffix(const _Tpvec& a) \ +{ \ + _Tpvec2 rs = func(a.val, vec_sld(a.val, a.val, 8)); \ + rs = func(rs, vec_sld(rs, rs, 4)); \ + rs = func(rs, vec_sld(rs, rs, 2)); \ + return vec_extract(func(rs, vec_sld(rs, rs, 1)), 0); \ +} +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_uint8x16, vec_uchar16, uchar, max, vec_max) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_uint8x16, vec_uchar16, uchar, min, vec_min) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_int8x16, vec_char16, schar, max, vec_max) +OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(v_int8x16, vec_char16, schar, min, vec_min) + +inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b, + const v_float32x4& c, const v_float32x4& d) +{ + vec_float4 ac = vec_add(vec_mergel(a.val, c.val), vec_mergeh(a.val, c.val)); + ac = vec_add(ac, vec_sld(ac, ac, 8)); + + vec_float4 bd = vec_add(vec_mergel(b.val, d.val), vec_mergeh(b.val, d.val)); + bd = vec_add(bd, vec_sld(bd, bd, 8)); + return v_float32x4(vec_mergeh(ac, bd)); +} + +inline unsigned v_reduce_sad(const v_uint8x16& a, const v_uint8x16& b) +{ + const vec_uint4 zero4 = vec_uint4_z; + vec_uint4 sum4 = vec_sum4s(vec_absd(a.val, b.val), zero4); + return (unsigned)vec_extract(vec_sums(vec_int4_c(sum4), vec_int4_c(zero4)), 3); +} +inline unsigned v_reduce_sad(const v_int8x16& a, const v_int8x16& b) +{ + const vec_int4 zero4 = vec_int4_z; + vec_char16 ad = vec_abss(vec_subs(a.val, b.val)); + vec_int4 sum4 = vec_sum4s(ad, zero4); + return (unsigned)vec_extract(vec_sums(sum4, zero4), 3); +} +inline unsigned v_reduce_sad(const v_uint16x8& a, const v_uint16x8& b) +{ + vec_ushort8 ad = vec_absd(a.val, b.val); + VSX_UNUSED(vec_int4) sum = vec_sums(vec_int4_c(vec_unpackhu(ad)) + vec_int4_c(vec_unpacklu(ad)), vec_int4_z); + return (unsigned)vec_extract(sum, 3); +} +inline unsigned v_reduce_sad(const v_int16x8& a, const v_int16x8& b) +{ + const vec_int4 zero4 = vec_int4_z; + vec_short8 ad = vec_abss(vec_subs(a.val, b.val)); + vec_int4 sum4 = vec_sum4s(ad, zero4); + return (unsigned)vec_extract(vec_sums(sum4, zero4), 3); +} +inline unsigned v_reduce_sad(const v_uint32x4& a, const v_uint32x4& b) +{ + const vec_uint4 ad = vec_absd(a.val, b.val); + const vec_uint4 rd = vec_add(ad, vec_sld(ad, ad, 8)); + return vec_extract(vec_add(rd, vec_sld(rd, rd, 4)), 0); +} +inline unsigned v_reduce_sad(const v_int32x4& a, const v_int32x4& b) +{ + vec_int4 ad = vec_abss(vec_sub(a.val, b.val)); + return (unsigned)vec_extract(vec_sums(ad, vec_int4_z), 3); +} +inline float v_reduce_sad(const v_float32x4& a, const v_float32x4& b) +{ + const vec_float4 ad = vec_abs(vec_sub(a.val, b.val)); + const vec_float4 rd = vec_add(ad, vec_sld(ad, ad, 8)); + return vec_extract(vec_add(rd, vec_sld(rd, rd, 4)), 0); +} + +/** Popcount **/ +inline v_uint8x16 v_popcount(const v_uint8x16& a) +{ return v_uint8x16(vec_popcntu(a.val)); } +inline v_uint8x16 v_popcount(const v_int8x16& a) +{ return v_uint8x16(vec_popcntu(a.val)); } +inline v_uint16x8 v_popcount(const v_uint16x8& a) +{ return v_uint16x8(vec_popcntu(a.val)); } +inline v_uint16x8 v_popcount(const v_int16x8& a) +{ return v_uint16x8(vec_popcntu(a.val)); } +inline v_uint32x4 v_popcount(const v_uint32x4& a) +{ return v_uint32x4(vec_popcntu(a.val)); } +inline v_uint32x4 v_popcount(const v_int32x4& a) +{ return v_uint32x4(vec_popcntu(a.val)); } +inline v_uint64x2 v_popcount(const v_uint64x2& a) +{ return v_uint64x2(vec_popcntu(a.val)); } +inline v_uint64x2 v_popcount(const v_int64x2& a) +{ return v_uint64x2(vec_popcntu(a.val)); } + +/** Mask **/ +inline int v_signmask(const v_uint8x16& a) +{ + vec_uchar16 sv = vec_sr(a.val, vec_uchar16_sp(7)); + static const vec_uchar16 slm = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7}; + sv = vec_sl(sv, slm); + vec_uint4 sv4 = vec_sum4s(sv, vec_uint4_z); + static const vec_uint4 slm4 = {0, 0, 8, 8}; + sv4 = vec_sl(sv4, slm4); + return vec_extract(vec_sums((vec_int4) sv4, vec_int4_z), 3); +} +inline int v_signmask(const v_int8x16& a) +{ return v_signmask(v_reinterpret_as_u8(a)); } + +inline int v_signmask(const v_int16x8& a) +{ + static const vec_ushort8 slm = {0, 1, 2, 3, 4, 5, 6, 7}; + vec_short8 sv = vec_sr(a.val, vec_ushort8_sp(15)); + sv = vec_sl(sv, slm); + vec_int4 svi = vec_int4_z; + svi = vec_sums(vec_sum4s(sv, svi), svi); + return vec_extract(svi, 3); +} +inline int v_signmask(const v_uint16x8& a) +{ return v_signmask(v_reinterpret_as_s16(a)); } + +inline int v_signmask(const v_int32x4& a) +{ + static const vec_uint4 slm = {0, 1, 2, 3}; + vec_int4 sv = vec_sr(a.val, vec_uint4_sp(31)); + sv = vec_sl(sv, slm); + sv = vec_sums(sv, vec_int4_z); + return vec_extract(sv, 3); +} +inline int v_signmask(const v_uint32x4& a) +{ return v_signmask(v_reinterpret_as_s32(a)); } +inline int v_signmask(const v_float32x4& a) +{ return v_signmask(v_reinterpret_as_s32(a)); } + +inline int v_signmask(const v_int64x2& a) +{ + VSX_UNUSED(const vec_dword2) sv = vec_sr(a.val, vec_udword2_sp(63)); + return (int)vec_extract(sv, 0) | (int)vec_extract(sv, 1) << 1; +} +inline int v_signmask(const v_uint64x2& a) +{ return v_signmask(v_reinterpret_as_s64(a)); } +inline int v_signmask(const v_float64x2& a) +{ return v_signmask(v_reinterpret_as_s64(a)); } + +inline int v_scan_forward(const v_int8x16& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint8x16& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_int16x8& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint16x8& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_int32x4& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint32x4& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_float32x4& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_int64x2& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_uint64x2& a) { return trailingZeros32(v_signmask(a)); } +inline int v_scan_forward(const v_float64x2& a) { return trailingZeros32(v_signmask(a)); } + +template +inline bool v_check_all(const _Tpvec& a) +{ return vec_all_lt(a.val, _Tpvec().val); } +inline bool v_check_all(const v_uint8x16& a) +{ return v_check_all(v_reinterpret_as_s8(a)); } +inline bool v_check_all(const v_uint16x8& a) +{ return v_check_all(v_reinterpret_as_s16(a)); } +inline bool v_check_all(const v_uint32x4& a) +{ return v_check_all(v_reinterpret_as_s32(a)); } +inline bool v_check_all(const v_float32x4& a) +{ return v_check_all(v_reinterpret_as_s32(a)); } +inline bool v_check_all(const v_float64x2& a) +{ return v_check_all(v_reinterpret_as_s64(a)); } + +template +inline bool v_check_any(const _Tpvec& a) +{ return vec_any_lt(a.val, _Tpvec().val); } +inline bool v_check_any(const v_uint8x16& a) +{ return v_check_any(v_reinterpret_as_s8(a)); } +inline bool v_check_any(const v_uint16x8& a) +{ return v_check_any(v_reinterpret_as_s16(a)); } +inline bool v_check_any(const v_uint32x4& a) +{ return v_check_any(v_reinterpret_as_s32(a)); } +inline bool v_check_any(const v_float32x4& a) +{ return v_check_any(v_reinterpret_as_s32(a)); } +inline bool v_check_any(const v_float64x2& a) +{ return v_check_any(v_reinterpret_as_s64(a)); } + +////////// Other math ///////// + +/** Some frequent operations **/ +inline v_float32x4 v_sqrt(const v_float32x4& x) +{ return v_float32x4(vec_sqrt(x.val)); } +inline v_float64x2 v_sqrt(const v_float64x2& x) +{ return v_float64x2(vec_sqrt(x.val)); } + +inline v_float32x4 v_invsqrt(const v_float32x4& x) +{ return v_float32x4(vec_rsqrt(x.val)); } +inline v_float64x2 v_invsqrt(const v_float64x2& x) +{ return v_float64x2(vec_rsqrt(x.val)); } + +#define OPENCV_HAL_IMPL_VSX_MULADD(_Tpvec) \ +inline _Tpvec v_magnitude(const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_sqrt(vec_madd(a.val, a.val, vec_mul(b.val, b.val)))); } \ +inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ +{ return _Tpvec(vec_madd(a.val, a.val, vec_mul(b.val, b.val))); } \ +inline _Tpvec v_fma(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ +{ return _Tpvec(vec_madd(a.val, b.val, c.val)); } \ +inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ +{ return _Tpvec(vec_madd(a.val, b.val, c.val)); } + +OPENCV_HAL_IMPL_VSX_MULADD(v_float32x4) +OPENCV_HAL_IMPL_VSX_MULADD(v_float64x2) + +inline v_int32x4 v_muladd(const v_int32x4& a, const v_int32x4& b, const v_int32x4& c) +{ return a * b + c; } + +// TODO: exp, log, sin, cos + +/** Absolute values **/ +inline v_uint8x16 v_abs(const v_int8x16& x) +{ return v_uint8x16(vec_uchar16_c(vec_abs(x.val))); } + +inline v_uint16x8 v_abs(const v_int16x8& x) +{ return v_uint16x8(vec_ushort8_c(vec_abs(x.val))); } + +inline v_uint32x4 v_abs(const v_int32x4& x) +{ return v_uint32x4(vec_uint4_c(vec_abs(x.val))); } + +inline v_float32x4 v_abs(const v_float32x4& x) +{ return v_float32x4(vec_abs(x.val)); } + +inline v_float64x2 v_abs(const v_float64x2& x) +{ return v_float64x2(vec_abs(x.val)); } + +/** Absolute difference **/ +// unsigned +OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_absdiff, vec_absd) + +inline v_uint8x16 v_absdiff(const v_int8x16& a, const v_int8x16& b) +{ return v_reinterpret_as_u8(v_sub_wrap(v_max(a, b), v_min(a, b))); } +inline v_uint16x8 v_absdiff(const v_int16x8& a, const v_int16x8& b) +{ return v_reinterpret_as_u16(v_sub_wrap(v_max(a, b), v_min(a, b))); } +inline v_uint32x4 v_absdiff(const v_int32x4& a, const v_int32x4& b) +{ return v_reinterpret_as_u32(v_max(a, b) - v_min(a, b)); } + +inline v_float32x4 v_absdiff(const v_float32x4& a, const v_float32x4& b) +{ return v_abs(a - b); } +inline v_float64x2 v_absdiff(const v_float64x2& a, const v_float64x2& b) +{ return v_abs(a - b); } + +/** Absolute difference for signed integers **/ +inline v_int8x16 v_absdiffs(const v_int8x16& a, const v_int8x16& b) +{ return v_int8x16(vec_abss(vec_subs(a.val, b.val))); } +inline v_int16x8 v_absdiffs(const v_int16x8& a, const v_int16x8& b) +{ return v_int16x8(vec_abss(vec_subs(a.val, b.val))); } + +////////// Conversions ///////// + +/** Rounding **/ +inline v_int32x4 v_round(const v_float32x4& a) +{ return v_int32x4(vec_cts(vec_rint(a.val))); } + +inline v_int32x4 v_round(const v_float64x2& a) +{ return v_int32x4(vec_mergesqo(vec_ctso(vec_rint(a.val)), vec_int4_z)); } + +inline v_int32x4 v_round(const v_float64x2& a, const v_float64x2& b) +{ return v_int32x4(vec_mergesqo(vec_ctso(vec_rint(a.val)), vec_ctso(vec_rint(b.val)))); } + +inline v_int32x4 v_floor(const v_float32x4& a) +{ return v_int32x4(vec_cts(vec_floor(a.val))); } + +inline v_int32x4 v_floor(const v_float64x2& a) +{ return v_int32x4(vec_mergesqo(vec_ctso(vec_floor(a.val)), vec_int4_z)); } + +inline v_int32x4 v_ceil(const v_float32x4& a) +{ return v_int32x4(vec_cts(vec_ceil(a.val))); } + +inline v_int32x4 v_ceil(const v_float64x2& a) +{ return v_int32x4(vec_mergesqo(vec_ctso(vec_ceil(a.val)), vec_int4_z)); } + +inline v_int32x4 v_trunc(const v_float32x4& a) +{ return v_int32x4(vec_cts(a.val)); } + +inline v_int32x4 v_trunc(const v_float64x2& a) +{ return v_int32x4(vec_mergesqo(vec_ctso(a.val), vec_int4_z)); } + +/** To float **/ +inline v_float32x4 v_cvt_f32(const v_int32x4& a) +{ return v_float32x4(vec_ctf(a.val)); } + +inline v_float32x4 v_cvt_f32(const v_float64x2& a) +{ return v_float32x4(vec_mergesqo(vec_cvfo(a.val), vec_float4_z)); } + +inline v_float32x4 v_cvt_f32(const v_float64x2& a, const v_float64x2& b) +{ return v_float32x4(vec_mergesqo(vec_cvfo(a.val), vec_cvfo(b.val))); } + +inline v_float64x2 v_cvt_f64(const v_int32x4& a) +{ return v_float64x2(vec_ctdo(vec_mergeh(a.val, a.val))); } + +inline v_float64x2 v_cvt_f64_high(const v_int32x4& a) +{ return v_float64x2(vec_ctdo(vec_mergel(a.val, a.val))); } + +inline v_float64x2 v_cvt_f64(const v_float32x4& a) +{ return v_float64x2(vec_cvfo(vec_mergeh(a.val, a.val))); } + +inline v_float64x2 v_cvt_f64_high(const v_float32x4& a) +{ return v_float64x2(vec_cvfo(vec_mergel(a.val, a.val))); } + +////////////// Lookup table access //////////////////// + +inline v_int8x16 v_lut(const schar* tab, const int* idx) +{ + return v_int8x16(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]], tab[idx[4]], tab[idx[5]], tab[idx[6]], tab[idx[7]], + tab[idx[8]], tab[idx[9]], tab[idx[10]], tab[idx[11]], tab[idx[12]], tab[idx[13]], tab[idx[14]], tab[idx[15]]); +} +inline v_int8x16 v_lut_pairs(const schar* tab, const int* idx) +{ + return v_reinterpret_as_s8(v_int16x8(*(const short*)(tab+idx[0]), *(const short*)(tab+idx[1]), *(const short*)(tab+idx[2]), *(const short*)(tab+idx[3]), + *(const short*)(tab+idx[4]), *(const short*)(tab+idx[5]), *(const short*)(tab+idx[6]), *(const short*)(tab+idx[7]))); +} +inline v_int8x16 v_lut_quads(const schar* tab, const int* idx) +{ + return v_reinterpret_as_s8(v_int32x4(*(const int*)(tab+idx[0]), *(const int*)(tab+idx[1]), *(const int*)(tab+idx[2]), *(const int*)(tab+idx[3]))); +} +inline v_uint8x16 v_lut(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut((const schar*)tab, idx)); } +inline v_uint8x16 v_lut_pairs(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_pairs((const schar*)tab, idx)); } +inline v_uint8x16 v_lut_quads(const uchar* tab, const int* idx) { return v_reinterpret_as_u8(v_lut_quads((const schar*)tab, idx)); } + +inline v_int16x8 v_lut(const short* tab, const int* idx) +{ + return v_int16x8(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]], tab[idx[4]], tab[idx[5]], tab[idx[6]], tab[idx[7]]); +} +inline v_int16x8 v_lut_pairs(const short* tab, const int* idx) +{ + return v_reinterpret_as_s16(v_int32x4(*(const int*)(tab + idx[0]), *(const int*)(tab + idx[1]), *(const int*)(tab + idx[2]), *(const int*)(tab + idx[3]))); +} +inline v_int16x8 v_lut_quads(const short* tab, const int* idx) +{ + return v_reinterpret_as_s16(v_int64x2(*(const int64*)(tab + idx[0]), *(const int64*)(tab + idx[1]))); +} +inline v_uint16x8 v_lut(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut((const short*)tab, idx)); } +inline v_uint16x8 v_lut_pairs(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_pairs((const short*)tab, idx)); } +inline v_uint16x8 v_lut_quads(const ushort* tab, const int* idx) { return v_reinterpret_as_u16(v_lut_quads((const short*)tab, idx)); } + +inline v_int32x4 v_lut(const int* tab, const int* idx) +{ + return v_int32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]); +} +inline v_int32x4 v_lut_pairs(const int* tab, const int* idx) +{ + return v_reinterpret_as_s32(v_int64x2(*(const int64*)(tab + idx[0]), *(const int64*)(tab + idx[1]))); +} +inline v_int32x4 v_lut_quads(const int* tab, const int* idx) +{ + return v_int32x4(vsx_ld(0, tab + idx[0])); +} +inline v_uint32x4 v_lut(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut((const int*)tab, idx)); } +inline v_uint32x4 v_lut_pairs(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_pairs((const int*)tab, idx)); } +inline v_uint32x4 v_lut_quads(const unsigned* tab, const int* idx) { return v_reinterpret_as_u32(v_lut_quads((const int*)tab, idx)); } + +inline v_int64x2 v_lut(const int64_t* tab, const int* idx) +{ + return v_int64x2(tab[idx[0]], tab[idx[1]]); +} +inline v_int64x2 v_lut_pairs(const int64_t* tab, const int* idx) +{ + return v_int64x2(vsx_ld2(0, tab + idx[0])); +} +inline v_uint64x2 v_lut(const uint64_t* tab, const int* idx) { return v_reinterpret_as_u64(v_lut((const int64_t *)tab, idx)); } +inline v_uint64x2 v_lut_pairs(const uint64_t* tab, const int* idx) { return v_reinterpret_as_u64(v_lut_pairs((const int64_t *)tab, idx)); } + +inline v_float32x4 v_lut(const float* tab, const int* idx) +{ + return v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]); +} +inline v_float32x4 v_lut_pairs(const float* tab, const int* idx) { return v_reinterpret_as_f32(v_lut_pairs((const int*)tab, idx)); } +inline v_float32x4 v_lut_quads(const float* tab, const int* idx) { return v_load(tab + *idx); } + +inline v_float64x2 v_lut(const double* tab, const int* idx) +{ + return v_float64x2(tab[idx[0]], tab[idx[1]]); +} +inline v_float64x2 v_lut_pairs(const double* tab, const int* idx) { return v_load(tab + *idx); } + +inline v_int32x4 v_lut(const int* tab, const v_int32x4& idxvec) +{ + const int idx[4] = { + vec_extract(idxvec.val, 0), + vec_extract(idxvec.val, 1), + vec_extract(idxvec.val, 2), + vec_extract(idxvec.val, 3) + }; + return v_int32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]); +} + +inline v_uint32x4 v_lut(const unsigned* tab, const v_int32x4& idxvec) +{ + const int idx[4] = { + vec_extract(idxvec.val, 0), + vec_extract(idxvec.val, 1), + vec_extract(idxvec.val, 2), + vec_extract(idxvec.val, 3) + }; + return v_uint32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]); +} + +inline v_float32x4 v_lut(const float* tab, const v_int32x4& idxvec) +{ + const int idx[4] = { + vec_extract(idxvec.val, 0), + vec_extract(idxvec.val, 1), + vec_extract(idxvec.val, 2), + vec_extract(idxvec.val, 3) + }; + return v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]); +} + +inline v_float64x2 v_lut(const double* tab, const v_int32x4& idxvec) +{ + const int idx[2] = { + vec_extract(idxvec.val, 0), + vec_extract(idxvec.val, 1) + }; + return v_float64x2(tab[idx[0]], tab[idx[1]]); +} + +inline void v_lut_deinterleave(const float* tab, const v_int32x4& idxvec, v_float32x4& x, v_float32x4& y) +{ + vec_float4 xy0 = vec_ld_l8(tab + vec_extract(idxvec.val, 0)); + vec_float4 xy1 = vec_ld_l8(tab + vec_extract(idxvec.val, 1)); + vec_float4 xy2 = vec_ld_l8(tab + vec_extract(idxvec.val, 2)); + vec_float4 xy3 = vec_ld_l8(tab + vec_extract(idxvec.val, 3)); + vec_float4 xy02 = vec_mergeh(xy0, xy2); // x0, x2, y0, y2 + vec_float4 xy13 = vec_mergeh(xy1, xy3); // x1, x3, y1, y3 + x.val = vec_mergeh(xy02, xy13); + y.val = vec_mergel(xy02, xy13); +} +inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_float64x2& x, v_float64x2& y) +{ + vec_double2 xy0 = vsx_ld(vec_extract(idxvec.val, 0), tab); + vec_double2 xy1 = vsx_ld(vec_extract(idxvec.val, 1), tab); + x.val = vec_mergeh(xy0, xy1); + y.val = vec_mergel(xy0, xy1); +} + +inline v_int8x16 v_interleave_pairs(const v_int8x16& vec) +{ + static const vec_uchar16 perm = {0, 2, 1, 3, 4, 6, 5, 7, 8, 10, 9, 11, 12, 14, 13, 15}; + return v_int8x16(vec_perm(vec.val, vec.val, perm)); +} +inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec) +{ return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); } + +inline v_int8x16 v_interleave_quads(const v_int8x16& vec) +{ + static const vec_uchar16 perm = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15}; + return v_int8x16(vec_perm(vec.val, vec.val, perm)); +} +inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec) +{ return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); } + +inline v_int16x8 v_interleave_pairs(const v_int16x8& vec) +{ + static const vec_uchar16 perm = {0,1, 4,5, 2,3, 6,7, 8,9, 12,13, 10,11, 14,15}; + return v_int16x8(vec_perm(vec.val, vec.val, perm)); +} +inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec) +{ return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); } + +inline v_int16x8 v_interleave_quads(const v_int16x8& vec) +{ + static const vec_uchar16 perm = {0,1, 8,9, 2,3, 10,11, 4,5, 12,13, 6,7, 14,15}; + return v_int16x8(vec_perm(vec.val, vec.val, perm)); +} +inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec) +{ return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_interleave_pairs(const v_int32x4& vec) +{ + static const vec_uchar16 perm = {0,1,2,3, 8,9,10,11, 4,5,6,7, 12,13,14,15}; + return v_int32x4(vec_perm(vec.val, vec.val, perm)); +} +inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec) +{ return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } +inline v_float32x4 v_interleave_pairs(const v_float32x4& vec) +{ return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); } + +inline v_int8x16 v_pack_triplets(const v_int8x16& vec) +{ + static const vec_uchar16 perm = {0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 15, 15, 15}; + return v_int8x16(vec_perm(vec.val, vec.val, perm)); +} +inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec) +{ return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); } + +inline v_int16x8 v_pack_triplets(const v_int16x8& vec) +{ + static const vec_uchar16 perm = {0,1, 2,3, 4,5, 8,9, 10,11, 12,13, 14,15, 14,15}; + return v_int16x8(vec_perm(vec.val, vec.val, perm)); +} +inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec) +{ return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); } + +inline v_int32x4 v_pack_triplets(const v_int32x4& vec) +{ return vec; } +inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) +{ return vec; } +inline v_float32x4 v_pack_triplets(const v_float32x4& vec) +{ return vec; } + +/////// FP16 support //////// + +inline v_float32x4 v_load_expand(const float16_t* ptr) +{ + vec_ushort8 vf16 = vec_ld_l8((const ushort*)ptr); +#if CV_VSX3 && defined(vec_extract_fp_from_shorth) + return v_float32x4(vec_extract_fp_from_shorth(vf16)); +#elif CV_VSX3 && !defined(CV_COMPILER_VSX_BROKEN_ASM) + vec_float4 vf32; + __asm__ __volatile__ ("xvcvhpsp %x0,%x1" : "=wf" (vf32) : "wa" (vec_mergeh(vf16, vf16))); + return v_float32x4(vf32); +#else + const vec_int4 z = vec_int4_z, delta = vec_int4_sp(0x38000000); + const vec_int4 signmask = vec_int4_sp(0x80000000); + const vec_int4 maxexp = vec_int4_sp(0x7c000000); + const vec_float4 deltaf = vec_float4_c(vec_int4_sp(0x38800000)); + + vec_int4 bits = vec_int4_c(vec_mergeh(vec_short8_c(z), vec_short8_c(vf16))); + vec_int4 e = vec_and(bits, maxexp), sign = vec_and(bits, signmask); + vec_int4 t = vec_add(vec_sr(vec_xor(bits, sign), vec_uint4_sp(3)), delta); // ((h & 0x7fff) << 13) + delta + vec_int4 zt = vec_int4_c(vec_sub(vec_float4_c(vec_add(t, vec_int4_sp(1 << 23))), deltaf)); + + t = vec_add(t, vec_and(delta, vec_cmpeq(maxexp, e))); + vec_bint4 zmask = vec_cmpeq(e, z); + vec_int4 ft = vec_sel(t, zt, zmask); + return v_float32x4(vec_float4_c(vec_or(ft, sign))); +#endif +} + +inline void v_pack_store(float16_t* ptr, const v_float32x4& v) +{ +// fixme: Is there any buitin op or intrinsic that cover "xvcvsphp"? +#if CV_VSX3 && !defined(CV_COMPILER_VSX_BROKEN_ASM) + vec_ushort8 vf16; + __asm__ __volatile__ ("xvcvsphp %x0,%x1" : "=wa" (vf16) : "wf" (v.val)); + vec_st_l8(vec_mergesqe(vf16, vf16), ptr); +#else + const vec_int4 signmask = vec_int4_sp(0x80000000); + const vec_int4 rval = vec_int4_sp(0x3f000000); + + vec_int4 t = vec_int4_c(v.val); + vec_int4 sign = vec_sra(vec_and(t, signmask), vec_uint4_sp(16)); + t = vec_and(vec_nor(signmask, signmask), t); + + vec_bint4 finitemask = vec_cmpgt(vec_int4_sp(0x47800000), t); + vec_bint4 isnan = vec_cmpgt(t, vec_int4_sp(0x7f800000)); + vec_int4 naninf = vec_sel(vec_int4_sp(0x7c00), vec_int4_sp(0x7e00), isnan); + vec_bint4 tinymask = vec_cmpgt(vec_int4_sp(0x38800000), t); + vec_int4 tt = vec_int4_c(vec_add(vec_float4_c(t), vec_float4_c(rval))); + tt = vec_sub(tt, rval); + vec_int4 odd = vec_and(vec_sr(t, vec_uint4_sp(13)), vec_int4_sp(1)); + vec_int4 nt = vec_add(t, vec_int4_sp(0xc8000fff)); + nt = vec_sr(vec_add(nt, odd), vec_uint4_sp(13)); + t = vec_sel(nt, tt, tinymask); + t = vec_sel(naninf, t, finitemask); + t = vec_or(t, sign); + vec_st_l8(vec_packs(t, t), ptr); +#endif +} + +inline void v_cleanup() {} + + +/** Reinterpret **/ +/** its up there with load and store operations **/ + +////////// Matrix operations ///////// + +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b) +{ return v_int32x4(vec_msum(a.val, b.val, vec_int4_z)); } + +inline v_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b, const v_int32x4& c) +{ return v_int32x4(vec_msum(a.val, b.val, c.val)); } + +inline v_float32x4 v_matmul(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& m3) +{ + const vec_float4 v0 = vec_splat(v.val, 0); + const vec_float4 v1 = vec_splat(v.val, 1); + const vec_float4 v2 = vec_splat(v.val, 2); + VSX_UNUSED(const vec_float4) v3 = vec_splat(v.val, 3); + return v_float32x4(vec_madd(v0, m0.val, vec_madd(v1, m1.val, vec_madd(v2, m2.val, vec_mul(v3, m3.val))))); +} + +inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0, + const v_float32x4& m1, const v_float32x4& m2, + const v_float32x4& a) +{ + const vec_float4 v0 = vec_splat(v.val, 0); + const vec_float4 v1 = vec_splat(v.val, 1); + const vec_float4 v2 = vec_splat(v.val, 2); + return v_float32x4(vec_madd(v0, m0.val, vec_madd(v1, m1.val, vec_madd(v2, m2.val, a.val)))); +} + +#define OPENCV_HAL_IMPL_VSX_TRANSPOSE4x4(_Tpvec, _Tpvec2) \ +inline void v_transpose4x4(const _Tpvec& a0, const _Tpvec& a1, \ + const _Tpvec& a2, const _Tpvec& a3, \ + _Tpvec& b0, _Tpvec& b1, _Tpvec& b2, _Tpvec& b3) \ +{ \ + _Tpvec2 a02 = vec_mergeh(a0.val, a2.val); \ + _Tpvec2 a13 = vec_mergeh(a1.val, a3.val); \ + b0.val = vec_mergeh(a02, a13); \ + b1.val = vec_mergel(a02, a13); \ + a02 = vec_mergel(a0.val, a2.val); \ + a13 = vec_mergel(a1.val, a3.val); \ + b2.val = vec_mergeh(a02, a13); \ + b3.val = vec_mergel(a02, a13); \ +} +OPENCV_HAL_IMPL_VSX_TRANSPOSE4x4(v_uint32x4, vec_uint4) +OPENCV_HAL_IMPL_VSX_TRANSPOSE4x4(v_int32x4, vec_int4) +OPENCV_HAL_IMPL_VSX_TRANSPOSE4x4(v_float32x4, vec_float4) + +CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END + +//! @endcond + +} + +#endif // OPENCV_HAL_VSX_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/mat.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/mat.hpp new file mode 100755 index 0000000..cba324a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/mat.hpp @@ -0,0 +1,3726 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_MAT_HPP +#define OPENCV_CORE_MAT_HPP + +#ifndef __cplusplus +# error mat.hpp header must be compiled as C++ +#endif + +#include "opencv2/core/matx.hpp" +#include "opencv2/core/types.hpp" + +#include "opencv2/core/bufferpool.hpp" + +#include + +namespace cv +{ + +//! @addtogroup core_basic +//! @{ + +enum AccessFlag { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25, + ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 }; +CV_ENUM_FLAGS(AccessFlag) +__CV_ENUM_FLAGS_BITWISE_AND(AccessFlag, int, AccessFlag) + +CV__DEBUG_NS_BEGIN + +class CV_EXPORTS _OutputArray; + +//////////////////////// Input/Output Array Arguments ///////////////////////////////// + +/** @brief This is the proxy class for passing read-only input arrays into OpenCV functions. + +It is defined as: +@code + typedef const _InputArray& InputArray; +@endcode +where _InputArray is a class that can be constructed from `Mat`, `Mat_`, `Matx`, +`std::vector`, `std::vector >`, `std::vector`, `std::vector >`, +`UMat`, `std::vector` or `double`. It can also be constructed from a matrix expression. + +Since this is mostly implementation-level class, and its interface may change in future versions, we +do not describe it in details. There are a few key things, though, that should be kept in mind: + +- When you see in the reference manual or in OpenCV source code a function that takes + InputArray, it means that you can actually pass `Mat`, `Matx`, `vector` etc. (see above the + complete list). +- Optional input arguments: If some of the input arrays may be empty, pass cv::noArray() (or + simply cv::Mat() as you probably did before). +- The class is designed solely for passing parameters. That is, normally you *should not* + declare class members, local and global variables of this type. +- If you want to design your own function or a class method that can operate of arrays of + multiple types, you can use InputArray (or OutputArray) for the respective parameters. Inside + a function you should use _InputArray::getMat() method to construct a matrix header for the + array (without copying data). _InputArray::kind() can be used to distinguish Mat from + `vector<>` etc., but normally it is not needed. + +Here is how you can use a function that takes InputArray : +@code + std::vector vec; + // points or a circle + for( int i = 0; i < 30; i++ ) + vec.push_back(Point2f((float)(100 + 30*cos(i*CV_PI*2/5)), + (float)(100 - 30*sin(i*CV_PI*2/5)))); + cv::transform(vec, vec, cv::Matx23f(0.707, -0.707, 10, 0.707, 0.707, 20)); +@endcode +That is, we form an STL vector containing points, and apply in-place affine transformation to the +vector using the 2x3 matrix created inline as `Matx` instance. + +Here is how such a function can be implemented (for simplicity, we implement a very specific case of +it, according to the assertion statement inside) : +@code + void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m) + { + // get Mat headers for input arrays. This is O(1) operation, + // unless _src and/or _m are matrix expressions. + Mat src = _src.getMat(), m = _m.getMat(); + CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) ); + + // [re]create the output array so that it has the proper size and type. + // In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize. + _dst.create(src.size(), src.type()); + Mat dst = _dst.getMat(); + + for( int i = 0; i < src.rows; i++ ) + for( int j = 0; j < src.cols; j++ ) + { + Point2f pt = src.at(i, j); + dst.at(i, j) = Point2f(m.at(0, 0)*pt.x + + m.at(0, 1)*pt.y + + m.at(0, 2), + m.at(1, 0)*pt.x + + m.at(1, 1)*pt.y + + m.at(1, 2)); + } + } +@endcode +There is another related type, InputArrayOfArrays, which is currently defined as a synonym for +InputArray: +@code + typedef InputArray InputArrayOfArrays; +@endcode +It denotes function arguments that are either vectors of vectors or vectors of matrices. A separate +synonym is needed to generate Python/Java etc. wrappers properly. At the function implementation +level their use is similar, but _InputArray::getMat(idx) should be used to get header for the +idx-th component of the outer vector and _InputArray::size().area() should be used to find the +number of components (vectors/matrices) of the outer vector. + +In general, type support is limited to cv::Mat types. Other types are forbidden. +But in some cases we need to support passing of custom non-general Mat types, like arrays of cv::KeyPoint, cv::DMatch, etc. +This data is not intented to be interpreted as an image data, or processed somehow like regular cv::Mat. +To pass such custom type use rawIn() / rawOut() / rawInOut() wrappers. +Custom type is wrapped as Mat-compatible `CV_8UC` values (N = sizeof(T), N <= CV_CN_MAX). + */ +class CV_EXPORTS _InputArray +{ +public: + enum KindFlag { + KIND_SHIFT = 16, + FIXED_TYPE = 0x8000 << KIND_SHIFT, + FIXED_SIZE = 0x4000 << KIND_SHIFT, + KIND_MASK = 31 << KIND_SHIFT, + + NONE = 0 << KIND_SHIFT, + MAT = 1 << KIND_SHIFT, + MATX = 2 << KIND_SHIFT, + STD_VECTOR = 3 << KIND_SHIFT, + STD_VECTOR_VECTOR = 4 << KIND_SHIFT, + STD_VECTOR_MAT = 5 << KIND_SHIFT, + EXPR = 6 << KIND_SHIFT, + OPENGL_BUFFER = 7 << KIND_SHIFT, + CUDA_HOST_MEM = 8 << KIND_SHIFT, + CUDA_GPU_MAT = 9 << KIND_SHIFT, + UMAT =10 << KIND_SHIFT, + STD_VECTOR_UMAT =11 << KIND_SHIFT, + STD_BOOL_VECTOR =12 << KIND_SHIFT, + STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT, + STD_ARRAY =14 << KIND_SHIFT, + STD_ARRAY_MAT =15 << KIND_SHIFT + }; + + _InputArray(); + _InputArray(int _flags, void* _obj); + _InputArray(const Mat& m); + _InputArray(const MatExpr& expr); + _InputArray(const std::vector& vec); + template _InputArray(const Mat_<_Tp>& m); + template _InputArray(const std::vector<_Tp>& vec); + _InputArray(const std::vector& vec); + template _InputArray(const std::vector >& vec); + _InputArray(const std::vector >&) = delete; // not supported + template _InputArray(const std::vector >& vec); + template _InputArray(const _Tp* vec, int n); + template _InputArray(const Matx<_Tp, m, n>& matx); + _InputArray(const double& val); + _InputArray(const cuda::GpuMat& d_mat); + _InputArray(const std::vector& d_mat_array); + _InputArray(const ogl::Buffer& buf); + _InputArray(const cuda::HostMem& cuda_mem); + template _InputArray(const cudev::GpuMat_<_Tp>& m); + _InputArray(const UMat& um); + _InputArray(const std::vector& umv); + + template _InputArray(const std::array<_Tp, _Nm>& arr); + template _InputArray(const std::array& arr); + + template static _InputArray rawIn(const std::vector<_Tp>& vec); + template static _InputArray rawIn(const std::array<_Tp, _Nm>& arr); + + Mat getMat(int idx=-1) const; + Mat getMat_(int idx=-1) const; + UMat getUMat(int idx=-1) const; + void getMatVector(std::vector& mv) const; + void getUMatVector(std::vector& umv) const; + void getGpuMatVector(std::vector& gpumv) const; + cuda::GpuMat getGpuMat() const; + ogl::Buffer getOGlBuffer() const; + + int getFlags() const; + void* getObj() const; + Size getSz() const; + + _InputArray::KindFlag kind() const; + int dims(int i=-1) const; + int cols(int i=-1) const; + int rows(int i=-1) const; + Size size(int i=-1) const; + int sizend(int* sz, int i=-1) const; + bool sameSize(const _InputArray& arr) const; + size_t total(int i=-1) const; + int type(int i=-1) const; + int depth(int i=-1) const; + int channels(int i=-1) const; + bool isContinuous(int i=-1) const; + bool isSubmatrix(int i=-1) const; + bool empty() const; + void copyTo(const _OutputArray& arr) const; + void copyTo(const _OutputArray& arr, const _InputArray & mask) const; + size_t offset(int i=-1) const; + size_t step(int i=-1) const; + bool isMat() const; + bool isUMat() const; + bool isMatVector() const; + bool isUMatVector() const; + bool isMatx() const; + bool isVector() const; + bool isGpuMat() const; + bool isGpuMatVector() const; + ~_InputArray(); + +protected: + int flags; + void* obj; + Size sz; + + void init(int _flags, const void* _obj); + void init(int _flags, const void* _obj, Size _sz); +}; +CV_ENUM_FLAGS(_InputArray::KindFlag) +__CV_ENUM_FLAGS_BITWISE_AND(_InputArray::KindFlag, int, _InputArray::KindFlag) + +/** @brief This type is very similar to InputArray except that it is used for input/output and output function +parameters. + +Just like with InputArray, OpenCV users should not care about OutputArray, they just pass `Mat`, +`vector` etc. to the functions. The same limitation as for `InputArray`: *Do not explicitly +create OutputArray instances* applies here too. + +If you want to make your function polymorphic (i.e. accept different arrays as output parameters), +it is also not very difficult. Take the sample above as the reference. Note that +_OutputArray::create() needs to be called before _OutputArray::getMat(). This way you guarantee +that the output array is properly allocated. + +Optional output parameters. If you do not need certain output array to be computed and returned to +you, pass cv::noArray(), just like you would in the case of optional input array. At the +implementation level, use _OutputArray::needed() to check if certain output array needs to be +computed or not. + +There are several synonyms for OutputArray that are used to assist automatic Python/Java/... wrapper +generators: +@code + typedef OutputArray OutputArrayOfArrays; + typedef OutputArray InputOutputArray; + typedef OutputArray InputOutputArrayOfArrays; +@endcode + */ +class CV_EXPORTS _OutputArray : public _InputArray +{ +public: + enum DepthMask + { + DEPTH_MASK_8U = 1 << CV_8U, + DEPTH_MASK_8S = 1 << CV_8S, + DEPTH_MASK_16U = 1 << CV_16U, + DEPTH_MASK_16S = 1 << CV_16S, + DEPTH_MASK_32S = 1 << CV_32S, + DEPTH_MASK_32F = 1 << CV_32F, + DEPTH_MASK_64F = 1 << CV_64F, + DEPTH_MASK_16F = 1 << CV_16F, + DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1, + DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S, + DEPTH_MASK_ALL_16F = (DEPTH_MASK_16F<<1)-1, + DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F + }; + + _OutputArray(); + _OutputArray(int _flags, void* _obj); + _OutputArray(Mat& m); + _OutputArray(std::vector& vec); + _OutputArray(cuda::GpuMat& d_mat); + _OutputArray(std::vector& d_mat); + _OutputArray(ogl::Buffer& buf); + _OutputArray(cuda::HostMem& cuda_mem); + template _OutputArray(cudev::GpuMat_<_Tp>& m); + template _OutputArray(std::vector<_Tp>& vec); + _OutputArray(std::vector& vec) = delete; // not supported + template _OutputArray(std::vector >& vec); + _OutputArray(std::vector >&) = delete; // not supported + template _OutputArray(std::vector >& vec); + template _OutputArray(Mat_<_Tp>& m); + template _OutputArray(_Tp* vec, int n); + template _OutputArray(Matx<_Tp, m, n>& matx); + _OutputArray(UMat& m); + _OutputArray(std::vector& vec); + + _OutputArray(const Mat& m); + _OutputArray(const std::vector& vec); + _OutputArray(const cuda::GpuMat& d_mat); + _OutputArray(const std::vector& d_mat); + _OutputArray(const ogl::Buffer& buf); + _OutputArray(const cuda::HostMem& cuda_mem); + template _OutputArray(const cudev::GpuMat_<_Tp>& m); + template _OutputArray(const std::vector<_Tp>& vec); + template _OutputArray(const std::vector >& vec); + template _OutputArray(const std::vector >& vec); + template _OutputArray(const Mat_<_Tp>& m); + template _OutputArray(const _Tp* vec, int n); + template _OutputArray(const Matx<_Tp, m, n>& matx); + _OutputArray(const UMat& m); + _OutputArray(const std::vector& vec); + + template _OutputArray(std::array<_Tp, _Nm>& arr); + template _OutputArray(const std::array<_Tp, _Nm>& arr); + template _OutputArray(std::array& arr); + template _OutputArray(const std::array& arr); + + template static _OutputArray rawOut(std::vector<_Tp>& vec); + template static _OutputArray rawOut(std::array<_Tp, _Nm>& arr); + + bool fixedSize() const; + bool fixedType() const; + bool needed() const; + Mat& getMatRef(int i=-1) const; + UMat& getUMatRef(int i=-1) const; + cuda::GpuMat& getGpuMatRef() const; + std::vector& getGpuMatVecRef() const; + ogl::Buffer& getOGlBufferRef() const; + cuda::HostMem& getHostMemRef() const; + void create(Size sz, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const; + void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const; + void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const; + void createSameSize(const _InputArray& arr, int mtype) const; + void release() const; + void clear() const; + void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const; + + void assign(const UMat& u) const; + void assign(const Mat& m) const; + + void assign(const std::vector& v) const; + void assign(const std::vector& v) const; + + void move(UMat& u) const; + void move(Mat& m) const; +}; + + +class CV_EXPORTS _InputOutputArray : public _OutputArray +{ +public: + _InputOutputArray(); + _InputOutputArray(int _flags, void* _obj); + _InputOutputArray(Mat& m); + _InputOutputArray(std::vector& vec); + _InputOutputArray(cuda::GpuMat& d_mat); + _InputOutputArray(ogl::Buffer& buf); + _InputOutputArray(cuda::HostMem& cuda_mem); + template _InputOutputArray(cudev::GpuMat_<_Tp>& m); + template _InputOutputArray(std::vector<_Tp>& vec); + _InputOutputArray(std::vector& vec) = delete; // not supported + template _InputOutputArray(std::vector >& vec); + template _InputOutputArray(std::vector >& vec); + template _InputOutputArray(Mat_<_Tp>& m); + template _InputOutputArray(_Tp* vec, int n); + template _InputOutputArray(Matx<_Tp, m, n>& matx); + _InputOutputArray(UMat& m); + _InputOutputArray(std::vector& vec); + + _InputOutputArray(const Mat& m); + _InputOutputArray(const std::vector& vec); + _InputOutputArray(const cuda::GpuMat& d_mat); + _InputOutputArray(const std::vector& d_mat); + _InputOutputArray(const ogl::Buffer& buf); + _InputOutputArray(const cuda::HostMem& cuda_mem); + template _InputOutputArray(const cudev::GpuMat_<_Tp>& m); + template _InputOutputArray(const std::vector<_Tp>& vec); + template _InputOutputArray(const std::vector >& vec); + template _InputOutputArray(const std::vector >& vec); + template _InputOutputArray(const Mat_<_Tp>& m); + template _InputOutputArray(const _Tp* vec, int n); + template _InputOutputArray(const Matx<_Tp, m, n>& matx); + _InputOutputArray(const UMat& m); + _InputOutputArray(const std::vector& vec); + + template _InputOutputArray(std::array<_Tp, _Nm>& arr); + template _InputOutputArray(const std::array<_Tp, _Nm>& arr); + template _InputOutputArray(std::array& arr); + template _InputOutputArray(const std::array& arr); + + template static _InputOutputArray rawInOut(std::vector<_Tp>& vec); + template _InputOutputArray rawInOut(std::array<_Tp, _Nm>& arr); + +}; + +/** Helper to wrap custom types. @see InputArray */ +template static inline _InputArray rawIn(_Tp& v); +/** Helper to wrap custom types. @see InputArray */ +template static inline _OutputArray rawOut(_Tp& v); +/** Helper to wrap custom types. @see InputArray */ +template static inline _InputOutputArray rawInOut(_Tp& v); + +CV__DEBUG_NS_END + +typedef const _InputArray& InputArray; +typedef InputArray InputArrayOfArrays; +typedef const _OutputArray& OutputArray; +typedef OutputArray OutputArrayOfArrays; +typedef const _InputOutputArray& InputOutputArray; +typedef InputOutputArray InputOutputArrayOfArrays; + +CV_EXPORTS InputOutputArray noArray(); + +/////////////////////////////////// MatAllocator ////////////////////////////////////// + +//! Usage flags for allocator +enum UMatUsageFlags +{ + USAGE_DEFAULT = 0, + + // buffer allocation policy is platform and usage specific + USAGE_ALLOCATE_HOST_MEMORY = 1 << 0, + USAGE_ALLOCATE_DEVICE_MEMORY = 1 << 1, + USAGE_ALLOCATE_SHARED_MEMORY = 1 << 2, // It is not equal to: USAGE_ALLOCATE_HOST_MEMORY | USAGE_ALLOCATE_DEVICE_MEMORY + + __UMAT_USAGE_FLAGS_32BIT = 0x7fffffff // Binary compatibility hint +}; + +struct CV_EXPORTS UMatData; + +/** @brief Custom array allocator +*/ +class CV_EXPORTS MatAllocator +{ +public: + MatAllocator() {} + virtual ~MatAllocator() {} + + // let's comment it off for now to detect and fix all the uses of allocator + //virtual void allocate(int dims, const int* sizes, int type, int*& refcount, + // uchar*& datastart, uchar*& data, size_t* step) = 0; + //virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0; + virtual UMatData* allocate(int dims, const int* sizes, int type, + void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const = 0; + virtual bool allocate(UMatData* data, AccessFlag accessflags, UMatUsageFlags usageFlags) const = 0; + virtual void deallocate(UMatData* data) const = 0; + virtual void map(UMatData* data, AccessFlag accessflags) const; + virtual void unmap(UMatData* data) const; + virtual void download(UMatData* data, void* dst, int dims, const size_t sz[], + const size_t srcofs[], const size_t srcstep[], + const size_t dststep[]) const; + virtual void upload(UMatData* data, const void* src, int dims, const size_t sz[], + const size_t dstofs[], const size_t dststep[], + const size_t srcstep[]) const; + virtual void copy(UMatData* srcdata, UMatData* dstdata, int dims, const size_t sz[], + const size_t srcofs[], const size_t srcstep[], + const size_t dstofs[], const size_t dststep[], bool sync) const; + + // default implementation returns DummyBufferPoolController + virtual BufferPoolController* getBufferPoolController(const char* id = NULL) const; +}; + + +//////////////////////////////// MatCommaInitializer ////////////////////////////////// + +/** @brief Comma-separated Matrix Initializer + + The class instances are usually not created explicitly. + Instead, they are created on "matrix << firstValue" operator. + + The sample below initializes 2x2 rotation matrix: + + \code + double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180); + Mat R = (Mat_(2,2) << a, -b, b, a); + \endcode +*/ +template class MatCommaInitializer_ +{ +public: + //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat + MatCommaInitializer_(Mat_<_Tp>* _m); + //! the operator that takes the next value and put it to the matrix + template MatCommaInitializer_<_Tp>& operator , (T2 v); + //! another form of conversion operator + operator Mat_<_Tp>() const; +protected: + MatIterator_<_Tp> it; +}; + + +/////////////////////////////////////// Mat /////////////////////////////////////////// + +// note that umatdata might be allocated together +// with the matrix data, not as a separate object. +// therefore, it does not have constructor or destructor; +// it should be explicitly initialized using init(). +struct CV_EXPORTS UMatData +{ + enum MemoryFlag { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2, + DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24, + USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64, + ASYNC_CLEANUP=128 + }; + UMatData(const MatAllocator* allocator); + ~UMatData(); + + // provide atomic access to the structure + void lock(); + void unlock(); + + bool hostCopyObsolete() const; + bool deviceCopyObsolete() const; + bool deviceMemMapped() const; + bool copyOnMap() const; + bool tempUMat() const; + bool tempCopiedUMat() const; + void markHostCopyObsolete(bool flag); + void markDeviceCopyObsolete(bool flag); + void markDeviceMemMapped(bool flag); + + const MatAllocator* prevAllocator; + const MatAllocator* currAllocator; + int urefcount; + int refcount; + uchar* data; + uchar* origdata; + size_t size; + + UMatData::MemoryFlag flags; + void* handle; + void* userdata; + int allocatorFlags_; + int mapcount; + UMatData* originalUMatData; +}; +CV_ENUM_FLAGS(UMatData::MemoryFlag) + + +struct CV_EXPORTS MatSize +{ + explicit MatSize(int* _p); + int dims() const; + Size operator()() const; + const int& operator[](int i) const; + int& operator[](int i); + operator const int*() const; // TODO OpenCV 4.0: drop this + bool operator == (const MatSize& sz) const; + bool operator != (const MatSize& sz) const; + + int* p; +}; + +struct CV_EXPORTS MatStep +{ + MatStep(); + explicit MatStep(size_t s); + const size_t& operator[](int i) const; + size_t& operator[](int i); + operator size_t() const; + MatStep& operator = (size_t s); + + size_t* p; + size_t buf[2]; +protected: + MatStep& operator = (const MatStep&); +}; + +/** @example samples/cpp/cout_mat.cpp +An example demonstrating the serial out capabilities of cv::Mat +*/ + + /** @brief n-dimensional dense array class \anchor CVMat_Details + +The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It +can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel +volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms +may be better stored in a SparseMat ). The data layout of the array `M` is defined by the array +`M.step[]`, so that the address of element \f$(i_0,...,i_{M.dims-1})\f$, where \f$0\leq i_k= M.step[i+1]` (in fact, `M.step[i] >= M.step[i+1]*M.size[i+1]` ). This means +that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane, +and so on. M.step[M.dims-1] is minimal and always equal to the element size M.elemSize() . + +So, the data layout in Mat is compatible with the majority of dense array types from the standard +toolkits and SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, +that is, with any array that uses *steps* (or *strides*) to compute the position of a pixel. +Due to this compatibility, it is possible to make a Mat header for user-allocated data and process +it in-place using OpenCV functions. + +There are many different ways to create a Mat object. The most popular options are listed below: + +- Use the create(nrows, ncols, type) method or the similar Mat(nrows, ncols, type[, fillValue]) +constructor. A new array of the specified size and type is allocated. type has the same meaning as +in the cvCreateMat method. For example, CV_8UC1 means a 8-bit single-channel array, CV_32FC2 +means a 2-channel (complex) floating-point array, and so on. +@code + // make a 7x7 complex matrix filled with 1+3j. + Mat M(7,7,CV_32FC2,Scalar(1,3)); + // and now turn M to a 100x60 15-channel 8-bit matrix. + // The old content will be deallocated + M.create(100,60,CV_8UC(15)); +@endcode +As noted in the introduction to this chapter, create() allocates only a new array when the shape +or type of the current array are different from the specified ones. + +- Create a multi-dimensional array: +@code + // create a 100x100x100 8-bit array + int sz[] = {100, 100, 100}; + Mat bigCube(3, sz, CV_8U, Scalar::all(0)); +@endcode +It passes the number of dimensions =1 to the Mat constructor but the created array will be +2-dimensional with the number of columns set to 1. So, Mat::dims is always \>= 2 (can also be 0 +when the array is empty). + +- Use a copy constructor or assignment operator where there can be an array or expression on the +right side (see below). As noted in the introduction, the array assignment is an O(1) operation +because it only copies the header and increases the reference counter. The Mat::clone() method can +be used to get a full (deep) copy of the array when you need it. + +- Construct a header for a part of another array. It can be a single row, single column, several +rows, several columns, rectangular region in the array (called a *minor* in algebra) or a +diagonal. Such operations are also O(1) because the new header references the same data. You can +actually modify a part of the array using this feature, for example: +@code + // add the 5-th row, multiplied by 3 to the 3rd row + M.row(3) = M.row(3) + M.row(5)*3; + // now copy the 7-th column to the 1-st column + // M.col(1) = M.col(7); // this will not work + Mat M1 = M.col(1); + M.col(7).copyTo(M1); + // create a new 320x240 image + Mat img(Size(320,240),CV_8UC3); + // select a ROI + Mat roi(img, Rect(10,10,100,100)); + // fill the ROI with (0,255,0) (which is green in RGB space); + // the original 320x240 image will be modified + roi = Scalar(0,255,0); +@endcode +Due to the additional datastart and dataend members, it is possible to compute a relative +sub-array position in the main *container* array using locateROI(): +@code + Mat A = Mat::eye(10, 10, CV_32S); + // extracts A columns, 1 (inclusive) to 3 (exclusive). + Mat B = A(Range::all(), Range(1, 3)); + // extracts B rows, 5 (inclusive) to 9 (exclusive). + // that is, C \~ A(Range(5, 9), Range(1, 3)) + Mat C = B(Range(5, 9), Range::all()); + Size size; Point ofs; + C.locateROI(size, ofs); + // size will be (width=10,height=10) and the ofs will be (x=1, y=5) +@endcode +As in case of whole matrices, if you need a deep copy, use the `clone()` method of the extracted +sub-matrices. + +- Make a header for user-allocated data. It can be useful to do the following: + -# Process "foreign" data using OpenCV (for example, when you implement a DirectShow\* filter or + a processing module for gstreamer, and so on). For example: + @code + void process_video_frame(const unsigned char* pixels, + int width, int height, int step) + { + Mat img(height, width, CV_8UC3, pixels, step); + GaussianBlur(img, img, Size(7,7), 1.5, 1.5); + } + @endcode + -# Quickly initialize small matrices and/or get a super-fast element access. + @code + double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; + Mat M = Mat(3, 3, CV_64F, m).inv(); + @endcode + . + +- Use MATLAB-style array initializers, zeros(), ones(), eye(), for example: +@code + // create a double-precision identity matrix and add it to M. + M += Mat::eye(M.rows, M.cols, CV_64F); +@endcode + +- Use a comma-separated initializer: +@code + // create a 3x3 double-precision identity matrix + Mat M = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); +@endcode +With this approach, you first call a constructor of the Mat class with the proper parameters, and +then you just put `<< operator` followed by comma-separated values that can be constants, +variables, expressions, and so on. Also, note the extra parentheses required to avoid compilation +errors. + +Once the array is created, it is automatically managed via a reference-counting mechanism. If the +array header is built on top of user-allocated data, you should handle the data by yourself. The +array data is deallocated when no one points to it. If you want to release the data pointed by a +array header before the array destructor is called, use Mat::release(). + +The next important thing to learn about the array class is element access. This manual already +described how to compute an address of each array element. Normally, you are not required to use the +formula directly in the code. If you know the array element type (which can be retrieved using the +method Mat::type() ), you can access the element \f$M_{ij}\f$ of a 2-dimensional array as: +@code + M.at(i,j) += 1.f; +@endcode +assuming that `M` is a double-precision floating-point array. There are several variants of the method +at for a different number of dimensions. + +If you need to process a whole row of a 2D array, the most efficient way is to get the pointer to +the row first, and then just use the plain C operator [] : +@code + // compute sum of positive matrix elements + // (assuming that M is a double-precision matrix) + double sum=0; + for(int i = 0; i < M.rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < M.cols; j++) + sum += std::max(Mi[j], 0.); + } +@endcode +Some operations, like the one above, do not actually depend on the array shape. They just process +elements of an array one by one (or elements from multiple arrays that have the same coordinates, +for example, array addition). Such operations are called *element-wise*. It makes sense to check +whether all the input/output arrays are continuous, namely, have no gaps at the end of each row. If +yes, process them as a long single row: +@code + // compute the sum of positive matrix elements, optimized variant + double sum=0; + int cols = M.cols, rows = M.rows; + if(M.isContinuous()) + { + cols *= rows; + rows = 1; + } + for(int i = 0; i < rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < cols; j++) + sum += std::max(Mi[j], 0.); + } +@endcode +In case of the continuous matrix, the outer loop body is executed just once. So, the overhead is +smaller, which is especially noticeable in case of small matrices. + +Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: +@code + // compute sum of positive matrix elements, iterator-based variant + double sum=0; + MatConstIterator_ it = M.begin(), it_end = M.end(); + for(; it != it_end; ++it) + sum += std::max(*it, 0.); +@endcode +The matrix iterators are random-access iterators, so they can be passed to any STL algorithm, +including std::sort(). + +@note Matrix Expressions and arithmetic see MatExpr +*/ +class CV_EXPORTS Mat +{ +public: + /** + These are various constructors that form a matrix. As noted in the AutomaticAllocation, often + the default constructor is enough, and the proper matrix will be allocated by an OpenCV function. + The constructed matrix can further be assigned to another matrix or matrix expression or can be + allocated with Mat::create . In the former case, the old content is de-referenced. + */ + Mat(); + + /** @overload + @param rows Number of rows in a 2D array. + @param cols Number of columns in a 2D array. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + */ + Mat(int rows, int cols, int type); + + /** @overload + @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the + number of columns go in the reverse order. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + */ + Mat(Size size, int type); + + /** @overload + @param rows Number of rows in a 2D array. + @param cols Number of columns in a 2D array. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param s An optional value to initialize each matrix element with. To set all the matrix elements to + the particular value after the construction, use the assignment operator + Mat::operator=(const Scalar& value) . + */ + Mat(int rows, int cols, int type, const Scalar& s); + + /** @overload + @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the + number of columns go in the reverse order. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param s An optional value to initialize each matrix element with. To set all the matrix elements to + the particular value after the construction, use the assignment operator + Mat::operator=(const Scalar& value) . + */ + Mat(Size size, int type, const Scalar& s); + + /** @overload + @param ndims Array dimensionality. + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + */ + Mat(int ndims, const int* sizes, int type); + + /** @overload + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + */ + Mat(const std::vector& sizes, int type); + + /** @overload + @param ndims Array dimensionality. + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param s An optional value to initialize each matrix element with. To set all the matrix elements to + the particular value after the construction, use the assignment operator + Mat::operator=(const Scalar& value) . + */ + Mat(int ndims, const int* sizes, int type, const Scalar& s); + + /** @overload + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param s An optional value to initialize each matrix element with. To set all the matrix elements to + the particular value after the construction, use the assignment operator + Mat::operator=(const Scalar& value) . + */ + Mat(const std::vector& sizes, int type, const Scalar& s); + + + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + */ + Mat(const Mat& m); + + /** @overload + @param rows Number of rows in a 2D array. + @param cols Number of columns in a 2D array. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param step Number of bytes each matrix row occupies. The value should include the padding bytes at + the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed + and the actual step is calculated as cols*elemSize(). See Mat::elemSize. + */ + Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); + + /** @overload + @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the + number of columns go in the reverse order. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param step Number of bytes each matrix row occupies. The value should include the padding bytes at + the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed + and the actual step is calculated as cols*elemSize(). See Mat::elemSize. + */ + Mat(Size size, int type, void* data, size_t step=AUTO_STEP); + + /** @overload + @param ndims Array dimensionality. + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param steps Array of ndims-1 steps in case of a multi-dimensional array (the last step is always + set to the element size). If not specified, the matrix is assumed to be continuous. + */ + Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); + + /** @overload + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param steps Array of ndims-1 steps in case of a multi-dimensional array (the last step is always + set to the element size). If not specified, the matrix is assumed to be continuous. + */ + Mat(const std::vector& sizes, int type, void* data, const size_t* steps=0); + + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + @param rowRange Range of the m rows to take. As usual, the range start is inclusive and the range + end is exclusive. Use Range::all() to take all the rows. + @param colRange Range of the m columns to take. Use Range::all() to take all the columns. + */ + Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); + + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + @param roi Region of interest. + */ + Mat(const Mat& m, const Rect& roi); + + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + @param ranges Array of selected ranges of m along each dimensionality. + */ + Mat(const Mat& m, const Range* ranges); + + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + @param ranges Array of selected ranges of m along each dimensionality. + */ + Mat(const Mat& m, const std::vector& ranges); + + /** @overload + @param vec STL vector whose elements form the matrix. The matrix has a single column and the number + of rows equal to the number of vector elements. Type of the matrix matches the type of vector + elements. The constructor can handle arbitrary types, for which there is a properly declared + DataType . This means that the vector elements must be primitive numbers or uni-type numerical + tuples of numbers. Mixed-type structures are not supported. The corresponding constructor is + explicit. Since STL vectors are not automatically converted to Mat instances, you should write + Mat(vec) explicitly. Unless you copy the data into the matrix ( copyData=true ), no new elements + will be added to the vector because it can potentially yield vector data reallocation, and, thus, + the matrix data pointer will be invalid. + @param copyData Flag to specify whether the underlying data of the STL vector should be copied + to (true) or shared with (false) the newly constructed matrix. When the data is copied, the + allocated buffer is managed using Mat reference counting mechanism. While the data is shared, + the reference counter is NULL, and you should not deallocate the data until the matrix is not + destructed. + */ + template explicit Mat(const std::vector<_Tp>& vec, bool copyData=false); + + /** @overload + */ + template::value>::type> + explicit Mat(const std::initializer_list<_Tp> list); + + /** @overload + */ + template explicit Mat(const std::initializer_list sizes, const std::initializer_list<_Tp> list); + + /** @overload + */ + template explicit Mat(const std::array<_Tp, _Nm>& arr, bool copyData=false); + + /** @overload + */ + template explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); + + /** @overload + */ + template explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); + + /** @overload + */ + template explicit Mat(const Point_<_Tp>& pt, bool copyData=true); + + /** @overload + */ + template explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); + + /** @overload + */ + template explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); + + //! download data from GpuMat + explicit Mat(const cuda::GpuMat& m); + + //! destructor - calls release() + ~Mat(); + + /** @brief assignment operators + + These are available assignment operators. Since they all are very different, make sure to read the + operator parameters description. + @param m Assigned, right-hand-side matrix. Matrix assignment is an O(1) operation. This means that + no data is copied but the data is shared and the reference counter, if any, is incremented. Before + assigning new data, the old data is de-referenced via Mat::release . + */ + Mat& operator = (const Mat& m); + + /** @overload + @param expr Assigned matrix expression object. As opposite to the first form of the assignment + operation, the second form can reuse already allocated matrix if it has the right size and type to + fit the matrix expression result. It is automatically handled by the real function that the matrix + expressions is expanded to. For example, C=A+B is expanded to add(A, B, C), and add takes care of + automatic C reallocation. + */ + Mat& operator = (const MatExpr& expr); + + //! retrieve UMat from Mat + UMat getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const; + + /** @brief Creates a matrix header for the specified matrix row. + + The method makes a new header for the specified matrix row and returns it. This is an O(1) + operation, regardless of the matrix size. The underlying data of the new matrix is shared with the + original matrix. Here is the example of one of the classical basic matrix processing operations, + axpy, used by LU and many other algorithms: + @code + inline void matrix_axpy(Mat& A, int i, int j, double alpha) + { + A.row(i) += A.row(j)*alpha; + } + @endcode + @note In the current implementation, the following code does not work as expected: + @code + Mat A; + ... + A.row(i) = A.row(j); // will not work + @endcode + This happens because A.row(i) forms a temporary header that is further assigned to another header. + Remember that each of these operations is O(1), that is, no data is copied. Thus, the above + assignment is not true if you may have expected the j-th row to be copied to the i-th row. To + achieve that, you should either turn this simple assignment into an expression or use the + Mat::copyTo method: + @code + Mat A; + ... + // works, but looks a bit obscure. + A.row(i) = A.row(j) + 0; + // this is a bit longer, but the recommended method. + A.row(j).copyTo(A.row(i)); + @endcode + @param y A 0-based row index. + */ + Mat row(int y) const; + + /** @brief Creates a matrix header for the specified matrix column. + + The method makes a new header for the specified matrix column and returns it. This is an O(1) + operation, regardless of the matrix size. The underlying data of the new matrix is shared with the + original matrix. See also the Mat::row description. + @param x A 0-based column index. + */ + Mat col(int x) const; + + /** @brief Creates a matrix header for the specified row span. + + The method makes a new header for the specified row span of the matrix. Similarly to Mat::row and + Mat::col , this is an O(1) operation. + @param startrow An inclusive 0-based start index of the row span. + @param endrow An exclusive 0-based ending index of the row span. + */ + Mat rowRange(int startrow, int endrow) const; + + /** @overload + @param r Range structure containing both the start and the end indices. + */ + Mat rowRange(const Range& r) const; + + /** @brief Creates a matrix header for the specified column span. + + The method makes a new header for the specified column span of the matrix. Similarly to Mat::row and + Mat::col , this is an O(1) operation. + @param startcol An inclusive 0-based start index of the column span. + @param endcol An exclusive 0-based ending index of the column span. + */ + Mat colRange(int startcol, int endcol) const; + + /** @overload + @param r Range structure containing both the start and the end indices. + */ + Mat colRange(const Range& r) const; + + /** @brief Extracts a diagonal from a matrix + + The method makes a new header for the specified matrix diagonal. The new matrix is represented as a + single-column matrix. Similarly to Mat::row and Mat::col, this is an O(1) operation. + @param d index of the diagonal, with the following values: + - `d=0` is the main diagonal. + - `d<0` is a diagonal from the lower half. For example, d=-1 means the diagonal is set + immediately below the main one. + - `d>0` is a diagonal from the upper half. For example, d=1 means the diagonal is set + immediately above the main one. + For example: + @code + Mat m = (Mat_(3,3) << + 1,2,3, + 4,5,6, + 7,8,9); + Mat d0 = m.diag(0); + Mat d1 = m.diag(1); + Mat d_1 = m.diag(-1); + @endcode + The resulting matrices are + @code + d0 = + [1; + 5; + 9] + d1 = + [2; + 6] + d_1 = + [4; + 8] + @endcode + */ + Mat diag(int d=0) const; + + /** @brief creates a diagonal matrix + + The method creates a square diagonal matrix from specified main diagonal. + @param d One-dimensional matrix that represents the main diagonal. + */ + static Mat diag(const Mat& d); + + /** @brief Creates a full copy of the array and the underlying data. + + The method creates a full copy of the array. The original step[] is not taken into account. So, the + array copy is a continuous array occupying total()*elemSize() bytes. + */ + Mat clone() const CV_NODISCARD; + + /** @brief Copies the matrix to another one. + + The method copies the matrix data to another matrix. Before copying the data, the method invokes : + @code + m.create(this->size(), this->type()); + @endcode + so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the + function does not handle the case of a partial overlap between the source and the destination + matrices. + + When the operation mask is specified, if the Mat::create call shown above reallocates the matrix, + the newly allocated matrix is initialized with all zeros before copying the data. + @param m Destination matrix. If it does not have a proper size or type before the operation, it is + reallocated. + */ + void copyTo( OutputArray m ) const; + + /** @overload + @param m Destination matrix. If it does not have a proper size or type before the operation, it is + reallocated. + @param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix + elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels. + */ + void copyTo( OutputArray m, InputArray mask ) const; + + /** @brief Converts an array to another data type with optional scaling. + + The method converts source pixel values to the target data type. saturate_cast\<\> is applied at + the end to avoid possible overflows: + + \f[m(x,y) = saturate \_ cast( \alpha (*this)(x,y) + \beta )\f] + @param m output matrix; if it does not have a proper size or type before the operation, it is + reallocated. + @param rtype desired output matrix type or, rather, the depth since the number of channels are the + same as the input has; if rtype is negative, the output matrix will have the same type as the input. + @param alpha optional scale factor. + @param beta optional delta added to the scaled values. + */ + void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; + + /** @brief Provides a functional form of convertTo. + + This is an internally used method called by the @ref MatrixExpressions engine. + @param m Destination array. + @param type Desired destination array depth (or -1 if it should be the same as the source type). + */ + void assignTo( Mat& m, int type=-1 ) const; + + /** @brief Sets all or some of the array elements to the specified value. + @param s Assigned scalar converted to the actual array type. + */ + Mat& operator = (const Scalar& s); + + /** @brief Sets all or some of the array elements to the specified value. + + This is an advanced variant of the Mat::operator=(const Scalar& s) operator. + @param value Assigned scalar converted to the actual array type. + @param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix + elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels + */ + Mat& setTo(InputArray value, InputArray mask=noArray()); + + /** @brief Changes the shape and/or the number of channels of a 2D matrix without copying the data. + + The method makes a new matrix header for \*this elements. The new matrix may have a different size + and/or different number of channels. Any combination is possible if: + - No extra elements are included into the new matrix and no elements are excluded. Consequently, + the product rows\*cols\*channels() must stay the same after the transformation. + - No data is copied. That is, this is an O(1) operation. Consequently, if you change the number of + rows, or the operation changes the indices of elements row in some other way, the matrix must be + continuous. See Mat::isContinuous . + + For example, if there is a set of 3D points stored as an STL vector, and you want to represent the + points as a 3xN matrix, do the following: + @code + std::vector vec; + ... + Mat pointMat = Mat(vec). // convert vector to Mat, O(1) operation + reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel. + // Also, an O(1) operation + t(); // finally, transpose the Nx3 matrix. + // This involves copying all the elements + @endcode + @param cn New number of channels. If the parameter is 0, the number of channels remains the same. + @param rows New number of rows. If the parameter is 0, the number of rows remains the same. + */ + Mat reshape(int cn, int rows=0) const; + + /** @overload */ + Mat reshape(int cn, int newndims, const int* newsz) const; + + /** @overload */ + Mat reshape(int cn, const std::vector& newshape) const; + + /** @brief Transposes a matrix. + + The method performs matrix transposition by means of matrix expressions. It does not perform the + actual transposition but returns a temporary matrix transposition object that can be further used as + a part of more complex matrix expressions or can be assigned to a matrix: + @code + Mat A1 = A + Mat::eye(A.size(), A.type())*lambda; + Mat C = A1.t()*A1; // compute (A + lambda*I)^t * (A + lamda*I) + @endcode + */ + MatExpr t() const; + + /** @brief Inverses a matrix. + + The method performs a matrix inversion by means of matrix expressions. This means that a temporary + matrix inversion object is returned by the method and can be used further as a part of more complex + matrix expressions or can be assigned to a matrix. + @param method Matrix inversion method. One of cv::DecompTypes + */ + MatExpr inv(int method=DECOMP_LU) const; + + /** @brief Performs an element-wise multiplication or division of the two matrices. + + The method returns a temporary object encoding per-element array multiplication, with optional + scale. Note that this is not a matrix multiplication that corresponds to a simpler "\*" operator. + + Example: + @code + Mat C = A.mul(5/B); // equivalent to divide(A, B, C, 5) + @endcode + @param m Another array of the same type and the same size as \*this, or a matrix expression. + @param scale Optional scale factor. + */ + MatExpr mul(InputArray m, double scale=1) const; + + /** @brief Computes a cross-product of two 3-element vectors. + + The method computes a cross-product of two 3-element vectors. The vectors must be 3-element + floating-point vectors of the same shape and size. The result is another 3-element vector of the + same shape and type as operands. + @param m Another cross-product operand. + */ + Mat cross(InputArray m) const; + + /** @brief Computes a dot-product of two vectors. + + The method computes a dot-product of two matrices. If the matrices are not single-column or + single-row vectors, the top-to-bottom left-to-right scan ordering is used to treat them as 1D + vectors. The vectors must have the same size and type. If the matrices have more than one channel, + the dot products from all the channels are summed together. + @param m another dot-product operand. + */ + double dot(InputArray m) const; + + /** @brief Returns a zero array of the specified size and type. + + The method returns a Matlab-style zero array initializer. It can be used to quickly form a constant + array as a function parameter, part of a matrix expression, or as a matrix initializer: + @code + Mat A; + A = Mat::zeros(3, 3, CV_32F); + @endcode + In the example above, a new matrix is allocated only if A is not a 3x3 floating-point matrix. + Otherwise, the existing matrix A is filled with zeros. + @param rows Number of rows. + @param cols Number of columns. + @param type Created matrix type. + */ + static MatExpr zeros(int rows, int cols, int type); + + /** @overload + @param size Alternative to the matrix size specification Size(cols, rows) . + @param type Created matrix type. + */ + static MatExpr zeros(Size size, int type); + + /** @overload + @param ndims Array dimensionality. + @param sz Array of integers specifying the array shape. + @param type Created matrix type. + */ + static MatExpr zeros(int ndims, const int* sz, int type); + + /** @brief Returns an array of all 1's of the specified size and type. + + The method returns a Matlab-style 1's array initializer, similarly to Mat::zeros. Note that using + this method you can initialize an array with an arbitrary value, using the following Matlab idiom: + @code + Mat A = Mat::ones(100, 100, CV_8U)*3; // make 100x100 matrix filled with 3. + @endcode + The above operation does not form a 100x100 matrix of 1's and then multiply it by 3. Instead, it + just remembers the scale factor (3 in this case) and use it when actually invoking the matrix + initializer. + @note In case of multi-channels type, only the first channel will be initialized with 1's, the + others will be set to 0's. + @param rows Number of rows. + @param cols Number of columns. + @param type Created matrix type. + */ + static MatExpr ones(int rows, int cols, int type); + + /** @overload + @param size Alternative to the matrix size specification Size(cols, rows) . + @param type Created matrix type. + */ + static MatExpr ones(Size size, int type); + + /** @overload + @param ndims Array dimensionality. + @param sz Array of integers specifying the array shape. + @param type Created matrix type. + */ + static MatExpr ones(int ndims, const int* sz, int type); + + /** @brief Returns an identity matrix of the specified size and type. + + The method returns a Matlab-style identity matrix initializer, similarly to Mat::zeros. Similarly to + Mat::ones, you can use a scale operation to create a scaled identity matrix efficiently: + @code + // make a 4x4 diagonal matrix with 0.1's on the diagonal. + Mat A = Mat::eye(4, 4, CV_32F)*0.1; + @endcode + @note In case of multi-channels type, identity matrix will be initialized only for the first channel, + the others will be set to 0's + @param rows Number of rows. + @param cols Number of columns. + @param type Created matrix type. + */ + static MatExpr eye(int rows, int cols, int type); + + /** @overload + @param size Alternative matrix size specification as Size(cols, rows) . + @param type Created matrix type. + */ + static MatExpr eye(Size size, int type); + + /** @brief Allocates new array data if needed. + + This is one of the key Mat methods. Most new-style OpenCV functions and methods that produce arrays + call this method for each output array. The method uses the following algorithm: + + -# If the current array shape and the type match the new ones, return immediately. Otherwise, + de-reference the previous data by calling Mat::release. + -# Initialize the new header. + -# Allocate the new data of total()\*elemSize() bytes. + -# Allocate the new, associated with the data, reference counter and set it to 1. + + Such a scheme makes the memory management robust and efficient at the same time and helps avoid + extra typing for you. This means that usually there is no need to explicitly allocate output arrays. + That is, instead of writing: + @code + Mat color; + ... + Mat gray(color.rows, color.cols, color.depth()); + cvtColor(color, gray, COLOR_BGR2GRAY); + @endcode + you can simply write: + @code + Mat color; + ... + Mat gray; + cvtColor(color, gray, COLOR_BGR2GRAY); + @endcode + because cvtColor, as well as the most of OpenCV functions, calls Mat::create() for the output array + internally. + @param rows New number of rows. + @param cols New number of columns. + @param type New matrix type. + */ + void create(int rows, int cols, int type); + + /** @overload + @param size Alternative new matrix size specification: Size(cols, rows) + @param type New matrix type. + */ + void create(Size size, int type); + + /** @overload + @param ndims New array dimensionality. + @param sizes Array of integers specifying a new array shape. + @param type New matrix type. + */ + void create(int ndims, const int* sizes, int type); + + /** @overload + @param sizes Array of integers specifying a new array shape. + @param type New matrix type. + */ + void create(const std::vector& sizes, int type); + + /** @brief Increments the reference counter. + + The method increments the reference counter associated with the matrix data. If the matrix header + points to an external data set (see Mat::Mat ), the reference counter is NULL, and the method has no + effect in this case. Normally, to avoid memory leaks, the method should not be called explicitly. It + is called implicitly by the matrix assignment operator. The reference counter increment is an atomic + operation on the platforms that support it. Thus, it is safe to operate on the same matrices + asynchronously in different threads. + */ + void addref(); + + /** @brief Decrements the reference counter and deallocates the matrix if needed. + + The method decrements the reference counter associated with the matrix data. When the reference + counter reaches 0, the matrix data is deallocated and the data and the reference counter pointers + are set to NULL's. If the matrix header points to an external data set (see Mat::Mat ), the + reference counter is NULL, and the method has no effect in this case. + + This method can be called manually to force the matrix data deallocation. But since this method is + automatically called in the destructor, or by any other method that changes the data pointer, it is + usually not needed. The reference counter decrement and check for 0 is an atomic operation on the + platforms that support it. Thus, it is safe to operate on the same matrices asynchronously in + different threads. + */ + void release(); + + //! internal use function, consider to use 'release' method instead; deallocates the matrix data + void deallocate(); + //! internal use function; properly re-allocates _size, _step arrays + void copySize(const Mat& m); + + /** @brief Reserves space for the certain number of rows. + + The method reserves space for sz rows. If the matrix already has enough space to store sz rows, + nothing happens. If the matrix is reallocated, the first Mat::rows rows are preserved. The method + emulates the corresponding method of the STL vector class. + @param sz Number of rows. + */ + void reserve(size_t sz); + + /** @brief Reserves space for the certain number of bytes. + + The method reserves space for sz bytes. If the matrix already has enough space to store sz bytes, + nothing happens. If matrix has to be reallocated its previous content could be lost. + @param sz Number of bytes. + */ + void reserveBuffer(size_t sz); + + /** @brief Changes the number of matrix rows. + + The methods change the number of matrix rows. If the matrix is reallocated, the first + min(Mat::rows, sz) rows are preserved. The methods emulate the corresponding methods of the STL + vector class. + @param sz New number of rows. + */ + void resize(size_t sz); + + /** @overload + @param sz New number of rows. + @param s Value assigned to the newly added elements. + */ + void resize(size_t sz, const Scalar& s); + + //! internal function + void push_back_(const void* elem); + + /** @brief Adds elements to the bottom of the matrix. + + The methods add one or more elements to the bottom of the matrix. They emulate the corresponding + method of the STL vector class. When elem is Mat , its type and the number of columns must be the + same as in the container matrix. + @param elem Added element(s). + */ + template void push_back(const _Tp& elem); + + /** @overload + @param elem Added element(s). + */ + template void push_back(const Mat_<_Tp>& elem); + + /** @overload + @param elem Added element(s). + */ + template void push_back(const std::vector<_Tp>& elem); + + /** @overload + @param m Added line(s). + */ + void push_back(const Mat& m); + + /** @brief Removes elements from the bottom of the matrix. + + The method removes one or more rows from the bottom of the matrix. + @param nelems Number of removed rows. If it is greater than the total number of rows, an exception + is thrown. + */ + void pop_back(size_t nelems=1); + + /** @brief Locates the matrix header within a parent matrix. + + After you extracted a submatrix from a matrix using Mat::row, Mat::col, Mat::rowRange, + Mat::colRange, and others, the resultant submatrix points just to the part of the original big + matrix. However, each submatrix contains information (represented by datastart and dataend + fields) that helps reconstruct the original matrix size and the position of the extracted + submatrix within the original matrix. The method locateROI does exactly that. + @param wholeSize Output parameter that contains the size of the whole matrix containing *this* + as a part. + @param ofs Output parameter that contains an offset of *this* inside the whole matrix. + */ + void locateROI( Size& wholeSize, Point& ofs ) const; + + /** @brief Adjusts a submatrix size and position within the parent matrix. + + The method is complimentary to Mat::locateROI . The typical use of these functions is to determine + the submatrix position within the parent matrix and then shift the position somehow. Typically, it + can be required for filtering operations when pixels outside of the ROI should be taken into + account. When all the method parameters are positive, the ROI needs to grow in all directions by the + specified amount, for example: + @code + A.adjustROI(2, 2, 2, 2); + @endcode + In this example, the matrix size is increased by 4 elements in each direction. The matrix is shifted + by 2 elements to the left and 2 elements up, which brings in all the necessary pixels for the + filtering with the 5x5 kernel. + + adjustROI forces the adjusted ROI to be inside of the parent matrix that is boundaries of the + adjusted ROI are constrained by boundaries of the parent matrix. For example, if the submatrix A is + located in the first row of a parent matrix and you called A.adjustROI(2, 2, 2, 2) then A will not + be increased in the upward direction. + + The function is used internally by the OpenCV filtering functions, like filter2D , morphological + operations, and so on. + @param dtop Shift of the top submatrix boundary upwards. + @param dbottom Shift of the bottom submatrix boundary downwards. + @param dleft Shift of the left submatrix boundary to the left. + @param dright Shift of the right submatrix boundary to the right. + @sa copyMakeBorder + */ + Mat& adjustROI( int dtop, int dbottom, int dleft, int dright ); + + /** @brief Extracts a rectangular submatrix. + + The operators make a new header for the specified sub-array of \*this . They are the most + generalized forms of Mat::row, Mat::col, Mat::rowRange, and Mat::colRange . For example, + `A(Range(0, 10), Range::all())` is equivalent to `A.rowRange(0, 10)`. Similarly to all of the above, + the operators are O(1) operations, that is, no matrix data is copied. + @param rowRange Start and end row of the extracted submatrix. The upper boundary is not included. To + select all the rows, use Range::all(). + @param colRange Start and end column of the extracted submatrix. The upper boundary is not included. + To select all the columns, use Range::all(). + */ + Mat operator()( Range rowRange, Range colRange ) const; + + /** @overload + @param roi Extracted submatrix specified as a rectangle. + */ + Mat operator()( const Rect& roi ) const; + + /** @overload + @param ranges Array of selected ranges along each array dimension. + */ + Mat operator()( const Range* ranges ) const; + + /** @overload + @param ranges Array of selected ranges along each array dimension. + */ + Mat operator()(const std::vector& ranges) const; + + template operator std::vector<_Tp>() const; + template operator Vec<_Tp, n>() const; + template operator Matx<_Tp, m, n>() const; + + template operator std::array<_Tp, _Nm>() const; + + /** @brief Reports whether the matrix is continuous or not. + + The method returns true if the matrix elements are stored continuously without gaps at the end of + each row. Otherwise, it returns false. Obviously, 1x1 or 1xN matrices are always continuous. + Matrices created with Mat::create are always continuous. But if you extract a part of the matrix + using Mat::col, Mat::diag, and so on, or constructed a matrix header for externally allocated data, + such matrices may no longer have this property. + + The continuity flag is stored as a bit in the Mat::flags field and is computed automatically when + you construct a matrix header. Thus, the continuity check is a very fast operation, though + theoretically it could be done as follows: + @code + // alternative implementation of Mat::isContinuous() + bool myCheckMatContinuity(const Mat& m) + { + //return (m.flags & Mat::CONTINUOUS_FLAG) != 0; + return m.rows == 1 || m.step == m.cols*m.elemSize(); + } + @endcode + The method is used in quite a few of OpenCV functions. The point is that element-wise operations + (such as arithmetic and logical operations, math functions, alpha blending, color space + transformations, and others) do not depend on the image geometry. Thus, if all the input and output + arrays are continuous, the functions can process them as very long single-row vectors. The example + below illustrates how an alpha-blending function can be implemented: + @code + template + void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst) + { + const float alpha_scale = (float)std::numeric_limits::max(), + inv_scale = 1.f/alpha_scale; + + CV_Assert( src1.type() == src2.type() && + src1.type() == CV_MAKETYPE(traits::Depth::value, 4) && + src1.size() == src2.size()); + Size size = src1.size(); + dst.create(size, src1.type()); + + // here is the idiom: check the arrays for continuity and, + // if this is the case, + // treat the arrays as 1D vectors + if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + size.width *= 4; + + for( int i = 0; i < size.height; i++ ) + { + // when the arrays are continuous, + // the outer loop is executed only once + const T* ptr1 = src1.ptr(i); + const T* ptr2 = src2.ptr(i); + T* dptr = dst.ptr(i); + + for( int j = 0; j < size.width; j += 4 ) + { + float alpha = ptr1[j+3]*inv_scale, beta = ptr2[j+3]*inv_scale; + dptr[j] = saturate_cast(ptr1[j]*alpha + ptr2[j]*beta); + dptr[j+1] = saturate_cast(ptr1[j+1]*alpha + ptr2[j+1]*beta); + dptr[j+2] = saturate_cast(ptr1[j+2]*alpha + ptr2[j+2]*beta); + dptr[j+3] = saturate_cast((1 - (1-alpha)*(1-beta))*alpha_scale); + } + } + } + @endcode + This approach, while being very simple, can boost the performance of a simple element-operation by + 10-20 percents, especially if the image is rather small and the operation is quite simple. + + Another OpenCV idiom in this function, a call of Mat::create for the destination array, that + allocates the destination array unless it already has the proper size and type. And while the newly + allocated arrays are always continuous, you still need to check the destination array because + Mat::create does not always allocate a new matrix. + */ + bool isContinuous() const; + + //! returns true if the matrix is a submatrix of another matrix + bool isSubmatrix() const; + + /** @brief Returns the matrix element size in bytes. + + The method returns the matrix element size in bytes. For example, if the matrix type is CV_16SC3 , + the method returns 3\*sizeof(short) or 6. + */ + size_t elemSize() const; + + /** @brief Returns the size of each matrix element channel in bytes. + + The method returns the matrix element channel size in bytes, that is, it ignores the number of + channels. For example, if the matrix type is CV_16SC3 , the method returns sizeof(short) or 2. + */ + size_t elemSize1() const; + + /** @brief Returns the type of a matrix element. + + The method returns a matrix element type. This is an identifier compatible with the CvMat type + system, like CV_16SC3 or 16-bit signed 3-channel array, and so on. + */ + int type() const; + + /** @brief Returns the depth of a matrix element. + + The method returns the identifier of the matrix element depth (the type of each individual channel). + For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of + matrix types contains the following values: + - CV_8U - 8-bit unsigned integers ( 0..255 ) + - CV_8S - 8-bit signed integers ( -128..127 ) + - CV_16U - 16-bit unsigned integers ( 0..65535 ) + - CV_16S - 16-bit signed integers ( -32768..32767 ) + - CV_32S - 32-bit signed integers ( -2147483648..2147483647 ) + - CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN ) + - CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN ) + */ + int depth() const; + + /** @brief Returns the number of matrix channels. + + The method returns the number of matrix channels. + */ + int channels() const; + + /** @brief Returns a normalized step. + + The method returns a matrix step divided by Mat::elemSize1() . It can be useful to quickly access an + arbitrary matrix element. + */ + size_t step1(int i=0) const; + + /** @brief Returns true if the array has no elements. + + The method returns true if Mat::total() is 0 or if Mat::data is NULL. Because of pop_back() and + resize() methods `M.total() == 0` does not imply that `M.data == NULL`. + */ + bool empty() const; + + /** @brief Returns the total number of array elements. + + The method returns the number of array elements (a number of pixels if the array represents an + image). + */ + size_t total() const; + + /** @brief Returns the total number of array elements. + + The method returns the number of elements within a certain sub-array slice with startDim <= dim < endDim + */ + size_t total(int startDim, int endDim=INT_MAX) const; + + /** + * @param elemChannels Number of channels or number of columns the matrix should have. + * For a 2-D matrix, when the matrix has only 1 column, then it should have + * elemChannels channels; When the matrix has only 1 channel, + * then it should have elemChannels columns. + * For a 3-D matrix, it should have only one channel. Furthermore, + * if the number of planes is not one, then the number of rows + * within every plane has to be 1; if the number of rows within + * every plane is not 1, then the number of planes has to be 1. + * @param depth The depth the matrix should have. Set it to -1 when any depth is fine. + * @param requireContinuous Set it to true to require the matrix to be continuous + * @return -1 if the requirement is not satisfied. + * Otherwise, it returns the number of elements in the matrix. Note + * that an element may have multiple channels. + * + * The following code demonstrates its usage for a 2-d matrix: + * @snippet snippets/core_mat_checkVector.cpp example-2d + * + * The following code demonstrates its usage for a 3-d matrix: + * @snippet snippets/core_mat_checkVector.cpp example-3d + */ + int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; + + /** @brief Returns a pointer to the specified matrix row. + + The methods return `uchar*` or typed pointer to the specified matrix row. See the sample in + Mat::isContinuous to know how to use these methods. + @param i0 A 0-based row index. + */ + uchar* ptr(int i0=0); + /** @overload */ + const uchar* ptr(int i0=0) const; + + /** @overload + @param row Index along the dimension 0 + @param col Index along the dimension 1 + */ + uchar* ptr(int row, int col); + /** @overload + @param row Index along the dimension 0 + @param col Index along the dimension 1 + */ + const uchar* ptr(int row, int col) const; + + /** @overload */ + uchar* ptr(int i0, int i1, int i2); + /** @overload */ + const uchar* ptr(int i0, int i1, int i2) const; + + /** @overload */ + uchar* ptr(const int* idx); + /** @overload */ + const uchar* ptr(const int* idx) const; + /** @overload */ + template uchar* ptr(const Vec& idx); + /** @overload */ + template const uchar* ptr(const Vec& idx) const; + + /** @overload */ + template _Tp* ptr(int i0=0); + /** @overload */ + template const _Tp* ptr(int i0=0) const; + /** @overload + @param row Index along the dimension 0 + @param col Index along the dimension 1 + */ + template _Tp* ptr(int row, int col); + /** @overload + @param row Index along the dimension 0 + @param col Index along the dimension 1 + */ + template const _Tp* ptr(int row, int col) const; + /** @overload */ + template _Tp* ptr(int i0, int i1, int i2); + /** @overload */ + template const _Tp* ptr(int i0, int i1, int i2) const; + /** @overload */ + template _Tp* ptr(const int* idx); + /** @overload */ + template const _Tp* ptr(const int* idx) const; + /** @overload */ + template _Tp* ptr(const Vec& idx); + /** @overload */ + template const _Tp* ptr(const Vec& idx) const; + + /** @brief Returns a reference to the specified array element. + + The template methods return a reference to the specified array element. For the sake of higher + performance, the index range checks are only performed in the Debug configuration. + + Note that the variants with a single index (i) can be used to access elements of single-row or + single-column 2-dimensional arrays. That is, if, for example, A is a 1 x N floating-point matrix and + B is an M x 1 integer matrix, you can simply write `A.at(k+4)` and `B.at(2*i+1)` + instead of `A.at(0,k+4)` and `B.at(2*i+1,0)`, respectively. + + The example below initializes a Hilbert matrix: + @code + Mat H(100, 100, CV_64F); + for(int i = 0; i < H.rows; i++) + for(int j = 0; j < H.cols; j++) + H.at(i,j)=1./(i+j+1); + @endcode + + Keep in mind that the size identifier used in the at operator cannot be chosen at random. It depends + on the image from which you are trying to retrieve the data. The table below gives a better insight in this: + - If matrix is of type `CV_8U` then use `Mat.at(y,x)`. + - If matrix is of type `CV_8S` then use `Mat.at(y,x)`. + - If matrix is of type `CV_16U` then use `Mat.at(y,x)`. + - If matrix is of type `CV_16S` then use `Mat.at(y,x)`. + - If matrix is of type `CV_32S` then use `Mat.at(y,x)`. + - If matrix is of type `CV_32F` then use `Mat.at(y,x)`. + - If matrix is of type `CV_64F` then use `Mat.at(y,x)`. + + @param i0 Index along the dimension 0 + */ + template _Tp& at(int i0=0); + /** @overload + @param i0 Index along the dimension 0 + */ + template const _Tp& at(int i0=0) const; + /** @overload + @param row Index along the dimension 0 + @param col Index along the dimension 1 + */ + template _Tp& at(int row, int col); + /** @overload + @param row Index along the dimension 0 + @param col Index along the dimension 1 + */ + template const _Tp& at(int row, int col) const; + + /** @overload + @param i0 Index along the dimension 0 + @param i1 Index along the dimension 1 + @param i2 Index along the dimension 2 + */ + template _Tp& at(int i0, int i1, int i2); + /** @overload + @param i0 Index along the dimension 0 + @param i1 Index along the dimension 1 + @param i2 Index along the dimension 2 + */ + template const _Tp& at(int i0, int i1, int i2) const; + + /** @overload + @param idx Array of Mat::dims indices. + */ + template _Tp& at(const int* idx); + /** @overload + @param idx Array of Mat::dims indices. + */ + template const _Tp& at(const int* idx) const; + + /** @overload */ + template _Tp& at(const Vec& idx); + /** @overload */ + template const _Tp& at(const Vec& idx) const; + + /** @overload + special versions for 2D arrays (especially convenient for referencing image pixels) + @param pt Element position specified as Point(j,i) . + */ + template _Tp& at(Point pt); + /** @overload + special versions for 2D arrays (especially convenient for referencing image pixels) + @param pt Element position specified as Point(j,i) . + */ + template const _Tp& at(Point pt) const; + + /** @brief Returns the matrix iterator and sets it to the first matrix element. + + The methods return the matrix read-only or read-write iterators. The use of matrix iterators is very + similar to the use of bi-directional STL iterators. In the example below, the alpha blending + function is rewritten using the matrix iterators: + @code + template + void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst) + { + typedef Vec VT; + + const float alpha_scale = (float)std::numeric_limits::max(), + inv_scale = 1.f/alpha_scale; + + CV_Assert( src1.type() == src2.type() && + src1.type() == traits::Type::value && + src1.size() == src2.size()); + Size size = src1.size(); + dst.create(size, src1.type()); + + MatConstIterator_ it1 = src1.begin(), it1_end = src1.end(); + MatConstIterator_ it2 = src2.begin(); + MatIterator_ dst_it = dst.begin(); + + for( ; it1 != it1_end; ++it1, ++it2, ++dst_it ) + { + VT pix1 = *it1, pix2 = *it2; + float alpha = pix1[3]*inv_scale, beta = pix2[3]*inv_scale; + *dst_it = VT(saturate_cast(pix1[0]*alpha + pix2[0]*beta), + saturate_cast(pix1[1]*alpha + pix2[1]*beta), + saturate_cast(pix1[2]*alpha + pix2[2]*beta), + saturate_cast((1 - (1-alpha)*(1-beta))*alpha_scale)); + } + } + @endcode + */ + template MatIterator_<_Tp> begin(); + template MatConstIterator_<_Tp> begin() const; + + /** @brief Returns the matrix iterator and sets it to the after-last matrix element. + + The methods return the matrix read-only or read-write iterators, set to the point following the last + matrix element. + */ + template MatIterator_<_Tp> end(); + template MatConstIterator_<_Tp> end() const; + + /** @brief Runs the given functor over all matrix elements in parallel. + + The operation passed as argument has to be a function pointer, a function object or a lambda(C++11). + + Example 1. All of the operations below put 0xFF the first channel of all matrix elements: + @code + Mat image(1920, 1080, CV_8UC3); + typedef cv::Point3_ Pixel; + + // first. raw pointer access. + for (int r = 0; r < image.rows; ++r) { + Pixel* ptr = image.ptr(r, 0); + const Pixel* ptr_end = ptr + image.cols; + for (; ptr != ptr_end; ++ptr) { + ptr->x = 255; + } + } + + // Using MatIterator. (Simple but there are a Iterator's overhead) + for (Pixel &p : cv::Mat_(image)) { + p.x = 255; + } + + // Parallel execution with function object. + struct Operator { + void operator ()(Pixel &pixel, const int * position) { + pixel.x = 255; + } + }; + image.forEach(Operator()); + + // Parallel execution using C++11 lambda. + image.forEach([](Pixel &p, const int * position) -> void { + p.x = 255; + }); + @endcode + Example 2. Using the pixel's position: + @code + // Creating 3D matrix (255 x 255 x 255) typed uint8_t + // and initialize all elements by the value which equals elements position. + // i.e. pixels (x,y,z) = (1,2,3) is (b,g,r) = (1,2,3). + + int sizes[] = { 255, 255, 255 }; + typedef cv::Point3_ Pixel; + + Mat_ image = Mat::zeros(3, sizes, CV_8UC3); + + image.forEach([&](Pixel& pixel, const int position[]) -> void { + pixel.x = position[0]; + pixel.y = position[1]; + pixel.z = position[2]; + }); + @endcode + */ + template void forEach(const Functor& operation); + /** @overload */ + template void forEach(const Functor& operation) const; + + Mat(Mat&& m); + Mat& operator = (Mat&& m); + + enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG }; + enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 }; + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + //! the matrix dimensionality, >= 2 + int dims; + //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions + int rows, cols; + //! pointer to the data + uchar* data; + + //! helper fields used in locateROI and adjustROI + const uchar* datastart; + const uchar* dataend; + const uchar* datalimit; + + //! custom allocator + MatAllocator* allocator; + //! and the standard allocator + static MatAllocator* getStdAllocator(); + static MatAllocator* getDefaultAllocator(); + static void setDefaultAllocator(MatAllocator* allocator); + + //! internal use method: updates the continuity flag + void updateContinuityFlag(); + + //! interaction with UMat + UMatData* u; + + MatSize size; + MatStep step; + +protected: + template void forEach_impl(const Functor& operation); +}; + + +///////////////////////////////// Mat_<_Tp> //////////////////////////////////// + +/** @brief Template matrix class derived from Mat + +@code{.cpp} + template class Mat_ : public Mat + { + public: + // ... some specific methods + // and + // no new extra fields + }; +@endcode +The class `Mat_<_Tp>` is a *thin* template wrapper on top of the Mat class. It does not have any +extra data fields. Nor this class nor Mat has any virtual methods. Thus, references or pointers to +these two classes can be freely but carefully converted one to another. For example: +@code{.cpp} + // create a 100x100 8-bit matrix + Mat M(100,100,CV_8U); + // this will be compiled fine. no any data conversion will be done. + Mat_& M1 = (Mat_&)M; + // the program is likely to crash at the statement below + M1(99,99) = 1.f; +@endcode +While Mat is sufficient in most cases, Mat_ can be more convenient if you use a lot of element +access operations and if you know matrix type at the compilation time. Note that +`Mat::at(int y,int x)` and `Mat_::operator()(int y,int x)` do absolutely the same +and run at the same speed, but the latter is certainly shorter: +@code{.cpp} + Mat_ M(20,20); + for(int i = 0; i < M.rows; i++) + for(int j = 0; j < M.cols; j++) + M(i,j) = 1./(i+j+1); + Mat E, V; + eigen(M,E,V); + cout << E.at(0,0)/E.at(M.rows-1,0); +@endcode +To use Mat_ for multi-channel images/matrices, pass Vec as a Mat_ parameter: +@code{.cpp} + // allocate a 320x240 color image and fill it with green (in RGB space) + Mat_ img(240, 320, Vec3b(0,255,0)); + // now draw a diagonal white line + for(int i = 0; i < 100; i++) + img(i,i)=Vec3b(255,255,255); + // and now scramble the 2nd (red) channel of each pixel + for(int i = 0; i < img.rows; i++) + for(int j = 0; j < img.cols; j++) + img(i,j)[2] ^= (uchar)(i ^ j); +@endcode +Mat_ is fully compatible with C++11 range-based for loop. For example such loop +can be used to safely apply look-up table: +@code{.cpp} +void applyTable(Mat_& I, const uchar* const table) +{ + for(auto& pixel : I) + { + pixel = table[pixel]; + } +} +@endcode + */ +template class Mat_ : public Mat +{ +public: + typedef _Tp value_type; + typedef typename DataType<_Tp>::channel_type channel_type; + typedef MatIterator_<_Tp> iterator; + typedef MatConstIterator_<_Tp> const_iterator; + + //! default constructor + Mat_(); + //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type) + Mat_(int _rows, int _cols); + //! constructor that sets each matrix element to specified value + Mat_(int _rows, int _cols, const _Tp& value); + //! equivalent to Mat(_size, DataType<_Tp>::type) + explicit Mat_(Size _size); + //! constructor that sets each matrix element to specified value + Mat_(Size _size, const _Tp& value); + //! n-dim array constructor + Mat_(int _ndims, const int* _sizes); + //! n-dim array constructor that sets each matrix element to specified value + Mat_(int _ndims, const int* _sizes, const _Tp& value); + //! copy/conversion constructor. If m is of different type, it's converted + Mat_(const Mat& m); + //! copy constructor + Mat_(const Mat_& m); + //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type + Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP); + //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type + Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0); + //! selects a submatrix + Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all()); + //! selects a submatrix + Mat_(const Mat_& m, const Rect& roi); + //! selects a submatrix, n-dim version + Mat_(const Mat_& m, const Range* ranges); + //! selects a submatrix, n-dim version + Mat_(const Mat_& m, const std::vector& ranges); + //! from a matrix expression + explicit Mat_(const MatExpr& e); + //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column + explicit Mat_(const std::vector<_Tp>& vec, bool copyData=false); + template explicit Mat_(const Vec::channel_type, n>& vec, bool copyData=true); + template explicit Mat_(const Matx::channel_type, m, n>& mtx, bool copyData=true); + explicit Mat_(const Point_::channel_type>& pt, bool copyData=true); + explicit Mat_(const Point3_::channel_type>& pt, bool copyData=true); + explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer); + + Mat_(std::initializer_list<_Tp> values); + explicit Mat_(const std::initializer_list sizes, const std::initializer_list<_Tp> values); + + template explicit Mat_(const std::array<_Tp, _Nm>& arr, bool copyData=false); + + Mat_& operator = (const Mat& m); + Mat_& operator = (const Mat_& m); + //! set all the elements to s. + Mat_& operator = (const _Tp& s); + //! assign a matrix expression + Mat_& operator = (const MatExpr& e); + + //! iterators; they are smart enough to skip gaps in the end of rows + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + //! template methods for for operation over all matrix elements. + // the operations take care of skipping gaps in the end of rows (if any) + template void forEach(const Functor& operation); + template void forEach(const Functor& operation) const; + + //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type) + void create(int _rows, int _cols); + //! equivalent to Mat::create(_size, DataType<_Tp>::type) + void create(Size _size); + //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type) + void create(int _ndims, const int* _sizes); + //! equivalent to Mat::release() + void release(); + //! cross-product + Mat_ cross(const Mat_& m) const; + //! data type conversion + template operator Mat_() const; + //! overridden forms of Mat::row() etc. + Mat_ row(int y) const; + Mat_ col(int x) const; + Mat_ diag(int d=0) const; + Mat_ clone() const CV_NODISCARD; + + //! overridden forms of Mat::elemSize() etc. + size_t elemSize() const; + size_t elemSize1() const; + int type() const; + int depth() const; + int channels() const; + size_t step1(int i=0) const; + //! returns step()/sizeof(_Tp) + size_t stepT(int i=0) const; + + //! overridden forms of Mat::zeros() etc. Data type is omitted, of course + static MatExpr zeros(int rows, int cols); + static MatExpr zeros(Size size); + static MatExpr zeros(int _ndims, const int* _sizes); + static MatExpr ones(int rows, int cols); + static MatExpr ones(Size size); + static MatExpr ones(int _ndims, const int* _sizes); + static MatExpr eye(int rows, int cols); + static MatExpr eye(Size size); + + //! some more overridden methods + Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright ); + Mat_ operator()( const Range& rowRange, const Range& colRange ) const; + Mat_ operator()( const Rect& roi ) const; + Mat_ operator()( const Range* ranges ) const; + Mat_ operator()(const std::vector& ranges) const; + + //! more convenient forms of row and element access operators + _Tp* operator [](int y); + const _Tp* operator [](int y) const; + + //! returns reference to the specified element + _Tp& operator ()(const int* idx); + //! returns read-only reference to the specified element + const _Tp& operator ()(const int* idx) const; + + //! returns reference to the specified element + template _Tp& operator ()(const Vec& idx); + //! returns read-only reference to the specified element + template const _Tp& operator ()(const Vec& idx) const; + + //! returns reference to the specified element (1D case) + _Tp& operator ()(int idx0); + //! returns read-only reference to the specified element (1D case) + const _Tp& operator ()(int idx0) const; + //! returns reference to the specified element (2D case) + _Tp& operator ()(int row, int col); + //! returns read-only reference to the specified element (2D case) + const _Tp& operator ()(int row, int col) const; + //! returns reference to the specified element (3D case) + _Tp& operator ()(int idx0, int idx1, int idx2); + //! returns read-only reference to the specified element (3D case) + const _Tp& operator ()(int idx0, int idx1, int idx2) const; + + _Tp& operator ()(Point pt); + const _Tp& operator ()(Point pt) const; + + //! conversion to vector. + operator std::vector<_Tp>() const; + + //! conversion to array. + template operator std::array<_Tp, _Nm>() const; + + //! conversion to Vec + template operator Vec::channel_type, n>() const; + //! conversion to Matx + template operator Matx::channel_type, m, n>() const; + + Mat_(Mat_&& m); + Mat_& operator = (Mat_&& m); + + Mat_(Mat&& m); + Mat_& operator = (Mat&& m); + + Mat_(MatExpr&& e); +}; + +typedef Mat_ Mat1b; +typedef Mat_ Mat2b; +typedef Mat_ Mat3b; +typedef Mat_ Mat4b; + +typedef Mat_ Mat1s; +typedef Mat_ Mat2s; +typedef Mat_ Mat3s; +typedef Mat_ Mat4s; + +typedef Mat_ Mat1w; +typedef Mat_ Mat2w; +typedef Mat_ Mat3w; +typedef Mat_ Mat4w; + +typedef Mat_ Mat1i; +typedef Mat_ Mat2i; +typedef Mat_ Mat3i; +typedef Mat_ Mat4i; + +typedef Mat_ Mat1f; +typedef Mat_ Mat2f; +typedef Mat_ Mat3f; +typedef Mat_ Mat4f; + +typedef Mat_ Mat1d; +typedef Mat_ Mat2d; +typedef Mat_ Mat3d; +typedef Mat_ Mat4d; + +/** @todo document */ +class CV_EXPORTS UMat +{ +public: + //! default constructor + UMat(UMatUsageFlags usageFlags = USAGE_DEFAULT); + //! constructs 2D matrix of the specified size and type + // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) + UMat(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT); + UMat(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT); + //! constucts 2D matrix and fills it with the specified value _s. + UMat(int rows, int cols, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT); + UMat(Size size, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT); + + //! constructs n-dimensional matrix + UMat(int ndims, const int* sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT); + UMat(int ndims, const int* sizes, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT); + + //! copy constructor + UMat(const UMat& m); + + //! creates a matrix header for a part of the bigger matrix + UMat(const UMat& m, const Range& rowRange, const Range& colRange=Range::all()); + UMat(const UMat& m, const Rect& roi); + UMat(const UMat& m, const Range* ranges); + UMat(const UMat& m, const std::vector& ranges); + //! builds matrix from std::vector with or without copying the data + template explicit UMat(const std::vector<_Tp>& vec, bool copyData=false); + + //! builds matrix from cv::Vec; the data is copied by default + template explicit UMat(const Vec<_Tp, n>& vec, bool copyData=true); + //! builds matrix from cv::Matx; the data is copied by default + template explicit UMat(const Matx<_Tp, m, n>& mtx, bool copyData=true); + //! builds matrix from a 2D point + template explicit UMat(const Point_<_Tp>& pt, bool copyData=true); + //! builds matrix from a 3D point + template explicit UMat(const Point3_<_Tp>& pt, bool copyData=true); + //! builds matrix from comma initializer + template explicit UMat(const MatCommaInitializer_<_Tp>& commaInitializer); + + //! destructor - calls release() + ~UMat(); + //! assignment operators + UMat& operator = (const UMat& m); + + Mat getMat(AccessFlag flags) const; + + //! returns a new matrix header for the specified row + UMat row(int y) const; + //! returns a new matrix header for the specified column + UMat col(int x) const; + //! ... for the specified row span + UMat rowRange(int startrow, int endrow) const; + UMat rowRange(const Range& r) const; + //! ... for the specified column span + UMat colRange(int startcol, int endcol) const; + UMat colRange(const Range& r) const; + //! ... for the specified diagonal + //! (d=0 - the main diagonal, + //! >0 - a diagonal from the upper half, + //! <0 - a diagonal from the lower half) + UMat diag(int d=0) const; + //! constructs a square diagonal matrix which main diagonal is vector "d" + static UMat diag(const UMat& d); + + //! returns deep copy of the matrix, i.e. the data is copied + UMat clone() const CV_NODISCARD; + //! copies the matrix content to "m". + // It calls m.create(this->size(), this->type()). + void copyTo( OutputArray m ) const; + //! copies those matrix elements to "m" that are marked with non-zero mask elements. + void copyTo( OutputArray m, InputArray mask ) const; + //! converts matrix to another datatype with optional scaling. See cvConvertScale. + void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; + + void assignTo( UMat& m, int type=-1 ) const; + + //! sets every matrix element to s + UMat& operator = (const Scalar& s); + //! sets some of the matrix elements to s, according to the mask + UMat& setTo(InputArray value, InputArray mask=noArray()); + //! creates alternative matrix header for the same data, with different + // number of channels and/or different number of rows. see cvReshape. + UMat reshape(int cn, int rows=0) const; + UMat reshape(int cn, int newndims, const int* newsz) const; + + //! matrix transposition by means of matrix expressions + UMat t() const; + //! matrix inversion by means of matrix expressions + UMat inv(int method=DECOMP_LU) const; + //! per-element matrix multiplication by means of matrix expressions + UMat mul(InputArray m, double scale=1) const; + + //! computes dot-product + double dot(InputArray m) const; + + //! Matlab-style matrix initialization + static UMat zeros(int rows, int cols, int type); + static UMat zeros(Size size, int type); + static UMat zeros(int ndims, const int* sz, int type); + static UMat ones(int rows, int cols, int type); + static UMat ones(Size size, int type); + static UMat ones(int ndims, const int* sz, int type); + static UMat eye(int rows, int cols, int type); + static UMat eye(Size size, int type); + + //! allocates new matrix data unless the matrix already has specified size and type. + // previous data is unreferenced if needed. + void create(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT); + void create(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT); + void create(int ndims, const int* sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT); + void create(const std::vector& sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT); + + //! increases the reference counter; use with care to avoid memleaks + void addref(); + //! decreases reference counter; + // deallocates the data when reference counter reaches 0. + void release(); + + //! deallocates the matrix data + void deallocate(); + //! internal use function; properly re-allocates _size, _step arrays + void copySize(const UMat& m); + + //! locates matrix header within a parent matrix. See below + void locateROI( Size& wholeSize, Point& ofs ) const; + //! moves/resizes the current matrix ROI inside the parent matrix. + UMat& adjustROI( int dtop, int dbottom, int dleft, int dright ); + //! extracts a rectangular sub-matrix + // (this is a generalized form of row, rowRange etc.) + UMat operator()( Range rowRange, Range colRange ) const; + UMat operator()( const Rect& roi ) const; + UMat operator()( const Range* ranges ) const; + UMat operator()(const std::vector& ranges) const; + + //! returns true iff the matrix data is continuous + // (i.e. when there are no gaps between successive rows). + // similar to CV_IS_MAT_CONT(cvmat->type) + bool isContinuous() const; + + //! returns true if the matrix is a submatrix of another matrix + bool isSubmatrix() const; + + //! returns element size in bytes, + // similar to CV_ELEM_SIZE(cvmat->type) + size_t elemSize() const; + //! returns the size of element channel in bytes. + size_t elemSize1() const; + //! returns element type, similar to CV_MAT_TYPE(cvmat->type) + int type() const; + //! returns element type, similar to CV_MAT_DEPTH(cvmat->type) + int depth() const; + //! returns element type, similar to CV_MAT_CN(cvmat->type) + int channels() const; + //! returns step/elemSize1() + size_t step1(int i=0) const; + //! returns true if matrix data is NULL + bool empty() const; + //! returns the total number of matrix elements + size_t total() const; + + //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise + int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; + + UMat(UMat&& m); + UMat& operator = (UMat&& m); + + /*! Returns the OpenCL buffer handle on which UMat operates on. + The UMat instance should be kept alive during the use of the handle to prevent the buffer to be + returned to the OpenCV buffer pool. + */ + void* handle(AccessFlag accessFlags) const; + void ndoffset(size_t* ofs) const; + + enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG }; + enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 }; + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + //! the matrix dimensionality, >= 2 + int dims; + //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions + int rows, cols; + + //! custom allocator + MatAllocator* allocator; + UMatUsageFlags usageFlags; // usage flags for allocator + //! and the standard allocator + static MatAllocator* getStdAllocator(); + + //! internal use method: updates the continuity flag + void updateContinuityFlag(); + + // black-box container of UMat data + UMatData* u; + + // offset of the submatrix (or 0) + size_t offset; + + MatSize size; + MatStep step; + +protected: +}; + + +/////////////////////////// multi-dimensional sparse matrix ////////////////////////// + +/** @brief The class SparseMat represents multi-dimensional sparse numerical arrays. + +Such a sparse array can store elements of any type that Mat can store. *Sparse* means that only +non-zero elements are stored (though, as a result of operations on a sparse matrix, some of its +stored elements can actually become 0. It is up to you to detect such elements and delete them +using SparseMat::erase ). The non-zero elements are stored in a hash table that grows when it is +filled so that the search time is O(1) in average (regardless of whether element is there or not). +Elements can be accessed using the following methods: +- Query operations (SparseMat::ptr and the higher-level SparseMat::ref, SparseMat::value and + SparseMat::find), for example: + @code + const int dims = 5; + int size[5] = {10, 10, 10, 10, 10}; + SparseMat sparse_mat(dims, size, CV_32F); + for(int i = 0; i < 1000; i++) + { + int idx[dims]; + for(int k = 0; k < dims; k++) + idx[k] = rand() % size[k]; + sparse_mat.ref(idx) += 1.f; + } + cout << "nnz = " << sparse_mat.nzcount() << endl; + @endcode +- Sparse matrix iterators. They are similar to MatIterator but different from NAryMatIterator. + That is, the iteration loop is familiar to STL users: + @code + // prints elements of a sparse floating-point matrix + // and the sum of elements. + SparseMatConstIterator_ + it = sparse_mat.begin(), + it_end = sparse_mat.end(); + double s = 0; + int dims = sparse_mat.dims(); + for(; it != it_end; ++it) + { + // print element indices and the element value + const SparseMat::Node* n = it.node(); + printf("("); + for(int i = 0; i < dims; i++) + printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")"); + printf(": %g\n", it.value()); + s += *it; + } + printf("Element sum is %g\n", s); + @endcode + If you run this loop, you will notice that elements are not enumerated in a logical order + (lexicographical, and so on). They come in the same order as they are stored in the hash table + (semi-randomly). You may collect pointers to the nodes and sort them to get the proper ordering. + Note, however, that pointers to the nodes may become invalid when you add more elements to the + matrix. This may happen due to possible buffer reallocation. +- Combination of the above 2 methods when you need to process 2 or more sparse matrices + simultaneously. For example, this is how you can compute unnormalized cross-correlation of the 2 + floating-point sparse matrices: + @code + double cross_corr(const SparseMat& a, const SparseMat& b) + { + const SparseMat *_a = &a, *_b = &b; + // if b contains less elements than a, + // it is faster to iterate through b + if(_a->nzcount() > _b->nzcount()) + std::swap(_a, _b); + SparseMatConstIterator_ it = _a->begin(), + it_end = _a->end(); + double ccorr = 0; + for(; it != it_end; ++it) + { + // take the next element from the first matrix + float avalue = *it; + const Node* anode = it.node(); + // and try to find an element with the same index in the second matrix. + // since the hash value depends only on the element index, + // reuse the hash value stored in the node + float bvalue = _b->value(anode->idx,&anode->hashval); + ccorr += avalue*bvalue; + } + return ccorr; + } + @endcode + */ +class CV_EXPORTS SparseMat +{ +public: + typedef SparseMatIterator iterator; + typedef SparseMatConstIterator const_iterator; + + enum { MAGIC_VAL=0x42FD0000, MAX_DIM=32, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 }; + + //! the sparse matrix header + struct CV_EXPORTS Hdr + { + Hdr(int _dims, const int* _sizes, int _type); + void clear(); + int refcount; + int dims; + int valueOffset; + size_t nodeSize; + size_t nodeCount; + size_t freeList; + std::vector pool; + std::vector hashtab; + int size[MAX_DIM]; + }; + + //! sparse matrix node - element of a hash table + struct CV_EXPORTS Node + { + //! hash value + size_t hashval; + //! index of the next node in the same hash table entry + size_t next; + //! index of the matrix element + int idx[MAX_DIM]; + }; + + /** @brief Various SparseMat constructors. + */ + SparseMat(); + + /** @overload + @param dims Array dimensionality. + @param _sizes Sparce matrix size on all dementions. + @param _type Sparse matrix data type. + */ + SparseMat(int dims, const int* _sizes, int _type); + + /** @overload + @param m Source matrix for copy constructor. If m is dense matrix (ocvMat) then it will be converted + to sparse representation. + */ + SparseMat(const SparseMat& m); + + /** @overload + @param m Source matrix for copy constructor. If m is dense matrix (ocvMat) then it will be converted + to sparse representation. + */ + explicit SparseMat(const Mat& m); + + //! the destructor + ~SparseMat(); + + //! assignment operator. This is O(1) operation, i.e. no data is copied + SparseMat& operator = (const SparseMat& m); + //! equivalent to the corresponding constructor + SparseMat& operator = (const Mat& m); + + //! creates full copy of the matrix + SparseMat clone() const CV_NODISCARD; + + //! copies all the data to the destination matrix. All the previous content of m is erased + void copyTo( SparseMat& m ) const; + //! converts sparse matrix to dense matrix. + void copyTo( Mat& m ) const; + //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type + void convertTo( SparseMat& m, int rtype, double alpha=1 ) const; + //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling. + /*! + @param [out] m - output matrix; if it does not have a proper size or type before the operation, + it is reallocated + @param [in] rtype - desired output matrix type or, rather, the depth since the number of channels + are the same as the input has; if rtype is negative, the output matrix will have the + same type as the input. + @param [in] alpha - optional scale factor + @param [in] beta - optional delta added to the scaled values + */ + void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const; + + // not used now + void assignTo( SparseMat& m, int type=-1 ) const; + + //! reallocates sparse matrix. + /*! + If the matrix already had the proper size and type, + it is simply cleared with clear(), otherwise, + the old matrix is released (using release()) and the new one is allocated. + */ + void create(int dims, const int* _sizes, int _type); + //! sets all the sparse matrix elements to 0, which means clearing the hash table. + void clear(); + //! manually increments the reference counter to the header. + void addref(); + // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated. + void release(); + + //! converts sparse matrix to the old-style representation; all the elements are copied. + //operator CvSparseMat*() const; + //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements) + size_t elemSize() const; + //! returns elemSize()/channels() + size_t elemSize1() const; + + //! returns type of sparse matrix elements + int type() const; + //! returns the depth of sparse matrix elements + int depth() const; + //! returns the number of channels + int channels() const; + + //! returns the array of sizes, or NULL if the matrix is not allocated + const int* size() const; + //! returns the size of i-th matrix dimension (or 0) + int size(int i) const; + //! returns the matrix dimensionality + int dims() const; + //! returns the number of non-zero elements (=the number of hash table nodes) + size_t nzcount() const; + + //! computes the element hash value (1D case) + size_t hash(int i0) const; + //! computes the element hash value (2D case) + size_t hash(int i0, int i1) const; + //! computes the element hash value (3D case) + size_t hash(int i0, int i1, int i2) const; + //! computes the element hash value (nD case) + size_t hash(const int* idx) const; + + //!@{ + /*! + specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case. + return pointer to the matrix element. + - if the element is there (it's non-zero), the pointer to it is returned + - if it's not there and createMissing=false, NULL pointer is returned + - if it's not there and createMissing=true, then the new element + is created and initialized with 0. Pointer to it is returned + - if the optional hashval pointer is not NULL, the element hash value is + not computed, but *hashval is taken instead. + */ + //! returns pointer to the specified element (1D case) + uchar* ptr(int i0, bool createMissing, size_t* hashval=0); + //! returns pointer to the specified element (2D case) + uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0); + //! returns pointer to the specified element (3D case) + uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0); + //! returns pointer to the specified element (nD case) + uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0); + //!@} + + //!@{ + /*! + return read-write reference to the specified sparse matrix element. + + `ref<_Tp>(i0,...[,hashval])` is equivalent to `*(_Tp*)ptr(i0,...,true[,hashval])`. + The methods always return a valid reference. + If the element did not exist, it is created and initialiazed with 0. + */ + //! returns reference to the specified element (1D case) + template _Tp& ref(int i0, size_t* hashval=0); + //! returns reference to the specified element (2D case) + template _Tp& ref(int i0, int i1, size_t* hashval=0); + //! returns reference to the specified element (3D case) + template _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); + //! returns reference to the specified element (nD case) + template _Tp& ref(const int* idx, size_t* hashval=0); + //!@} + + //!@{ + /*! + return value of the specified sparse matrix element. + + `value<_Tp>(i0,...[,hashval])` is equivalent to + @code + { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); } + @endcode + + That is, if the element did not exist, the methods return 0. + */ + //! returns value of the specified element (1D case) + template _Tp value(int i0, size_t* hashval=0) const; + //! returns value of the specified element (2D case) + template _Tp value(int i0, int i1, size_t* hashval=0) const; + //! returns value of the specified element (3D case) + template _Tp value(int i0, int i1, int i2, size_t* hashval=0) const; + //! returns value of the specified element (nD case) + template _Tp value(const int* idx, size_t* hashval=0) const; + //!@} + + //!@{ + /*! + Return pointer to the specified sparse matrix element if it exists + + `find<_Tp>(i0,...[,hashval])` is equivalent to `(_const Tp*)ptr(i0,...false[,hashval])`. + + If the specified element does not exist, the methods return NULL. + */ + //! returns pointer to the specified element (1D case) + template const _Tp* find(int i0, size_t* hashval=0) const; + //! returns pointer to the specified element (2D case) + template const _Tp* find(int i0, int i1, size_t* hashval=0) const; + //! returns pointer to the specified element (3D case) + template const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const; + //! returns pointer to the specified element (nD case) + template const _Tp* find(const int* idx, size_t* hashval=0) const; + //!@} + + //! erases the specified element (2D case) + void erase(int i0, int i1, size_t* hashval=0); + //! erases the specified element (3D case) + void erase(int i0, int i1, int i2, size_t* hashval=0); + //! erases the specified element (nD case) + void erase(const int* idx, size_t* hashval=0); + + //!@{ + /*! + return the sparse matrix iterator pointing to the first sparse matrix element + */ + //! returns the sparse matrix iterator at the matrix beginning + SparseMatIterator begin(); + //! returns the sparse matrix iterator at the matrix beginning + template SparseMatIterator_<_Tp> begin(); + //! returns the read-only sparse matrix iterator at the matrix beginning + SparseMatConstIterator begin() const; + //! returns the read-only sparse matrix iterator at the matrix beginning + template SparseMatConstIterator_<_Tp> begin() const; + //!@} + /*! + return the sparse matrix iterator pointing to the element following the last sparse matrix element + */ + //! returns the sparse matrix iterator at the matrix end + SparseMatIterator end(); + //! returns the read-only sparse matrix iterator at the matrix end + SparseMatConstIterator end() const; + //! returns the typed sparse matrix iterator at the matrix end + template SparseMatIterator_<_Tp> end(); + //! returns the typed read-only sparse matrix iterator at the matrix end + template SparseMatConstIterator_<_Tp> end() const; + + //! returns the value stored in the sparse martix node + template _Tp& value(Node* n); + //! returns the value stored in the sparse martix node + template const _Tp& value(const Node* n) const; + + ////////////// some internal-use methods /////////////// + Node* node(size_t nidx); + const Node* node(size_t nidx) const; + + uchar* newNode(const int* idx, size_t hashval); + void removeNode(size_t hidx, size_t nidx, size_t previdx); + void resizeHashTab(size_t newsize); + + int flags; + Hdr* hdr; +}; + + + +///////////////////////////////// SparseMat_<_Tp> //////////////////////////////////// + +/** @brief Template sparse n-dimensional array class derived from SparseMat + +SparseMat_ is a thin wrapper on top of SparseMat created in the same way as Mat_ . It simplifies +notation of some operations: +@code + int sz[] = {10, 20, 30}; + SparseMat_ M(3, sz); + ... + M.ref(1, 2, 3) = M(4, 5, 6) + M(7, 8, 9); +@endcode + */ +template class SparseMat_ : public SparseMat +{ +public: + typedef SparseMatIterator_<_Tp> iterator; + typedef SparseMatConstIterator_<_Tp> const_iterator; + + //! the default constructor + SparseMat_(); + //! the full constructor equivalent to SparseMat(dims, _sizes, DataType<_Tp>::type) + SparseMat_(int dims, const int* _sizes); + //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted + SparseMat_(const SparseMat& m); + //! the copy constructor. This is O(1) operation - no data is copied + SparseMat_(const SparseMat_& m); + //! converts dense matrix to the sparse form + SparseMat_(const Mat& m); + //! converts the old-style sparse matrix to the C++ class. All the elements are copied + //SparseMat_(const CvSparseMat* m); + //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted + SparseMat_& operator = (const SparseMat& m); + //! the assignment operator. This is O(1) operation - no data is copied + SparseMat_& operator = (const SparseMat_& m); + //! converts dense matrix to the sparse form + SparseMat_& operator = (const Mat& m); + + //! makes full copy of the matrix. All the elements are duplicated + SparseMat_ clone() const CV_NODISCARD; + //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type) + void create(int dims, const int* _sizes); + //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied + //operator CvSparseMat*() const; + + //! returns type of the matrix elements + int type() const; + //! returns depth of the matrix elements + int depth() const; + //! returns the number of channels in each matrix element + int channels() const; + + //! equivalent to SparseMat::ref<_Tp>(i0, hashval) + _Tp& ref(int i0, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval) + _Tp& ref(int i0, int i1, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval) + _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); + //! equivalent to SparseMat::ref<_Tp>(idx, hashval) + _Tp& ref(const int* idx, size_t* hashval=0); + + //! equivalent to SparseMat::value<_Tp>(i0, hashval) + _Tp operator()(int i0, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval) + _Tp operator()(int i0, int i1, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval) + _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const; + //! equivalent to SparseMat::value<_Tp>(idx, hashval) + _Tp operator()(const int* idx, size_t* hashval=0) const; + + //! returns sparse matrix iterator pointing to the first sparse matrix element + SparseMatIterator_<_Tp> begin(); + //! returns read-only sparse matrix iterator pointing to the first sparse matrix element + SparseMatConstIterator_<_Tp> begin() const; + //! returns sparse matrix iterator pointing to the element following the last sparse matrix element + SparseMatIterator_<_Tp> end(); + //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element + SparseMatConstIterator_<_Tp> end() const; +}; + + + +////////////////////////////////// MatConstIterator ////////////////////////////////// + +class CV_EXPORTS MatConstIterator +{ +public: + typedef uchar* value_type; + typedef ptrdiff_t difference_type; + typedef const uchar** pointer; + typedef uchar* reference; + + typedef std::random_access_iterator_tag iterator_category; + + //! default constructor + MatConstIterator(); + //! constructor that sets the iterator to the beginning of the matrix + MatConstIterator(const Mat* _m); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator(const Mat* _m, int _row, int _col=0); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator(const Mat* _m, Point _pt); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator(const Mat* _m, const int* _idx); + //! copy constructor + MatConstIterator(const MatConstIterator& it); + + //! copy operator + MatConstIterator& operator = (const MatConstIterator& it); + //! returns the current matrix element + const uchar* operator *() const; + //! returns the i-th matrix element, relative to the current + const uchar* operator [](ptrdiff_t i) const; + + //! shifts the iterator forward by the specified number of elements + MatConstIterator& operator += (ptrdiff_t ofs); + //! shifts the iterator backward by the specified number of elements + MatConstIterator& operator -= (ptrdiff_t ofs); + //! decrements the iterator + MatConstIterator& operator --(); + //! decrements the iterator + MatConstIterator operator --(int); + //! increments the iterator + MatConstIterator& operator ++(); + //! increments the iterator + MatConstIterator operator ++(int); + //! returns the current iterator position + Point pos() const; + //! returns the current iterator position + void pos(int* _idx) const; + + ptrdiff_t lpos() const; + void seek(ptrdiff_t ofs, bool relative = false); + void seek(const int* _idx, bool relative = false); + + const Mat* m; + size_t elemSize; + const uchar* ptr; + const uchar* sliceStart; + const uchar* sliceEnd; +}; + + + +////////////////////////////////// MatConstIterator_ ///////////////////////////////// + +/** @brief Matrix read-only iterator + */ +template +class MatConstIterator_ : public MatConstIterator +{ +public: + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + typedef std::random_access_iterator_tag iterator_category; + + //! default constructor + MatConstIterator_(); + //! constructor that sets the iterator to the beginning of the matrix + MatConstIterator_(const Mat_<_Tp>* _m); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator_(const Mat_<_Tp>* _m, Point _pt); + //! constructor that sets the iterator to the specified element of the matrix + MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx); + //! copy constructor + MatConstIterator_(const MatConstIterator_& it); + + //! copy operator + MatConstIterator_& operator = (const MatConstIterator_& it); + //! returns the current matrix element + const _Tp& operator *() const; + //! returns the i-th matrix element, relative to the current + const _Tp& operator [](ptrdiff_t i) const; + + //! shifts the iterator forward by the specified number of elements + MatConstIterator_& operator += (ptrdiff_t ofs); + //! shifts the iterator backward by the specified number of elements + MatConstIterator_& operator -= (ptrdiff_t ofs); + //! decrements the iterator + MatConstIterator_& operator --(); + //! decrements the iterator + MatConstIterator_ operator --(int); + //! increments the iterator + MatConstIterator_& operator ++(); + //! increments the iterator + MatConstIterator_ operator ++(int); + //! returns the current iterator position + Point pos() const; +}; + + + +//////////////////////////////////// MatIterator_ //////////////////////////////////// + +/** @brief Matrix read-write iterator +*/ +template +class MatIterator_ : public MatConstIterator_<_Tp> +{ +public: + typedef _Tp* pointer; + typedef _Tp& reference; + + typedef std::random_access_iterator_tag iterator_category; + + //! the default constructor + MatIterator_(); + //! constructor that sets the iterator to the beginning of the matrix + MatIterator_(Mat_<_Tp>* _m); + //! constructor that sets the iterator to the specified element of the matrix + MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0); + //! constructor that sets the iterator to the specified element of the matrix + MatIterator_(Mat_<_Tp>* _m, Point _pt); + //! constructor that sets the iterator to the specified element of the matrix + MatIterator_(Mat_<_Tp>* _m, const int* _idx); + //! copy constructor + MatIterator_(const MatIterator_& it); + //! copy operator + MatIterator_& operator = (const MatIterator_<_Tp>& it ); + + //! returns the current matrix element + _Tp& operator *() const; + //! returns the i-th matrix element, relative to the current + _Tp& operator [](ptrdiff_t i) const; + + //! shifts the iterator forward by the specified number of elements + MatIterator_& operator += (ptrdiff_t ofs); + //! shifts the iterator backward by the specified number of elements + MatIterator_& operator -= (ptrdiff_t ofs); + //! decrements the iterator + MatIterator_& operator --(); + //! decrements the iterator + MatIterator_ operator --(int); + //! increments the iterator + MatIterator_& operator ++(); + //! increments the iterator + MatIterator_ operator ++(int); +}; + + + +/////////////////////////////// SparseMatConstIterator /////////////////////////////// + +/** @brief Read-Only Sparse Matrix Iterator. + + Here is how to use the iterator to compute the sum of floating-point sparse matrix elements: + + \code + SparseMatConstIterator it = m.begin(), it_end = m.end(); + double s = 0; + CV_Assert( m.type() == CV_32F ); + for( ; it != it_end; ++it ) + s += it.value(); + \endcode +*/ +class CV_EXPORTS SparseMatConstIterator +{ +public: + //! the default constructor + SparseMatConstIterator(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatConstIterator(const SparseMat* _m); + //! the copy constructor + SparseMatConstIterator(const SparseMatConstIterator& it); + + //! the assignment operator + SparseMatConstIterator& operator = (const SparseMatConstIterator& it); + + //! template method returning the current matrix element + template const _Tp& value() const; + //! returns the current node of the sparse matrix. it.node->idx is the current element index + const SparseMat::Node* node() const; + + //! moves iterator to the previous element + SparseMatConstIterator& operator --(); + //! moves iterator to the previous element + SparseMatConstIterator operator --(int); + //! moves iterator to the next element + SparseMatConstIterator& operator ++(); + //! moves iterator to the next element + SparseMatConstIterator operator ++(int); + + //! moves iterator to the element after the last element + void seekEnd(); + + const SparseMat* m; + size_t hashidx; + uchar* ptr; +}; + + + +////////////////////////////////// SparseMatIterator ///////////////////////////////// + +/** @brief Read-write Sparse Matrix Iterator + + The class is similar to cv::SparseMatConstIterator, + but can be used for in-place modification of the matrix elements. +*/ +class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator +{ +public: + //! the default constructor + SparseMatIterator(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatIterator(SparseMat* _m); + //! the full constructor setting the iterator to the specified sparse matrix element + SparseMatIterator(SparseMat* _m, const int* idx); + //! the copy constructor + SparseMatIterator(const SparseMatIterator& it); + + //! the assignment operator + SparseMatIterator& operator = (const SparseMatIterator& it); + //! returns read-write reference to the current sparse matrix element + template _Tp& value() const; + //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!) + SparseMat::Node* node() const; + + //! moves iterator to the next element + SparseMatIterator& operator ++(); + //! moves iterator to the next element + SparseMatIterator operator ++(int); +}; + + + +/////////////////////////////// SparseMatConstIterator_ ////////////////////////////// + +/** @brief Template Read-Only Sparse Matrix Iterator Class. + + This is the derived from SparseMatConstIterator class that + introduces more convenient operator *() for accessing the current element. +*/ +template class SparseMatConstIterator_ : public SparseMatConstIterator +{ +public: + + typedef std::forward_iterator_tag iterator_category; + + //! the default constructor + SparseMatConstIterator_(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatConstIterator_(const SparseMat_<_Tp>* _m); + SparseMatConstIterator_(const SparseMat* _m); + //! the copy constructor + SparseMatConstIterator_(const SparseMatConstIterator_& it); + + //! the assignment operator + SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it); + //! the element access operator + const _Tp& operator *() const; + + //! moves iterator to the next element + SparseMatConstIterator_& operator ++(); + //! moves iterator to the next element + SparseMatConstIterator_ operator ++(int); +}; + + + +///////////////////////////////// SparseMatIterator_ ///////////////////////////////// + +/** @brief Template Read-Write Sparse Matrix Iterator Class. + + This is the derived from cv::SparseMatConstIterator_ class that + introduces more convenient operator *() for accessing the current element. +*/ +template class SparseMatIterator_ : public SparseMatConstIterator_<_Tp> +{ +public: + + typedef std::forward_iterator_tag iterator_category; + + //! the default constructor + SparseMatIterator_(); + //! the full constructor setting the iterator to the first sparse matrix element + SparseMatIterator_(SparseMat_<_Tp>* _m); + SparseMatIterator_(SparseMat* _m); + //! the copy constructor + SparseMatIterator_(const SparseMatIterator_& it); + + //! the assignment operator + SparseMatIterator_& operator = (const SparseMatIterator_& it); + //! returns the reference to the current element + _Tp& operator *() const; + + //! moves the iterator to the next element + SparseMatIterator_& operator ++(); + //! moves the iterator to the next element + SparseMatIterator_ operator ++(int); +}; + + + +/////////////////////////////////// NAryMatIterator ////////////////////////////////// + +/** @brief n-ary multi-dimensional array iterator. + +Use the class to implement unary, binary, and, generally, n-ary element-wise operations on +multi-dimensional arrays. Some of the arguments of an n-ary function may be continuous arrays, some +may be not. It is possible to use conventional MatIterator 's for each array but incrementing all of +the iterators after each small operations may be a big overhead. In this case consider using +NAryMatIterator to iterate through several matrices simultaneously as long as they have the same +geometry (dimensionality and all the dimension sizes are the same). On each iteration `it.planes[0]`, +`it.planes[1]`,... will be the slices of the corresponding matrices. + +The example below illustrates how you can compute a normalized and threshold 3D color histogram: +@code + void computeNormalizedColorHist(const Mat& image, Mat& hist, int N, double minProb) + { + const int histSize[] = {N, N, N}; + + // make sure that the histogram has a proper size and type + hist.create(3, histSize, CV_32F); + + // and clear it + hist = Scalar(0); + + // the loop below assumes that the image + // is a 8-bit 3-channel. check it. + CV_Assert(image.type() == CV_8UC3); + MatConstIterator_ it = image.begin(), + it_end = image.end(); + for( ; it != it_end; ++it ) + { + const Vec3b& pix = *it; + hist.at(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f; + } + + minProb *= image.rows*image.cols; + + // initialize iterator (the style is different from STL). + // after initialization the iterator will contain + // the number of slices or planes the iterator will go through. + // it simultaneously increments iterators for several matrices + // supplied as a null terminated list of pointers + const Mat* arrays[] = {&hist, 0}; + Mat planes[1]; + NAryMatIterator itNAry(arrays, planes, 1); + double s = 0; + // iterate through the matrix. on each iteration + // itNAry.planes[i] (of type Mat) will be set to the current plane + // of the i-th n-dim matrix passed to the iterator constructor. + for(int p = 0; p < itNAry.nplanes; p++, ++itNAry) + { + threshold(itNAry.planes[0], itNAry.planes[0], minProb, 0, THRESH_TOZERO); + s += sum(itNAry.planes[0])[0]; + } + + s = 1./s; + itNAry = NAryMatIterator(arrays, planes, 1); + for(int p = 0; p < itNAry.nplanes; p++, ++itNAry) + itNAry.planes[0] *= s; + } +@endcode + */ +class CV_EXPORTS NAryMatIterator +{ +public: + //! the default constructor + NAryMatIterator(); + //! the full constructor taking arbitrary number of n-dim matrices + NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1); + //! the full constructor taking arbitrary number of n-dim matrices + NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1); + //! the separate iterator initialization method + void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1); + + //! proceeds to the next plane of every iterated matrix + NAryMatIterator& operator ++(); + //! proceeds to the next plane of every iterated matrix (postfix increment operator) + NAryMatIterator operator ++(int); + + //! the iterated arrays + const Mat** arrays; + //! the current planes + Mat* planes; + //! data pointers + uchar** ptrs; + //! the number of arrays + int narrays; + //! the number of hyper-planes that the iterator steps through + size_t nplanes; + //! the size of each segment (in elements) + size_t size; +protected: + int iterdepth; + size_t idx; +}; + + + +///////////////////////////////// Matrix Expressions ///////////////////////////////// + +class CV_EXPORTS MatOp +{ +public: + MatOp(); + virtual ~MatOp(); + + virtual bool elementWise(const MatExpr& expr) const; + virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0; + virtual void roi(const MatExpr& expr, const Range& rowRange, + const Range& colRange, MatExpr& res) const; + virtual void diag(const MatExpr& expr, int d, MatExpr& res) const; + virtual void augAssignAdd(const MatExpr& expr, Mat& m) const; + virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const; + virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const; + virtual void augAssignDivide(const MatExpr& expr, Mat& m) const; + virtual void augAssignAnd(const MatExpr& expr, Mat& m) const; + virtual void augAssignOr(const MatExpr& expr, Mat& m) const; + virtual void augAssignXor(const MatExpr& expr, Mat& m) const; + + virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const; + + virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; + + virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; + virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const; + + virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; + virtual void divide(double s, const MatExpr& expr, MatExpr& res) const; + + virtual void abs(const MatExpr& expr, MatExpr& res) const; + + virtual void transpose(const MatExpr& expr, MatExpr& res) const; + virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void invert(const MatExpr& expr, int method, MatExpr& res) const; + + virtual Size size(const MatExpr& expr) const; + virtual int type(const MatExpr& expr) const; +}; + +/** @brief Matrix expression representation +@anchor MatrixExpressions +This is a list of implemented matrix operations that can be combined in arbitrary complex +expressions (here A, B stand for matrices ( Mat ), s for a scalar ( Scalar ), alpha for a +real-valued scalar ( double )): +- Addition, subtraction, negation: `A+B`, `A-B`, `A+s`, `A-s`, `s+A`, `s-A`, `-A` +- Scaling: `A*alpha` +- Per-element multiplication and division: `A.mul(B)`, `A/B`, `alpha/A` +- Matrix multiplication: `A*B` +- Transposition: `A.t()` (means AT) +- Matrix inversion and pseudo-inversion, solving linear systems and least-squares problems: + `A.inv([method]) (~ A-1)`, `A.inv([method])*B (~ X: AX=B)` +- Comparison: `A cmpop B`, `A cmpop alpha`, `alpha cmpop A`, where *cmpop* is one of + `>`, `>=`, `==`, `!=`, `<=`, `<`. The result of comparison is an 8-bit single channel mask whose + elements are set to 255 (if the particular element or pair of elements satisfy the condition) or + 0. +- Bitwise logical operations: `A logicop B`, `A logicop s`, `s logicop A`, `~A`, where *logicop* is one of + `&`, `|`, `^`. +- Element-wise minimum and maximum: `min(A, B)`, `min(A, alpha)`, `max(A, B)`, `max(A, alpha)` +- Element-wise absolute value: `abs(A)` +- Cross-product, dot-product: `A.cross(B)`, `A.dot(B)` +- Any function of matrix or matrices and scalars that returns a matrix or a scalar, such as norm, + mean, sum, countNonZero, trace, determinant, repeat, and others. +- Matrix initializers ( Mat::eye(), Mat::zeros(), Mat::ones() ), matrix comma-separated + initializers, matrix constructors and operators that extract sub-matrices (see Mat description). +- Mat_() constructors to cast the result to the proper type. +@note Comma-separated initializers and probably some other operations may require additional +explicit Mat() or Mat_() constructor calls to resolve a possible ambiguity. + +Here are examples of matrix expressions: +@code + // compute pseudo-inverse of A, equivalent to A.inv(DECOMP_SVD) + SVD svd(A); + Mat pinvA = svd.vt.t()*Mat::diag(1./svd.w)*svd.u.t(); + + // compute the new vector of parameters in the Levenberg-Marquardt algorithm + x -= (A.t()*A + lambda*Mat::eye(A.cols,A.cols,A.type())).inv(DECOMP_CHOLESKY)*(A.t()*err); + + // sharpen image using "unsharp mask" algorithm + Mat blurred; double sigma = 1, threshold = 5, amount = 1; + GaussianBlur(img, blurred, Size(), sigma, sigma); + Mat lowContrastMask = abs(img - blurred) < threshold; + Mat sharpened = img*(1+amount) + blurred*(-amount); + img.copyTo(sharpened, lowContrastMask); +@endcode +*/ +class CV_EXPORTS MatExpr +{ +public: + MatExpr(); + explicit MatExpr(const Mat& m); + + MatExpr(const MatOp* _op, int _flags, const Mat& _a = Mat(), const Mat& _b = Mat(), + const Mat& _c = Mat(), double _alpha = 1, double _beta = 1, const Scalar& _s = Scalar()); + + operator Mat() const; + template operator Mat_<_Tp>() const; + + Size size() const; + int type() const; + + MatExpr row(int y) const; + MatExpr col(int x) const; + MatExpr diag(int d = 0) const; + MatExpr operator()( const Range& rowRange, const Range& colRange ) const; + MatExpr operator()( const Rect& roi ) const; + + MatExpr t() const; + MatExpr inv(int method = DECOMP_LU) const; + MatExpr mul(const MatExpr& e, double scale=1) const; + MatExpr mul(const Mat& m, double scale=1) const; + + Mat cross(const Mat& m) const; + double dot(const Mat& m) const; + + const MatOp* op; + int flags; + + Mat a, b, c; + double alpha, beta; + Scalar s; +}; + +//! @} core_basic + +//! @relates cv::MatExpr +//! @{ +CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a); +CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s); +CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e); +CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator + (const Mat& a, const Matx<_Tp, m, n>& b) { return a + Mat(b); } +template static inline +MatExpr operator + (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) + b; } + +CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a); +CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s); +CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e); +CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator - (const Mat& a, const Matx<_Tp, m, n>& b) { return a - Mat(b); } +template static inline +MatExpr operator - (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) - b; } + +CV_EXPORTS MatExpr operator - (const Mat& m); +CV_EXPORTS MatExpr operator - (const MatExpr& e); + +CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator * (const Mat& a, double s); +CV_EXPORTS MatExpr operator * (double s, const Mat& a); +CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator * (const MatExpr& e, double s); +CV_EXPORTS MatExpr operator * (double s, const MatExpr& e); +CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator * (const Mat& a, const Matx<_Tp, m, n>& b) { return a * Mat(b); } +template static inline +MatExpr operator * (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) * b; } + +CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator / (const Mat& a, double s); +CV_EXPORTS MatExpr operator / (double s, const Mat& a); +CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator / (const MatExpr& e, double s); +CV_EXPORTS MatExpr operator / (double s, const MatExpr& e); +CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2); +template static inline +MatExpr operator / (const Mat& a, const Matx<_Tp, m, n>& b) { return a / Mat(b); } +template static inline +MatExpr operator / (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) / b; } + +CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator < (const Mat& a, double s); +CV_EXPORTS MatExpr operator < (double s, const Mat& a); +template static inline +MatExpr operator < (const Mat& a, const Matx<_Tp, m, n>& b) { return a < Mat(b); } +template static inline +MatExpr operator < (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) < b; } + +CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator <= (const Mat& a, double s); +CV_EXPORTS MatExpr operator <= (double s, const Mat& a); +template static inline +MatExpr operator <= (const Mat& a, const Matx<_Tp, m, n>& b) { return a <= Mat(b); } +template static inline +MatExpr operator <= (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) <= b; } + +CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator == (const Mat& a, double s); +CV_EXPORTS MatExpr operator == (double s, const Mat& a); +template static inline +MatExpr operator == (const Mat& a, const Matx<_Tp, m, n>& b) { return a == Mat(b); } +template static inline +MatExpr operator == (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) == b; } + +CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator != (const Mat& a, double s); +CV_EXPORTS MatExpr operator != (double s, const Mat& a); +template static inline +MatExpr operator != (const Mat& a, const Matx<_Tp, m, n>& b) { return a != Mat(b); } +template static inline +MatExpr operator != (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) != b; } + +CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator >= (const Mat& a, double s); +CV_EXPORTS MatExpr operator >= (double s, const Mat& a); +template static inline +MatExpr operator >= (const Mat& a, const Matx<_Tp, m, n>& b) { return a >= Mat(b); } +template static inline +MatExpr operator >= (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) >= b; } + +CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator > (const Mat& a, double s); +CV_EXPORTS MatExpr operator > (double s, const Mat& a); +template static inline +MatExpr operator > (const Mat& a, const Matx<_Tp, m, n>& b) { return a > Mat(b); } +template static inline +MatExpr operator > (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) > b; } + +CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a); +template static inline +MatExpr operator & (const Mat& a, const Matx<_Tp, m, n>& b) { return a & Mat(b); } +template static inline +MatExpr operator & (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) & b; } + +CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a); +template static inline +MatExpr operator | (const Mat& a, const Matx<_Tp, m, n>& b) { return a | Mat(b); } +template static inline +MatExpr operator | (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) | b; } + +CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a); +template static inline +MatExpr operator ^ (const Mat& a, const Matx<_Tp, m, n>& b) { return a ^ Mat(b); } +template static inline +MatExpr operator ^ (const Matx<_Tp, m, n>& a, const Mat& b) { return Mat(a) ^ b; } + +CV_EXPORTS MatExpr operator ~(const Mat& m); + +CV_EXPORTS MatExpr min(const Mat& a, const Mat& b); +CV_EXPORTS MatExpr min(const Mat& a, double s); +CV_EXPORTS MatExpr min(double s, const Mat& a); +template static inline +MatExpr min (const Mat& a, const Matx<_Tp, m, n>& b) { return min(a, Mat(b)); } +template static inline +MatExpr min (const Matx<_Tp, m, n>& a, const Mat& b) { return min(Mat(a), b); } + +CV_EXPORTS MatExpr max(const Mat& a, const Mat& b); +CV_EXPORTS MatExpr max(const Mat& a, double s); +CV_EXPORTS MatExpr max(double s, const Mat& a); +template static inline +MatExpr max (const Mat& a, const Matx<_Tp, m, n>& b) { return max(a, Mat(b)); } +template static inline +MatExpr max (const Matx<_Tp, m, n>& a, const Mat& b) { return max(Mat(a), b); } + +/** @brief Calculates an absolute value of each matrix element. + +abs is a meta-function that is expanded to one of absdiff or convertScaleAbs forms: +- C = abs(A-B) is equivalent to `absdiff(A, B, C)` +- C = abs(A) is equivalent to `absdiff(A, Scalar::all(0), C)` +- C = `Mat_ >(abs(A*alpha + beta))` is equivalent to `convertScaleAbs(A, C, alpha, +beta)` + +The output matrix has the same size and the same type as the input one except for the last case, +where C is depth=CV_8U . +@param m matrix. +@sa @ref MatrixExpressions, absdiff, convertScaleAbs + */ +CV_EXPORTS MatExpr abs(const Mat& m); +/** @overload +@param e matrix expression. +*/ +CV_EXPORTS MatExpr abs(const MatExpr& e); +//! @} relates cv::MatExpr + +} // cv + +#include "opencv2/core/mat.inl.hpp" + +#endif // OPENCV_CORE_MAT_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/mat.inl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/mat.inl.hpp new file mode 100755 index 0000000..0ef6405 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/mat.inl.hpp @@ -0,0 +1,3973 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_MATRIX_OPERATIONS_HPP +#define OPENCV_CORE_MATRIX_OPERATIONS_HPP + +#ifndef __cplusplus +# error mat.inl.hpp header must be compiled as C++ +#endif + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4127 ) +#endif + +namespace cv +{ +CV__DEBUG_NS_BEGIN + + +//! @cond IGNORED + +////////////////////////// Custom (raw) type wrapper ////////////////////////// + +template static inline +int rawType() +{ + CV_StaticAssert(sizeof(_Tp) <= CV_CN_MAX, "sizeof(_Tp) is too large"); + const int elemSize = sizeof(_Tp); + return (int)CV_MAKETYPE(CV_8U, elemSize); +} + +//////////////////////// Input/Output Arrays //////////////////////// + +inline void _InputArray::init(int _flags, const void* _obj) +{ flags = _flags; obj = (void*)_obj; } + +inline void _InputArray::init(int _flags, const void* _obj, Size _sz) +{ flags = _flags; obj = (void*)_obj; sz = _sz; } + +inline void* _InputArray::getObj() const { return obj; } +inline int _InputArray::getFlags() const { return flags; } +inline Size _InputArray::getSz() const { return sz; } + +inline _InputArray::_InputArray() { init(0 + NONE, 0); } +inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); } +inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); } +inline _InputArray::_InputArray(const std::vector& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); } +inline _InputArray::_InputArray(const UMat& m) { init(UMAT+ACCESS_READ, &m); } +inline _InputArray::_InputArray(const std::vector& vec) { init(STD_VECTOR_UMAT+ACCESS_READ, &vec); } + +template inline +_InputArray::_InputArray(const std::vector<_Tp>& vec) +{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); } + +template inline +_InputArray::_InputArray(const std::array<_Tp, _Nm>& arr) +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_READ, arr.data(), Size(1, _Nm)); } + +template inline +_InputArray::_InputArray(const std::array& arr) +{ init(STD_ARRAY_MAT + ACCESS_READ, arr.data(), Size(1, _Nm)); } + +inline +_InputArray::_InputArray(const std::vector& vec) +{ init(FIXED_TYPE + STD_BOOL_VECTOR + traits::Type::value + ACCESS_READ, &vec); } + +template inline +_InputArray::_InputArray(const std::vector >& vec) +{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); } + +template inline +_InputArray::_InputArray(const std::vector >& vec) +{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_READ, &vec); } + +template inline +_InputArray::_InputArray(const Matx<_Tp, m, n>& mtx) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, &mtx, Size(n, m)); } + +template inline +_InputArray::_InputArray(const _Tp* vec, int n) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, vec, Size(n, 1)); } + +template inline +_InputArray::_InputArray(const Mat_<_Tp>& m) +{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_READ, &m); } + +inline _InputArray::_InputArray(const double& val) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); } + +inline _InputArray::_InputArray(const MatExpr& expr) +{ init(FIXED_TYPE + FIXED_SIZE + EXPR + ACCESS_READ, &expr); } + +inline _InputArray::_InputArray(const cuda::GpuMat& d_mat) +{ init(CUDA_GPU_MAT + ACCESS_READ, &d_mat); } + +inline _InputArray::_InputArray(const std::vector& d_mat) +{ init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat);} + +inline _InputArray::_InputArray(const ogl::Buffer& buf) +{ init(OPENGL_BUFFER + ACCESS_READ, &buf); } + +inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem) +{ init(CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); } + +template inline +_InputArray _InputArray::rawIn(const std::vector<_Tp>& vec) +{ + _InputArray v; + v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_READ; + v.obj = (void*)&vec; + return v; +} + +template inline +_InputArray _InputArray::rawIn(const std::array<_Tp, _Nm>& arr) +{ + _InputArray v; + v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_READ; + v.obj = (void*)arr.data(); + v.sz = Size(1, _Nm); + return v; +} + +inline _InputArray::~_InputArray() {} + +inline Mat _InputArray::getMat(int i) const +{ + if( kind() == MAT && i < 0 ) + return *(const Mat*)obj; + return getMat_(i); +} + +inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; } +inline bool _InputArray::isUMat() const { return kind() == _InputArray::UMAT; } +inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; } +inline bool _InputArray::isUMatVector() const { return kind() == _InputArray::STD_VECTOR_UMAT; } +inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; } +inline bool _InputArray::isVector() const { return kind() == _InputArray::STD_VECTOR || + kind() == _InputArray::STD_BOOL_VECTOR || + kind() == _InputArray::STD_ARRAY; } +inline bool _InputArray::isGpuMat() const { return kind() == _InputArray::CUDA_GPU_MAT; } +inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::STD_VECTOR_CUDA_GPU_MAT; } + +//////////////////////////////////////////////////////////////////////////////////////// + +inline _OutputArray::_OutputArray() { init(NONE + ACCESS_WRITE, 0); } +inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags + ACCESS_WRITE, _obj); } +inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); } +inline _OutputArray::_OutputArray(std::vector& vec) { init(STD_VECTOR_MAT + ACCESS_WRITE, &vec); } +inline _OutputArray::_OutputArray(UMat& m) { init(UMAT + ACCESS_WRITE, &m); } +inline _OutputArray::_OutputArray(std::vector& vec) { init(STD_VECTOR_UMAT + ACCESS_WRITE, &vec); } + +template inline +_OutputArray::_OutputArray(std::vector<_Tp>& vec) +{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } + +template inline +_OutputArray::_OutputArray(std::array<_Tp, _Nm>& arr) +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } + +template inline +_OutputArray::_OutputArray(std::array& arr) +{ init(STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } + +template inline +_OutputArray::_OutputArray(std::vector >& vec) +{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } + +template inline +_OutputArray::_OutputArray(std::vector >& vec) +{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } + +template inline +_OutputArray::_OutputArray(Mat_<_Tp>& m) +{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m); } + +template inline +_OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)); } + +template inline +_OutputArray::_OutputArray(_Tp* vec, int n) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)); } + +template inline +_OutputArray::_OutputArray(const std::vector<_Tp>& vec) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } + +template inline +_OutputArray::_OutputArray(const std::array<_Tp, _Nm>& arr) +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } + +template inline +_OutputArray::_OutputArray(const std::array& arr) +{ init(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } + +template inline +_OutputArray::_OutputArray(const std::vector >& vec) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } + +template inline +_OutputArray::_OutputArray(const std::vector >& vec) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } + +template inline +_OutputArray::_OutputArray(const Mat_<_Tp>& m) +{ init(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m); } + +template inline +_OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)); } + +template inline +_OutputArray::_OutputArray(const _Tp* vec, int n) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)); } + +inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat) +{ init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); } + +inline _OutputArray::_OutputArray(std::vector& d_mat) +{ init(STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat);} + +inline _OutputArray::_OutputArray(ogl::Buffer& buf) +{ init(OPENGL_BUFFER + ACCESS_WRITE, &buf); } + +inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem) +{ init(CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); } + +inline _OutputArray::_OutputArray(const Mat& m) +{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); } + +inline _OutputArray::_OutputArray(const std::vector& vec) +{ init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec); } + +inline _OutputArray::_OutputArray(const UMat& m) +{ init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m); } + +inline _OutputArray::_OutputArray(const std::vector& vec) +{ init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec); } + +inline _OutputArray::_OutputArray(const cuda::GpuMat& d_mat) +{ init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); } + + +inline _OutputArray::_OutputArray(const ogl::Buffer& buf) +{ init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf); } + +inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem) +{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); } + +template inline +_OutputArray _OutputArray::rawOut(std::vector<_Tp>& vec) +{ + _OutputArray v; + v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_WRITE; + v.obj = (void*)&vec; + return v; +} + +template inline +_OutputArray _OutputArray::rawOut(std::array<_Tp, _Nm>& arr) +{ + _OutputArray v; + v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_WRITE; + v.obj = (void*)arr.data(); + v.sz = Size(1, _Nm); + return v; +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +inline _InputOutputArray::_InputOutputArray() { init(0+ACCESS_RW, 0); } +inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags+ACCESS_RW, _obj); } +inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); } +inline _InputOutputArray::_InputOutputArray(std::vector& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); } +inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); } +inline _InputOutputArray::_InputOutputArray(std::vector& vec) { init(STD_VECTOR_UMAT+ACCESS_RW, &vec); } + +template inline +_InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec) +{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } + +template inline +_InputOutputArray::_InputOutputArray(std::array<_Tp, _Nm>& arr) +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)); } + +template inline +_InputOutputArray::_InputOutputArray(std::array& arr) +{ init(STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)); } + +template inline +_InputOutputArray::_InputOutputArray(std::vector >& vec) +{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } + +template inline +_InputOutputArray::_InputOutputArray(std::vector >& vec) +{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec); } + +template inline +_InputOutputArray::_InputOutputArray(Mat_<_Tp>& m) +{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m); } + +template inline +_InputOutputArray::_InputOutputArray(Matx<_Tp, m, n>& mtx) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)); } + +template inline +_InputOutputArray::_InputOutputArray(_Tp* vec, int n) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)); } + +template inline +_InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } + +template inline +_InputOutputArray::_InputOutputArray(const std::array<_Tp, _Nm>& arr) +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)); } + +template inline +_InputOutputArray::_InputOutputArray(const std::array& arr) +{ init(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)); } + +template inline +_InputOutputArray::_InputOutputArray(const std::vector >& vec) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } + +template inline +_InputOutputArray::_InputOutputArray(const std::vector >& vec) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec); } + +template inline +_InputOutputArray::_InputOutputArray(const Mat_<_Tp>& m) +{ init(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m); } + +template inline +_InputOutputArray::_InputOutputArray(const Matx<_Tp, m, n>& mtx) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)); } + +template inline +_InputOutputArray::_InputOutputArray(const _Tp* vec, int n) +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)); } + +inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat) +{ init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); } + +inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf) +{ init(OPENGL_BUFFER + ACCESS_RW, &buf); } + +inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem) +{ init(CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); } + +inline _InputOutputArray::_InputOutputArray(const Mat& m) +{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); } + +inline _InputOutputArray::_InputOutputArray(const std::vector& vec) +{ init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); } + +inline _InputOutputArray::_InputOutputArray(const UMat& m) +{ init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); } + +inline _InputOutputArray::_InputOutputArray(const std::vector& vec) +{ init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); } + +inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat) +{ init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat); } + +inline _InputOutputArray::_InputOutputArray(const std::vector& d_mat) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);} + +template<> inline _InputOutputArray::_InputOutputArray(std::vector& d_mat) +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);} + +inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf) +{ init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf); } + +inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem) +{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); } + +template inline +_InputOutputArray _InputOutputArray::rawInOut(std::vector<_Tp>& vec) +{ + _InputOutputArray v; + v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_RW; + v.obj = (void*)&vec; + return v; +} + +template inline +_InputOutputArray _InputOutputArray::rawInOut(std::array<_Tp, _Nm>& arr) +{ + _InputOutputArray v; + v.flags = FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_RW; + v.obj = (void*)arr.data(); + v.sz = Size(1, _Nm); + return v; +} + + +template static inline _InputArray rawIn(_Tp& v) { return _InputArray::rawIn(v); } +template static inline _OutputArray rawOut(_Tp& v) { return _OutputArray::rawOut(v); } +template static inline _InputOutputArray rawInOut(_Tp& v) { return _InputOutputArray::rawInOut(v); } + +CV__DEBUG_NS_END + +//////////////////////////////////////////// Mat ////////////////////////////////////////// + +inline +Mat::Mat() + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{} + +inline +Mat::Mat(int _rows, int _cols, int _type) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create(_rows, _cols, _type); +} + +inline +Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create(_rows, _cols, _type); + *this = _s; +} + +inline +Mat::Mat(Size _sz, int _type) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create( _sz.height, _sz.width, _type ); +} + +inline +Mat::Mat(Size _sz, int _type, const Scalar& _s) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create(_sz.height, _sz.width, _type); + *this = _s; +} + +inline +Mat::Mat(int _dims, const int* _sz, int _type) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create(_dims, _sz, _type); +} + +inline +Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create(_dims, _sz, _type); + *this = _s; +} + +inline +Mat::Mat(const std::vector& _sz, int _type) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create(_sz, _type); +} + +inline +Mat::Mat(const std::vector& _sz, int _type, const Scalar& _s) + : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), + datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + create(_sz, _type); + *this = _s; +} + +inline +Mat::Mat(const Mat& m) + : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data), + datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator), + u(m.u), size(&rows), step(0) +{ + if( u ) + CV_XADD(&u->refcount, 1); + if( m.dims <= 2 ) + { + step[0] = m.step[0]; step[1] = m.step[1]; + } + else + { + dims = 0; + copySize(m); + } +} + +inline +Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step) + : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols), + data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0), + allocator(0), u(0), size(&rows) +{ + CV_Assert(total() == 0 || data != NULL); + + size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type); + size_t minstep = cols * esz; + if( _step == AUTO_STEP ) + { + _step = minstep; + } + else + { + CV_DbgAssert( _step >= minstep ); + if (_step % esz1 != 0) + { + CV_Error(Error::BadStep, "Step must be a multiple of esz1"); + } + } + step[0] = _step; + step[1] = esz; + datalimit = datastart + _step * rows; + dataend = datalimit - _step + minstep; + updateContinuityFlag(); +} + +inline +Mat::Mat(Size _sz, int _type, void* _data, size_t _step) + : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width), + data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0), + allocator(0), u(0), size(&rows) +{ + CV_Assert(total() == 0 || data != NULL); + + size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type); + size_t minstep = cols*esz; + if( _step == AUTO_STEP ) + { + _step = minstep; + } + else + { + CV_DbgAssert( _step >= minstep ); + + if (_step % esz1 != 0) + { + CV_Error(Error::BadStep, "Step must be a multiple of esz1"); + } + } + step[0] = _step; + step[1] = esz; + datalimit = datastart + _step*rows; + dataend = datalimit - _step + minstep; + updateContinuityFlag(); +} + +template inline +Mat::Mat(const std::vector<_Tp>& vec, bool copyData) + : flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()), + cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + if(vec.empty()) + return; + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + datastart = data = (uchar*)&vec[0]; + datalimit = dataend = datastart + rows * step[0]; + } + else + Mat((int)vec.size(), 1, traits::Type<_Tp>::value, (uchar*)&vec[0]).copyTo(*this); +} + +template inline +Mat::Mat(const std::initializer_list<_Tp> list) + : Mat() +{ + CV_Assert(list.size() != 0); + Mat((int)list.size(), 1, traits::Type<_Tp>::value, (uchar*)list.begin()).copyTo(*this); +} + +template inline +Mat::Mat(const std::initializer_list sizes, const std::initializer_list<_Tp> list) + : Mat() +{ + size_t size_total = 1; + for(auto s : sizes) + size_total *= s; + CV_Assert(list.size() != 0); + CV_Assert(size_total == list.size()); + Mat((int)sizes.size(), (int*)sizes.begin(), traits::Type<_Tp>::value, (uchar*)list.begin()).copyTo(*this); +} + +template inline +Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData) + : flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()), + cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + if(arr.empty()) + return; + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + datastart = data = (uchar*)arr.data(); + datalimit = dataend = datastart + rows * step[0]; + } + else + Mat((int)arr.size(), 1, traits::Type<_Tp>::value, (uchar*)arr.data()).copyTo(*this); +} + +template inline +Mat::Mat(const Vec<_Tp, n>& vec, bool copyData) + : flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0), + datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + datastart = data = (uchar*)vec.val; + datalimit = dataend = datastart + rows * step[0]; + } + else + Mat(n, 1, traits::Type<_Tp>::value, (void*)vec.val).copyTo(*this); +} + + +template inline +Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData) + : flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0), + datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + if( !copyData ) + { + step[0] = cols * sizeof(_Tp); + step[1] = sizeof(_Tp); + datastart = data = (uchar*)M.val; + datalimit = dataend = datastart + rows * step[0]; + } + else + Mat(m, n, traits::Type<_Tp>::value, (uchar*)M.val).copyTo(*this); +} + +template inline +Mat::Mat(const Point_<_Tp>& pt, bool copyData) + : flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0), + datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + datastart = data = (uchar*)&pt.x; + datalimit = dataend = datastart + rows * step[0]; + } + else + { + create(2, 1, traits::Type<_Tp>::value); + ((_Tp*)data)[0] = pt.x; + ((_Tp*)data)[1] = pt.y; + } +} + +template inline +Mat::Mat(const Point3_<_Tp>& pt, bool copyData) + : flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0), + datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) +{ + if( !copyData ) + { + step[0] = step[1] = sizeof(_Tp); + datastart = data = (uchar*)&pt.x; + datalimit = dataend = datastart + rows * step[0]; + } + else + { + create(3, 1, traits::Type<_Tp>::value); + ((_Tp*)data)[0] = pt.x; + ((_Tp*)data)[1] = pt.y; + ((_Tp*)data)[2] = pt.z; + } +} + +template inline +Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer) + : flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0), + datastart(0), dataend(0), allocator(0), u(0), size(&rows) +{ + *this = commaInitializer.operator Mat_<_Tp>(); +} + +inline +Mat::~Mat() +{ + release(); + if( step.p != step.buf ) + fastFree(step.p); +} + +inline +Mat& Mat::operator = (const Mat& m) +{ + if( this != &m ) + { + if( m.u ) + CV_XADD(&m.u->refcount, 1); + release(); + flags = m.flags; + if( dims <= 2 && m.dims <= 2 ) + { + dims = m.dims; + rows = m.rows; + cols = m.cols; + step[0] = m.step[0]; + step[1] = m.step[1]; + } + else + copySize(m); + data = m.data; + datastart = m.datastart; + dataend = m.dataend; + datalimit = m.datalimit; + allocator = m.allocator; + u = m.u; + } + return *this; +} + +inline +Mat Mat::row(int y) const +{ + return Mat(*this, Range(y, y + 1), Range::all()); +} + +inline +Mat Mat::col(int x) const +{ + return Mat(*this, Range::all(), Range(x, x + 1)); +} + +inline +Mat Mat::rowRange(int startrow, int endrow) const +{ + return Mat(*this, Range(startrow, endrow), Range::all()); +} + +inline +Mat Mat::rowRange(const Range& r) const +{ + return Mat(*this, r, Range::all()); +} + +inline +Mat Mat::colRange(int startcol, int endcol) const +{ + return Mat(*this, Range::all(), Range(startcol, endcol)); +} + +inline +Mat Mat::colRange(const Range& r) const +{ + return Mat(*this, Range::all(), r); +} + +inline +Mat Mat::clone() const +{ + Mat m; + copyTo(m); + return m; +} + +inline +void Mat::assignTo( Mat& m, int _type ) const +{ + if( _type < 0 ) + m = *this; + else + convertTo(m, _type); +} + +inline +void Mat::create(int _rows, int _cols, int _type) +{ + _type &= TYPE_MASK; + if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data ) + return; + int sz[] = {_rows, _cols}; + create(2, sz, _type); +} + +inline +void Mat::create(Size _sz, int _type) +{ + create(_sz.height, _sz.width, _type); +} + +inline +void Mat::addref() +{ + if( u ) + CV_XADD(&u->refcount, 1); +} + +inline +void Mat::release() +{ + if( u && CV_XADD(&u->refcount, -1) == 1 ) + deallocate(); + u = NULL; + datastart = dataend = datalimit = data = 0; + for(int i = 0; i < dims; i++) + size.p[i] = 0; +#ifdef _DEBUG + flags = MAGIC_VAL; + dims = rows = cols = 0; + if(step.p != step.buf) + { + fastFree(step.p); + step.p = step.buf; + size.p = &rows; + } +#endif +} + +inline +Mat Mat::operator()( Range _rowRange, Range _colRange ) const +{ + return Mat(*this, _rowRange, _colRange); +} + +inline +Mat Mat::operator()( const Rect& roi ) const +{ + return Mat(*this, roi); +} + +inline +Mat Mat::operator()(const Range* ranges) const +{ + return Mat(*this, ranges); +} + +inline +Mat Mat::operator()(const std::vector& ranges) const +{ + return Mat(*this, ranges); +} + +inline +bool Mat::isContinuous() const +{ + return (flags & CONTINUOUS_FLAG) != 0; +} + +inline +bool Mat::isSubmatrix() const +{ + return (flags & SUBMATRIX_FLAG) != 0; +} + +inline +size_t Mat::elemSize() const +{ + size_t res = dims > 0 ? step.p[dims - 1] : 0; + CV_DbgAssert(res != 0); + return res; +} + +inline +size_t Mat::elemSize1() const +{ + return CV_ELEM_SIZE1(flags); +} + +inline +int Mat::type() const +{ + return CV_MAT_TYPE(flags); +} + +inline +int Mat::depth() const +{ + return CV_MAT_DEPTH(flags); +} + +inline +int Mat::channels() const +{ + return CV_MAT_CN(flags); +} + +inline +size_t Mat::step1(int i) const +{ + return step.p[i] / elemSize1(); +} + +inline +bool Mat::empty() const +{ + return data == 0 || total() == 0 || dims == 0; +} + +inline +size_t Mat::total() const +{ + if( dims <= 2 ) + return (size_t)rows * cols; + size_t p = 1; + for( int i = 0; i < dims; i++ ) + p *= size[i]; + return p; +} + +inline +size_t Mat::total(int startDim, int endDim) const +{ + CV_Assert( 0 <= startDim && startDim <= endDim); + size_t p = 1; + int endDim_ = endDim <= dims ? endDim : dims; + for( int i = startDim; i < endDim_; i++ ) + p *= size[i]; + return p; +} + +inline +uchar* Mat::ptr(int y) +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return data + step.p[0] * y; +} + +inline +const uchar* Mat::ptr(int y) const +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return data + step.p[0] * y; +} + +template inline +_Tp* Mat::ptr(int y) +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return (_Tp*)(data + step.p[0] * y); +} + +template inline +const _Tp* Mat::ptr(int y) const +{ + CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) ); + return (const _Tp*)(data + step.p[0] * y); +} + +inline +uchar* Mat::ptr(int i0, int i1) +{ + CV_DbgAssert(dims >= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + return data + i0 * step.p[0] + i1 * step.p[1]; +} + +inline +const uchar* Mat::ptr(int i0, int i1) const +{ + CV_DbgAssert(dims >= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + return data + i0 * step.p[0] + i1 * step.p[1]; +} + +template inline +_Tp* Mat::ptr(int i0, int i1) +{ + CV_DbgAssert(dims >= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1]); +} + +template inline +const _Tp* Mat::ptr(int i0, int i1) const +{ + CV_DbgAssert(dims >= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1]); +} + +inline +uchar* Mat::ptr(int i0, int i1, int i2) +{ + CV_DbgAssert(dims >= 3); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]); + return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]; +} + +inline +const uchar* Mat::ptr(int i0, int i1, int i2) const +{ + CV_DbgAssert(dims >= 3); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]); + return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]; +} + +template inline +_Tp* Mat::ptr(int i0, int i1, int i2) +{ + CV_DbgAssert(dims >= 3); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]); + return (_Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]); +} + +template inline +const _Tp* Mat::ptr(int i0, int i1, int i2) const +{ + CV_DbgAssert(dims >= 3); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]); + return (const _Tp*)(data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2]); +} + +inline +uchar* Mat::ptr(const int* idx) +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i] * step.p[i]; + } + return p; +} + +inline +const uchar* Mat::ptr(const int* idx) const +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i] * step.p[i]; + } + return p; +} + +template inline +_Tp* Mat::ptr(const int* idx) +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i] * step.p[i]; + } + return (_Tp*)p; +} + +template inline +const _Tp* Mat::ptr(const int* idx) const +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i] * step.p[i]; + } + return (const _Tp*)p; +} + +template inline +_Tp& Mat::at(int i0, int i1) +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); + return ((_Tp*)(data + step.p[0] * i0))[i1]; +} + +template inline +const _Tp& Mat::at(int i0, int i1) const +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); + return ((const _Tp*)(data + step.p[0] * i0))[i1]; +} + +template inline +_Tp& Mat::at(Point pt) +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); + return ((_Tp*)(data + step.p[0] * pt.y))[pt.x]; +} + +template inline +const _Tp& Mat::at(Point pt) const +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); + return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x]; +} + +template inline +_Tp& Mat::at(int i0) +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1])); + CV_DbgAssert(elemSize() == sizeof(_Tp)); + if( isContinuous() || size.p[0] == 1 ) + return ((_Tp*)data)[i0]; + if( size.p[1] == 1 ) + return *(_Tp*)(data + step.p[0] * i0); + int i = i0 / cols, j = i0 - i * cols; + return ((_Tp*)(data + step.p[0] * i))[j]; +} + +template inline +const _Tp& Mat::at(int i0) const +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1])); + CV_DbgAssert(elemSize() == sizeof(_Tp)); + if( isContinuous() || size.p[0] == 1 ) + return ((const _Tp*)data)[i0]; + if( size.p[1] == 1 ) + return *(const _Tp*)(data + step.p[0] * i0); + int i = i0 / cols, j = i0 - i * cols; + return ((const _Tp*)(data + step.p[0] * i))[j]; +} + +template inline +_Tp& Mat::at(int i0, int i1, int i2) +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return *(_Tp*)ptr(i0, i1, i2); +} + +template inline +const _Tp& Mat::at(int i0, int i1, int i2) const +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return *(const _Tp*)ptr(i0, i1, i2); +} + +template inline +_Tp& Mat::at(const int* idx) +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return *(_Tp*)ptr(idx); +} + +template inline +const _Tp& Mat::at(const int* idx) const +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return *(const _Tp*)ptr(idx); +} + +template inline +_Tp& Mat::at(const Vec& idx) +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return *(_Tp*)ptr(idx.val); +} + +template inline +const _Tp& Mat::at(const Vec& idx) const +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return *(const _Tp*)ptr(idx.val); +} + +template inline +MatConstIterator_<_Tp> Mat::begin() const +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this); +} + +template inline +MatConstIterator_<_Tp> Mat::end() const +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this); + it += total(); + return it; +} + +template inline +MatIterator_<_Tp> Mat::begin() +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + return MatIterator_<_Tp>((Mat_<_Tp>*)this); +} + +template inline +MatIterator_<_Tp> Mat::end() +{ + CV_DbgAssert( elemSize() == sizeof(_Tp) ); + MatIterator_<_Tp> it((Mat_<_Tp>*)this); + it += total(); + return it; +} + +template inline +void Mat::forEach(const Functor& operation) { + this->forEach_impl<_Tp>(operation); +} + +template inline +void Mat::forEach(const Functor& operation) const { + // call as not const + (const_cast(this))->forEach<_Tp>(operation); +} + +template inline +Mat::operator std::vector<_Tp>() const +{ + std::vector<_Tp> v; + copyTo(v); + return v; +} + +template inline +Mat::operator std::array<_Tp, _Nm>() const +{ + std::array<_Tp, _Nm> v; + copyTo(v); + return v; +} + +template inline +Mat::operator Vec<_Tp, n>() const +{ + CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) && + rows + cols - 1 == n && channels() == 1 ); + + if( isContinuous() && type() == traits::Type<_Tp>::value ) + return Vec<_Tp, n>((_Tp*)data); + Vec<_Tp, n> v; + Mat tmp(rows, cols, traits::Type<_Tp>::value, v.val); + convertTo(tmp, tmp.type()); + return v; +} + +template inline +Mat::operator Matx<_Tp, m, n>() const +{ + CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 ); + + if( isContinuous() && type() == traits::Type<_Tp>::value ) + return Matx<_Tp, m, n>((_Tp*)data); + Matx<_Tp, m, n> mtx; + Mat tmp(rows, cols, traits::Type<_Tp>::value, mtx.val); + convertTo(tmp, tmp.type()); + return mtx; +} + +template inline +void Mat::push_back(const _Tp& elem) +{ + if( !data ) + { + *this = Mat(1, 1, traits::Type<_Tp>::value, (void*)&elem).clone(); + return; + } + CV_Assert(traits::Type<_Tp>::value == type() && cols == 1 + /* && dims == 2 (cols == 1 implies dims == 2) */); + const uchar* tmp = dataend + step[0]; + if( !isSubmatrix() && isContinuous() && tmp <= datalimit ) + { + *(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem; + dataend = tmp; + } + else + push_back_(&elem); +} + +template inline +void Mat::push_back(const Mat_<_Tp>& m) +{ + push_back((const Mat&)m); +} + +template<> inline +void Mat::push_back(const MatExpr& expr) +{ + push_back(static_cast(expr)); +} + + +template inline +void Mat::push_back(const std::vector<_Tp>& v) +{ + push_back(Mat(v)); +} + +inline +Mat::Mat(Mat&& m) + : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data), + datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator), + u(m.u), size(&rows) +{ + if (m.dims <= 2) // move new step/size info + { + step[0] = m.step[0]; + step[1] = m.step[1]; + } + else + { + CV_DbgAssert(m.step.p != m.step.buf); + step.p = m.step.p; + size.p = m.size.p; + m.step.p = m.step.buf; + m.size.p = &m.rows; + } + m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0; + m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL; + m.allocator = NULL; + m.u = NULL; +} + +inline +Mat& Mat::operator = (Mat&& m) +{ + if (this == &m) + return *this; + + release(); + flags = m.flags; dims = m.dims; rows = m.rows; cols = m.cols; data = m.data; + datastart = m.datastart; dataend = m.dataend; datalimit = m.datalimit; allocator = m.allocator; + u = m.u; + if (step.p != step.buf) // release self step/size + { + fastFree(step.p); + step.p = step.buf; + size.p = &rows; + } + if (m.dims <= 2) // move new step/size info + { + step[0] = m.step[0]; + step[1] = m.step[1]; + } + else + { + CV_DbgAssert(m.step.p != m.step.buf); + step.p = m.step.p; + size.p = m.size.p; + m.step.p = m.step.buf; + m.size.p = &m.rows; + } + m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0; + m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL; + m.allocator = NULL; + m.u = NULL; + return *this; +} + + +///////////////////////////// MatSize //////////////////////////// + +inline +MatSize::MatSize(int* _p) + : p(_p) {} + +inline +int MatSize::dims() const +{ + return (p - 1)[0]; +} + +inline +Size MatSize::operator()() const +{ + CV_DbgAssert(dims() <= 2); + return Size(p[1], p[0]); +} + +inline +const int& MatSize::operator[](int i) const +{ + CV_DbgAssert(i < dims()); +#ifdef __OPENCV_BUILD + CV_DbgAssert(i >= 0); +#endif + return p[i]; +} + +inline +int& MatSize::operator[](int i) +{ + CV_DbgAssert(i < dims()); +#ifdef __OPENCV_BUILD + CV_DbgAssert(i >= 0); +#endif + return p[i]; +} + +inline +MatSize::operator const int*() const +{ + return p; +} + +inline +bool MatSize::operator == (const MatSize& sz) const +{ + int d = dims(); + int dsz = sz.dims(); + if( d != dsz ) + return false; + if( d == 2 ) + return p[0] == sz.p[0] && p[1] == sz.p[1]; + + for( int i = 0; i < d; i++ ) + if( p[i] != sz.p[i] ) + return false; + return true; +} + +inline +bool MatSize::operator != (const MatSize& sz) const +{ + return !(*this == sz); +} + + + +///////////////////////////// MatStep //////////////////////////// + +inline +MatStep::MatStep() +{ + p = buf; p[0] = p[1] = 0; +} + +inline +MatStep::MatStep(size_t s) +{ + p = buf; p[0] = s; p[1] = 0; +} + +inline +const size_t& MatStep::operator[](int i) const +{ + return p[i]; +} + +inline +size_t& MatStep::operator[](int i) +{ + return p[i]; +} + +inline MatStep::operator size_t() const +{ + CV_DbgAssert( p == buf ); + return buf[0]; +} + +inline MatStep& MatStep::operator = (size_t s) +{ + CV_DbgAssert( p == buf ); + buf[0] = s; + return *this; +} + + + +////////////////////////////// Mat_<_Tp> //////////////////////////// + +template inline +Mat_<_Tp>::Mat_() + : Mat() +{ + flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value; +} + +template inline +Mat_<_Tp>::Mat_(int _rows, int _cols) + : Mat(_rows, _cols, traits::Type<_Tp>::value) +{ +} + +template inline +Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value) + : Mat(_rows, _cols, traits::Type<_Tp>::value) +{ + *this = value; +} + +template inline +Mat_<_Tp>::Mat_(Size _sz) + : Mat(_sz.height, _sz.width, traits::Type<_Tp>::value) +{} + +template inline +Mat_<_Tp>::Mat_(Size _sz, const _Tp& value) + : Mat(_sz.height, _sz.width, traits::Type<_Tp>::value) +{ + *this = value; +} + +template inline +Mat_<_Tp>::Mat_(int _dims, const int* _sz) + : Mat(_dims, _sz, traits::Type<_Tp>::value) +{} + +template inline +Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s) + : Mat(_dims, _sz, traits::Type<_Tp>::value, Scalar(_s)) +{} + +template inline +Mat_<_Tp>::Mat_(int _dims, const int* _sz, _Tp* _data, const size_t* _steps) + : Mat(_dims, _sz, traits::Type<_Tp>::value, _data, _steps) +{} + +template inline +Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges) + : Mat(m, ranges) +{} + +template inline +Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const std::vector& ranges) + : Mat(m, ranges) +{} + +template inline +Mat_<_Tp>::Mat_(const Mat& m) + : Mat() +{ + flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value; + *this = m; +} + +template inline +Mat_<_Tp>::Mat_(const Mat_& m) + : Mat(m) +{} + +template inline +Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps) + : Mat(_rows, _cols, traits::Type<_Tp>::value, _data, steps) +{} + +template inline +Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange) + : Mat(m, _rowRange, _colRange) +{} + +template inline +Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi) + : Mat(m, roi) +{} + +template template inline +Mat_<_Tp>::Mat_(const Vec::channel_type, n>& vec, bool copyData) + : Mat(n / DataType<_Tp>::channels, 1, traits::Type<_Tp>::value, (void*)&vec) +{ + CV_Assert(n%DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template template inline +Mat_<_Tp>::Mat_(const Matx::channel_type, m, n>& M, bool copyData) + : Mat(m, n / DataType<_Tp>::channels, traits::Type<_Tp>::value, (void*)&M) +{ + CV_Assert(n % DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template inline +Mat_<_Tp>::Mat_(const Point_::channel_type>& pt, bool copyData) + : Mat(2 / DataType<_Tp>::channels, 1, traits::Type<_Tp>::value, (void*)&pt) +{ + CV_Assert(2 % DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template inline +Mat_<_Tp>::Mat_(const Point3_::channel_type>& pt, bool copyData) + : Mat(3 / DataType<_Tp>::channels, 1, traits::Type<_Tp>::value, (void*)&pt) +{ + CV_Assert(3 % DataType<_Tp>::channels == 0); + if( copyData ) + *this = clone(); +} + +template inline +Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer) + : Mat(commaInitializer) +{} + +template inline +Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData) + : Mat(vec, copyData) +{} + +template inline +Mat_<_Tp>::Mat_(std::initializer_list<_Tp> list) + : Mat(list) +{} + +template inline +Mat_<_Tp>::Mat_(const std::initializer_list sizes, std::initializer_list<_Tp> list) + : Mat(sizes, list) +{} + +template template inline +Mat_<_Tp>::Mat_(const std::array<_Tp, _Nm>& arr, bool copyData) + : Mat(arr, copyData) +{} + +template inline +Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m) +{ + if( traits::Type<_Tp>::value == m.type() ) + { + Mat::operator = (m); + return *this; + } + if( traits::Depth<_Tp>::value == m.depth() ) + { + return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0)); + } + CV_Assert(DataType<_Tp>::channels == m.channels() || m.empty()); + m.convertTo(*this, type()); + return *this; +} + +template inline +Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m) +{ + Mat::operator=(m); + return *this; +} + +template inline +Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s) +{ + typedef typename DataType<_Tp>::vec_type VT; + Mat::operator=(Scalar((const VT&)s)); + return *this; +} + +template inline +void Mat_<_Tp>::create(int _rows, int _cols) +{ + Mat::create(_rows, _cols, traits::Type<_Tp>::value); +} + +template inline +void Mat_<_Tp>::create(Size _sz) +{ + Mat::create(_sz, traits::Type<_Tp>::value); +} + +template inline +void Mat_<_Tp>::create(int _dims, const int* _sz) +{ + Mat::create(_dims, _sz, traits::Type<_Tp>::value); +} + +template inline +void Mat_<_Tp>::release() +{ + Mat::release(); +#ifdef _DEBUG + flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value; +#endif +} + +template inline +Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const +{ + return Mat_<_Tp>(Mat::cross(m)); +} + +template template inline +Mat_<_Tp>::operator Mat_() const +{ + return Mat_(*this); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::row(int y) const +{ + return Mat_(*this, Range(y, y+1), Range::all()); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::col(int x) const +{ + return Mat_(*this, Range::all(), Range(x, x+1)); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::diag(int d) const +{ + return Mat_(Mat::diag(d)); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::clone() const +{ + return Mat_(Mat::clone()); +} + +template inline +size_t Mat_<_Tp>::elemSize() const +{ + CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) ); + return sizeof(_Tp); +} + +template inline +size_t Mat_<_Tp>::elemSize1() const +{ + CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp) / DataType<_Tp>::channels ); + return sizeof(_Tp) / DataType<_Tp>::channels; +} + +template inline +int Mat_<_Tp>::type() const +{ + CV_DbgAssert( Mat::type() == traits::Type<_Tp>::value ); + return traits::Type<_Tp>::value; +} + +template inline +int Mat_<_Tp>::depth() const +{ + CV_DbgAssert( Mat::depth() == traits::Depth<_Tp>::value ); + return traits::Depth<_Tp>::value; +} + +template inline +int Mat_<_Tp>::channels() const +{ + CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels ); + return DataType<_Tp>::channels; +} + +template inline +size_t Mat_<_Tp>::stepT(int i) const +{ + return step.p[i] / elemSize(); +} + +template inline +size_t Mat_<_Tp>::step1(int i) const +{ + return step.p[i] / elemSize1(); +} + +template inline +Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright ) +{ + return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright)); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const +{ + return Mat_<_Tp>(*this, _rowRange, _colRange); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const +{ + return Mat_<_Tp>(*this, roi); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const +{ + return Mat_<_Tp>(*this, ranges); +} + +template inline +Mat_<_Tp> Mat_<_Tp>::operator()(const std::vector& ranges) const +{ + return Mat_<_Tp>(*this, ranges); +} + +template inline +_Tp* Mat_<_Tp>::operator [](int y) +{ + CV_DbgAssert( 0 <= y && y < size.p[0] ); + return (_Tp*)(data + y*step.p[0]); +} + +template inline +const _Tp* Mat_<_Tp>::operator [](int y) const +{ + CV_DbgAssert( 0 <= y && y < size.p[0] ); + return (const _Tp*)(data + y*step.p[0]); +} + +template inline +_Tp& Mat_<_Tp>::operator ()(int i0, int i1) +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + CV_DbgAssert(type() == traits::Type<_Tp>::value); + return ((_Tp*)(data + step.p[0] * i0))[i1]; +} + +template inline +const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); + CV_DbgAssert(type() == traits::Type<_Tp>::value); + return ((const _Tp*)(data + step.p[0] * i0))[i1]; +} + +template inline +_Tp& Mat_<_Tp>::operator ()(Point pt) +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]); + CV_DbgAssert(type() == traits::Type<_Tp>::value); + return ((_Tp*)(data + step.p[0] * pt.y))[pt.x]; +} + +template inline +const _Tp& Mat_<_Tp>::operator ()(Point pt) const +{ + CV_DbgAssert(dims <= 2); + CV_DbgAssert(data); + CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); + CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]); + CV_DbgAssert(type() == traits::Type<_Tp>::value); + return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x]; +} + +template inline +_Tp& Mat_<_Tp>::operator ()(const int* idx) +{ + return Mat::at<_Tp>(idx); +} + +template inline +const _Tp& Mat_<_Tp>::operator ()(const int* idx) const +{ + return Mat::at<_Tp>(idx); +} + +template template inline +_Tp& Mat_<_Tp>::operator ()(const Vec& idx) +{ + return Mat::at<_Tp>(idx); +} + +template template inline +const _Tp& Mat_<_Tp>::operator ()(const Vec& idx) const +{ + return Mat::at<_Tp>(idx); +} + +template inline +_Tp& Mat_<_Tp>::operator ()(int i0) +{ + return this->at<_Tp>(i0); +} + +template inline +const _Tp& Mat_<_Tp>::operator ()(int i0) const +{ + return this->at<_Tp>(i0); +} + +template inline +_Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) +{ + return this->at<_Tp>(i0, i1, i2); +} + +template inline +const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const +{ + return this->at<_Tp>(i0, i1, i2); +} + +template inline +Mat_<_Tp>::operator std::vector<_Tp>() const +{ + std::vector<_Tp> v; + copyTo(v); + return v; +} + +template template inline +Mat_<_Tp>::operator std::array<_Tp, _Nm>() const +{ + std::array<_Tp, _Nm> a; + copyTo(a); + return a; +} + +template template inline +Mat_<_Tp>::operator Vec::channel_type, n>() const +{ + CV_Assert(n % DataType<_Tp>::channels == 0); + +#if defined _MSC_VER + const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround) + return pMat->operator Vec::channel_type, n>(); +#else + return this->Mat::operator Vec::channel_type, n>(); +#endif +} + +template template inline +Mat_<_Tp>::operator Matx::channel_type, m, n>() const +{ + CV_Assert(n % DataType<_Tp>::channels == 0); + +#if defined _MSC_VER + const Mat* pMat = (const Mat*)this; // workaround for MSVS <= 2012 compiler bugs (but GCC 4.6 dislikes this workaround) + Matx::channel_type, m, n> res = pMat->operator Matx::channel_type, m, n>(); + return res; +#else + Matx::channel_type, m, n> res = this->Mat::operator Matx::channel_type, m, n>(); + return res; +#endif +} + +template inline +MatConstIterator_<_Tp> Mat_<_Tp>::begin() const +{ + return Mat::begin<_Tp>(); +} + +template inline +MatConstIterator_<_Tp> Mat_<_Tp>::end() const +{ + return Mat::end<_Tp>(); +} + +template inline +MatIterator_<_Tp> Mat_<_Tp>::begin() +{ + return Mat::begin<_Tp>(); +} + +template inline +MatIterator_<_Tp> Mat_<_Tp>::end() +{ + return Mat::end<_Tp>(); +} + +template template inline +void Mat_<_Tp>::forEach(const Functor& operation) { + Mat::forEach<_Tp, Functor>(operation); +} + +template template inline +void Mat_<_Tp>::forEach(const Functor& operation) const { + Mat::forEach<_Tp, Functor>(operation); +} + +template inline +Mat_<_Tp>::Mat_(Mat_&& m) + : Mat(m) +{ +} + +template inline +Mat_<_Tp>& Mat_<_Tp>::operator = (Mat_&& m) +{ + Mat::operator = (std::move(m)); + return *this; +} + +template inline +Mat_<_Tp>::Mat_(Mat&& m) + : Mat() +{ + flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value; + *this = m; +} + +template inline +Mat_<_Tp>& Mat_<_Tp>::operator = (Mat&& m) +{ + if( traits::Type<_Tp>::value == m.type() ) + { + Mat::operator = ((Mat&&)m); + return *this; + } + if( traits::Depth<_Tp>::value == m.depth() ) + { + Mat::operator = ((Mat&&)m.reshape(DataType<_Tp>::channels, m.dims, 0)); + return *this; + } + CV_DbgAssert(DataType<_Tp>::channels == m.channels()); + m.convertTo(*this, type()); + return *this; +} + +template inline +Mat_<_Tp>::Mat_(MatExpr&& e) + : Mat() +{ + flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value; + *this = Mat(e); +} + + +///////////////////////////// SparseMat ///////////////////////////// + +inline +SparseMat::SparseMat() + : flags(MAGIC_VAL), hdr(0) +{} + +inline +SparseMat::SparseMat(int _dims, const int* _sizes, int _type) + : flags(MAGIC_VAL), hdr(0) +{ + create(_dims, _sizes, _type); +} + +inline +SparseMat::SparseMat(const SparseMat& m) + : flags(m.flags), hdr(m.hdr) +{ + addref(); +} + +inline +SparseMat::~SparseMat() +{ + release(); +} + +inline +SparseMat& SparseMat::operator = (const SparseMat& m) +{ + if( this != &m ) + { + if( m.hdr ) + CV_XADD(&m.hdr->refcount, 1); + release(); + flags = m.flags; + hdr = m.hdr; + } + return *this; +} + +inline +SparseMat& SparseMat::operator = (const Mat& m) +{ + return (*this = SparseMat(m)); +} + +inline +SparseMat SparseMat::clone() const +{ + SparseMat temp; + this->copyTo(temp); + return temp; +} + +inline +void SparseMat::assignTo( SparseMat& m, int _type ) const +{ + if( _type < 0 ) + m = *this; + else + convertTo(m, _type); +} + +inline +void SparseMat::addref() +{ + if( hdr ) + CV_XADD(&hdr->refcount, 1); +} + +inline +void SparseMat::release() +{ + if( hdr && CV_XADD(&hdr->refcount, -1) == 1 ) + delete hdr; + hdr = 0; +} + +inline +size_t SparseMat::elemSize() const +{ + return CV_ELEM_SIZE(flags); +} + +inline +size_t SparseMat::elemSize1() const +{ + return CV_ELEM_SIZE1(flags); +} + +inline +int SparseMat::type() const +{ + return CV_MAT_TYPE(flags); +} + +inline +int SparseMat::depth() const +{ + return CV_MAT_DEPTH(flags); +} + +inline +int SparseMat::channels() const +{ + return CV_MAT_CN(flags); +} + +inline +const int* SparseMat::size() const +{ + return hdr ? hdr->size : 0; +} + +inline +int SparseMat::size(int i) const +{ + if( hdr ) + { + CV_DbgAssert((unsigned)i < (unsigned)hdr->dims); + return hdr->size[i]; + } + return 0; +} + +inline +int SparseMat::dims() const +{ + return hdr ? hdr->dims : 0; +} + +inline +size_t SparseMat::nzcount() const +{ + return hdr ? hdr->nodeCount : 0; +} + +inline +size_t SparseMat::hash(int i0) const +{ + return (size_t)i0; +} + +inline +size_t SparseMat::hash(int i0, int i1) const +{ + return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1; +} + +inline +size_t SparseMat::hash(int i0, int i1, int i2) const +{ + return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2; +} + +inline +size_t SparseMat::hash(const int* idx) const +{ + size_t h = (unsigned)idx[0]; + if( !hdr ) + return 0; + int d = hdr->dims; + for(int i = 1; i < d; i++ ) + h = h * HASH_SCALE + (unsigned)idx[i]; + return h; +} + +template inline +_Tp& SparseMat::ref(int i0, size_t* hashval) +{ + return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); +} + +template inline +_Tp& SparseMat::ref(int i0, int i1, size_t* hashval) +{ + return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); +} + +template inline +_Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval) +{ + return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); +} + +template inline +_Tp& SparseMat::ref(const int* idx, size_t* hashval) +{ + return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); +} + +template inline +_Tp SparseMat::value(int i0, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); + return p ? *p : _Tp(); +} + +template inline +_Tp SparseMat::value(int i0, int i1, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); + return p ? *p : _Tp(); +} + +template inline +_Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); + return p ? *p : _Tp(); +} + +template inline +_Tp SparseMat::value(const int* idx, size_t* hashval) const +{ + const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); + return p ? *p : _Tp(); +} + +template inline +const _Tp* SparseMat::find(int i0, size_t* hashval) const +{ + return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); +} + +template inline +const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const +{ + return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); +} + +template inline +const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const +{ + return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); +} + +template inline +const _Tp* SparseMat::find(const int* idx, size_t* hashval) const +{ + return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); +} + +template inline +_Tp& SparseMat::value(Node* n) +{ + return *(_Tp*)((uchar*)n + hdr->valueOffset); +} + +template inline +const _Tp& SparseMat::value(const Node* n) const +{ + return *(const _Tp*)((const uchar*)n + hdr->valueOffset); +} + +inline +SparseMat::Node* SparseMat::node(size_t nidx) +{ + return (Node*)(void*)&hdr->pool[nidx]; +} + +inline +const SparseMat::Node* SparseMat::node(size_t nidx) const +{ + return (const Node*)(const void*)&hdr->pool[nidx]; +} + +inline +SparseMatIterator SparseMat::begin() +{ + return SparseMatIterator(this); +} + +inline +SparseMatConstIterator SparseMat::begin() const +{ + return SparseMatConstIterator(this); +} + +inline +SparseMatIterator SparseMat::end() +{ + SparseMatIterator it(this); + it.seekEnd(); + return it; +} + +inline +SparseMatConstIterator SparseMat::end() const +{ + SparseMatConstIterator it(this); + it.seekEnd(); + return it; +} + +template inline +SparseMatIterator_<_Tp> SparseMat::begin() +{ + return SparseMatIterator_<_Tp>(this); +} + +template inline +SparseMatConstIterator_<_Tp> SparseMat::begin() const +{ + return SparseMatConstIterator_<_Tp>(this); +} + +template inline +SparseMatIterator_<_Tp> SparseMat::end() +{ + SparseMatIterator_<_Tp> it(this); + it.seekEnd(); + return it; +} + +template inline +SparseMatConstIterator_<_Tp> SparseMat::end() const +{ + SparseMatConstIterator_<_Tp> it(this); + it.seekEnd(); + return it; +} + + + +///////////////////////////// SparseMat_ //////////////////////////// + +template inline +SparseMat_<_Tp>::SparseMat_() +{ + flags = MAGIC_VAL + traits::Type<_Tp>::value; +} + +template inline +SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes) + : SparseMat(_dims, _sizes, traits::Type<_Tp>::value) +{} + +template inline +SparseMat_<_Tp>::SparseMat_(const SparseMat& m) +{ + if( m.type() == traits::Type<_Tp>::value ) + *this = (const SparseMat_<_Tp>&)m; + else + m.convertTo(*this, traits::Type<_Tp>::value); +} + +template inline +SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m) +{ + this->flags = m.flags; + this->hdr = m.hdr; + if( this->hdr ) + CV_XADD(&this->hdr->refcount, 1); +} + +template inline +SparseMat_<_Tp>::SparseMat_(const Mat& m) +{ + SparseMat sm(m); + *this = sm; +} + +template inline +SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m) +{ + if( this != &m ) + { + if( m.hdr ) CV_XADD(&m.hdr->refcount, 1); + release(); + flags = m.flags; + hdr = m.hdr; + } + return *this; +} + +template inline +SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m) +{ + if( m.type() == traits::Type<_Tp>::value ) + return (*this = (const SparseMat_<_Tp>&)m); + m.convertTo(*this, traits::Type<_Tp>::value); + return *this; +} + +template inline +SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const Mat& m) +{ + return (*this = SparseMat(m)); +} + +template inline +SparseMat_<_Tp> SparseMat_<_Tp>::clone() const +{ + SparseMat_<_Tp> m; + this->copyTo(m); + return m; +} + +template inline +void SparseMat_<_Tp>::create(int _dims, const int* _sizes) +{ + SparseMat::create(_dims, _sizes, traits::Type<_Tp>::value); +} + +template inline +int SparseMat_<_Tp>::type() const +{ + return traits::Type<_Tp>::value; +} + +template inline +int SparseMat_<_Tp>::depth() const +{ + return traits::Depth<_Tp>::value; +} + +template inline +int SparseMat_<_Tp>::channels() const +{ + return DataType<_Tp>::channels; +} + +template inline +_Tp& SparseMat_<_Tp>::ref(int i0, size_t* hashval) +{ + return SparseMat::ref<_Tp>(i0, hashval); +} + +template inline +_Tp SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const +{ + return SparseMat::value<_Tp>(i0, hashval); +} + +template inline +_Tp& SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval) +{ + return SparseMat::ref<_Tp>(i0, i1, hashval); +} + +template inline +_Tp SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const +{ + return SparseMat::value<_Tp>(i0, i1, hashval); +} + +template inline +_Tp& SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval) +{ + return SparseMat::ref<_Tp>(i0, i1, i2, hashval); +} + +template inline +_Tp SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const +{ + return SparseMat::value<_Tp>(i0, i1, i2, hashval); +} + +template inline +_Tp& SparseMat_<_Tp>::ref(const int* idx, size_t* hashval) +{ + return SparseMat::ref<_Tp>(idx, hashval); +} + +template inline +_Tp SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const +{ + return SparseMat::value<_Tp>(idx, hashval); +} + +template inline +SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin() +{ + return SparseMatIterator_<_Tp>(this); +} + +template inline +SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const +{ + return SparseMatConstIterator_<_Tp>(this); +} + +template inline +SparseMatIterator_<_Tp> SparseMat_<_Tp>::end() +{ + SparseMatIterator_<_Tp> it(this); + it.seekEnd(); + return it; +} + +template inline +SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const +{ + SparseMatConstIterator_<_Tp> it(this); + it.seekEnd(); + return it; +} + + + +////////////////////////// MatConstIterator ///////////////////////// + +inline +MatConstIterator::MatConstIterator() + : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) +{} + +inline +MatConstIterator::MatConstIterator(const Mat* _m) + : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0) +{ + if( m && m->isContinuous() ) + { + sliceStart = m->ptr(); + sliceEnd = sliceStart + m->total()*elemSize; + } + seek((const int*)0); +} + +inline +MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col) + : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0) +{ + CV_Assert(m && m->dims <= 2); + if( m->isContinuous() ) + { + sliceStart = m->ptr(); + sliceEnd = sliceStart + m->total()*elemSize; + } + int idx[] = {_row, _col}; + seek(idx); +} + +inline +MatConstIterator::MatConstIterator(const Mat* _m, Point _pt) + : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0) +{ + CV_Assert(m && m->dims <= 2); + if( m->isContinuous() ) + { + sliceStart = m->ptr(); + sliceEnd = sliceStart + m->total()*elemSize; + } + int idx[] = {_pt.y, _pt.x}; + seek(idx); +} + +inline +MatConstIterator::MatConstIterator(const MatConstIterator& it) + : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd) +{} + +inline +MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it ) +{ + m = it.m; elemSize = it.elemSize; ptr = it.ptr; + sliceStart = it.sliceStart; sliceEnd = it.sliceEnd; + return *this; +} + +inline +const uchar* MatConstIterator::operator *() const +{ + return ptr; +} + +inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs) +{ + if( !m || ofs == 0 ) + return *this; + ptrdiff_t ofsb = ofs*elemSize; + ptr += ofsb; + if( ptr < sliceStart || sliceEnd <= ptr ) + { + ptr -= ofsb; + seek(ofs, true); + } + return *this; +} + +inline +MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs) +{ + return (*this += -ofs); +} + +inline +MatConstIterator& MatConstIterator::operator --() +{ + if( m && (ptr -= elemSize) < sliceStart ) + { + ptr += elemSize; + seek(-1, true); + } + return *this; +} + +inline +MatConstIterator MatConstIterator::operator --(int) +{ + MatConstIterator b = *this; + *this += -1; + return b; +} + +inline +MatConstIterator& MatConstIterator::operator ++() +{ + if( m && (ptr += elemSize) >= sliceEnd ) + { + ptr -= elemSize; + seek(1, true); + } + return *this; +} + +inline MatConstIterator MatConstIterator::operator ++(int) +{ + MatConstIterator b = *this; + *this += 1; + return b; +} + + +static inline +bool operator == (const MatConstIterator& a, const MatConstIterator& b) +{ + return a.m == b.m && a.ptr == b.ptr; +} + +static inline +bool operator != (const MatConstIterator& a, const MatConstIterator& b) +{ + return !(a == b); +} + +static inline +bool operator < (const MatConstIterator& a, const MatConstIterator& b) +{ + return a.ptr < b.ptr; +} + +static inline +bool operator > (const MatConstIterator& a, const MatConstIterator& b) +{ + return a.ptr > b.ptr; +} + +static inline +bool operator <= (const MatConstIterator& a, const MatConstIterator& b) +{ + return a.ptr <= b.ptr; +} + +static inline +bool operator >= (const MatConstIterator& a, const MatConstIterator& b) +{ + return a.ptr >= b.ptr; +} + +static inline +ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a) +{ + if( a.m != b.m ) + return ((size_t)(-1) >> 1); + if( a.sliceEnd == b.sliceEnd ) + return (b.ptr - a.ptr)/static_cast(b.elemSize); + + return b.lpos() - a.lpos(); +} + +static inline +MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs) +{ + MatConstIterator b = a; + return b += ofs; +} + +static inline +MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a) +{ + MatConstIterator b = a; + return b += ofs; +} + +static inline +MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs) +{ + MatConstIterator b = a; + return b += -ofs; +} + + +inline +const uchar* MatConstIterator::operator [](ptrdiff_t i) const +{ + return *(*this + i); +} + + + +///////////////////////// MatConstIterator_ ///////////////////////// + +template inline +MatConstIterator_<_Tp>::MatConstIterator_() +{} + +template inline +MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m) + : MatConstIterator(_m) +{} + +template inline +MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col) + : MatConstIterator(_m, _row, _col) +{} + +template inline +MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m, Point _pt) + : MatConstIterator(_m, _pt) +{} + +template inline +MatConstIterator_<_Tp>::MatConstIterator_(const MatConstIterator_& it) + : MatConstIterator(it) +{} + +template inline +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it ) +{ + MatConstIterator::operator = (it); + return *this; +} + +template inline +const _Tp& MatConstIterator_<_Tp>::operator *() const +{ + return *(_Tp*)(this->ptr); +} + +template inline +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs) +{ + MatConstIterator::operator += (ofs); + return *this; +} + +template inline +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs) +{ + return (*this += -ofs); +} + +template inline +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --() +{ + MatConstIterator::operator --(); + return *this; +} + +template inline +MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int) +{ + MatConstIterator_ b = *this; + MatConstIterator::operator --(); + return b; +} + +template inline +MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++() +{ + MatConstIterator::operator ++(); + return *this; +} + +template inline +MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int) +{ + MatConstIterator_ b = *this; + MatConstIterator::operator ++(); + return b; +} + + +template inline +Point MatConstIterator_<_Tp>::pos() const +{ + if( !m ) + return Point(); + CV_DbgAssert( m->dims <= 2 ); + if( m->isContinuous() ) + { + ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data; + int y = (int)(ofs / m->cols); + int x = (int)(ofs - (ptrdiff_t)y * m->cols); + return Point(x, y); + } + else + { + ptrdiff_t ofs = (uchar*)ptr - m->data; + int y = (int)(ofs / m->step); + int x = (int)((ofs - y * m->step)/sizeof(_Tp)); + return Point(x, y); + } +} + + +template static inline +bool operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b) +{ + return a.m == b.m && a.ptr == b.ptr; +} + +template static inline +bool operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b) +{ + return a.m != b.m || a.ptr != b.ptr; +} + +template static inline +MatConstIterator_<_Tp> operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs) +{ + MatConstIterator t = (const MatConstIterator&)a + ofs; + return (MatConstIterator_<_Tp>&)t; +} + +template static inline +MatConstIterator_<_Tp> operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a) +{ + MatConstIterator t = (const MatConstIterator&)a + ofs; + return (MatConstIterator_<_Tp>&)t; +} + +template static inline +MatConstIterator_<_Tp> operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs) +{ + MatConstIterator t = (const MatConstIterator&)a - ofs; + return (MatConstIterator_<_Tp>&)t; +} + +template inline +const _Tp& MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const +{ + return *(_Tp*)MatConstIterator::operator [](i); +} + + + +//////////////////////////// MatIterator_ /////////////////////////// + +template inline +MatIterator_<_Tp>::MatIterator_() + : MatConstIterator_<_Tp>() +{} + +template inline +MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m) + : MatConstIterator_<_Tp>(_m) +{} + +template inline +MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col) + : MatConstIterator_<_Tp>(_m, _row, _col) +{} + +template inline +MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, Point _pt) + : MatConstIterator_<_Tp>(_m, _pt) +{} + +template inline +MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, const int* _idx) + : MatConstIterator_<_Tp>(_m, _idx) +{} + +template inline +MatIterator_<_Tp>::MatIterator_(const MatIterator_& it) + : MatConstIterator_<_Tp>(it) +{} + +template inline +MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it ) +{ + MatConstIterator::operator = (it); + return *this; +} + +template inline +_Tp& MatIterator_<_Tp>::operator *() const +{ + return *(_Tp*)(this->ptr); +} + +template inline +MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs) +{ + MatConstIterator::operator += (ofs); + return *this; +} + +template inline +MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs) +{ + MatConstIterator::operator += (-ofs); + return *this; +} + +template inline +MatIterator_<_Tp>& MatIterator_<_Tp>::operator --() +{ + MatConstIterator::operator --(); + return *this; +} + +template inline +MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int) +{ + MatIterator_ b = *this; + MatConstIterator::operator --(); + return b; +} + +template inline +MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++() +{ + MatConstIterator::operator ++(); + return *this; +} + +template inline +MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int) +{ + MatIterator_ b = *this; + MatConstIterator::operator ++(); + return b; +} + +template inline +_Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const +{ + return *(*this + i); +} + + +template static inline +bool operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b) +{ + return a.m == b.m && a.ptr == b.ptr; +} + +template static inline +bool operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b) +{ + return a.m != b.m || a.ptr != b.ptr; +} + +template static inline +MatIterator_<_Tp> operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs) +{ + MatConstIterator t = (const MatConstIterator&)a + ofs; + return (MatIterator_<_Tp>&)t; +} + +template static inline +MatIterator_<_Tp> operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a) +{ + MatConstIterator t = (const MatConstIterator&)a + ofs; + return (MatIterator_<_Tp>&)t; +} + +template static inline +MatIterator_<_Tp> operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs) +{ + MatConstIterator t = (const MatConstIterator&)a - ofs; + return (MatIterator_<_Tp>&)t; +} + + + +/////////////////////// SparseMatConstIterator ////////////////////// + +inline +SparseMatConstIterator::SparseMatConstIterator() + : m(0), hashidx(0), ptr(0) +{} + +inline +SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it) + : m(it.m), hashidx(it.hashidx), ptr(it.ptr) +{} + +inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it) +{ + if( this != &it ) + { + m = it.m; + hashidx = it.hashidx; + ptr = it.ptr; + } + return *this; +} + +template inline +const _Tp& SparseMatConstIterator::value() const +{ + return *(const _Tp*)ptr; +} + +inline +const SparseMat::Node* SparseMatConstIterator::node() const +{ + return (ptr && m && m->hdr) ? (const SparseMat::Node*)(const void*)(ptr - m->hdr->valueOffset) : 0; +} + +inline +SparseMatConstIterator SparseMatConstIterator::operator ++(int) +{ + SparseMatConstIterator it = *this; + ++*this; + return it; +} + +inline +void SparseMatConstIterator::seekEnd() +{ + if( m && m->hdr ) + { + hashidx = m->hdr->hashtab.size(); + ptr = 0; + } +} + + +static inline +bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2) +{ + return it1.m == it2.m && it1.ptr == it2.ptr; +} + +static inline +bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2) +{ + return !(it1 == it2); +} + + + +///////////////////////// SparseMatIterator ///////////////////////// + +inline +SparseMatIterator::SparseMatIterator() +{} + +inline +SparseMatIterator::SparseMatIterator(SparseMat* _m) + : SparseMatConstIterator(_m) +{} + +inline +SparseMatIterator::SparseMatIterator(const SparseMatIterator& it) + : SparseMatConstIterator(it) +{} + +inline +SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it) +{ + (SparseMatConstIterator&)*this = it; + return *this; +} + +template inline +_Tp& SparseMatIterator::value() const +{ + return *(_Tp*)ptr; +} + +inline +SparseMat::Node* SparseMatIterator::node() const +{ + return (SparseMat::Node*)SparseMatConstIterator::node(); +} + +inline +SparseMatIterator& SparseMatIterator::operator ++() +{ + SparseMatConstIterator::operator ++(); + return *this; +} + +inline +SparseMatIterator SparseMatIterator::operator ++(int) +{ + SparseMatIterator it = *this; + ++*this; + return it; +} + + + +////////////////////// SparseMatConstIterator_ ////////////////////// + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_() +{} + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m) + : SparseMatConstIterator(_m) +{} + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m) + : SparseMatConstIterator(_m) +{ + CV_Assert( _m->type() == traits::Type<_Tp>::value ); +} + +template inline +SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it) + : SparseMatConstIterator(it) +{} + +template inline +SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it) +{ + return reinterpret_cast&> + (*reinterpret_cast(this) = + reinterpret_cast(it)); +} + +template inline +const _Tp& SparseMatConstIterator_<_Tp>::operator *() const +{ + return *(const _Tp*)this->ptr; +} + +template inline +SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++() +{ + SparseMatConstIterator::operator ++(); + return *this; +} + +template inline +SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int) +{ + SparseMatConstIterator_<_Tp> it = *this; + SparseMatConstIterator::operator ++(); + return it; +} + + + +///////////////////////// SparseMatIterator_ //////////////////////// + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_() +{} + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m) + : SparseMatConstIterator_<_Tp>(_m) +{} + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m) + : SparseMatConstIterator_<_Tp>(_m) +{} + +template inline +SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it) + : SparseMatConstIterator_<_Tp>(it) +{} + +template inline +SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it) +{ + return reinterpret_cast&> + (*reinterpret_cast(this) = + reinterpret_cast(it)); +} + +template inline +_Tp& SparseMatIterator_<_Tp>::operator *() const +{ + return *(_Tp*)this->ptr; +} + +template inline +SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++() +{ + SparseMatConstIterator::operator ++(); + return *this; +} + +template inline +SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int) +{ + SparseMatIterator_<_Tp> it = *this; + SparseMatConstIterator::operator ++(); + return it; +} + + + +//////////////////////// MatCommaInitializer_ /////////////////////// + +template inline +MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) + : it(_m) +{} + +template template inline +MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v) +{ + CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() ); + *this->it = _Tp(v); + ++this->it; + return *this; +} + +template inline +MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const +{ + CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() ); + return Mat_<_Tp>(*this->it.m); +} + + +template static inline +MatCommaInitializer_<_Tp> operator << (const Mat_<_Tp>& m, T2 val) +{ + MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m); + return (commaInitializer, val); +} + + + +///////////////////////// Matrix Expressions //////////////////////// + +inline +Mat& Mat::operator = (const MatExpr& e) +{ + e.op->assign(e, *this); + return *this; +} + +template inline +Mat_<_Tp>::Mat_(const MatExpr& e) +{ + e.op->assign(e, *this, traits::Type<_Tp>::value); +} + +template inline +Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e) +{ + e.op->assign(e, *this, traits::Type<_Tp>::value); + return *this; +} + +template inline +MatExpr Mat_<_Tp>::zeros(int rows, int cols) +{ + return Mat::zeros(rows, cols, traits::Type<_Tp>::value); +} + +template inline +MatExpr Mat_<_Tp>::zeros(Size sz) +{ + return Mat::zeros(sz, traits::Type<_Tp>::value); +} + +template inline +MatExpr Mat_<_Tp>::ones(int rows, int cols) +{ + return Mat::ones(rows, cols, traits::Type<_Tp>::value); +} + +template inline +MatExpr Mat_<_Tp>::ones(Size sz) +{ + return Mat::ones(sz, traits::Type<_Tp>::value); +} + +template inline +MatExpr Mat_<_Tp>::eye(int rows, int cols) +{ + return Mat::eye(rows, cols, traits::Type<_Tp>::value); +} + +template inline +MatExpr Mat_<_Tp>::eye(Size sz) +{ + return Mat::eye(sz, traits::Type<_Tp>::value); +} + +inline +MatExpr::MatExpr() + : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s() +{} + +inline +MatExpr::MatExpr(const MatOp* _op, int _flags, const Mat& _a, const Mat& _b, + const Mat& _c, double _alpha, double _beta, const Scalar& _s) + : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s) +{} + +inline +MatExpr::operator Mat() const +{ + Mat m; + op->assign(*this, m); + return m; +} + +template inline +MatExpr::operator Mat_<_Tp>() const +{ + Mat_<_Tp> m; + op->assign(*this, m, traits::Type<_Tp>::value); + return m; +} + + +template static inline +MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + return cv::min((const Mat&)a, (const Mat&)b); +} + +template static inline +MatExpr min(const Mat_<_Tp>& a, double s) +{ + return cv::min((const Mat&)a, s); +} + +template static inline +MatExpr min(double s, const Mat_<_Tp>& a) +{ + return cv::min((const Mat&)a, s); +} + +template static inline +MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + return cv::max((const Mat&)a, (const Mat&)b); +} + +template static inline +MatExpr max(const Mat_<_Tp>& a, double s) +{ + return cv::max((const Mat&)a, s); +} + +template static inline +MatExpr max(double s, const Mat_<_Tp>& a) +{ + return cv::max((const Mat&)a, s); +} + +template static inline +MatExpr abs(const Mat_<_Tp>& m) +{ + return cv::abs((const Mat&)m); +} + + +static inline +Mat& operator += (Mat& a, const MatExpr& b) +{ + b.op->augAssignAdd(b, a); + return a; +} + +static inline +const Mat& operator += (const Mat& a, const MatExpr& b) +{ + b.op->augAssignAdd(b, (Mat&)a); + return a; +} + +template static inline +Mat_<_Tp>& operator += (Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignAdd(b, a); + return a; +} + +template static inline +const Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignAdd(b, (Mat&)a); + return a; +} + +static inline +Mat& operator -= (Mat& a, const MatExpr& b) +{ + b.op->augAssignSubtract(b, a); + return a; +} + +static inline +const Mat& operator -= (const Mat& a, const MatExpr& b) +{ + b.op->augAssignSubtract(b, (Mat&)a); + return a; +} + +template static inline +Mat_<_Tp>& operator -= (Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignSubtract(b, a); + return a; +} + +template static inline +const Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignSubtract(b, (Mat&)a); + return a; +} + +static inline +Mat& operator *= (Mat& a, const MatExpr& b) +{ + b.op->augAssignMultiply(b, a); + return a; +} + +static inline +const Mat& operator *= (const Mat& a, const MatExpr& b) +{ + b.op->augAssignMultiply(b, (Mat&)a); + return a; +} + +template static inline +Mat_<_Tp>& operator *= (Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignMultiply(b, a); + return a; +} + +template static inline +const Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignMultiply(b, (Mat&)a); + return a; +} + +static inline +Mat& operator /= (Mat& a, const MatExpr& b) +{ + b.op->augAssignDivide(b, a); + return a; +} + +static inline +const Mat& operator /= (const Mat& a, const MatExpr& b) +{ + b.op->augAssignDivide(b, (Mat&)a); + return a; +} + +template static inline +Mat_<_Tp>& operator /= (Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignDivide(b, a); + return a; +} + +template static inline +const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignDivide(b, (Mat&)a); + return a; +} + + +//////////////////////////////// UMat //////////////////////////////// + +inline +UMat::UMat(UMatUsageFlags _usageFlags) +: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows) +{} + +inline +UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags) +: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows) +{ + create(_rows, _cols, _type); +} + +inline +UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags) +: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows) +{ + create(_rows, _cols, _type); + *this = _s; +} + +inline +UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags) +: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows) +{ + create( _sz.height, _sz.width, _type ); +} + +inline +UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags) +: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows) +{ + create(_sz.height, _sz.width, _type); + *this = _s; +} + +inline +UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags) +: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows) +{ + create(_dims, _sz, _type); +} + +inline +UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags) +: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows) +{ + create(_dims, _sz, _type); + *this = _s; +} + +inline +UMat::UMat(const UMat& m) +: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator), + usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows) +{ + addref(); + if( m.dims <= 2 ) + { + step[0] = m.step[0]; step[1] = m.step[1]; + } + else + { + dims = 0; + copySize(m); + } +} + + +template inline +UMat::UMat(const std::vector<_Tp>& vec, bool copyData) +: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()), +cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows) +{ + if(vec.empty()) + return; + if( !copyData ) + { + // !!!TODO!!! + CV_Error(Error::StsNotImplemented, ""); + } + else + Mat((int)vec.size(), 1, traits::Type<_Tp>::value, (uchar*)&vec[0]).copyTo(*this); +} + +inline +UMat& UMat::operator = (const UMat& m) +{ + if( this != &m ) + { + const_cast(m).addref(); + release(); + flags = m.flags; + if( dims <= 2 && m.dims <= 2 ) + { + dims = m.dims; + rows = m.rows; + cols = m.cols; + step[0] = m.step[0]; + step[1] = m.step[1]; + } + else + copySize(m); + allocator = m.allocator; + if (usageFlags == USAGE_DEFAULT) + usageFlags = m.usageFlags; + u = m.u; + offset = m.offset; + } + return *this; +} + +inline +UMat UMat::row(int y) const +{ + return UMat(*this, Range(y, y + 1), Range::all()); +} + +inline +UMat UMat::col(int x) const +{ + return UMat(*this, Range::all(), Range(x, x + 1)); +} + +inline +UMat UMat::rowRange(int startrow, int endrow) const +{ + return UMat(*this, Range(startrow, endrow), Range::all()); +} + +inline +UMat UMat::rowRange(const Range& r) const +{ + return UMat(*this, r, Range::all()); +} + +inline +UMat UMat::colRange(int startcol, int endcol) const +{ + return UMat(*this, Range::all(), Range(startcol, endcol)); +} + +inline +UMat UMat::colRange(const Range& r) const +{ + return UMat(*this, Range::all(), r); +} + +inline +UMat UMat::clone() const +{ + UMat m; + copyTo(m); + return m; +} + +inline +void UMat::assignTo( UMat& m, int _type ) const +{ + if( _type < 0 ) + m = *this; + else + convertTo(m, _type); +} + +inline +void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags) +{ + _type &= TYPE_MASK; + if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u ) + return; + int sz[] = {_rows, _cols}; + create(2, sz, _type, _usageFlags); +} + +inline +void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags) +{ + create(_sz.height, _sz.width, _type, _usageFlags); +} + +inline +void UMat::addref() +{ + if( u ) + CV_XADD(&(u->urefcount), 1); +} + +inline void UMat::release() +{ + if( u && CV_XADD(&(u->urefcount), -1) == 1 ) + deallocate(); + for(int i = 0; i < dims; i++) + size.p[i] = 0; + u = 0; +} + +inline +UMat UMat::operator()( Range _rowRange, Range _colRange ) const +{ + return UMat(*this, _rowRange, _colRange); +} + +inline +UMat UMat::operator()( const Rect& roi ) const +{ + return UMat(*this, roi); +} + +inline +UMat UMat::operator()(const Range* ranges) const +{ + return UMat(*this, ranges); +} + +inline +UMat UMat::operator()(const std::vector& ranges) const +{ + return UMat(*this, ranges); +} + +inline +bool UMat::isContinuous() const +{ + return (flags & CONTINUOUS_FLAG) != 0; +} + +inline +bool UMat::isSubmatrix() const +{ + return (flags & SUBMATRIX_FLAG) != 0; +} + +inline +size_t UMat::elemSize() const +{ + size_t res = dims > 0 ? step.p[dims - 1] : 0; + CV_DbgAssert(res != 0); + return res; +} + +inline +size_t UMat::elemSize1() const +{ + return CV_ELEM_SIZE1(flags); +} + +inline +int UMat::type() const +{ + return CV_MAT_TYPE(flags); +} + +inline +int UMat::depth() const +{ + return CV_MAT_DEPTH(flags); +} + +inline +int UMat::channels() const +{ + return CV_MAT_CN(flags); +} + +inline +size_t UMat::step1(int i) const +{ + return step.p[i] / elemSize1(); +} + +inline +bool UMat::empty() const +{ + return u == 0 || total() == 0 || dims == 0; +} + +inline +size_t UMat::total() const +{ + if( dims <= 2 ) + return (size_t)rows * cols; + size_t p = 1; + for( int i = 0; i < dims; i++ ) + p *= size[i]; + return p; +} + +inline +UMat::UMat(UMat&& m) +: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator), + usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows) +{ + if (m.dims <= 2) // move new step/size info + { + step[0] = m.step[0]; + step[1] = m.step[1]; + } + else + { + CV_DbgAssert(m.step.p != m.step.buf); + step.p = m.step.p; + size.p = m.size.p; + m.step.p = m.step.buf; + m.size.p = &m.rows; + } + m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0; + m.allocator = NULL; + m.u = NULL; + m.offset = 0; +} + +inline +UMat& UMat::operator = (UMat&& m) +{ + if (this == &m) + return *this; + release(); + flags = m.flags; dims = m.dims; rows = m.rows; cols = m.cols; + allocator = m.allocator; usageFlags = m.usageFlags; + u = m.u; + offset = m.offset; + if (step.p != step.buf) // release self step/size + { + fastFree(step.p); + step.p = step.buf; + size.p = &rows; + } + if (m.dims <= 2) // move new step/size info + { + step[0] = m.step[0]; + step[1] = m.step[1]; + } + else + { + CV_DbgAssert(m.step.p != m.step.buf); + step.p = m.step.p; + size.p = m.size.p; + m.step.p = m.step.buf; + m.size.p = &m.rows; + } + m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0; + m.allocator = NULL; + m.u = NULL; + m.offset = 0; + return *this; +} + + +inline bool UMatData::hostCopyObsolete() const { return (flags & HOST_COPY_OBSOLETE) != 0; } +inline bool UMatData::deviceCopyObsolete() const { return (flags & DEVICE_COPY_OBSOLETE) != 0; } +inline bool UMatData::deviceMemMapped() const { return (flags & DEVICE_MEM_MAPPED) != 0; } +inline bool UMatData::copyOnMap() const { return (flags & COPY_ON_MAP) != 0; } +inline bool UMatData::tempUMat() const { return (flags & TEMP_UMAT) != 0; } +inline bool UMatData::tempCopiedUMat() const { return (flags & TEMP_COPIED_UMAT) == TEMP_COPIED_UMAT; } + +inline void UMatData::markDeviceMemMapped(bool flag) +{ + if(flag) + flags |= DEVICE_MEM_MAPPED; + else + flags &= ~DEVICE_MEM_MAPPED; +} + +inline void UMatData::markHostCopyObsolete(bool flag) +{ + if(flag) + flags |= HOST_COPY_OBSOLETE; + else + flags &= ~HOST_COPY_OBSOLETE; +} +inline void UMatData::markDeviceCopyObsolete(bool flag) +{ + if(flag) + flags |= DEVICE_COPY_OBSOLETE; + else + flags &= ~DEVICE_COPY_OBSOLETE; +} + +//! @endcond + +} //cv + +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/matx.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/matx.hpp new file mode 100755 index 0000000..de34da4 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/matx.hpp @@ -0,0 +1,1471 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_MATX_HPP +#define OPENCV_CORE_MATX_HPP + +#ifndef __cplusplus +# error matx.hpp header must be compiled as C++ +#endif + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/base.hpp" +#include "opencv2/core/traits.hpp" +#include "opencv2/core/saturate.hpp" + +#include + +namespace cv +{ + +//! @addtogroup core_basic +//! @{ + +////////////////////////////// Small Matrix /////////////////////////// + +//! @cond IGNORED +// FIXIT Remove this (especially CV_EXPORTS modifier) +struct CV_EXPORTS Matx_AddOp { Matx_AddOp() {} Matx_AddOp(const Matx_AddOp&) {} }; +struct CV_EXPORTS Matx_SubOp { Matx_SubOp() {} Matx_SubOp(const Matx_SubOp&) {} }; +struct CV_EXPORTS Matx_ScaleOp { Matx_ScaleOp() {} Matx_ScaleOp(const Matx_ScaleOp&) {} }; +struct CV_EXPORTS Matx_MulOp { Matx_MulOp() {} Matx_MulOp(const Matx_MulOp&) {} }; +struct CV_EXPORTS Matx_DivOp { Matx_DivOp() {} Matx_DivOp(const Matx_DivOp&) {} }; +struct CV_EXPORTS Matx_MatMulOp { Matx_MatMulOp() {} Matx_MatMulOp(const Matx_MatMulOp&) {} }; +struct CV_EXPORTS Matx_TOp { Matx_TOp() {} Matx_TOp(const Matx_TOp&) {} }; +//! @endcond + +/** @brief Template class for small matrices whose type and size are known at compilation time + +If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the +M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are +available. To do an operation on Matx that is not implemented, you can easily convert the matrix to +Mat and backwards: +@code{.cpp} + Matx33f m(1, 2, 3, + 4, 5, 6, + 7, 8, 9); + cout << sum(Mat(m*m.t())) << endl; +@endcode +Except of the plain constructor which takes a list of elements, Matx can be initialized from a C-array: +@code{.cpp} + float values[] = { 1, 2, 3}; + Matx31f m(values); +@endcode +In case if C++11 features are available, std::initializer_list can be also used to initialize Matx: +@code{.cpp} + Matx31f m = { 1, 2, 3}; +@endcode + */ +template class Matx +{ +public: + enum { + rows = m, + cols = n, + channels = rows*cols, +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + depth = traits::Type<_Tp>::value, + type = CV_MAKETYPE(depth, channels), +#endif + shortdim = (m < n ? m : n) + }; + + typedef _Tp value_type; + typedef Matx<_Tp, m, n> mat_type; + typedef Matx<_Tp, shortdim, 1> diag_type; + + //! default constructor + Matx(); + + explicit Matx(_Tp v0); //!< 1x1 matrix + Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9, _Tp v10, _Tp v11, + _Tp v12, _Tp v13); //!< 1x14, 2x7, 7x2 or 14x1 matrix + Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, + _Tp v4, _Tp v5, _Tp v6, _Tp v7, + _Tp v8, _Tp v9, _Tp v10, _Tp v11, + _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix + explicit Matx(const _Tp* vals); //!< initialize from a plain array + + Matx(std::initializer_list<_Tp>); //!< initialize from an initializer list + + static Matx all(_Tp alpha); + static Matx zeros(); + static Matx ones(); + static Matx eye(); + static Matx diag(const diag_type& d); + static Matx randu(_Tp a, _Tp b); + static Matx randn(_Tp a, _Tp b); + + //! dot product computed with the default precision + _Tp dot(const Matx<_Tp, m, n>& v) const; + + //! dot product computed in double-precision arithmetics + double ddot(const Matx<_Tp, m, n>& v) const; + + //! conversion to another data type + template operator Matx() const; + + //! change the matrix shape + template Matx<_Tp, m1, n1> reshape() const; + + //! extract part of the matrix + template Matx<_Tp, m1, n1> get_minor(int base_row, int base_col) const; + + //! extract the matrix row + Matx<_Tp, 1, n> row(int i) const; + + //! extract the matrix column + Matx<_Tp, m, 1> col(int i) const; + + //! extract the matrix diagonal + diag_type diag() const; + + //! transpose the matrix + Matx<_Tp, n, m> t() const; + + //! invert the matrix + Matx<_Tp, n, m> inv(int method=DECOMP_LU, bool *p_is_ok = NULL) const; + + //! solve linear system + template Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const; + Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const; + + //! multiply two matrices element-wise + Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const; + + //! divide two matrices element-wise + Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const; + + //! element access + const _Tp& operator ()(int row, int col) const; + _Tp& operator ()(int row, int col); + + //! 1D element access + const _Tp& operator ()(int i) const; + _Tp& operator ()(int i); + + Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp); + Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp); + template Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp); + Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp); + Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp); + template Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp); + Matx(const Matx<_Tp, n, m>& a, Matx_TOp); + + _Tp val[m*n]; //< matrix elements +}; + +typedef Matx Matx12f; +typedef Matx Matx12d; +typedef Matx Matx13f; +typedef Matx Matx13d; +typedef Matx Matx14f; +typedef Matx Matx14d; +typedef Matx Matx16f; +typedef Matx Matx16d; + +typedef Matx Matx21f; +typedef Matx Matx21d; +typedef Matx Matx31f; +typedef Matx Matx31d; +typedef Matx Matx41f; +typedef Matx Matx41d; +typedef Matx Matx61f; +typedef Matx Matx61d; + +typedef Matx Matx22f; +typedef Matx Matx22d; +typedef Matx Matx23f; +typedef Matx Matx23d; +typedef Matx Matx32f; +typedef Matx Matx32d; + +typedef Matx Matx33f; +typedef Matx Matx33d; + +typedef Matx Matx34f; +typedef Matx Matx34d; +typedef Matx Matx43f; +typedef Matx Matx43d; + +typedef Matx Matx44f; +typedef Matx Matx44d; +typedef Matx Matx66f; +typedef Matx Matx66d; + +/*! + traits +*/ +template class DataType< Matx<_Tp, m, n> > +{ +public: + typedef Matx<_Tp, m, n> value_type; + typedef Matx::work_type, m, n> work_type; + typedef _Tp channel_type; + typedef value_type vec_type; + + enum { generic_type = 0, + channels = m * n, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; +}; + +namespace traits { +template +struct Depth< Matx<_Tp, m, n> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Matx<_Tp, m, n> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, n*m) }; }; +} // namespace + + +/** @brief Comma-separated Matrix Initializer +*/ +template class MatxCommaInitializer +{ +public: + MatxCommaInitializer(Matx<_Tp, m, n>* _mtx); + template MatxCommaInitializer<_Tp, m, n>& operator , (T2 val); + Matx<_Tp, m, n> operator *() const; + + Matx<_Tp, m, n>* dst; + int idx; +}; + +/* + Utility methods +*/ +template static double determinant(const Matx<_Tp, m, m>& a); +template static double trace(const Matx<_Tp, m, n>& a); +template static double norm(const Matx<_Tp, m, n>& M); +template static double norm(const Matx<_Tp, m, n>& M, int normType); + + + +/////////////////////// Vec (used as element of multi-channel images ///////////////////// + +/** @brief Template class for short numerical vectors, a partial case of Matx + +This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) on which you +can perform basic arithmetical operations, access individual elements using [] operator etc. The +vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., which +elements are dynamically allocated in the heap. + +The template takes 2 parameters: +@tparam _Tp element type +@tparam cn the number of elements + +In addition to the universal notation like Vec, you can use shorter aliases +for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec. + +It is possible to convert Vec\ to/from Point_, Vec\ to/from Point3_ , and Vec\ +to CvScalar or Scalar_. Use operator[] to access the elements of Vec. + +All the expected vector operations are also implemented: +- v1 = v2 + v3 +- v1 = v2 - v3 +- v1 = v2 \* scale +- v1 = scale \* v2 +- v1 = -v2 +- v1 += v2 and other augmenting operations +- v1 == v2, v1 != v2 +- norm(v1) (euclidean norm) +The Vec class is commonly used to describe pixel types of multi-channel arrays. See Mat for details. +*/ +template class Vec : public Matx<_Tp, cn, 1> +{ +public: + typedef _Tp value_type; + enum { + channels = cn, +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + depth = Matx<_Tp, cn, 1>::depth, + type = CV_MAKETYPE(depth, channels), +#endif + _dummy_enum_finalizer = 0 + }; + + //! default constructor + Vec(); + + Vec(_Tp v0); //!< 1-element vector constructor + Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor + Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13); //!< 14-element vector constructor + explicit Vec(const _Tp* values); + + Vec(std::initializer_list<_Tp>); + + Vec(const Vec<_Tp, cn>& v); + + static Vec all(_Tp alpha); + + //! per-element multiplication + Vec mul(const Vec<_Tp, cn>& v) const; + + //! conjugation (makes sense for complex numbers and quaternions) + Vec conj() const; + + /*! + cross product of the two 3D vectors. + + For other dimensionalities the exception is raised + */ + Vec cross(const Vec& v) const; + //! conversion to another data type + template operator Vec() const; + + /*! element access */ + const _Tp& operator [](int i) const; + _Tp& operator[](int i); + const _Tp& operator ()(int i) const; + _Tp& operator ()(int i); + +#ifdef CV_CXX11 + Vec<_Tp, cn>& operator=(const Vec<_Tp, cn>& rhs) = default; +#endif + + Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp); + Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp); + template Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp); +}; + +/** @name Shorter aliases for the most popular specializations of Vec + @{ +*/ +typedef Vec Vec2b; +typedef Vec Vec3b; +typedef Vec Vec4b; + +typedef Vec Vec2s; +typedef Vec Vec3s; +typedef Vec Vec4s; + +typedef Vec Vec2w; +typedef Vec Vec3w; +typedef Vec Vec4w; + +typedef Vec Vec2i; +typedef Vec Vec3i; +typedef Vec Vec4i; +typedef Vec Vec6i; +typedef Vec Vec8i; + +typedef Vec Vec2f; +typedef Vec Vec3f; +typedef Vec Vec4f; +typedef Vec Vec6f; + +typedef Vec Vec2d; +typedef Vec Vec3d; +typedef Vec Vec4d; +typedef Vec Vec6d; +/** @} */ + +/*! + traits +*/ +template class DataType< Vec<_Tp, cn> > +{ +public: + typedef Vec<_Tp, cn> value_type; + typedef Vec::work_type, cn> work_type; + typedef _Tp channel_type; + typedef value_type vec_type; + + enum { generic_type = 0, + channels = cn, + fmt = DataType::fmt + ((channels - 1) << 8), +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + depth = DataType::depth, + type = CV_MAKETYPE(depth, channels), +#endif + _dummy_enum_finalizer = 0 + }; +}; + +namespace traits { +template +struct Depth< Vec<_Tp, cn> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Vec<_Tp, cn> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, cn) }; }; +} // namespace + + +/** @brief Comma-separated Vec Initializer +*/ +template class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> +{ +public: + VecCommaInitializer(Vec<_Tp, m>* _vec); + template VecCommaInitializer<_Tp, m>& operator , (T2 val); + Vec<_Tp, m> operator *() const; +}; + +template static Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v); + +//! @} core_basic + +//! @cond IGNORED + +///////////////////////////////////// helper classes ///////////////////////////////////// +namespace internal +{ + +template struct Matx_DetOp +{ + double operator ()(const Matx<_Tp, m, m>& a) const + { + Matx<_Tp, m, m> temp = a; + double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0); + if( p == 0 ) + return p; + for( int i = 0; i < m; i++ ) + p *= temp(i, i); + return p; + } +}; + +template struct Matx_DetOp<_Tp, 1> +{ + double operator ()(const Matx<_Tp, 1, 1>& a) const + { + return a(0,0); + } +}; + +template struct Matx_DetOp<_Tp, 2> +{ + double operator ()(const Matx<_Tp, 2, 2>& a) const + { + return a(0,0)*a(1,1) - a(0,1)*a(1,0); + } +}; + +template struct Matx_DetOp<_Tp, 3> +{ + double operator ()(const Matx<_Tp, 3, 3>& a) const + { + return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) - + a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) + + a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1)); + } +}; + +template Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v) +{ + return Vec<_Tp, 2>(v[0], -v[1]); +} + +template Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v) +{ + return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]); +} + +} // internal + + + +////////////////////////////////// Matx Implementation /////////////////////////////////// + +template inline +Matx<_Tp, m, n>::Matx() +{ + for(int i = 0; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0) +{ + val[0] = v0; + for(int i = 1; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1) +{ + CV_StaticAssert(channels >= 2, "Matx should have at least 2 elements."); + val[0] = v0; val[1] = v1; + for(int i = 2; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2) +{ + CV_StaticAssert(channels >= 3, "Matx should have at least 3 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; + for(int i = 3; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3) +{ + CV_StaticAssert(channels >= 4, "Matx should have at least 4 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + for(int i = 4; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) +{ + CV_StaticAssert(channels >= 5, "Matx should have at least 5 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4; + for(int i = 5; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) +{ + CV_StaticAssert(channels >= 6, "Matx should have at least 6 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; + for(int i = 6; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) +{ + CV_StaticAssert(channels >= 7, "Matx should have at least 7 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; + for(int i = 7; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) +{ + CV_StaticAssert(channels >= 8, "Matx should have at least 8 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + for(int i = 8; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) +{ + CV_StaticAssert(channels >= 9, "Matx should have at least 9 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; + for(int i = 9; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) +{ + CV_StaticAssert(channels >= 10, "Matx should have at least 10 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; + for(int i = 10; i < channels; i++) val[i] = _Tp(0); +} + + +template inline +Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11) +{ + CV_StaticAssert(channels >= 12, "Matx should have at least 12 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; + for(int i = 12; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) +{ + CV_StaticAssert(channels >= 14, "Matx should have at least 14 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; + val[12] = v12; val[13] = v13; + for (int i = 14; i < channels; i++) val[i] = _Tp(0); +} + + +template inline +Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13, _Tp v14, _Tp v15) +{ + CV_StaticAssert(channels >= 16, "Matx should have at least 16 elements."); + val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; + val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7; + val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11; + val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15; + for(int i = 16; i < channels; i++) val[i] = _Tp(0); +} + +template inline +Matx<_Tp, m, n>::Matx(const _Tp* values) +{ + for( int i = 0; i < channels; i++ ) val[i] = values[i]; +} + +template inline +Matx<_Tp, m, n>::Matx(std::initializer_list<_Tp> list) +{ + CV_DbgAssert(list.size() == channels); + int i = 0; + for(const auto& elem : list) + { + val[i++] = elem; + } +} + +template inline +Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha) +{ + Matx<_Tp, m, n> M; + for( int i = 0; i < m*n; i++ ) M.val[i] = alpha; + return M; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros() +{ + return all(0); +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::ones() +{ + return all(1); +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::eye() +{ + Matx<_Tp,m,n> M; + for(int i = 0; i < shortdim; i++) + M(i,i) = 1; + return M; +} + +template inline +_Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const +{ + _Tp s = 0; + for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i]; + return s; +} + +template inline +double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const +{ + double s = 0; + for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i]; + return s; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d) +{ + Matx<_Tp,m,n> M; + for(int i = 0; i < shortdim; i++) + M(i,i) = d(i, 0); + return M; +} + +template template +inline Matx<_Tp, m, n>::operator Matx() const +{ + Matx M; + for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast(val[i]); + return M; +} + +template template inline +Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const +{ + CV_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements"); + return (const Matx<_Tp, m1, n1>&)*this; +} + +template +template inline +Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int base_row, int base_col) const +{ + CV_DbgAssert(0 <= base_row && base_row+m1 <= m && 0 <= base_col && base_col+n1 <= n); + Matx<_Tp, m1, n1> s; + for( int di = 0; di < m1; di++ ) + for( int dj = 0; dj < n1; dj++ ) + s(di, dj) = (*this)(base_row+di, base_col+dj); + return s; +} + +template inline +Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const +{ + CV_DbgAssert((unsigned)i < (unsigned)m); + return Matx<_Tp, 1, n>(&val[i*n]); +} + +template inline +Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const +{ + CV_DbgAssert((unsigned)j < (unsigned)n); + Matx<_Tp, m, 1> v; + for( int i = 0; i < m; i++ ) + v.val[i] = val[i*n + j]; + return v; +} + +template inline +typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const +{ + diag_type d; + for( int i = 0; i < shortdim; i++ ) + d.val[i] = val[i*n + i]; + return d; +} + +template inline +const _Tp& Matx<_Tp, m, n>::operator()(int row_idx, int col_idx) const +{ + CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n ); + return this->val[row_idx*n + col_idx]; +} + +template inline +_Tp& Matx<_Tp, m, n>::operator ()(int row_idx, int col_idx) +{ + CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n ); + return val[row_idx*n + col_idx]; +} + +template inline +const _Tp& Matx<_Tp, m, n>::operator ()(int i) const +{ + CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); + CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); + return val[i]; +} + +template inline +_Tp& Matx<_Tp, m, n>::operator ()(int i) +{ + CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row"); + CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) ); + return val[i]; +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]); +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]); +} + +template template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] * alpha); +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]); +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp) +{ + for( int i = 0; i < channels; i++ ) + val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]); +} + +template template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp) +{ + for( int i = 0; i < m; i++ ) + for( int j = 0; j < n; j++ ) + { + _Tp s = 0; + for( int k = 0; k < l; k++ ) + s += a(i, k) * b(k, j); + val[i*n + j] = s; + } +} + +template inline +Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp) +{ + for( int i = 0; i < m; i++ ) + for( int j = 0; j < n; j++ ) + val[i*n + j] = a(j, i); +} + +template inline +Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const +{ + return Matx<_Tp, m, n>(*this, a, Matx_MulOp()); +} + +template inline +Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const +{ + return Matx<_Tp, m, n>(*this, a, Matx_DivOp()); +} + +template inline +Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const +{ + return Matx<_Tp, n, m>(*this, Matx_TOp()); +} + +template inline +Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const +{ + Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method); + return (Vec<_Tp, n>&)(x); +} + +template static inline +double determinant(const Matx<_Tp, m, m>& a) +{ + return cv::internal::Matx_DetOp<_Tp, m>()(a); +} + +template static inline +double trace(const Matx<_Tp, m, n>& a) +{ + _Tp s = 0; + for( int i = 0; i < std::min(m, n); i++ ) + s += a(i,i); + return s; +} + +template static inline +double norm(const Matx<_Tp, m, n>& M) +{ + return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n)); +} + +template static inline +double norm(const Matx<_Tp, m, n>& M, int normType) +{ + switch(normType) { + case NORM_INF: + return (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); + case NORM_L1: + return (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); + case NORM_L2SQR: + return (double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n); + default: + case NORM_L2: + return std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n)); + } +} + + + +//////////////////////////////// matx comma initializer ////////////////////////////////// + +template static inline +MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val) +{ + MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx); + return (commaInitializer, val); +} + +template inline +MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx) + : dst(_mtx), idx(0) +{} + +template template inline +MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value) +{ + CV_DbgAssert( idx < m*n ); + dst->val[idx++] = saturate_cast<_Tp>(value); + return *this; +} + +template inline +Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const +{ + CV_DbgAssert( idx == n*m ); + return *dst; +} + + + +/////////////////////////////////// Vec Implementation /////////////////////////////////// + +template inline +Vec<_Tp, cn>::Vec() {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0) + : Matx<_Tp, cn, 1>(v0) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1) + : Matx<_Tp, cn, 1>(v0, v1) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2) + : Matx<_Tp, cn, 1>(v0, v1, v2) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {} + +template inline +Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13) + : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {} + +template inline +Vec<_Tp, cn>::Vec(const _Tp* values) + : Matx<_Tp, cn, 1>(values) {} + +template inline +Vec<_Tp, cn>::Vec(std::initializer_list<_Tp> list) + : Matx<_Tp, cn, 1>(list) {} + +template inline +Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m) + : Matx<_Tp, cn, 1>(m.val) {} + +template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op) + : Matx<_Tp, cn, 1>(a, b, op) {} + +template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op) + : Matx<_Tp, cn, 1>(a, b, op) {} + +template template inline +Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op) + : Matx<_Tp, cn, 1>(a, alpha, op) {} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha) +{ + Vec v; + for( int i = 0; i < cn; i++ ) v.val[i] = alpha; + return v; +} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const +{ + Vec<_Tp, cn> w; + for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]); + return w; +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template<> inline +Vec Vec::conj() const +{ + return cv::internal::conjugate(*this); +} + +template inline +Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const +{ + CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined"); + return Vec<_Tp, cn>(); +} + +template<> inline +Vec Vec::cross(const Vec& v) const +{ + return Vec(this->val[1]*v.val[2] - this->val[2]*v.val[1], + this->val[2]*v.val[0] - this->val[0]*v.val[2], + this->val[0]*v.val[1] - this->val[1]*v.val[0]); +} + +template<> inline +Vec Vec::cross(const Vec& v) const +{ + return Vec(this->val[1]*v.val[2] - this->val[2]*v.val[1], + this->val[2]*v.val[0] - this->val[0]*v.val[2], + this->val[0]*v.val[1] - this->val[1]*v.val[0]); +} + +template template inline +Vec<_Tp, cn>::operator Vec() const +{ + Vec v; + for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast(this->val[i]); + return v; +} + +template inline +const _Tp& Vec<_Tp, cn>::operator [](int i) const +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +_Tp& Vec<_Tp, cn>::operator [](int i) +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +const _Tp& Vec<_Tp, cn>::operator ()(int i) const +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +_Tp& Vec<_Tp, cn>::operator ()(int i) +{ + CV_DbgAssert( (unsigned)i < (unsigned)cn ); + return this->val[i]; +} + +template inline +Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v) +{ + double nv = norm(v); + return v * (nv ? 1./nv : 0.); +} + + + +//////////////////////////////// vec comma initializer ////////////////////////////////// + + +template static inline +VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val) +{ + VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec); + return (commaInitializer, val); +} + +template inline +VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec) + : MatxCommaInitializer<_Tp, cn, 1>(_vec) +{} + +template template inline +VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value) +{ + CV_DbgAssert( this->idx < cn ); + this->dst->val[this->idx++] = saturate_cast<_Tp>(value); + return *this; +} + +template inline +Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const +{ + CV_DbgAssert( this->idx == cn ); + return *this->dst; +} + +//! @endcond + +///////////////////////////// Matx out-of-class operators //////////////////////////////// + +//! @relates cv::Matx +//! @{ + +template static inline +Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); + return a; +} + +template static inline +Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); + return a; +} + +template static inline +Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_AddOp()); +} + +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_SubOp()); +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha) +{ + for( int i = 0; i < m*n; i++ ) + a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha); + return a; +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a) +{ + return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp()); +} + +template static inline +Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b) +{ + return Matx<_Tp, m, n>(a, b, Matx_MatMulOp()); +} + +template static inline +Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b) +{ + Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp()); + return (const Vec<_Tp, m>&)(c); +} + +template static inline +bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + for( int i = 0; i < m*n; i++ ) + if( a.val[i] != b.val[i] ) return false; + return true; +} + +template static inline +bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b) +{ + return !(a == b); +} + +//! @} + +////////////////////////////// Vec out-of-class operators //////////////////////////////// + +//! @relates cv::Vec +//! @{ + +template static inline +Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) +{ + for( int i = 0; i < cn; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]); + return a; +} + +template static inline +Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) +{ + for( int i = 0; i < cn; i++ ) + a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]); + return a; +} + +template static inline +Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) +{ + return Vec<_Tp, cn>(a, b, Matx_AddOp()); +} + +template static inline +Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b) +{ + return Vec<_Tp, cn>(a, b, Matx_SubOp()); +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha) +{ + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*alpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha) +{ + double ialpha = 1./alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha) +{ + float ialpha = 1.f/alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha) +{ + double ialpha = 1./alpha; + for( int i = 0; i < cn; i++ ) + a[i] = saturate_cast<_Tp>(a[i]*ialpha); + return a; +} + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a) +{ + return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha) +{ + return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha) +{ + return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha) +{ + return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp()); +} + +template static inline +Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a) +{ + Vec<_Tp,cn> t; + for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]); + return t; +} + +template inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) +{ + return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]), + saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]), + saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]), + saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0])); +} + +template inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2) +{ + v1 = v1 * v2; + return v1; +} + +//! @} + +} // cv + +#endif // OPENCV_CORE_MATX_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/neon_utils.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/neon_utils.hpp new file mode 100755 index 0000000..573ba99 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/neon_utils.hpp @@ -0,0 +1,128 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HAL_NEON_UTILS_HPP +#define OPENCV_HAL_NEON_UTILS_HPP + +#include "opencv2/core/cvdef.h" + +//! @addtogroup core_utils_neon +//! @{ + +#if CV_NEON + +inline int32x2_t cv_vrnd_s32_f32(float32x2_t v) +{ + static int32x2_t v_sign = vdup_n_s32(1 << 31), + v_05 = vreinterpret_s32_f32(vdup_n_f32(0.5f)); + + int32x2_t v_addition = vorr_s32(v_05, vand_s32(v_sign, vreinterpret_s32_f32(v))); + return vcvt_s32_f32(vadd_f32(v, vreinterpret_f32_s32(v_addition))); +} + +inline int32x4_t cv_vrndq_s32_f32(float32x4_t v) +{ + static int32x4_t v_sign = vdupq_n_s32(1 << 31), + v_05 = vreinterpretq_s32_f32(vdupq_n_f32(0.5f)); + + int32x4_t v_addition = vorrq_s32(v_05, vandq_s32(v_sign, vreinterpretq_s32_f32(v))); + return vcvtq_s32_f32(vaddq_f32(v, vreinterpretq_f32_s32(v_addition))); +} + +inline uint32x2_t cv_vrnd_u32_f32(float32x2_t v) +{ + static float32x2_t v_05 = vdup_n_f32(0.5f); + return vcvt_u32_f32(vadd_f32(v, v_05)); +} + +inline uint32x4_t cv_vrndq_u32_f32(float32x4_t v) +{ + static float32x4_t v_05 = vdupq_n_f32(0.5f); + return vcvtq_u32_f32(vaddq_f32(v, v_05)); +} + +inline float32x4_t cv_vrecpq_f32(float32x4_t val) +{ + float32x4_t reciprocal = vrecpeq_f32(val); + reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal); + reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal); + return reciprocal; +} + +inline float32x2_t cv_vrecp_f32(float32x2_t val) +{ + float32x2_t reciprocal = vrecpe_f32(val); + reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal); + reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal); + return reciprocal; +} + +inline float32x4_t cv_vrsqrtq_f32(float32x4_t val) +{ + float32x4_t e = vrsqrteq_f32(val); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e); + return e; +} + +inline float32x2_t cv_vrsqrt_f32(float32x2_t val) +{ + float32x2_t e = vrsqrte_f32(val); + e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e); + e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e); + return e; +} + +inline float32x4_t cv_vsqrtq_f32(float32x4_t val) +{ + return cv_vrecpq_f32(cv_vrsqrtq_f32(val)); +} + +inline float32x2_t cv_vsqrt_f32(float32x2_t val) +{ + return cv_vrecp_f32(cv_vrsqrt_f32(val)); +} + +#endif + +//! @} + +#endif // OPENCV_HAL_NEON_UTILS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/ocl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/ocl.hpp new file mode 100755 index 0000000..115f5d1 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/ocl.hpp @@ -0,0 +1,710 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_OPENCL_HPP +#define OPENCV_OPENCL_HPP + +#include "opencv2/core.hpp" + +namespace cv { namespace ocl { + +//! @addtogroup core_opencl +//! @{ + +CV_EXPORTS_W bool haveOpenCL(); +CV_EXPORTS_W bool useOpenCL(); +CV_EXPORTS_W bool haveAmdBlas(); +CV_EXPORTS_W bool haveAmdFft(); +CV_EXPORTS_W void setUseOpenCL(bool flag); +CV_EXPORTS_W void finish(); + +CV_EXPORTS bool haveSVM(); + +class CV_EXPORTS Context; +class CV_EXPORTS_W_SIMPLE Device; +class CV_EXPORTS Kernel; +class CV_EXPORTS Program; +class CV_EXPORTS ProgramSource; +class CV_EXPORTS Queue; +class CV_EXPORTS PlatformInfo; +class CV_EXPORTS Image2D; + +class CV_EXPORTS_W_SIMPLE Device +{ +public: + CV_WRAP Device(); + explicit Device(void* d); + Device(const Device& d); + Device& operator = (const Device& d); + CV_WRAP ~Device(); + + void set(void* d); + + enum + { + TYPE_DEFAULT = (1 << 0), + TYPE_CPU = (1 << 1), + TYPE_GPU = (1 << 2), + TYPE_ACCELERATOR = (1 << 3), + TYPE_DGPU = TYPE_GPU + (1 << 16), + TYPE_IGPU = TYPE_GPU + (1 << 17), + TYPE_ALL = 0xFFFFFFFF + }; + + CV_WRAP String name() const; + CV_WRAP String extensions() const; + CV_WRAP bool isExtensionSupported(const String& extensionName) const; + CV_WRAP String version() const; + CV_WRAP String vendorName() const; + CV_WRAP String OpenCL_C_Version() const; + CV_WRAP String OpenCLVersion() const; + CV_WRAP int deviceVersionMajor() const; + CV_WRAP int deviceVersionMinor() const; + CV_WRAP String driverVersion() const; + void* ptr() const; + + CV_WRAP int type() const; + + CV_WRAP int addressBits() const; + CV_WRAP bool available() const; + CV_WRAP bool compilerAvailable() const; + CV_WRAP bool linkerAvailable() const; + + enum + { + FP_DENORM=(1 << 0), + FP_INF_NAN=(1 << 1), + FP_ROUND_TO_NEAREST=(1 << 2), + FP_ROUND_TO_ZERO=(1 << 3), + FP_ROUND_TO_INF=(1 << 4), + FP_FMA=(1 << 5), + FP_SOFT_FLOAT=(1 << 6), + FP_CORRECTLY_ROUNDED_DIVIDE_SQRT=(1 << 7) + }; + CV_WRAP int doubleFPConfig() const; + CV_WRAP int singleFPConfig() const; + CV_WRAP int halfFPConfig() const; + + CV_WRAP bool endianLittle() const; + CV_WRAP bool errorCorrectionSupport() const; + + enum + { + EXEC_KERNEL=(1 << 0), + EXEC_NATIVE_KERNEL=(1 << 1) + }; + CV_WRAP int executionCapabilities() const; + + CV_WRAP size_t globalMemCacheSize() const; + + enum + { + NO_CACHE=0, + READ_ONLY_CACHE=1, + READ_WRITE_CACHE=2 + }; + CV_WRAP int globalMemCacheType() const; + CV_WRAP int globalMemCacheLineSize() const; + CV_WRAP size_t globalMemSize() const; + + CV_WRAP size_t localMemSize() const; + enum + { + NO_LOCAL_MEM=0, + LOCAL_IS_LOCAL=1, + LOCAL_IS_GLOBAL=2 + }; + CV_WRAP int localMemType() const; + CV_WRAP bool hostUnifiedMemory() const; + + CV_WRAP bool imageSupport() const; + + CV_WRAP bool imageFromBufferSupport() const; + uint imagePitchAlignment() const; + uint imageBaseAddressAlignment() const; + + /// deprecated, use isExtensionSupported() method (probably with "cl_khr_subgroups" value) + CV_WRAP bool intelSubgroupsSupport() const; + + CV_WRAP size_t image2DMaxWidth() const; + CV_WRAP size_t image2DMaxHeight() const; + + CV_WRAP size_t image3DMaxWidth() const; + CV_WRAP size_t image3DMaxHeight() const; + CV_WRAP size_t image3DMaxDepth() const; + + CV_WRAP size_t imageMaxBufferSize() const; + CV_WRAP size_t imageMaxArraySize() const; + + enum + { + UNKNOWN_VENDOR=0, + VENDOR_AMD=1, + VENDOR_INTEL=2, + VENDOR_NVIDIA=3 + }; + CV_WRAP int vendorID() const; + // FIXIT + // dev.isAMD() doesn't work for OpenCL CPU devices from AMD OpenCL platform. + // This method should use platform name instead of vendor name. + // After fix restore code in arithm.cpp: ocl_compare() + CV_WRAP inline bool isAMD() const { return vendorID() == VENDOR_AMD; } + CV_WRAP inline bool isIntel() const { return vendorID() == VENDOR_INTEL; } + CV_WRAP inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; } + + CV_WRAP int maxClockFrequency() const; + CV_WRAP int maxComputeUnits() const; + CV_WRAP int maxConstantArgs() const; + CV_WRAP size_t maxConstantBufferSize() const; + + CV_WRAP size_t maxMemAllocSize() const; + CV_WRAP size_t maxParameterSize() const; + + CV_WRAP int maxReadImageArgs() const; + CV_WRAP int maxWriteImageArgs() const; + CV_WRAP int maxSamplers() const; + + CV_WRAP size_t maxWorkGroupSize() const; + CV_WRAP int maxWorkItemDims() const; + void maxWorkItemSizes(size_t*) const; + + CV_WRAP int memBaseAddrAlign() const; + + CV_WRAP int nativeVectorWidthChar() const; + CV_WRAP int nativeVectorWidthShort() const; + CV_WRAP int nativeVectorWidthInt() const; + CV_WRAP int nativeVectorWidthLong() const; + CV_WRAP int nativeVectorWidthFloat() const; + CV_WRAP int nativeVectorWidthDouble() const; + CV_WRAP int nativeVectorWidthHalf() const; + + CV_WRAP int preferredVectorWidthChar() const; + CV_WRAP int preferredVectorWidthShort() const; + CV_WRAP int preferredVectorWidthInt() const; + CV_WRAP int preferredVectorWidthLong() const; + CV_WRAP int preferredVectorWidthFloat() const; + CV_WRAP int preferredVectorWidthDouble() const; + CV_WRAP int preferredVectorWidthHalf() const; + + CV_WRAP size_t printfBufferSize() const; + CV_WRAP size_t profilingTimerResolution() const; + + CV_WRAP static const Device& getDefault(); + +protected: + struct Impl; + Impl* p; +}; + + +class CV_EXPORTS Context +{ +public: + Context(); + explicit Context(int dtype); + ~Context(); + Context(const Context& c); + Context& operator = (const Context& c); + + bool create(); + bool create(int dtype); + size_t ndevices() const; + const Device& device(size_t idx) const; + Program getProg(const ProgramSource& prog, + const String& buildopt, String& errmsg); + void unloadProg(Program& prog); + + static Context& getDefault(bool initialize = true); + void* ptr() const; + + friend void initializeContextFromHandle(Context& ctx, void* platform, void* context, void* device); + + bool useSVM() const; + void setUseSVM(bool enabled); + + struct Impl; + inline Impl* getImpl() const { return (Impl*)p; } +//protected: + Impl* p; +}; + +class CV_EXPORTS Platform +{ +public: + Platform(); + ~Platform(); + Platform(const Platform& p); + Platform& operator = (const Platform& p); + + void* ptr() const; + static Platform& getDefault(); + + friend void initializeContextFromHandle(Context& ctx, void* platform, void* context, void* device); +protected: + struct Impl; + Impl* p; +}; + +/** @brief Attaches OpenCL context to OpenCV +@note + OpenCV will check if available OpenCL platform has platformName name, then assign context to + OpenCV and call `clRetainContext` function. The deviceID device will be used as target device and + new command queue will be created. +@param platformName name of OpenCL platform to attach, this string is used to check if platform is available to OpenCV at runtime +@param platformID ID of platform attached context was created for +@param context OpenCL context to be attached to OpenCV +@param deviceID ID of device, must be created from attached context +*/ +CV_EXPORTS void attachContext(const String& platformName, void* platformID, void* context, void* deviceID); + +/** @brief Convert OpenCL buffer to UMat +@note + OpenCL buffer (cl_mem_buffer) should contain 2D image data, compatible with OpenCV. Memory + content is not copied from `clBuffer` to UMat. Instead, buffer handle assigned to UMat and + `clRetainMemObject` is called. +@param cl_mem_buffer source clBuffer handle +@param step num of bytes in single row +@param rows number of rows +@param cols number of cols +@param type OpenCV type of image +@param dst destination UMat +*/ +CV_EXPORTS void convertFromBuffer(void* cl_mem_buffer, size_t step, int rows, int cols, int type, UMat& dst); + +/** @brief Convert OpenCL image2d_t to UMat +@note + OpenCL `image2d_t` (cl_mem_image), should be compatible with OpenCV UMat formats. Memory content + is copied from image to UMat with `clEnqueueCopyImageToBuffer` function. +@param cl_mem_image source image2d_t handle +@param dst destination UMat +*/ +CV_EXPORTS void convertFromImage(void* cl_mem_image, UMat& dst); + +// TODO Move to internal header +void initializeContextFromHandle(Context& ctx, void* platform, void* context, void* device); + +class CV_EXPORTS Queue +{ +public: + Queue(); + explicit Queue(const Context& c, const Device& d=Device()); + ~Queue(); + Queue(const Queue& q); + Queue& operator = (const Queue& q); + + bool create(const Context& c=Context(), const Device& d=Device()); + void finish(); + void* ptr() const; + static Queue& getDefault(); + + /// @brief Returns OpenCL command queue with enable profiling mode support + const Queue& getProfilingQueue() const; + + struct Impl; friend struct Impl; + inline Impl* getImpl() const { return p; } +protected: + Impl* p; +}; + + +class CV_EXPORTS KernelArg +{ +public: + enum { LOCAL=1, READ_ONLY=2, WRITE_ONLY=4, READ_WRITE=6, CONSTANT=8, PTR_ONLY = 16, NO_SIZE=256 }; + KernelArg(int _flags, UMat* _m, int wscale=1, int iwscale=1, const void* _obj=0, size_t _sz=0); + KernelArg(); + + static KernelArg Local(size_t localMemSize) + { return KernelArg(LOCAL, 0, 1, 1, 0, localMemSize); } + static KernelArg PtrWriteOnly(const UMat& m) + { return KernelArg(PTR_ONLY+WRITE_ONLY, (UMat*)&m); } + static KernelArg PtrReadOnly(const UMat& m) + { return KernelArg(PTR_ONLY+READ_ONLY, (UMat*)&m); } + static KernelArg PtrReadWrite(const UMat& m) + { return KernelArg(PTR_ONLY+READ_WRITE, (UMat*)&m); } + static KernelArg ReadWrite(const UMat& m, int wscale=1, int iwscale=1) + { return KernelArg(READ_WRITE, (UMat*)&m, wscale, iwscale); } + static KernelArg ReadWriteNoSize(const UMat& m, int wscale=1, int iwscale=1) + { return KernelArg(READ_WRITE+NO_SIZE, (UMat*)&m, wscale, iwscale); } + static KernelArg ReadOnly(const UMat& m, int wscale=1, int iwscale=1) + { return KernelArg(READ_ONLY, (UMat*)&m, wscale, iwscale); } + static KernelArg WriteOnly(const UMat& m, int wscale=1, int iwscale=1) + { return KernelArg(WRITE_ONLY, (UMat*)&m, wscale, iwscale); } + static KernelArg ReadOnlyNoSize(const UMat& m, int wscale=1, int iwscale=1) + { return KernelArg(READ_ONLY+NO_SIZE, (UMat*)&m, wscale, iwscale); } + static KernelArg WriteOnlyNoSize(const UMat& m, int wscale=1, int iwscale=1) + { return KernelArg(WRITE_ONLY+NO_SIZE, (UMat*)&m, wscale, iwscale); } + static KernelArg Constant(const Mat& m); + template static KernelArg Constant(const _Tp* arr, size_t n) + { return KernelArg(CONSTANT, 0, 1, 1, (void*)arr, n); } + + int flags; + UMat* m; + const void* obj; + size_t sz; + int wscale, iwscale; +}; + + +class CV_EXPORTS Kernel +{ +public: + Kernel(); + Kernel(const char* kname, const Program& prog); + Kernel(const char* kname, const ProgramSource& prog, + const String& buildopts = String(), String* errmsg=0); + ~Kernel(); + Kernel(const Kernel& k); + Kernel& operator = (const Kernel& k); + + bool empty() const; + bool create(const char* kname, const Program& prog); + bool create(const char* kname, const ProgramSource& prog, + const String& buildopts, String* errmsg=0); + + int set(int i, const void* value, size_t sz); + int set(int i, const Image2D& image2D); + int set(int i, const UMat& m); + int set(int i, const KernelArg& arg); + template int set(int i, const _Tp& value) + { return set(i, &value, sizeof(value)); } + + +protected: + template inline + int set_args_(int i, const _Tp0& a0) { return set(i, a0); } + template inline + int set_args_(int i, const _Tp0& a0, const _Tps&... rest_args) { i = set(i, a0); return set_args_(i, rest_args...); } +public: + /** @brief Setup OpenCL Kernel arguments. + Avoid direct using of set(i, ...) methods. + @code + bool ok = kernel + .args( + srcUMat, dstUMat, + (float)some_float_param + ).run(ndims, globalSize, localSize); + if (!ok) return false; + @endcode + */ + template inline + Kernel& args(const _Tps&... kernel_args) { set_args_(0, kernel_args...); return *this; } + + + /** @brief Run the OpenCL kernel. + @param dims the work problem dimensions. It is the length of globalsize and localsize. It can be either 1, 2 or 3. + @param globalsize work items for each dimension. It is not the final globalsize passed to + OpenCL. Each dimension will be adjusted to the nearest integer divisible by the corresponding + value in localsize. If localsize is NULL, it will still be adjusted depending on dims. The + adjusted values are greater than or equal to the original values. + @param localsize work-group size for each dimension. + @param sync specify whether to wait for OpenCL computation to finish before return. + @param q command queue + */ + bool run(int dims, size_t globalsize[], + size_t localsize[], bool sync, const Queue& q=Queue()); + bool runTask(bool sync, const Queue& q=Queue()); + + /** @brief Similar to synchronized run() call with returning of kernel execution time + * Separate OpenCL command queue may be used (with CL_QUEUE_PROFILING_ENABLE) + * @return Execution time in nanoseconds or negative number on error + */ + int64 runProfiling(int dims, size_t globalsize[], size_t localsize[], const Queue& q=Queue()); + + size_t workGroupSize() const; + size_t preferedWorkGroupSizeMultiple() const; + bool compileWorkGroupSize(size_t wsz[]) const; + size_t localMemSize() const; + + void* ptr() const; + struct Impl; + +protected: + Impl* p; +}; + +class CV_EXPORTS Program +{ +public: + Program(); + Program(const ProgramSource& src, + const String& buildflags, String& errmsg); + Program(const Program& prog); + + Program& operator = (const Program& prog); + ~Program(); + + bool create(const ProgramSource& src, + const String& buildflags, String& errmsg); + + void* ptr() const; + + /** + * @brief Query device-specific program binary. + * + * Returns RAW OpenCL executable binary without additional attachments. + * + * @sa ProgramSource::fromBinary + * + * @param[out] binary output buffer + */ + void getBinary(std::vector& binary) const; + + struct Impl; friend struct Impl; + inline Impl* getImpl() const { return (Impl*)p; } +protected: + Impl* p; +public: +#ifndef OPENCV_REMOVE_DEPRECATED_API + // TODO Remove this + CV_DEPRECATED bool read(const String& buf, const String& buildflags); // removed, use ProgramSource instead + CV_DEPRECATED bool write(String& buf) const; // removed, use getBinary() method instead (RAW OpenCL binary) + CV_DEPRECATED const ProgramSource& source() const; // implementation removed + CV_DEPRECATED String getPrefix() const; // deprecated, implementation replaced + CV_DEPRECATED static String getPrefix(const String& buildflags); // deprecated, implementation replaced +#endif +}; + + +class CV_EXPORTS ProgramSource +{ +public: + typedef uint64 hash_t; // deprecated + + ProgramSource(); + explicit ProgramSource(const String& module, const String& name, const String& codeStr, const String& codeHash); + explicit ProgramSource(const String& prog); // deprecated + explicit ProgramSource(const char* prog); // deprecated + ~ProgramSource(); + ProgramSource(const ProgramSource& prog); + ProgramSource& operator = (const ProgramSource& prog); + + const String& source() const; // deprecated + hash_t hash() const; // deprecated + + + /** @brief Describe OpenCL program binary. + * Do not call clCreateProgramWithBinary() and/or clBuildProgram(). + * + * Caller should guarantee binary buffer lifetime greater than ProgramSource object (and any of its copies). + * + * This kind of binary is not portable between platforms in general - it is specific to OpenCL vendor / device / driver version. + * + * @param module name of program owner module + * @param name unique name of program (module+name is used as key for OpenCL program caching) + * @param binary buffer address. See buffer lifetime requirement in description. + * @param size buffer size + * @param buildOptions additional program-related build options passed to clBuildProgram() + * @return created ProgramSource object + */ + static ProgramSource fromBinary(const String& module, const String& name, + const unsigned char* binary, const size_t size, + const cv::String& buildOptions = cv::String()); + + /** @brief Describe OpenCL program in SPIR format. + * Do not call clCreateProgramWithBinary() and/or clBuildProgram(). + * + * Supports SPIR 1.2 by default (pass '-spir-std=X.Y' in buildOptions to override this behavior) + * + * Caller should guarantee binary buffer lifetime greater than ProgramSource object (and any of its copies). + * + * Programs in this format are portable between OpenCL implementations with 'khr_spir' extension: + * https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/cl_khr_spir.html + * (but they are not portable between different platforms: 32-bit / 64-bit) + * + * Note: these programs can't support vendor specific extensions, like 'cl_intel_subgroups'. + * + * @param module name of program owner module + * @param name unique name of program (module+name is used as key for OpenCL program caching) + * @param binary buffer address. See buffer lifetime requirement in description. + * @param size buffer size + * @param buildOptions additional program-related build options passed to clBuildProgram() + * (these options are added automatically: '-x spir' and '-spir-std=1.2') + * @return created ProgramSource object. + */ + static ProgramSource fromSPIR(const String& module, const String& name, + const unsigned char* binary, const size_t size, + const cv::String& buildOptions = cv::String()); + + //OpenCL 2.1+ only + //static Program fromSPIRV(const String& module, const String& name, + // const unsigned char* binary, const size_t size, + // const cv::String& buildOptions = cv::String()); + + struct Impl; friend struct Impl; + inline Impl* getImpl() const { return (Impl*)p; } +protected: + Impl* p; +}; + +class CV_EXPORTS PlatformInfo +{ +public: + PlatformInfo(); + explicit PlatformInfo(void* id); + ~PlatformInfo(); + + PlatformInfo(const PlatformInfo& i); + PlatformInfo& operator =(const PlatformInfo& i); + + String name() const; + String vendor() const; + String version() const; + int deviceNumber() const; + void getDevice(Device& device, int d) const; + +protected: + struct Impl; + Impl* p; +}; + +CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf); +CV_EXPORTS const char* typeToStr(int t); +CV_EXPORTS const char* memopTypeToStr(int t); +CV_EXPORTS const char* vecopTypeToStr(int t); +CV_EXPORTS const char* getOpenCLErrorString(int errorCode); +CV_EXPORTS String kernelToStr(InputArray _kernel, int ddepth = -1, const char * name = NULL); +CV_EXPORTS void getPlatfomsInfo(std::vector& platform_info); + + +enum OclVectorStrategy +{ + // all matrices have its own vector width + OCL_VECTOR_OWN = 0, + // all matrices have maximal vector width among all matrices + // (useful for cases when matrices have different data types) + OCL_VECTOR_MAX = 1, + + // default strategy + OCL_VECTOR_DEFAULT = OCL_VECTOR_OWN +}; + +CV_EXPORTS int predictOptimalVectorWidth(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(), + InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(), + InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray(), + OclVectorStrategy strat = OCL_VECTOR_DEFAULT); + +CV_EXPORTS int checkOptimalVectorWidth(const int *vectorWidths, + InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(), + InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(), + InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray(), + OclVectorStrategy strat = OCL_VECTOR_DEFAULT); + +// with OCL_VECTOR_MAX strategy +CV_EXPORTS int predictOptimalVectorWidthMax(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(), + InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(), + InputArray src7 = noArray(), InputArray src8 = noArray(), InputArray src9 = noArray()); + +CV_EXPORTS void buildOptionsAddMatrixDescription(String& buildOptions, const String& name, InputArray _m); + +class CV_EXPORTS Image2D +{ +public: + Image2D(); + + /** + @param src UMat object from which to get image properties and data + @param norm flag to enable the use of normalized channel data types + @param alias flag indicating that the image should alias the src UMat. If true, changes to the + image or src will be reflected in both objects. + */ + explicit Image2D(const UMat &src, bool norm = false, bool alias = false); + Image2D(const Image2D & i); + ~Image2D(); + + Image2D & operator = (const Image2D & i); + + /** Indicates if creating an aliased image should succeed. + Depends on the underlying platform and the dimensions of the UMat. + */ + static bool canCreateAlias(const UMat &u); + + /** Indicates if the image format is supported. + */ + static bool isFormatSupported(int depth, int cn, bool norm); + + void* ptr() const; +protected: + struct Impl; + Impl* p; +}; + +class CV_EXPORTS Timer +{ +public: + Timer(const Queue& q); + ~Timer(); + void start(); + void stop(); + + uint64 durationNS() const; //< duration in nanoseconds + +protected: + struct Impl; + Impl* const p; + +private: + Timer(const Timer&); // disabled + Timer& operator=(const Timer&); // disabled +}; + +CV_EXPORTS MatAllocator* getOpenCLAllocator(); + + +#ifdef __OPENCV_BUILD +namespace internal { + +CV_EXPORTS bool isOpenCLForced(); +#define OCL_FORCE_CHECK(condition) (cv::ocl::internal::isOpenCLForced() || (condition)) + +CV_EXPORTS bool isPerformanceCheckBypassed(); +#define OCL_PERFORMANCE_CHECK(condition) (cv::ocl::internal::isPerformanceCheckBypassed() || (condition)) + +CV_EXPORTS bool isCLBuffer(UMat& u); + +} // namespace internal +#endif + +//! @} + +}} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/ocl_genbase.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/ocl_genbase.hpp new file mode 100755 index 0000000..5334cf1 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/ocl_genbase.hpp @@ -0,0 +1,69 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_OPENCL_GENBASE_HPP +#define OPENCV_OPENCL_GENBASE_HPP + +//! @cond IGNORED + +namespace cv { +namespace ocl { + +class ProgramSource; + +namespace internal { + +struct CV_EXPORTS ProgramEntry +{ + const char* module; + const char* name; + const char* programCode; + const char* programHash; + ProgramSource* pProgramSource; + + operator ProgramSource& () const; +}; + +} } } // namespace + +//! @endcond + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/ocl_defs.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/ocl_defs.hpp new file mode 100755 index 0000000..14df750 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/ocl_defs.hpp @@ -0,0 +1,82 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. + +#ifndef OPENCV_CORE_OPENCL_DEFS_HPP +#define OPENCV_CORE_OPENCL_DEFS_HPP + +#include "opencv2/core/utility.hpp" +#include "cvconfig.h" + +namespace cv { namespace ocl { +#ifdef HAVE_OPENCL +/// Call is similar to useOpenCL() but doesn't try to load OpenCL runtime or create OpenCL context +CV_EXPORTS bool isOpenCLActivated(); +#else +static inline bool isOpenCLActivated() { return false; } +#endif +}} // namespace + + +//#define CV_OPENCL_RUN_ASSERT + +#ifdef HAVE_OPENCL + +#ifdef CV_OPENCL_RUN_VERBOSE +#define CV_OCL_RUN_(condition, func, ...) \ + { \ + if (cv::ocl::isOpenCLActivated() && (condition) && func) \ + { \ + printf("%s: OpenCL implementation is running\n", CV_Func); \ + fflush(stdout); \ + CV_IMPL_ADD(CV_IMPL_OCL); \ + return __VA_ARGS__; \ + } \ + else \ + { \ + printf("%s: Plain implementation is running\n", CV_Func); \ + fflush(stdout); \ + } \ + } +#elif defined CV_OPENCL_RUN_ASSERT +#define CV_OCL_RUN_(condition, func, ...) \ + { \ + if (cv::ocl::isOpenCLActivated() && (condition)) \ + { \ + if(func) \ + { \ + CV_IMPL_ADD(CV_IMPL_OCL); \ + } \ + else \ + { \ + CV_Error(cv::Error::StsAssert, #func); \ + } \ + return __VA_ARGS__; \ + } \ + } +#else +#define CV_OCL_RUN_(condition, func, ...) \ +try \ +{ \ + if (cv::ocl::isOpenCLActivated() && (condition) && func) \ + { \ + CV_IMPL_ADD(CV_IMPL_OCL); \ + return __VA_ARGS__; \ + } \ +} \ +catch (const cv::Exception& e) \ +{ \ + CV_UNUSED(e); /* TODO: Add some logging here */ \ +} +#endif + +#else +#define CV_OCL_RUN_(condition, func, ...) +#endif + +#define CV_OCL_RUN(condition, func) CV_OCL_RUN_(condition, func) + +#endif // OPENCV_CORE_OPENCL_DEFS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_info.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_info.hpp new file mode 100755 index 0000000..b5d3739 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_info.hpp @@ -0,0 +1,198 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#include + +#include +#include + +#ifndef DUMP_CONFIG_PROPERTY +#define DUMP_CONFIG_PROPERTY(...) +#endif + +#ifndef DUMP_MESSAGE_STDOUT +#define DUMP_MESSAGE_STDOUT(...) do { std::cout << __VA_ARGS__ << std::endl; } while (false) +#endif + +namespace cv { + +namespace { +static std::string bytesToStringRepr(size_t value) +{ + size_t b = value % 1024; + value /= 1024; + + size_t kb = value % 1024; + value /= 1024; + + size_t mb = value % 1024; + value /= 1024; + + size_t gb = value; + + std::ostringstream stream; + + if (gb > 0) + stream << gb << " GB "; + if (mb > 0) + stream << mb << " MB "; + if (kb > 0) + stream << kb << " KB "; + if (b > 0) + stream << b << " B"; + + std::string s = stream.str(); + if (s[s.size() - 1] == ' ') + s = s.substr(0, s.size() - 1); + return s; +} +} // namespace + +static void dumpOpenCLInformation() +{ + using namespace cv::ocl; + + try + { + if (!haveOpenCL() || !useOpenCL()) + { + DUMP_MESSAGE_STDOUT("OpenCL is disabled"); + DUMP_CONFIG_PROPERTY("cv_ocl", "disabled"); + return; + } + + std::vector platforms; + cv::ocl::getPlatfomsInfo(platforms); + if (platforms.size() > 0) + { + DUMP_MESSAGE_STDOUT("OpenCL Platforms: "); + for (size_t i = 0; i < platforms.size(); i++) + { + const PlatformInfo* platform = &platforms[i]; + DUMP_MESSAGE_STDOUT(" " << platform->name().c_str()); + Device current_device; + for (int j = 0; j < platform->deviceNumber(); j++) + { + platform->getDevice(current_device, j); + const char* deviceTypeStr = current_device.type() == Device::TYPE_CPU + ? ("CPU") : (current_device.type() == Device::TYPE_GPU ? current_device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown"); + DUMP_MESSAGE_STDOUT( " " << deviceTypeStr << ": " << current_device.name().c_str() << " (" << current_device.version().c_str() << ")"); + DUMP_CONFIG_PROPERTY( cv::format("cv_ocl_platform_%d_device_%d", (int)i, (int)j ), + cv::format("(Platform=%s)(Type=%s)(Name=%s)(Version=%s)", + platform->name().c_str(), deviceTypeStr, current_device.name().c_str(), current_device.version().c_str()) ); + } + } + } + else + { + DUMP_MESSAGE_STDOUT("OpenCL is not available"); + DUMP_CONFIG_PROPERTY("cv_ocl", "not available"); + return; + } + + const Device& device = Device::getDefault(); + if (!device.available()) + CV_Error(Error::OpenCLInitError, "OpenCL device is not available"); + + DUMP_MESSAGE_STDOUT("Current OpenCL device: "); + +#if 0 + DUMP_MESSAGE_STDOUT(" Platform = " << device.getPlatform().name()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_platformName", device.getPlatform().name()); +#endif + + const char* deviceTypeStr = device.type() == Device::TYPE_CPU + ? ("CPU") : (device.type() == Device::TYPE_GPU ? device.hostUnifiedMemory() ? "iGPU" : "dGPU" : "unknown"); + DUMP_MESSAGE_STDOUT(" Type = " << deviceTypeStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_deviceType", deviceTypeStr); + + DUMP_MESSAGE_STDOUT(" Name = " << device.name()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_deviceName", device.name()); + + DUMP_MESSAGE_STDOUT(" Version = " << device.version()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_deviceVersion", device.version()); + + DUMP_MESSAGE_STDOUT(" Driver version = " << device.driverVersion()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_driverVersion", device.driverVersion()); + + DUMP_MESSAGE_STDOUT(" Address bits = " << device.addressBits()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_addressBits", device.addressBits()); + + DUMP_MESSAGE_STDOUT(" Compute units = " << device.maxComputeUnits()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_maxComputeUnits", device.maxComputeUnits()); + + DUMP_MESSAGE_STDOUT(" Max work group size = " << device.maxWorkGroupSize()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_maxWorkGroupSize", device.maxWorkGroupSize()); + + std::string localMemorySizeStr = bytesToStringRepr(device.localMemSize()); + DUMP_MESSAGE_STDOUT(" Local memory size = " << localMemorySizeStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_localMemSize", device.localMemSize()); + + std::string maxMemAllocSizeStr = bytesToStringRepr(device.maxMemAllocSize()); + DUMP_MESSAGE_STDOUT(" Max memory allocation size = " << maxMemAllocSizeStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_maxMemAllocSize", device.maxMemAllocSize()); + + const char* doubleSupportStr = device.doubleFPConfig() > 0 ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Double support = " << doubleSupportStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_haveDoubleSupport", device.doubleFPConfig() > 0); + + const char* isUnifiedMemoryStr = device.hostUnifiedMemory() ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Host unified memory = " << isUnifiedMemoryStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_hostUnifiedMemory", device.hostUnifiedMemory()); + + DUMP_MESSAGE_STDOUT(" Device extensions:"); + String extensionsStr = device.extensions(); + size_t pos = 0; + while (pos < extensionsStr.size()) + { + size_t pos2 = extensionsStr.find(' ', pos); + if (pos2 == String::npos) + pos2 = extensionsStr.size(); + if (pos2 > pos) + { + String extensionName = extensionsStr.substr(pos, pos2 - pos); + DUMP_MESSAGE_STDOUT(" " << extensionName); + } + pos = pos2 + 1; + } + DUMP_CONFIG_PROPERTY("cv_ocl_current_extensions", extensionsStr.c_str()); + + const char* haveAmdBlasStr = haveAmdBlas() ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Has AMD Blas = " << haveAmdBlasStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_AmdBlas", haveAmdBlas()); + + const char* haveAmdFftStr = haveAmdFft() ? "Yes" : "No"; + DUMP_MESSAGE_STDOUT(" Has AMD Fft = " << haveAmdFftStr); + DUMP_CONFIG_PROPERTY("cv_ocl_current_AmdFft", haveAmdFft()); + + + DUMP_MESSAGE_STDOUT(" Preferred vector width char = " << device.preferredVectorWidthChar()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthChar", device.preferredVectorWidthChar()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width short = " << device.preferredVectorWidthShort()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthShort", device.preferredVectorWidthShort()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width int = " << device.preferredVectorWidthInt()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthInt", device.preferredVectorWidthInt()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width long = " << device.preferredVectorWidthLong()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthLong", device.preferredVectorWidthLong()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width float = " << device.preferredVectorWidthFloat()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthFloat", device.preferredVectorWidthFloat()); + + DUMP_MESSAGE_STDOUT(" Preferred vector width double = " << device.preferredVectorWidthDouble()); + DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthDouble", device.preferredVectorWidthDouble()); + } + catch (...) + { + DUMP_MESSAGE_STDOUT("Exception. Can't dump OpenCL info"); + DUMP_MESSAGE_STDOUT("OpenCL device not available"); + DUMP_CONFIG_PROPERTY("cv_ocl", "not available"); + } +} +#undef DUMP_MESSAGE_STDOUT +#undef DUMP_CONFIG_PROPERTY + +} // namespace diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_svm.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_svm.hpp new file mode 100755 index 0000000..7453082 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/opencl_svm.hpp @@ -0,0 +1,81 @@ +/* See LICENSE file in the root OpenCV directory */ + +#ifndef OPENCV_CORE_OPENCL_SVM_HPP +#define OPENCV_CORE_OPENCL_SVM_HPP + +// +// Internal usage only (binary compatibility is not guaranteed) +// +#ifndef __OPENCV_BUILD +#error Internal header file +#endif + +#if defined(HAVE_OPENCL) && defined(HAVE_OPENCL_SVM) +#include "runtime/opencl_core.hpp" +#include "runtime/opencl_svm_20.hpp" +#include "runtime/opencl_svm_hsa_extension.hpp" + +namespace cv { namespace ocl { namespace svm { + +struct SVMCapabilities +{ + enum Value + { + SVM_COARSE_GRAIN_BUFFER = (1 << 0), + SVM_FINE_GRAIN_BUFFER = (1 << 1), + SVM_FINE_GRAIN_SYSTEM = (1 << 2), + SVM_ATOMICS = (1 << 3), + }; + int value_; + + SVMCapabilities(int capabilities = 0) : value_(capabilities) { } + operator int() const { return value_; } + + inline bool isNoSVMSupport() const { return value_ == 0; } + inline bool isSupportCoarseGrainBuffer() const { return (value_ & SVM_COARSE_GRAIN_BUFFER) != 0; } + inline bool isSupportFineGrainBuffer() const { return (value_ & SVM_FINE_GRAIN_BUFFER) != 0; } + inline bool isSupportFineGrainSystem() const { return (value_ & SVM_FINE_GRAIN_SYSTEM) != 0; } + inline bool isSupportAtomics() const { return (value_ & SVM_ATOMICS) != 0; } +}; + +CV_EXPORTS const SVMCapabilities getSVMCapabilitites(const ocl::Context& context); + +struct SVMFunctions +{ + clSVMAllocAMD_fn fn_clSVMAlloc; + clSVMFreeAMD_fn fn_clSVMFree; + clSetKernelArgSVMPointerAMD_fn fn_clSetKernelArgSVMPointer; + //clSetKernelExecInfoAMD_fn fn_clSetKernelExecInfo; + //clEnqueueSVMFreeAMD_fn fn_clEnqueueSVMFree; + clEnqueueSVMMemcpyAMD_fn fn_clEnqueueSVMMemcpy; + clEnqueueSVMMemFillAMD_fn fn_clEnqueueSVMMemFill; + clEnqueueSVMMapAMD_fn fn_clEnqueueSVMMap; + clEnqueueSVMUnmapAMD_fn fn_clEnqueueSVMUnmap; + + inline SVMFunctions() + : fn_clSVMAlloc(NULL), fn_clSVMFree(NULL), + fn_clSetKernelArgSVMPointer(NULL), /*fn_clSetKernelExecInfo(NULL),*/ + /*fn_clEnqueueSVMFree(NULL),*/ fn_clEnqueueSVMMemcpy(NULL), fn_clEnqueueSVMMemFill(NULL), + fn_clEnqueueSVMMap(NULL), fn_clEnqueueSVMUnmap(NULL) + { + // nothing + } + + inline bool isValid() const + { + return fn_clSVMAlloc != NULL && fn_clSVMFree && fn_clSetKernelArgSVMPointer && + /*fn_clSetKernelExecInfo && fn_clEnqueueSVMFree &&*/ fn_clEnqueueSVMMemcpy && + fn_clEnqueueSVMMemFill && fn_clEnqueueSVMMap && fn_clEnqueueSVMUnmap; + } +}; + +// We should guarantee that SVMFunctions lifetime is not less than context's lifetime +CV_EXPORTS const SVMFunctions* getSVMFunctions(const ocl::Context& context); + +CV_EXPORTS bool useSVM(UMatUsageFlags usageFlags); + +}}} //namespace cv::ocl::svm +#endif + +#endif // OPENCV_CORE_OPENCL_SVM_HPP +/* End of file. */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp new file mode 100755 index 0000000..65c8493 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp @@ -0,0 +1,714 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDBLAS_HPP +#error "Invalid usage" +#endif + +// generated by parser_clamdblas.py +#define clAmdBlasAddScratchImage clAmdBlasAddScratchImage_ +#define clAmdBlasCaxpy clAmdBlasCaxpy_ +#define clAmdBlasCcopy clAmdBlasCcopy_ +#define clAmdBlasCdotc clAmdBlasCdotc_ +#define clAmdBlasCdotu clAmdBlasCdotu_ +#define clAmdBlasCgbmv clAmdBlasCgbmv_ +#define clAmdBlasCgemm clAmdBlasCgemm_ +#define clAmdBlasCgemmEx clAmdBlasCgemmEx_ +#define clAmdBlasCgemv clAmdBlasCgemv_ +#define clAmdBlasCgemvEx clAmdBlasCgemvEx_ +#define clAmdBlasCgerc clAmdBlasCgerc_ +#define clAmdBlasCgeru clAmdBlasCgeru_ +#define clAmdBlasChbmv clAmdBlasChbmv_ +#define clAmdBlasChemm clAmdBlasChemm_ +#define clAmdBlasChemv clAmdBlasChemv_ +#define clAmdBlasCher clAmdBlasCher_ +#define clAmdBlasCher2 clAmdBlasCher2_ +#define clAmdBlasCher2k clAmdBlasCher2k_ +#define clAmdBlasCherk clAmdBlasCherk_ +#define clAmdBlasChpmv clAmdBlasChpmv_ +#define clAmdBlasChpr clAmdBlasChpr_ +#define clAmdBlasChpr2 clAmdBlasChpr2_ +#define clAmdBlasCrotg clAmdBlasCrotg_ +#define clAmdBlasCscal clAmdBlasCscal_ +#define clAmdBlasCsrot clAmdBlasCsrot_ +#define clAmdBlasCsscal clAmdBlasCsscal_ +#define clAmdBlasCswap clAmdBlasCswap_ +#define clAmdBlasCsymm clAmdBlasCsymm_ +#define clAmdBlasCsyr2k clAmdBlasCsyr2k_ +#define clAmdBlasCsyr2kEx clAmdBlasCsyr2kEx_ +#define clAmdBlasCsyrk clAmdBlasCsyrk_ +#define clAmdBlasCsyrkEx clAmdBlasCsyrkEx_ +#define clAmdBlasCtbmv clAmdBlasCtbmv_ +#define clAmdBlasCtbsv clAmdBlasCtbsv_ +#define clAmdBlasCtpmv clAmdBlasCtpmv_ +#define clAmdBlasCtpsv clAmdBlasCtpsv_ +#define clAmdBlasCtrmm clAmdBlasCtrmm_ +#define clAmdBlasCtrmmEx clAmdBlasCtrmmEx_ +#define clAmdBlasCtrmv clAmdBlasCtrmv_ +#define clAmdBlasCtrsm clAmdBlasCtrsm_ +#define clAmdBlasCtrsmEx clAmdBlasCtrsmEx_ +#define clAmdBlasCtrsv clAmdBlasCtrsv_ +#define clAmdBlasDasum clAmdBlasDasum_ +#define clAmdBlasDaxpy clAmdBlasDaxpy_ +#define clAmdBlasDcopy clAmdBlasDcopy_ +#define clAmdBlasDdot clAmdBlasDdot_ +#define clAmdBlasDgbmv clAmdBlasDgbmv_ +#define clAmdBlasDgemm clAmdBlasDgemm_ +#define clAmdBlasDgemmEx clAmdBlasDgemmEx_ +#define clAmdBlasDgemv clAmdBlasDgemv_ +#define clAmdBlasDgemvEx clAmdBlasDgemvEx_ +#define clAmdBlasDger clAmdBlasDger_ +#define clAmdBlasDnrm2 clAmdBlasDnrm2_ +#define clAmdBlasDrot clAmdBlasDrot_ +#define clAmdBlasDrotg clAmdBlasDrotg_ +#define clAmdBlasDrotm clAmdBlasDrotm_ +#define clAmdBlasDrotmg clAmdBlasDrotmg_ +#define clAmdBlasDsbmv clAmdBlasDsbmv_ +#define clAmdBlasDscal clAmdBlasDscal_ +#define clAmdBlasDspmv clAmdBlasDspmv_ +#define clAmdBlasDspr clAmdBlasDspr_ +#define clAmdBlasDspr2 clAmdBlasDspr2_ +#define clAmdBlasDswap clAmdBlasDswap_ +#define clAmdBlasDsymm clAmdBlasDsymm_ +#define clAmdBlasDsymv clAmdBlasDsymv_ +#define clAmdBlasDsymvEx clAmdBlasDsymvEx_ +#define clAmdBlasDsyr clAmdBlasDsyr_ +#define clAmdBlasDsyr2 clAmdBlasDsyr2_ +#define clAmdBlasDsyr2k clAmdBlasDsyr2k_ +#define clAmdBlasDsyr2kEx clAmdBlasDsyr2kEx_ +#define clAmdBlasDsyrk clAmdBlasDsyrk_ +#define clAmdBlasDsyrkEx clAmdBlasDsyrkEx_ +#define clAmdBlasDtbmv clAmdBlasDtbmv_ +#define clAmdBlasDtbsv clAmdBlasDtbsv_ +#define clAmdBlasDtpmv clAmdBlasDtpmv_ +#define clAmdBlasDtpsv clAmdBlasDtpsv_ +#define clAmdBlasDtrmm clAmdBlasDtrmm_ +#define clAmdBlasDtrmmEx clAmdBlasDtrmmEx_ +#define clAmdBlasDtrmv clAmdBlasDtrmv_ +#define clAmdBlasDtrsm clAmdBlasDtrsm_ +#define clAmdBlasDtrsmEx clAmdBlasDtrsmEx_ +#define clAmdBlasDtrsv clAmdBlasDtrsv_ +#define clAmdBlasDzasum clAmdBlasDzasum_ +#define clAmdBlasDznrm2 clAmdBlasDznrm2_ +#define clAmdBlasGetVersion clAmdBlasGetVersion_ +#define clAmdBlasRemoveScratchImage clAmdBlasRemoveScratchImage_ +#define clAmdBlasSasum clAmdBlasSasum_ +#define clAmdBlasSaxpy clAmdBlasSaxpy_ +#define clAmdBlasScasum clAmdBlasScasum_ +#define clAmdBlasScnrm2 clAmdBlasScnrm2_ +#define clAmdBlasScopy clAmdBlasScopy_ +#define clAmdBlasSdot clAmdBlasSdot_ +#define clAmdBlasSetup clAmdBlasSetup_ +#define clAmdBlasSgbmv clAmdBlasSgbmv_ +#define clAmdBlasSgemm clAmdBlasSgemm_ +#define clAmdBlasSgemmEx clAmdBlasSgemmEx_ +#define clAmdBlasSgemv clAmdBlasSgemv_ +#define clAmdBlasSgemvEx clAmdBlasSgemvEx_ +#define clAmdBlasSger clAmdBlasSger_ +#define clAmdBlasSnrm2 clAmdBlasSnrm2_ +#define clAmdBlasSrot clAmdBlasSrot_ +#define clAmdBlasSrotg clAmdBlasSrotg_ +#define clAmdBlasSrotm clAmdBlasSrotm_ +#define clAmdBlasSrotmg clAmdBlasSrotmg_ +#define clAmdBlasSsbmv clAmdBlasSsbmv_ +#define clAmdBlasSscal clAmdBlasSscal_ +#define clAmdBlasSspmv clAmdBlasSspmv_ +#define clAmdBlasSspr clAmdBlasSspr_ +#define clAmdBlasSspr2 clAmdBlasSspr2_ +#define clAmdBlasSswap clAmdBlasSswap_ +#define clAmdBlasSsymm clAmdBlasSsymm_ +#define clAmdBlasSsymv clAmdBlasSsymv_ +#define clAmdBlasSsymvEx clAmdBlasSsymvEx_ +#define clAmdBlasSsyr clAmdBlasSsyr_ +#define clAmdBlasSsyr2 clAmdBlasSsyr2_ +#define clAmdBlasSsyr2k clAmdBlasSsyr2k_ +#define clAmdBlasSsyr2kEx clAmdBlasSsyr2kEx_ +#define clAmdBlasSsyrk clAmdBlasSsyrk_ +#define clAmdBlasSsyrkEx clAmdBlasSsyrkEx_ +#define clAmdBlasStbmv clAmdBlasStbmv_ +#define clAmdBlasStbsv clAmdBlasStbsv_ +#define clAmdBlasStpmv clAmdBlasStpmv_ +#define clAmdBlasStpsv clAmdBlasStpsv_ +#define clAmdBlasStrmm clAmdBlasStrmm_ +#define clAmdBlasStrmmEx clAmdBlasStrmmEx_ +#define clAmdBlasStrmv clAmdBlasStrmv_ +#define clAmdBlasStrsm clAmdBlasStrsm_ +#define clAmdBlasStrsmEx clAmdBlasStrsmEx_ +#define clAmdBlasStrsv clAmdBlasStrsv_ +#define clAmdBlasTeardown clAmdBlasTeardown_ +#define clAmdBlasZaxpy clAmdBlasZaxpy_ +#define clAmdBlasZcopy clAmdBlasZcopy_ +#define clAmdBlasZdotc clAmdBlasZdotc_ +#define clAmdBlasZdotu clAmdBlasZdotu_ +#define clAmdBlasZdrot clAmdBlasZdrot_ +#define clAmdBlasZdscal clAmdBlasZdscal_ +#define clAmdBlasZgbmv clAmdBlasZgbmv_ +#define clAmdBlasZgemm clAmdBlasZgemm_ +#define clAmdBlasZgemmEx clAmdBlasZgemmEx_ +#define clAmdBlasZgemv clAmdBlasZgemv_ +#define clAmdBlasZgemvEx clAmdBlasZgemvEx_ +#define clAmdBlasZgerc clAmdBlasZgerc_ +#define clAmdBlasZgeru clAmdBlasZgeru_ +#define clAmdBlasZhbmv clAmdBlasZhbmv_ +#define clAmdBlasZhemm clAmdBlasZhemm_ +#define clAmdBlasZhemv clAmdBlasZhemv_ +#define clAmdBlasZher clAmdBlasZher_ +#define clAmdBlasZher2 clAmdBlasZher2_ +#define clAmdBlasZher2k clAmdBlasZher2k_ +#define clAmdBlasZherk clAmdBlasZherk_ +#define clAmdBlasZhpmv clAmdBlasZhpmv_ +#define clAmdBlasZhpr clAmdBlasZhpr_ +#define clAmdBlasZhpr2 clAmdBlasZhpr2_ +#define clAmdBlasZrotg clAmdBlasZrotg_ +#define clAmdBlasZscal clAmdBlasZscal_ +#define clAmdBlasZswap clAmdBlasZswap_ +#define clAmdBlasZsymm clAmdBlasZsymm_ +#define clAmdBlasZsyr2k clAmdBlasZsyr2k_ +#define clAmdBlasZsyr2kEx clAmdBlasZsyr2kEx_ +#define clAmdBlasZsyrk clAmdBlasZsyrk_ +#define clAmdBlasZsyrkEx clAmdBlasZsyrkEx_ +#define clAmdBlasZtbmv clAmdBlasZtbmv_ +#define clAmdBlasZtbsv clAmdBlasZtbsv_ +#define clAmdBlasZtpmv clAmdBlasZtpmv_ +#define clAmdBlasZtpsv clAmdBlasZtpsv_ +#define clAmdBlasZtrmm clAmdBlasZtrmm_ +#define clAmdBlasZtrmmEx clAmdBlasZtrmmEx_ +#define clAmdBlasZtrmv clAmdBlasZtrmv_ +#define clAmdBlasZtrsm clAmdBlasZtrsm_ +#define clAmdBlasZtrsmEx clAmdBlasZtrsmEx_ +#define clAmdBlasZtrsv clAmdBlasZtrsv_ +#define clAmdBlasiCamax clAmdBlasiCamax_ +#define clAmdBlasiDamax clAmdBlasiDamax_ +#define clAmdBlasiSamax clAmdBlasiSamax_ +#define clAmdBlasiZamax clAmdBlasiZamax_ + +#include + +// generated by parser_clamdblas.py +#undef clAmdBlasAddScratchImage +//#define clAmdBlasAddScratchImage clAmdBlasAddScratchImage_pfn +#undef clAmdBlasCaxpy +//#define clAmdBlasCaxpy clAmdBlasCaxpy_pfn +#undef clAmdBlasCcopy +//#define clAmdBlasCcopy clAmdBlasCcopy_pfn +#undef clAmdBlasCdotc +//#define clAmdBlasCdotc clAmdBlasCdotc_pfn +#undef clAmdBlasCdotu +//#define clAmdBlasCdotu clAmdBlasCdotu_pfn +#undef clAmdBlasCgbmv +//#define clAmdBlasCgbmv clAmdBlasCgbmv_pfn +#undef clAmdBlasCgemm +//#define clAmdBlasCgemm clAmdBlasCgemm_pfn +#undef clAmdBlasCgemmEx +#define clAmdBlasCgemmEx clAmdBlasCgemmEx_pfn +#undef clAmdBlasCgemv +//#define clAmdBlasCgemv clAmdBlasCgemv_pfn +#undef clAmdBlasCgemvEx +//#define clAmdBlasCgemvEx clAmdBlasCgemvEx_pfn +#undef clAmdBlasCgerc +//#define clAmdBlasCgerc clAmdBlasCgerc_pfn +#undef clAmdBlasCgeru +//#define clAmdBlasCgeru clAmdBlasCgeru_pfn +#undef clAmdBlasChbmv +//#define clAmdBlasChbmv clAmdBlasChbmv_pfn +#undef clAmdBlasChemm +//#define clAmdBlasChemm clAmdBlasChemm_pfn +#undef clAmdBlasChemv +//#define clAmdBlasChemv clAmdBlasChemv_pfn +#undef clAmdBlasCher +//#define clAmdBlasCher clAmdBlasCher_pfn +#undef clAmdBlasCher2 +//#define clAmdBlasCher2 clAmdBlasCher2_pfn +#undef clAmdBlasCher2k +//#define clAmdBlasCher2k clAmdBlasCher2k_pfn +#undef clAmdBlasCherk +//#define clAmdBlasCherk clAmdBlasCherk_pfn +#undef clAmdBlasChpmv +//#define clAmdBlasChpmv clAmdBlasChpmv_pfn +#undef clAmdBlasChpr +//#define clAmdBlasChpr clAmdBlasChpr_pfn +#undef clAmdBlasChpr2 +//#define clAmdBlasChpr2 clAmdBlasChpr2_pfn +#undef clAmdBlasCrotg +//#define clAmdBlasCrotg clAmdBlasCrotg_pfn +#undef clAmdBlasCscal +//#define clAmdBlasCscal clAmdBlasCscal_pfn +#undef clAmdBlasCsrot +//#define clAmdBlasCsrot clAmdBlasCsrot_pfn +#undef clAmdBlasCsscal +//#define clAmdBlasCsscal clAmdBlasCsscal_pfn +#undef clAmdBlasCswap +//#define clAmdBlasCswap clAmdBlasCswap_pfn +#undef clAmdBlasCsymm +//#define clAmdBlasCsymm clAmdBlasCsymm_pfn +#undef clAmdBlasCsyr2k +//#define clAmdBlasCsyr2k clAmdBlasCsyr2k_pfn +#undef clAmdBlasCsyr2kEx +//#define clAmdBlasCsyr2kEx clAmdBlasCsyr2kEx_pfn +#undef clAmdBlasCsyrk +//#define clAmdBlasCsyrk clAmdBlasCsyrk_pfn +#undef clAmdBlasCsyrkEx +//#define clAmdBlasCsyrkEx clAmdBlasCsyrkEx_pfn +#undef clAmdBlasCtbmv +//#define clAmdBlasCtbmv clAmdBlasCtbmv_pfn +#undef clAmdBlasCtbsv +//#define clAmdBlasCtbsv clAmdBlasCtbsv_pfn +#undef clAmdBlasCtpmv +//#define clAmdBlasCtpmv clAmdBlasCtpmv_pfn +#undef clAmdBlasCtpsv +//#define clAmdBlasCtpsv clAmdBlasCtpsv_pfn +#undef clAmdBlasCtrmm +//#define clAmdBlasCtrmm clAmdBlasCtrmm_pfn +#undef clAmdBlasCtrmmEx +//#define clAmdBlasCtrmmEx clAmdBlasCtrmmEx_pfn +#undef clAmdBlasCtrmv +//#define clAmdBlasCtrmv clAmdBlasCtrmv_pfn +#undef clAmdBlasCtrsm +//#define clAmdBlasCtrsm clAmdBlasCtrsm_pfn +#undef clAmdBlasCtrsmEx +//#define clAmdBlasCtrsmEx clAmdBlasCtrsmEx_pfn +#undef clAmdBlasCtrsv +//#define clAmdBlasCtrsv clAmdBlasCtrsv_pfn +#undef clAmdBlasDasum +//#define clAmdBlasDasum clAmdBlasDasum_pfn +#undef clAmdBlasDaxpy +//#define clAmdBlasDaxpy clAmdBlasDaxpy_pfn +#undef clAmdBlasDcopy +//#define clAmdBlasDcopy clAmdBlasDcopy_pfn +#undef clAmdBlasDdot +//#define clAmdBlasDdot clAmdBlasDdot_pfn +#undef clAmdBlasDgbmv +//#define clAmdBlasDgbmv clAmdBlasDgbmv_pfn +#undef clAmdBlasDgemm +//#define clAmdBlasDgemm clAmdBlasDgemm_pfn +#undef clAmdBlasDgemmEx +#define clAmdBlasDgemmEx clAmdBlasDgemmEx_pfn +#undef clAmdBlasDgemv +//#define clAmdBlasDgemv clAmdBlasDgemv_pfn +#undef clAmdBlasDgemvEx +//#define clAmdBlasDgemvEx clAmdBlasDgemvEx_pfn +#undef clAmdBlasDger +//#define clAmdBlasDger clAmdBlasDger_pfn +#undef clAmdBlasDnrm2 +//#define clAmdBlasDnrm2 clAmdBlasDnrm2_pfn +#undef clAmdBlasDrot +//#define clAmdBlasDrot clAmdBlasDrot_pfn +#undef clAmdBlasDrotg +//#define clAmdBlasDrotg clAmdBlasDrotg_pfn +#undef clAmdBlasDrotm +//#define clAmdBlasDrotm clAmdBlasDrotm_pfn +#undef clAmdBlasDrotmg +//#define clAmdBlasDrotmg clAmdBlasDrotmg_pfn +#undef clAmdBlasDsbmv +//#define clAmdBlasDsbmv clAmdBlasDsbmv_pfn +#undef clAmdBlasDscal +//#define clAmdBlasDscal clAmdBlasDscal_pfn +#undef clAmdBlasDspmv +//#define clAmdBlasDspmv clAmdBlasDspmv_pfn +#undef clAmdBlasDspr +//#define clAmdBlasDspr clAmdBlasDspr_pfn +#undef clAmdBlasDspr2 +//#define clAmdBlasDspr2 clAmdBlasDspr2_pfn +#undef clAmdBlasDswap +//#define clAmdBlasDswap clAmdBlasDswap_pfn +#undef clAmdBlasDsymm +//#define clAmdBlasDsymm clAmdBlasDsymm_pfn +#undef clAmdBlasDsymv +//#define clAmdBlasDsymv clAmdBlasDsymv_pfn +#undef clAmdBlasDsymvEx +//#define clAmdBlasDsymvEx clAmdBlasDsymvEx_pfn +#undef clAmdBlasDsyr +//#define clAmdBlasDsyr clAmdBlasDsyr_pfn +#undef clAmdBlasDsyr2 +//#define clAmdBlasDsyr2 clAmdBlasDsyr2_pfn +#undef clAmdBlasDsyr2k +//#define clAmdBlasDsyr2k clAmdBlasDsyr2k_pfn +#undef clAmdBlasDsyr2kEx +//#define clAmdBlasDsyr2kEx clAmdBlasDsyr2kEx_pfn +#undef clAmdBlasDsyrk +//#define clAmdBlasDsyrk clAmdBlasDsyrk_pfn +#undef clAmdBlasDsyrkEx +//#define clAmdBlasDsyrkEx clAmdBlasDsyrkEx_pfn +#undef clAmdBlasDtbmv +//#define clAmdBlasDtbmv clAmdBlasDtbmv_pfn +#undef clAmdBlasDtbsv +//#define clAmdBlasDtbsv clAmdBlasDtbsv_pfn +#undef clAmdBlasDtpmv +//#define clAmdBlasDtpmv clAmdBlasDtpmv_pfn +#undef clAmdBlasDtpsv +//#define clAmdBlasDtpsv clAmdBlasDtpsv_pfn +#undef clAmdBlasDtrmm +//#define clAmdBlasDtrmm clAmdBlasDtrmm_pfn +#undef clAmdBlasDtrmmEx +//#define clAmdBlasDtrmmEx clAmdBlasDtrmmEx_pfn +#undef clAmdBlasDtrmv +//#define clAmdBlasDtrmv clAmdBlasDtrmv_pfn +#undef clAmdBlasDtrsm +//#define clAmdBlasDtrsm clAmdBlasDtrsm_pfn +#undef clAmdBlasDtrsmEx +//#define clAmdBlasDtrsmEx clAmdBlasDtrsmEx_pfn +#undef clAmdBlasDtrsv +//#define clAmdBlasDtrsv clAmdBlasDtrsv_pfn +#undef clAmdBlasDzasum +//#define clAmdBlasDzasum clAmdBlasDzasum_pfn +#undef clAmdBlasDznrm2 +//#define clAmdBlasDznrm2 clAmdBlasDznrm2_pfn +#undef clAmdBlasGetVersion +//#define clAmdBlasGetVersion clAmdBlasGetVersion_pfn +#undef clAmdBlasRemoveScratchImage +//#define clAmdBlasRemoveScratchImage clAmdBlasRemoveScratchImage_pfn +#undef clAmdBlasSasum +//#define clAmdBlasSasum clAmdBlasSasum_pfn +#undef clAmdBlasSaxpy +//#define clAmdBlasSaxpy clAmdBlasSaxpy_pfn +#undef clAmdBlasScasum +//#define clAmdBlasScasum clAmdBlasScasum_pfn +#undef clAmdBlasScnrm2 +//#define clAmdBlasScnrm2 clAmdBlasScnrm2_pfn +#undef clAmdBlasScopy +//#define clAmdBlasScopy clAmdBlasScopy_pfn +#undef clAmdBlasSdot +//#define clAmdBlasSdot clAmdBlasSdot_pfn +#undef clAmdBlasSetup +#define clAmdBlasSetup clAmdBlasSetup_pfn +#undef clAmdBlasSgbmv +//#define clAmdBlasSgbmv clAmdBlasSgbmv_pfn +#undef clAmdBlasSgemm +//#define clAmdBlasSgemm clAmdBlasSgemm_pfn +#undef clAmdBlasSgemmEx +#define clAmdBlasSgemmEx clAmdBlasSgemmEx_pfn +#undef clAmdBlasSgemv +//#define clAmdBlasSgemv clAmdBlasSgemv_pfn +#undef clAmdBlasSgemvEx +//#define clAmdBlasSgemvEx clAmdBlasSgemvEx_pfn +#undef clAmdBlasSger +//#define clAmdBlasSger clAmdBlasSger_pfn +#undef clAmdBlasSnrm2 +//#define clAmdBlasSnrm2 clAmdBlasSnrm2_pfn +#undef clAmdBlasSrot +//#define clAmdBlasSrot clAmdBlasSrot_pfn +#undef clAmdBlasSrotg +//#define clAmdBlasSrotg clAmdBlasSrotg_pfn +#undef clAmdBlasSrotm +//#define clAmdBlasSrotm clAmdBlasSrotm_pfn +#undef clAmdBlasSrotmg +//#define clAmdBlasSrotmg clAmdBlasSrotmg_pfn +#undef clAmdBlasSsbmv +//#define clAmdBlasSsbmv clAmdBlasSsbmv_pfn +#undef clAmdBlasSscal +//#define clAmdBlasSscal clAmdBlasSscal_pfn +#undef clAmdBlasSspmv +//#define clAmdBlasSspmv clAmdBlasSspmv_pfn +#undef clAmdBlasSspr +//#define clAmdBlasSspr clAmdBlasSspr_pfn +#undef clAmdBlasSspr2 +//#define clAmdBlasSspr2 clAmdBlasSspr2_pfn +#undef clAmdBlasSswap +//#define clAmdBlasSswap clAmdBlasSswap_pfn +#undef clAmdBlasSsymm +//#define clAmdBlasSsymm clAmdBlasSsymm_pfn +#undef clAmdBlasSsymv +//#define clAmdBlasSsymv clAmdBlasSsymv_pfn +#undef clAmdBlasSsymvEx +//#define clAmdBlasSsymvEx clAmdBlasSsymvEx_pfn +#undef clAmdBlasSsyr +//#define clAmdBlasSsyr clAmdBlasSsyr_pfn +#undef clAmdBlasSsyr2 +//#define clAmdBlasSsyr2 clAmdBlasSsyr2_pfn +#undef clAmdBlasSsyr2k +//#define clAmdBlasSsyr2k clAmdBlasSsyr2k_pfn +#undef clAmdBlasSsyr2kEx +//#define clAmdBlasSsyr2kEx clAmdBlasSsyr2kEx_pfn +#undef clAmdBlasSsyrk +//#define clAmdBlasSsyrk clAmdBlasSsyrk_pfn +#undef clAmdBlasSsyrkEx +//#define clAmdBlasSsyrkEx clAmdBlasSsyrkEx_pfn +#undef clAmdBlasStbmv +//#define clAmdBlasStbmv clAmdBlasStbmv_pfn +#undef clAmdBlasStbsv +//#define clAmdBlasStbsv clAmdBlasStbsv_pfn +#undef clAmdBlasStpmv +//#define clAmdBlasStpmv clAmdBlasStpmv_pfn +#undef clAmdBlasStpsv +//#define clAmdBlasStpsv clAmdBlasStpsv_pfn +#undef clAmdBlasStrmm +//#define clAmdBlasStrmm clAmdBlasStrmm_pfn +#undef clAmdBlasStrmmEx +//#define clAmdBlasStrmmEx clAmdBlasStrmmEx_pfn +#undef clAmdBlasStrmv +//#define clAmdBlasStrmv clAmdBlasStrmv_pfn +#undef clAmdBlasStrsm +//#define clAmdBlasStrsm clAmdBlasStrsm_pfn +#undef clAmdBlasStrsmEx +//#define clAmdBlasStrsmEx clAmdBlasStrsmEx_pfn +#undef clAmdBlasStrsv +//#define clAmdBlasStrsv clAmdBlasStrsv_pfn +#undef clAmdBlasTeardown +#define clAmdBlasTeardown clAmdBlasTeardown_pfn +#undef clAmdBlasZaxpy +//#define clAmdBlasZaxpy clAmdBlasZaxpy_pfn +#undef clAmdBlasZcopy +//#define clAmdBlasZcopy clAmdBlasZcopy_pfn +#undef clAmdBlasZdotc +//#define clAmdBlasZdotc clAmdBlasZdotc_pfn +#undef clAmdBlasZdotu +//#define clAmdBlasZdotu clAmdBlasZdotu_pfn +#undef clAmdBlasZdrot +//#define clAmdBlasZdrot clAmdBlasZdrot_pfn +#undef clAmdBlasZdscal +//#define clAmdBlasZdscal clAmdBlasZdscal_pfn +#undef clAmdBlasZgbmv +//#define clAmdBlasZgbmv clAmdBlasZgbmv_pfn +#undef clAmdBlasZgemm +//#define clAmdBlasZgemm clAmdBlasZgemm_pfn +#undef clAmdBlasZgemmEx +#define clAmdBlasZgemmEx clAmdBlasZgemmEx_pfn +#undef clAmdBlasZgemv +//#define clAmdBlasZgemv clAmdBlasZgemv_pfn +#undef clAmdBlasZgemvEx +//#define clAmdBlasZgemvEx clAmdBlasZgemvEx_pfn +#undef clAmdBlasZgerc +//#define clAmdBlasZgerc clAmdBlasZgerc_pfn +#undef clAmdBlasZgeru +//#define clAmdBlasZgeru clAmdBlasZgeru_pfn +#undef clAmdBlasZhbmv +//#define clAmdBlasZhbmv clAmdBlasZhbmv_pfn +#undef clAmdBlasZhemm +//#define clAmdBlasZhemm clAmdBlasZhemm_pfn +#undef clAmdBlasZhemv +//#define clAmdBlasZhemv clAmdBlasZhemv_pfn +#undef clAmdBlasZher +//#define clAmdBlasZher clAmdBlasZher_pfn +#undef clAmdBlasZher2 +//#define clAmdBlasZher2 clAmdBlasZher2_pfn +#undef clAmdBlasZher2k +//#define clAmdBlasZher2k clAmdBlasZher2k_pfn +#undef clAmdBlasZherk +//#define clAmdBlasZherk clAmdBlasZherk_pfn +#undef clAmdBlasZhpmv +//#define clAmdBlasZhpmv clAmdBlasZhpmv_pfn +#undef clAmdBlasZhpr +//#define clAmdBlasZhpr clAmdBlasZhpr_pfn +#undef clAmdBlasZhpr2 +//#define clAmdBlasZhpr2 clAmdBlasZhpr2_pfn +#undef clAmdBlasZrotg +//#define clAmdBlasZrotg clAmdBlasZrotg_pfn +#undef clAmdBlasZscal +//#define clAmdBlasZscal clAmdBlasZscal_pfn +#undef clAmdBlasZswap +//#define clAmdBlasZswap clAmdBlasZswap_pfn +#undef clAmdBlasZsymm +//#define clAmdBlasZsymm clAmdBlasZsymm_pfn +#undef clAmdBlasZsyr2k +//#define clAmdBlasZsyr2k clAmdBlasZsyr2k_pfn +#undef clAmdBlasZsyr2kEx +//#define clAmdBlasZsyr2kEx clAmdBlasZsyr2kEx_pfn +#undef clAmdBlasZsyrk +//#define clAmdBlasZsyrk clAmdBlasZsyrk_pfn +#undef clAmdBlasZsyrkEx +//#define clAmdBlasZsyrkEx clAmdBlasZsyrkEx_pfn +#undef clAmdBlasZtbmv +//#define clAmdBlasZtbmv clAmdBlasZtbmv_pfn +#undef clAmdBlasZtbsv +//#define clAmdBlasZtbsv clAmdBlasZtbsv_pfn +#undef clAmdBlasZtpmv +//#define clAmdBlasZtpmv clAmdBlasZtpmv_pfn +#undef clAmdBlasZtpsv +//#define clAmdBlasZtpsv clAmdBlasZtpsv_pfn +#undef clAmdBlasZtrmm +//#define clAmdBlasZtrmm clAmdBlasZtrmm_pfn +#undef clAmdBlasZtrmmEx +//#define clAmdBlasZtrmmEx clAmdBlasZtrmmEx_pfn +#undef clAmdBlasZtrmv +//#define clAmdBlasZtrmv clAmdBlasZtrmv_pfn +#undef clAmdBlasZtrsm +//#define clAmdBlasZtrsm clAmdBlasZtrsm_pfn +#undef clAmdBlasZtrsmEx +//#define clAmdBlasZtrsmEx clAmdBlasZtrsmEx_pfn +#undef clAmdBlasZtrsv +//#define clAmdBlasZtrsv clAmdBlasZtrsv_pfn +#undef clAmdBlasiCamax +//#define clAmdBlasiCamax clAmdBlasiCamax_pfn +#undef clAmdBlasiDamax +//#define clAmdBlasiDamax clAmdBlasiDamax_pfn +#undef clAmdBlasiSamax +//#define clAmdBlasiSamax clAmdBlasiSamax_pfn +#undef clAmdBlasiZamax +//#define clAmdBlasiZamax clAmdBlasiZamax_pfn + +// generated by parser_clamdblas.py +//extern CL_RUNTIME_EXPORT cl_ulong (*clAmdBlasAddScratchImage)(cl_context context, size_t width, size_t height, clAmdBlasStatus* status); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCaxpy)(size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCdotc)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCdotu)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, FloatComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, FloatComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, FloatComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgerc)(clAmdBlasOrder order, size_t M, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCgeru)(clAmdBlasOrder order, size_t M, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChemm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChemv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, FloatComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, FloatComplex beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCher)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCher2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCher2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCherk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, float alpha, const cl_mem A, size_t offa, size_t lda, float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float2 alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_float2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChpr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasChpr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCrotg)(cl_mem CA, size_t offCA, cl_mem CB, size_t offCB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCscal)(size_t N, cl_float2 alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_float C, cl_float S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsscal)(size_t N, cl_float alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_float2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, FloatComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t lda, FloatComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, FloatComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, FloatComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasCtrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDaxpy)(size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDdot)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_double beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDger)(clAmdBlasOrder order, size_t M, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_double C, cl_double S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrotg)(cl_mem DA, size_t offDA, cl_mem DB, size_t offDB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrotm)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, const cl_mem DPARAM, size_t offDparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDrotmg)(cl_mem DD1, size_t offDD1, cl_mem DD2, size_t offDD2, cl_mem DX1, size_t offDX1, const cl_mem DY1, size_t offDY1, cl_mem DPARAM, size_t offDparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDscal)(size_t N, cl_double alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDspmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_double beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDspr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDspr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsymv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsymvEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_double beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_double beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t lda, cl_double beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_double beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_double alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDtrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDzasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasDznrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasGetVersion)(cl_uint* major, cl_uint* minor, cl_uint* patch); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasRemoveScratchImage)(cl_ulong imageID); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSaxpy)(size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasScasum)(size_t N, cl_mem asum, size_t offAsum, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasScnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasScopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSdot)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSetup)(); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_float beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSger)(clAmdBlasOrder order, size_t M, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSnrm2)(size_t N, cl_mem NRM2, size_t offNRM2, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_float C, cl_float S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrotg)(cl_mem SA, size_t offSA, cl_mem SB, size_t offSB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrotm)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, const cl_mem SPARAM, size_t offSparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSrotmg)(cl_mem SD1, size_t offSD1, cl_mem SD2, size_t offSD2, cl_mem SX1, size_t offSX1, const cl_mem SY1, size_t offSY1, cl_mem SPARAM, size_t offSparam, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSscal)(size_t N, cl_float alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSspmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_float beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSspr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSspr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_float beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsymv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsymvEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, cl_float beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_float alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, cl_float beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t lda, cl_float beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasSsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_float beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, cl_float alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasStrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT void (*clAmdBlasTeardown)(); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZaxpy)(size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZcopy)(size_t N, const cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdotc)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdotu)(size_t N, cl_mem dotProduct, size_t offDP, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdrot)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_double C, cl_double S, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZdscal)(size_t N, cl_double alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgbmv)(clAmdBlasOrder order, clAmdBlasTranspose trans, size_t M, size_t N, size_t KL, size_t KU, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemm)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, DoubleComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemmEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, clAmdBlasTranspose transB, size_t M, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemv)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t lda, const cl_mem x, size_t offx, int incx, DoubleComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgemvEx)(clAmdBlasOrder order, clAmdBlasTranspose transA, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem x, size_t offx, int incx, DoubleComplex beta, cl_mem y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgerc)(clAmdBlasOrder order, size_t M, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZgeru)(clAmdBlasOrder order, size_t M, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, size_t K, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhemm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhemv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, DoubleComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem X, size_t offx, int incx, DoubleComplex beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZher)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZher2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem A, size_t offa, size_t lda, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZher2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZherk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, double alpha, const cl_mem A, size_t offa, size_t lda, double beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double2 alpha, const cl_mem AP, size_t offa, const cl_mem X, size_t offx, int incx, cl_double2 beta, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhpr)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double alpha, const cl_mem X, size_t offx, int incx, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZhpr2)(clAmdBlasOrder order, clAmdBlasUplo uplo, size_t N, cl_double2 alpha, const cl_mem X, size_t offx, int incx, const cl_mem Y, size_t offy, int incy, cl_mem AP, size_t offa, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZrotg)(cl_mem CA, size_t offCA, cl_mem CB, size_t offCB, cl_mem C, size_t offC, cl_mem S, size_t offS, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZscal)(size_t N, cl_double2 alpha, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZswap)(size_t N, cl_mem X, size_t offx, int incx, cl_mem Y, size_t offy, int incy, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsymm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, size_t M, size_t N, cl_double2 alpha, const cl_mem A, size_t offa, size_t lda, const cl_mem B, size_t offb, size_t ldb, cl_double2 beta, cl_mem C, size_t offc, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyr2k)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t lda, const cl_mem B, size_t ldb, DoubleComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyr2kEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transAB, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, const cl_mem B, size_t offB, size_t ldb, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyrk)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t lda, DoubleComplex beta, cl_mem C, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZsyrkEx)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose transA, size_t N, size_t K, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, DoubleComplex beta, cl_mem C, size_t offC, size_t ldc, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtbmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtbsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, size_t K, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtpmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem AP, size_t offa, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtpsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrmm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrmmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrmv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrsm)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t lda, cl_mem B, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrsmEx)(clAmdBlasOrder order, clAmdBlasSide side, clAmdBlasUplo uplo, clAmdBlasTranspose transA, clAmdBlasDiag diag, size_t M, size_t N, DoubleComplex alpha, const cl_mem A, size_t offA, size_t lda, cl_mem B, size_t offB, size_t ldb, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasZtrsv)(clAmdBlasOrder order, clAmdBlasUplo uplo, clAmdBlasTranspose trans, clAmdBlasDiag diag, size_t N, const cl_mem A, size_t offa, size_t lda, cl_mem X, size_t offx, int incx, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiCamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiDamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiSamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); +//extern CL_RUNTIME_EXPORT clAmdBlasStatus (*clAmdBlasiZamax)(size_t N, cl_mem iMax, size_t offiMax, const cl_mem X, size_t offx, int incx, cl_mem scratchBuff, cl_uint numCommandQueues, cl_command_queue* commandQueues, cl_uint numEventsInWaitList, const cl_event* eventWaitList, cl_event* events); diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp new file mode 100755 index 0000000..1457d7e --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp @@ -0,0 +1,142 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDFFT_HPP +#error "Invalid usage" +#endif + +// generated by parser_clamdfft.py +#define clAmdFftBakePlan clAmdFftBakePlan_ +#define clAmdFftCopyPlan clAmdFftCopyPlan_ +#define clAmdFftCreateDefaultPlan clAmdFftCreateDefaultPlan_ +#define clAmdFftDestroyPlan clAmdFftDestroyPlan_ +#define clAmdFftEnqueueTransform clAmdFftEnqueueTransform_ +#define clAmdFftGetLayout clAmdFftGetLayout_ +#define clAmdFftGetPlanBatchSize clAmdFftGetPlanBatchSize_ +#define clAmdFftGetPlanContext clAmdFftGetPlanContext_ +#define clAmdFftGetPlanDim clAmdFftGetPlanDim_ +#define clAmdFftGetPlanDistance clAmdFftGetPlanDistance_ +#define clAmdFftGetPlanInStride clAmdFftGetPlanInStride_ +#define clAmdFftGetPlanLength clAmdFftGetPlanLength_ +#define clAmdFftGetPlanOutStride clAmdFftGetPlanOutStride_ +#define clAmdFftGetPlanPrecision clAmdFftGetPlanPrecision_ +#define clAmdFftGetPlanScale clAmdFftGetPlanScale_ +#define clAmdFftGetPlanTransposeResult clAmdFftGetPlanTransposeResult_ +#define clAmdFftGetResultLocation clAmdFftGetResultLocation_ +#define clAmdFftGetTmpBufSize clAmdFftGetTmpBufSize_ +#define clAmdFftGetVersion clAmdFftGetVersion_ +#define clAmdFftSetLayout clAmdFftSetLayout_ +#define clAmdFftSetPlanBatchSize clAmdFftSetPlanBatchSize_ +#define clAmdFftSetPlanDim clAmdFftSetPlanDim_ +#define clAmdFftSetPlanDistance clAmdFftSetPlanDistance_ +#define clAmdFftSetPlanInStride clAmdFftSetPlanInStride_ +#define clAmdFftSetPlanLength clAmdFftSetPlanLength_ +#define clAmdFftSetPlanOutStride clAmdFftSetPlanOutStride_ +#define clAmdFftSetPlanPrecision clAmdFftSetPlanPrecision_ +#define clAmdFftSetPlanScale clAmdFftSetPlanScale_ +#define clAmdFftSetPlanTransposeResult clAmdFftSetPlanTransposeResult_ +#define clAmdFftSetResultLocation clAmdFftSetResultLocation_ +#define clAmdFftSetup clAmdFftSetup_ +#define clAmdFftTeardown clAmdFftTeardown_ + +#include + +// generated by parser_clamdfft.py +#undef clAmdFftBakePlan +#define clAmdFftBakePlan clAmdFftBakePlan_pfn +#undef clAmdFftCopyPlan +//#define clAmdFftCopyPlan clAmdFftCopyPlan_pfn +#undef clAmdFftCreateDefaultPlan +#define clAmdFftCreateDefaultPlan clAmdFftCreateDefaultPlan_pfn +#undef clAmdFftDestroyPlan +#define clAmdFftDestroyPlan clAmdFftDestroyPlan_pfn +#undef clAmdFftEnqueueTransform +#define clAmdFftEnqueueTransform clAmdFftEnqueueTransform_pfn +#undef clAmdFftGetLayout +//#define clAmdFftGetLayout clAmdFftGetLayout_pfn +#undef clAmdFftGetPlanBatchSize +//#define clAmdFftGetPlanBatchSize clAmdFftGetPlanBatchSize_pfn +#undef clAmdFftGetPlanContext +//#define clAmdFftGetPlanContext clAmdFftGetPlanContext_pfn +#undef clAmdFftGetPlanDim +//#define clAmdFftGetPlanDim clAmdFftGetPlanDim_pfn +#undef clAmdFftGetPlanDistance +//#define clAmdFftGetPlanDistance clAmdFftGetPlanDistance_pfn +#undef clAmdFftGetPlanInStride +//#define clAmdFftGetPlanInStride clAmdFftGetPlanInStride_pfn +#undef clAmdFftGetPlanLength +//#define clAmdFftGetPlanLength clAmdFftGetPlanLength_pfn +#undef clAmdFftGetPlanOutStride +//#define clAmdFftGetPlanOutStride clAmdFftGetPlanOutStride_pfn +#undef clAmdFftGetPlanPrecision +//#define clAmdFftGetPlanPrecision clAmdFftGetPlanPrecision_pfn +#undef clAmdFftGetPlanScale +//#define clAmdFftGetPlanScale clAmdFftGetPlanScale_pfn +#undef clAmdFftGetPlanTransposeResult +//#define clAmdFftGetPlanTransposeResult clAmdFftGetPlanTransposeResult_pfn +#undef clAmdFftGetResultLocation +//#define clAmdFftGetResultLocation clAmdFftGetResultLocation_pfn +#undef clAmdFftGetTmpBufSize +#define clAmdFftGetTmpBufSize clAmdFftGetTmpBufSize_pfn +#undef clAmdFftGetVersion +#define clAmdFftGetVersion clAmdFftGetVersion_pfn +#undef clAmdFftSetLayout +#define clAmdFftSetLayout clAmdFftSetLayout_pfn +#undef clAmdFftSetPlanBatchSize +#define clAmdFftSetPlanBatchSize clAmdFftSetPlanBatchSize_pfn +#undef clAmdFftSetPlanDim +//#define clAmdFftSetPlanDim clAmdFftSetPlanDim_pfn +#undef clAmdFftSetPlanDistance +#define clAmdFftSetPlanDistance clAmdFftSetPlanDistance_pfn +#undef clAmdFftSetPlanInStride +#define clAmdFftSetPlanInStride clAmdFftSetPlanInStride_pfn +#undef clAmdFftSetPlanLength +//#define clAmdFftSetPlanLength clAmdFftSetPlanLength_pfn +#undef clAmdFftSetPlanOutStride +#define clAmdFftSetPlanOutStride clAmdFftSetPlanOutStride_pfn +#undef clAmdFftSetPlanPrecision +#define clAmdFftSetPlanPrecision clAmdFftSetPlanPrecision_pfn +#undef clAmdFftSetPlanScale +#define clAmdFftSetPlanScale clAmdFftSetPlanScale_pfn +#undef clAmdFftSetPlanTransposeResult +//#define clAmdFftSetPlanTransposeResult clAmdFftSetPlanTransposeResult_pfn +#undef clAmdFftSetResultLocation +#define clAmdFftSetResultLocation clAmdFftSetResultLocation_pfn +#undef clAmdFftSetup +#define clAmdFftSetup clAmdFftSetup_pfn +#undef clAmdFftTeardown +#define clAmdFftTeardown clAmdFftTeardown_pfn + +// generated by parser_clamdfft.py +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftBakePlan)(clAmdFftPlanHandle plHandle, cl_uint numQueues, cl_command_queue* commQueueFFT, void (CL_CALLBACK* pfn_notify) (clAmdFftPlanHandle plHandle, void* user_data), void* user_data); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftCopyPlan)(clAmdFftPlanHandle* out_plHandle, cl_context new_context, clAmdFftPlanHandle in_plHandle); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftCreateDefaultPlan)(clAmdFftPlanHandle* plHandle, cl_context context, const clAmdFftDim dim, const size_t* clLengths); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftDestroyPlan)(clAmdFftPlanHandle* plHandle); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftEnqueueTransform)(clAmdFftPlanHandle plHandle, clAmdFftDirection dir, cl_uint numQueuesAndEvents, cl_command_queue* commQueues, cl_uint numWaitEvents, const cl_event* waitEvents, cl_event* outEvents, cl_mem* inputBuffers, cl_mem* outputBuffers, cl_mem tmpBuffer); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetLayout)(const clAmdFftPlanHandle plHandle, clAmdFftLayout* iLayout, clAmdFftLayout* oLayout); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanBatchSize)(const clAmdFftPlanHandle plHandle, size_t* batchSize); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanContext)(const clAmdFftPlanHandle plHandle, cl_context* context); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanDim)(const clAmdFftPlanHandle plHandle, clAmdFftDim* dim, cl_uint* size); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanDistance)(const clAmdFftPlanHandle plHandle, size_t* iDist, size_t* oDist); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanInStride)(const clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanLength)(const clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clLengths); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanOutStride)(const clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanPrecision)(const clAmdFftPlanHandle plHandle, clAmdFftPrecision* precision); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanScale)(const clAmdFftPlanHandle plHandle, clAmdFftDirection dir, cl_float* scale); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetPlanTransposeResult)(const clAmdFftPlanHandle plHandle, clAmdFftResultTransposed* transposed); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetResultLocation)(const clAmdFftPlanHandle plHandle, clAmdFftResultLocation* placeness); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetTmpBufSize)(const clAmdFftPlanHandle plHandle, size_t* buffersize); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftGetVersion)(cl_uint* major, cl_uint* minor, cl_uint* patch); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetLayout)(clAmdFftPlanHandle plHandle, clAmdFftLayout iLayout, clAmdFftLayout oLayout); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanBatchSize)(clAmdFftPlanHandle plHandle, size_t batchSize); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanDim)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanDistance)(clAmdFftPlanHandle plHandle, size_t iDist, size_t oDist); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanInStride)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanLength)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim, const size_t* clLengths); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanOutStride)(clAmdFftPlanHandle plHandle, const clAmdFftDim dim, size_t* clStrides); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanPrecision)(clAmdFftPlanHandle plHandle, clAmdFftPrecision precision); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanScale)(clAmdFftPlanHandle plHandle, clAmdFftDirection dir, cl_float scale); +//extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetPlanTransposeResult)(clAmdFftPlanHandle plHandle, clAmdFftResultTransposed transposed); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetResultLocation)(clAmdFftPlanHandle plHandle, clAmdFftResultLocation placeness); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftSetup)(const clAmdFftSetupData* setupData); +extern CL_RUNTIME_EXPORT clAmdFftStatus (*clAmdFftTeardown)(); diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp new file mode 100755 index 0000000..28618a1 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp @@ -0,0 +1,371 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_CORE_HPP +#error "Invalid usage" +#endif + +// generated by parser_cl.py +#define clBuildProgram clBuildProgram_ +#define clCompileProgram clCompileProgram_ +#define clCreateBuffer clCreateBuffer_ +#define clCreateCommandQueue clCreateCommandQueue_ +#define clCreateContext clCreateContext_ +#define clCreateContextFromType clCreateContextFromType_ +#define clCreateImage clCreateImage_ +#define clCreateImage2D clCreateImage2D_ +#define clCreateImage3D clCreateImage3D_ +#define clCreateKernel clCreateKernel_ +#define clCreateKernelsInProgram clCreateKernelsInProgram_ +#define clCreateProgramWithBinary clCreateProgramWithBinary_ +#define clCreateProgramWithBuiltInKernels clCreateProgramWithBuiltInKernels_ +#define clCreateProgramWithSource clCreateProgramWithSource_ +#define clCreateSampler clCreateSampler_ +#define clCreateSubBuffer clCreateSubBuffer_ +#define clCreateSubDevices clCreateSubDevices_ +#define clCreateUserEvent clCreateUserEvent_ +#define clEnqueueBarrier clEnqueueBarrier_ +#define clEnqueueBarrierWithWaitList clEnqueueBarrierWithWaitList_ +#define clEnqueueCopyBuffer clEnqueueCopyBuffer_ +#define clEnqueueCopyBufferRect clEnqueueCopyBufferRect_ +#define clEnqueueCopyBufferToImage clEnqueueCopyBufferToImage_ +#define clEnqueueCopyImage clEnqueueCopyImage_ +#define clEnqueueCopyImageToBuffer clEnqueueCopyImageToBuffer_ +#define clEnqueueFillBuffer clEnqueueFillBuffer_ +#define clEnqueueFillImage clEnqueueFillImage_ +#define clEnqueueMapBuffer clEnqueueMapBuffer_ +#define clEnqueueMapImage clEnqueueMapImage_ +#define clEnqueueMarker clEnqueueMarker_ +#define clEnqueueMarkerWithWaitList clEnqueueMarkerWithWaitList_ +#define clEnqueueMigrateMemObjects clEnqueueMigrateMemObjects_ +#define clEnqueueNDRangeKernel clEnqueueNDRangeKernel_ +#define clEnqueueNativeKernel clEnqueueNativeKernel_ +#define clEnqueueReadBuffer clEnqueueReadBuffer_ +#define clEnqueueReadBufferRect clEnqueueReadBufferRect_ +#define clEnqueueReadImage clEnqueueReadImage_ +#define clEnqueueTask clEnqueueTask_ +#define clEnqueueUnmapMemObject clEnqueueUnmapMemObject_ +#define clEnqueueWaitForEvents clEnqueueWaitForEvents_ +#define clEnqueueWriteBuffer clEnqueueWriteBuffer_ +#define clEnqueueWriteBufferRect clEnqueueWriteBufferRect_ +#define clEnqueueWriteImage clEnqueueWriteImage_ +#define clFinish clFinish_ +#define clFlush clFlush_ +#define clGetCommandQueueInfo clGetCommandQueueInfo_ +#define clGetContextInfo clGetContextInfo_ +#define clGetDeviceIDs clGetDeviceIDs_ +#define clGetDeviceInfo clGetDeviceInfo_ +#define clGetEventInfo clGetEventInfo_ +#define clGetEventProfilingInfo clGetEventProfilingInfo_ +#define clGetExtensionFunctionAddress clGetExtensionFunctionAddress_ +#define clGetExtensionFunctionAddressForPlatform clGetExtensionFunctionAddressForPlatform_ +#define clGetImageInfo clGetImageInfo_ +#define clGetKernelArgInfo clGetKernelArgInfo_ +#define clGetKernelInfo clGetKernelInfo_ +#define clGetKernelWorkGroupInfo clGetKernelWorkGroupInfo_ +#define clGetMemObjectInfo clGetMemObjectInfo_ +#define clGetPlatformIDs clGetPlatformIDs_ +#define clGetPlatformInfo clGetPlatformInfo_ +#define clGetProgramBuildInfo clGetProgramBuildInfo_ +#define clGetProgramInfo clGetProgramInfo_ +#define clGetSamplerInfo clGetSamplerInfo_ +#define clGetSupportedImageFormats clGetSupportedImageFormats_ +#define clLinkProgram clLinkProgram_ +#define clReleaseCommandQueue clReleaseCommandQueue_ +#define clReleaseContext clReleaseContext_ +#define clReleaseDevice clReleaseDevice_ +#define clReleaseEvent clReleaseEvent_ +#define clReleaseKernel clReleaseKernel_ +#define clReleaseMemObject clReleaseMemObject_ +#define clReleaseProgram clReleaseProgram_ +#define clReleaseSampler clReleaseSampler_ +#define clRetainCommandQueue clRetainCommandQueue_ +#define clRetainContext clRetainContext_ +#define clRetainDevice clRetainDevice_ +#define clRetainEvent clRetainEvent_ +#define clRetainKernel clRetainKernel_ +#define clRetainMemObject clRetainMemObject_ +#define clRetainProgram clRetainProgram_ +#define clRetainSampler clRetainSampler_ +#define clSetEventCallback clSetEventCallback_ +#define clSetKernelArg clSetKernelArg_ +#define clSetMemObjectDestructorCallback clSetMemObjectDestructorCallback_ +#define clSetUserEventStatus clSetUserEventStatus_ +#define clUnloadCompiler clUnloadCompiler_ +#define clUnloadPlatformCompiler clUnloadPlatformCompiler_ +#define clWaitForEvents clWaitForEvents_ + +#if defined __APPLE__ +#define CL_SILENCE_DEPRECATION +#include +#else +#include +#endif + +// generated by parser_cl.py +#undef clBuildProgram +#define clBuildProgram clBuildProgram_pfn +#undef clCompileProgram +#define clCompileProgram clCompileProgram_pfn +#undef clCreateBuffer +#define clCreateBuffer clCreateBuffer_pfn +#undef clCreateCommandQueue +#define clCreateCommandQueue clCreateCommandQueue_pfn +#undef clCreateContext +#define clCreateContext clCreateContext_pfn +#undef clCreateContextFromType +#define clCreateContextFromType clCreateContextFromType_pfn +#undef clCreateImage +#define clCreateImage clCreateImage_pfn +#undef clCreateImage2D +#define clCreateImage2D clCreateImage2D_pfn +#undef clCreateImage3D +#define clCreateImage3D clCreateImage3D_pfn +#undef clCreateKernel +#define clCreateKernel clCreateKernel_pfn +#undef clCreateKernelsInProgram +#define clCreateKernelsInProgram clCreateKernelsInProgram_pfn +#undef clCreateProgramWithBinary +#define clCreateProgramWithBinary clCreateProgramWithBinary_pfn +#undef clCreateProgramWithBuiltInKernels +#define clCreateProgramWithBuiltInKernels clCreateProgramWithBuiltInKernels_pfn +#undef clCreateProgramWithSource +#define clCreateProgramWithSource clCreateProgramWithSource_pfn +#undef clCreateSampler +#define clCreateSampler clCreateSampler_pfn +#undef clCreateSubBuffer +#define clCreateSubBuffer clCreateSubBuffer_pfn +#undef clCreateSubDevices +#define clCreateSubDevices clCreateSubDevices_pfn +#undef clCreateUserEvent +#define clCreateUserEvent clCreateUserEvent_pfn +#undef clEnqueueBarrier +#define clEnqueueBarrier clEnqueueBarrier_pfn +#undef clEnqueueBarrierWithWaitList +#define clEnqueueBarrierWithWaitList clEnqueueBarrierWithWaitList_pfn +#undef clEnqueueCopyBuffer +#define clEnqueueCopyBuffer clEnqueueCopyBuffer_pfn +#undef clEnqueueCopyBufferRect +#define clEnqueueCopyBufferRect clEnqueueCopyBufferRect_pfn +#undef clEnqueueCopyBufferToImage +#define clEnqueueCopyBufferToImage clEnqueueCopyBufferToImage_pfn +#undef clEnqueueCopyImage +#define clEnqueueCopyImage clEnqueueCopyImage_pfn +#undef clEnqueueCopyImageToBuffer +#define clEnqueueCopyImageToBuffer clEnqueueCopyImageToBuffer_pfn +#undef clEnqueueFillBuffer +#define clEnqueueFillBuffer clEnqueueFillBuffer_pfn +#undef clEnqueueFillImage +#define clEnqueueFillImage clEnqueueFillImage_pfn +#undef clEnqueueMapBuffer +#define clEnqueueMapBuffer clEnqueueMapBuffer_pfn +#undef clEnqueueMapImage +#define clEnqueueMapImage clEnqueueMapImage_pfn +#undef clEnqueueMarker +#define clEnqueueMarker clEnqueueMarker_pfn +#undef clEnqueueMarkerWithWaitList +#define clEnqueueMarkerWithWaitList clEnqueueMarkerWithWaitList_pfn +#undef clEnqueueMigrateMemObjects +#define clEnqueueMigrateMemObjects clEnqueueMigrateMemObjects_pfn +#undef clEnqueueNDRangeKernel +#define clEnqueueNDRangeKernel clEnqueueNDRangeKernel_pfn +#undef clEnqueueNativeKernel +#define clEnqueueNativeKernel clEnqueueNativeKernel_pfn +#undef clEnqueueReadBuffer +#define clEnqueueReadBuffer clEnqueueReadBuffer_pfn +#undef clEnqueueReadBufferRect +#define clEnqueueReadBufferRect clEnqueueReadBufferRect_pfn +#undef clEnqueueReadImage +#define clEnqueueReadImage clEnqueueReadImage_pfn +#undef clEnqueueTask +#define clEnqueueTask clEnqueueTask_pfn +#undef clEnqueueUnmapMemObject +#define clEnqueueUnmapMemObject clEnqueueUnmapMemObject_pfn +#undef clEnqueueWaitForEvents +#define clEnqueueWaitForEvents clEnqueueWaitForEvents_pfn +#undef clEnqueueWriteBuffer +#define clEnqueueWriteBuffer clEnqueueWriteBuffer_pfn +#undef clEnqueueWriteBufferRect +#define clEnqueueWriteBufferRect clEnqueueWriteBufferRect_pfn +#undef clEnqueueWriteImage +#define clEnqueueWriteImage clEnqueueWriteImage_pfn +#undef clFinish +#define clFinish clFinish_pfn +#undef clFlush +#define clFlush clFlush_pfn +#undef clGetCommandQueueInfo +#define clGetCommandQueueInfo clGetCommandQueueInfo_pfn +#undef clGetContextInfo +#define clGetContextInfo clGetContextInfo_pfn +#undef clGetDeviceIDs +#define clGetDeviceIDs clGetDeviceIDs_pfn +#undef clGetDeviceInfo +#define clGetDeviceInfo clGetDeviceInfo_pfn +#undef clGetEventInfo +#define clGetEventInfo clGetEventInfo_pfn +#undef clGetEventProfilingInfo +#define clGetEventProfilingInfo clGetEventProfilingInfo_pfn +#undef clGetExtensionFunctionAddress +#define clGetExtensionFunctionAddress clGetExtensionFunctionAddress_pfn +#undef clGetExtensionFunctionAddressForPlatform +#define clGetExtensionFunctionAddressForPlatform clGetExtensionFunctionAddressForPlatform_pfn +#undef clGetImageInfo +#define clGetImageInfo clGetImageInfo_pfn +#undef clGetKernelArgInfo +#define clGetKernelArgInfo clGetKernelArgInfo_pfn +#undef clGetKernelInfo +#define clGetKernelInfo clGetKernelInfo_pfn +#undef clGetKernelWorkGroupInfo +#define clGetKernelWorkGroupInfo clGetKernelWorkGroupInfo_pfn +#undef clGetMemObjectInfo +#define clGetMemObjectInfo clGetMemObjectInfo_pfn +#undef clGetPlatformIDs +#define clGetPlatformIDs clGetPlatformIDs_pfn +#undef clGetPlatformInfo +#define clGetPlatformInfo clGetPlatformInfo_pfn +#undef clGetProgramBuildInfo +#define clGetProgramBuildInfo clGetProgramBuildInfo_pfn +#undef clGetProgramInfo +#define clGetProgramInfo clGetProgramInfo_pfn +#undef clGetSamplerInfo +#define clGetSamplerInfo clGetSamplerInfo_pfn +#undef clGetSupportedImageFormats +#define clGetSupportedImageFormats clGetSupportedImageFormats_pfn +#undef clLinkProgram +#define clLinkProgram clLinkProgram_pfn +#undef clReleaseCommandQueue +#define clReleaseCommandQueue clReleaseCommandQueue_pfn +#undef clReleaseContext +#define clReleaseContext clReleaseContext_pfn +#undef clReleaseDevice +#define clReleaseDevice clReleaseDevice_pfn +#undef clReleaseEvent +#define clReleaseEvent clReleaseEvent_pfn +#undef clReleaseKernel +#define clReleaseKernel clReleaseKernel_pfn +#undef clReleaseMemObject +#define clReleaseMemObject clReleaseMemObject_pfn +#undef clReleaseProgram +#define clReleaseProgram clReleaseProgram_pfn +#undef clReleaseSampler +#define clReleaseSampler clReleaseSampler_pfn +#undef clRetainCommandQueue +#define clRetainCommandQueue clRetainCommandQueue_pfn +#undef clRetainContext +#define clRetainContext clRetainContext_pfn +#undef clRetainDevice +#define clRetainDevice clRetainDevice_pfn +#undef clRetainEvent +#define clRetainEvent clRetainEvent_pfn +#undef clRetainKernel +#define clRetainKernel clRetainKernel_pfn +#undef clRetainMemObject +#define clRetainMemObject clRetainMemObject_pfn +#undef clRetainProgram +#define clRetainProgram clRetainProgram_pfn +#undef clRetainSampler +#define clRetainSampler clRetainSampler_pfn +#undef clSetEventCallback +#define clSetEventCallback clSetEventCallback_pfn +#undef clSetKernelArg +#define clSetKernelArg clSetKernelArg_pfn +#undef clSetMemObjectDestructorCallback +#define clSetMemObjectDestructorCallback clSetMemObjectDestructorCallback_pfn +#undef clSetUserEventStatus +#define clSetUserEventStatus clSetUserEventStatus_pfn +#undef clUnloadCompiler +#define clUnloadCompiler clUnloadCompiler_pfn +#undef clUnloadPlatformCompiler +#define clUnloadPlatformCompiler clUnloadPlatformCompiler_pfn +#undef clWaitForEvents +#define clWaitForEvents clWaitForEvents_pfn + +// generated by parser_cl.py +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clBuildProgram)(cl_program, cl_uint, const cl_device_id*, const char*, void (CL_CALLBACK*) (cl_program, void*), void*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clCompileProgram)(cl_program, cl_uint, const cl_device_id*, const char*, cl_uint, const cl_program*, const char**, void (CL_CALLBACK*) (cl_program, void*), void*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateBuffer)(cl_context, cl_mem_flags, size_t, void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_command_queue (CL_API_CALL*clCreateCommandQueue)(cl_context, cl_device_id, cl_command_queue_properties, cl_int*); +extern CL_RUNTIME_EXPORT cl_context (CL_API_CALL*clCreateContext)(const cl_context_properties*, cl_uint, const cl_device_id*, void (CL_CALLBACK*) (const char*, const void*, size_t, void*), void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_context (CL_API_CALL*clCreateContextFromType)(const cl_context_properties*, cl_device_type, void (CL_CALLBACK*) (const char*, const void*, size_t, void*), void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateImage)(cl_context, cl_mem_flags, const cl_image_format*, const cl_image_desc*, void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateImage2D)(cl_context, cl_mem_flags, const cl_image_format*, size_t, size_t, size_t, void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateImage3D)(cl_context, cl_mem_flags, const cl_image_format*, size_t, size_t, size_t, size_t, size_t, void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_kernel (CL_API_CALL*clCreateKernel)(cl_program, const char*, cl_int*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clCreateKernelsInProgram)(cl_program, cl_uint, cl_kernel*, cl_uint*); +extern CL_RUNTIME_EXPORT cl_program (CL_API_CALL*clCreateProgramWithBinary)(cl_context, cl_uint, const cl_device_id*, const size_t*, const unsigned char**, cl_int*, cl_int*); +extern CL_RUNTIME_EXPORT cl_program (CL_API_CALL*clCreateProgramWithBuiltInKernels)(cl_context, cl_uint, const cl_device_id*, const char*, cl_int*); +extern CL_RUNTIME_EXPORT cl_program (CL_API_CALL*clCreateProgramWithSource)(cl_context, cl_uint, const char**, const size_t*, cl_int*); +extern CL_RUNTIME_EXPORT cl_sampler (CL_API_CALL*clCreateSampler)(cl_context, cl_bool, cl_addressing_mode, cl_filter_mode, cl_int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateSubBuffer)(cl_mem, cl_mem_flags, cl_buffer_create_type, const void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clCreateSubDevices)(cl_device_id, const cl_device_partition_property*, cl_uint, cl_device_id*, cl_uint*); +extern CL_RUNTIME_EXPORT cl_event (CL_API_CALL*clCreateUserEvent)(cl_context, cl_int*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueBarrier)(cl_command_queue); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueBarrierWithWaitList)(cl_command_queue, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueCopyBuffer)(cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueCopyBufferRect)(cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, const size_t*, size_t, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueCopyBufferToImage)(cl_command_queue, cl_mem, cl_mem, size_t, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueCopyImage)(cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueCopyImageToBuffer)(cl_command_queue, cl_mem, cl_mem, const size_t*, const size_t*, size_t, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueFillBuffer)(cl_command_queue, cl_mem, const void*, size_t, size_t, size_t, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueFillImage)(cl_command_queue, cl_mem, const void*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT void* (CL_API_CALL*clEnqueueMapBuffer)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, const cl_event*, cl_event*, cl_int*); +extern CL_RUNTIME_EXPORT void* (CL_API_CALL*clEnqueueMapImage)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, const size_t*, const size_t*, size_t*, size_t*, cl_uint, const cl_event*, cl_event*, cl_int*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueMarker)(cl_command_queue, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueMarkerWithWaitList)(cl_command_queue, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueMigrateMemObjects)(cl_command_queue, cl_uint, const cl_mem*, cl_mem_migration_flags, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueNDRangeKernel)(cl_command_queue, cl_kernel, cl_uint, const size_t*, const size_t*, const size_t*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueNativeKernel)(cl_command_queue, void (CL_CALLBACK*) (void*), void*, size_t, cl_uint, const cl_mem*, const void**, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueReadBuffer)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueReadBufferRect)(cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, const size_t*, size_t, size_t, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueReadImage)(cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, size_t, size_t, void*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueTask)(cl_command_queue, cl_kernel, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueUnmapMemObject)(cl_command_queue, cl_mem, void*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueWaitForEvents)(cl_command_queue, cl_uint, const cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueWriteBuffer)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueWriteBufferRect)(cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, const size_t*, size_t, size_t, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueWriteImage)(cl_command_queue, cl_mem, cl_bool, const size_t*, const size_t*, size_t, size_t, const void*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clFinish)(cl_command_queue); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clFlush)(cl_command_queue); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetCommandQueueInfo)(cl_command_queue, cl_command_queue_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetContextInfo)(cl_context, cl_context_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetDeviceIDs)(cl_platform_id, cl_device_type, cl_uint, cl_device_id*, cl_uint*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetDeviceInfo)(cl_device_id, cl_device_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetEventInfo)(cl_event, cl_event_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetEventProfilingInfo)(cl_event, cl_profiling_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT void* (CL_API_CALL*clGetExtensionFunctionAddress)(const char*); +extern CL_RUNTIME_EXPORT void* (CL_API_CALL*clGetExtensionFunctionAddressForPlatform)(cl_platform_id, const char*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetImageInfo)(cl_mem, cl_image_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetKernelArgInfo)(cl_kernel, cl_uint, cl_kernel_arg_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetKernelInfo)(cl_kernel, cl_kernel_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetKernelWorkGroupInfo)(cl_kernel, cl_device_id, cl_kernel_work_group_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetMemObjectInfo)(cl_mem, cl_mem_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetPlatformIDs)(cl_uint, cl_platform_id*, cl_uint*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetPlatformInfo)(cl_platform_id, cl_platform_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetProgramBuildInfo)(cl_program, cl_device_id, cl_program_build_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetProgramInfo)(cl_program, cl_program_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetSamplerInfo)(cl_sampler, cl_sampler_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetSupportedImageFormats)(cl_context, cl_mem_flags, cl_mem_object_type, cl_uint, cl_image_format*, cl_uint*); +extern CL_RUNTIME_EXPORT cl_program (CL_API_CALL*clLinkProgram)(cl_context, cl_uint, const cl_device_id*, const char*, cl_uint, const cl_program*, void (CL_CALLBACK*) (cl_program, void*), void*, cl_int*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseCommandQueue)(cl_command_queue); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseContext)(cl_context); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseDevice)(cl_device_id); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseEvent)(cl_event); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseKernel)(cl_kernel); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseMemObject)(cl_mem); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseProgram)(cl_program); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clReleaseSampler)(cl_sampler); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainCommandQueue)(cl_command_queue); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainContext)(cl_context); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainDevice)(cl_device_id); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainEvent)(cl_event); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainKernel)(cl_kernel); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainMemObject)(cl_mem); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainProgram)(cl_program); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clRetainSampler)(cl_sampler); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clSetEventCallback)(cl_event, cl_int, void (CL_CALLBACK*) (cl_event, cl_int, void*), void*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clSetKernelArg)(cl_kernel, cl_uint, size_t, const void*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clSetMemObjectDestructorCallback)(cl_mem, void (CL_CALLBACK*) (cl_mem, void*), void*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clSetUserEventStatus)(cl_event, cl_int); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clUnloadCompiler)(); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clUnloadPlatformCompiler)(cl_platform_id); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clWaitForEvents)(cl_uint, const cl_event*); diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp new file mode 100755 index 0000000..216b22b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp @@ -0,0 +1,272 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_WRAPPERS_HPP +#error "Invalid usage" +#endif + +// generated by parser_cl.py +#undef clBuildProgram +#define clBuildProgram clBuildProgram_fn +inline cl_int clBuildProgram(cl_program p0, cl_uint p1, const cl_device_id* p2, const char* p3, void (CL_CALLBACK*p4) (cl_program, void*), void* p5) { return clBuildProgram_pfn(p0, p1, p2, p3, p4, p5); } +#undef clCompileProgram +#define clCompileProgram clCompileProgram_fn +inline cl_int clCompileProgram(cl_program p0, cl_uint p1, const cl_device_id* p2, const char* p3, cl_uint p4, const cl_program* p5, const char** p6, void (CL_CALLBACK*p7) (cl_program, void*), void* p8) { return clCompileProgram_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clCreateBuffer +#define clCreateBuffer clCreateBuffer_fn +inline cl_mem clCreateBuffer(cl_context p0, cl_mem_flags p1, size_t p2, void* p3, cl_int* p4) { return clCreateBuffer_pfn(p0, p1, p2, p3, p4); } +#undef clCreateCommandQueue +#define clCreateCommandQueue clCreateCommandQueue_fn +inline cl_command_queue clCreateCommandQueue(cl_context p0, cl_device_id p1, cl_command_queue_properties p2, cl_int* p3) { return clCreateCommandQueue_pfn(p0, p1, p2, p3); } +#undef clCreateContext +#define clCreateContext clCreateContext_fn +inline cl_context clCreateContext(const cl_context_properties* p0, cl_uint p1, const cl_device_id* p2, void (CL_CALLBACK*p3) (const char*, const void*, size_t, void*), void* p4, cl_int* p5) { return clCreateContext_pfn(p0, p1, p2, p3, p4, p5); } +#undef clCreateContextFromType +#define clCreateContextFromType clCreateContextFromType_fn +inline cl_context clCreateContextFromType(const cl_context_properties* p0, cl_device_type p1, void (CL_CALLBACK*p2) (const char*, const void*, size_t, void*), void* p3, cl_int* p4) { return clCreateContextFromType_pfn(p0, p1, p2, p3, p4); } +#undef clCreateImage +#define clCreateImage clCreateImage_fn +inline cl_mem clCreateImage(cl_context p0, cl_mem_flags p1, const cl_image_format* p2, const cl_image_desc* p3, void* p4, cl_int* p5) { return clCreateImage_pfn(p0, p1, p2, p3, p4, p5); } +#undef clCreateImage2D +#define clCreateImage2D clCreateImage2D_fn +inline cl_mem clCreateImage2D(cl_context p0, cl_mem_flags p1, const cl_image_format* p2, size_t p3, size_t p4, size_t p5, void* p6, cl_int* p7) { return clCreateImage2D_pfn(p0, p1, p2, p3, p4, p5, p6, p7); } +#undef clCreateImage3D +#define clCreateImage3D clCreateImage3D_fn +inline cl_mem clCreateImage3D(cl_context p0, cl_mem_flags p1, const cl_image_format* p2, size_t p3, size_t p4, size_t p5, size_t p6, size_t p7, void* p8, cl_int* p9) { return clCreateImage3D_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); } +#undef clCreateKernel +#define clCreateKernel clCreateKernel_fn +inline cl_kernel clCreateKernel(cl_program p0, const char* p1, cl_int* p2) { return clCreateKernel_pfn(p0, p1, p2); } +#undef clCreateKernelsInProgram +#define clCreateKernelsInProgram clCreateKernelsInProgram_fn +inline cl_int clCreateKernelsInProgram(cl_program p0, cl_uint p1, cl_kernel* p2, cl_uint* p3) { return clCreateKernelsInProgram_pfn(p0, p1, p2, p3); } +#undef clCreateProgramWithBinary +#define clCreateProgramWithBinary clCreateProgramWithBinary_fn +inline cl_program clCreateProgramWithBinary(cl_context p0, cl_uint p1, const cl_device_id* p2, const size_t* p3, const unsigned char** p4, cl_int* p5, cl_int* p6) { return clCreateProgramWithBinary_pfn(p0, p1, p2, p3, p4, p5, p6); } +#undef clCreateProgramWithBuiltInKernels +#define clCreateProgramWithBuiltInKernels clCreateProgramWithBuiltInKernels_fn +inline cl_program clCreateProgramWithBuiltInKernels(cl_context p0, cl_uint p1, const cl_device_id* p2, const char* p3, cl_int* p4) { return clCreateProgramWithBuiltInKernels_pfn(p0, p1, p2, p3, p4); } +#undef clCreateProgramWithSource +#define clCreateProgramWithSource clCreateProgramWithSource_fn +inline cl_program clCreateProgramWithSource(cl_context p0, cl_uint p1, const char** p2, const size_t* p3, cl_int* p4) { return clCreateProgramWithSource_pfn(p0, p1, p2, p3, p4); } +#undef clCreateSampler +#define clCreateSampler clCreateSampler_fn +inline cl_sampler clCreateSampler(cl_context p0, cl_bool p1, cl_addressing_mode p2, cl_filter_mode p3, cl_int* p4) { return clCreateSampler_pfn(p0, p1, p2, p3, p4); } +#undef clCreateSubBuffer +#define clCreateSubBuffer clCreateSubBuffer_fn +inline cl_mem clCreateSubBuffer(cl_mem p0, cl_mem_flags p1, cl_buffer_create_type p2, const void* p3, cl_int* p4) { return clCreateSubBuffer_pfn(p0, p1, p2, p3, p4); } +#undef clCreateSubDevices +#define clCreateSubDevices clCreateSubDevices_fn +inline cl_int clCreateSubDevices(cl_device_id p0, const cl_device_partition_property* p1, cl_uint p2, cl_device_id* p3, cl_uint* p4) { return clCreateSubDevices_pfn(p0, p1, p2, p3, p4); } +#undef clCreateUserEvent +#define clCreateUserEvent clCreateUserEvent_fn +inline cl_event clCreateUserEvent(cl_context p0, cl_int* p1) { return clCreateUserEvent_pfn(p0, p1); } +#undef clEnqueueBarrier +#define clEnqueueBarrier clEnqueueBarrier_fn +inline cl_int clEnqueueBarrier(cl_command_queue p0) { return clEnqueueBarrier_pfn(p0); } +#undef clEnqueueBarrierWithWaitList +#define clEnqueueBarrierWithWaitList clEnqueueBarrierWithWaitList_fn +inline cl_int clEnqueueBarrierWithWaitList(cl_command_queue p0, cl_uint p1, const cl_event* p2, cl_event* p3) { return clEnqueueBarrierWithWaitList_pfn(p0, p1, p2, p3); } +#undef clEnqueueCopyBuffer +#define clEnqueueCopyBuffer clEnqueueCopyBuffer_fn +inline cl_int clEnqueueCopyBuffer(cl_command_queue p0, cl_mem p1, cl_mem p2, size_t p3, size_t p4, size_t p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueCopyBuffer_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueCopyBufferRect +#define clEnqueueCopyBufferRect clEnqueueCopyBufferRect_fn +inline cl_int clEnqueueCopyBufferRect(cl_command_queue p0, cl_mem p1, cl_mem p2, const size_t* p3, const size_t* p4, const size_t* p5, size_t p6, size_t p7, size_t p8, size_t p9, cl_uint p10, const cl_event* p11, cl_event* p12) { return clEnqueueCopyBufferRect_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } +#undef clEnqueueCopyBufferToImage +#define clEnqueueCopyBufferToImage clEnqueueCopyBufferToImage_fn +inline cl_int clEnqueueCopyBufferToImage(cl_command_queue p0, cl_mem p1, cl_mem p2, size_t p3, const size_t* p4, const size_t* p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueCopyBufferToImage_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueCopyImage +#define clEnqueueCopyImage clEnqueueCopyImage_fn +inline cl_int clEnqueueCopyImage(cl_command_queue p0, cl_mem p1, cl_mem p2, const size_t* p3, const size_t* p4, const size_t* p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueCopyImage_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueCopyImageToBuffer +#define clEnqueueCopyImageToBuffer clEnqueueCopyImageToBuffer_fn +inline cl_int clEnqueueCopyImageToBuffer(cl_command_queue p0, cl_mem p1, cl_mem p2, const size_t* p3, const size_t* p4, size_t p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueCopyImageToBuffer_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueFillBuffer +#define clEnqueueFillBuffer clEnqueueFillBuffer_fn +inline cl_int clEnqueueFillBuffer(cl_command_queue p0, cl_mem p1, const void* p2, size_t p3, size_t p4, size_t p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueFillBuffer_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueFillImage +#define clEnqueueFillImage clEnqueueFillImage_fn +inline cl_int clEnqueueFillImage(cl_command_queue p0, cl_mem p1, const void* p2, const size_t* p3, const size_t* p4, cl_uint p5, const cl_event* p6, cl_event* p7) { return clEnqueueFillImage_pfn(p0, p1, p2, p3, p4, p5, p6, p7); } +#undef clEnqueueMapBuffer +#define clEnqueueMapBuffer clEnqueueMapBuffer_fn +inline void* clEnqueueMapBuffer(cl_command_queue p0, cl_mem p1, cl_bool p2, cl_map_flags p3, size_t p4, size_t p5, cl_uint p6, const cl_event* p7, cl_event* p8, cl_int* p9) { return clEnqueueMapBuffer_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); } +#undef clEnqueueMapImage +#define clEnqueueMapImage clEnqueueMapImage_fn +inline void* clEnqueueMapImage(cl_command_queue p0, cl_mem p1, cl_bool p2, cl_map_flags p3, const size_t* p4, const size_t* p5, size_t* p6, size_t* p7, cl_uint p8, const cl_event* p9, cl_event* p10, cl_int* p11) { return clEnqueueMapImage_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } +#undef clEnqueueMarker +#define clEnqueueMarker clEnqueueMarker_fn +inline cl_int clEnqueueMarker(cl_command_queue p0, cl_event* p1) { return clEnqueueMarker_pfn(p0, p1); } +#undef clEnqueueMarkerWithWaitList +#define clEnqueueMarkerWithWaitList clEnqueueMarkerWithWaitList_fn +inline cl_int clEnqueueMarkerWithWaitList(cl_command_queue p0, cl_uint p1, const cl_event* p2, cl_event* p3) { return clEnqueueMarkerWithWaitList_pfn(p0, p1, p2, p3); } +#undef clEnqueueMigrateMemObjects +#define clEnqueueMigrateMemObjects clEnqueueMigrateMemObjects_fn +inline cl_int clEnqueueMigrateMemObjects(cl_command_queue p0, cl_uint p1, const cl_mem* p2, cl_mem_migration_flags p3, cl_uint p4, const cl_event* p5, cl_event* p6) { return clEnqueueMigrateMemObjects_pfn(p0, p1, p2, p3, p4, p5, p6); } +#undef clEnqueueNDRangeKernel +#define clEnqueueNDRangeKernel clEnqueueNDRangeKernel_fn +inline cl_int clEnqueueNDRangeKernel(cl_command_queue p0, cl_kernel p1, cl_uint p2, const size_t* p3, const size_t* p4, const size_t* p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueNDRangeKernel_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueNativeKernel +#define clEnqueueNativeKernel clEnqueueNativeKernel_fn +inline cl_int clEnqueueNativeKernel(cl_command_queue p0, void (CL_CALLBACK*p1) (void*), void* p2, size_t p3, cl_uint p4, const cl_mem* p5, const void** p6, cl_uint p7, const cl_event* p8, cl_event* p9) { return clEnqueueNativeKernel_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); } +#undef clEnqueueReadBuffer +#define clEnqueueReadBuffer clEnqueueReadBuffer_fn +inline cl_int clEnqueueReadBuffer(cl_command_queue p0, cl_mem p1, cl_bool p2, size_t p3, size_t p4, void* p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueReadBuffer_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueReadBufferRect +#define clEnqueueReadBufferRect clEnqueueReadBufferRect_fn +inline cl_int clEnqueueReadBufferRect(cl_command_queue p0, cl_mem p1, cl_bool p2, const size_t* p3, const size_t* p4, const size_t* p5, size_t p6, size_t p7, size_t p8, size_t p9, void* p10, cl_uint p11, const cl_event* p12, cl_event* p13) { return clEnqueueReadBufferRect_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } +#undef clEnqueueReadImage +#define clEnqueueReadImage clEnqueueReadImage_fn +inline cl_int clEnqueueReadImage(cl_command_queue p0, cl_mem p1, cl_bool p2, const size_t* p3, const size_t* p4, size_t p5, size_t p6, void* p7, cl_uint p8, const cl_event* p9, cl_event* p10) { return clEnqueueReadImage_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } +#undef clEnqueueTask +#define clEnqueueTask clEnqueueTask_fn +inline cl_int clEnqueueTask(cl_command_queue p0, cl_kernel p1, cl_uint p2, const cl_event* p3, cl_event* p4) { return clEnqueueTask_pfn(p0, p1, p2, p3, p4); } +#undef clEnqueueUnmapMemObject +#define clEnqueueUnmapMemObject clEnqueueUnmapMemObject_fn +inline cl_int clEnqueueUnmapMemObject(cl_command_queue p0, cl_mem p1, void* p2, cl_uint p3, const cl_event* p4, cl_event* p5) { return clEnqueueUnmapMemObject_pfn(p0, p1, p2, p3, p4, p5); } +#undef clEnqueueWaitForEvents +#define clEnqueueWaitForEvents clEnqueueWaitForEvents_fn +inline cl_int clEnqueueWaitForEvents(cl_command_queue p0, cl_uint p1, const cl_event* p2) { return clEnqueueWaitForEvents_pfn(p0, p1, p2); } +#undef clEnqueueWriteBuffer +#define clEnqueueWriteBuffer clEnqueueWriteBuffer_fn +inline cl_int clEnqueueWriteBuffer(cl_command_queue p0, cl_mem p1, cl_bool p2, size_t p3, size_t p4, const void* p5, cl_uint p6, const cl_event* p7, cl_event* p8) { return clEnqueueWriteBuffer_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clEnqueueWriteBufferRect +#define clEnqueueWriteBufferRect clEnqueueWriteBufferRect_fn +inline cl_int clEnqueueWriteBufferRect(cl_command_queue p0, cl_mem p1, cl_bool p2, const size_t* p3, const size_t* p4, const size_t* p5, size_t p6, size_t p7, size_t p8, size_t p9, const void* p10, cl_uint p11, const cl_event* p12, cl_event* p13) { return clEnqueueWriteBufferRect_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } +#undef clEnqueueWriteImage +#define clEnqueueWriteImage clEnqueueWriteImage_fn +inline cl_int clEnqueueWriteImage(cl_command_queue p0, cl_mem p1, cl_bool p2, const size_t* p3, const size_t* p4, size_t p5, size_t p6, const void* p7, cl_uint p8, const cl_event* p9, cl_event* p10) { return clEnqueueWriteImage_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } +#undef clFinish +#define clFinish clFinish_fn +inline cl_int clFinish(cl_command_queue p0) { return clFinish_pfn(p0); } +#undef clFlush +#define clFlush clFlush_fn +inline cl_int clFlush(cl_command_queue p0) { return clFlush_pfn(p0); } +#undef clGetCommandQueueInfo +#define clGetCommandQueueInfo clGetCommandQueueInfo_fn +inline cl_int clGetCommandQueueInfo(cl_command_queue p0, cl_command_queue_info p1, size_t p2, void* p3, size_t* p4) { return clGetCommandQueueInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetContextInfo +#define clGetContextInfo clGetContextInfo_fn +inline cl_int clGetContextInfo(cl_context p0, cl_context_info p1, size_t p2, void* p3, size_t* p4) { return clGetContextInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetDeviceIDs +#define clGetDeviceIDs clGetDeviceIDs_fn +inline cl_int clGetDeviceIDs(cl_platform_id p0, cl_device_type p1, cl_uint p2, cl_device_id* p3, cl_uint* p4) { return clGetDeviceIDs_pfn(p0, p1, p2, p3, p4); } +#undef clGetDeviceInfo +#define clGetDeviceInfo clGetDeviceInfo_fn +inline cl_int clGetDeviceInfo(cl_device_id p0, cl_device_info p1, size_t p2, void* p3, size_t* p4) { return clGetDeviceInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetEventInfo +#define clGetEventInfo clGetEventInfo_fn +inline cl_int clGetEventInfo(cl_event p0, cl_event_info p1, size_t p2, void* p3, size_t* p4) { return clGetEventInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetEventProfilingInfo +#define clGetEventProfilingInfo clGetEventProfilingInfo_fn +inline cl_int clGetEventProfilingInfo(cl_event p0, cl_profiling_info p1, size_t p2, void* p3, size_t* p4) { return clGetEventProfilingInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetExtensionFunctionAddress +#define clGetExtensionFunctionAddress clGetExtensionFunctionAddress_fn +inline void* clGetExtensionFunctionAddress(const char* p0) { return clGetExtensionFunctionAddress_pfn(p0); } +#undef clGetExtensionFunctionAddressForPlatform +#define clGetExtensionFunctionAddressForPlatform clGetExtensionFunctionAddressForPlatform_fn +inline void* clGetExtensionFunctionAddressForPlatform(cl_platform_id p0, const char* p1) { return clGetExtensionFunctionAddressForPlatform_pfn(p0, p1); } +#undef clGetImageInfo +#define clGetImageInfo clGetImageInfo_fn +inline cl_int clGetImageInfo(cl_mem p0, cl_image_info p1, size_t p2, void* p3, size_t* p4) { return clGetImageInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetKernelArgInfo +#define clGetKernelArgInfo clGetKernelArgInfo_fn +inline cl_int clGetKernelArgInfo(cl_kernel p0, cl_uint p1, cl_kernel_arg_info p2, size_t p3, void* p4, size_t* p5) { return clGetKernelArgInfo_pfn(p0, p1, p2, p3, p4, p5); } +#undef clGetKernelInfo +#define clGetKernelInfo clGetKernelInfo_fn +inline cl_int clGetKernelInfo(cl_kernel p0, cl_kernel_info p1, size_t p2, void* p3, size_t* p4) { return clGetKernelInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetKernelWorkGroupInfo +#define clGetKernelWorkGroupInfo clGetKernelWorkGroupInfo_fn +inline cl_int clGetKernelWorkGroupInfo(cl_kernel p0, cl_device_id p1, cl_kernel_work_group_info p2, size_t p3, void* p4, size_t* p5) { return clGetKernelWorkGroupInfo_pfn(p0, p1, p2, p3, p4, p5); } +#undef clGetMemObjectInfo +#define clGetMemObjectInfo clGetMemObjectInfo_fn +inline cl_int clGetMemObjectInfo(cl_mem p0, cl_mem_info p1, size_t p2, void* p3, size_t* p4) { return clGetMemObjectInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetPlatformIDs +#define clGetPlatformIDs clGetPlatformIDs_fn +inline cl_int clGetPlatformIDs(cl_uint p0, cl_platform_id* p1, cl_uint* p2) { return clGetPlatformIDs_pfn(p0, p1, p2); } +#undef clGetPlatformInfo +#define clGetPlatformInfo clGetPlatformInfo_fn +inline cl_int clGetPlatformInfo(cl_platform_id p0, cl_platform_info p1, size_t p2, void* p3, size_t* p4) { return clGetPlatformInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetProgramBuildInfo +#define clGetProgramBuildInfo clGetProgramBuildInfo_fn +inline cl_int clGetProgramBuildInfo(cl_program p0, cl_device_id p1, cl_program_build_info p2, size_t p3, void* p4, size_t* p5) { return clGetProgramBuildInfo_pfn(p0, p1, p2, p3, p4, p5); } +#undef clGetProgramInfo +#define clGetProgramInfo clGetProgramInfo_fn +inline cl_int clGetProgramInfo(cl_program p0, cl_program_info p1, size_t p2, void* p3, size_t* p4) { return clGetProgramInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetSamplerInfo +#define clGetSamplerInfo clGetSamplerInfo_fn +inline cl_int clGetSamplerInfo(cl_sampler p0, cl_sampler_info p1, size_t p2, void* p3, size_t* p4) { return clGetSamplerInfo_pfn(p0, p1, p2, p3, p4); } +#undef clGetSupportedImageFormats +#define clGetSupportedImageFormats clGetSupportedImageFormats_fn +inline cl_int clGetSupportedImageFormats(cl_context p0, cl_mem_flags p1, cl_mem_object_type p2, cl_uint p3, cl_image_format* p4, cl_uint* p5) { return clGetSupportedImageFormats_pfn(p0, p1, p2, p3, p4, p5); } +#undef clLinkProgram +#define clLinkProgram clLinkProgram_fn +inline cl_program clLinkProgram(cl_context p0, cl_uint p1, const cl_device_id* p2, const char* p3, cl_uint p4, const cl_program* p5, void (CL_CALLBACK*p6) (cl_program, void*), void* p7, cl_int* p8) { return clLinkProgram_pfn(p0, p1, p2, p3, p4, p5, p6, p7, p8); } +#undef clReleaseCommandQueue +#define clReleaseCommandQueue clReleaseCommandQueue_fn +inline cl_int clReleaseCommandQueue(cl_command_queue p0) { return clReleaseCommandQueue_pfn(p0); } +#undef clReleaseContext +#define clReleaseContext clReleaseContext_fn +inline cl_int clReleaseContext(cl_context p0) { return clReleaseContext_pfn(p0); } +#undef clReleaseDevice +#define clReleaseDevice clReleaseDevice_fn +inline cl_int clReleaseDevice(cl_device_id p0) { return clReleaseDevice_pfn(p0); } +#undef clReleaseEvent +#define clReleaseEvent clReleaseEvent_fn +inline cl_int clReleaseEvent(cl_event p0) { return clReleaseEvent_pfn(p0); } +#undef clReleaseKernel +#define clReleaseKernel clReleaseKernel_fn +inline cl_int clReleaseKernel(cl_kernel p0) { return clReleaseKernel_pfn(p0); } +#undef clReleaseMemObject +#define clReleaseMemObject clReleaseMemObject_fn +inline cl_int clReleaseMemObject(cl_mem p0) { return clReleaseMemObject_pfn(p0); } +#undef clReleaseProgram +#define clReleaseProgram clReleaseProgram_fn +inline cl_int clReleaseProgram(cl_program p0) { return clReleaseProgram_pfn(p0); } +#undef clReleaseSampler +#define clReleaseSampler clReleaseSampler_fn +inline cl_int clReleaseSampler(cl_sampler p0) { return clReleaseSampler_pfn(p0); } +#undef clRetainCommandQueue +#define clRetainCommandQueue clRetainCommandQueue_fn +inline cl_int clRetainCommandQueue(cl_command_queue p0) { return clRetainCommandQueue_pfn(p0); } +#undef clRetainContext +#define clRetainContext clRetainContext_fn +inline cl_int clRetainContext(cl_context p0) { return clRetainContext_pfn(p0); } +#undef clRetainDevice +#define clRetainDevice clRetainDevice_fn +inline cl_int clRetainDevice(cl_device_id p0) { return clRetainDevice_pfn(p0); } +#undef clRetainEvent +#define clRetainEvent clRetainEvent_fn +inline cl_int clRetainEvent(cl_event p0) { return clRetainEvent_pfn(p0); } +#undef clRetainKernel +#define clRetainKernel clRetainKernel_fn +inline cl_int clRetainKernel(cl_kernel p0) { return clRetainKernel_pfn(p0); } +#undef clRetainMemObject +#define clRetainMemObject clRetainMemObject_fn +inline cl_int clRetainMemObject(cl_mem p0) { return clRetainMemObject_pfn(p0); } +#undef clRetainProgram +#define clRetainProgram clRetainProgram_fn +inline cl_int clRetainProgram(cl_program p0) { return clRetainProgram_pfn(p0); } +#undef clRetainSampler +#define clRetainSampler clRetainSampler_fn +inline cl_int clRetainSampler(cl_sampler p0) { return clRetainSampler_pfn(p0); } +#undef clSetEventCallback +#define clSetEventCallback clSetEventCallback_fn +inline cl_int clSetEventCallback(cl_event p0, cl_int p1, void (CL_CALLBACK*p2) (cl_event, cl_int, void*), void* p3) { return clSetEventCallback_pfn(p0, p1, p2, p3); } +#undef clSetKernelArg +#define clSetKernelArg clSetKernelArg_fn +inline cl_int clSetKernelArg(cl_kernel p0, cl_uint p1, size_t p2, const void* p3) { return clSetKernelArg_pfn(p0, p1, p2, p3); } +#undef clSetMemObjectDestructorCallback +#define clSetMemObjectDestructorCallback clSetMemObjectDestructorCallback_fn +inline cl_int clSetMemObjectDestructorCallback(cl_mem p0, void (CL_CALLBACK*p1) (cl_mem, void*), void* p2) { return clSetMemObjectDestructorCallback_pfn(p0, p1, p2); } +#undef clSetUserEventStatus +#define clSetUserEventStatus clSetUserEventStatus_fn +inline cl_int clSetUserEventStatus(cl_event p0, cl_int p1) { return clSetUserEventStatus_pfn(p0, p1); } +#undef clUnloadCompiler +#define clUnloadCompiler clUnloadCompiler_fn +inline cl_int clUnloadCompiler() { return clUnloadCompiler_pfn(); } +#undef clUnloadPlatformCompiler +#define clUnloadPlatformCompiler clUnloadPlatformCompiler_fn +inline cl_int clUnloadPlatformCompiler(cl_platform_id p0) { return clUnloadPlatformCompiler_pfn(p0); } +#undef clWaitForEvents +#define clWaitForEvents clWaitForEvents_fn +inline cl_int clWaitForEvents(cl_uint p0, const cl_event* p1) { return clWaitForEvents_pfn(p0, p1); } diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp new file mode 100755 index 0000000..0b12aed --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp @@ -0,0 +1,62 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_HPP +#error "Invalid usage" +#endif + +// generated by parser_cl.py +#define clCreateFromGLBuffer clCreateFromGLBuffer_ +#define clCreateFromGLRenderbuffer clCreateFromGLRenderbuffer_ +#define clCreateFromGLTexture clCreateFromGLTexture_ +#define clCreateFromGLTexture2D clCreateFromGLTexture2D_ +#define clCreateFromGLTexture3D clCreateFromGLTexture3D_ +#define clEnqueueAcquireGLObjects clEnqueueAcquireGLObjects_ +#define clEnqueueReleaseGLObjects clEnqueueReleaseGLObjects_ +#define clGetGLContextInfoKHR clGetGLContextInfoKHR_ +#define clGetGLObjectInfo clGetGLObjectInfo_ +#define clGetGLTextureInfo clGetGLTextureInfo_ + +#if defined __APPLE__ +#include +#else +#include +#endif + +// generated by parser_cl.py +#undef clCreateFromGLBuffer +#define clCreateFromGLBuffer clCreateFromGLBuffer_pfn +#undef clCreateFromGLRenderbuffer +#define clCreateFromGLRenderbuffer clCreateFromGLRenderbuffer_pfn +#undef clCreateFromGLTexture +#define clCreateFromGLTexture clCreateFromGLTexture_pfn +#undef clCreateFromGLTexture2D +#define clCreateFromGLTexture2D clCreateFromGLTexture2D_pfn +#undef clCreateFromGLTexture3D +#define clCreateFromGLTexture3D clCreateFromGLTexture3D_pfn +#undef clEnqueueAcquireGLObjects +#define clEnqueueAcquireGLObjects clEnqueueAcquireGLObjects_pfn +#undef clEnqueueReleaseGLObjects +#define clEnqueueReleaseGLObjects clEnqueueReleaseGLObjects_pfn +#undef clGetGLContextInfoKHR +#define clGetGLContextInfoKHR clGetGLContextInfoKHR_pfn +#undef clGetGLObjectInfo +#define clGetGLObjectInfo clGetGLObjectInfo_pfn +#undef clGetGLTextureInfo +#define clGetGLTextureInfo clGetGLTextureInfo_pfn + +#ifdef cl_khr_gl_sharing + +// generated by parser_cl.py +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateFromGLBuffer)(cl_context, cl_mem_flags, cl_GLuint, int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateFromGLRenderbuffer)(cl_context, cl_mem_flags, cl_GLuint, cl_int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateFromGLTexture)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateFromGLTexture2D)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int*); +extern CL_RUNTIME_EXPORT cl_mem (CL_API_CALL*clCreateFromGLTexture3D)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueAcquireGLObjects)(cl_command_queue, cl_uint, const cl_mem*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clEnqueueReleaseGLObjects)(cl_command_queue, cl_uint, const cl_mem*, cl_uint, const cl_event*, cl_event*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetGLContextInfoKHR)(const cl_context_properties*, cl_gl_context_info, size_t, void*, size_t*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetGLObjectInfo)(cl_mem, cl_gl_object_type*, cl_GLuint*); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL*clGetGLTextureInfo)(cl_mem, cl_gl_texture_info, size_t, void*, size_t*); + +#endif // cl_khr_gl_sharing diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp new file mode 100755 index 0000000..12f342b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp @@ -0,0 +1,42 @@ +// +// AUTOGENERATED, DO NOT EDIT +// +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_WRAPPERS_HPP +#error "Invalid usage" +#endif + +#ifdef cl_khr_gl_sharing + +// generated by parser_cl.py +#undef clCreateFromGLBuffer +#define clCreateFromGLBuffer clCreateFromGLBuffer_fn +inline cl_mem clCreateFromGLBuffer(cl_context p0, cl_mem_flags p1, cl_GLuint p2, int* p3) { return clCreateFromGLBuffer_pfn(p0, p1, p2, p3); } +#undef clCreateFromGLRenderbuffer +#define clCreateFromGLRenderbuffer clCreateFromGLRenderbuffer_fn +inline cl_mem clCreateFromGLRenderbuffer(cl_context p0, cl_mem_flags p1, cl_GLuint p2, cl_int* p3) { return clCreateFromGLRenderbuffer_pfn(p0, p1, p2, p3); } +#undef clCreateFromGLTexture +#define clCreateFromGLTexture clCreateFromGLTexture_fn +inline cl_mem clCreateFromGLTexture(cl_context p0, cl_mem_flags p1, cl_GLenum p2, cl_GLint p3, cl_GLuint p4, cl_int* p5) { return clCreateFromGLTexture_pfn(p0, p1, p2, p3, p4, p5); } +#undef clCreateFromGLTexture2D +#define clCreateFromGLTexture2D clCreateFromGLTexture2D_fn +inline cl_mem clCreateFromGLTexture2D(cl_context p0, cl_mem_flags p1, cl_GLenum p2, cl_GLint p3, cl_GLuint p4, cl_int* p5) { return clCreateFromGLTexture2D_pfn(p0, p1, p2, p3, p4, p5); } +#undef clCreateFromGLTexture3D +#define clCreateFromGLTexture3D clCreateFromGLTexture3D_fn +inline cl_mem clCreateFromGLTexture3D(cl_context p0, cl_mem_flags p1, cl_GLenum p2, cl_GLint p3, cl_GLuint p4, cl_int* p5) { return clCreateFromGLTexture3D_pfn(p0, p1, p2, p3, p4, p5); } +#undef clEnqueueAcquireGLObjects +#define clEnqueueAcquireGLObjects clEnqueueAcquireGLObjects_fn +inline cl_int clEnqueueAcquireGLObjects(cl_command_queue p0, cl_uint p1, const cl_mem* p2, cl_uint p3, const cl_event* p4, cl_event* p5) { return clEnqueueAcquireGLObjects_pfn(p0, p1, p2, p3, p4, p5); } +#undef clEnqueueReleaseGLObjects +#define clEnqueueReleaseGLObjects clEnqueueReleaseGLObjects_fn +inline cl_int clEnqueueReleaseGLObjects(cl_command_queue p0, cl_uint p1, const cl_mem* p2, cl_uint p3, const cl_event* p4, cl_event* p5) { return clEnqueueReleaseGLObjects_pfn(p0, p1, p2, p3, p4, p5); } +#undef clGetGLContextInfoKHR +#define clGetGLContextInfoKHR clGetGLContextInfoKHR_fn +inline cl_int clGetGLContextInfoKHR(const cl_context_properties* p0, cl_gl_context_info p1, size_t p2, void* p3, size_t* p4) { return clGetGLContextInfoKHR_pfn(p0, p1, p2, p3, p4); } +#undef clGetGLObjectInfo +#define clGetGLObjectInfo clGetGLObjectInfo_fn +inline cl_int clGetGLObjectInfo(cl_mem p0, cl_gl_object_type* p1, cl_GLuint* p2) { return clGetGLObjectInfo_pfn(p0, p1, p2); } +#undef clGetGLTextureInfo +#define clGetGLTextureInfo clGetGLTextureInfo_fn +inline cl_int clGetGLTextureInfo(cl_mem p0, cl_gl_texture_info p1, size_t p2, void* p3, size_t* p4) { return clGetGLTextureInfo_pfn(p0, p1, p2, p3, p4); } + +#endif // cl_khr_gl_sharing diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp new file mode 100755 index 0000000..2ad8ac0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp @@ -0,0 +1,53 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDBLAS_HPP +#define OPENCV_CORE_OCL_RUNTIME_CLAMDBLAS_HPP + +#ifdef HAVE_CLAMDBLAS + +#include "opencl_core.hpp" + +#include "autogenerated/opencl_clamdblas.hpp" + +#endif // HAVE_CLAMDBLAS + +#endif // OPENCV_CORE_OCL_RUNTIME_CLAMDBLAS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp new file mode 100755 index 0000000..a328f72 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp @@ -0,0 +1,53 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OCL_RUNTIME_CLAMDFFT_HPP +#define OPENCV_CORE_OCL_RUNTIME_CLAMDFFT_HPP + +#ifdef HAVE_CLAMDFFT + +#include "opencl_core.hpp" + +#include "autogenerated/opencl_clamdfft.hpp" + +#endif // HAVE_CLAMDFFT + +#endif // OPENCV_CORE_OCL_RUNTIME_CLAMDFFT_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core.hpp new file mode 100755 index 0000000..0404b31 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core.hpp @@ -0,0 +1,84 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_CORE_HPP +#define OPENCV_CORE_OCL_RUNTIME_OPENCL_CORE_HPP + +#ifdef HAVE_OPENCL + +#ifndef CL_RUNTIME_EXPORT +#if (defined(BUILD_SHARED_LIBS) || defined(OPENCV_CORE_SHARED)) && (defined _WIN32 || defined WINCE) && \ + !(defined(__OPENCV_BUILD) && defined(OPENCV_MODULE_IS_PART_OF_WORLD)) +#define CL_RUNTIME_EXPORT __declspec(dllimport) +#else +#define CL_RUNTIME_EXPORT +#endif +#endif + +#ifdef HAVE_OPENCL_SVM +#define clSVMAlloc clSVMAlloc_ +#define clSVMFree clSVMFree_ +#define clSetKernelArgSVMPointer clSetKernelArgSVMPointer_ +#define clSetKernelExecInfo clSetKernelExecInfo_ +#define clEnqueueSVMFree clEnqueueSVMFree_ +#define clEnqueueSVMMemcpy clEnqueueSVMMemcpy_ +#define clEnqueueSVMMemFill clEnqueueSVMMemFill_ +#define clEnqueueSVMMap clEnqueueSVMMap_ +#define clEnqueueSVMUnmap clEnqueueSVMUnmap_ +#endif + +#include "autogenerated/opencl_core.hpp" + +#ifndef CL_DEVICE_DOUBLE_FP_CONFIG +#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 +#endif + +#ifndef CL_DEVICE_HALF_FP_CONFIG +#define CL_DEVICE_HALF_FP_CONFIG 0x1033 +#endif + +#ifndef CL_VERSION_1_2 +#define CV_REQUIRE_OPENCL_1_2_ERROR CV_Error(cv::Error::OpenCLApiCallError, "OpenCV compiled without OpenCL v1.2 support, so we can't use functionality from OpenCL v1.2") +#endif + +#endif // HAVE_OPENCL + +#endif // OPENCV_CORE_OCL_RUNTIME_OPENCL_CORE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp new file mode 100755 index 0000000..38fcae9 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_WRAPPERS_HPP +#define OPENCV_CORE_OCL_RUNTIME_OPENCL_WRAPPERS_HPP + +#include "autogenerated/opencl_core_wrappers.hpp" + +#endif // OPENCV_CORE_OCL_RUNTIME_OPENCL_WRAPPERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp new file mode 100755 index 0000000..659c7d8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp @@ -0,0 +1,53 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_HPP +#define OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_HPP + +#if defined HAVE_OPENCL && defined HAVE_OPENGL + +#include "opencl_core.hpp" + +#include "autogenerated/opencl_gl.hpp" + +#endif // defined HAVE_OPENCL && defined HAVE_OPENGL + +#endif // OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp new file mode 100755 index 0000000..9700004 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_WRAPPERS_HPP +#define OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_WRAPPERS_HPP + +#include "autogenerated/opencl_gl_wrappers.hpp" + +#endif // OPENCV_CORE_OCL_RUNTIME_OPENCL_GL_WRAPPERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp new file mode 100755 index 0000000..9636b19 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp @@ -0,0 +1,48 @@ +/* See LICENSE file in the root OpenCV directory */ + +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_2_0_HPP +#define OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_2_0_HPP + +#if defined(HAVE_OPENCL_SVM) +#include "opencl_core.hpp" + +#include "opencl_svm_definitions.hpp" + +#undef clSVMAlloc +#define clSVMAlloc clSVMAlloc_pfn +#undef clSVMFree +#define clSVMFree clSVMFree_pfn +#undef clSetKernelArgSVMPointer +#define clSetKernelArgSVMPointer clSetKernelArgSVMPointer_pfn +#undef clSetKernelExecInfo +//#define clSetKernelExecInfo clSetKernelExecInfo_pfn +#undef clEnqueueSVMFree +//#define clEnqueueSVMFree clEnqueueSVMFree_pfn +#undef clEnqueueSVMMemcpy +#define clEnqueueSVMMemcpy clEnqueueSVMMemcpy_pfn +#undef clEnqueueSVMMemFill +#define clEnqueueSVMMemFill clEnqueueSVMMemFill_pfn +#undef clEnqueueSVMMap +#define clEnqueueSVMMap clEnqueueSVMMap_pfn +#undef clEnqueueSVMUnmap +#define clEnqueueSVMUnmap clEnqueueSVMUnmap_pfn + +extern CL_RUNTIME_EXPORT void* (CL_API_CALL *clSVMAlloc)(cl_context context, cl_svm_mem_flags flags, size_t size, unsigned int alignment); +extern CL_RUNTIME_EXPORT void (CL_API_CALL *clSVMFree)(cl_context context, void* svm_pointer); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL *clSetKernelArgSVMPointer)(cl_kernel kernel, cl_uint arg_index, const void* arg_value); +//extern CL_RUNTIME_EXPORT void* (CL_API_CALL *clSetKernelExecInfo)(cl_kernel kernel, cl_kernel_exec_info param_name, size_t param_value_size, const void* param_value); +//extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL *clEnqueueSVMFree)(cl_command_queue command_queue, cl_uint num_svm_pointers, void* svm_pointers[], +// void (CL_CALLBACK *pfn_free_func)(cl_command_queue queue, cl_uint num_svm_pointers, void* svm_pointers[], void* user_data), void* user_data, +// cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL *clEnqueueSVMMemcpy)(cl_command_queue command_queue, cl_bool blocking_copy, void* dst_ptr, const void* src_ptr, size_t size, + cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL *clEnqueueSVMMemFill)(cl_command_queue command_queue, void* svm_ptr, const void* pattern, size_t pattern_size, size_t size, + cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL *clEnqueueSVMMap)(cl_command_queue command_queue, cl_bool blocking_map, cl_map_flags map_flags, void* svm_ptr, size_t size, + cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event); +extern CL_RUNTIME_EXPORT cl_int (CL_API_CALL *clEnqueueSVMUnmap)(cl_command_queue command_queue, void* svm_ptr, + cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event); + +#endif // HAVE_OPENCL_SVM + +#endif // OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_2_0_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp new file mode 100755 index 0000000..97c927b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp @@ -0,0 +1,42 @@ +/* See LICENSE file in the root OpenCV directory */ + +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_DEFINITIONS_HPP +#define OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_DEFINITIONS_HPP + +#if defined(HAVE_OPENCL_SVM) +#if defined(CL_VERSION_2_0) + +// OpenCL 2.0 contains SVM definitions + +#else + +typedef cl_bitfield cl_device_svm_capabilities; +typedef cl_bitfield cl_svm_mem_flags; +typedef cl_uint cl_kernel_exec_info; + +// +// TODO Add real values after OpenCL 2.0 release +// + +#ifndef CL_DEVICE_SVM_CAPABILITIES +#define CL_DEVICE_SVM_CAPABILITIES 0x1053 + +#define CL_DEVICE_SVM_COARSE_GRAIN_BUFFER (1 << 0) +#define CL_DEVICE_SVM_FINE_GRAIN_BUFFER (1 << 1) +#define CL_DEVICE_SVM_FINE_GRAIN_SYSTEM (1 << 2) +#define CL_DEVICE_SVM_ATOMICS (1 << 3) +#endif + +#ifndef CL_MEM_SVM_FINE_GRAIN_BUFFER +#define CL_MEM_SVM_FINE_GRAIN_BUFFER (1 << 10) +#endif + +#ifndef CL_MEM_SVM_ATOMICS +#define CL_MEM_SVM_ATOMICS (1 << 11) +#endif + + +#endif // CL_VERSION_2_0 +#endif // HAVE_OPENCL_SVM + +#endif // OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_DEFINITIONS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp new file mode 100755 index 0000000..497bc3d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp @@ -0,0 +1,166 @@ +/* See LICENSE file in the root OpenCV directory */ + +#ifndef OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_HSA_EXTENSION_HPP +#define OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_HSA_EXTENSION_HPP + +#if defined(HAVE_OPENCL_SVM) +#include "opencl_core.hpp" + +#ifndef CL_DEVICE_SVM_CAPABILITIES_AMD +// +// Part of the file is an extract from the cl_ext.h file from AMD APP SDK package. +// Below is the original copyright. +// +/******************************************************************************* + * Copyright (c) 2008-2013 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + ******************************************************************************/ + +/******************************************* + * Shared Virtual Memory (SVM) extension + *******************************************/ +typedef cl_bitfield cl_device_svm_capabilities_amd; +typedef cl_bitfield cl_svm_mem_flags_amd; +typedef cl_uint cl_kernel_exec_info_amd; + +/* cl_device_info */ +#define CL_DEVICE_SVM_CAPABILITIES_AMD 0x1053 +#define CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT_AMD 0x1054 + +/* cl_device_svm_capabilities_amd */ +#define CL_DEVICE_SVM_COARSE_GRAIN_BUFFER_AMD (1 << 0) +#define CL_DEVICE_SVM_FINE_GRAIN_BUFFER_AMD (1 << 1) +#define CL_DEVICE_SVM_FINE_GRAIN_SYSTEM_AMD (1 << 2) +#define CL_DEVICE_SVM_ATOMICS_AMD (1 << 3) + +/* cl_svm_mem_flags_amd */ +#define CL_MEM_SVM_FINE_GRAIN_BUFFER_AMD (1 << 10) +#define CL_MEM_SVM_ATOMICS_AMD (1 << 11) + +/* cl_mem_info */ +#define CL_MEM_USES_SVM_POINTER_AMD 0x1109 + +/* cl_kernel_exec_info_amd */ +#define CL_KERNEL_EXEC_INFO_SVM_PTRS_AMD 0x11B6 +#define CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM_AMD 0x11B7 + +/* cl_command_type */ +#define CL_COMMAND_SVM_FREE_AMD 0x1209 +#define CL_COMMAND_SVM_MEMCPY_AMD 0x120A +#define CL_COMMAND_SVM_MEMFILL_AMD 0x120B +#define CL_COMMAND_SVM_MAP_AMD 0x120C +#define CL_COMMAND_SVM_UNMAP_AMD 0x120D + +typedef CL_API_ENTRY void* +(CL_API_CALL * clSVMAllocAMD_fn)( + cl_context /* context */, + cl_svm_mem_flags_amd /* flags */, + size_t /* size */, + unsigned int /* alignment */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY void +(CL_API_CALL * clSVMFreeAMD_fn)( + cl_context /* context */, + void* /* svm_pointer */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int +(CL_API_CALL * clEnqueueSVMFreeAMD_fn)( + cl_command_queue /* command_queue */, + cl_uint /* num_svm_pointers */, + void** /* svm_pointers */, + void (CL_CALLBACK *)( /*pfn_free_func*/ + cl_command_queue /* queue */, + cl_uint /* num_svm_pointers */, + void** /* svm_pointers */, + void* /* user_data */), + void* /* user_data */, + cl_uint /* num_events_in_wait_list */, + const cl_event* /* event_wait_list */, + cl_event* /* event */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int +(CL_API_CALL * clEnqueueSVMMemcpyAMD_fn)( + cl_command_queue /* command_queue */, + cl_bool /* blocking_copy */, + void* /* dst_ptr */, + const void* /* src_ptr */, + size_t /* size */, + cl_uint /* num_events_in_wait_list */, + const cl_event* /* event_wait_list */, + cl_event* /* event */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int +(CL_API_CALL * clEnqueueSVMMemFillAMD_fn)( + cl_command_queue /* command_queue */, + void* /* svm_ptr */, + const void* /* pattern */, + size_t /* pattern_size */, + size_t /* size */, + cl_uint /* num_events_in_wait_list */, + const cl_event* /* event_wait_list */, + cl_event* /* event */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int +(CL_API_CALL * clEnqueueSVMMapAMD_fn)( + cl_command_queue /* command_queue */, + cl_bool /* blocking_map */, + cl_map_flags /* map_flags */, + void* /* svm_ptr */, + size_t /* size */, + cl_uint /* num_events_in_wait_list */, + const cl_event* /* event_wait_list */, + cl_event* /* event */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int +(CL_API_CALL * clEnqueueSVMUnmapAMD_fn)( + cl_command_queue /* command_queue */, + void* /* svm_ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event* /* event_wait_list */, + cl_event* /* event */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int +(CL_API_CALL * clSetKernelArgSVMPointerAMD_fn)( + cl_kernel /* kernel */, + cl_uint /* arg_index */, + const void * /* arg_value */ +) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int +(CL_API_CALL * clSetKernelExecInfoAMD_fn)( + cl_kernel /* kernel */, + cl_kernel_exec_info_amd /* param_name */, + size_t /* param_value_size */, + const void * /* param_value */ +) CL_EXT_SUFFIX__VERSION_1_2; + +#endif + +#endif // HAVE_OPENCL_SVM + +#endif // OPENCV_CORE_OCL_RUNTIME_OPENCL_SVM_HSA_EXTENSION_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/opengl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/opengl.hpp new file mode 100755 index 0000000..a311ce2 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/opengl.hpp @@ -0,0 +1,725 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OPENGL_HPP +#define OPENCV_CORE_OPENGL_HPP + +#ifndef __cplusplus +# error opengl.hpp header must be compiled as C++ +#endif + +#include "opencv2/core.hpp" +#include "ocl.hpp" + +namespace cv { namespace ogl { + +/** @addtogroup core_opengl +This section describes OpenGL interoperability. + +To enable OpenGL support, configure OpenCV using CMake with WITH_OPENGL=ON . Currently OpenGL is +supported only with WIN32, GTK and Qt backends on Windows and Linux (MacOS and Android are not +supported). For GTK backend gtkglext-1.0 library is required. + +To use OpenGL functionality you should first create OpenGL context (window or frame buffer). You can +do this with namedWindow function or with other OpenGL toolkit (GLUT, for example). +*/ +//! @{ + +/////////////////// OpenGL Objects /////////////////// + +/** @brief Smart pointer for OpenGL buffer object with reference counting. + +Buffer Objects are OpenGL objects that store an array of unformatted memory allocated by the OpenGL +context. These can be used to store vertex data, pixel data retrieved from images or the +framebuffer, and a variety of other things. + +ogl::Buffer has interface similar with Mat interface and represents 2D array memory. + +ogl::Buffer supports memory transfers between host and device and also can be mapped to CUDA memory. + */ +class CV_EXPORTS Buffer +{ +public: + /** @brief The target defines how you intend to use the buffer object. + */ + enum Target + { + ARRAY_BUFFER = 0x8892, //!< The buffer will be used as a source for vertex data + ELEMENT_ARRAY_BUFFER = 0x8893, //!< The buffer will be used for indices (in glDrawElements, for example) + PIXEL_PACK_BUFFER = 0x88EB, //!< The buffer will be used for reading from OpenGL textures + PIXEL_UNPACK_BUFFER = 0x88EC //!< The buffer will be used for writing to OpenGL textures + }; + + enum Access + { + READ_ONLY = 0x88B8, + WRITE_ONLY = 0x88B9, + READ_WRITE = 0x88BA + }; + + /** @brief The constructors. + + Creates empty ogl::Buffer object, creates ogl::Buffer object from existed buffer ( abufId + parameter), allocates memory for ogl::Buffer object or copies from host/device memory. + */ + Buffer(); + + /** @overload + @param arows Number of rows in a 2D array. + @param acols Number of columns in a 2D array. + @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details. + @param abufId Buffer object name. + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + Buffer(int arows, int acols, int atype, unsigned int abufId, bool autoRelease = false); + + /** @overload + @param asize 2D array size. + @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details. + @param abufId Buffer object name. + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + Buffer(Size asize, int atype, unsigned int abufId, bool autoRelease = false); + + /** @overload + @param arows Number of rows in a 2D array. + @param acols Number of columns in a 2D array. + @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details. + @param target Buffer usage. See cv::ogl::Buffer::Target . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + Buffer(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); + + /** @overload + @param asize 2D array size. + @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details. + @param target Buffer usage. See cv::ogl::Buffer::Target . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + Buffer(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); + + /** @overload + @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or std::vector ). + @param target Buffer usage. See cv::ogl::Buffer::Target . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + explicit Buffer(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false); + + /** @brief Allocates memory for ogl::Buffer object. + + @param arows Number of rows in a 2D array. + @param acols Number of columns in a 2D array. + @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details. + @param target Buffer usage. See cv::ogl::Buffer::Target . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + void create(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); + + /** @overload + @param asize 2D array size. + @param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details. + @param target Buffer usage. See cv::ogl::Buffer::Target . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + void create(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false); + + /** @brief Decrements the reference counter and destroys the buffer object if needed. + + The function will call setAutoRelease(true) . + */ + void release(); + + /** @brief Sets auto release mode. + + The lifetime of the OpenGL object is tied to the lifetime of the context. If OpenGL context was + bound to a window it could be released at any time (user can close a window). If object's destructor + is called after destruction of the context it will cause an error. Thus ogl::Buffer doesn't destroy + OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL context). + This function can force ogl::Buffer destructor to destroy OpenGL object. + @param flag Auto release mode (if true, release will be called in object's destructor). + */ + void setAutoRelease(bool flag); + + /** @brief Copies from host/device memory to OpenGL buffer. + @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or std::vector ). + @param target Buffer usage. See cv::ogl::Buffer::Target . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + void copyFrom(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false); + + /** @overload */ + void copyFrom(InputArray arr, cuda::Stream& stream, Target target = ARRAY_BUFFER, bool autoRelease = false); + + /** @brief Copies from OpenGL buffer to host/device memory or another OpenGL buffer object. + + @param arr Destination array (host or device memory, can be Mat , cuda::GpuMat , std::vector or + ogl::Buffer ). + */ + void copyTo(OutputArray arr) const; + + /** @overload */ + void copyTo(OutputArray arr, cuda::Stream& stream) const; + + /** @brief Creates a full copy of the buffer object and the underlying data. + + @param target Buffer usage for destination buffer. + @param autoRelease Auto release mode for destination buffer. + */ + Buffer clone(Target target = ARRAY_BUFFER, bool autoRelease = false) const; + + /** @brief Binds OpenGL buffer to the specified buffer binding point. + + @param target Binding point. See cv::ogl::Buffer::Target . + */ + void bind(Target target) const; + + /** @brief Unbind any buffers from the specified binding point. + + @param target Binding point. See cv::ogl::Buffer::Target . + */ + static void unbind(Target target); + + /** @brief Maps OpenGL buffer to host memory. + + mapHost maps to the client's address space the entire data store of the buffer object. The data can + then be directly read and/or written relative to the returned pointer, depending on the specified + access policy. + + A mapped data store must be unmapped with ogl::Buffer::unmapHost before its buffer object is used. + + This operation can lead to memory transfers between host and device. + + Only one buffer object can be mapped at a time. + @param access Access policy, indicating whether it will be possible to read from, write to, or both + read from and write to the buffer object's mapped data store. The symbolic constant must be + ogl::Buffer::READ_ONLY , ogl::Buffer::WRITE_ONLY or ogl::Buffer::READ_WRITE . + */ + Mat mapHost(Access access); + + /** @brief Unmaps OpenGL buffer. + */ + void unmapHost(); + + //! map to device memory (blocking) + cuda::GpuMat mapDevice(); + void unmapDevice(); + + /** @brief Maps OpenGL buffer to CUDA device memory. + + This operation doesn't copy data. Several buffer objects can be mapped to CUDA memory at a time. + + A mapped data store must be unmapped with ogl::Buffer::unmapDevice before its buffer object is used. + */ + cuda::GpuMat mapDevice(cuda::Stream& stream); + + /** @brief Unmaps OpenGL buffer. + */ + void unmapDevice(cuda::Stream& stream); + + int rows() const; + int cols() const; + Size size() const; + bool empty() const; + + int type() const; + int depth() const; + int channels() const; + int elemSize() const; + int elemSize1() const; + + //! get OpenGL opject id + unsigned int bufId() const; + + class Impl; + +private: + Ptr impl_; + int rows_; + int cols_; + int type_; +}; + +/** @brief Smart pointer for OpenGL 2D texture memory with reference counting. + */ +class CV_EXPORTS Texture2D +{ +public: + /** @brief An Image Format describes the way that the images in Textures store their data. + */ + enum Format + { + NONE = 0, + DEPTH_COMPONENT = 0x1902, //!< Depth + RGB = 0x1907, //!< Red, Green, Blue + RGBA = 0x1908 //!< Red, Green, Blue, Alpha + }; + + /** @brief The constructors. + + Creates empty ogl::Texture2D object, allocates memory for ogl::Texture2D object or copies from + host/device memory. + */ + Texture2D(); + + /** @overload */ + Texture2D(int arows, int acols, Format aformat, unsigned int atexId, bool autoRelease = false); + + /** @overload */ + Texture2D(Size asize, Format aformat, unsigned int atexId, bool autoRelease = false); + + /** @overload + @param arows Number of rows. + @param acols Number of columns. + @param aformat Image format. See cv::ogl::Texture2D::Format . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + Texture2D(int arows, int acols, Format aformat, bool autoRelease = false); + + /** @overload + @param asize 2D array size. + @param aformat Image format. See cv::ogl::Texture2D::Format . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + Texture2D(Size asize, Format aformat, bool autoRelease = false); + + /** @overload + @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or ogl::Buffer ). + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + explicit Texture2D(InputArray arr, bool autoRelease = false); + + /** @brief Allocates memory for ogl::Texture2D object. + + @param arows Number of rows. + @param acols Number of columns. + @param aformat Image format. See cv::ogl::Texture2D::Format . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + void create(int arows, int acols, Format aformat, bool autoRelease = false); + /** @overload + @param asize 2D array size. + @param aformat Image format. See cv::ogl::Texture2D::Format . + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + void create(Size asize, Format aformat, bool autoRelease = false); + + /** @brief Decrements the reference counter and destroys the texture object if needed. + + The function will call setAutoRelease(true) . + */ + void release(); + + /** @brief Sets auto release mode. + + @param flag Auto release mode (if true, release will be called in object's destructor). + + The lifetime of the OpenGL object is tied to the lifetime of the context. If OpenGL context was + bound to a window it could be released at any time (user can close a window). If object's destructor + is called after destruction of the context it will cause an error. Thus ogl::Texture2D doesn't + destroy OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL + context). This function can force ogl::Texture2D destructor to destroy OpenGL object. + */ + void setAutoRelease(bool flag); + + /** @brief Copies from host/device memory to OpenGL texture. + + @param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or ogl::Buffer ). + @param autoRelease Auto release mode (if true, release will be called in object's destructor). + */ + void copyFrom(InputArray arr, bool autoRelease = false); + + /** @brief Copies from OpenGL texture to host/device memory or another OpenGL texture object. + + @param arr Destination array (host or device memory, can be Mat , cuda::GpuMat , ogl::Buffer or + ogl::Texture2D ). + @param ddepth Destination depth. + @param autoRelease Auto release mode for destination buffer (if arr is OpenGL buffer or texture). + */ + void copyTo(OutputArray arr, int ddepth = CV_32F, bool autoRelease = false) const; + + /** @brief Binds texture to current active texture unit for GL_TEXTURE_2D target. + */ + void bind() const; + + int rows() const; + int cols() const; + Size size() const; + bool empty() const; + + Format format() const; + + //! get OpenGL opject id + unsigned int texId() const; + + class Impl; + +private: + Ptr impl_; + int rows_; + int cols_; + Format format_; +}; + +/** @brief Wrapper for OpenGL Client-Side Vertex arrays. + +ogl::Arrays stores vertex data in ogl::Buffer objects. + */ +class CV_EXPORTS Arrays +{ +public: + /** @brief Default constructor + */ + Arrays(); + + /** @brief Sets an array of vertex coordinates. + @param vertex array with vertex coordinates, can be both host and device memory. + */ + void setVertexArray(InputArray vertex); + + /** @brief Resets vertex coordinates. + */ + void resetVertexArray(); + + /** @brief Sets an array of vertex colors. + @param color array with vertex colors, can be both host and device memory. + */ + void setColorArray(InputArray color); + + /** @brief Resets vertex colors. + */ + void resetColorArray(); + + /** @brief Sets an array of vertex normals. + @param normal array with vertex normals, can be both host and device memory. + */ + void setNormalArray(InputArray normal); + + /** @brief Resets vertex normals. + */ + void resetNormalArray(); + + /** @brief Sets an array of vertex texture coordinates. + @param texCoord array with vertex texture coordinates, can be both host and device memory. + */ + void setTexCoordArray(InputArray texCoord); + + /** @brief Resets vertex texture coordinates. + */ + void resetTexCoordArray(); + + /** @brief Releases all inner buffers. + */ + void release(); + + /** @brief Sets auto release mode all inner buffers. + @param flag Auto release mode. + */ + void setAutoRelease(bool flag); + + /** @brief Binds all vertex arrays. + */ + void bind() const; + + /** @brief Returns the vertex count. + */ + int size() const; + bool empty() const; + +private: + int size_; + Buffer vertex_; + Buffer color_; + Buffer normal_; + Buffer texCoord_; +}; + +/////////////////// Render Functions /////////////////// + +//! render mode +enum RenderModes { + POINTS = 0x0000, + LINES = 0x0001, + LINE_LOOP = 0x0002, + LINE_STRIP = 0x0003, + TRIANGLES = 0x0004, + TRIANGLE_STRIP = 0x0005, + TRIANGLE_FAN = 0x0006, + QUADS = 0x0007, + QUAD_STRIP = 0x0008, + POLYGON = 0x0009 +}; + +/** @brief Render OpenGL texture or primitives. +@param tex Texture to draw. +@param wndRect Region of window, where to draw a texture (normalized coordinates). +@param texRect Region of texture to draw (normalized coordinates). + */ +CV_EXPORTS void render(const Texture2D& tex, + Rect_ wndRect = Rect_(0.0, 0.0, 1.0, 1.0), + Rect_ texRect = Rect_(0.0, 0.0, 1.0, 1.0)); + +/** @overload +@param arr Array of privitives vertices. +@param mode Render mode. One of cv::ogl::RenderModes +@param color Color for all vertices. Will be used if arr doesn't contain color array. +*/ +CV_EXPORTS void render(const Arrays& arr, int mode = POINTS, Scalar color = Scalar::all(255)); + +/** @overload +@param arr Array of privitives vertices. +@param indices Array of vertices indices (host or device memory). +@param mode Render mode. One of cv::ogl::RenderModes +@param color Color for all vertices. Will be used if arr doesn't contain color array. +*/ +CV_EXPORTS void render(const Arrays& arr, InputArray indices, int mode = POINTS, Scalar color = Scalar::all(255)); + +/////////////////// CL-GL Interoperability Functions /////////////////// + +namespace ocl { +using namespace cv::ocl; + +// TODO static functions in the Context class +/** @brief Creates OpenCL context from GL. +@return Returns reference to OpenCL Context + */ +CV_EXPORTS Context& initializeContextFromGL(); + +} // namespace cv::ogl::ocl + +/** @brief Converts InputArray to Texture2D object. +@param src - source InputArray. +@param texture - destination Texture2D object. + */ +CV_EXPORTS void convertToGLTexture2D(InputArray src, Texture2D& texture); + +/** @brief Converts Texture2D object to OutputArray. +@param texture - source Texture2D object. +@param dst - destination OutputArray. + */ +CV_EXPORTS void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst); + +/** @brief Maps Buffer object to process on CL side (convert to UMat). + +Function creates CL buffer from GL one, and then constructs UMat that can be used +to process buffer data with OpenCV functions. Note that in current implementation +UMat constructed this way doesn't own corresponding GL buffer object, so it is +the user responsibility to close down CL/GL buffers relationships by explicitly +calling unmapGLBuffer() function. +@param buffer - source Buffer object. +@param accessFlags - data access flags (ACCESS_READ|ACCESS_WRITE). +@return Returns UMat object + */ +CV_EXPORTS UMat mapGLBuffer(const Buffer& buffer, AccessFlag accessFlags = ACCESS_READ | ACCESS_WRITE); + +/** @brief Unmaps Buffer object (releases UMat, previously mapped from Buffer). + +Function must be called explicitly by the user for each UMat previously constructed +by the call to mapGLBuffer() function. +@param u - source UMat, created by mapGLBuffer(). + */ +CV_EXPORTS void unmapGLBuffer(UMat& u); + +//! @} +}} // namespace cv::ogl + +namespace cv { namespace cuda { + +/** @brief Sets a CUDA device and initializes it for the current thread with OpenGL interoperability. + +This function should be explicitly called after OpenGL context creation and before any CUDA calls. +@param device System index of a CUDA device starting with 0. +@ingroup core_opengl + */ +CV_EXPORTS void setGlDevice(int device = 0); + +}} + +//! @cond IGNORED + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +inline +cv::ogl::Buffer::Buffer(int arows, int acols, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ + create(arows, acols, atype, target, autoRelease); +} + +inline +cv::ogl::Buffer::Buffer(Size asize, int atype, Target target, bool autoRelease) : rows_(0), cols_(0), type_(0) +{ + create(asize, atype, target, autoRelease); +} + +inline +void cv::ogl::Buffer::create(Size asize, int atype, Target target, bool autoRelease) +{ + create(asize.height, asize.width, atype, target, autoRelease); +} + +inline +int cv::ogl::Buffer::rows() const +{ + return rows_; +} + +inline +int cv::ogl::Buffer::cols() const +{ + return cols_; +} + +inline +cv::Size cv::ogl::Buffer::size() const +{ + return Size(cols_, rows_); +} + +inline +bool cv::ogl::Buffer::empty() const +{ + return rows_ == 0 || cols_ == 0; +} + +inline +int cv::ogl::Buffer::type() const +{ + return type_; +} + +inline +int cv::ogl::Buffer::depth() const +{ + return CV_MAT_DEPTH(type_); +} + +inline +int cv::ogl::Buffer::channels() const +{ + return CV_MAT_CN(type_); +} + +inline +int cv::ogl::Buffer::elemSize() const +{ + return CV_ELEM_SIZE(type_); +} + +inline +int cv::ogl::Buffer::elemSize1() const +{ + return CV_ELEM_SIZE1(type_); +} + +/////// + +inline +cv::ogl::Texture2D::Texture2D(int arows, int acols, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ + create(arows, acols, aformat, autoRelease); +} + +inline +cv::ogl::Texture2D::Texture2D(Size asize, Format aformat, bool autoRelease) : rows_(0), cols_(0), format_(NONE) +{ + create(asize, aformat, autoRelease); +} + +inline +void cv::ogl::Texture2D::create(Size asize, Format aformat, bool autoRelease) +{ + create(asize.height, asize.width, aformat, autoRelease); +} + +inline +int cv::ogl::Texture2D::rows() const +{ + return rows_; +} + +inline +int cv::ogl::Texture2D::cols() const +{ + return cols_; +} + +inline +cv::Size cv::ogl::Texture2D::size() const +{ + return Size(cols_, rows_); +} + +inline +bool cv::ogl::Texture2D::empty() const +{ + return rows_ == 0 || cols_ == 0; +} + +inline +cv::ogl::Texture2D::Format cv::ogl::Texture2D::format() const +{ + return format_; +} + +/////// + +inline +cv::ogl::Arrays::Arrays() : size_(0) +{ +} + +inline +int cv::ogl::Arrays::size() const +{ + return size_; +} + +inline +bool cv::ogl::Arrays::empty() const +{ + return size_ == 0; +} + +//! @endcond + +#endif /* OPENCV_CORE_OPENGL_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/operations.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/operations.hpp new file mode 100755 index 0000000..92943a6 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/operations.hpp @@ -0,0 +1,594 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_OPERATIONS_HPP +#define OPENCV_CORE_OPERATIONS_HPP + +#ifndef __cplusplus +# error operations.hpp header must be compiled as C++ +#endif + +#include + +#if defined(__GNUC__) || defined(__clang__) // at least GCC 3.1+, clang 3.5+ +# if defined(__MINGW_PRINTF_FORMAT) // https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. +# define CV_FORMAT_PRINTF(string_idx, first_to_check) __attribute__ ((format (__MINGW_PRINTF_FORMAT, string_idx, first_to_check))) +# else +# define CV_FORMAT_PRINTF(string_idx, first_to_check) __attribute__ ((format (printf, string_idx, first_to_check))) +# endif +#else +# define CV_FORMAT_PRINTF(A, B) +#endif + +//! @cond IGNORED + +namespace cv +{ + +////////////////////////////// Matx methods depending on core API ///////////////////////////// + +namespace internal +{ + +template struct Matx_FastInvOp +{ + bool operator()(const Matx<_Tp, m, n>& a, Matx<_Tp, n, m>& b, int method) const + { + return invert(a, b, method) != 0; + } +}; + +template struct Matx_FastInvOp<_Tp, m, m> +{ + bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const + { + if (method == DECOMP_LU || method == DECOMP_CHOLESKY) + { + Matx<_Tp, m, m> temp = a; + + // assume that b is all 0's on input => make it a unity matrix + for (int i = 0; i < m; i++) + b(i, i) = (_Tp)1; + + if (method == DECOMP_CHOLESKY) + return Cholesky(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m); + + return LU(temp.val, m*sizeof(_Tp), m, b.val, m*sizeof(_Tp), m) != 0; + } + else + { + return invert(a, b, method) != 0; + } + } +}; + +template struct Matx_FastInvOp<_Tp, 2, 2> +{ + bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int /*method*/) const + { + _Tp d = (_Tp)determinant(a); + if (d == 0) + return false; + d = 1/d; + b(1,1) = a(0,0)*d; + b(0,0) = a(1,1)*d; + b(0,1) = -a(0,1)*d; + b(1,0) = -a(1,0)*d; + return true; + } +}; + +template struct Matx_FastInvOp<_Tp, 3, 3> +{ + bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int /*method*/) const + { + _Tp d = (_Tp)determinant(a); + if (d == 0) + return false; + d = 1/d; + b(0,0) = (a(1,1) * a(2,2) - a(1,2) * a(2,1)) * d; + b(0,1) = (a(0,2) * a(2,1) - a(0,1) * a(2,2)) * d; + b(0,2) = (a(0,1) * a(1,2) - a(0,2) * a(1,1)) * d; + + b(1,0) = (a(1,2) * a(2,0) - a(1,0) * a(2,2)) * d; + b(1,1) = (a(0,0) * a(2,2) - a(0,2) * a(2,0)) * d; + b(1,2) = (a(0,2) * a(1,0) - a(0,0) * a(1,2)) * d; + + b(2,0) = (a(1,0) * a(2,1) - a(1,1) * a(2,0)) * d; + b(2,1) = (a(0,1) * a(2,0) - a(0,0) * a(2,1)) * d; + b(2,2) = (a(0,0) * a(1,1) - a(0,1) * a(1,0)) * d; + return true; + } +}; + + +template struct Matx_FastSolveOp +{ + bool operator()(const Matx<_Tp, m, l>& a, const Matx<_Tp, m, n>& b, + Matx<_Tp, l, n>& x, int method) const + { + return cv::solve(a, b, x, method); + } +}; + +template struct Matx_FastSolveOp<_Tp, m, m, n> +{ + bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b, + Matx<_Tp, m, n>& x, int method) const + { + if (method == DECOMP_LU || method == DECOMP_CHOLESKY) + { + Matx<_Tp, m, m> temp = a; + x = b; + if( method == DECOMP_CHOLESKY ) + return Cholesky(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n); + + return LU(temp.val, m*sizeof(_Tp), m, x.val, n*sizeof(_Tp), n) != 0; + } + else + { + return cv::solve(a, b, x, method); + } + } +}; + +template struct Matx_FastSolveOp<_Tp, 2, 2, 1> +{ + bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b, + Matx<_Tp, 2, 1>& x, int) const + { + _Tp d = (_Tp)determinant(a); + if (d == 0) + return false; + d = 1/d; + x(0) = (b(0)*a(1,1) - b(1)*a(0,1))*d; + x(1) = (b(1)*a(0,0) - b(0)*a(1,0))*d; + return true; + } +}; + +template struct Matx_FastSolveOp<_Tp, 3, 3, 1> +{ + bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b, + Matx<_Tp, 3, 1>& x, int) const + { + _Tp d = (_Tp)determinant(a); + if (d == 0) + return false; + d = 1/d; + x(0) = d*(b(0)*(a(1,1)*a(2,2) - a(1,2)*a(2,1)) - + a(0,1)*(b(1)*a(2,2) - a(1,2)*b(2)) + + a(0,2)*(b(1)*a(2,1) - a(1,1)*b(2))); + + x(1) = d*(a(0,0)*(b(1)*a(2,2) - a(1,2)*b(2)) - + b(0)*(a(1,0)*a(2,2) - a(1,2)*a(2,0)) + + a(0,2)*(a(1,0)*b(2) - b(1)*a(2,0))); + + x(2) = d*(a(0,0)*(a(1,1)*b(2) - b(1)*a(2,1)) - + a(0,1)*(a(1,0)*b(2) - b(1)*a(2,0)) + + b(0)*(a(1,0)*a(2,1) - a(1,1)*a(2,0))); + return true; + } +}; + +} // internal + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::randu(_Tp a, _Tp b) +{ + Matx<_Tp,m,n> M; + cv::randu(M, Scalar(a), Scalar(b)); + return M; +} + +template inline +Matx<_Tp,m,n> Matx<_Tp,m,n>::randn(_Tp a, _Tp b) +{ + Matx<_Tp,m,n> M; + cv::randn(M, Scalar(a), Scalar(b)); + return M; +} + +template inline +Matx<_Tp, n, m> Matx<_Tp, m, n>::inv(int method, bool *p_is_ok /*= NULL*/) const +{ + Matx<_Tp, n, m> b; + bool ok = cv::internal::Matx_FastInvOp<_Tp, m, n>()(*this, b, method); + if (p_is_ok) *p_is_ok = ok; + return ok ? b : Matx<_Tp, n, m>::zeros(); +} + +template template inline +Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) const +{ + Matx<_Tp, n, l> x; + bool ok = cv::internal::Matx_FastSolveOp<_Tp, m, n, l>()(*this, rhs, x, method); + return ok ? x : Matx<_Tp, n, l>::zeros(); +} + + + +////////////////////////// Augmenting algebraic & logical operations ////////////////////////// + +#define CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \ + static inline A& operator op (A& a, const B& b) { cvop; return a; } + +#define CV_MAT_AUG_OPERATOR(op, cvop, A, B) \ + CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \ + CV_MAT_AUG_OPERATOR1(op, cvop, const A, B) + +#define CV_MAT_AUG_OPERATOR_T(op, cvop, A, B) \ + template CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \ + template CV_MAT_AUG_OPERATOR1(op, cvop, const A, B) + +#define CV_MAT_AUG_OPERATOR_TN(op, cvop, A) \ + template static inline A& operator op (A& a, const Matx<_Tp,m,n>& b) { cvop; return a; } \ + template static inline const A& operator op (const A& a, const Matx<_Tp,m,n>& b) { cvop; return a; } + +CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Mat) +CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Scalar) +CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat) +CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Scalar) +CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a,Mat(b),a), Mat) +CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a,Mat(b),a), Mat_<_Tp>) + +CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Mat) +CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Scalar) +CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat) +CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Scalar) +CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a,Mat(b),a), Mat) +CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a,Mat(b),a), Mat_<_Tp>) + +CV_MAT_AUG_OPERATOR (*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat, Mat) +CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat) +CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR (*=, a.convertTo(a, -1, b), Mat, double) +CV_MAT_AUG_OPERATOR_T(*=, a.convertTo(a, -1, b), Mat_<_Tp>, double) +CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat) +CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat_<_Tp>) + +CV_MAT_AUG_OPERATOR (/=, cv::divide(a,b,a), Mat, Mat) +CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat) +CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR (/=, a.convertTo((Mat&)a, -1, 1./b), Mat, double) +CV_MAT_AUG_OPERATOR_T(/=, a.convertTo((Mat&)a, -1, 1./b), Mat_<_Tp>, double) +CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), a), Mat_<_Tp>) + +CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Mat) +CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Scalar) +CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat) +CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Scalar) +CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), a), Mat_<_Tp>) + +CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Mat) +CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Scalar) +CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat) +CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Scalar) +CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), a), Mat_<_Tp>) + +CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Mat) +CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Scalar) +CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat) +CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Scalar) +CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat_<_Tp>) +CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), a), Mat) +CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), a), Mat_<_Tp>) + +#undef CV_MAT_AUG_OPERATOR_TN +#undef CV_MAT_AUG_OPERATOR_T +#undef CV_MAT_AUG_OPERATOR +#undef CV_MAT_AUG_OPERATOR1 + + + +///////////////////////////////////////////// SVD ///////////////////////////////////////////// + +inline SVD::SVD() {} +inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); } +inline void SVD::solveZ( InputArray m, OutputArray _dst ) +{ + Mat mtx = m.getMat(); + SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV)); + _dst.create(svd.vt.cols, 1, svd.vt.type()); + Mat dst = _dst.getMat(); + svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst); +} + +template inline void + SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt ) +{ + CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector."); + Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false); + SVD::compute(_a, _w, _u, _vt); + CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]); +} + +template inline void +SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w ) +{ + CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector."); + Mat _a(a, false), _w(w, false); + SVD::compute(_a, _w); + CV_Assert(_w.data == (uchar*)&w.val[0]); +} + +template inline void +SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u, + const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, + Matx<_Tp, n, nb>& dst ) +{ + CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector."); + Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false); + SVD::backSubst(_w, _u, _vt, _rhs, _dst); + CV_Assert(_dst.data == (uchar*)&dst.val[0]); +} + + + +/////////////////////////////////// Multiply-with-Carry RNG /////////////////////////////////// + +inline RNG::RNG() { state = 0xffffffff; } +inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; } + +inline RNG::operator uchar() { return (uchar)next(); } +inline RNG::operator schar() { return (schar)next(); } +inline RNG::operator ushort() { return (ushort)next(); } +inline RNG::operator short() { return (short)next(); } +inline RNG::operator int() { return (int)next(); } +inline RNG::operator unsigned() { return next(); } +inline RNG::operator float() { return next()*2.3283064365386962890625e-10f; } +inline RNG::operator double() { unsigned t = next(); return (((uint64)t << 32) | next()) * 5.4210108624275221700372640043497e-20; } + +inline unsigned RNG::operator ()(unsigned N) { return (unsigned)uniform(0,N); } +inline unsigned RNG::operator ()() { return next(); } + +inline int RNG::uniform(int a, int b) { return a == b ? a : (int)(next() % (b - a) + a); } +inline float RNG::uniform(float a, float b) { return ((float)*this)*(b - a) + a; } +inline double RNG::uniform(double a, double b) { return ((double)*this)*(b - a) + a; } + +inline bool RNG::operator ==(const RNG& other) const { return state == other.state; } + +inline unsigned RNG::next() +{ + state = (uint64)(unsigned)state* /*CV_RNG_COEFF*/ 4164903690U + (unsigned)(state >> 32); + return (unsigned)state; +} + +//! returns the next uniformly-distributed random number of the specified type +template static inline _Tp randu() +{ + return (_Tp)theRNG(); +} + +///////////////////////////////// Formatted string generation ///////////////////////////////// + +/** @brief Returns a text string formatted using the printf-like expression. + +The function acts like sprintf but forms and returns an STL string. It can be used to form an error +message in the Exception constructor. +@param fmt printf-compatible formatting specifiers. + +**Note**: +|Type|Specifier| +|-|-| +|`const char*`|`%s`| +|`char`|`%c`| +|`float` / `double`|`%f`,`%g`| +|`int`, `long`, `long long`|`%d`, `%ld`, ``%lld`| +|`unsigned`, `unsigned long`, `unsigned long long`|`%u`, `%lu`, `%llu`| +|`uint64` -> `uintmax_t`, `int64` -> `intmax_t`|`%ju`, `%jd`| +|`size_t`|`%zu`| + */ +CV_EXPORTS String format( const char* fmt, ... ) CV_FORMAT_PRINTF(1, 2); + +///////////////////////////////// Formatted output of cv::Mat ///////////////////////////////// + +static inline +Ptr format(InputArray mtx, Formatter::FormatType fmt) +{ + return Formatter::get(fmt)->format(mtx.getMat()); +} + +static inline +int print(Ptr fmtd, FILE* stream = stdout) +{ + int written = 0; + fmtd->reset(); + for(const char* str = fmtd->next(); str; str = fmtd->next()) + written += fputs(str, stream); + + return written; +} + +static inline +int print(const Mat& mtx, FILE* stream = stdout) +{ + return print(Formatter::get()->format(mtx), stream); +} + +static inline +int print(const UMat& mtx, FILE* stream = stdout) +{ + return print(Formatter::get()->format(mtx.getMat(ACCESS_READ)), stream); +} + +template static inline +int print(const std::vector >& vec, FILE* stream = stdout) +{ + return print(Formatter::get()->format(Mat(vec)), stream); +} + +template static inline +int print(const std::vector >& vec, FILE* stream = stdout) +{ + return print(Formatter::get()->format(Mat(vec)), stream); +} + +template static inline +int print(const Matx<_Tp, m, n>& matx, FILE* stream = stdout) +{ + return print(Formatter::get()->format(cv::Mat(matx)), stream); +} + +//! @endcond + +/****************************************************************************************\ +* Auxiliary algorithms * +\****************************************************************************************/ + +/** @brief Splits an element set into equivalency classes. + +The generic function partition implements an \f$O(N^2)\f$ algorithm for splitting a set of \f$N\f$ elements +into one or more equivalency classes, as described in + . The function returns the number of +equivalency classes. +@param _vec Set of elements stored as a vector. +@param labels Output vector of labels. It contains as many elements as vec. Each label labels[i] is +a 0-based cluster index of `vec[i]`. +@param predicate Equivalence predicate (pointer to a boolean function of two arguments or an +instance of the class that has the method bool operator()(const _Tp& a, const _Tp& b) ). The +predicate returns true when the elements are certainly in the same class, and returns false if they +may or may not be in the same class. +@ingroup core_cluster +*/ +template int +partition( const std::vector<_Tp>& _vec, std::vector& labels, + _EqPredicate predicate=_EqPredicate()) +{ + int i, j, N = (int)_vec.size(); + const _Tp* vec = &_vec[0]; + + const int PARENT=0; + const int RANK=1; + + std::vector _nodes(N*2); + int (*nodes)[2] = (int(*)[2])&_nodes[0]; + + // The first O(N) pass: create N single-vertex trees + for(i = 0; i < N; i++) + { + nodes[i][PARENT]=-1; + nodes[i][RANK] = 0; + } + + // The main O(N^2) pass: merge connected components + for( i = 0; i < N; i++ ) + { + int root = i; + + // find root + while( nodes[root][PARENT] >= 0 ) + root = nodes[root][PARENT]; + + for( j = 0; j < N; j++ ) + { + if( i == j || !predicate(vec[i], vec[j])) + continue; + int root2 = j; + + while( nodes[root2][PARENT] >= 0 ) + root2 = nodes[root2][PARENT]; + + if( root2 != root ) + { + // unite both trees + int rank = nodes[root][RANK], rank2 = nodes[root2][RANK]; + if( rank > rank2 ) + nodes[root2][PARENT] = root; + else + { + nodes[root][PARENT] = root2; + nodes[root2][RANK] += rank == rank2; + root = root2; + } + CV_Assert( nodes[root][PARENT] < 0 ); + + int k = j, parent; + + // compress the path from node2 to root + while( (parent = nodes[k][PARENT]) >= 0 ) + { + nodes[k][PARENT] = root; + k = parent; + } + + // compress the path from node to root + k = i; + while( (parent = nodes[k][PARENT]) >= 0 ) + { + nodes[k][PARENT] = root; + k = parent; + } + } + } + } + + // Final O(N) pass: enumerate classes + labels.resize(N); + int nclasses = 0; + + for( i = 0; i < N; i++ ) + { + int root = i; + while( nodes[root][PARENT] >= 0 ) + root = nodes[root][PARENT]; + // re-use the rank as the class label + if( nodes[root][RANK] >= 0 ) + nodes[root][RANK] = ~nclasses++; + labels[i] = ~nodes[root][RANK]; + } + + return nclasses; +} + +} // cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/optim.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/optim.hpp new file mode 100755 index 0000000..70e037f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/optim.hpp @@ -0,0 +1,302 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_OPTIM_HPP +#define OPENCV_OPTIM_HPP + +#include "opencv2/core.hpp" + +namespace cv +{ + +/** @addtogroup core_optim +The algorithms in this section minimize or maximize function value within specified constraints or +without any constraints. +@{ +*/ + +/** @brief Basic interface for all solvers + */ +class CV_EXPORTS MinProblemSolver : public Algorithm +{ +public: + /** @brief Represents function being optimized + */ + class CV_EXPORTS Function + { + public: + virtual ~Function() {} + virtual int getDims() const = 0; + virtual double getGradientEps() const; + virtual double calc(const double* x) const = 0; + virtual void getGradient(const double* x,double* grad); + }; + + /** @brief Getter for the optimized function. + + The optimized function is represented by Function interface, which requires derivatives to + implement the calc(double*) and getDim() methods to evaluate the function. + + @return Smart-pointer to an object that implements Function interface - it represents the + function that is being optimized. It can be empty, if no function was given so far. + */ + virtual Ptr getFunction() const = 0; + + /** @brief Setter for the optimized function. + + *It should be called at least once before the call to* minimize(), as default value is not usable. + + @param f The new function to optimize. + */ + virtual void setFunction(const Ptr& f) = 0; + + /** @brief Getter for the previously set terminal criteria for this algorithm. + + @return Deep copy of the terminal criteria used at the moment. + */ + virtual TermCriteria getTermCriteria() const = 0; + + /** @brief Set terminal criteria for solver. + + This method *is not necessary* to be called before the first call to minimize(), as the default + value is sensible. + + Algorithm stops when the number of function evaluations done exceeds termcrit.maxCount, when + the function values at the vertices of simplex are within termcrit.epsilon range or simplex + becomes so small that it can enclosed in a box with termcrit.epsilon sides, whatever comes + first. + @param termcrit Terminal criteria to be used, represented as cv::TermCriteria structure. + */ + virtual void setTermCriteria(const TermCriteria& termcrit) = 0; + + /** @brief actually runs the algorithm and performs the minimization. + + The sole input parameter determines the centroid of the starting simplex (roughly, it tells + where to start), all the others (terminal criteria, initial step, function to be minimized) are + supposed to be set via the setters before the call to this method or the default values (not + always sensible) will be used. + + @param x The initial point, that will become a centroid of an initial simplex. After the algorithm + will terminate, it will be set to the point where the algorithm stops, the point of possible + minimum. + @return The value of a function at the point found. + */ + virtual double minimize(InputOutputArray x) = 0; +}; + +/** @brief This class is used to perform the non-linear non-constrained minimization of a function, + +defined on an `n`-dimensional Euclidean space, using the **Nelder-Mead method**, also known as +**downhill simplex method**. The basic idea about the method can be obtained from +. + +It should be noted, that this method, although deterministic, is rather a heuristic and therefore +may converge to a local minima, not necessary a global one. It is iterative optimization technique, +which at each step uses an information about the values of a function evaluated only at `n+1` +points, arranged as a *simplex* in `n`-dimensional space (hence the second name of the method). At +each step new point is chosen to evaluate function at, obtained value is compared with previous +ones and based on this information simplex changes it's shape , slowly moving to the local minimum. +Thus this method is using *only* function values to make decision, on contrary to, say, Nonlinear +Conjugate Gradient method (which is also implemented in optim). + +Algorithm stops when the number of function evaluations done exceeds termcrit.maxCount, when the +function values at the vertices of simplex are within termcrit.epsilon range or simplex becomes so +small that it can enclosed in a box with termcrit.epsilon sides, whatever comes first, for some +defined by user positive integer termcrit.maxCount and positive non-integer termcrit.epsilon. + +@note DownhillSolver is a derivative of the abstract interface +cv::MinProblemSolver, which in turn is derived from the Algorithm interface and is used to +encapsulate the functionality, common to all non-linear optimization algorithms in the optim +module. + +@note term criteria should meet following condition: +@code + termcrit.type == (TermCriteria::MAX_ITER + TermCriteria::EPS) && termcrit.epsilon > 0 && termcrit.maxCount > 0 +@endcode + */ +class CV_EXPORTS DownhillSolver : public MinProblemSolver +{ +public: + /** @brief Returns the initial step that will be used in downhill simplex algorithm. + + @param step Initial step that will be used in algorithm. Note, that although corresponding setter + accepts column-vectors as well as row-vectors, this method will return a row-vector. + @see DownhillSolver::setInitStep + */ + virtual void getInitStep(OutputArray step) const=0; + + /** @brief Sets the initial step that will be used in downhill simplex algorithm. + + Step, together with initial point (givin in DownhillSolver::minimize) are two `n`-dimensional + vectors that are used to determine the shape of initial simplex. Roughly said, initial point + determines the position of a simplex (it will become simplex's centroid), while step determines the + spread (size in each dimension) of a simplex. To be more precise, if \f$s,x_0\in\mathbb{R}^n\f$ are + the initial step and initial point respectively, the vertices of a simplex will be: + \f$v_0:=x_0-\frac{1}{2} s\f$ and \f$v_i:=x_0+s_i\f$ for \f$i=1,2,\dots,n\f$ where \f$s_i\f$ denotes + projections of the initial step of *n*-th coordinate (the result of projection is treated to be + vector given by \f$s_i:=e_i\cdot\left\f$, where \f$e_i\f$ form canonical basis) + + @param step Initial step that will be used in algorithm. Roughly said, it determines the spread + (size in each dimension) of an initial simplex. + */ + virtual void setInitStep(InputArray step)=0; + + /** @brief This function returns the reference to the ready-to-use DownhillSolver object. + + All the parameters are optional, so this procedure can be called even without parameters at + all. In this case, the default values will be used. As default value for terminal criteria are + the only sensible ones, MinProblemSolver::setFunction() and DownhillSolver::setInitStep() + should be called upon the obtained object, if the respective parameters were not given to + create(). Otherwise, the two ways (give parameters to createDownhillSolver() or miss them out + and call the MinProblemSolver::setFunction() and DownhillSolver::setInitStep()) are absolutely + equivalent (and will drop the same errors in the same way, should invalid input be detected). + @param f Pointer to the function that will be minimized, similarly to the one you submit via + MinProblemSolver::setFunction. + @param initStep Initial step, that will be used to construct the initial simplex, similarly to the one + you submit via MinProblemSolver::setInitStep. + @param termcrit Terminal criteria to the algorithm, similarly to the one you submit via + MinProblemSolver::setTermCriteria. + */ + static Ptr create(const Ptr& f=Ptr(), + InputArray initStep=Mat_(1,1,0.0), + TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001)); +}; + +/** @brief This class is used to perform the non-linear non-constrained minimization of a function +with known gradient, + +defined on an *n*-dimensional Euclidean space, using the **Nonlinear Conjugate Gradient method**. +The implementation was done based on the beautifully clear explanatory article [An Introduction to +the Conjugate Gradient Method Without the Agonizing +Pain](http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf) by Jonathan Richard +Shewchuk. The method can be seen as an adaptation of a standard Conjugate Gradient method (see, for +example ) for numerically solving the +systems of linear equations. + +It should be noted, that this method, although deterministic, is rather a heuristic method and +therefore may converge to a local minima, not necessary a global one. What is even more disastrous, +most of its behaviour is ruled by gradient, therefore it essentially cannot distinguish between +local minima and maxima. Therefore, if it starts sufficiently near to the local maximum, it may +converge to it. Another obvious restriction is that it should be possible to compute the gradient of +a function at any point, thus it is preferable to have analytic expression for gradient and +computational burden should be born by the user. + +The latter responsibility is accomplished via the getGradient method of a +MinProblemSolver::Function interface (which represents function being optimized). This method takes +point a point in *n*-dimensional space (first argument represents the array of coordinates of that +point) and compute its gradient (it should be stored in the second argument as an array). + +@note class ConjGradSolver thus does not add any new methods to the basic MinProblemSolver interface. + +@note term criteria should meet following condition: +@code + termcrit.type == (TermCriteria::MAX_ITER + TermCriteria::EPS) && termcrit.epsilon > 0 && termcrit.maxCount > 0 + // or + termcrit.type == TermCriteria::MAX_ITER) && termcrit.maxCount > 0 +@endcode + */ +class CV_EXPORTS ConjGradSolver : public MinProblemSolver +{ +public: + /** @brief This function returns the reference to the ready-to-use ConjGradSolver object. + + All the parameters are optional, so this procedure can be called even without parameters at + all. In this case, the default values will be used. As default value for terminal criteria are + the only sensible ones, MinProblemSolver::setFunction() should be called upon the obtained + object, if the function was not given to create(). Otherwise, the two ways (submit it to + create() or miss it out and call the MinProblemSolver::setFunction()) are absolutely equivalent + (and will drop the same errors in the same way, should invalid input be detected). + @param f Pointer to the function that will be minimized, similarly to the one you submit via + MinProblemSolver::setFunction. + @param termcrit Terminal criteria to the algorithm, similarly to the one you submit via + MinProblemSolver::setTermCriteria. + */ + static Ptr create(const Ptr& f=Ptr(), + TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001)); +}; + +//! return codes for cv::solveLP() function +enum SolveLPResult +{ + SOLVELP_UNBOUNDED = -2, //!< problem is unbounded (target function can achieve arbitrary high values) + SOLVELP_UNFEASIBLE = -1, //!< problem is unfeasible (there are no points that satisfy all the constraints imposed) + SOLVELP_SINGLE = 0, //!< there is only one maximum for target function + SOLVELP_MULTI = 1 //!< there are multiple maxima for target function - the arbitrary one is returned +}; + +/** @brief Solve given (non-integer) linear programming problem using the Simplex Algorithm (Simplex Method). + +What we mean here by "linear programming problem" (or LP problem, for short) can be formulated as: + +\f[\mbox{Maximize } c\cdot x\\ + \mbox{Subject to:}\\ + Ax\leq b\\ + x\geq 0\f] + +Where \f$c\f$ is fixed `1`-by-`n` row-vector, \f$A\f$ is fixed `m`-by-`n` matrix, \f$b\f$ is fixed `m`-by-`1` +column vector and \f$x\f$ is an arbitrary `n`-by-`1` column vector, which satisfies the constraints. + +Simplex algorithm is one of many algorithms that are designed to handle this sort of problems +efficiently. Although it is not optimal in theoretical sense (there exist algorithms that can solve +any problem written as above in polynomial time, while simplex method degenerates to exponential +time for some special cases), it is well-studied, easy to implement and is shown to work well for +real-life purposes. + +The particular implementation is taken almost verbatim from **Introduction to Algorithms, third +edition** by T. H. Cormen, C. E. Leiserson, R. L. Rivest and Clifford Stein. In particular, the +Bland's rule is used to prevent cycling. + +@param Func This row-vector corresponds to \f$c\f$ in the LP problem formulation (see above). It should +contain 32- or 64-bit floating point numbers. As a convenience, column-vector may be also submitted, +in the latter case it is understood to correspond to \f$c^T\f$. +@param Constr `m`-by-`n+1` matrix, whose rightmost column corresponds to \f$b\f$ in formulation above +and the remaining to \f$A\f$. It should contain 32- or 64-bit floating point numbers. +@param z The solution will be returned here as a column-vector - it corresponds to \f$c\f$ in the +formulation above. It will contain 64-bit floating point numbers. +@return One of cv::SolveLPResult + */ +CV_EXPORTS_W int solveLP(InputArray Func, InputArray Constr, OutputArray z); + +//! @} + +}// cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/ovx.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/ovx.hpp new file mode 100755 index 0000000..8bb7d54 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/ovx.hpp @@ -0,0 +1,28 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +// Copyright (C) 2016, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. + +// OpenVX related definitions and declarations + +#pragma once +#ifndef OPENCV_OVX_HPP +#define OPENCV_OVX_HPP + +#include "cvdef.h" + +namespace cv +{ +/// Check if use of OpenVX is possible +CV_EXPORTS_W bool haveOpenVX(); + +/// Check if use of OpenVX is enabled +CV_EXPORTS_W bool useOpenVX(); + +/// Enable/disable use of OpenVX +CV_EXPORTS_W void setUseOpenVX(bool flag); +} // namespace cv + +#endif // OPENCV_OVX_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/persistence.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/persistence.hpp new file mode 100755 index 0000000..ba02d69 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/persistence.hpp @@ -0,0 +1,1333 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_PERSISTENCE_HPP +#define OPENCV_CORE_PERSISTENCE_HPP + +#ifndef CV_DOXYGEN +/// Define to support persistence legacy formats +#define CV__LEGACY_PERSISTENCE +#endif + +#ifndef __cplusplus +# error persistence.hpp header must be compiled as C++ +#endif + +//! @addtogroup core_c +//! @{ + +/** @brief "black box" representation of the file storage associated with a file on disk. + +Several functions that are described below take CvFileStorage\* as inputs and allow the user to +save or to load hierarchical collections that consist of scalar values, standard CXCore objects +(such as matrices, sequences, graphs), and user-defined objects. + +OpenCV can read and write data in XML (), YAML () or +JSON () formats. Below is an example of 3x3 floating-point identity matrix A, +stored in XML and YAML files +using CXCore functions: +XML: +@code{.xml} + + + + 3 + 3 +
    f
    + 1. 0. 0. 0. 1. 0. 0. 0. 1. + + +@endcode +YAML: +@code{.yaml} + %YAML:1.0 + A: !!opencv-matrix + rows: 3 + cols: 3 + dt: f + data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.] +@endcode +As it can be seen from the examples, XML uses nested tags to represent hierarchy, while YAML uses +indentation for that purpose (similar to the Python programming language). + +The same functions can read and write data in both formats; the particular format is determined by +the extension of the opened file, ".xml" for XML files, ".yml" or ".yaml" for YAML and ".json" for +JSON. + */ + +//! @} core_c + +#include "opencv2/core/types.hpp" +#include "opencv2/core/mat.hpp" + +namespace cv { + +/** @addtogroup core_xml + +XML/YAML/JSON file storages. {#xml_storage} +======================= +Writing to a file storage. +-------------------------- +You can store and then restore various OpenCV data structures to/from XML (), +YAML () or JSON () formats. Also, it is possible to store +and load arbitrarily complex data structures, which include OpenCV data structures, as well as +primitive data types (integer and floating-point numbers and text strings) as their elements. + +Use the following procedure to write something to XML, YAML or JSON: +-# Create new FileStorage and open it for writing. It can be done with a single call to +FileStorage::FileStorage constructor that takes a filename, or you can use the default constructor +and then call FileStorage::open. Format of the file (XML, YAML or JSON) is determined from the filename +extension (".xml", ".yml"/".yaml" and ".json", respectively) +-# Write all the data you want using the streaming operator `<<`, just like in the case of STL +streams. +-# Close the file using FileStorage::release. FileStorage destructor also closes the file. + +Here is an example: +@code + #include "opencv2/opencv.hpp" + #include + + using namespace cv; + + int main(int, char** argv) + { + FileStorage fs("test.yml", FileStorage::WRITE); + + fs << "frameCount" << 5; + time_t rawtime; time(&rawtime); + fs << "calibrationDate" << asctime(localtime(&rawtime)); + Mat cameraMatrix = (Mat_(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); + Mat distCoeffs = (Mat_(5,1) << 0.1, 0.01, -0.001, 0, 0); + fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs; + fs << "features" << "["; + for( int i = 0; i < 3; i++ ) + { + int x = rand() % 640; + int y = rand() % 480; + uchar lbp = rand() % 256; + + fs << "{:" << "x" << x << "y" << y << "lbp" << "[:"; + for( int j = 0; j < 8; j++ ) + fs << ((lbp >> j) & 1); + fs << "]" << "}"; + } + fs << "]"; + fs.release(); + return 0; + } +@endcode +The sample above stores to YML an integer, a text string (calibration date), 2 matrices, and a custom +structure "feature", which includes feature coordinates and LBP (local binary pattern) value. Here +is output of the sample: +@code{.yaml} +%YAML:1.0 +frameCount: 5 +calibrationDate: "Fri Jun 17 14:09:29 2011\n" +cameraMatrix: !!opencv-matrix + rows: 3 + cols: 3 + dt: d + data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ] +distCoeffs: !!opencv-matrix + rows: 5 + cols: 1 + dt: d + data: [ 1.0000000000000001e-01, 1.0000000000000000e-02, + -1.0000000000000000e-03, 0., 0. ] +features: + - { x:167, y:49, lbp:[ 1, 0, 0, 1, 1, 0, 1, 1 ] } + - { x:298, y:130, lbp:[ 0, 0, 0, 1, 0, 0, 1, 1 ] } + - { x:344, y:158, lbp:[ 1, 1, 0, 0, 0, 0, 1, 0 ] } +@endcode + +As an exercise, you can replace ".yml" with ".xml" or ".json" in the sample above and see, how the +corresponding XML file will look like. + +Several things can be noted by looking at the sample code and the output: + +- The produced YAML (and XML/JSON) consists of heterogeneous collections that can be nested. There are + 2 types of collections: named collections (mappings) and unnamed collections (sequences). In mappings + each element has a name and is accessed by name. This is similar to structures and std::map in + C/C++ and dictionaries in Python. In sequences elements do not have names, they are accessed by + indices. This is similar to arrays and std::vector in C/C++ and lists, tuples in Python. + "Heterogeneous" means that elements of each single collection can have different types. + + Top-level collection in YAML/XML/JSON is a mapping. Each matrix is stored as a mapping, and the matrix + elements are stored as a sequence. Then, there is a sequence of features, where each feature is + represented a mapping, and lbp value in a nested sequence. + +- When you write to a mapping (a structure), you write element name followed by its value. When you + write to a sequence, you simply write the elements one by one. OpenCV data structures (such as + cv::Mat) are written in absolutely the same way as simple C data structures - using `<<` + operator. + +- To write a mapping, you first write the special string `{` to the storage, then write the + elements as pairs (`fs << << `) and then write the closing + `}`. + +- To write a sequence, you first write the special string `[`, then write the elements, then + write the closing `]`. + +- In YAML/JSON (but not XML), mappings and sequences can be written in a compact Python-like inline + form. In the sample above matrix elements, as well as each feature, including its lbp value, is + stored in such inline form. To store a mapping/sequence in a compact form, put `:` after the + opening character, e.g. use `{:` instead of `{` and `[:` instead of `[`. When the + data is written to XML, those extra `:` are ignored. + +Reading data from a file storage. +--------------------------------- +To read the previously written XML, YAML or JSON file, do the following: +-# Open the file storage using FileStorage::FileStorage constructor or FileStorage::open method. + In the current implementation the whole file is parsed and the whole representation of file + storage is built in memory as a hierarchy of file nodes (see FileNode) + +-# Read the data you are interested in. Use FileStorage::operator [], FileNode::operator [] + and/or FileNodeIterator. + +-# Close the storage using FileStorage::release. + +Here is how to read the file created by the code sample above: +@code + FileStorage fs2("test.yml", FileStorage::READ); + + // first method: use (type) operator on FileNode. + int frameCount = (int)fs2["frameCount"]; + + String date; + // second method: use FileNode::operator >> + fs2["calibrationDate"] >> date; + + Mat cameraMatrix2, distCoeffs2; + fs2["cameraMatrix"] >> cameraMatrix2; + fs2["distCoeffs"] >> distCoeffs2; + + cout << "frameCount: " << frameCount << endl + << "calibration date: " << date << endl + << "camera matrix: " << cameraMatrix2 << endl + << "distortion coeffs: " << distCoeffs2 << endl; + + FileNode features = fs2["features"]; + FileNodeIterator it = features.begin(), it_end = features.end(); + int idx = 0; + std::vector lbpval; + + // iterate through a sequence using FileNodeIterator + for( ; it != it_end; ++it, idx++ ) + { + cout << "feature #" << idx << ": "; + cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: ("; + // you can also easily read numerical arrays using FileNode >> std::vector operator. + (*it)["lbp"] >> lbpval; + for( int i = 0; i < (int)lbpval.size(); i++ ) + cout << " " << (int)lbpval[i]; + cout << ")" << endl; + } + fs2.release(); +@endcode + +Format specification {#format_spec} +-------------------- +`([count]{u|c|w|s|i|f|d})`... where the characters correspond to fundamental C++ types: +- `u` 8-bit unsigned number +- `c` 8-bit signed number +- `w` 16-bit unsigned number +- `s` 16-bit signed number +- `i` 32-bit signed number +- `f` single precision floating-point number +- `d` double precision floating-point number +- `r` pointer, 32 lower bits of which are written as a signed integer. The type can be used to + store structures with links between the elements. + +`count` is the optional counter of values of a given type. For example, `2if` means that each array +element is a structure of 2 integers, followed by a single-precision floating-point number. The +equivalent notations of the above specification are `iif`, `2i1f` and so forth. Other examples: `u` +means that the array consists of bytes, and `2d` means the array consists of pairs of doubles. + +@see @ref samples/cpp/filestorage.cpp +*/ + +//! @{ + +/** @example samples/cpp/filestorage.cpp +A complete example using the FileStorage interface +*/ + +////////////////////////// XML & YAML I/O ////////////////////////// + +class CV_EXPORTS FileNode; +class CV_EXPORTS FileNodeIterator; + +/** @brief XML/YAML/JSON file storage class that encapsulates all the information necessary for writing or +reading data to/from a file. + */ +class CV_EXPORTS_W FileStorage +{ +public: + //! file storage mode + enum Mode + { + READ = 0, //!< value, open the file for reading + WRITE = 1, //!< value, open the file for writing + APPEND = 2, //!< value, open the file for appending + MEMORY = 4, //!< flag, read data from source or write data to the internal buffer (which is + //!< returned by FileStorage::release) + FORMAT_MASK = (7<<3), //!< mask for format flags + FORMAT_AUTO = 0, //!< flag, auto format + FORMAT_XML = (1<<3), //!< flag, XML format + FORMAT_YAML = (2<<3), //!< flag, YAML format + FORMAT_JSON = (3<<3), //!< flag, JSON format + + BASE64 = 64, //!< flag, write rawdata in Base64 by default. (consider using WRITE_BASE64) + WRITE_BASE64 = BASE64 | WRITE, //!< flag, enable both WRITE and BASE64 + }; + enum State + { + UNDEFINED = 0, + VALUE_EXPECTED = 1, + NAME_EXPECTED = 2, + INSIDE_MAP = 4 + }; + + /** @brief The constructors. + + The full constructor opens the file. Alternatively you can use the default constructor and then + call FileStorage::open. + */ + CV_WRAP FileStorage(); + + /** @overload + @copydoc open() + */ + CV_WRAP FileStorage(const String& filename, int flags, const String& encoding=String()); + + //! the destructor. calls release() + virtual ~FileStorage(); + + /** @brief Opens a file. + + See description of parameters in FileStorage::FileStorage. The method calls FileStorage::release + before opening the file. + @param filename Name of the file to open or the text string to read the data from. + Extension of the file (.xml, .yml/.yaml or .json) determines its format (XML, YAML or JSON + respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both + FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify + the output file format (e.g. mydata.xml, .yml etc.). A file name can also contain parameters. + You can use this format, "*?base64" (e.g. "file.json?base64" (case sensitive)), as an alternative to + FileStorage::BASE64 flag. + @param flags Mode of operation. One of FileStorage::Mode + @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and + you should use 8-bit encoding instead of it. + */ + CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String()); + + /** @brief Checks whether the file is opened. + + @returns true if the object is associated with the current file and false otherwise. It is a + good practice to call this method after you tried to open a file. + */ + CV_WRAP virtual bool isOpened() const; + + /** @brief Closes the file and releases all the memory buffers. + + Call this method after all I/O operations with the storage are finished. + */ + CV_WRAP virtual void release(); + + /** @brief Closes the file and releases all the memory buffers. + + Call this method after all I/O operations with the storage are finished. If the storage was + opened for writing data and FileStorage::WRITE was specified + */ + CV_WRAP virtual String releaseAndGetString(); + + /** @brief Returns the first element of the top-level mapping. + @returns The first element of the top-level mapping. + */ + CV_WRAP FileNode getFirstTopLevelNode() const; + + /** @brief Returns the top-level mapping + @param streamidx Zero-based index of the stream. In most cases there is only one stream in the file. + However, YAML supports multiple streams and so there can be several. + @returns The top-level mapping. + */ + CV_WRAP FileNode root(int streamidx=0) const; + + /** @brief Returns the specified element of the top-level mapping. + @param nodename Name of the file node. + @returns Node with the given name. + */ + FileNode operator[](const String& nodename) const; + + /** @overload */ + CV_WRAP_AS(getNode) FileNode operator[](const char* nodename) const; + + /** + * @brief Simplified writing API to use with bindings. + * @param name Name of the written object + * @param val Value of the written object + */ + CV_WRAP void write(const String& name, int val); + /// @overload + CV_WRAP void write(const String& name, double val); + /// @overload + CV_WRAP void write(const String& name, const String& val); + /// @overload + CV_WRAP void write(const String& name, const Mat& val); + /// @overload + CV_WRAP void write(const String& name, const std::vector& val); + + /** @brief Writes multiple numbers. + + Writes one or more numbers of the specified format to the currently written structure. Usually it is + more convenient to use operator `<<` instead of this method. + @param fmt Specification of each array element, see @ref format_spec "format specification" + @param vec Pointer to the written array. + @param len Number of the uchar elements to write. + */ + void writeRaw( const String& fmt, const void* vec, size_t len ); + + /** @brief Writes a comment. + + The function writes a comment into file storage. The comments are skipped when the storage is read. + @param comment The written comment, single-line or multi-line + @param append If true, the function tries to put the comment at the end of current line. + Else 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. + */ + CV_WRAP void writeComment(const String& comment, bool append = false); + + void startWriteStruct(const String& name, int flags, const String& typeName); + void endWriteStruct(); + + /** @brief Returns the normalized object name for the specified name of a file. + @param filename Name of a file + @returns The normalized object name. + */ + static String getDefaultObjectName(const String& filename); + + /** @brief Returns the current format. + * @returns The current format, see FileStorage::Mode + */ + CV_WRAP int getFormat() const; + + int state; + std::string elname; + + class Impl; + Ptr p; +}; + +/** @brief File Storage Node class. + +The node is used to store each and every element of the file storage opened for reading. When +XML/YAML file is read, it is first parsed and stored in the memory as a hierarchical collection of +nodes. Each node can be a "leaf" that is contain a single number or a string, or be a collection of +other nodes. There can be named collections (mappings) where each element has a name and it is +accessed by a name, and ordered collections (sequences) where elements do not have names but rather +accessed by index. Type of the file node can be determined using FileNode::type method. + +Note that file nodes are only used for navigating file storages opened for reading. When a file +storage is opened for writing, no data is stored in memory after it is written. + */ +class CV_EXPORTS_W_SIMPLE FileNode +{ +public: + //! type of the file storage node + enum + { + NONE = 0, //!< empty node + INT = 1, //!< an integer + REAL = 2, //!< floating-point number + FLOAT = REAL, //!< synonym or REAL + STR = 3, //!< text string in UTF-8 encoding + STRING = STR, //!< synonym for STR + SEQ = 4, //!< sequence + MAP = 5, //!< mapping + TYPE_MASK = 7, + + FLOW = 8, //!< compact representation of a sequence or mapping. Used only by YAML writer + UNIFORM = 8, //!< if set, means that all the collection elements are numbers of the same type (real's or int's). + //!< UNIFORM is used only when reading FileStorage; FLOW is used only when writing. So they share the same bit + EMPTY = 16, //!< empty structure (sequence or mapping) + NAMED = 32 //!< the node has a name (i.e. it is element of a mapping). + }; + /** @brief The constructors. + + These constructors are used to create a default file node, construct it from obsolete structures or + from the another file node. + */ + CV_WRAP FileNode(); + + /** @overload + @param fs Pointer to the file storage structure. + @param blockIdx Index of the memory block where the file node is stored + @param ofs Offset in bytes from the beginning of the serialized storage + */ + FileNode(const FileStorage* fs, size_t blockIdx, size_t ofs); + + /** @overload + @param node File node to be used as initialization for the created file node. + */ + FileNode(const FileNode& node); + + /** @brief Returns element of a mapping node or a sequence node. + @param nodename Name of an element in the mapping node. + @returns Returns the element with the given identifier. + */ + FileNode operator[](const String& nodename) const; + + /** @overload + @param nodename Name of an element in the mapping node. + */ + CV_WRAP_AS(getNode) FileNode operator[](const char* nodename) const; + + /** @overload + @param i Index of an element in the sequence node. + */ + CV_WRAP_AS(at) FileNode operator[](int i) const; + + /** @brief Returns keys of a mapping node. + @returns Keys of a mapping node. + */ + CV_WRAP std::vector keys() const; + + /** @brief Returns type of the node. + @returns Type of the node. See FileNode::Type + */ + CV_WRAP int type() const; + + //! returns true if the node is empty + CV_WRAP bool empty() const; + //! returns true if the node is a "none" object + CV_WRAP bool isNone() const; + //! returns true if the node is a sequence + CV_WRAP bool isSeq() const; + //! returns true if the node is a mapping + CV_WRAP bool isMap() const; + //! returns true if the node is an integer + CV_WRAP bool isInt() const; + //! returns true if the node is a floating-point number + CV_WRAP bool isReal() const; + //! returns true if the node is a text string + CV_WRAP bool isString() const; + //! returns true if the node has a name + CV_WRAP bool isNamed() const; + //! returns the node name or an empty string if the node is nameless + CV_WRAP std::string name() const; + //! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise. + CV_WRAP size_t size() const; + //! returns raw size of the FileNode in bytes + CV_WRAP size_t rawSize() const; + //! returns the node content as an integer. If the node stores floating-point number, it is rounded. + operator int() const; + //! returns the node content as float + operator float() const; + //! returns the node content as double + operator double() const; + //! returns the node content as text string + inline operator std::string() const { return this->string(); } + + static bool isMap(int flags); + static bool isSeq(int flags); + static bool isCollection(int flags); + static bool isEmptyCollection(int flags); + static bool isFlow(int flags); + + uchar* ptr(); + const uchar* ptr() const; + + //! returns iterator pointing to the first node element + FileNodeIterator begin() const; + //! returns iterator pointing to the element following the last node element + FileNodeIterator end() const; + + /** @brief Reads node elements to the buffer with the specified format. + + Usually it is more convenient to use operator `>>` instead of this method. + @param fmt Specification of each array element. See @ref format_spec "format specification" + @param vec Pointer to the destination array. + @param len Number of elements to read. If it is greater than number of remaining elements then all + of them will be read. + */ + void readRaw( const String& fmt, void* vec, size_t len ) const; + + /** Internal method used when reading FileStorage. + Sets the type (int, real or string) and value of the previously created node. + */ + void setValue( int type, const void* value, int len=-1 ); + + //! Simplified reading API to use with bindings. + CV_WRAP double real() const; + //! Simplified reading API to use with bindings. + CV_WRAP std::string string() const; + //! Simplified reading API to use with bindings. + CV_WRAP Mat mat() const; + + //protected: + const FileStorage* fs; + size_t blockIdx; + size_t ofs; +}; + + +/** @brief 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. + */ +class CV_EXPORTS FileNodeIterator +{ +public: + /** @brief The constructors. + + These constructors are used to create a default iterator, set it to specific element in a file node + or construct it from another iterator. + */ + FileNodeIterator(); + + /** @overload + @param node File node - the collection to iterate over; + it can be a scalar (equivalent to 1-element collection) or "none" (equivalent to empty collection). + @param seekEnd - true if iterator needs to be set after the last element of the node; + that is: + * node.begin() => FileNodeIterator(node, false) + * node.end() => FileNodeIterator(node, true) + */ + FileNodeIterator(const FileNode& node, bool seekEnd); + + /** @overload + @param it Iterator to be used as initialization for the created iterator. + */ + FileNodeIterator(const FileNodeIterator& it); + + //! returns the currently observed element + FileNode operator *() const; + + //! moves iterator to the next node + FileNodeIterator& operator ++ (); + //! moves iterator to the next node + FileNodeIterator operator ++ (int); + //! moves iterator forward by the specified offset (possibly negative) + FileNodeIterator& operator += (int ofs); + + /** @brief Reads node elements to the buffer with the specified format. + + Usually it is more convenient to use operator `>>` instead of this method. + @param fmt Specification of each array element. See @ref format_spec "format specification" + @param vec Pointer to the destination array. + @param maxCount Number of elements to read. If it is greater than number of remaining elements then + all of them will be read. + */ + FileNodeIterator& readRaw( const String& fmt, void* vec, + size_t maxCount=(size_t)INT_MAX ); + + //! returns the number of remaining (not read yet) elements + size_t remaining() const; + + bool equalTo(const FileNodeIterator& it) const; + +protected: + const FileStorage* fs; + size_t blockIdx; + size_t ofs; + size_t blockSize; + size_t nodeNElems; + size_t idx; +}; + +//! @} core_xml + +/////////////////// XML & YAML I/O implementation ////////////////// + +//! @relates cv::FileStorage +//! @{ + +CV_EXPORTS void write( FileStorage& fs, const String& name, int value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, float value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, double value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value ); +CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value ); +#ifdef CV__LEGACY_PERSISTENCE +CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector& value); +CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector& value); +#endif + +CV_EXPORTS void writeScalar( FileStorage& fs, int value ); +CV_EXPORTS void writeScalar( FileStorage& fs, float value ); +CV_EXPORTS void writeScalar( FileStorage& fs, double value ); +CV_EXPORTS void writeScalar( FileStorage& fs, const String& value ); + +//! @} + +//! @relates cv::FileNode +//! @{ + +CV_EXPORTS void read(const FileNode& node, int& value, int default_value); +CV_EXPORTS void read(const FileNode& node, float& value, float default_value); +CV_EXPORTS void read(const FileNode& node, double& value, double default_value); +CV_EXPORTS void read(const FileNode& node, std::string& value, const std::string& default_value); +CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() ); +CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() ); +#ifdef CV__LEGACY_PERSISTENCE +CV_EXPORTS void read(const FileNode& node, std::vector& keypoints); +CV_EXPORTS void read(const FileNode& node, std::vector& matches); +#endif +CV_EXPORTS void read(const FileNode& node, KeyPoint& value, const KeyPoint& default_value); +CV_EXPORTS void read(const FileNode& node, DMatch& value, const DMatch& default_value); + +template static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value) +{ + std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; + value = temp.size() != 2 ? default_value : Point_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); +} + +template static inline void read(const FileNode& node, Point3_<_Tp>& value, const Point3_<_Tp>& default_value) +{ + std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; + value = temp.size() != 3 ? default_value : Point3_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), + saturate_cast<_Tp>(temp[2])); +} + +template static inline void read(const FileNode& node, Size_<_Tp>& value, const Size_<_Tp>& default_value) +{ + std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; + value = temp.size() != 2 ? default_value : Size_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); +} + +template static inline void read(const FileNode& node, Complex<_Tp>& value, const Complex<_Tp>& default_value) +{ + std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; + value = temp.size() != 2 ? default_value : Complex<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1])); +} + +template static inline void read(const FileNode& node, Rect_<_Tp>& value, const Rect_<_Tp>& default_value) +{ + std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; + value = temp.size() != 4 ? default_value : Rect_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), + saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3])); +} + +template static inline void read(const FileNode& node, Vec<_Tp, cn>& value, const Vec<_Tp, cn>& default_value) +{ + std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; + value = temp.size() != cn ? default_value : Vec<_Tp, cn>(&temp[0]); +} + +template static inline void read(const FileNode& node, Matx<_Tp, m, n>& value, const Matx<_Tp, m, n>& default_matx = Matx<_Tp, m, n>()) +{ + Mat temp; + read(node, temp); // read as a Mat class + + if (temp.empty()) + value = default_matx; + else + value = Matx<_Tp, m, n>(temp); +} + +template static inline void read(const FileNode& node, Scalar_<_Tp>& value, const Scalar_<_Tp>& default_value) +{ + std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp; + value = temp.size() != 4 ? default_value : Scalar_<_Tp>(saturate_cast<_Tp>(temp[0]), saturate_cast<_Tp>(temp[1]), + saturate_cast<_Tp>(temp[2]), saturate_cast<_Tp>(temp[3])); +} + +static inline void read(const FileNode& node, Range& value, const Range& default_value) +{ + Point2i temp(value.start, value.end); const Point2i default_temp = Point2i(default_value.start, default_value.end); + read(node, temp, default_temp); + value.start = temp.x; value.end = temp.y; +} + +//! @} + +/** @brief Writes string to a file storage. +@relates cv::FileStorage + */ +CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str); + +//! @cond IGNORED + +namespace internal +{ + class CV_EXPORTS WriteStructContext + { + public: + WriteStructContext(FileStorage& _fs, const String& name, int flags, const String& typeName = String()); + ~WriteStructContext(); + private: + FileStorage* fs; + }; + + template class VecWriterProxy + { + public: + VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} + void operator()(const std::vector<_Tp>& vec) const + { + size_t count = vec.size(); + for (size_t i = 0; i < count; i++) + write(*fs, vec[i]); + } + private: + FileStorage* fs; + }; + + template class VecWriterProxy<_Tp, 1> + { + public: + VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} + void operator()(const std::vector<_Tp>& vec) const + { + int _fmt = traits::SafeFmt<_Tp>::fmt; + char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' }; + fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp)); + } + private: + FileStorage* fs; + }; + + template class VecReaderProxy + { + public: + VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} + void operator()(std::vector<_Tp>& vec, size_t count) const + { + count = std::min(count, it->remaining()); + vec.resize(count); + for (size_t i = 0; i < count; i++, ++(*it)) + read(**it, vec[i], _Tp()); + } + private: + FileNodeIterator* it; + }; + + template class VecReaderProxy<_Tp, 1> + { + public: + VecReaderProxy( FileNodeIterator* _it ) : it(_it) {} + void operator()(std::vector<_Tp>& vec, size_t count) const + { + size_t remaining = it->remaining(); + size_t cn = DataType<_Tp>::channels; + int _fmt = traits::SafeFmt<_Tp>::fmt; + CV_Assert((_fmt >> 8) < 9); + char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' }; + CV_Assert((remaining % cn) == 0); + size_t remaining1 = remaining / cn; + count = count > remaining1 ? remaining1 : count; + vec.resize(count); + it->readRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp)); + } + private: + FileNodeIterator* it; + }; + +} // internal + +//! @endcond + +//! @relates cv::FileStorage +//! @{ + +template static inline +void write(FileStorage& fs, const _Tp& value) +{ + write(fs, String(), value); +} + +template<> inline +void write( FileStorage& fs, const int& value ) +{ + writeScalar(fs, value); +} + +template<> inline +void write( FileStorage& fs, const float& value ) +{ + writeScalar(fs, value); +} + +template<> inline +void write( FileStorage& fs, const double& value ) +{ + writeScalar(fs, value); +} + +template<> inline +void write( FileStorage& fs, const String& value ) +{ + writeScalar(fs, value); +} + +template static inline +void write(FileStorage& fs, const Point_<_Tp>& pt ) +{ + write(fs, pt.x); + write(fs, pt.y); +} + +template static inline +void write(FileStorage& fs, const Point3_<_Tp>& pt ) +{ + write(fs, pt.x); + write(fs, pt.y); + write(fs, pt.z); +} + +template static inline +void write(FileStorage& fs, const Size_<_Tp>& sz ) +{ + write(fs, sz.width); + write(fs, sz.height); +} + +template static inline +void write(FileStorage& fs, const Complex<_Tp>& c ) +{ + write(fs, c.re); + write(fs, c.im); +} + +template static inline +void write(FileStorage& fs, const Rect_<_Tp>& r ) +{ + write(fs, r.x); + write(fs, r.y); + write(fs, r.width); + write(fs, r.height); +} + +template static inline +void write(FileStorage& fs, const Vec<_Tp, cn>& v ) +{ + for(int i = 0; i < cn; i++) + write(fs, v.val[i]); +} + +template static inline +void write(FileStorage& fs, const Matx<_Tp, m, n>& x ) +{ + write(fs, Mat(x)); // write as a Mat class +} + +template static inline +void write(FileStorage& fs, const Scalar_<_Tp>& s ) +{ + write(fs, s.val[0]); + write(fs, s.val[1]); + write(fs, s.val[2]); + write(fs, s.val[3]); +} + +static inline +void write(FileStorage& fs, const Range& r ) +{ + write(fs, r.start); + write(fs, r.end); +} + +template static inline +void write( FileStorage& fs, const std::vector<_Tp>& vec ) +{ + cv::internal::VecWriterProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> w(&fs); + w(vec); +} + +template static inline +void write(FileStorage& fs, const String& name, const Point_<_Tp>& pt ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, pt); +} + +template static inline +void write(FileStorage& fs, const String& name, const Point3_<_Tp>& pt ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, pt); +} + +template static inline +void write(FileStorage& fs, const String& name, const Size_<_Tp>& sz ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, sz); +} + +template static inline +void write(FileStorage& fs, const String& name, const Complex<_Tp>& c ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, c); +} + +template static inline +void write(FileStorage& fs, const String& name, const Rect_<_Tp>& r ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, r); +} + +template static inline +void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, v); +} + +template static inline +void write(FileStorage& fs, const String& name, const Matx<_Tp, m, n>& x ) +{ + write(fs, name, Mat(x)); // write as a Mat class +} + +template static inline +void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, s); +} + +static inline +void write(FileStorage& fs, const String& name, const Range& r ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, r); +} + +static inline +void write(FileStorage& fs, const String& name, const KeyPoint& kpt) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, kpt.pt.x); + write(fs, kpt.pt.y); + write(fs, kpt.size); + write(fs, kpt.angle); + write(fs, kpt.response); + write(fs, kpt.octave); + write(fs, kpt.class_id); +} + +static inline +void write(FileStorage& fs, const String& name, const DMatch& m) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); + write(fs, m.queryIdx); + write(fs, m.trainIdx); + write(fs, m.imgIdx); + write(fs, m.distance); +} + +template::value >::type* = nullptr> +static inline void write( FileStorage& fs, const String& name, const _Tp& val ) +{ + write(fs, name, static_cast(val)); +} + +template static inline +void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(traits::SafeFmt<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); + write(fs, vec); +} + +template static inline +void write( FileStorage& fs, const String& name, const std::vector< std::vector<_Tp> >& vec ) +{ + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ); + for(size_t i = 0; i < vec.size(); i++) + { + cv::internal::WriteStructContext ws_(fs, name, FileNode::SEQ+(traits::SafeFmt<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); + write(fs, vec[i]); + } +} + +#ifdef CV__LEGACY_PERSISTENCE +// This code is not needed anymore, but it is preserved here to keep source compatibility +// Implementation is similar to templates instantiations +static inline void write(FileStorage& fs, const KeyPoint& kpt) { write(fs, String(), kpt); } +static inline void write(FileStorage& fs, const DMatch& m) { write(fs, String(), m); } +static inline void write(FileStorage& fs, const std::vector& vec) +{ + cv::internal::VecWriterProxy w(&fs); + w(vec); +} +static inline void write(FileStorage& fs, const std::vector& vec) +{ + cv::internal::VecWriterProxy w(&fs); + w(vec); + +} +#endif + +//! @} FileStorage + +//! @relates cv::FileNode +//! @{ + +static inline +void read(const FileNode& node, bool& value, bool default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = temp != 0; +} + +static inline +void read(const FileNode& node, uchar& value, uchar default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline +void read(const FileNode& node, schar& value, schar default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline +void read(const FileNode& node, ushort& value, ushort default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +static inline +void read(const FileNode& node, short& value, short default_value) +{ + int temp; + read(node, temp, (int)default_value); + value = saturate_cast(temp); +} + +template static inline +void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX ) +{ + cv::internal::VecReaderProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> r(&it); + r(vec, maxCount); +} + +template::value >::type* = nullptr> +static inline void read(const FileNode& node, _Tp& value, const _Tp& default_value = static_cast<_Tp>(0)) +{ + int temp; + read(node, temp, static_cast(default_value)); + value = static_cast<_Tp>(temp); +} + +template static inline +void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() ) +{ + if(node.empty()) + vec = default_value; + else + { + FileNodeIterator it = node.begin(); + read( it, vec ); + } +} + +static inline +void read( const FileNode& node, std::vector& vec, const std::vector& default_value ) +{ + if(node.empty()) + vec = default_value; + else + read(node, vec); +} + +static inline +void read( const FileNode& node, std::vector& vec, const std::vector& default_value ) +{ + if(node.empty()) + vec = default_value; + else + read(node, vec); +} + +//! @} FileNode + +//! @relates cv::FileStorage +//! @{ + +/** @brief Writes data to a file storage. + */ +template static inline +FileStorage& operator << (FileStorage& fs, const _Tp& value) +{ + if( !fs.isOpened() ) + return fs; + if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP ) + CV_Error( Error::StsError, "No element name has been given" ); + write( fs, fs.elname, value ); + if( fs.state & FileStorage::INSIDE_MAP ) + fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP; + return fs; +} + +/** @brief Writes data to a file storage. + */ +static inline +FileStorage& operator << (FileStorage& fs, const char* str) +{ + return (fs << String(str)); +} + +/** @brief Writes data to a file storage. + */ +static inline +FileStorage& operator << (FileStorage& fs, char* value) +{ + return (fs << String(value)); +} + +//! @} FileStorage + +//! @relates cv::FileNodeIterator +//! @{ + +/** @brief Reads data from a file storage. + */ +template static inline +FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value) +{ + read( *it, value, _Tp()); + return ++it; +} + +/** @brief Reads data from a file storage. + */ +template static inline +FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec) +{ + cv::internal::VecReaderProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> r(&it); + r(vec, (size_t)INT_MAX); + return it; +} + +//! @} FileNodeIterator + +//! @relates cv::FileNode +//! @{ + +/** @brief Reads data from a file storage. + */ +template static inline +void operator >> (const FileNode& n, _Tp& value) +{ + read( n, value, _Tp()); +} + +/** @brief Reads data from a file storage. + */ +template static inline +void operator >> (const FileNode& n, std::vector<_Tp>& vec) +{ + FileNodeIterator it = n.begin(); + it >> vec; +} + +/** @brief Reads KeyPoint from a file storage. +*/ +//It needs special handling because it contains two types of fields, int & float. +static inline +void operator >> (const FileNode& n, KeyPoint& kpt) +{ + FileNodeIterator it = n.begin(); + it >> kpt.pt.x >> kpt.pt.y >> kpt.size >> kpt.angle >> kpt.response >> kpt.octave >> kpt.class_id; +} + +#ifdef CV__LEGACY_PERSISTENCE +static inline +void operator >> (const FileNode& n, std::vector& vec) +{ + read(n, vec); +} +static inline +void operator >> (const FileNode& n, std::vector& vec) +{ + read(n, vec); +} +#endif + +/** @brief Reads DMatch from a file storage. +*/ +//It needs special handling because it contains two types of fields, int & float. +static inline +void operator >> (const FileNode& n, DMatch& m) +{ + FileNodeIterator it = n.begin(); + it >> m.queryIdx >> m.trainIdx >> m.imgIdx >> m.distance; +} + +//! @} FileNode + +//! @relates cv::FileNodeIterator +//! @{ + +CV_EXPORTS bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2); +CV_EXPORTS bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2); + +static inline +ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it2.remaining() - it1.remaining(); +} + +static inline +bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2) +{ + return it1.remaining() > it2.remaining(); +} + +//! @} FileNodeIterator + +} // cv + +#endif // OPENCV_CORE_PERSISTENCE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/saturate.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/saturate.hpp new file mode 100755 index 0000000..ced5e66 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/saturate.hpp @@ -0,0 +1,181 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2014, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_SATURATE_HPP +#define OPENCV_CORE_SATURATE_HPP + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/fast_math.hpp" + +namespace cv +{ + +//! @addtogroup core_utils +//! @{ + +/////////////// saturate_cast (used in image & signal processing) /////////////////// + +/** @brief Template function for accurate conversion from one primitive type to another. + + The function saturate_cast resembles the standard C++ cast operations, such as static_cast\() + and others. It perform an efficient and accurate conversion from one primitive type to another + (see the introduction chapter). saturate in the name means that when the input value v is out of the + range of the target type, the result is not formed just by taking low bits of the input, but instead + the value is clipped. For example: + @code + uchar a = saturate_cast(-100); // a = 0 (UCHAR_MIN) + short b = saturate_cast(33333.33333); // b = 32767 (SHRT_MAX) + @endcode + Such clipping is done when the target type is unsigned char , signed char , unsigned short or + signed short . For 32-bit integers, no clipping is done. + + When the parameter is a floating-point value and the target type is an integer (8-, 16- or 32-bit), + the floating-point value is first rounded to the nearest integer and then clipped if needed (when + the target type is 8- or 16-bit). + + This operation is used in the simplest or most complex image processing functions in OpenCV. + + @param v Function parameter. + @sa add, subtract, multiply, divide, Mat::convertTo + */ +template static inline _Tp saturate_cast(uchar v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(schar v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(ushort v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(short v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(unsigned v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(int v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(float v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(double v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(int64 v) { return _Tp(v); } +/** @overload */ +template static inline _Tp saturate_cast(uint64 v) { return _Tp(v); } + +template<> inline uchar saturate_cast(schar v) { return (uchar)std::max((int)v, 0); } +template<> inline uchar saturate_cast(ushort v) { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); } +template<> inline uchar saturate_cast(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } +template<> inline uchar saturate_cast(short v) { return saturate_cast((int)v); } +template<> inline uchar saturate_cast(unsigned v) { return (uchar)std::min(v, (unsigned)UCHAR_MAX); } +template<> inline uchar saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline uchar saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline uchar saturate_cast(int64 v) { return (uchar)((uint64)v <= (uint64)UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } +template<> inline uchar saturate_cast(uint64 v) { return (uchar)std::min(v, (uint64)UCHAR_MAX); } + +template<> inline schar saturate_cast(uchar v) { return (schar)std::min((int)v, SCHAR_MAX); } +template<> inline schar saturate_cast(ushort v) { return (schar)std::min((unsigned)v, (unsigned)SCHAR_MAX); } +template<> inline schar saturate_cast(int v) { return (schar)((unsigned)(v-SCHAR_MIN) <= (unsigned)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); } +template<> inline schar saturate_cast(short v) { return saturate_cast((int)v); } +template<> inline schar saturate_cast(unsigned v) { return (schar)std::min(v, (unsigned)SCHAR_MAX); } +template<> inline schar saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline schar saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline schar saturate_cast(int64 v) { return (schar)((uint64)((int64)v-SCHAR_MIN) <= (uint64)UCHAR_MAX ? v : v > 0 ? SCHAR_MAX : SCHAR_MIN); } +template<> inline schar saturate_cast(uint64 v) { return (schar)std::min(v, (uint64)SCHAR_MAX); } + +template<> inline ushort saturate_cast(schar v) { return (ushort)std::max((int)v, 0); } +template<> inline ushort saturate_cast(short v) { return (ushort)std::max((int)v, 0); } +template<> inline ushort saturate_cast(int v) { return (ushort)((unsigned)v <= (unsigned)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } +template<> inline ushort saturate_cast(unsigned v) { return (ushort)std::min(v, (unsigned)USHRT_MAX); } +template<> inline ushort saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline ushort saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline ushort saturate_cast(int64 v) { return (ushort)((uint64)v <= (uint64)USHRT_MAX ? v : v > 0 ? USHRT_MAX : 0); } +template<> inline ushort saturate_cast(uint64 v) { return (ushort)std::min(v, (uint64)USHRT_MAX); } + +template<> inline short saturate_cast(ushort v) { return (short)std::min((int)v, SHRT_MAX); } +template<> inline short saturate_cast(int v) { return (short)((unsigned)(v - SHRT_MIN) <= (unsigned)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); } +template<> inline short saturate_cast(unsigned v) { return (short)std::min(v, (unsigned)SHRT_MAX); } +template<> inline short saturate_cast(float v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline short saturate_cast(double v) { int iv = cvRound(v); return saturate_cast(iv); } +template<> inline short saturate_cast(int64 v) { return (short)((uint64)((int64)v - SHRT_MIN) <= (uint64)USHRT_MAX ? v : v > 0 ? SHRT_MAX : SHRT_MIN); } +template<> inline short saturate_cast(uint64 v) { return (short)std::min(v, (uint64)SHRT_MAX); } + +template<> inline int saturate_cast(unsigned v) { return (int)std::min(v, (unsigned)INT_MAX); } +template<> inline int saturate_cast(int64 v) { return (int)((uint64)(v - INT_MIN) <= (uint64)UINT_MAX ? v : v > 0 ? INT_MAX : INT_MIN); } +template<> inline int saturate_cast(uint64 v) { return (int)std::min(v, (uint64)INT_MAX); } +template<> inline int saturate_cast(float v) { return cvRound(v); } +template<> inline int saturate_cast(double v) { return cvRound(v); } + +template<> inline unsigned saturate_cast(schar v) { return (unsigned)std::max(v, (schar)0); } +template<> inline unsigned saturate_cast(short v) { return (unsigned)std::max(v, (short)0); } +template<> inline unsigned saturate_cast(int v) { return (unsigned)std::max(v, (int)0); } +template<> inline unsigned saturate_cast(int64 v) { return (unsigned)((uint64)v <= (uint64)UINT_MAX ? v : v > 0 ? UINT_MAX : 0); } +template<> inline unsigned saturate_cast(uint64 v) { return (unsigned)std::min(v, (uint64)UINT_MAX); } +// we intentionally do not clip negative numbers, to make -1 become 0xffffffff etc. +template<> inline unsigned saturate_cast(float v) { return static_cast(cvRound(v)); } +template<> inline unsigned saturate_cast(double v) { return static_cast(cvRound(v)); } + +template<> inline uint64 saturate_cast(schar v) { return (uint64)std::max(v, (schar)0); } +template<> inline uint64 saturate_cast(short v) { return (uint64)std::max(v, (short)0); } +template<> inline uint64 saturate_cast(int v) { return (uint64)std::max(v, (int)0); } +template<> inline uint64 saturate_cast(int64 v) { return (uint64)std::max(v, (int64)0); } + +template<> inline int64 saturate_cast(uint64 v) { return (int64)std::min(v, (uint64)LLONG_MAX); } + +/** @overload */ +template static inline _Tp saturate_cast(float16_t v) { return saturate_cast<_Tp>((float)v); } + +// in theory, we could use a LUT for 8u/8s->16f conversion, +// but with hardware support for FP32->FP16 conversion the current approach is preferable +template<> inline float16_t saturate_cast(uchar v) { return float16_t((float)v); } +template<> inline float16_t saturate_cast(schar v) { return float16_t((float)v); } +template<> inline float16_t saturate_cast(ushort v) { return float16_t((float)v); } +template<> inline float16_t saturate_cast(short v) { return float16_t((float)v); } +template<> inline float16_t saturate_cast(unsigned v){ return float16_t((float)v); } +template<> inline float16_t saturate_cast(int v) { return float16_t((float)v); } +template<> inline float16_t saturate_cast(uint64 v) { return float16_t((float)v); } +template<> inline float16_t saturate_cast(int64 v) { return float16_t((float)v); } +template<> inline float16_t saturate_cast(float v) { return float16_t(v); } +template<> inline float16_t saturate_cast(double v) { return float16_t((float)v); } + +//! @} + +} // cv + +#endif // OPENCV_CORE_SATURATE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/softfloat.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/softfloat.hpp new file mode 100755 index 0000000..5470980 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/softfloat.hpp @@ -0,0 +1,514 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +// This file is based on files from package issued with the following license: + +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3c, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#pragma once +#ifndef softfloat_h +#define softfloat_h 1 + +#include "cvdef.h" + +namespace cv +{ + +/** @addtogroup core_utils_softfloat + + [SoftFloat](http://www.jhauser.us/arithmetic/SoftFloat.html) is a software implementation + of floating-point calculations according to IEEE 754 standard. + All calculations are done in integers, that's why they are machine-independent and bit-exact. + This library can be useful in accuracy-critical parts like look-up tables generation, tests, etc. + OpenCV contains a subset of SoftFloat partially rewritten to C++. + + ### Types + + There are two basic types: @ref softfloat and @ref softdouble. + These types are binary compatible with float and double types respectively + and support conversions to/from them. + Other types from original SoftFloat library like fp16 or fp128 were thrown away + as well as quiet/signaling NaN support, on-the-fly rounding mode switch + and exception flags (though exceptions can be implemented in the future). + + ### Operations + + Both types support the following: + - Construction from signed and unsigned 32-bit and 64 integers, + float/double or raw binary representation + - Conversions between each other, to float or double and to int + using @ref cvRound, @ref cvTrunc, @ref cvFloor, @ref cvCeil or a bunch of + saturate_cast functions + - Add, subtract, multiply, divide, remainder, square root, FMA with absolute precision + - Comparison operations + - Explicit sign, exponent and significand manipulation through get/set methods, + number state indicators (isInf, isNan, isSubnormal) + - Type-specific constants like eps, minimum/maximum value, best pi approximation, etc. + - min(), max(), abs(), exp(), log() and pow() functions + +*/ +//! @{ + +struct softfloat; +struct softdouble; + +struct CV_EXPORTS softfloat +{ +public: + /** @brief Default constructor */ + softfloat() { v = 0; } + /** @brief Copy constructor */ + softfloat( const softfloat& c) { v = c.v; } + /** @brief Assign constructor */ + softfloat& operator=( const softfloat& c ) + { + if(&c != this) v = c.v; + return *this; + } + /** @brief Construct from raw + + Builds new value from raw binary representation + */ + static const softfloat fromRaw( const uint32_t a ) { softfloat x; x.v = a; return x; } + + /** @brief Construct from integer */ + explicit softfloat( const uint32_t ); + explicit softfloat( const uint64_t ); + explicit softfloat( const int32_t ); + explicit softfloat( const int64_t ); + +#ifdef CV_INT32_T_IS_LONG_INT + // for platforms with int32_t = long int + explicit softfloat( const int a ) { *this = softfloat(static_cast(a)); } +#endif + + /** @brief Construct from float */ + explicit softfloat( const float a ) { Cv32suf s; s.f = a; v = s.u; } + + /** @brief Type casts */ + operator softdouble() const; + operator float() const { Cv32suf s; s.u = v; return s.f; } + + /** @brief Basic arithmetics */ + softfloat operator + (const softfloat&) const; + softfloat operator - (const softfloat&) const; + softfloat operator * (const softfloat&) const; + softfloat operator / (const softfloat&) const; + softfloat operator - () const { softfloat x; x.v = v ^ (1U << 31); return x; } + + /** @brief Remainder operator + + A quote from original SoftFloat manual: + + > The IEEE Standard remainder operation computes the value + > a - n * b, where n is the integer closest to a / b. + > If a / b is exactly halfway between two integers, n is the even integer + > closest to a / b. The IEEE Standard’s remainder operation is always exact and so requires no rounding. + > Depending on the relative magnitudes of the operands, the remainder functions + > can take considerably longer to execute than the other SoftFloat functions. + > This is an inherent characteristic of the remainder operation itself and is not a flaw + > in the SoftFloat implementation. + */ + softfloat operator % (const softfloat&) const; + + softfloat& operator += (const softfloat& a) { *this = *this + a; return *this; } + softfloat& operator -= (const softfloat& a) { *this = *this - a; return *this; } + softfloat& operator *= (const softfloat& a) { *this = *this * a; return *this; } + softfloat& operator /= (const softfloat& a) { *this = *this / a; return *this; } + softfloat& operator %= (const softfloat& a) { *this = *this % a; return *this; } + + /** @brief Comparison operations + + - Any operation with NaN produces false + + The only exception is when x is NaN: x != y for any y. + - Positive and negative zeros are equal + */ + bool operator == ( const softfloat& ) const; + bool operator != ( const softfloat& ) const; + bool operator > ( const softfloat& ) const; + bool operator >= ( const softfloat& ) const; + bool operator < ( const softfloat& ) const; + bool operator <= ( const softfloat& ) const; + + /** @brief NaN state indicator */ + inline bool isNaN() const { return (v & 0x7fffffff) > 0x7f800000; } + /** @brief Inf state indicator */ + inline bool isInf() const { return (v & 0x7fffffff) == 0x7f800000; } + /** @brief Subnormal number indicator */ + inline bool isSubnormal() const { return ((v >> 23) & 0xFF) == 0; } + + /** @brief Get sign bit */ + inline bool getSign() const { return (v >> 31) != 0; } + /** @brief Construct a copy with new sign bit */ + inline softfloat setSign(bool sign) const { softfloat x; x.v = (v & ((1U << 31) - 1)) | ((uint32_t)sign << 31); return x; } + /** @brief Get 0-based exponent */ + inline int getExp() const { return ((v >> 23) & 0xFF) - 127; } + /** @brief Construct a copy with new 0-based exponent */ + inline softfloat setExp(int e) const { softfloat x; x.v = (v & 0x807fffff) | (((e + 127) & 0xFF) << 23 ); return x; } + + /** @brief Get a fraction part + + Returns a number 1 <= x < 2 with the same significand + */ + inline softfloat getFrac() const + { + uint_fast32_t vv = (v & 0x007fffff) | (127 << 23); + return softfloat::fromRaw(vv); + } + /** @brief Construct a copy with provided significand + + Constructs a copy of a number with significand taken from parameter + */ + inline softfloat setFrac(const softfloat& s) const + { + softfloat x; + x.v = (v & 0xff800000) | (s.v & 0x007fffff); + return x; + } + + /** @brief Zero constant */ + static softfloat zero() { return softfloat::fromRaw( 0 ); } + /** @brief Positive infinity constant */ + static softfloat inf() { return softfloat::fromRaw( 0xFF << 23 ); } + /** @brief Default NaN constant */ + static softfloat nan() { return softfloat::fromRaw( 0x7fffffff ); } + /** @brief One constant */ + static softfloat one() { return softfloat::fromRaw( 127 << 23 ); } + /** @brief Smallest normalized value */ + static softfloat min() { return softfloat::fromRaw( 0x01 << 23 ); } + /** @brief Difference between 1 and next representable value */ + static softfloat eps() { return softfloat::fromRaw( (127 - 23) << 23 ); } + /** @brief Biggest finite value */ + static softfloat max() { return softfloat::fromRaw( (0xFF << 23) - 1 ); } + /** @brief Correct pi approximation */ + static softfloat pi() { return softfloat::fromRaw( 0x40490fdb ); } + + uint32_t v; +}; + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ + +struct CV_EXPORTS softdouble +{ +public: + /** @brief Default constructor */ + softdouble() : v(0) { } + /** @brief Copy constructor */ + softdouble( const softdouble& c) { v = c.v; } + /** @brief Assign constructor */ + softdouble& operator=( const softdouble& c ) + { + if(&c != this) v = c.v; + return *this; + } + /** @brief Construct from raw + + Builds new value from raw binary representation + */ + static softdouble fromRaw( const uint64_t a ) { softdouble x; x.v = a; return x; } + + /** @brief Construct from integer */ + explicit softdouble( const uint32_t ); + explicit softdouble( const uint64_t ); + explicit softdouble( const int32_t ); + explicit softdouble( const int64_t ); + +#ifdef CV_INT32_T_IS_LONG_INT + // for platforms with int32_t = long int + explicit softdouble( const int a ) { *this = softdouble(static_cast(a)); } +#endif + + /** @brief Construct from double */ + explicit softdouble( const double a ) { Cv64suf s; s.f = a; v = s.u; } + + /** @brief Type casts */ + operator softfloat() const; + operator double() const { Cv64suf s; s.u = v; return s.f; } + + /** @brief Basic arithmetics */ + softdouble operator + (const softdouble&) const; + softdouble operator - (const softdouble&) const; + softdouble operator * (const softdouble&) const; + softdouble operator / (const softdouble&) const; + softdouble operator - () const { softdouble x; x.v = v ^ (1ULL << 63); return x; } + + /** @brief Remainder operator + + A quote from original SoftFloat manual: + + > The IEEE Standard remainder operation computes the value + > a - n * b, where n is the integer closest to a / b. + > If a / b is exactly halfway between two integers, n is the even integer + > closest to a / b. The IEEE Standard’s remainder operation is always exact and so requires no rounding. + > Depending on the relative magnitudes of the operands, the remainder functions + > can take considerably longer to execute than the other SoftFloat functions. + > This is an inherent characteristic of the remainder operation itself and is not a flaw + > in the SoftFloat implementation. + */ + softdouble operator % (const softdouble&) const; + + softdouble& operator += (const softdouble& a) { *this = *this + a; return *this; } + softdouble& operator -= (const softdouble& a) { *this = *this - a; return *this; } + softdouble& operator *= (const softdouble& a) { *this = *this * a; return *this; } + softdouble& operator /= (const softdouble& a) { *this = *this / a; return *this; } + softdouble& operator %= (const softdouble& a) { *this = *this % a; return *this; } + + /** @brief Comparison operations + + - Any operation with NaN produces false + + The only exception is when x is NaN: x != y for any y. + - Positive and negative zeros are equal + */ + bool operator == ( const softdouble& ) const; + bool operator != ( const softdouble& ) const; + bool operator > ( const softdouble& ) const; + bool operator >= ( const softdouble& ) const; + bool operator < ( const softdouble& ) const; + bool operator <= ( const softdouble& ) const; + + /** @brief NaN state indicator */ + inline bool isNaN() const { return (v & 0x7fffffffffffffff) > 0x7ff0000000000000; } + /** @brief Inf state indicator */ + inline bool isInf() const { return (v & 0x7fffffffffffffff) == 0x7ff0000000000000; } + /** @brief Subnormal number indicator */ + inline bool isSubnormal() const { return ((v >> 52) & 0x7FF) == 0; } + + /** @brief Get sign bit */ + inline bool getSign() const { return (v >> 63) != 0; } + /** @brief Construct a copy with new sign bit */ + softdouble setSign(bool sign) const { softdouble x; x.v = (v & ((1ULL << 63) - 1)) | ((uint_fast64_t)(sign) << 63); return x; } + /** @brief Get 0-based exponent */ + inline int getExp() const { return ((v >> 52) & 0x7FF) - 1023; } + /** @brief Construct a copy with new 0-based exponent */ + inline softdouble setExp(int e) const + { + softdouble x; + x.v = (v & 0x800FFFFFFFFFFFFF) | ((uint_fast64_t)((e + 1023) & 0x7FF) << 52); + return x; + } + + /** @brief Get a fraction part + + Returns a number 1 <= x < 2 with the same significand + */ + inline softdouble getFrac() const + { + uint_fast64_t vv = (v & 0x000FFFFFFFFFFFFF) | ((uint_fast64_t)(1023) << 52); + return softdouble::fromRaw(vv); + } + /** @brief Construct a copy with provided significand + + Constructs a copy of a number with significand taken from parameter + */ + inline softdouble setFrac(const softdouble& s) const + { + softdouble x; + x.v = (v & 0xFFF0000000000000) | (s.v & 0x000FFFFFFFFFFFFF); + return x; + } + + /** @brief Zero constant */ + static softdouble zero() { return softdouble::fromRaw( 0 ); } + /** @brief Positive infinity constant */ + static softdouble inf() { return softdouble::fromRaw( (uint_fast64_t)(0x7FF) << 52 ); } + /** @brief Default NaN constant */ + static softdouble nan() { return softdouble::fromRaw( CV_BIG_INT(0x7FFFFFFFFFFFFFFF) ); } + /** @brief One constant */ + static softdouble one() { return softdouble::fromRaw( (uint_fast64_t)( 1023) << 52 ); } + /** @brief Smallest normalized value */ + static softdouble min() { return softdouble::fromRaw( (uint_fast64_t)( 0x01) << 52 ); } + /** @brief Difference between 1 and next representable value */ + static softdouble eps() { return softdouble::fromRaw( (uint_fast64_t)( 1023 - 52 ) << 52 ); } + /** @brief Biggest finite value */ + static softdouble max() { return softdouble::fromRaw( ((uint_fast64_t)(0x7FF) << 52) - 1 ); } + /** @brief Correct pi approximation */ + static softdouble pi() { return softdouble::fromRaw( CV_BIG_INT(0x400921FB54442D18) ); } + + uint64_t v; +}; + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ + +/** @brief Fused Multiplication and Addition + +Computes (a*b)+c with single rounding +*/ +CV_EXPORTS softfloat mulAdd( const softfloat& a, const softfloat& b, const softfloat & c); +CV_EXPORTS softdouble mulAdd( const softdouble& a, const softdouble& b, const softdouble& c); + +/** @brief Square root */ +CV_EXPORTS softfloat sqrt( const softfloat& a ); +CV_EXPORTS softdouble sqrt( const softdouble& a ); +} + +/*---------------------------------------------------------------------------- +| Ported from OpenCV and added for usability +*----------------------------------------------------------------------------*/ + +/** @brief Truncates number to integer with minimum magnitude */ +CV_EXPORTS int cvTrunc(const cv::softfloat& a); +CV_EXPORTS int cvTrunc(const cv::softdouble& a); + +/** @brief Rounds a number to nearest even integer */ +CV_EXPORTS int cvRound(const cv::softfloat& a); +CV_EXPORTS int cvRound(const cv::softdouble& a); + +/** @brief Rounds a number to nearest even long long integer */ +CV_EXPORTS int64_t cvRound64(const cv::softdouble& a); + +/** @brief Rounds a number down to integer */ +CV_EXPORTS int cvFloor(const cv::softfloat& a); +CV_EXPORTS int cvFloor(const cv::softdouble& a); + +/** @brief Rounds number up to integer */ +CV_EXPORTS int cvCeil(const cv::softfloat& a); +CV_EXPORTS int cvCeil(const cv::softdouble& a); + +namespace cv +{ +/** @brief Saturate casts */ +template static inline _Tp saturate_cast(softfloat a) { return _Tp(a); } +template static inline _Tp saturate_cast(softdouble a) { return _Tp(a); } + +template<> inline uchar saturate_cast(softfloat a) { return (uchar)std::max(std::min(cvRound(a), (int)UCHAR_MAX), 0); } +template<> inline uchar saturate_cast(softdouble a) { return (uchar)std::max(std::min(cvRound(a), (int)UCHAR_MAX), 0); } + +template<> inline schar saturate_cast(softfloat a) { return (schar)std::min(std::max(cvRound(a), (int)SCHAR_MIN), (int)SCHAR_MAX); } +template<> inline schar saturate_cast(softdouble a) { return (schar)std::min(std::max(cvRound(a), (int)SCHAR_MIN), (int)SCHAR_MAX); } + +template<> inline ushort saturate_cast(softfloat a) { return (ushort)std::max(std::min(cvRound(a), (int)USHRT_MAX), 0); } +template<> inline ushort saturate_cast(softdouble a) { return (ushort)std::max(std::min(cvRound(a), (int)USHRT_MAX), 0); } + +template<> inline short saturate_cast(softfloat a) { return (short)std::min(std::max(cvRound(a), (int)SHRT_MIN), (int)SHRT_MAX); } +template<> inline short saturate_cast(softdouble a) { return (short)std::min(std::max(cvRound(a), (int)SHRT_MIN), (int)SHRT_MAX); } + +template<> inline int saturate_cast(softfloat a) { return cvRound(a); } +template<> inline int saturate_cast(softdouble a) { return cvRound(a); } + +template<> inline int64_t saturate_cast(softfloat a) { return cvRound(a); } +template<> inline int64_t saturate_cast(softdouble a) { return cvRound64(a); } + +/** @brief Saturate cast to unsigned integer and unsigned long long integer +We intentionally do not clip negative numbers, to make -1 become 0xffffffff etc. +*/ +template<> inline unsigned saturate_cast(softfloat a) { return cvRound(a); } +template<> inline unsigned saturate_cast(softdouble a) { return cvRound(a); } + +template<> inline uint64_t saturate_cast(softfloat a) { return cvRound(a); } +template<> inline uint64_t saturate_cast(softdouble a) { return cvRound64(a); } + +/** @brief Min and Max functions */ +inline softfloat min(const softfloat& a, const softfloat& b) { return (a > b) ? b : a; } +inline softdouble min(const softdouble& a, const softdouble& b) { return (a > b) ? b : a; } + +inline softfloat max(const softfloat& a, const softfloat& b) { return (a > b) ? a : b; } +inline softdouble max(const softdouble& a, const softdouble& b) { return (a > b) ? a : b; } + +/** @brief Absolute value */ +inline softfloat abs( softfloat a) { softfloat x; x.v = a.v & ((1U << 31) - 1); return x; } +inline softdouble abs( softdouble a) { softdouble x; x.v = a.v & ((1ULL << 63) - 1); return x; } + +/** @brief Exponent + +Special cases: +- exp(NaN) is NaN +- exp(-Inf) == 0 +- exp(+Inf) == +Inf +*/ +CV_EXPORTS softfloat exp( const softfloat& a); +CV_EXPORTS softdouble exp( const softdouble& a); + +/** @brief Natural logarithm + +Special cases: +- log(NaN), log(x < 0) are NaN +- log(0) == -Inf +*/ +CV_EXPORTS softfloat log( const softfloat& a ); +CV_EXPORTS softdouble log( const softdouble& a ); + +/** @brief Raising to the power + +Special cases: +- x**NaN is NaN for any x +- ( |x| == 1 )**Inf is NaN +- ( |x| > 1 )**+Inf or ( |x| < 1 )**-Inf is +Inf +- ( |x| > 1 )**-Inf or ( |x| < 1 )**+Inf is 0 +- x ** 0 == 1 for any x +- x ** 1 == 1 for any x +- NaN ** y is NaN for any other y +- Inf**(y < 0) == 0 +- Inf ** y is +Inf for any other y +- (x < 0)**y is NaN for any other y if x can't be correctly rounded to integer +- 0 ** 0 == 1 +- 0 ** (y < 0) is +Inf +- 0 ** (y > 0) is 0 +*/ +CV_EXPORTS softfloat pow( const softfloat& a, const softfloat& b); +CV_EXPORTS softdouble pow( const softdouble& a, const softdouble& b); + +/** @brief Cube root + +Special cases: +- cbrt(NaN) is NaN +- cbrt(+/-Inf) is +/-Inf +*/ +CV_EXPORTS softfloat cbrt( const softfloat& a ); + +/** @brief Sine + +Special cases: +- sin(Inf) or sin(NaN) is NaN +- sin(x) == x when sin(x) is close to zero +*/ +CV_EXPORTS softdouble sin( const softdouble& a ); + +/** @brief Cosine + * +Special cases: +- cos(Inf) or cos(NaN) is NaN +- cos(x) == +/- 1 when cos(x) is close to +/- 1 +*/ +CV_EXPORTS softdouble cos( const softdouble& a ); + +} + +//! @} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/sse_utils.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/sse_utils.hpp new file mode 100755 index 0000000..0906583 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/sse_utils.hpp @@ -0,0 +1,652 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_SSE_UTILS_HPP +#define OPENCV_CORE_SSE_UTILS_HPP + +#ifndef __cplusplus +# error sse_utils.hpp header must be compiled as C++ +#endif + +#include "opencv2/core/cvdef.h" + +//! @addtogroup core_utils_sse +//! @{ + +#if CV_SSE2 + +inline void _mm_deinterleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1) +{ + __m128i layer1_chunk0 = _mm_unpacklo_epi8(v_r0, v_g0); + __m128i layer1_chunk1 = _mm_unpackhi_epi8(v_r0, v_g0); + __m128i layer1_chunk2 = _mm_unpacklo_epi8(v_r1, v_g1); + __m128i layer1_chunk3 = _mm_unpackhi_epi8(v_r1, v_g1); + + __m128i layer2_chunk0 = _mm_unpacklo_epi8(layer1_chunk0, layer1_chunk2); + __m128i layer2_chunk1 = _mm_unpackhi_epi8(layer1_chunk0, layer1_chunk2); + __m128i layer2_chunk2 = _mm_unpacklo_epi8(layer1_chunk1, layer1_chunk3); + __m128i layer2_chunk3 = _mm_unpackhi_epi8(layer1_chunk1, layer1_chunk3); + + __m128i layer3_chunk0 = _mm_unpacklo_epi8(layer2_chunk0, layer2_chunk2); + __m128i layer3_chunk1 = _mm_unpackhi_epi8(layer2_chunk0, layer2_chunk2); + __m128i layer3_chunk2 = _mm_unpacklo_epi8(layer2_chunk1, layer2_chunk3); + __m128i layer3_chunk3 = _mm_unpackhi_epi8(layer2_chunk1, layer2_chunk3); + + __m128i layer4_chunk0 = _mm_unpacklo_epi8(layer3_chunk0, layer3_chunk2); + __m128i layer4_chunk1 = _mm_unpackhi_epi8(layer3_chunk0, layer3_chunk2); + __m128i layer4_chunk2 = _mm_unpacklo_epi8(layer3_chunk1, layer3_chunk3); + __m128i layer4_chunk3 = _mm_unpackhi_epi8(layer3_chunk1, layer3_chunk3); + + v_r0 = _mm_unpacklo_epi8(layer4_chunk0, layer4_chunk2); + v_r1 = _mm_unpackhi_epi8(layer4_chunk0, layer4_chunk2); + v_g0 = _mm_unpacklo_epi8(layer4_chunk1, layer4_chunk3); + v_g1 = _mm_unpackhi_epi8(layer4_chunk1, layer4_chunk3); +} + +inline void _mm_deinterleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, + __m128i & v_g1, __m128i & v_b0, __m128i & v_b1) +{ + __m128i layer1_chunk0 = _mm_unpacklo_epi8(v_r0, v_g1); + __m128i layer1_chunk1 = _mm_unpackhi_epi8(v_r0, v_g1); + __m128i layer1_chunk2 = _mm_unpacklo_epi8(v_r1, v_b0); + __m128i layer1_chunk3 = _mm_unpackhi_epi8(v_r1, v_b0); + __m128i layer1_chunk4 = _mm_unpacklo_epi8(v_g0, v_b1); + __m128i layer1_chunk5 = _mm_unpackhi_epi8(v_g0, v_b1); + + __m128i layer2_chunk0 = _mm_unpacklo_epi8(layer1_chunk0, layer1_chunk3); + __m128i layer2_chunk1 = _mm_unpackhi_epi8(layer1_chunk0, layer1_chunk3); + __m128i layer2_chunk2 = _mm_unpacklo_epi8(layer1_chunk1, layer1_chunk4); + __m128i layer2_chunk3 = _mm_unpackhi_epi8(layer1_chunk1, layer1_chunk4); + __m128i layer2_chunk4 = _mm_unpacklo_epi8(layer1_chunk2, layer1_chunk5); + __m128i layer2_chunk5 = _mm_unpackhi_epi8(layer1_chunk2, layer1_chunk5); + + __m128i layer3_chunk0 = _mm_unpacklo_epi8(layer2_chunk0, layer2_chunk3); + __m128i layer3_chunk1 = _mm_unpackhi_epi8(layer2_chunk0, layer2_chunk3); + __m128i layer3_chunk2 = _mm_unpacklo_epi8(layer2_chunk1, layer2_chunk4); + __m128i layer3_chunk3 = _mm_unpackhi_epi8(layer2_chunk1, layer2_chunk4); + __m128i layer3_chunk4 = _mm_unpacklo_epi8(layer2_chunk2, layer2_chunk5); + __m128i layer3_chunk5 = _mm_unpackhi_epi8(layer2_chunk2, layer2_chunk5); + + __m128i layer4_chunk0 = _mm_unpacklo_epi8(layer3_chunk0, layer3_chunk3); + __m128i layer4_chunk1 = _mm_unpackhi_epi8(layer3_chunk0, layer3_chunk3); + __m128i layer4_chunk2 = _mm_unpacklo_epi8(layer3_chunk1, layer3_chunk4); + __m128i layer4_chunk3 = _mm_unpackhi_epi8(layer3_chunk1, layer3_chunk4); + __m128i layer4_chunk4 = _mm_unpacklo_epi8(layer3_chunk2, layer3_chunk5); + __m128i layer4_chunk5 = _mm_unpackhi_epi8(layer3_chunk2, layer3_chunk5); + + v_r0 = _mm_unpacklo_epi8(layer4_chunk0, layer4_chunk3); + v_r1 = _mm_unpackhi_epi8(layer4_chunk0, layer4_chunk3); + v_g0 = _mm_unpacklo_epi8(layer4_chunk1, layer4_chunk4); + v_g1 = _mm_unpackhi_epi8(layer4_chunk1, layer4_chunk4); + v_b0 = _mm_unpacklo_epi8(layer4_chunk2, layer4_chunk5); + v_b1 = _mm_unpackhi_epi8(layer4_chunk2, layer4_chunk5); +} + +inline void _mm_deinterleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1, + __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1) +{ + __m128i layer1_chunk0 = _mm_unpacklo_epi8(v_r0, v_b0); + __m128i layer1_chunk1 = _mm_unpackhi_epi8(v_r0, v_b0); + __m128i layer1_chunk2 = _mm_unpacklo_epi8(v_r1, v_b1); + __m128i layer1_chunk3 = _mm_unpackhi_epi8(v_r1, v_b1); + __m128i layer1_chunk4 = _mm_unpacklo_epi8(v_g0, v_a0); + __m128i layer1_chunk5 = _mm_unpackhi_epi8(v_g0, v_a0); + __m128i layer1_chunk6 = _mm_unpacklo_epi8(v_g1, v_a1); + __m128i layer1_chunk7 = _mm_unpackhi_epi8(v_g1, v_a1); + + __m128i layer2_chunk0 = _mm_unpacklo_epi8(layer1_chunk0, layer1_chunk4); + __m128i layer2_chunk1 = _mm_unpackhi_epi8(layer1_chunk0, layer1_chunk4); + __m128i layer2_chunk2 = _mm_unpacklo_epi8(layer1_chunk1, layer1_chunk5); + __m128i layer2_chunk3 = _mm_unpackhi_epi8(layer1_chunk1, layer1_chunk5); + __m128i layer2_chunk4 = _mm_unpacklo_epi8(layer1_chunk2, layer1_chunk6); + __m128i layer2_chunk5 = _mm_unpackhi_epi8(layer1_chunk2, layer1_chunk6); + __m128i layer2_chunk6 = _mm_unpacklo_epi8(layer1_chunk3, layer1_chunk7); + __m128i layer2_chunk7 = _mm_unpackhi_epi8(layer1_chunk3, layer1_chunk7); + + __m128i layer3_chunk0 = _mm_unpacklo_epi8(layer2_chunk0, layer2_chunk4); + __m128i layer3_chunk1 = _mm_unpackhi_epi8(layer2_chunk0, layer2_chunk4); + __m128i layer3_chunk2 = _mm_unpacklo_epi8(layer2_chunk1, layer2_chunk5); + __m128i layer3_chunk3 = _mm_unpackhi_epi8(layer2_chunk1, layer2_chunk5); + __m128i layer3_chunk4 = _mm_unpacklo_epi8(layer2_chunk2, layer2_chunk6); + __m128i layer3_chunk5 = _mm_unpackhi_epi8(layer2_chunk2, layer2_chunk6); + __m128i layer3_chunk6 = _mm_unpacklo_epi8(layer2_chunk3, layer2_chunk7); + __m128i layer3_chunk7 = _mm_unpackhi_epi8(layer2_chunk3, layer2_chunk7); + + __m128i layer4_chunk0 = _mm_unpacklo_epi8(layer3_chunk0, layer3_chunk4); + __m128i layer4_chunk1 = _mm_unpackhi_epi8(layer3_chunk0, layer3_chunk4); + __m128i layer4_chunk2 = _mm_unpacklo_epi8(layer3_chunk1, layer3_chunk5); + __m128i layer4_chunk3 = _mm_unpackhi_epi8(layer3_chunk1, layer3_chunk5); + __m128i layer4_chunk4 = _mm_unpacklo_epi8(layer3_chunk2, layer3_chunk6); + __m128i layer4_chunk5 = _mm_unpackhi_epi8(layer3_chunk2, layer3_chunk6); + __m128i layer4_chunk6 = _mm_unpacklo_epi8(layer3_chunk3, layer3_chunk7); + __m128i layer4_chunk7 = _mm_unpackhi_epi8(layer3_chunk3, layer3_chunk7); + + v_r0 = _mm_unpacklo_epi8(layer4_chunk0, layer4_chunk4); + v_r1 = _mm_unpackhi_epi8(layer4_chunk0, layer4_chunk4); + v_g0 = _mm_unpacklo_epi8(layer4_chunk1, layer4_chunk5); + v_g1 = _mm_unpackhi_epi8(layer4_chunk1, layer4_chunk5); + v_b0 = _mm_unpacklo_epi8(layer4_chunk2, layer4_chunk6); + v_b1 = _mm_unpackhi_epi8(layer4_chunk2, layer4_chunk6); + v_a0 = _mm_unpacklo_epi8(layer4_chunk3, layer4_chunk7); + v_a1 = _mm_unpackhi_epi8(layer4_chunk3, layer4_chunk7); +} + +inline void _mm_interleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1) +{ + __m128i v_mask = _mm_set1_epi16(0x00ff); + + __m128i layer4_chunk0 = _mm_packus_epi16(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask)); + __m128i layer4_chunk2 = _mm_packus_epi16(_mm_srli_epi16(v_r0, 8), _mm_srli_epi16(v_r1, 8)); + __m128i layer4_chunk1 = _mm_packus_epi16(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask)); + __m128i layer4_chunk3 = _mm_packus_epi16(_mm_srli_epi16(v_g0, 8), _mm_srli_epi16(v_g1, 8)); + + __m128i layer3_chunk0 = _mm_packus_epi16(_mm_and_si128(layer4_chunk0, v_mask), _mm_and_si128(layer4_chunk1, v_mask)); + __m128i layer3_chunk2 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk0, 8), _mm_srli_epi16(layer4_chunk1, 8)); + __m128i layer3_chunk1 = _mm_packus_epi16(_mm_and_si128(layer4_chunk2, v_mask), _mm_and_si128(layer4_chunk3, v_mask)); + __m128i layer3_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk2, 8), _mm_srli_epi16(layer4_chunk3, 8)); + + __m128i layer2_chunk0 = _mm_packus_epi16(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask)); + __m128i layer2_chunk2 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk0, 8), _mm_srli_epi16(layer3_chunk1, 8)); + __m128i layer2_chunk1 = _mm_packus_epi16(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask)); + __m128i layer2_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk2, 8), _mm_srli_epi16(layer3_chunk3, 8)); + + __m128i layer1_chunk0 = _mm_packus_epi16(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask)); + __m128i layer1_chunk2 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk0, 8), _mm_srli_epi16(layer2_chunk1, 8)); + __m128i layer1_chunk1 = _mm_packus_epi16(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask)); + __m128i layer1_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk2, 8), _mm_srli_epi16(layer2_chunk3, 8)); + + v_r0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask)); + v_g0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk0, 8), _mm_srli_epi16(layer1_chunk1, 8)); + v_r1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask)); + v_g1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk2, 8), _mm_srli_epi16(layer1_chunk3, 8)); +} + +inline void _mm_interleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, + __m128i & v_g1, __m128i & v_b0, __m128i & v_b1) +{ + __m128i v_mask = _mm_set1_epi16(0x00ff); + + __m128i layer4_chunk0 = _mm_packus_epi16(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask)); + __m128i layer4_chunk3 = _mm_packus_epi16(_mm_srli_epi16(v_r0, 8), _mm_srli_epi16(v_r1, 8)); + __m128i layer4_chunk1 = _mm_packus_epi16(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask)); + __m128i layer4_chunk4 = _mm_packus_epi16(_mm_srli_epi16(v_g0, 8), _mm_srli_epi16(v_g1, 8)); + __m128i layer4_chunk2 = _mm_packus_epi16(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask)); + __m128i layer4_chunk5 = _mm_packus_epi16(_mm_srli_epi16(v_b0, 8), _mm_srli_epi16(v_b1, 8)); + + __m128i layer3_chunk0 = _mm_packus_epi16(_mm_and_si128(layer4_chunk0, v_mask), _mm_and_si128(layer4_chunk1, v_mask)); + __m128i layer3_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk0, 8), _mm_srli_epi16(layer4_chunk1, 8)); + __m128i layer3_chunk1 = _mm_packus_epi16(_mm_and_si128(layer4_chunk2, v_mask), _mm_and_si128(layer4_chunk3, v_mask)); + __m128i layer3_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk2, 8), _mm_srli_epi16(layer4_chunk3, 8)); + __m128i layer3_chunk2 = _mm_packus_epi16(_mm_and_si128(layer4_chunk4, v_mask), _mm_and_si128(layer4_chunk5, v_mask)); + __m128i layer3_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk4, 8), _mm_srli_epi16(layer4_chunk5, 8)); + + __m128i layer2_chunk0 = _mm_packus_epi16(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask)); + __m128i layer2_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk0, 8), _mm_srli_epi16(layer3_chunk1, 8)); + __m128i layer2_chunk1 = _mm_packus_epi16(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask)); + __m128i layer2_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk2, 8), _mm_srli_epi16(layer3_chunk3, 8)); + __m128i layer2_chunk2 = _mm_packus_epi16(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask)); + __m128i layer2_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk4, 8), _mm_srli_epi16(layer3_chunk5, 8)); + + __m128i layer1_chunk0 = _mm_packus_epi16(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask)); + __m128i layer1_chunk3 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk0, 8), _mm_srli_epi16(layer2_chunk1, 8)); + __m128i layer1_chunk1 = _mm_packus_epi16(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask)); + __m128i layer1_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk2, 8), _mm_srli_epi16(layer2_chunk3, 8)); + __m128i layer1_chunk2 = _mm_packus_epi16(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask)); + __m128i layer1_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk4, 8), _mm_srli_epi16(layer2_chunk5, 8)); + + v_r0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask)); + v_g1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk0, 8), _mm_srli_epi16(layer1_chunk1, 8)); + v_r1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask)); + v_b0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk2, 8), _mm_srli_epi16(layer1_chunk3, 8)); + v_g0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask)); + v_b1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk4, 8), _mm_srli_epi16(layer1_chunk5, 8)); +} + +inline void _mm_interleave_epi8(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1, + __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1) +{ + __m128i v_mask = _mm_set1_epi16(0x00ff); + + __m128i layer4_chunk0 = _mm_packus_epi16(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask)); + __m128i layer4_chunk4 = _mm_packus_epi16(_mm_srli_epi16(v_r0, 8), _mm_srli_epi16(v_r1, 8)); + __m128i layer4_chunk1 = _mm_packus_epi16(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask)); + __m128i layer4_chunk5 = _mm_packus_epi16(_mm_srli_epi16(v_g0, 8), _mm_srli_epi16(v_g1, 8)); + __m128i layer4_chunk2 = _mm_packus_epi16(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask)); + __m128i layer4_chunk6 = _mm_packus_epi16(_mm_srli_epi16(v_b0, 8), _mm_srli_epi16(v_b1, 8)); + __m128i layer4_chunk3 = _mm_packus_epi16(_mm_and_si128(v_a0, v_mask), _mm_and_si128(v_a1, v_mask)); + __m128i layer4_chunk7 = _mm_packus_epi16(_mm_srli_epi16(v_a0, 8), _mm_srli_epi16(v_a1, 8)); + + __m128i layer3_chunk0 = _mm_packus_epi16(_mm_and_si128(layer4_chunk0, v_mask), _mm_and_si128(layer4_chunk1, v_mask)); + __m128i layer3_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk0, 8), _mm_srli_epi16(layer4_chunk1, 8)); + __m128i layer3_chunk1 = _mm_packus_epi16(_mm_and_si128(layer4_chunk2, v_mask), _mm_and_si128(layer4_chunk3, v_mask)); + __m128i layer3_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk2, 8), _mm_srli_epi16(layer4_chunk3, 8)); + __m128i layer3_chunk2 = _mm_packus_epi16(_mm_and_si128(layer4_chunk4, v_mask), _mm_and_si128(layer4_chunk5, v_mask)); + __m128i layer3_chunk6 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk4, 8), _mm_srli_epi16(layer4_chunk5, 8)); + __m128i layer3_chunk3 = _mm_packus_epi16(_mm_and_si128(layer4_chunk6, v_mask), _mm_and_si128(layer4_chunk7, v_mask)); + __m128i layer3_chunk7 = _mm_packus_epi16(_mm_srli_epi16(layer4_chunk6, 8), _mm_srli_epi16(layer4_chunk7, 8)); + + __m128i layer2_chunk0 = _mm_packus_epi16(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask)); + __m128i layer2_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk0, 8), _mm_srli_epi16(layer3_chunk1, 8)); + __m128i layer2_chunk1 = _mm_packus_epi16(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask)); + __m128i layer2_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk2, 8), _mm_srli_epi16(layer3_chunk3, 8)); + __m128i layer2_chunk2 = _mm_packus_epi16(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask)); + __m128i layer2_chunk6 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk4, 8), _mm_srli_epi16(layer3_chunk5, 8)); + __m128i layer2_chunk3 = _mm_packus_epi16(_mm_and_si128(layer3_chunk6, v_mask), _mm_and_si128(layer3_chunk7, v_mask)); + __m128i layer2_chunk7 = _mm_packus_epi16(_mm_srli_epi16(layer3_chunk6, 8), _mm_srli_epi16(layer3_chunk7, 8)); + + __m128i layer1_chunk0 = _mm_packus_epi16(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask)); + __m128i layer1_chunk4 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk0, 8), _mm_srli_epi16(layer2_chunk1, 8)); + __m128i layer1_chunk1 = _mm_packus_epi16(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask)); + __m128i layer1_chunk5 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk2, 8), _mm_srli_epi16(layer2_chunk3, 8)); + __m128i layer1_chunk2 = _mm_packus_epi16(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask)); + __m128i layer1_chunk6 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk4, 8), _mm_srli_epi16(layer2_chunk5, 8)); + __m128i layer1_chunk3 = _mm_packus_epi16(_mm_and_si128(layer2_chunk6, v_mask), _mm_and_si128(layer2_chunk7, v_mask)); + __m128i layer1_chunk7 = _mm_packus_epi16(_mm_srli_epi16(layer2_chunk6, 8), _mm_srli_epi16(layer2_chunk7, 8)); + + v_r0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask)); + v_b0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk0, 8), _mm_srli_epi16(layer1_chunk1, 8)); + v_r1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask)); + v_b1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk2, 8), _mm_srli_epi16(layer1_chunk3, 8)); + v_g0 = _mm_packus_epi16(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask)); + v_a0 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk4, 8), _mm_srli_epi16(layer1_chunk5, 8)); + v_g1 = _mm_packus_epi16(_mm_and_si128(layer1_chunk6, v_mask), _mm_and_si128(layer1_chunk7, v_mask)); + v_a1 = _mm_packus_epi16(_mm_srli_epi16(layer1_chunk6, 8), _mm_srli_epi16(layer1_chunk7, 8)); +} + +inline void _mm_deinterleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1) +{ + __m128i layer1_chunk0 = _mm_unpacklo_epi16(v_r0, v_g0); + __m128i layer1_chunk1 = _mm_unpackhi_epi16(v_r0, v_g0); + __m128i layer1_chunk2 = _mm_unpacklo_epi16(v_r1, v_g1); + __m128i layer1_chunk3 = _mm_unpackhi_epi16(v_r1, v_g1); + + __m128i layer2_chunk0 = _mm_unpacklo_epi16(layer1_chunk0, layer1_chunk2); + __m128i layer2_chunk1 = _mm_unpackhi_epi16(layer1_chunk0, layer1_chunk2); + __m128i layer2_chunk2 = _mm_unpacklo_epi16(layer1_chunk1, layer1_chunk3); + __m128i layer2_chunk3 = _mm_unpackhi_epi16(layer1_chunk1, layer1_chunk3); + + __m128i layer3_chunk0 = _mm_unpacklo_epi16(layer2_chunk0, layer2_chunk2); + __m128i layer3_chunk1 = _mm_unpackhi_epi16(layer2_chunk0, layer2_chunk2); + __m128i layer3_chunk2 = _mm_unpacklo_epi16(layer2_chunk1, layer2_chunk3); + __m128i layer3_chunk3 = _mm_unpackhi_epi16(layer2_chunk1, layer2_chunk3); + + v_r0 = _mm_unpacklo_epi16(layer3_chunk0, layer3_chunk2); + v_r1 = _mm_unpackhi_epi16(layer3_chunk0, layer3_chunk2); + v_g0 = _mm_unpacklo_epi16(layer3_chunk1, layer3_chunk3); + v_g1 = _mm_unpackhi_epi16(layer3_chunk1, layer3_chunk3); +} + +inline void _mm_deinterleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, + __m128i & v_g1, __m128i & v_b0, __m128i & v_b1) +{ + __m128i layer1_chunk0 = _mm_unpacklo_epi16(v_r0, v_g1); + __m128i layer1_chunk1 = _mm_unpackhi_epi16(v_r0, v_g1); + __m128i layer1_chunk2 = _mm_unpacklo_epi16(v_r1, v_b0); + __m128i layer1_chunk3 = _mm_unpackhi_epi16(v_r1, v_b0); + __m128i layer1_chunk4 = _mm_unpacklo_epi16(v_g0, v_b1); + __m128i layer1_chunk5 = _mm_unpackhi_epi16(v_g0, v_b1); + + __m128i layer2_chunk0 = _mm_unpacklo_epi16(layer1_chunk0, layer1_chunk3); + __m128i layer2_chunk1 = _mm_unpackhi_epi16(layer1_chunk0, layer1_chunk3); + __m128i layer2_chunk2 = _mm_unpacklo_epi16(layer1_chunk1, layer1_chunk4); + __m128i layer2_chunk3 = _mm_unpackhi_epi16(layer1_chunk1, layer1_chunk4); + __m128i layer2_chunk4 = _mm_unpacklo_epi16(layer1_chunk2, layer1_chunk5); + __m128i layer2_chunk5 = _mm_unpackhi_epi16(layer1_chunk2, layer1_chunk5); + + __m128i layer3_chunk0 = _mm_unpacklo_epi16(layer2_chunk0, layer2_chunk3); + __m128i layer3_chunk1 = _mm_unpackhi_epi16(layer2_chunk0, layer2_chunk3); + __m128i layer3_chunk2 = _mm_unpacklo_epi16(layer2_chunk1, layer2_chunk4); + __m128i layer3_chunk3 = _mm_unpackhi_epi16(layer2_chunk1, layer2_chunk4); + __m128i layer3_chunk4 = _mm_unpacklo_epi16(layer2_chunk2, layer2_chunk5); + __m128i layer3_chunk5 = _mm_unpackhi_epi16(layer2_chunk2, layer2_chunk5); + + v_r0 = _mm_unpacklo_epi16(layer3_chunk0, layer3_chunk3); + v_r1 = _mm_unpackhi_epi16(layer3_chunk0, layer3_chunk3); + v_g0 = _mm_unpacklo_epi16(layer3_chunk1, layer3_chunk4); + v_g1 = _mm_unpackhi_epi16(layer3_chunk1, layer3_chunk4); + v_b0 = _mm_unpacklo_epi16(layer3_chunk2, layer3_chunk5); + v_b1 = _mm_unpackhi_epi16(layer3_chunk2, layer3_chunk5); +} + +inline void _mm_deinterleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1, + __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1) +{ + __m128i layer1_chunk0 = _mm_unpacklo_epi16(v_r0, v_b0); + __m128i layer1_chunk1 = _mm_unpackhi_epi16(v_r0, v_b0); + __m128i layer1_chunk2 = _mm_unpacklo_epi16(v_r1, v_b1); + __m128i layer1_chunk3 = _mm_unpackhi_epi16(v_r1, v_b1); + __m128i layer1_chunk4 = _mm_unpacklo_epi16(v_g0, v_a0); + __m128i layer1_chunk5 = _mm_unpackhi_epi16(v_g0, v_a0); + __m128i layer1_chunk6 = _mm_unpacklo_epi16(v_g1, v_a1); + __m128i layer1_chunk7 = _mm_unpackhi_epi16(v_g1, v_a1); + + __m128i layer2_chunk0 = _mm_unpacklo_epi16(layer1_chunk0, layer1_chunk4); + __m128i layer2_chunk1 = _mm_unpackhi_epi16(layer1_chunk0, layer1_chunk4); + __m128i layer2_chunk2 = _mm_unpacklo_epi16(layer1_chunk1, layer1_chunk5); + __m128i layer2_chunk3 = _mm_unpackhi_epi16(layer1_chunk1, layer1_chunk5); + __m128i layer2_chunk4 = _mm_unpacklo_epi16(layer1_chunk2, layer1_chunk6); + __m128i layer2_chunk5 = _mm_unpackhi_epi16(layer1_chunk2, layer1_chunk6); + __m128i layer2_chunk6 = _mm_unpacklo_epi16(layer1_chunk3, layer1_chunk7); + __m128i layer2_chunk7 = _mm_unpackhi_epi16(layer1_chunk3, layer1_chunk7); + + __m128i layer3_chunk0 = _mm_unpacklo_epi16(layer2_chunk0, layer2_chunk4); + __m128i layer3_chunk1 = _mm_unpackhi_epi16(layer2_chunk0, layer2_chunk4); + __m128i layer3_chunk2 = _mm_unpacklo_epi16(layer2_chunk1, layer2_chunk5); + __m128i layer3_chunk3 = _mm_unpackhi_epi16(layer2_chunk1, layer2_chunk5); + __m128i layer3_chunk4 = _mm_unpacklo_epi16(layer2_chunk2, layer2_chunk6); + __m128i layer3_chunk5 = _mm_unpackhi_epi16(layer2_chunk2, layer2_chunk6); + __m128i layer3_chunk6 = _mm_unpacklo_epi16(layer2_chunk3, layer2_chunk7); + __m128i layer3_chunk7 = _mm_unpackhi_epi16(layer2_chunk3, layer2_chunk7); + + v_r0 = _mm_unpacklo_epi16(layer3_chunk0, layer3_chunk4); + v_r1 = _mm_unpackhi_epi16(layer3_chunk0, layer3_chunk4); + v_g0 = _mm_unpacklo_epi16(layer3_chunk1, layer3_chunk5); + v_g1 = _mm_unpackhi_epi16(layer3_chunk1, layer3_chunk5); + v_b0 = _mm_unpacklo_epi16(layer3_chunk2, layer3_chunk6); + v_b1 = _mm_unpackhi_epi16(layer3_chunk2, layer3_chunk6); + v_a0 = _mm_unpacklo_epi16(layer3_chunk3, layer3_chunk7); + v_a1 = _mm_unpackhi_epi16(layer3_chunk3, layer3_chunk7); +} + +#if CV_SSE4_1 + +inline void _mm_interleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1) +{ + __m128i v_mask = _mm_set1_epi32(0x0000ffff); + + __m128i layer3_chunk0 = _mm_packus_epi32(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask)); + __m128i layer3_chunk2 = _mm_packus_epi32(_mm_srli_epi32(v_r0, 16), _mm_srli_epi32(v_r1, 16)); + __m128i layer3_chunk1 = _mm_packus_epi32(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask)); + __m128i layer3_chunk3 = _mm_packus_epi32(_mm_srli_epi32(v_g0, 16), _mm_srli_epi32(v_g1, 16)); + + __m128i layer2_chunk0 = _mm_packus_epi32(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask)); + __m128i layer2_chunk2 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk0, 16), _mm_srli_epi32(layer3_chunk1, 16)); + __m128i layer2_chunk1 = _mm_packus_epi32(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask)); + __m128i layer2_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk2, 16), _mm_srli_epi32(layer3_chunk3, 16)); + + __m128i layer1_chunk0 = _mm_packus_epi32(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask)); + __m128i layer1_chunk2 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk0, 16), _mm_srli_epi32(layer2_chunk1, 16)); + __m128i layer1_chunk1 = _mm_packus_epi32(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask)); + __m128i layer1_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk2, 16), _mm_srli_epi32(layer2_chunk3, 16)); + + v_r0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask)); + v_g0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk0, 16), _mm_srli_epi32(layer1_chunk1, 16)); + v_r1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask)); + v_g1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk2, 16), _mm_srli_epi32(layer1_chunk3, 16)); +} + +inline void _mm_interleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, + __m128i & v_g1, __m128i & v_b0, __m128i & v_b1) +{ + __m128i v_mask = _mm_set1_epi32(0x0000ffff); + + __m128i layer3_chunk0 = _mm_packus_epi32(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask)); + __m128i layer3_chunk3 = _mm_packus_epi32(_mm_srli_epi32(v_r0, 16), _mm_srli_epi32(v_r1, 16)); + __m128i layer3_chunk1 = _mm_packus_epi32(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask)); + __m128i layer3_chunk4 = _mm_packus_epi32(_mm_srli_epi32(v_g0, 16), _mm_srli_epi32(v_g1, 16)); + __m128i layer3_chunk2 = _mm_packus_epi32(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask)); + __m128i layer3_chunk5 = _mm_packus_epi32(_mm_srli_epi32(v_b0, 16), _mm_srli_epi32(v_b1, 16)); + + __m128i layer2_chunk0 = _mm_packus_epi32(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask)); + __m128i layer2_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk0, 16), _mm_srli_epi32(layer3_chunk1, 16)); + __m128i layer2_chunk1 = _mm_packus_epi32(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask)); + __m128i layer2_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk2, 16), _mm_srli_epi32(layer3_chunk3, 16)); + __m128i layer2_chunk2 = _mm_packus_epi32(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask)); + __m128i layer2_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk4, 16), _mm_srli_epi32(layer3_chunk5, 16)); + + __m128i layer1_chunk0 = _mm_packus_epi32(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask)); + __m128i layer1_chunk3 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk0, 16), _mm_srli_epi32(layer2_chunk1, 16)); + __m128i layer1_chunk1 = _mm_packus_epi32(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask)); + __m128i layer1_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk2, 16), _mm_srli_epi32(layer2_chunk3, 16)); + __m128i layer1_chunk2 = _mm_packus_epi32(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask)); + __m128i layer1_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk4, 16), _mm_srli_epi32(layer2_chunk5, 16)); + + v_r0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask)); + v_g1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk0, 16), _mm_srli_epi32(layer1_chunk1, 16)); + v_r1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask)); + v_b0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk2, 16), _mm_srli_epi32(layer1_chunk3, 16)); + v_g0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask)); + v_b1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk4, 16), _mm_srli_epi32(layer1_chunk5, 16)); +} + +inline void _mm_interleave_epi16(__m128i & v_r0, __m128i & v_r1, __m128i & v_g0, __m128i & v_g1, + __m128i & v_b0, __m128i & v_b1, __m128i & v_a0, __m128i & v_a1) +{ + __m128i v_mask = _mm_set1_epi32(0x0000ffff); + + __m128i layer3_chunk0 = _mm_packus_epi32(_mm_and_si128(v_r0, v_mask), _mm_and_si128(v_r1, v_mask)); + __m128i layer3_chunk4 = _mm_packus_epi32(_mm_srli_epi32(v_r0, 16), _mm_srli_epi32(v_r1, 16)); + __m128i layer3_chunk1 = _mm_packus_epi32(_mm_and_si128(v_g0, v_mask), _mm_and_si128(v_g1, v_mask)); + __m128i layer3_chunk5 = _mm_packus_epi32(_mm_srli_epi32(v_g0, 16), _mm_srli_epi32(v_g1, 16)); + __m128i layer3_chunk2 = _mm_packus_epi32(_mm_and_si128(v_b0, v_mask), _mm_and_si128(v_b1, v_mask)); + __m128i layer3_chunk6 = _mm_packus_epi32(_mm_srli_epi32(v_b0, 16), _mm_srli_epi32(v_b1, 16)); + __m128i layer3_chunk3 = _mm_packus_epi32(_mm_and_si128(v_a0, v_mask), _mm_and_si128(v_a1, v_mask)); + __m128i layer3_chunk7 = _mm_packus_epi32(_mm_srli_epi32(v_a0, 16), _mm_srli_epi32(v_a1, 16)); + + __m128i layer2_chunk0 = _mm_packus_epi32(_mm_and_si128(layer3_chunk0, v_mask), _mm_and_si128(layer3_chunk1, v_mask)); + __m128i layer2_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk0, 16), _mm_srli_epi32(layer3_chunk1, 16)); + __m128i layer2_chunk1 = _mm_packus_epi32(_mm_and_si128(layer3_chunk2, v_mask), _mm_and_si128(layer3_chunk3, v_mask)); + __m128i layer2_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk2, 16), _mm_srli_epi32(layer3_chunk3, 16)); + __m128i layer2_chunk2 = _mm_packus_epi32(_mm_and_si128(layer3_chunk4, v_mask), _mm_and_si128(layer3_chunk5, v_mask)); + __m128i layer2_chunk6 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk4, 16), _mm_srli_epi32(layer3_chunk5, 16)); + __m128i layer2_chunk3 = _mm_packus_epi32(_mm_and_si128(layer3_chunk6, v_mask), _mm_and_si128(layer3_chunk7, v_mask)); + __m128i layer2_chunk7 = _mm_packus_epi32(_mm_srli_epi32(layer3_chunk6, 16), _mm_srli_epi32(layer3_chunk7, 16)); + + __m128i layer1_chunk0 = _mm_packus_epi32(_mm_and_si128(layer2_chunk0, v_mask), _mm_and_si128(layer2_chunk1, v_mask)); + __m128i layer1_chunk4 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk0, 16), _mm_srli_epi32(layer2_chunk1, 16)); + __m128i layer1_chunk1 = _mm_packus_epi32(_mm_and_si128(layer2_chunk2, v_mask), _mm_and_si128(layer2_chunk3, v_mask)); + __m128i layer1_chunk5 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk2, 16), _mm_srli_epi32(layer2_chunk3, 16)); + __m128i layer1_chunk2 = _mm_packus_epi32(_mm_and_si128(layer2_chunk4, v_mask), _mm_and_si128(layer2_chunk5, v_mask)); + __m128i layer1_chunk6 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk4, 16), _mm_srli_epi32(layer2_chunk5, 16)); + __m128i layer1_chunk3 = _mm_packus_epi32(_mm_and_si128(layer2_chunk6, v_mask), _mm_and_si128(layer2_chunk7, v_mask)); + __m128i layer1_chunk7 = _mm_packus_epi32(_mm_srli_epi32(layer2_chunk6, 16), _mm_srli_epi32(layer2_chunk7, 16)); + + v_r0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk0, v_mask), _mm_and_si128(layer1_chunk1, v_mask)); + v_b0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk0, 16), _mm_srli_epi32(layer1_chunk1, 16)); + v_r1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk2, v_mask), _mm_and_si128(layer1_chunk3, v_mask)); + v_b1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk2, 16), _mm_srli_epi32(layer1_chunk3, 16)); + v_g0 = _mm_packus_epi32(_mm_and_si128(layer1_chunk4, v_mask), _mm_and_si128(layer1_chunk5, v_mask)); + v_a0 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk4, 16), _mm_srli_epi32(layer1_chunk5, 16)); + v_g1 = _mm_packus_epi32(_mm_and_si128(layer1_chunk6, v_mask), _mm_and_si128(layer1_chunk7, v_mask)); + v_a1 = _mm_packus_epi32(_mm_srli_epi32(layer1_chunk6, 16), _mm_srli_epi32(layer1_chunk7, 16)); +} + +#endif // CV_SSE4_1 + +inline void _mm_deinterleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1) +{ + __m128 layer1_chunk0 = _mm_unpacklo_ps(v_r0, v_g0); + __m128 layer1_chunk1 = _mm_unpackhi_ps(v_r0, v_g0); + __m128 layer1_chunk2 = _mm_unpacklo_ps(v_r1, v_g1); + __m128 layer1_chunk3 = _mm_unpackhi_ps(v_r1, v_g1); + + __m128 layer2_chunk0 = _mm_unpacklo_ps(layer1_chunk0, layer1_chunk2); + __m128 layer2_chunk1 = _mm_unpackhi_ps(layer1_chunk0, layer1_chunk2); + __m128 layer2_chunk2 = _mm_unpacklo_ps(layer1_chunk1, layer1_chunk3); + __m128 layer2_chunk3 = _mm_unpackhi_ps(layer1_chunk1, layer1_chunk3); + + v_r0 = _mm_unpacklo_ps(layer2_chunk0, layer2_chunk2); + v_r1 = _mm_unpackhi_ps(layer2_chunk0, layer2_chunk2); + v_g0 = _mm_unpacklo_ps(layer2_chunk1, layer2_chunk3); + v_g1 = _mm_unpackhi_ps(layer2_chunk1, layer2_chunk3); +} + +inline void _mm_deinterleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, + __m128 & v_g1, __m128 & v_b0, __m128 & v_b1) +{ + __m128 layer1_chunk0 = _mm_unpacklo_ps(v_r0, v_g1); + __m128 layer1_chunk1 = _mm_unpackhi_ps(v_r0, v_g1); + __m128 layer1_chunk2 = _mm_unpacklo_ps(v_r1, v_b0); + __m128 layer1_chunk3 = _mm_unpackhi_ps(v_r1, v_b0); + __m128 layer1_chunk4 = _mm_unpacklo_ps(v_g0, v_b1); + __m128 layer1_chunk5 = _mm_unpackhi_ps(v_g0, v_b1); + + __m128 layer2_chunk0 = _mm_unpacklo_ps(layer1_chunk0, layer1_chunk3); + __m128 layer2_chunk1 = _mm_unpackhi_ps(layer1_chunk0, layer1_chunk3); + __m128 layer2_chunk2 = _mm_unpacklo_ps(layer1_chunk1, layer1_chunk4); + __m128 layer2_chunk3 = _mm_unpackhi_ps(layer1_chunk1, layer1_chunk4); + __m128 layer2_chunk4 = _mm_unpacklo_ps(layer1_chunk2, layer1_chunk5); + __m128 layer2_chunk5 = _mm_unpackhi_ps(layer1_chunk2, layer1_chunk5); + + v_r0 = _mm_unpacklo_ps(layer2_chunk0, layer2_chunk3); + v_r1 = _mm_unpackhi_ps(layer2_chunk0, layer2_chunk3); + v_g0 = _mm_unpacklo_ps(layer2_chunk1, layer2_chunk4); + v_g1 = _mm_unpackhi_ps(layer2_chunk1, layer2_chunk4); + v_b0 = _mm_unpacklo_ps(layer2_chunk2, layer2_chunk5); + v_b1 = _mm_unpackhi_ps(layer2_chunk2, layer2_chunk5); +} + +inline void _mm_deinterleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1, + __m128 & v_b0, __m128 & v_b1, __m128 & v_a0, __m128 & v_a1) +{ + __m128 layer1_chunk0 = _mm_unpacklo_ps(v_r0, v_b0); + __m128 layer1_chunk1 = _mm_unpackhi_ps(v_r0, v_b0); + __m128 layer1_chunk2 = _mm_unpacklo_ps(v_r1, v_b1); + __m128 layer1_chunk3 = _mm_unpackhi_ps(v_r1, v_b1); + __m128 layer1_chunk4 = _mm_unpacklo_ps(v_g0, v_a0); + __m128 layer1_chunk5 = _mm_unpackhi_ps(v_g0, v_a0); + __m128 layer1_chunk6 = _mm_unpacklo_ps(v_g1, v_a1); + __m128 layer1_chunk7 = _mm_unpackhi_ps(v_g1, v_a1); + + __m128 layer2_chunk0 = _mm_unpacklo_ps(layer1_chunk0, layer1_chunk4); + __m128 layer2_chunk1 = _mm_unpackhi_ps(layer1_chunk0, layer1_chunk4); + __m128 layer2_chunk2 = _mm_unpacklo_ps(layer1_chunk1, layer1_chunk5); + __m128 layer2_chunk3 = _mm_unpackhi_ps(layer1_chunk1, layer1_chunk5); + __m128 layer2_chunk4 = _mm_unpacklo_ps(layer1_chunk2, layer1_chunk6); + __m128 layer2_chunk5 = _mm_unpackhi_ps(layer1_chunk2, layer1_chunk6); + __m128 layer2_chunk6 = _mm_unpacklo_ps(layer1_chunk3, layer1_chunk7); + __m128 layer2_chunk7 = _mm_unpackhi_ps(layer1_chunk3, layer1_chunk7); + + v_r0 = _mm_unpacklo_ps(layer2_chunk0, layer2_chunk4); + v_r1 = _mm_unpackhi_ps(layer2_chunk0, layer2_chunk4); + v_g0 = _mm_unpacklo_ps(layer2_chunk1, layer2_chunk5); + v_g1 = _mm_unpackhi_ps(layer2_chunk1, layer2_chunk5); + v_b0 = _mm_unpacklo_ps(layer2_chunk2, layer2_chunk6); + v_b1 = _mm_unpackhi_ps(layer2_chunk2, layer2_chunk6); + v_a0 = _mm_unpacklo_ps(layer2_chunk3, layer2_chunk7); + v_a1 = _mm_unpackhi_ps(layer2_chunk3, layer2_chunk7); +} + +inline void _mm_interleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1) +{ + enum { mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1) }; + + __m128 layer2_chunk0 = _mm_shuffle_ps(v_r0, v_r1, mask_lo); + __m128 layer2_chunk2 = _mm_shuffle_ps(v_r0, v_r1, mask_hi); + __m128 layer2_chunk1 = _mm_shuffle_ps(v_g0, v_g1, mask_lo); + __m128 layer2_chunk3 = _mm_shuffle_ps(v_g0, v_g1, mask_hi); + + __m128 layer1_chunk0 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_lo); + __m128 layer1_chunk2 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_hi); + __m128 layer1_chunk1 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_lo); + __m128 layer1_chunk3 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_hi); + + v_r0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_lo); + v_g0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_hi); + v_r1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_lo); + v_g1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_hi); +} + +inline void _mm_interleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, + __m128 & v_g1, __m128 & v_b0, __m128 & v_b1) +{ + enum { mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1) }; + + __m128 layer2_chunk0 = _mm_shuffle_ps(v_r0, v_r1, mask_lo); + __m128 layer2_chunk3 = _mm_shuffle_ps(v_r0, v_r1, mask_hi); + __m128 layer2_chunk1 = _mm_shuffle_ps(v_g0, v_g1, mask_lo); + __m128 layer2_chunk4 = _mm_shuffle_ps(v_g0, v_g1, mask_hi); + __m128 layer2_chunk2 = _mm_shuffle_ps(v_b0, v_b1, mask_lo); + __m128 layer2_chunk5 = _mm_shuffle_ps(v_b0, v_b1, mask_hi); + + __m128 layer1_chunk0 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_lo); + __m128 layer1_chunk3 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_hi); + __m128 layer1_chunk1 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_lo); + __m128 layer1_chunk4 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_hi); + __m128 layer1_chunk2 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_lo); + __m128 layer1_chunk5 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_hi); + + v_r0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_lo); + v_g1 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_hi); + v_r1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_lo); + v_b0 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_hi); + v_g0 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_lo); + v_b1 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_hi); +} + +inline void _mm_interleave_ps(__m128 & v_r0, __m128 & v_r1, __m128 & v_g0, __m128 & v_g1, + __m128 & v_b0, __m128 & v_b1, __m128 & v_a0, __m128 & v_a1) +{ + enum { mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1) }; + + __m128 layer2_chunk0 = _mm_shuffle_ps(v_r0, v_r1, mask_lo); + __m128 layer2_chunk4 = _mm_shuffle_ps(v_r0, v_r1, mask_hi); + __m128 layer2_chunk1 = _mm_shuffle_ps(v_g0, v_g1, mask_lo); + __m128 layer2_chunk5 = _mm_shuffle_ps(v_g0, v_g1, mask_hi); + __m128 layer2_chunk2 = _mm_shuffle_ps(v_b0, v_b1, mask_lo); + __m128 layer2_chunk6 = _mm_shuffle_ps(v_b0, v_b1, mask_hi); + __m128 layer2_chunk3 = _mm_shuffle_ps(v_a0, v_a1, mask_lo); + __m128 layer2_chunk7 = _mm_shuffle_ps(v_a0, v_a1, mask_hi); + + __m128 layer1_chunk0 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_lo); + __m128 layer1_chunk4 = _mm_shuffle_ps(layer2_chunk0, layer2_chunk1, mask_hi); + __m128 layer1_chunk1 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_lo); + __m128 layer1_chunk5 = _mm_shuffle_ps(layer2_chunk2, layer2_chunk3, mask_hi); + __m128 layer1_chunk2 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_lo); + __m128 layer1_chunk6 = _mm_shuffle_ps(layer2_chunk4, layer2_chunk5, mask_hi); + __m128 layer1_chunk3 = _mm_shuffle_ps(layer2_chunk6, layer2_chunk7, mask_lo); + __m128 layer1_chunk7 = _mm_shuffle_ps(layer2_chunk6, layer2_chunk7, mask_hi); + + v_r0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_lo); + v_b0 = _mm_shuffle_ps(layer1_chunk0, layer1_chunk1, mask_hi); + v_r1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_lo); + v_b1 = _mm_shuffle_ps(layer1_chunk2, layer1_chunk3, mask_hi); + v_g0 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_lo); + v_a0 = _mm_shuffle_ps(layer1_chunk4, layer1_chunk5, mask_hi); + v_g1 = _mm_shuffle_ps(layer1_chunk6, layer1_chunk7, mask_lo); + v_a1 = _mm_shuffle_ps(layer1_chunk6, layer1_chunk7, mask_hi); +} + +#endif // CV_SSE2 + +//! @} + +#endif //OPENCV_CORE_SSE_UTILS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/traits.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/traits.hpp new file mode 100755 index 0000000..52ab083 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/traits.hpp @@ -0,0 +1,417 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_TRAITS_HPP +#define OPENCV_CORE_TRAITS_HPP + +#include "opencv2/core/cvdef.h" + +namespace cv +{ + +//#define OPENCV_TRAITS_ENABLE_DEPRECATED + +//! @addtogroup core_basic +//! @{ + +/** @brief Template "trait" class for OpenCV primitive data types. + +@note Deprecated. This is replaced by "single purpose" traits: traits::Type and traits::Depth + +A primitive OpenCV data type is one of unsigned char, bool, signed char, unsigned short, signed +short, int, float, double, or a tuple of values of one of these types, where all the values in the +tuple have the same type. Any primitive type from the list can be defined by an identifier in the +form CV_\{U|S|F}C(\), for example: uchar \~ CV_8UC1, 3-element +floating-point tuple \~ CV_32FC3, and so on. A universal OpenCV structure that is able to store a +single instance of such a primitive data type is Vec. Multiple instances of such a type can be +stored in a std::vector, Mat, Mat_, SparseMat, SparseMat_, or any other container that is able to +store Vec instances. + +The DataType class is basically used to provide a description of such primitive data types without +adding any fields or methods to the corresponding classes (and it is actually impossible to add +anything to primitive C/C++ data types). This technique is known in C++ as class traits. It is not +DataType itself that is used but its specialized versions, such as: +@code + template<> class DataType + { + typedef uchar value_type; + typedef int work_type; + typedef uchar channel_type; + enum { channel_type = CV_8U, channels = 1, fmt='u', type = CV_8U }; + }; + ... + template DataType > + { + typedef std::complex<_Tp> value_type; + typedef std::complex<_Tp> work_type; + typedef _Tp channel_type; + // DataDepth is another helper trait class + enum { depth = DataDepth<_Tp>::value, channels=2, + fmt=(channels-1)*256+DataDepth<_Tp>::fmt, + type=CV_MAKETYPE(depth, channels) }; + }; + ... +@endcode +The main purpose of this class is to convert compilation-time type information to an +OpenCV-compatible data type identifier, for example: +@code + // allocates a 30x40 floating-point matrix + Mat A(30, 40, DataType::type); + + Mat B = Mat_ >(3, 3); + // the statement below will print 6, 2 , that is depth == CV_64F, channels == 2 + cout << B.depth() << ", " << B.channels() << endl; +@endcode +So, such traits are used to tell OpenCV which data type you are working with, even if such a type is +not native to OpenCV. For example, the matrix B initialization above is compiled because OpenCV +defines the proper specialized template class DataType\ \> . This mechanism is also +useful (and used in OpenCV this way) for generic algorithms implementations. + +@note Default values were dropped to stop confusing developers about using of unsupported types (see #7599) +*/ +template class DataType +{ +public: +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + typedef _Tp value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 1, + depth = -1, + channels = 1, + fmt = 0, + type = CV_MAKETYPE(depth, channels) + }; +#endif +}; + +template<> class DataType +{ +public: + typedef bool value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_8U, + channels = 1, + fmt = (int)'u', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef uchar value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_8U, + channels = 1, + fmt = (int)'u', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef schar value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_8S, + channels = 1, + fmt = (int)'c', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef schar value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_8S, + channels = 1, + fmt = (int)'c', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef ushort value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_16U, + channels = 1, + fmt = (int)'w', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef short value_type; + typedef int work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_16S, + channels = 1, + fmt = (int)'s', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef int value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_32S, + channels = 1, + fmt = (int)'i', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef float value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_32F, + channels = 1, + fmt = (int)'f', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef double value_type; + typedef value_type work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_64F, + channels = 1, + fmt = (int)'d', + type = CV_MAKETYPE(depth, channels) + }; +}; + +template<> class DataType +{ +public: + typedef float16_t value_type; + typedef float work_type; + typedef value_type channel_type; + typedef value_type vec_type; + enum { generic_type = 0, + depth = CV_16F, + channels = 1, + fmt = (int)'h', + type = CV_MAKETYPE(depth, channels) + }; +}; + +/** @brief A helper class for cv::DataType + +The class is specialized for each fundamental numerical data type supported by OpenCV. It provides +DataDepth::value constant. +*/ +template class DataDepth +{ +public: + enum + { + value = DataType<_Tp>::depth, + fmt = DataType<_Tp>::fmt + }; +}; + + +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + +template class TypeDepth +{ +#ifdef OPENCV_TRAITS_ENABLE_LEGACY_DEFAULTS + enum { depth = CV_USRTYPE1 }; + typedef void value_type; +#endif +}; + +template<> class TypeDepth +{ + enum { depth = CV_8U }; + typedef uchar value_type; +}; + +template<> class TypeDepth +{ + enum { depth = CV_8S }; + typedef schar value_type; +}; + +template<> class TypeDepth +{ + enum { depth = CV_16U }; + typedef ushort value_type; +}; + +template<> class TypeDepth +{ + enum { depth = CV_16S }; + typedef short value_type; +}; + +template<> class TypeDepth +{ + enum { depth = CV_32S }; + typedef int value_type; +}; + +template<> class TypeDepth +{ + enum { depth = CV_32F }; + typedef float value_type; +}; + +template<> class TypeDepth +{ + enum { depth = CV_64F }; + typedef double value_type; +}; + +template<> class TypeDepth +{ + enum { depth = CV_16F }; + typedef float16_t value_type; +}; + +#endif + +//! @} + +namespace traits { + +namespace internal { +#define CV_CREATE_MEMBER_CHECK(X) \ +template class CheckMember_##X { \ + struct Fallback { int X; }; \ + struct Derived : T, Fallback { }; \ + template struct Check; \ + typedef char CV_NO[1]; \ + typedef char CV_YES[2]; \ + template static CV_NO & func(Check *); \ + template static CV_YES & func(...); \ +public: \ + typedef CheckMember_##X type; \ + enum { value = sizeof(func(0)) == sizeof(CV_YES) }; \ +}; + +CV_CREATE_MEMBER_CHECK(fmt) +CV_CREATE_MEMBER_CHECK(type) + +} // namespace internal + + +template +struct Depth +{ enum { value = DataType::depth }; }; + +template +struct Type +{ enum { value = DataType::type }; }; + +/** Similar to traits::Type but has value = -1 in case of unknown type (instead of compiler error) */ +template >::value > +struct SafeType {}; + +template +struct SafeType +{ enum { value = -1 }; }; + +template +struct SafeType +{ enum { value = Type::value }; }; + + +template >::value > +struct SafeFmt {}; + +template +struct SafeFmt +{ enum { fmt = 0 }; }; + +template +struct SafeFmt +{ enum { fmt = DataType::fmt }; }; + + +} // namespace + +} // cv + +#endif // OPENCV_CORE_TRAITS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/types.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/types.hpp new file mode 100755 index 0000000..b1fa676 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/types.hpp @@ -0,0 +1,2476 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_TYPES_HPP +#define OPENCV_CORE_TYPES_HPP + +#ifndef __cplusplus +# error types.hpp header must be compiled as C++ +#endif + +#include +#include +#include +#include + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/cvstd.hpp" +#include "opencv2/core/matx.hpp" + +namespace cv +{ + +//! @addtogroup core_basic +//! @{ + +//////////////////////////////// Complex ////////////////////////////// + +/** @brief A complex number class. + + The template class is similar and compatible with std::complex, however it provides slightly + more convenient access to the real and imaginary parts using through the simple field access, as opposite + to std::complex::real() and std::complex::imag(). +*/ +template class Complex +{ +public: + + //! default constructor + Complex(); + Complex( _Tp _re, _Tp _im = 0 ); + + //! conversion to another data type + template operator Complex() const; + //! conjugation + Complex conj() const; + + _Tp re, im; //< the real and the imaginary parts +}; + +typedef Complex Complexf; +typedef Complex Complexd; + +template class DataType< Complex<_Tp> > +{ +public: + typedef Complex<_Tp> value_type; + typedef value_type work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + channels = 2, + fmt = DataType::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template +struct Depth< Complex<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Complex<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; }; +} // namespace + + +//////////////////////////////// Point_ //////////////////////////////// + +/** @brief Template class for 2D points specified by its coordinates `x` and `y`. + +An instance of the class is interchangeable with C structures, CvPoint and CvPoint2D32f . There is +also a cast operator to convert point coordinates to the specified type. The conversion from +floating-point coordinates to integer coordinates is done by rounding. Commonly, the conversion +uses this operation for each of the coordinates. Besides the class members listed in the +declaration above, the following operations on points are implemented: +@code + pt1 = pt2 + pt3; + pt1 = pt2 - pt3; + pt1 = pt2 * a; + pt1 = a * pt2; + pt1 = pt2 / a; + pt1 += pt2; + pt1 -= pt2; + pt1 *= a; + pt1 /= a; + double value = norm(pt); // L2 norm + pt1 == pt2; + pt1 != pt2; +@endcode +For your convenience, the following type aliases are defined: +@code + typedef Point_ Point2i; + typedef Point2i Point; + typedef Point_ Point2f; + typedef Point_ Point2d; +@endcode +Example: +@code + Point2f a(0.3f, 0.f), b(0.f, 0.4f); + Point pt = (a + b)*10.f; + cout << pt.x << ", " << pt.y << endl; +@endcode +*/ +template class Point_ +{ +public: + typedef _Tp value_type; + + //! default constructor + Point_(); + Point_(_Tp _x, _Tp _y); + Point_(const Point_& pt); + Point_(Point_&& pt) CV_NOEXCEPT; + Point_(const Size_<_Tp>& sz); + Point_(const Vec<_Tp, 2>& v); + + Point_& operator = (const Point_& pt); + Point_& operator = (Point_&& pt) CV_NOEXCEPT; + //! conversion to another data type + template operator Point_<_Tp2>() const; + + //! conversion to the old-style C structures + operator Vec<_Tp, 2>() const; + + //! dot product + _Tp dot(const Point_& pt) const; + //! dot product computed in double-precision arithmetics + double ddot(const Point_& pt) const; + //! cross-product + double cross(const Point_& pt) const; + //! checks whether the point is inside the specified rectangle + bool inside(const Rect_<_Tp>& r) const; + _Tp x; //!< x coordinate of the point + _Tp y; //!< y coordinate of the point +}; + +typedef Point_ Point2i; +typedef Point_ Point2l; +typedef Point_ Point2f; +typedef Point_ Point2d; +typedef Point2i Point; + +template class DataType< Point_<_Tp> > +{ +public: + typedef Point_<_Tp> value_type; + typedef Point_::work_type> work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + channels = 2, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template +struct Depth< Point_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Point_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; }; +} // namespace + + +//////////////////////////////// Point3_ //////////////////////////////// + +/** @brief Template class for 3D points specified by its coordinates `x`, `y` and `z`. + +An instance of the class is interchangeable with the C structure CvPoint2D32f . Similarly to +Point_ , the coordinates of 3D points can be converted to another type. The vector arithmetic and +comparison operations are also supported. + +The following Point3_\<\> aliases are available: +@code + typedef Point3_ Point3i; + typedef Point3_ Point3f; + typedef Point3_ Point3d; +@endcode +@see cv::Point3i, cv::Point3f and cv::Point3d +*/ +template class Point3_ +{ +public: + typedef _Tp value_type; + + //! default constructor + Point3_(); + Point3_(_Tp _x, _Tp _y, _Tp _z); + Point3_(const Point3_& pt); + Point3_(Point3_&& pt) CV_NOEXCEPT; + explicit Point3_(const Point_<_Tp>& pt); + Point3_(const Vec<_Tp, 3>& v); + + Point3_& operator = (const Point3_& pt); + Point3_& operator = (Point3_&& pt) CV_NOEXCEPT; + //! conversion to another data type + template operator Point3_<_Tp2>() const; + //! conversion to cv::Vec<> + operator Vec<_Tp, 3>() const; + + //! dot product + _Tp dot(const Point3_& pt) const; + //! dot product computed in double-precision arithmetics + double ddot(const Point3_& pt) const; + //! cross product of the 2 3D points + Point3_ cross(const Point3_& pt) const; + _Tp x; //!< x coordinate of the 3D point + _Tp y; //!< y coordinate of the 3D point + _Tp z; //!< z coordinate of the 3D point +}; + +typedef Point3_ Point3i; +typedef Point3_ Point3f; +typedef Point3_ Point3d; + +template class DataType< Point3_<_Tp> > +{ +public: + typedef Point3_<_Tp> value_type; + typedef Point3_::work_type> work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + channels = 3, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template +struct Depth< Point3_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Point3_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 3) }; }; +} // namespace + +//////////////////////////////// Size_ //////////////////////////////// + +/** @brief Template class for specifying the size of an image or rectangle. + +The class includes two members called width and height. The structure can be converted to and from +the old OpenCV structures CvSize and CvSize2D32f . The same set of arithmetic and comparison +operations as for Point_ is available. + +OpenCV defines the following Size_\<\> aliases: +@code + typedef Size_ Size2i; + typedef Size2i Size; + typedef Size_ Size2f; +@endcode +*/ +template class Size_ +{ +public: + typedef _Tp value_type; + + //! default constructor + Size_(); + Size_(_Tp _width, _Tp _height); + Size_(const Size_& sz); + Size_(Size_&& sz) CV_NOEXCEPT; + Size_(const Point_<_Tp>& pt); + + Size_& operator = (const Size_& sz); + Size_& operator = (Size_&& sz) CV_NOEXCEPT; + //! the area (width*height) + _Tp area() const; + //! aspect ratio (width/height) + double aspectRatio() const; + //! true if empty + bool empty() const; + + //! conversion of another data type. + template operator Size_<_Tp2>() const; + + _Tp width; //!< the width + _Tp height; //!< the height +}; + +typedef Size_ Size2i; +typedef Size_ Size2l; +typedef Size_ Size2f; +typedef Size_ Size2d; +typedef Size2i Size; + +template class DataType< Size_<_Tp> > +{ +public: + typedef Size_<_Tp> value_type; + typedef Size_::work_type> work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + channels = 2, + fmt = DataType::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template +struct Depth< Size_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Size_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; }; +} // namespace + +//////////////////////////////// Rect_ //////////////////////////////// + +/** @brief Template class for 2D rectangles + +described by the following parameters: +- Coordinates of the top-left corner. This is a default interpretation of Rect_::x and Rect_::y + in OpenCV. Though, in your algorithms you may count x and y from the bottom-left corner. +- Rectangle width and height. + +OpenCV typically assumes that the top and left boundary of the rectangle are inclusive, while the +right and bottom boundaries are not. For example, the method Rect_::contains returns true if + +\f[x \leq pt.x < x+width, + y \leq pt.y < y+height\f] + +Virtually every loop over an image ROI in OpenCV (where ROI is specified by Rect_\ ) is +implemented as: +@code + for(int y = roi.y; y < roi.y + roi.height; y++) + for(int x = roi.x; x < roi.x + roi.width; x++) + { + // ... + } +@endcode +In addition to the class members, the following operations on rectangles are implemented: +- \f$\texttt{rect} = \texttt{rect} \pm \texttt{point}\f$ (shifting a rectangle by a certain offset) +- \f$\texttt{rect} = \texttt{rect} \pm \texttt{size}\f$ (expanding or shrinking a rectangle by a + certain amount) +- rect += point, rect -= point, rect += size, rect -= size (augmenting operations) +- rect = rect1 & rect2 (rectangle intersection) +- rect = rect1 | rect2 (minimum area rectangle containing rect1 and rect2 ) +- rect &= rect1, rect |= rect1 (and the corresponding augmenting operations) +- rect == rect1, rect != rect1 (rectangle comparison) + +This is an example how the partial ordering on rectangles can be established (rect1 \f$\subseteq\f$ +rect2): +@code + template inline bool + operator <= (const Rect_<_Tp>& r1, const Rect_<_Tp>& r2) + { + return (r1 & r2) == r1; + } +@endcode +For your convenience, the Rect_\<\> alias is available: cv::Rect +*/ +template class Rect_ +{ +public: + typedef _Tp value_type; + + //! default constructor + Rect_(); + Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height); + Rect_(const Rect_& r); + Rect_(Rect_&& r) CV_NOEXCEPT; + Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz); + Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2); + + Rect_& operator = ( const Rect_& r ); + Rect_& operator = ( Rect_&& r ) CV_NOEXCEPT; + //! the top-left corner + Point_<_Tp> tl() const; + //! the bottom-right corner + Point_<_Tp> br() const; + + //! size (width, height) of the rectangle + Size_<_Tp> size() const; + //! area (width*height) of the rectangle + _Tp area() const; + //! true if empty + bool empty() const; + + //! conversion to another data type + template operator Rect_<_Tp2>() const; + + //! checks whether the rectangle contains the point + bool contains(const Point_<_Tp>& pt) const; + + _Tp x; //!< x coordinate of the top-left corner + _Tp y; //!< y coordinate of the top-left corner + _Tp width; //!< width of the rectangle + _Tp height; //!< height of the rectangle +}; + +typedef Rect_ Rect2i; +typedef Rect_ Rect2f; +typedef Rect_ Rect2d; +typedef Rect2i Rect; + +template class DataType< Rect_<_Tp> > +{ +public: + typedef Rect_<_Tp> value_type; + typedef Rect_::work_type> work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + channels = 4, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template +struct Depth< Rect_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Rect_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; }; +} // namespace + +///////////////////////////// RotatedRect ///////////////////////////// + +/** @brief The class represents rotated (i.e. not up-right) rectangles on a plane. + +Each rectangle is specified by the center point (mass center), length of each side (represented by +#Size2f structure) and the rotation angle in degrees. + +The sample below demonstrates how to use RotatedRect: +@snippet snippets/core_various.cpp RotatedRect_demo +![image](pics/rotatedrect.png) + +@sa CamShift, fitEllipse, minAreaRect, CvBox2D +*/ +class CV_EXPORTS RotatedRect +{ +public: + //! default constructor + RotatedRect(); + /** full constructor + @param center The rectangle mass center. + @param size Width and height of the rectangle. + @param angle The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc., + the rectangle becomes an up-right rectangle. + */ + RotatedRect(const Point2f& center, const Size2f& size, float angle); + /** + Any 3 end points of the RotatedRect. They must be given in order (either clockwise or + anticlockwise). + */ + RotatedRect(const Point2f& point1, const Point2f& point2, const Point2f& point3); + + /** returns 4 vertices of the rectangle + @param pts The points array for storing rectangle vertices. The order is bottomLeft, topLeft, topRight, bottomRight. + */ + void points(Point2f pts[]) const; + //! returns the minimal up-right integer rectangle containing the rotated rectangle + Rect boundingRect() const; + //! returns the minimal (exact) floating point rectangle containing the rotated rectangle, not intended for use with images + Rect_ boundingRect2f() const; + //! returns the rectangle mass center + Point2f center; + //! returns width and height of the rectangle + Size2f size; + //! returns the rotation angle. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle. + float angle; +}; + +template<> class DataType< RotatedRect > +{ +public: + typedef RotatedRect value_type; + typedef value_type work_type; + typedef float channel_type; + + enum { generic_type = 0, + channels = (int)sizeof(value_type)/sizeof(channel_type), // 5 + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template<> +struct Depth< RotatedRect > { enum { value = Depth::value }; }; +template<> +struct Type< RotatedRect > { enum { value = CV_MAKETYPE(Depth::value, (int)sizeof(RotatedRect)/sizeof(float)) }; }; +} // namespace + + +//////////////////////////////// Range ///////////////////////////////// + +/** @brief Template class specifying a continuous subsequence (slice) of a sequence. + +The class is used to specify a row or a column span in a matrix ( Mat ) and for many other purposes. +Range(a,b) is basically the same as a:b in Matlab or a..b in Python. As in Python, start is an +inclusive left boundary of the range and end is an exclusive right boundary of the range. Such a +half-opened interval is usually denoted as \f$[start,end)\f$ . + +The static method Range::all() returns a special variable that means "the whole sequence" or "the +whole range", just like " : " in Matlab or " ... " in Python. All the methods and functions in +OpenCV that take Range support this special Range::all() value. But, of course, in case of your own +custom processing, you will probably have to check and handle it explicitly: +@code + void my_function(..., const Range& r, ....) + { + if(r == Range::all()) { + // process all the data + } + else { + // process [r.start, r.end) + } + } +@endcode +*/ +class CV_EXPORTS Range +{ +public: + Range(); + Range(int _start, int _end); + int size() const; + bool empty() const; + static Range all(); + + int start, end; +}; + +template<> class DataType +{ +public: + typedef Range value_type; + typedef value_type work_type; + typedef int channel_type; + + enum { generic_type = 0, + channels = 2, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template<> +struct Depth< Range > { enum { value = Depth::value }; }; +template<> +struct Type< Range > { enum { value = CV_MAKETYPE(Depth::value, 2) }; }; +} // namespace + + +//////////////////////////////// Scalar_ /////////////////////////////// + +/** @brief Template class for a 4-element vector derived from Vec. + +Being derived from Vec\<_Tp, 4\> , Scalar\_ and Scalar can be used just as typical 4-element +vectors. In addition, they can be converted to/from CvScalar . The type Scalar is widely used in +OpenCV to pass pixel values. +*/ +template class Scalar_ : public Vec<_Tp, 4> +{ +public: + //! default constructor + Scalar_(); + Scalar_(_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0); + Scalar_(_Tp v0); + + Scalar_(const Scalar_& s); + Scalar_(Scalar_&& s) CV_NOEXCEPT; + + Scalar_& operator=(const Scalar_& s); + Scalar_& operator=(Scalar_&& s) CV_NOEXCEPT; + + template + Scalar_(const Vec<_Tp2, cn>& v); + + //! returns a scalar with all elements set to v0 + static Scalar_<_Tp> all(_Tp v0); + + //! conversion to another data type + template operator Scalar_() const; + + //! per-element product + Scalar_<_Tp> mul(const Scalar_<_Tp>& a, double scale=1 ) const; + + //! returns (v0, -v1, -v2, -v3) + Scalar_<_Tp> conj() const; + + //! returns true iff v1 == v2 == v3 == 0 + bool isReal() const; +}; + +typedef Scalar_ Scalar; + +template class DataType< Scalar_<_Tp> > +{ +public: + typedef Scalar_<_Tp> value_type; + typedef Scalar_::work_type> work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + channels = 4, + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template +struct Depth< Scalar_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Scalar_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; }; +} // namespace + + +/////////////////////////////// KeyPoint //////////////////////////////// + +/** @brief Data structure for salient point detectors. + +The class instance stores a keypoint, i.e. a point feature found by one of many available keypoint +detectors, such as Harris corner detector, #FAST, %StarDetector, %SURF, %SIFT etc. + +The keypoint is characterized by the 2D position, scale (proportional to the diameter of the +neighborhood that needs to be taken into account), orientation and some other parameters. The +keypoint neighborhood is then analyzed by another algorithm that builds a descriptor (usually +represented as a feature vector). The keypoints representing the same object in different images +can then be matched using %KDTree or another method. +*/ +class CV_EXPORTS_W_SIMPLE KeyPoint +{ +public: + //! the default constructor + CV_WRAP 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 + */ + KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1); + /** + @param x x-coordinate of the keypoint + @param y y-coordinate of the keypoint + @param _size keypoint diameter + @param _angle keypoint orientation + @param _response keypoint detector response on the keypoint (that is, strength of the keypoint) + @param _octave pyramid octave in which the keypoint has been detected + @param _class_id object id + */ + CV_WRAP KeyPoint(float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1); + + size_t hash() const; + + /** + This method converts vector of keypoints to vector of points or the reverse, where each keypoint is + assigned the same size and the same orientation. + + @param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB + @param points2f Array of (x,y) coordinates of each keypoint + @param keypointIndexes Array of indexes of keypoints to be converted to points. (Acts like a mask to + convert only specified keypoints) + */ + CV_WRAP static void convert(const std::vector& keypoints, + CV_OUT std::vector& points2f, + const std::vector& keypointIndexes=std::vector()); + /** @overload + @param points2f Array of (x,y) coordinates of each keypoint + @param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB + @param size keypoint diameter + @param response keypoint detector response on the keypoint (that is, strength of the keypoint) + @param octave pyramid octave in which the keypoint has been detected + @param class_id object id + */ + CV_WRAP static void convert(const std::vector& points2f, + CV_OUT std::vector& keypoints, + float size=1, float response=1, int octave=0, int class_id=-1); + + /** + This method computes overlap for pair of keypoints. Overlap is the ratio between area of keypoint + regions' intersection and area of keypoint regions' union (considering keypoint region as circle). + If they don't overlap, we get zero. If they coincide at same location with same size, we get 1. + @param kp1 First keypoint + @param kp2 Second keypoint + */ + CV_WRAP static float overlap(const KeyPoint& kp1, const KeyPoint& kp2); + + CV_PROP_RW Point2f pt; //!< coordinates of the keypoints + CV_PROP_RW float size; //!< diameter of the meaningful keypoint neighborhood + CV_PROP_RW float angle; //!< computed orientation of the keypoint (-1 if not applicable); + //!< it's in [0,360) degrees and measured relative to + //!< image coordinate system, ie in clockwise. + CV_PROP_RW float response; //!< the response by which the most strong keypoints have been selected. Can be used for the further sorting or subsampling + CV_PROP_RW int octave; //!< octave (pyramid layer) from which the keypoint has been extracted + CV_PROP_RW int class_id; //!< object class (if the keypoints need to be clustered by an object they belong to) +}; + +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED +template<> class DataType +{ +public: + typedef KeyPoint value_type; + typedef float work_type; + typedef float channel_type; + + enum { generic_type = 0, + depth = DataType::depth, + channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 7 + fmt = DataType::fmt + ((channels - 1) << 8), + type = CV_MAKETYPE(depth, channels) + }; + + typedef Vec vec_type; +}; +#endif + + +//////////////////////////////// DMatch ///////////////////////////////// + +/** @brief Class for matching keypoint descriptors + +query descriptor index, train descriptor index, train image index, and distance between +descriptors. +*/ +class CV_EXPORTS_W_SIMPLE DMatch +{ +public: + CV_WRAP DMatch(); + CV_WRAP DMatch(int _queryIdx, int _trainIdx, float _distance); + CV_WRAP DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance); + + CV_PROP_RW int queryIdx; //!< query descriptor index + CV_PROP_RW int trainIdx; //!< train descriptor index + CV_PROP_RW int imgIdx; //!< train image index + + CV_PROP_RW float distance; + + // less is better + bool operator<(const DMatch &m) const; +}; + +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED +template<> class DataType +{ +public: + typedef DMatch value_type; + typedef int work_type; + typedef int channel_type; + + enum { generic_type = 0, + depth = DataType::depth, + channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 4 + fmt = DataType::fmt + ((channels - 1) << 8), + type = CV_MAKETYPE(depth, channels) + }; + + typedef Vec vec_type; +}; +#endif + + +///////////////////////////// TermCriteria ////////////////////////////// + +/** @brief The class defining termination criteria for iterative algorithms. + +You can initialize it by default constructor and then override any parameters, or the structure may +be fully initialized using the advanced variant of the constructor. +*/ +class CV_EXPORTS TermCriteria +{ +public: + /** + Criteria type, can be one of: COUNT, EPS or COUNT + EPS + */ + enum Type + { + COUNT=1, //!< the maximum number of iterations or elements to compute + MAX_ITER=COUNT, //!< ditto + EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops + }; + + //! default constructor + TermCriteria(); + /** + @param type The type of termination criteria, one of TermCriteria::Type + @param maxCount The maximum number of iterations or elements to compute. + @param epsilon The desired accuracy or change in parameters at which the iterative algorithm stops. + */ + TermCriteria(int type, int maxCount, double epsilon); + + inline bool isValid() const + { + const bool isCount = (type & COUNT) && maxCount > 0; + const bool isEps = (type & EPS) && !cvIsNaN(epsilon); + return isCount || isEps; + } + + int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS + int maxCount; //!< the maximum number of iterations/elements + double epsilon; //!< the desired accuracy +}; + + +//! @} core_basic + +///////////////////////// raster image moments ////////////////////////// + +//! @addtogroup imgproc_shape +//! @{ + +/** @brief struct returned by cv::moments + +The spatial moments \f$\texttt{Moments::m}_{ji}\f$ are computed as: + +\f[\texttt{m} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot x^j \cdot y^i \right )\f] + +The central moments \f$\texttt{Moments::mu}_{ji}\f$ are computed as: + +\f[\texttt{mu} _{ji}= \sum _{x,y} \left ( \texttt{array} (x,y) \cdot (x - \bar{x} )^j \cdot (y - \bar{y} )^i \right )\f] + +where \f$(\bar{x}, \bar{y})\f$ is the mass center: + +\f[\bar{x} = \frac{\texttt{m}_{10}}{\texttt{m}_{00}} , \; \bar{y} = \frac{\texttt{m}_{01}}{\texttt{m}_{00}}\f] + +The normalized central moments \f$\texttt{Moments::nu}_{ij}\f$ are computed as: + +\f[\texttt{nu} _{ji}= \frac{\texttt{mu}_{ji}}{\texttt{m}_{00}^{(i+j)/2+1}} .\f] + +@note +\f$\texttt{mu}_{00}=\texttt{m}_{00}\f$, \f$\texttt{nu}_{00}=1\f$ +\f$\texttt{nu}_{10}=\texttt{mu}_{10}=\texttt{mu}_{01}=\texttt{mu}_{10}=0\f$ , hence the values are not +stored. + +The moments of a contour are defined in the same way but computed using the Green's formula (see +). So, due to a limited raster resolution, the moments +computed for a contour are slightly different from the moments computed for the same rasterized +contour. + +@note +Since the contour moments are computed using Green formula, you may get seemingly odd results for +contours with self-intersections, e.g. a zero area (m00) for butterfly-shaped contours. + */ +class CV_EXPORTS_W_MAP Moments +{ +public: + //! the default constructor + Moments(); + //! the full constructor + Moments(double m00, double m10, double m01, double m20, double m11, + double m02, double m30, double m21, double m12, double m03 ); + ////! the conversion from CvMoments + //Moments( const CvMoments& moments ); + ////! the conversion to CvMoments + //operator CvMoments() const; + + //! @name spatial moments + //! @{ + CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; + //! @} + + //! @name central moments + //! @{ + CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03; + //! @} + + //! @name central normalized moments + //! @{ + CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03; + //! @} +}; + +template<> class DataType +{ +public: + typedef Moments value_type; + typedef double work_type; + typedef double channel_type; + + enum { generic_type = 0, + channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 24 + fmt = DataType::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; + + typedef Vec vec_type; +}; + +namespace traits { +template<> +struct Depth< Moments > { enum { value = Depth::value }; }; +template<> +struct Type< Moments > { enum { value = CV_MAKETYPE(Depth::value, (int)(sizeof(Moments)/sizeof(double))) }; }; +} // namespace + +//! @} imgproc_shape + +//! @cond IGNORED + +///////////////////////////////////////////////////////////////////////// +///////////////////////////// Implementation //////////////////////////// +///////////////////////////////////////////////////////////////////////// + +//////////////////////////////// Complex //////////////////////////////// + +template inline +Complex<_Tp>::Complex() + : re(0), im(0) {} + +template inline +Complex<_Tp>::Complex( _Tp _re, _Tp _im ) + : re(_re), im(_im) {} + +template template inline +Complex<_Tp>::operator Complex() const +{ + return Complex(saturate_cast(re), saturate_cast(im)); +} + +template inline +Complex<_Tp> Complex<_Tp>::conj() const +{ + return Complex<_Tp>(re, -im); +} + + +template static inline +bool operator == (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ + return a.re == b.re && a.im == b.im; +} + +template static inline +bool operator != (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ + return a.re != b.re || a.im != b.im; +} + +template static inline +Complex<_Tp> operator + (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ + return Complex<_Tp>( a.re + b.re, a.im + b.im ); +} + +template static inline +Complex<_Tp>& operator += (Complex<_Tp>& a, const Complex<_Tp>& b) +{ + a.re += b.re; a.im += b.im; + return a; +} + +template static inline +Complex<_Tp> operator - (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ + return Complex<_Tp>( a.re - b.re, a.im - b.im ); +} + +template static inline +Complex<_Tp>& operator -= (Complex<_Tp>& a, const Complex<_Tp>& b) +{ + a.re -= b.re; a.im -= b.im; + return a; +} + +template static inline +Complex<_Tp> operator - (const Complex<_Tp>& a) +{ + return Complex<_Tp>(-a.re, -a.im); +} + +template static inline +Complex<_Tp> operator * (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ + return Complex<_Tp>( a.re*b.re - a.im*b.im, a.re*b.im + a.im*b.re ); +} + +template static inline +Complex<_Tp> operator * (const Complex<_Tp>& a, _Tp b) +{ + return Complex<_Tp>( a.re*b, a.im*b ); +} + +template static inline +Complex<_Tp> operator * (_Tp b, const Complex<_Tp>& a) +{ + return Complex<_Tp>( a.re*b, a.im*b ); +} + +template static inline +Complex<_Tp> operator + (const Complex<_Tp>& a, _Tp b) +{ + return Complex<_Tp>( a.re + b, a.im ); +} + +template static inline +Complex<_Tp> operator - (const Complex<_Tp>& a, _Tp b) +{ return Complex<_Tp>( a.re - b, a.im ); } + +template static inline +Complex<_Tp> operator + (_Tp b, const Complex<_Tp>& a) +{ + return Complex<_Tp>( a.re + b, a.im ); +} + +template static inline +Complex<_Tp> operator - (_Tp b, const Complex<_Tp>& a) +{ + return Complex<_Tp>( b - a.re, -a.im ); +} + +template static inline +Complex<_Tp>& operator += (Complex<_Tp>& a, _Tp b) +{ + a.re += b; return a; +} + +template static inline +Complex<_Tp>& operator -= (Complex<_Tp>& a, _Tp b) +{ + a.re -= b; return a; +} + +template static inline +Complex<_Tp>& operator *= (Complex<_Tp>& a, _Tp b) +{ + a.re *= b; a.im *= b; return a; +} + +template static inline +double abs(const Complex<_Tp>& a) +{ + return std::sqrt( (double)a.re*a.re + (double)a.im*a.im); +} + +template static inline +Complex<_Tp> operator / (const Complex<_Tp>& a, const Complex<_Tp>& b) +{ + double t = 1./((double)b.re*b.re + (double)b.im*b.im); + return Complex<_Tp>( (_Tp)((a.re*b.re + a.im*b.im)*t), + (_Tp)((-a.re*b.im + a.im*b.re)*t) ); +} + +template static inline +Complex<_Tp>& operator /= (Complex<_Tp>& a, const Complex<_Tp>& b) +{ + a = a / b; + return a; +} + +template static inline +Complex<_Tp> operator / (const Complex<_Tp>& a, _Tp b) +{ + _Tp t = (_Tp)1/b; + return Complex<_Tp>( a.re*t, a.im*t ); +} + +template static inline +Complex<_Tp> operator / (_Tp b, const Complex<_Tp>& a) +{ + return Complex<_Tp>(b)/a; +} + +template static inline +Complex<_Tp> operator /= (const Complex<_Tp>& a, _Tp b) +{ + _Tp t = (_Tp)1/b; + a.re *= t; a.im *= t; return a; +} + + + +//////////////////////////////// 2D Point /////////////////////////////// + +template inline +Point_<_Tp>::Point_() + : x(0), y(0) {} + +template inline +Point_<_Tp>::Point_(_Tp _x, _Tp _y) + : x(_x), y(_y) {} + +template inline +Point_<_Tp>::Point_(const Point_& pt) + : x(pt.x), y(pt.y) {} + +template inline +Point_<_Tp>::Point_(Point_&& pt) CV_NOEXCEPT + : x(std::move(pt.x)), y(std::move(pt.y)) {} + +template inline +Point_<_Tp>::Point_(const Size_<_Tp>& sz) + : x(sz.width), y(sz.height) {} + +template inline +Point_<_Tp>::Point_(const Vec<_Tp,2>& v) + : x(v[0]), y(v[1]) {} + +template inline +Point_<_Tp>& Point_<_Tp>::operator = (const Point_& pt) +{ + x = pt.x; y = pt.y; + return *this; +} + +template inline +Point_<_Tp>& Point_<_Tp>::operator = (Point_&& pt) CV_NOEXCEPT +{ + x = std::move(pt.x); y = std::move(pt.y); + return *this; +} + +template template inline +Point_<_Tp>::operator Point_<_Tp2>() const +{ + return Point_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y)); +} + +template inline +Point_<_Tp>::operator Vec<_Tp, 2>() const +{ + return Vec<_Tp, 2>(x, y); +} + +template inline +_Tp Point_<_Tp>::dot(const Point_& pt) const +{ + return saturate_cast<_Tp>(x*pt.x + y*pt.y); +} + +template inline +double Point_<_Tp>::ddot(const Point_& pt) const +{ + return (double)x*pt.x + (double)y*pt.y; +} + +template inline +double Point_<_Tp>::cross(const Point_& pt) const +{ + return (double)x*pt.y - (double)y*pt.x; +} + +template inline bool +Point_<_Tp>::inside( const Rect_<_Tp>& r ) const +{ + return r.contains(*this); +} + + +template static inline +Point_<_Tp>& operator += (Point_<_Tp>& a, const Point_<_Tp>& b) +{ + a.x += b.x; + a.y += b.y; + return a; +} + +template static inline +Point_<_Tp>& operator -= (Point_<_Tp>& a, const Point_<_Tp>& b) +{ + a.x -= b.x; + a.y -= b.y; + return a; +} + +template static inline +Point_<_Tp>& operator *= (Point_<_Tp>& a, int b) +{ + a.x = saturate_cast<_Tp>(a.x * b); + a.y = saturate_cast<_Tp>(a.y * b); + return a; +} + +template static inline +Point_<_Tp>& operator *= (Point_<_Tp>& a, float b) +{ + a.x = saturate_cast<_Tp>(a.x * b); + a.y = saturate_cast<_Tp>(a.y * b); + return a; +} + +template static inline +Point_<_Tp>& operator *= (Point_<_Tp>& a, double b) +{ + a.x = saturate_cast<_Tp>(a.x * b); + a.y = saturate_cast<_Tp>(a.y * b); + return a; +} + +template static inline +Point_<_Tp>& operator /= (Point_<_Tp>& a, int b) +{ + a.x = saturate_cast<_Tp>(a.x / b); + a.y = saturate_cast<_Tp>(a.y / b); + return a; +} + +template static inline +Point_<_Tp>& operator /= (Point_<_Tp>& a, float b) +{ + a.x = saturate_cast<_Tp>(a.x / b); + a.y = saturate_cast<_Tp>(a.y / b); + return a; +} + +template static inline +Point_<_Tp>& operator /= (Point_<_Tp>& a, double b) +{ + a.x = saturate_cast<_Tp>(a.x / b); + a.y = saturate_cast<_Tp>(a.y / b); + return a; +} + +template static inline +double norm(const Point_<_Tp>& pt) +{ + return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y); +} + +template static inline +bool operator == (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ + return a.x == b.x && a.y == b.y; +} + +template static inline +bool operator != (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ + return a.x != b.x || a.y != b.y; +} + +template static inline +Point_<_Tp> operator + (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y) ); +} + +template static inline +Point_<_Tp> operator - (const Point_<_Tp>& a, const Point_<_Tp>& b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y) ); +} + +template static inline +Point_<_Tp> operator - (const Point_<_Tp>& a) +{ + return Point_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y) ); +} + +template static inline +Point_<_Tp> operator * (const Point_<_Tp>& a, int b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); +} + +template static inline +Point_<_Tp> operator * (int a, const Point_<_Tp>& b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); +} + +template static inline +Point_<_Tp> operator * (const Point_<_Tp>& a, float b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); +} + +template static inline +Point_<_Tp> operator * (float a, const Point_<_Tp>& b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); +} + +template static inline +Point_<_Tp> operator * (const Point_<_Tp>& a, double b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b) ); +} + +template static inline +Point_<_Tp> operator * (double a, const Point_<_Tp>& b) +{ + return Point_<_Tp>( saturate_cast<_Tp>(b.x*a), saturate_cast<_Tp>(b.y*a) ); +} + +template static inline +Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b) +{ + Matx<_Tp, 2, 1> tmp = a * Vec<_Tp,2>(b.x, b.y); + return Point_<_Tp>(tmp.val[0], tmp.val[1]); +} + +template static inline +Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point_<_Tp>& b) +{ + Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, 1); + return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]); +} + +template static inline +Point_<_Tp> operator / (const Point_<_Tp>& a, int b) +{ + Point_<_Tp> tmp(a); + tmp /= b; + return tmp; +} + +template static inline +Point_<_Tp> operator / (const Point_<_Tp>& a, float b) +{ + Point_<_Tp> tmp(a); + tmp /= b; + return tmp; +} + +template static inline +Point_<_Tp> operator / (const Point_<_Tp>& a, double b) +{ + Point_<_Tp> tmp(a); + tmp /= b; + return tmp; +} + + +template static inline _AccTp normL2Sqr(const Point_& pt); +template static inline _AccTp normL2Sqr(const Point_& pt); +template static inline _AccTp normL2Sqr(const Point_& pt); +template static inline _AccTp normL2Sqr(const Point_& pt); + +template<> inline int normL2Sqr(const Point_& pt) { return pt.dot(pt); } +template<> inline int64 normL2Sqr(const Point_& pt) { return pt.dot(pt); } +template<> inline float normL2Sqr(const Point_& pt) { return pt.dot(pt); } +template<> inline double normL2Sqr(const Point_& pt) { return pt.dot(pt); } + +template<> inline double normL2Sqr(const Point_& pt) { return pt.ddot(pt); } +template<> inline double normL2Sqr(const Point_& pt) { return pt.ddot(pt); } + + + +//////////////////////////////// 3D Point /////////////////////////////// + +template inline +Point3_<_Tp>::Point3_() + : x(0), y(0), z(0) {} + +template inline +Point3_<_Tp>::Point3_(_Tp _x, _Tp _y, _Tp _z) + : x(_x), y(_y), z(_z) {} + +template inline +Point3_<_Tp>::Point3_(const Point3_& pt) + : x(pt.x), y(pt.y), z(pt.z) {} + +template inline +Point3_<_Tp>::Point3_(Point3_&& pt) CV_NOEXCEPT + : x(std::move(pt.x)), y(std::move(pt.y)), z(std::move(pt.z)) {} + +template inline +Point3_<_Tp>::Point3_(const Point_<_Tp>& pt) + : x(pt.x), y(pt.y), z(_Tp()) {} + +template inline +Point3_<_Tp>::Point3_(const Vec<_Tp, 3>& v) + : x(v[0]), y(v[1]), z(v[2]) {} + +template template inline +Point3_<_Tp>::operator Point3_<_Tp2>() const +{ + return Point3_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(z)); +} + +template inline +Point3_<_Tp>::operator Vec<_Tp, 3>() const +{ + return Vec<_Tp, 3>(x, y, z); +} + +template inline +Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt) +{ + x = pt.x; y = pt.y; z = pt.z; + return *this; +} + +template inline +Point3_<_Tp>& Point3_<_Tp>::operator = (Point3_&& pt) CV_NOEXCEPT +{ + x = std::move(pt.x); y = std::move(pt.y); z = std::move(pt.z); + return *this; +} + +template inline +_Tp Point3_<_Tp>::dot(const Point3_& pt) const +{ + return saturate_cast<_Tp>(x*pt.x + y*pt.y + z*pt.z); +} + +template inline +double Point3_<_Tp>::ddot(const Point3_& pt) const +{ + return (double)x*pt.x + (double)y*pt.y + (double)z*pt.z; +} + +template inline +Point3_<_Tp> Point3_<_Tp>::cross(const Point3_<_Tp>& pt) const +{ + return Point3_<_Tp>(y*pt.z - z*pt.y, z*pt.x - x*pt.z, x*pt.y - y*pt.x); +} + + +template static inline +Point3_<_Tp>& operator += (Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + return a; +} + +template static inline +Point3_<_Tp>& operator -= (Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + return a; +} + +template static inline +Point3_<_Tp>& operator *= (Point3_<_Tp>& a, int b) +{ + a.x = saturate_cast<_Tp>(a.x * b); + a.y = saturate_cast<_Tp>(a.y * b); + a.z = saturate_cast<_Tp>(a.z * b); + return a; +} + +template static inline +Point3_<_Tp>& operator *= (Point3_<_Tp>& a, float b) +{ + a.x = saturate_cast<_Tp>(a.x * b); + a.y = saturate_cast<_Tp>(a.y * b); + a.z = saturate_cast<_Tp>(a.z * b); + return a; +} + +template static inline +Point3_<_Tp>& operator *= (Point3_<_Tp>& a, double b) +{ + a.x = saturate_cast<_Tp>(a.x * b); + a.y = saturate_cast<_Tp>(a.y * b); + a.z = saturate_cast<_Tp>(a.z * b); + return a; +} + +template static inline +Point3_<_Tp>& operator /= (Point3_<_Tp>& a, int b) +{ + a.x = saturate_cast<_Tp>(a.x / b); + a.y = saturate_cast<_Tp>(a.y / b); + a.z = saturate_cast<_Tp>(a.z / b); + return a; +} + +template static inline +Point3_<_Tp>& operator /= (Point3_<_Tp>& a, float b) +{ + a.x = saturate_cast<_Tp>(a.x / b); + a.y = saturate_cast<_Tp>(a.y / b); + a.z = saturate_cast<_Tp>(a.z / b); + return a; +} + +template static inline +Point3_<_Tp>& operator /= (Point3_<_Tp>& a, double b) +{ + a.x = saturate_cast<_Tp>(a.x / b); + a.y = saturate_cast<_Tp>(a.y / b); + a.z = saturate_cast<_Tp>(a.z / b); + return a; +} + +template static inline +double norm(const Point3_<_Tp>& pt) +{ + return std::sqrt((double)pt.x*pt.x + (double)pt.y*pt.y + (double)pt.z*pt.z); +} + +template static inline +bool operator == (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + return a.x == b.x && a.y == b.y && a.z == b.z; +} + +template static inline +bool operator != (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + return a.x != b.x || a.y != b.y || a.z != b.z; +} + +template static inline +Point3_<_Tp> operator + (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(a.x + b.x), saturate_cast<_Tp>(a.y + b.y), saturate_cast<_Tp>(a.z + b.z)); +} + +template static inline +Point3_<_Tp> operator - (const Point3_<_Tp>& a, const Point3_<_Tp>& b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(a.x - b.x), saturate_cast<_Tp>(a.y - b.y), saturate_cast<_Tp>(a.z - b.z)); +} + +template static inline +Point3_<_Tp> operator - (const Point3_<_Tp>& a) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(-a.x), saturate_cast<_Tp>(-a.y), saturate_cast<_Tp>(-a.z) ); +} + +template static inline +Point3_<_Tp> operator * (const Point3_<_Tp>& a, int b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(a.x*b), saturate_cast<_Tp>(a.y*b), saturate_cast<_Tp>(a.z*b) ); +} + +template static inline +Point3_<_Tp> operator * (int a, const Point3_<_Tp>& b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) ); +} + +template static inline +Point3_<_Tp> operator * (const Point3_<_Tp>& a, float b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) ); +} + +template static inline +Point3_<_Tp> operator * (float a, const Point3_<_Tp>& b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) ); +} + +template static inline +Point3_<_Tp> operator * (const Point3_<_Tp>& a, double b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(a.x * b), saturate_cast<_Tp>(a.y * b), saturate_cast<_Tp>(a.z * b) ); +} + +template static inline +Point3_<_Tp> operator * (double a, const Point3_<_Tp>& b) +{ + return Point3_<_Tp>( saturate_cast<_Tp>(b.x * a), saturate_cast<_Tp>(b.y * a), saturate_cast<_Tp>(b.z * a) ); +} + +template static inline +Point3_<_Tp> operator * (const Matx<_Tp, 3, 3>& a, const Point3_<_Tp>& b) +{ + Matx<_Tp, 3, 1> tmp = a * Vec<_Tp,3>(b.x, b.y, b.z); + return Point3_<_Tp>(tmp.val[0], tmp.val[1], tmp.val[2]); +} + +template static inline +Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b) +{ + return a * Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1); +} + +template static inline +Point3_<_Tp> operator / (const Point3_<_Tp>& a, int b) +{ + Point3_<_Tp> tmp(a); + tmp /= b; + return tmp; +} + +template static inline +Point3_<_Tp> operator / (const Point3_<_Tp>& a, float b) +{ + Point3_<_Tp> tmp(a); + tmp /= b; + return tmp; +} + +template static inline +Point3_<_Tp> operator / (const Point3_<_Tp>& a, double b) +{ + Point3_<_Tp> tmp(a); + tmp /= b; + return tmp; +} + + + +////////////////////////////////// Size ///////////////////////////////// + +template inline +Size_<_Tp>::Size_() + : width(0), height(0) {} + +template inline +Size_<_Tp>::Size_(_Tp _width, _Tp _height) + : width(_width), height(_height) {} + +template inline +Size_<_Tp>::Size_(const Size_& sz) + : width(sz.width), height(sz.height) {} + +template inline +Size_<_Tp>::Size_(Size_&& sz) CV_NOEXCEPT + : width(std::move(sz.width)), height(std::move(sz.height)) {} + +template inline +Size_<_Tp>::Size_(const Point_<_Tp>& pt) + : width(pt.x), height(pt.y) {} + +template template inline +Size_<_Tp>::operator Size_<_Tp2>() const +{ + return Size_<_Tp2>(saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); +} + +template inline +Size_<_Tp>& Size_<_Tp>::operator = (const Size_<_Tp>& sz) +{ + width = sz.width; height = sz.height; + return *this; +} + +template inline +Size_<_Tp>& Size_<_Tp>::operator = (Size_<_Tp>&& sz) CV_NOEXCEPT +{ + width = std::move(sz.width); height = std::move(sz.height); + return *this; +} + +template inline +_Tp Size_<_Tp>::area() const +{ + const _Tp result = width * height; + CV_DbgAssert(!std::numeric_limits<_Tp>::is_integer + || width == 0 || result / width == height); // make sure the result fits in the return value + return result; +} + +template inline +double Size_<_Tp>::aspectRatio() const +{ + return width / static_cast(height); +} + +template inline +bool Size_<_Tp>::empty() const +{ + return width <= 0 || height <= 0; +} + + +template static inline +Size_<_Tp>& operator *= (Size_<_Tp>& a, _Tp b) +{ + a.width *= b; + a.height *= b; + return a; +} + +template static inline +Size_<_Tp> operator * (const Size_<_Tp>& a, _Tp b) +{ + Size_<_Tp> tmp(a); + tmp *= b; + return tmp; +} + +template static inline +Size_<_Tp>& operator /= (Size_<_Tp>& a, _Tp b) +{ + a.width /= b; + a.height /= b; + return a; +} + +template static inline +Size_<_Tp> operator / (const Size_<_Tp>& a, _Tp b) +{ + Size_<_Tp> tmp(a); + tmp /= b; + return tmp; +} + +template static inline +Size_<_Tp>& operator += (Size_<_Tp>& a, const Size_<_Tp>& b) +{ + a.width += b.width; + a.height += b.height; + return a; +} + +template static inline +Size_<_Tp> operator + (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ + Size_<_Tp> tmp(a); + tmp += b; + return tmp; +} + +template static inline +Size_<_Tp>& operator -= (Size_<_Tp>& a, const Size_<_Tp>& b) +{ + a.width -= b.width; + a.height -= b.height; + return a; +} + +template static inline +Size_<_Tp> operator - (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ + Size_<_Tp> tmp(a); + tmp -= b; + return tmp; +} + +template static inline +bool operator == (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ + return a.width == b.width && a.height == b.height; +} + +template static inline +bool operator != (const Size_<_Tp>& a, const Size_<_Tp>& b) +{ + return !(a == b); +} + + + +////////////////////////////////// Rect ///////////////////////////////// + +template inline +Rect_<_Tp>::Rect_() + : x(0), y(0), width(0), height(0) {} + +template inline +Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) + : x(_x), y(_y), width(_width), height(_height) {} + +template inline +Rect_<_Tp>::Rect_(const Rect_<_Tp>& r) + : x(r.x), y(r.y), width(r.width), height(r.height) {} + +template inline +Rect_<_Tp>::Rect_(Rect_<_Tp>&& r) CV_NOEXCEPT + : x(std::move(r.x)), y(std::move(r.y)), width(std::move(r.width)), height(std::move(r.height)) {} + +template inline +Rect_<_Tp>::Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz) + : x(org.x), y(org.y), width(sz.width), height(sz.height) {} + +template inline +Rect_<_Tp>::Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2) +{ + x = std::min(pt1.x, pt2.x); + y = std::min(pt1.y, pt2.y); + width = std::max(pt1.x, pt2.x) - x; + height = std::max(pt1.y, pt2.y) - y; +} + +template inline +Rect_<_Tp>& Rect_<_Tp>::operator = ( const Rect_<_Tp>& r ) +{ + x = r.x; + y = r.y; + width = r.width; + height = r.height; + return *this; +} + +template inline +Rect_<_Tp>& Rect_<_Tp>::operator = ( Rect_<_Tp>&& r ) CV_NOEXCEPT +{ + x = std::move(r.x); + y = std::move(r.y); + width = std::move(r.width); + height = std::move(r.height); + return *this; +} + +template inline +Point_<_Tp> Rect_<_Tp>::tl() const +{ + return Point_<_Tp>(x,y); +} + +template inline +Point_<_Tp> Rect_<_Tp>::br() const +{ + return Point_<_Tp>(x + width, y + height); +} + +template inline +Size_<_Tp> Rect_<_Tp>::size() const +{ + return Size_<_Tp>(width, height); +} + +template inline +_Tp Rect_<_Tp>::area() const +{ + const _Tp result = width * height; + CV_DbgAssert(!std::numeric_limits<_Tp>::is_integer + || width == 0 || result / width == height); // make sure the result fits in the return value + return result; +} + +template inline +bool Rect_<_Tp>::empty() const +{ + return width <= 0 || height <= 0; +} + +template template inline +Rect_<_Tp>::operator Rect_<_Tp2>() const +{ + return Rect_<_Tp2>(saturate_cast<_Tp2>(x), saturate_cast<_Tp2>(y), saturate_cast<_Tp2>(width), saturate_cast<_Tp2>(height)); +} + +template inline +bool Rect_<_Tp>::contains(const Point_<_Tp>& pt) const +{ + return x <= pt.x && pt.x < x + width && y <= pt.y && pt.y < y + height; +} + + +template static inline +Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Point_<_Tp>& b ) +{ + a.x += b.x; + a.y += b.y; + return a; +} + +template static inline +Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Point_<_Tp>& b ) +{ + a.x -= b.x; + a.y -= b.y; + return a; +} + +template static inline +Rect_<_Tp>& operator += ( Rect_<_Tp>& a, const Size_<_Tp>& b ) +{ + a.width += b.width; + a.height += b.height; + return a; +} + +template static inline +Rect_<_Tp>& operator -= ( Rect_<_Tp>& a, const Size_<_Tp>& b ) +{ + const _Tp width = a.width - b.width; + const _Tp height = a.height - b.height; + CV_DbgAssert(width >= 0 && height >= 0); + a.width = width; + a.height = height; + return a; +} + +template static inline +Rect_<_Tp>& operator &= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) +{ + _Tp x1 = std::max(a.x, b.x); + _Tp y1 = std::max(a.y, b.y); + a.width = std::min(a.x + a.width, b.x + b.width) - x1; + a.height = std::min(a.y + a.height, b.y + b.height) - y1; + a.x = x1; + a.y = y1; + if( a.width <= 0 || a.height <= 0 ) + a = Rect(); + return a; +} + +template static inline +Rect_<_Tp>& operator |= ( Rect_<_Tp>& a, const Rect_<_Tp>& b ) +{ + if (a.empty()) { + a = b; + } + else if (!b.empty()) { + _Tp x1 = std::min(a.x, b.x); + _Tp y1 = std::min(a.y, b.y); + a.width = std::max(a.x + a.width, b.x + b.width) - x1; + a.height = std::max(a.y + a.height, b.y + b.height) - y1; + a.x = x1; + a.y = y1; + } + return a; +} + +template static inline +bool operator == (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height; +} + +template static inline +bool operator != (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height; +} + +template static inline +Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Point_<_Tp>& b) +{ + return Rect_<_Tp>( a.x + b.x, a.y + b.y, a.width, a.height ); +} + +template static inline +Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Point_<_Tp>& b) +{ + return Rect_<_Tp>( a.x - b.x, a.y - b.y, a.width, a.height ); +} + +template static inline +Rect_<_Tp> operator + (const Rect_<_Tp>& a, const Size_<_Tp>& b) +{ + return Rect_<_Tp>( a.x, a.y, a.width + b.width, a.height + b.height ); +} + +template static inline +Rect_<_Tp> operator - (const Rect_<_Tp>& a, const Size_<_Tp>& b) +{ + const _Tp width = a.width - b.width; + const _Tp height = a.height - b.height; + CV_DbgAssert(width >= 0 && height >= 0); + return Rect_<_Tp>( a.x, a.y, width, height ); +} + +template static inline +Rect_<_Tp> operator & (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + Rect_<_Tp> c = a; + return c &= b; +} + +template static inline +Rect_<_Tp> operator | (const Rect_<_Tp>& a, const Rect_<_Tp>& b) +{ + Rect_<_Tp> c = a; + return c |= b; +} + +/** + * @brief measure dissimilarity between two sample sets + * + * computes the complement of the Jaccard Index as described in . + * For rectangles this reduces to computing the intersection over the union. + */ +template static inline +double jaccardDistance(const Rect_<_Tp>& a, const Rect_<_Tp>& b) { + _Tp Aa = a.area(); + _Tp Ab = b.area(); + + if ((Aa + Ab) <= std::numeric_limits<_Tp>::epsilon()) { + // jaccard_index = 1 -> distance = 0 + return 0.0; + } + + double Aab = (a & b).area(); + // distance = 1 - jaccard_index + return 1.0 - Aab / (Aa + Ab - Aab); +} + +////////////////////////////// RotatedRect ////////////////////////////// + +inline +RotatedRect::RotatedRect() + : center(), size(), angle(0) {} + +inline +RotatedRect::RotatedRect(const Point2f& _center, const Size2f& _size, float _angle) + : center(_center), size(_size), angle(_angle) {} + +///////////////////////////////// Range ///////////////////////////////// + +inline +Range::Range() + : start(0), end(0) {} + +inline +Range::Range(int _start, int _end) + : start(_start), end(_end) {} + +inline +int Range::size() const +{ + return end - start; +} + +inline +bool Range::empty() const +{ + return start == end; +} + +inline +Range Range::all() +{ + return Range(INT_MIN, INT_MAX); +} + + +static inline +bool operator == (const Range& r1, const Range& r2) +{ + return r1.start == r2.start && r1.end == r2.end; +} + +static inline +bool operator != (const Range& r1, const Range& r2) +{ + return !(r1 == r2); +} + +static inline +bool operator !(const Range& r) +{ + return r.start == r.end; +} + +static inline +Range operator & (const Range& r1, const Range& r2) +{ + Range r(std::max(r1.start, r2.start), std::min(r1.end, r2.end)); + r.end = std::max(r.end, r.start); + return r; +} + +static inline +Range& operator &= (Range& r1, const Range& r2) +{ + r1 = r1 & r2; + return r1; +} + +static inline +Range operator + (const Range& r1, int delta) +{ + return Range(r1.start + delta, r1.end + delta); +} + +static inline +Range operator + (int delta, const Range& r1) +{ + return Range(r1.start + delta, r1.end + delta); +} + +static inline +Range operator - (const Range& r1, int delta) +{ + return r1 + (-delta); +} + + + +///////////////////////////////// Scalar //////////////////////////////// + +template inline +Scalar_<_Tp>::Scalar_() +{ + this->val[0] = this->val[1] = this->val[2] = this->val[3] = 0; +} + +template inline +Scalar_<_Tp>::Scalar_(_Tp v0, _Tp v1, _Tp v2, _Tp v3) +{ + this->val[0] = v0; + this->val[1] = v1; + this->val[2] = v2; + this->val[3] = v3; +} + +template inline +Scalar_<_Tp>::Scalar_(const Scalar_<_Tp>& s) : Vec<_Tp, 4>(s) { +} + +template inline +Scalar_<_Tp>::Scalar_(Scalar_<_Tp>&& s) CV_NOEXCEPT { + this->val[0] = std::move(s.val[0]); + this->val[1] = std::move(s.val[1]); + this->val[2] = std::move(s.val[2]); + this->val[3] = std::move(s.val[3]); +} + +template inline +Scalar_<_Tp>& Scalar_<_Tp>::operator=(const Scalar_<_Tp>& s) { + this->val[0] = s.val[0]; + this->val[1] = s.val[1]; + this->val[2] = s.val[2]; + this->val[3] = s.val[3]; + return *this; +} + +template inline +Scalar_<_Tp>& Scalar_<_Tp>::operator=(Scalar_<_Tp>&& s) CV_NOEXCEPT { + this->val[0] = std::move(s.val[0]); + this->val[1] = std::move(s.val[1]); + this->val[2] = std::move(s.val[2]); + this->val[3] = std::move(s.val[3]); + return *this; +} + +template template inline +Scalar_<_Tp>::Scalar_(const Vec<_Tp2, cn>& v) +{ + int i; + for( i = 0; i < (cn < 4 ? cn : 4); i++ ) + this->val[i] = cv::saturate_cast<_Tp>(v.val[i]); + for( ; i < 4; i++ ) + this->val[i] = 0; +} + +template inline +Scalar_<_Tp>::Scalar_(_Tp v0) +{ + this->val[0] = v0; + this->val[1] = this->val[2] = this->val[3] = 0; +} + +template inline +Scalar_<_Tp> Scalar_<_Tp>::all(_Tp v0) +{ + return Scalar_<_Tp>(v0, v0, v0, v0); +} + + +template inline +Scalar_<_Tp> Scalar_<_Tp>::mul(const Scalar_<_Tp>& a, double scale ) const +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(this->val[0] * a.val[0] * scale), + saturate_cast<_Tp>(this->val[1] * a.val[1] * scale), + saturate_cast<_Tp>(this->val[2] * a.val[2] * scale), + saturate_cast<_Tp>(this->val[3] * a.val[3] * scale)); +} + +template inline +Scalar_<_Tp> Scalar_<_Tp>::conj() const +{ + return Scalar_<_Tp>(saturate_cast<_Tp>( this->val[0]), + saturate_cast<_Tp>(-this->val[1]), + saturate_cast<_Tp>(-this->val[2]), + saturate_cast<_Tp>(-this->val[3])); +} + +template inline +bool Scalar_<_Tp>::isReal() const +{ + return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0; +} + + +template template inline +Scalar_<_Tp>::operator Scalar_() const +{ + return Scalar_(saturate_cast(this->val[0]), + saturate_cast(this->val[1]), + saturate_cast(this->val[2]), + saturate_cast(this->val[3])); +} + + +template static inline +Scalar_<_Tp>& operator += (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a.val[0] += b.val[0]; + a.val[1] += b.val[1]; + a.val[2] += b.val[2]; + a.val[3] += b.val[3]; + return a; +} + +template static inline +Scalar_<_Tp>& operator -= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a.val[0] -= b.val[0]; + a.val[1] -= b.val[1]; + a.val[2] -= b.val[2]; + a.val[3] -= b.val[3]; + return a; +} + +template static inline +Scalar_<_Tp>& operator *= ( Scalar_<_Tp>& a, _Tp v ) +{ + a.val[0] *= v; + a.val[1] *= v; + a.val[2] *= v; + a.val[3] *= v; + return a; +} + +template static inline +bool operator == ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b ) +{ + return a.val[0] == b.val[0] && a.val[1] == b.val[1] && + a.val[2] == b.val[2] && a.val[3] == b.val[3]; +} + +template static inline +bool operator != ( const Scalar_<_Tp>& a, const Scalar_<_Tp>& b ) +{ + return a.val[0] != b.val[0] || a.val[1] != b.val[1] || + a.val[2] != b.val[2] || a.val[3] != b.val[3]; +} + +template static inline +Scalar_<_Tp> operator + (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return Scalar_<_Tp>(a.val[0] + b.val[0], + a.val[1] + b.val[1], + a.val[2] + b.val[2], + a.val[3] + b.val[3]); +} + +template static inline +Scalar_<_Tp> operator - (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a.val[0] - b.val[0]), + saturate_cast<_Tp>(a.val[1] - b.val[1]), + saturate_cast<_Tp>(a.val[2] - b.val[2]), + saturate_cast<_Tp>(a.val[3] - b.val[3])); +} + +template static inline +Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, _Tp alpha) +{ + return Scalar_<_Tp>(a.val[0] * alpha, + a.val[1] * alpha, + a.val[2] * alpha, + a.val[3] * alpha); +} + +template static inline +Scalar_<_Tp> operator * (_Tp alpha, const Scalar_<_Tp>& a) +{ + return a*alpha; +} + +template static inline +Scalar_<_Tp> operator - (const Scalar_<_Tp>& a) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(-a.val[0]), + saturate_cast<_Tp>(-a.val[1]), + saturate_cast<_Tp>(-a.val[2]), + saturate_cast<_Tp>(-a.val[3])); +} + + +template static inline +Scalar_<_Tp> operator * (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return Scalar_<_Tp>(saturate_cast<_Tp>(a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3]), + saturate_cast<_Tp>(a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2]), + saturate_cast<_Tp>(a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1]), + saturate_cast<_Tp>(a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0])); +} + +template static inline +Scalar_<_Tp>& operator *= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a = a * b; + return a; +} + +template static inline +Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha) +{ + return Scalar_<_Tp>(a.val[0] / alpha, + a.val[1] / alpha, + a.val[2] / alpha, + a.val[3] / alpha); +} + +template static inline +Scalar_ operator / (const Scalar_& a, float alpha) +{ + float s = 1 / alpha; + return Scalar_(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s); +} + +template static inline +Scalar_ operator / (const Scalar_& a, double alpha) +{ + double s = 1 / alpha; + return Scalar_(a.val[0] * s, a.val[1] * s, a.val[2] * s, a.val[3] * s); +} + +template static inline +Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, _Tp alpha) +{ + a = a / alpha; + return a; +} + +template static inline +Scalar_<_Tp> operator / (_Tp a, const Scalar_<_Tp>& b) +{ + _Tp s = a / (b[0]*b[0] + b[1]*b[1] + b[2]*b[2] + b[3]*b[3]); + return b.conj() * s; +} + +template static inline +Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + return a * ((_Tp)1 / b); +} + +template static inline +Scalar_<_Tp>& operator /= (Scalar_<_Tp>& a, const Scalar_<_Tp>& b) +{ + a = a / b; + return a; +} + +template static inline +Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b) +{ + Matx c((Matx)a, b, Matx_MatMulOp()); + return reinterpret_cast(c); +} + +template<> inline +Scalar operator * (const Matx& a, const Scalar& b) +{ + Matx c(a, b, Matx_MatMulOp()); + return reinterpret_cast(c); +} + + + +//////////////////////////////// KeyPoint /////////////////////////////// + +inline +KeyPoint::KeyPoint() + : pt(0,0), size(0), angle(-1), response(0), octave(0), class_id(-1) {} + +inline +KeyPoint::KeyPoint(Point2f _pt, float _size, float _angle, float _response, int _octave, int _class_id) + : pt(_pt), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {} + +inline +KeyPoint::KeyPoint(float x, float y, float _size, float _angle, float _response, int _octave, int _class_id) + : pt(x, y), size(_size), angle(_angle), response(_response), octave(_octave), class_id(_class_id) {} + + + +///////////////////////////////// DMatch //////////////////////////////// + +inline +DMatch::DMatch() + : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(FLT_MAX) {} + +inline +DMatch::DMatch(int _queryIdx, int _trainIdx, float _distance) + : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {} + +inline +DMatch::DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance) + : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {} + +inline +bool DMatch::operator < (const DMatch &m) const +{ + return distance < m.distance; +} + + + +////////////////////////////// TermCriteria ///////////////////////////// + +inline +TermCriteria::TermCriteria() + : type(0), maxCount(0), epsilon(0) {} + +inline +TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon) + : type(_type), maxCount(_maxCount), epsilon(_epsilon) {} + +//! @endcond + +} // cv + +#endif //OPENCV_CORE_TYPES_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/types_c.h b/Prj-Win/3rd/opencv/include/opencv2/core/types_c.h new file mode 100755 index 0000000..a095bc3 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/types_c.h @@ -0,0 +1,2120 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_TYPES_H +#define OPENCV_CORE_TYPES_H + +#if !defined(__OPENCV_BUILD) && !defined(CV__DISABLE_C_API_CTORS) +#define CV__ENABLE_C_API_CTORS // enable C API ctors (must be removed) +#endif + +//#define CV__VALIDATE_UNUNITIALIZED_VARS 1 // C++11 & GCC only + +#ifdef __cplusplus + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#define CV_STRUCT_INITIALIZER {0,} +#else +#if defined(__GNUC__) && __GNUC__ == 4 // GCC 4.x warns on "= {}" initialization, fixed in GCC 5.0 +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif +#define CV_STRUCT_INITIALIZER {} +#endif + +#else +#define CV_STRUCT_INITIALIZER {0} +#endif + + +#ifdef HAVE_IPL +# ifndef __IPL_H__ +# if defined _WIN32 +# include +# else +# include +# endif +# endif +#elif defined __IPL_H__ +# define HAVE_IPL +#endif + +#include "opencv2/core/cvdef.h" + +#ifndef SKIP_INCLUDES +#include +#include +#include +#include +#endif // SKIP_INCLUDES + +#if defined _WIN32 +# define CV_CDECL __cdecl +# define CV_STDCALL __stdcall +#else +# define CV_CDECL +# define CV_STDCALL +#endif + +#ifndef CV_DEFAULT +# ifdef __cplusplus +# define CV_DEFAULT(val) = val +# else +# define CV_DEFAULT(val) +# endif +#endif + +#ifndef CV_EXTERN_C_FUNCPTR +# ifdef __cplusplus +# define CV_EXTERN_C_FUNCPTR(x) extern "C" { typedef x; } +# else +# define CV_EXTERN_C_FUNCPTR(x) typedef x +# endif +#endif + +#ifndef CVAPI +# define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL +#endif + +#ifndef CV_IMPL +# define CV_IMPL CV_EXTERN_C +#endif + +#ifdef __cplusplus +# include "opencv2/core.hpp" +#endif + +/** @addtogroup core_c + @{ +*/ + +/** @brief This is the "metatype" used *only* as a function parameter. + +It denotes that the function accepts arrays of multiple types, such as IplImage*, CvMat* or even +CvSeq* sometimes. The particular array type is determined at runtime by analyzing the first 4 +bytes of the header. In C++ interface the role of CvArr is played by InputArray and OutputArray. + */ +typedef void CvArr; + +typedef int CVStatus; + +/** @see cv::Error::Code */ +enum { + CV_StsOk= 0, /**< everything is ok */ + CV_StsBackTrace= -1, /**< pseudo error for back trace */ + CV_StsError= -2, /**< unknown /unspecified error */ + CV_StsInternal= -3, /**< internal error (bad state) */ + CV_StsNoMem= -4, /**< insufficient memory */ + CV_StsBadArg= -5, /**< function arg/param is bad */ + CV_StsBadFunc= -6, /**< unsupported function */ + CV_StsNoConv= -7, /**< iter. didn't converge */ + CV_StsAutoTrace= -8, /**< tracing */ + CV_HeaderIsNull= -9, /**< image header is NULL */ + CV_BadImageSize= -10, /**< image size is invalid */ + CV_BadOffset= -11, /**< offset is invalid */ + CV_BadDataPtr= -12, /**/ + CV_BadStep= -13, /**< image step is wrong, this may happen for a non-continuous matrix */ + CV_BadModelOrChSeq= -14, /**/ + CV_BadNumChannels= -15, /**< bad number of channels, for example, some functions accept only single channel matrices */ + CV_BadNumChannel1U= -16, /**/ + CV_BadDepth= -17, /**< input image depth is not supported by the function */ + CV_BadAlphaChannel= -18, /**/ + CV_BadOrder= -19, /**< number of dimensions is out of range */ + CV_BadOrigin= -20, /**< incorrect input origin */ + CV_BadAlign= -21, /**< incorrect input align */ + CV_BadCallBack= -22, /**/ + CV_BadTileSize= -23, /**/ + CV_BadCOI= -24, /**< input COI is not supported */ + CV_BadROISize= -25, /**< incorrect input roi */ + CV_MaskIsTiled= -26, /**/ + CV_StsNullPtr= -27, /**< null pointer */ + CV_StsVecLengthErr= -28, /**< incorrect vector length */ + CV_StsFilterStructContentErr= -29, /**< incorrect filter structure content */ + CV_StsKernelStructContentErr= -30, /**< incorrect transform kernel content */ + CV_StsFilterOffsetErr= -31, /**< incorrect filter offset value */ + CV_StsBadSize= -201, /**< the input/output structure size is incorrect */ + CV_StsDivByZero= -202, /**< division by zero */ + CV_StsInplaceNotSupported= -203, /**< in-place operation is not supported */ + CV_StsObjectNotFound= -204, /**< request can't be completed */ + CV_StsUnmatchedFormats= -205, /**< formats of input/output arrays differ */ + CV_StsBadFlag= -206, /**< flag is wrong or not supported */ + CV_StsBadPoint= -207, /**< bad CvPoint */ + CV_StsBadMask= -208, /**< bad format of mask (neither 8uC1 nor 8sC1)*/ + CV_StsUnmatchedSizes= -209, /**< sizes of input/output structures do not match */ + CV_StsUnsupportedFormat= -210, /**< the data format/type is not supported by the function*/ + CV_StsOutOfRange= -211, /**< some of parameters are out of range */ + CV_StsParseError= -212, /**< invalid syntax/structure of the parsed file */ + CV_StsNotImplemented= -213, /**< the requested function/feature is not implemented */ + CV_StsBadMemBlock= -214, /**< an allocated block has been corrupted */ + CV_StsAssert= -215, /**< assertion failed */ + CV_GpuNotSupported= -216, /**< no CUDA support */ + CV_GpuApiCallError= -217, /**< GPU API call error */ + CV_OpenGlNotSupported= -218, /**< no OpenGL support */ + CV_OpenGlApiCallError= -219, /**< OpenGL API call error */ + CV_OpenCLApiCallError= -220, /**< OpenCL API call error */ + CV_OpenCLDoubleNotSupported= -221, + CV_OpenCLInitError= -222, /**< OpenCL initialization error */ + CV_OpenCLNoAMDBlasFft= -223 +}; + +/****************************************************************************************\ +* Common macros and inline functions * +\****************************************************************************************/ + +#define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t)) + +/** min & max without jumps */ +#define CV_IMIN(a, b) ((a) ^ (((a)^(b)) & (((a) < (b)) - 1))) + +#define CV_IMAX(a, b) ((a) ^ (((a)^(b)) & (((a) > (b)) - 1))) + +/** absolute value without jumps */ +#ifndef __cplusplus +# define CV_IABS(a) (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0)) +#else +# define CV_IABS(a) abs(a) +#endif +#define CV_CMP(a,b) (((a) > (b)) - ((a) < (b))) +#define CV_SIGN(a) CV_CMP((a),0) + +#define cvInvSqrt(value) ((float)(1./sqrt(value))) +#define cvSqrt(value) ((float)sqrt(value)) + + +/*************** Random number generation *******************/ + +typedef uint64 CvRNG; + +#define CV_RNG_COEFF 4164903690U + +/** @brief Initializes a random number generator state. + +The function initializes a random number generator and returns the state. The pointer to the state +can be then passed to the cvRandInt, cvRandReal and cvRandArr functions. In the current +implementation a multiply-with-carry generator is used. +@param seed 64-bit value used to initiate a random sequence +@sa the C++ class RNG replaced CvRNG. + */ +CV_INLINE CvRNG cvRNG( int64 seed CV_DEFAULT(-1)) +{ + CvRNG rng = seed ? (uint64)seed : (uint64)(int64)-1; + return rng; +} + +/** @brief Returns a 32-bit unsigned integer and updates RNG. + +The function returns a uniformly-distributed random 32-bit unsigned integer and updates the RNG +state. It is similar to the rand() function from the C runtime library, except that OpenCV functions +always generates a 32-bit random number, regardless of the platform. +@param rng CvRNG state initialized by cvRNG. + */ +CV_INLINE unsigned cvRandInt( CvRNG* rng ) +{ + uint64 temp = *rng; + temp = (uint64)(unsigned)temp*CV_RNG_COEFF + (temp >> 32); + *rng = temp; + return (unsigned)temp; +} + +/** @brief Returns a floating-point random number and updates RNG. + +The function returns a uniformly-distributed random floating-point number between 0 and 1 (1 is not +included). +@param rng RNG state initialized by cvRNG + */ +CV_INLINE double cvRandReal( CvRNG* rng ) +{ + return cvRandInt(rng)*2.3283064365386962890625e-10 /* 2^-32 */; +} + +/****************************************************************************************\ +* Image type (IplImage) * +\****************************************************************************************/ + +#ifndef HAVE_IPL + +/* + * The following definitions (until #endif) + * is an extract from IPL headers. + * Copyright (c) 1995 Intel Corporation. + */ +#define IPL_DEPTH_SIGN 0x80000000 + +#define IPL_DEPTH_1U 1 +#define IPL_DEPTH_8U 8 +#define IPL_DEPTH_16U 16 +#define IPL_DEPTH_32F 32 + +#define IPL_DEPTH_8S (IPL_DEPTH_SIGN| 8) +#define IPL_DEPTH_16S (IPL_DEPTH_SIGN|16) +#define IPL_DEPTH_32S (IPL_DEPTH_SIGN|32) + +#define IPL_DATA_ORDER_PIXEL 0 +#define IPL_DATA_ORDER_PLANE 1 + +#define IPL_ORIGIN_TL 0 +#define IPL_ORIGIN_BL 1 + +#define IPL_ALIGN_4BYTES 4 +#define IPL_ALIGN_8BYTES 8 +#define IPL_ALIGN_16BYTES 16 +#define IPL_ALIGN_32BYTES 32 + +#define IPL_ALIGN_DWORD IPL_ALIGN_4BYTES +#define IPL_ALIGN_QWORD IPL_ALIGN_8BYTES + +#define IPL_BORDER_CONSTANT 0 +#define IPL_BORDER_REPLICATE 1 +#define IPL_BORDER_REFLECT 2 +#define IPL_BORDER_WRAP 3 + +#ifdef __cplusplus +typedef struct _IplImage IplImage; +CV_EXPORTS _IplImage cvIplImage(const cv::Mat& m); +#endif + +/** The IplImage is taken from the Intel Image Processing Library, in which the format is native. OpenCV +only supports a subset of possible IplImage formats, as outlined in the parameter list above. + +In addition to the above restrictions, OpenCV handles ROIs differently. OpenCV functions require +that the image size or ROI size of all source and destination images match exactly. On the other +hand, the Intel Image Processing Library processes the area of intersection between the source and +destination images (or ROIs), allowing them to vary independently. +*/ +typedef struct +_IplImage +{ + int nSize; /**< sizeof(IplImage) */ + int ID; /**< version (=0)*/ + int nChannels; /**< Most of OpenCV functions support 1,2,3 or 4 channels */ + int alphaChannel; /**< Ignored by OpenCV */ + int depth; /**< Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, + IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */ + char colorModel[4]; /**< Ignored by OpenCV */ + char channelSeq[4]; /**< ditto */ + int dataOrder; /**< 0 - interleaved color channels, 1 - separate color channels. + cvCreateImage can only create interleaved images */ + int origin; /**< 0 - top-left origin, + 1 - bottom-left origin (Windows bitmaps style). */ + int align; /**< Alignment of image rows (4 or 8). + OpenCV ignores it and uses widthStep instead. */ + int width; /**< Image width in pixels. */ + int height; /**< Image height in pixels. */ + struct _IplROI *roi; /**< Image ROI. If NULL, the whole image is selected. */ + struct _IplImage *maskROI; /**< Must be NULL. */ + void *imageId; /**< " " */ + struct _IplTileInfo *tileInfo; /**< " " */ + int imageSize; /**< Image data size in bytes + (==image->height*image->widthStep + in case of interleaved data)*/ + char *imageData; /**< Pointer to aligned image data. */ + int widthStep; /**< Size of aligned image row in bytes. */ + int BorderMode[4]; /**< Ignored by OpenCV. */ + int BorderConst[4]; /**< Ditto. */ + char *imageDataOrigin; /**< Pointer to very origin of image data + (not necessarily aligned) - + needed for correct deallocation */ + +#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + _IplImage() {} + _IplImage(const cv::Mat& m) { *this = cvIplImage(m); } +#endif +} +IplImage; + +CV_INLINE IplImage cvIplImage() +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + IplImage self = CV_STRUCT_INITIALIZER; self.nSize = sizeof(IplImage); return self; +#else + return _IplImage(); +#endif +} + +typedef struct _IplTileInfo IplTileInfo; + +typedef struct _IplROI +{ + int coi; /**< 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/ + int xOffset; + int yOffset; + int width; + int height; +} +IplROI; + +typedef struct _IplConvKernel +{ + int nCols; + int nRows; + int anchorX; + int anchorY; + int *values; + int nShiftR; +} +IplConvKernel; + +typedef struct _IplConvKernelFP +{ + int nCols; + int nRows; + int anchorX; + int anchorY; + float *values; +} +IplConvKernelFP; + +#define IPL_IMAGE_HEADER 1 +#define IPL_IMAGE_DATA 2 +#define IPL_IMAGE_ROI 4 + +#endif/*HAVE_IPL*/ + +/** extra border mode */ +#define IPL_BORDER_REFLECT_101 4 +#define IPL_BORDER_TRANSPARENT 5 + +#define IPL_IMAGE_MAGIC_VAL ((int)sizeof(IplImage)) +#define CV_TYPE_NAME_IMAGE "opencv-image" + +#define CV_IS_IMAGE_HDR(img) \ + ((img) != NULL && ((const IplImage*)(img))->nSize == sizeof(IplImage)) + +#define CV_IS_IMAGE(img) \ + (CV_IS_IMAGE_HDR(img) && ((IplImage*)img)->imageData != NULL) + +/** for storing double-precision + floating point data in IplImage's */ +#define IPL_DEPTH_64F 64 + +/** get reference to pixel at (col,row), + for multi-channel images (col) should be multiplied by number of channels */ +#define CV_IMAGE_ELEM( image, elemtype, row, col ) \ + (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)]) + +/****************************************************************************************\ +* Matrix type (CvMat) * +\****************************************************************************************/ + +#define CV_AUTO_STEP 0x7fffffff +#define CV_WHOLE_ARR cvSlice( 0, 0x3fffffff ) + +#define CV_MAGIC_MASK 0xFFFF0000 +#define CV_MAT_MAGIC_VAL 0x42420000 +#define CV_TYPE_NAME_MAT "opencv-matrix" + +#ifdef __cplusplus +typedef struct CvMat CvMat; +CV_INLINE CvMat cvMat(const cv::Mat& m); +#endif + +/** Matrix elements are stored row by row. Element (i, j) (i - 0-based row index, j - 0-based column +index) of a matrix can be retrieved or modified using CV_MAT_ELEM macro: + + uchar pixval = CV_MAT_ELEM(grayimg, uchar, i, j) + CV_MAT_ELEM(cameraMatrix, float, 0, 2) = image.width*0.5f; + +To access multiple-channel matrices, you can use +CV_MAT_ELEM(matrix, type, i, j\*nchannels + channel_idx). + +@deprecated CvMat is now obsolete; consider using Mat instead. + */ +typedef struct CvMat +{ + int type; + int step; + + /* for internal use only */ + int* refcount; + int hdr_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 + +#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvMat() {} + CvMat(const cv::Mat& m) { *this = cvMat(m); } +#endif +} +CvMat; + + +#define CV_IS_MAT_HDR(mat) \ + ((mat) != NULL && \ + (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \ + ((const CvMat*)(mat))->cols > 0 && ((const CvMat*)(mat))->rows > 0) + +#define CV_IS_MAT_HDR_Z(mat) \ + ((mat) != NULL && \ + (((const CvMat*)(mat))->type & CV_MAGIC_MASK) == CV_MAT_MAGIC_VAL && \ + ((const CvMat*)(mat))->cols >= 0 && ((const CvMat*)(mat))->rows >= 0) + +#define CV_IS_MAT(mat) \ + (CV_IS_MAT_HDR(mat) && ((const CvMat*)(mat))->data.ptr != NULL) + +#define CV_IS_MASK_ARR(mat) \ + (((mat)->type & (CV_MAT_TYPE_MASK & ~CV_8SC1)) == 0) + +#define CV_ARE_TYPES_EQ(mat1, mat2) \ + ((((mat1)->type ^ (mat2)->type) & CV_MAT_TYPE_MASK) == 0) + +#define CV_ARE_CNS_EQ(mat1, mat2) \ + ((((mat1)->type ^ (mat2)->type) & CV_MAT_CN_MASK) == 0) + +#define CV_ARE_DEPTHS_EQ(mat1, mat2) \ + ((((mat1)->type ^ (mat2)->type) & CV_MAT_DEPTH_MASK) == 0) + +#define CV_ARE_SIZES_EQ(mat1, mat2) \ + ((mat1)->rows == (mat2)->rows && (mat1)->cols == (mat2)->cols) + +#define CV_IS_MAT_CONST(mat) \ + (((mat)->rows|(mat)->cols) == 1) + +#define IPL2CV_DEPTH(depth) \ + ((((CV_8U)+(CV_16U<<4)+(CV_32F<<8)+(CV_64F<<16)+(CV_8S<<20)+ \ + (CV_16S<<24)+(CV_32S<<28)) >> ((((depth) & 0xF0) >> 2) + \ + (((depth) & IPL_DEPTH_SIGN) ? 20 : 0))) & 15) + +/** Inline constructor. No data is allocated internally!!! + * (Use together with cvCreateData, or use cvCreateMat instead to + * get a matrix with allocated data): + */ +CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL)) +{ + CvMat m; + + assert( (unsigned)CV_MAT_DEPTH(type) <= CV_64F ); + type = CV_MAT_TYPE(type); + m.type = CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG | type; + m.cols = cols; + m.rows = rows; + m.step = m.cols*CV_ELEM_SIZE(type); + m.data.ptr = (uchar*)data; + m.refcount = NULL; + m.hdr_refcount = 0; + + return m; +} + +#ifdef __cplusplus + +CV_INLINE CvMat cvMat(const cv::Mat& m) +{ + CvMat self; + CV_DbgAssert(m.dims <= 2); + self = cvMat(m.rows, m.dims == 1 ? 1 : m.cols, m.type(), m.data); + self.step = (int)m.step[0]; + self.type = (self.type & ~cv::Mat::CONTINUOUS_FLAG) | (m.flags & cv::Mat::CONTINUOUS_FLAG); + return self; +} +CV_INLINE CvMat cvMat() +{ +#if !defined(CV__ENABLE_C_API_CTORS) + CvMat self = CV_STRUCT_INITIALIZER; return self; +#else + return CvMat(); +#endif +} +CV_INLINE CvMat cvMat(const CvMat& m) +{ +#if !defined(CV__ENABLE_C_API_CTORS) + CvMat self = CV_STRUCT_INITIALIZER; memcpy(&self, &m, sizeof(self)); return self; +#else + return CvMat(m); +#endif +} + +#endif // __cplusplus + + +#define CV_MAT_ELEM_PTR_FAST( mat, row, col, pix_size ) \ + (assert( (unsigned)(row) < (unsigned)(mat).rows && \ + (unsigned)(col) < (unsigned)(mat).cols ), \ + (mat).data.ptr + (size_t)(mat).step*(row) + (pix_size)*(col)) + +#define CV_MAT_ELEM_PTR( mat, row, col ) \ + CV_MAT_ELEM_PTR_FAST( mat, row, col, CV_ELEM_SIZE((mat).type) ) + +#define CV_MAT_ELEM( mat, elemtype, row, col ) \ + (*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype))) + +/** @brief Returns the particular element of single-channel floating-point matrix. + +The function is a fast replacement for cvGetReal2D in the case of single-channel floating-point +matrices. It is faster because it is inline, it does fewer checks for array type and array element +type, and it checks for the row and column ranges only in debug mode. +@param mat Input matrix +@param row The zero-based index of row +@param col The zero-based index of column + */ +CV_INLINE double cvmGet( const CvMat* mat, int row, int col ) +{ + int type; + + type = CV_MAT_TYPE(mat->type); + assert( (unsigned)row < (unsigned)mat->rows && + (unsigned)col < (unsigned)mat->cols ); + + if( type == CV_32FC1 ) + return ((float*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col]; + else + { + assert( type == CV_64FC1 ); + return ((double*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col]; + } +} + +/** @brief Sets a specific element of a single-channel floating-point matrix. + +The function is a fast replacement for cvSetReal2D in the case of single-channel floating-point +matrices. It is faster because it is inline, it does fewer checks for array type and array element +type, and it checks for the row and column ranges only in debug mode. +@param mat The matrix +@param row The zero-based index of row +@param col The zero-based index of column +@param value The new value of the matrix element + */ +CV_INLINE void cvmSet( CvMat* mat, int row, int col, double value ) +{ + int type; + type = CV_MAT_TYPE(mat->type); + assert( (unsigned)row < (unsigned)mat->rows && + (unsigned)col < (unsigned)mat->cols ); + + if( type == CV_32FC1 ) + ((float*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col] = (float)value; + else + { + assert( type == CV_64FC1 ); + ((double*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col] = value; + } +} + + +CV_INLINE int cvIplDepth( int type ) +{ + int depth = CV_MAT_DEPTH(type); + return CV_ELEM_SIZE1(depth)*8 | (depth == CV_8S || depth == CV_16S || + depth == CV_32S ? IPL_DEPTH_SIGN : 0); +} + + +/****************************************************************************************\ +* Multi-dimensional dense array (CvMatND) * +\****************************************************************************************/ + +#define CV_MATND_MAGIC_VAL 0x42430000 +#define CV_TYPE_NAME_MATND "opencv-nd-matrix" + +#define CV_MAX_DIM 32 + +#ifdef __cplusplus +typedef struct CvMatND CvMatND; +CV_EXPORTS CvMatND cvMatND(const cv::Mat& m); +#endif + +/** + @deprecated consider using cv::Mat instead + */ +typedef struct +CvMatND +{ + int type; + int dims; + + int* refcount; + int hdr_refcount; + + union + { + uchar* ptr; + float* fl; + double* db; + int* i; + short* s; + } data; + + struct + { + int size; + int step; + } + dim[CV_MAX_DIM]; + +#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvMatND() {} + CvMatND(const cv::Mat& m) { *this = cvMatND(m); } +#endif +} +CvMatND; + + +CV_INLINE CvMatND cvMatND() +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvMatND self = CV_STRUCT_INITIALIZER; return self; +#else + return CvMatND(); +#endif +} + +#define CV_IS_MATND_HDR(mat) \ + ((mat) != NULL && (((const CvMatND*)(mat))->type & CV_MAGIC_MASK) == CV_MATND_MAGIC_VAL) + +#define CV_IS_MATND(mat) \ + (CV_IS_MATND_HDR(mat) && ((const CvMatND*)(mat))->data.ptr != NULL) + + +/****************************************************************************************\ +* Multi-dimensional sparse array (CvSparseMat) * +\****************************************************************************************/ + +#define CV_SPARSE_MAT_MAGIC_VAL 0x42440000 +#define CV_TYPE_NAME_SPARSE_MAT "opencv-sparse-matrix" + +struct CvSet; + +typedef struct CvSparseMat +{ + int type; + int dims; + int* refcount; + int hdr_refcount; + + struct CvSet* heap; + void** hashtable; + int hashsize; + int valoffset; + int idxoffset; + int size[CV_MAX_DIM]; + +#ifdef __cplusplus + CV_EXPORTS void copyToSparseMat(cv::SparseMat& m) const; +#endif +} +CvSparseMat; + +#ifdef __cplusplus +CV_EXPORTS CvSparseMat* cvCreateSparseMat(const cv::SparseMat& m); +#endif + +#define CV_IS_SPARSE_MAT_HDR(mat) \ + ((mat) != NULL && \ + (((const CvSparseMat*)(mat))->type & CV_MAGIC_MASK) == CV_SPARSE_MAT_MAGIC_VAL) + +#define CV_IS_SPARSE_MAT(mat) \ + CV_IS_SPARSE_MAT_HDR(mat) + +/**************** iteration through a sparse array *****************/ + +typedef struct CvSparseNode +{ + unsigned hashval; + struct CvSparseNode* next; +} +CvSparseNode; + +typedef struct CvSparseMatIterator +{ + CvSparseMat* mat; + CvSparseNode* node; + int curidx; +} +CvSparseMatIterator; + +#define CV_NODE_VAL(mat,node) ((void*)((uchar*)(node) + (mat)->valoffset)) +#define CV_NODE_IDX(mat,node) ((int*)((uchar*)(node) + (mat)->idxoffset)) + +/****************************************************************************************\ +* Histogram * +\****************************************************************************************/ + +typedef int CvHistType; + +#define CV_HIST_MAGIC_VAL 0x42450000 +#define CV_HIST_UNIFORM_FLAG (1 << 10) + +/** indicates whether bin ranges are set already or not */ +#define CV_HIST_RANGES_FLAG (1 << 11) + +#define CV_HIST_ARRAY 0 +#define CV_HIST_SPARSE 1 +#define CV_HIST_TREE CV_HIST_SPARSE + +/** should be used as a parameter only, + it turns to CV_HIST_UNIFORM_FLAG of hist->type */ +#define CV_HIST_UNIFORM 1 + +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; + +#define CV_IS_HIST( hist ) \ + ((hist) != NULL && \ + (((CvHistogram*)(hist))->type & CV_MAGIC_MASK) == CV_HIST_MAGIC_VAL && \ + (hist)->bins != NULL) + +#define CV_IS_UNIFORM_HIST( hist ) \ + (((hist)->type & CV_HIST_UNIFORM_FLAG) != 0) + +#define CV_IS_SPARSE_HIST( hist ) \ + CV_IS_SPARSE_MAT((hist)->bins) + +#define CV_HIST_HAS_RANGES( hist ) \ + (((hist)->type & CV_HIST_RANGES_FLAG) != 0) + +/****************************************************************************************\ +* Other supplementary data type definitions * +\****************************************************************************************/ + +/*************************************** CvRect *****************************************/ +/** @sa Rect_ */ +typedef struct CvRect +{ + int x; + int y; + int width; + int height; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvRect() __attribute__(( warning("Non-initialized variable") )) {}; + template CvRect(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 4); + x = y = width = height = 0; + if (list.size() == 4) + { + x = list.begin()[0]; y = list.begin()[1]; width = list.begin()[2]; height = list.begin()[3]; + } + }; +#elif defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvRect(int _x = 0, int _y = 0, int w = 0, int h = 0): x(_x), y(_y), width(w), height(h) {} + template + CvRect(const cv::Rect_<_Tp>& r): x(cv::saturate_cast(r.x)), y(cv::saturate_cast(r.y)), width(cv::saturate_cast(r.width)), height(cv::saturate_cast(r.height)) {} +#endif +#ifdef __cplusplus + template + operator cv::Rect_<_Tp>() const { return cv::Rect_<_Tp>((_Tp)x, (_Tp)y, (_Tp)width, (_Tp)height); } +#endif +} +CvRect; + +/** constructs CvRect structure. */ +CV_INLINE CvRect cvRect( int x, int y, int width, int height ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvRect r = {x, y, width, height}; +#else + CvRect r(x, y , width, height); +#endif + return r; +} +#ifdef __cplusplus +CV_INLINE CvRect cvRect(const cv::Rect& rc) { return cvRect(rc.x, rc.y, rc.width, rc.height); } +#endif + +CV_INLINE IplROI cvRectToROI( CvRect rect, int coi ) +{ + IplROI roi; + roi.xOffset = rect.x; + roi.yOffset = rect.y; + roi.width = rect.width; + roi.height = rect.height; + roi.coi = coi; + + return roi; +} + + +CV_INLINE CvRect cvROIToRect( IplROI roi ) +{ + return cvRect( roi.xOffset, roi.yOffset, roi.width, roi.height ); +} + +/*********************************** CvTermCriteria *************************************/ + +#define CV_TERMCRIT_ITER 1 +#define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER +#define CV_TERMCRIT_EPS 2 + +/** @sa TermCriteria + */ +typedef struct CvTermCriteria +{ + int type; /**< may be combination of + CV_TERMCRIT_ITER + CV_TERMCRIT_EPS */ + int max_iter; + double epsilon; +#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvTermCriteria(int _type = 0, int _iter = 0, double _eps = 0) : type(_type), max_iter(_iter), epsilon(_eps) {} + CvTermCriteria(const cv::TermCriteria& t) : type(t.type), max_iter(t.maxCount), epsilon(t.epsilon) {} +#endif +#ifdef __cplusplus + operator cv::TermCriteria() const { return cv::TermCriteria(type, max_iter, epsilon); } +#endif +} +CvTermCriteria; + +CV_INLINE CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvTermCriteria t = { type, max_iter, (float)epsilon}; +#else + CvTermCriteria t(type, max_iter, epsilon); +#endif + return t; +} +#ifdef __cplusplus +CV_INLINE CvTermCriteria cvTermCriteria(const cv::TermCriteria& t) { return cvTermCriteria(t.type, t.maxCount, t.epsilon); } +#endif + + +/******************************* CvPoint and variants ***********************************/ + +typedef struct CvPoint +{ + int x; + int y; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvPoint() __attribute__(( warning("Non-initialized variable") )) {} + template CvPoint(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 2); + x = y = 0; + if (list.size() == 2) + { + x = list.begin()[0]; y = list.begin()[1]; + } + }; +#elif defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvPoint(int _x = 0, int _y = 0): x(_x), y(_y) {} + template + CvPoint(const cv::Point_<_Tp>& pt): x((int)pt.x), y((int)pt.y) {} +#endif +#ifdef __cplusplus + template + operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); } +#endif +} +CvPoint; + +/** constructs CvPoint structure. */ +CV_INLINE CvPoint cvPoint( int x, int y ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvPoint p = {x, y}; +#else + CvPoint p(x, y); +#endif + return p; +} +#ifdef __cplusplus +CV_INLINE CvPoint cvPoint(const cv::Point& pt) { return cvPoint(pt.x, pt.y); } +#endif + +typedef struct CvPoint2D32f +{ + float x; + float y; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvPoint2D32f() __attribute__(( warning("Non-initialized variable") )) {} + template CvPoint2D32f(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 2); + x = y = 0; + if (list.size() == 2) + { + x = list.begin()[0]; y = list.begin()[1]; + } + }; +#elif defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvPoint2D32f(float _x = 0, float _y = 0): x(_x), y(_y) {} + template + CvPoint2D32f(const cv::Point_<_Tp>& pt): x((float)pt.x), y((float)pt.y) {} +#endif +#ifdef __cplusplus + template + operator cv::Point_<_Tp>() const { return cv::Point_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y)); } +#endif +} +CvPoint2D32f; + +/** constructs CvPoint2D32f structure. */ +CV_INLINE CvPoint2D32f cvPoint2D32f( double x, double y ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvPoint2D32f p = { (float)x, (float)y }; +#else + CvPoint2D32f p((float)x, (float)y); +#endif + return p; +} + +#ifdef __cplusplus +template +CvPoint2D32f cvPoint2D32f(const cv::Point_<_Tp>& pt) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvPoint2D32f p = { (float)pt.x, (float)pt.y }; +#else + CvPoint2D32f p((float)pt.x, (float)pt.y); +#endif + return p; +} +#endif + +/** converts CvPoint to CvPoint2D32f. */ +CV_INLINE CvPoint2D32f cvPointTo32f( CvPoint point ) +{ + return cvPoint2D32f( (float)point.x, (float)point.y ); +} + +/** converts CvPoint2D32f to CvPoint. */ +CV_INLINE CvPoint cvPointFrom32f( CvPoint2D32f point ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvPoint ipt = { cvRound(point.x), cvRound(point.y) }; +#else + CvPoint ipt(cvRound(point.x), cvRound(point.y)); +#endif + return ipt; +} + + +typedef struct CvPoint3D32f +{ + float x; + float y; + float z; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvPoint3D32f() __attribute__(( warning("Non-initialized variable") )) {} + template CvPoint3D32f(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 3); + x = y = z = 0; + if (list.size() == 3) + { + x = list.begin()[0]; y = list.begin()[1]; z = list.begin()[2]; + } + }; +#elif defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvPoint3D32f(float _x = 0, float _y = 0, float _z = 0): x(_x), y(_y), z(_z) {} + template + CvPoint3D32f(const cv::Point3_<_Tp>& pt): x((float)pt.x), y((float)pt.y), z((float)pt.z) {} +#endif +#ifdef __cplusplus + template + operator cv::Point3_<_Tp>() const { return cv::Point3_<_Tp>(cv::saturate_cast<_Tp>(x), cv::saturate_cast<_Tp>(y), cv::saturate_cast<_Tp>(z)); } +#endif +} +CvPoint3D32f; + +/** constructs CvPoint3D32f structure. */ +CV_INLINE CvPoint3D32f cvPoint3D32f( double x, double y, double z ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvPoint3D32f p = { (float)x, (float)y, (float)z }; +#else + CvPoint3D32f p((float)x, (float)y, (float)z); +#endif + return p; +} + +#ifdef __cplusplus +template +CvPoint3D32f cvPoint3D32f(const cv::Point3_<_Tp>& pt) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvPoint3D32f p = { (float)pt.x, (float)pt.y, (float)pt.z }; +#else + CvPoint3D32f p((float)pt.x, (float)pt.y, (float)pt.z); +#endif + return p; +} +#endif + + +typedef struct CvPoint2D64f +{ + double x; + double y; +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvPoint2D64f() __attribute__(( warning("Non-initialized variable") )) {} + template CvPoint2D64f(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 2); + x = y = 0; + if (list.size() == 2) + { + x = list.begin()[0]; y = list.begin()[1]; + } + }; +#endif +} +CvPoint2D64f; + +/** constructs CvPoint2D64f structure.*/ +CV_INLINE CvPoint2D64f cvPoint2D64f( double x, double y ) +{ + CvPoint2D64f p = { x, y }; + return p; +} + + +typedef struct CvPoint3D64f +{ + double x; + double y; + double z; +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvPoint3D64f() __attribute__(( warning("Non-initialized variable") )) {} + template CvPoint3D64f(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 3); + x = y = z = 0; + if (list.size() == 3) + { + x = list.begin()[0]; y = list.begin()[1]; z = list.begin()[2]; + } + }; +#endif +} +CvPoint3D64f; + +/** constructs CvPoint3D64f structure. */ +CV_INLINE CvPoint3D64f cvPoint3D64f( double x, double y, double z ) +{ + CvPoint3D64f p = { x, y, z }; + return p; +} + + +/******************************** CvSize's & CvBox **************************************/ + +typedef struct CvSize +{ + int width; + int height; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvSize() __attribute__(( warning("Non-initialized variable") )) {} + template CvSize(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 2); + width = 0; height = 0; + if (list.size() == 2) + { + width = list.begin()[0]; height = list.begin()[1]; + } + }; +#elif defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvSize(int w = 0, int h = 0): width(w), height(h) {} + template + CvSize(const cv::Size_<_Tp>& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {} +#endif +#ifdef __cplusplus + template + operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); } +#endif +} +CvSize; + +/** constructs CvSize structure. */ +CV_INLINE CvSize cvSize( int width, int height ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvSize s = { width, height }; +#else + CvSize s(width, height); +#endif + return s; +} + +#ifdef __cplusplus +CV_INLINE CvSize cvSize(const cv::Size& sz) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvSize s = { sz.width, sz.height }; +#else + CvSize s(sz.width, sz.height); +#endif + return s; +} +#endif + +typedef struct CvSize2D32f +{ + float width; + float height; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvSize2D32f() __attribute__(( warning("Non-initialized variable") )) {} + template CvSize2D32f(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 2); + width = 0; height = 0; + if (list.size() == 2) + { + width = list.begin()[0]; height = list.begin()[1]; + } + }; +#elif defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvSize2D32f(float w = 0, float h = 0): width(w), height(h) {} + template + CvSize2D32f(const cv::Size_<_Tp>& sz): width(cv::saturate_cast(sz.width)), height(cv::saturate_cast(sz.height)) {} +#endif +#ifdef __cplusplus + template + operator cv::Size_<_Tp>() const { return cv::Size_<_Tp>(cv::saturate_cast<_Tp>(width), cv::saturate_cast<_Tp>(height)); } +#endif +} +CvSize2D32f; + +/** constructs CvSize2D32f structure. */ +CV_INLINE CvSize2D32f cvSize2D32f( double width, double height ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvSize2D32f s = { (float)width, (float)height }; +#else + CvSize2D32f s((float)width, (float)height); +#endif + return s; +} +#ifdef __cplusplus +template +CvSize2D32f cvSize2D32f(const cv::Size_<_Tp>& sz) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvSize2D32f s = { (float)sz.width, (float)sz.height }; +#else + CvSize2D32f s((float)sz.width, (float)sz.height); +#endif + return s; +} +#endif + +/** @sa RotatedRect + */ +typedef struct CvBox2D +{ + CvPoint2D32f center; /**< Center of the box. */ + CvSize2D32f size; /**< Box width and length. */ + float angle; /**< Angle between the horizontal axis */ + /**< and the first side (i.e. length) in degrees */ + +#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvBox2D(CvPoint2D32f c = CvPoint2D32f(), CvSize2D32f s = CvSize2D32f(), float a = 0) : center(c), size(s), angle(a) {} + CvBox2D(const cv::RotatedRect& rr) : center(rr.center), size(rr.size), angle(rr.angle) {} +#endif +#ifdef __cplusplus + operator cv::RotatedRect() const { return cv::RotatedRect(center, size, angle); } +#endif +} +CvBox2D; + + +#ifdef __cplusplus +CV_INLINE CvBox2D cvBox2D(CvPoint2D32f c = CvPoint2D32f(), CvSize2D32f s = CvSize2D32f(), float a = 0) +{ + CvBox2D self; + self.center = c; + self.size = s; + self.angle = a; + return self; +} +CV_INLINE CvBox2D cvBox2D(const cv::RotatedRect& rr) +{ + CvBox2D self; + self.center = cvPoint2D32f(rr.center); + self.size = cvSize2D32f(rr.size); + self.angle = rr.angle; + return self; +} +#endif + + +/** Line iterator state: */ +typedef struct CvLineIterator +{ + /** Pointer to the current point: */ + uchar* ptr; + + /* Bresenham algorithm state: */ + int err; + int plus_delta; + int minus_delta; + int plus_step; + int minus_step; +} +CvLineIterator; + + + +/************************************* CvSlice ******************************************/ +#define CV_WHOLE_SEQ_END_INDEX 0x3fffffff +#define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX) + +typedef struct CvSlice +{ + int start_index, end_index; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvSlice() __attribute__(( warning("Non-initialized variable") )) {} + template CvSlice(const std::initializer_list<_Tp> list) + { + CV_Assert(list.size() == 0 || list.size() == 2); + start_index = end_index = 0; + if (list.size() == 2) + { + start_index = list.begin()[0]; end_index = list.begin()[1]; + } + }; +#endif +#if defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) && !defined(__CUDACC__) + CvSlice(int start = 0, int end = 0) : start_index(start), end_index(end) {} + CvSlice(const cv::Range& r) { *this = (r.start != INT_MIN && r.end != INT_MAX) ? CvSlice(r.start, r.end) : CvSlice(0, CV_WHOLE_SEQ_END_INDEX); } + operator cv::Range() const { return (start_index == 0 && end_index == CV_WHOLE_SEQ_END_INDEX ) ? cv::Range::all() : cv::Range(start_index, end_index); } +#endif +} +CvSlice; + +CV_INLINE CvSlice cvSlice( int start, int end ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) && !defined(__CUDACC__)) + CvSlice slice = { start, end }; +#else + CvSlice slice(start, end); +#endif + return slice; +} + +#if defined(__cplusplus) +CV_INLINE CvSlice cvSlice(const cv::Range& r) +{ + CvSlice slice = (r.start != INT_MIN && r.end != INT_MAX) ? cvSlice(r.start, r.end) : cvSlice(0, CV_WHOLE_SEQ_END_INDEX); + return slice; +} +#endif + + +/************************************* CvScalar *****************************************/ +/** @sa Scalar_ + */ +typedef struct CvScalar +{ + double val[4]; + +#ifdef CV__VALIDATE_UNUNITIALIZED_VARS + CvScalar() __attribute__(( warning("Non-initialized variable") )) {} + CvScalar(const std::initializer_list list) + { + CV_Assert(list.size() == 0 || list.size() == 4); + val[0] = val[1] = val[2] = val[3] = 0; + if (list.size() == 4) + { + val[0] = list.begin()[0]; val[1] = list.begin()[1]; val[2] = list.begin()[2]; val[3] = list.begin()[3]; + } + }; +#elif defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus) + CvScalar() {} + CvScalar(double d0, double d1 = 0, double d2 = 0, double d3 = 0) { val[0] = d0; val[1] = d1; val[2] = d2; val[3] = d3; } + template + CvScalar(const cv::Scalar_<_Tp>& s) { val[0] = s.val[0]; val[1] = s.val[1]; val[2] = s.val[2]; val[3] = s.val[3]; } + template + CvScalar(const cv::Vec<_Tp, cn>& v) + { + int i; + for( i = 0; i < (cn < 4 ? cn : 4); i++ ) val[i] = v.val[i]; + for( ; i < 4; i++ ) val[i] = 0; + } +#endif +#ifdef __cplusplus + template + operator cv::Scalar_<_Tp>() const { return cv::Scalar_<_Tp>(cv::saturate_cast<_Tp>(val[0]), cv::saturate_cast<_Tp>(val[1]), cv::saturate_cast<_Tp>(val[2]), cv::saturate_cast<_Tp>(val[3])); } +#endif +} +CvScalar; + +CV_INLINE CvScalar cvScalar( double val0, double val1 CV_DEFAULT(0), + double val2 CV_DEFAULT(0), double val3 CV_DEFAULT(0)) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvScalar scalar = CV_STRUCT_INITIALIZER; +#else + CvScalar scalar; +#endif + scalar.val[0] = val0; scalar.val[1] = val1; + scalar.val[2] = val2; scalar.val[3] = val3; + return scalar; +} + +#ifdef __cplusplus +CV_INLINE CvScalar cvScalar() +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvScalar scalar = CV_STRUCT_INITIALIZER; +#else + CvScalar scalar; +#endif + scalar.val[0] = scalar.val[1] = scalar.val[2] = scalar.val[3] = 0; + return scalar; +} +CV_INLINE CvScalar cvScalar(const cv::Scalar& s) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvScalar scalar = CV_STRUCT_INITIALIZER; +#else + CvScalar scalar; +#endif + scalar.val[0] = s.val[0]; + scalar.val[1] = s.val[1]; + scalar.val[2] = s.val[2]; + scalar.val[3] = s.val[3]; + return scalar; +} +#endif + +CV_INLINE CvScalar cvRealScalar( double val0 ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvScalar scalar = CV_STRUCT_INITIALIZER; +#else + CvScalar scalar; +#endif + scalar.val[0] = val0; + scalar.val[1] = scalar.val[2] = scalar.val[3] = 0; + return scalar; +} + +CV_INLINE CvScalar cvScalarAll( double val0123 ) +{ +#if !(defined(CV__ENABLE_C_API_CTORS) && defined(__cplusplus)) + CvScalar scalar = CV_STRUCT_INITIALIZER; +#else + CvScalar scalar; +#endif + scalar.val[0] = val0123; + scalar.val[1] = val0123; + scalar.val[2] = val0123; + scalar.val[3] = val0123; + return scalar; +} + +/****************************************************************************************\ +* Dynamic Data structures * +\****************************************************************************************/ + +/******************************** Memory storage ****************************************/ + +typedef struct CvMemBlock +{ + struct CvMemBlock* prev; + struct CvMemBlock* next; +} +CvMemBlock; + +#define CV_STORAGE_MAGIC_VAL 0x42890000 + +typedef struct CvMemStorage +{ + int signature; + CvMemBlock* bottom; /**< First allocated block. */ + CvMemBlock* top; /**< Current memory block - top of the stack. */ + struct CvMemStorage* parent; /**< We get new blocks from parent as needed. */ + int block_size; /**< Block size. */ + int free_space; /**< Remaining free space in current block. */ +} +CvMemStorage; + +#define CV_IS_STORAGE(storage) \ + ((storage) != NULL && \ + (((CvMemStorage*)(storage))->signature & CV_MAGIC_MASK) == CV_STORAGE_MAGIC_VAL) + + +typedef struct CvMemStoragePos +{ + CvMemBlock* top; + int free_space; +} +CvMemStoragePos; + + +/*********************************** Sequence *******************************************/ + +typedef struct CvSeqBlock +{ + struct CvSeqBlock* prev; /**< Previous sequence block. */ + struct CvSeqBlock* next; /**< Next sequence block. */ + int start_index; /**< Index of the first element in the block + */ + /**< sequence->first->start_index. */ + int count; /**< Number of elements in the block. */ + schar* data; /**< Pointer to the first element of the block. */ +} +CvSeqBlock; + + +#define CV_TREE_NODE_FIELDS(node_type) \ + int flags; /**< Miscellaneous flags. */ \ + int header_size; /**< Size of sequence header. */ \ + struct node_type* h_prev; /**< Previous sequence. */ \ + struct node_type* h_next; /**< Next sequence. */ \ + struct node_type* v_prev; /**< 2nd previous sequence. */ \ + struct node_type* v_next /**< 2nd next sequence. */ + +/** + Read/Write sequence. + Elements can be dynamically inserted to or deleted from the sequence. +*/ +#define CV_SEQUENCE_FIELDS() \ + CV_TREE_NODE_FIELDS(CvSeq); \ + int total; /**< Total number of elements. */ \ + int elem_size; /**< Size of sequence element in bytes. */ \ + schar* block_max; /**< Maximal bound of the last block. */ \ + schar* ptr; /**< Current write pointer. */ \ + int delta_elems; /**< Grow seq this many at a time. */ \ + CvMemStorage* storage; /**< Where the seq is stored. */ \ + CvSeqBlock* free_blocks; /**< Free blocks list. */ \ + CvSeqBlock* first; /**< Pointer to the first sequence block. */ + +typedef struct CvSeq +{ + CV_SEQUENCE_FIELDS() +} +CvSeq; + +#define CV_TYPE_NAME_SEQ "opencv-sequence" +#define CV_TYPE_NAME_SEQ_TREE "opencv-sequence-tree" + +/*************************************** Set ********************************************/ +/** @brief Set + Order is not preserved. There can be gaps between sequence elements. + After the element has been inserted it stays in the same place all the time. + The MSB(most-significant or sign bit) of the first field (flags) is 0 iff the element exists. +*/ +#define CV_SET_ELEM_FIELDS(elem_type) \ + int flags; \ + struct elem_type* next_free; + +typedef struct CvSetElem +{ + CV_SET_ELEM_FIELDS(CvSetElem) +} +CvSetElem; + +#define CV_SET_FIELDS() \ + CV_SEQUENCE_FIELDS() \ + CvSetElem* free_elems; \ + int active_count; + +typedef struct CvSet +{ + CV_SET_FIELDS() +} +CvSet; + + +#define CV_SET_ELEM_IDX_MASK ((1 << 26) - 1) +#define CV_SET_ELEM_FREE_FLAG (1 << (sizeof(int)*8-1)) + +/** Checks whether the element pointed by ptr belongs to a set or not */ +#define CV_IS_SET_ELEM( ptr ) (((CvSetElem*)(ptr))->flags >= 0) + +/************************************* Graph ********************************************/ + +/** @name Graph + +We represent a graph as a set of vertices. Vertices contain their adjacency lists (more exactly, +pointers to first incoming or outcoming edge (or 0 if isolated vertex)). Edges are stored in +another set. There is a singly-linked list of incoming/outcoming edges for each vertex. + +Each edge consists of: + +- Two pointers to the starting and ending vertices (vtx[0] and vtx[1] respectively). + + A graph may be oriented or not. In the latter case, edges between vertex i to vertex j are not +distinguished during search operations. + +- Two pointers to next edges for the starting and ending vertices, where next[0] points to the +next edge in the vtx[0] adjacency list and next[1] points to the next edge in the vtx[1] +adjacency list. + +@see CvGraphEdge, CvGraphVtx, CvGraphVtx2D, CvGraph +@{ +*/ +#define CV_GRAPH_EDGE_FIELDS() \ + int flags; \ + float weight; \ + struct CvGraphEdge* next[2]; \ + struct CvGraphVtx* vtx[2]; + + +#define CV_GRAPH_VERTEX_FIELDS() \ + int flags; \ + struct CvGraphEdge* first; + + +typedef struct CvGraphEdge +{ + CV_GRAPH_EDGE_FIELDS() +} +CvGraphEdge; + +typedef struct CvGraphVtx +{ + CV_GRAPH_VERTEX_FIELDS() +} +CvGraphVtx; + +typedef struct CvGraphVtx2D +{ + CV_GRAPH_VERTEX_FIELDS() + CvPoint2D32f* ptr; +} +CvGraphVtx2D; + +/** + Graph is "derived" from the set (this is set a of vertices) + and includes another set (edges) +*/ +#define CV_GRAPH_FIELDS() \ + CV_SET_FIELDS() \ + CvSet* edges; + +typedef struct CvGraph +{ + CV_GRAPH_FIELDS() +} +CvGraph; + +#define CV_TYPE_NAME_GRAPH "opencv-graph" + +/** @} */ + +/*********************************** Chain/Contour *************************************/ + +typedef struct CvChain +{ + CV_SEQUENCE_FIELDS() + CvPoint origin; +} +CvChain; + +#define CV_CONTOUR_FIELDS() \ + CV_SEQUENCE_FIELDS() \ + CvRect rect; \ + int color; \ + int reserved[3]; + +typedef struct CvContour +{ + CV_CONTOUR_FIELDS() +} +CvContour; + +typedef CvContour CvPoint2DSeq; + +/****************************************************************************************\ +* Sequence types * +\****************************************************************************************/ + +#define CV_SEQ_MAGIC_VAL 0x42990000 + +#define CV_IS_SEQ(seq) \ + ((seq) != NULL && (((CvSeq*)(seq))->flags & CV_MAGIC_MASK) == CV_SEQ_MAGIC_VAL) + +#define CV_SET_MAGIC_VAL 0x42980000 +#define CV_IS_SET(set) \ + ((set) != NULL && (((CvSeq*)(set))->flags & CV_MAGIC_MASK) == CV_SET_MAGIC_VAL) + +#define CV_SEQ_ELTYPE_BITS 12 +#define CV_SEQ_ELTYPE_MASK ((1 << CV_SEQ_ELTYPE_BITS) - 1) + +#define CV_SEQ_ELTYPE_POINT CV_32SC2 /**< (x,y) */ +#define CV_SEQ_ELTYPE_CODE CV_8UC1 /**< freeman code: 0..7 */ +#define CV_SEQ_ELTYPE_GENERIC 0 +#define CV_SEQ_ELTYPE_PTR CV_MAKE_TYPE(CV_8U, 8 /*sizeof(void*)*/) +#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /**< &(x,y) */ +#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /**< #(x,y) */ +#define CV_SEQ_ELTYPE_GRAPH_EDGE 0 /**< &next_o, &next_d, &vtx_o, &vtx_d */ +#define CV_SEQ_ELTYPE_GRAPH_VERTEX 0 /**< first_edge, &(x,y) */ +#define CV_SEQ_ELTYPE_TRIAN_ATR 0 /**< vertex of the binary tree */ +#define CV_SEQ_ELTYPE_CONNECTED_COMP 0 /**< connected component */ +#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /**< (x,y,z) */ + +#define CV_SEQ_KIND_BITS 2 +#define CV_SEQ_KIND_MASK (((1 << CV_SEQ_KIND_BITS) - 1)<flags & CV_SEQ_ELTYPE_MASK) +#define CV_SEQ_KIND( seq ) ((seq)->flags & CV_SEQ_KIND_MASK ) + +/** flag checking */ +#define CV_IS_SEQ_INDEX( seq ) ((CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_INDEX) && \ + (CV_SEQ_KIND(seq) == CV_SEQ_KIND_GENERIC)) + +#define CV_IS_SEQ_CURVE( seq ) (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE) +#define CV_IS_SEQ_CLOSED( seq ) (((seq)->flags & CV_SEQ_FLAG_CLOSED) != 0) +#define CV_IS_SEQ_CONVEX( seq ) 0 +#define CV_IS_SEQ_HOLE( seq ) (((seq)->flags & CV_SEQ_FLAG_HOLE) != 0) +#define CV_IS_SEQ_SIMPLE( seq ) 1 + +/** type checking macros */ +#define CV_IS_SEQ_POINT_SET( seq ) \ + ((CV_SEQ_ELTYPE(seq) == CV_32SC2 || CV_SEQ_ELTYPE(seq) == CV_32FC2)) + +#define CV_IS_SEQ_POINT_SUBSET( seq ) \ + (CV_IS_SEQ_INDEX( seq ) || CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_PPOINT) + +#define CV_IS_SEQ_POLYLINE( seq ) \ + (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && CV_IS_SEQ_POINT_SET(seq)) + +#define CV_IS_SEQ_POLYGON( seq ) \ + (CV_IS_SEQ_POLYLINE(seq) && CV_IS_SEQ_CLOSED(seq)) + +#define CV_IS_SEQ_CHAIN( seq ) \ + (CV_SEQ_KIND(seq) == CV_SEQ_KIND_CURVE && (seq)->elem_size == 1) + +#define CV_IS_SEQ_CONTOUR( seq ) \ + (CV_IS_SEQ_CLOSED(seq) && (CV_IS_SEQ_POLYLINE(seq) || CV_IS_SEQ_CHAIN(seq))) + +#define CV_IS_SEQ_CHAIN_CONTOUR( seq ) \ + (CV_IS_SEQ_CHAIN( seq ) && CV_IS_SEQ_CLOSED( seq )) + +#define CV_IS_SEQ_POLYGON_TREE( seq ) \ + (CV_SEQ_ELTYPE (seq) == CV_SEQ_ELTYPE_TRIAN_ATR && \ + CV_SEQ_KIND( seq ) == CV_SEQ_KIND_BIN_TREE ) + +#define CV_IS_GRAPH( seq ) \ + (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_GRAPH) + +#define CV_IS_GRAPH_ORIENTED( seq ) \ + (((seq)->flags & CV_GRAPH_FLAG_ORIENTED) != 0) + +#define CV_IS_SUBDIV2D( seq ) \ + (CV_IS_SET(seq) && CV_SEQ_KIND((CvSet*)(seq)) == CV_SEQ_KIND_SUBDIV2D) + +/****************************************************************************************/ +/* Sequence writer & reader */ +/****************************************************************************************/ + +#define CV_SEQ_WRITER_FIELDS() \ + int header_size; \ + CvSeq* seq; /**< the sequence written */ \ + CvSeqBlock* block; /**< current block */ \ + schar* ptr; /**< pointer to free space */ \ + schar* block_min; /**< pointer to the beginning of block*/\ + schar* block_max; /**< pointer to the end of block */ + +typedef struct CvSeqWriter +{ + CV_SEQ_WRITER_FIELDS() +} +CvSeqWriter; + + +#define CV_SEQ_READER_FIELDS() \ + int header_size; \ + CvSeq* seq; /**< sequence, beign read */ \ + CvSeqBlock* block; /**< current block */ \ + schar* ptr; /**< pointer to element be read next */ \ + schar* block_min; /**< pointer to the beginning of block */\ + schar* block_max; /**< pointer to the end of block */ \ + int delta_index;/**< = seq->first->start_index */ \ + schar* prev_elem; /**< pointer to previous element */ + +typedef struct CvSeqReader +{ + CV_SEQ_READER_FIELDS() +} +CvSeqReader; + +/****************************************************************************************/ +/* Operations on sequences */ +/****************************************************************************************/ + +#define CV_SEQ_ELEM( seq, elem_type, index ) \ +/** assert gives some guarantee that parameter is valid */ \ +( assert(sizeof((seq)->first[0]) == sizeof(CvSeqBlock) && \ + (seq)->elem_size == sizeof(elem_type)), \ + (elem_type*)((seq)->first && (unsigned)index < \ + (unsigned)((seq)->first->count) ? \ + (seq)->first->data + (index) * sizeof(elem_type) : \ + cvGetSeqElem( (CvSeq*)(seq), (index) ))) +#define CV_GET_SEQ_ELEM( elem_type, seq, index ) CV_SEQ_ELEM( (seq), elem_type, (index) ) + +/** Add element to sequence: */ +#define CV_WRITE_SEQ_ELEM_VAR( elem_ptr, writer ) \ +{ \ + if( (writer).ptr >= (writer).block_max ) \ + { \ + cvCreateSeqBlock( &writer); \ + } \ + memcpy((writer).ptr, elem_ptr, (writer).seq->elem_size);\ + (writer).ptr += (writer).seq->elem_size; \ +} + +#define CV_WRITE_SEQ_ELEM( elem, writer ) \ +{ \ + assert( (writer).seq->elem_size == sizeof(elem)); \ + if( (writer).ptr >= (writer).block_max ) \ + { \ + cvCreateSeqBlock( &writer); \ + } \ + assert( (writer).ptr <= (writer).block_max - sizeof(elem));\ + memcpy((writer).ptr, &(elem), sizeof(elem)); \ + (writer).ptr += sizeof(elem); \ +} + + +/** Move reader position forward: */ +#define CV_NEXT_SEQ_ELEM( elem_size, reader ) \ +{ \ + if( ((reader).ptr += (elem_size)) >= (reader).block_max ) \ + { \ + cvChangeSeqBlock( &(reader), 1 ); \ + } \ +} + + +/** Move reader position backward: */ +#define CV_PREV_SEQ_ELEM( elem_size, reader ) \ +{ \ + if( ((reader).ptr -= (elem_size)) < (reader).block_min ) \ + { \ + cvChangeSeqBlock( &(reader), -1 ); \ + } \ +} + +/** Read element and move read position forward: */ +#define CV_READ_SEQ_ELEM( elem, reader ) \ +{ \ + assert( (reader).seq->elem_size == sizeof(elem)); \ + memcpy( &(elem), (reader).ptr, sizeof((elem))); \ + CV_NEXT_SEQ_ELEM( sizeof(elem), reader ) \ +} + +/** Read element and move read position backward: */ +#define CV_REV_READ_SEQ_ELEM( elem, reader ) \ +{ \ + assert( (reader).seq->elem_size == sizeof(elem)); \ + memcpy(&(elem), (reader).ptr, sizeof((elem))); \ + CV_PREV_SEQ_ELEM( sizeof(elem), reader ) \ +} + + +#define CV_READ_CHAIN_POINT( _pt, reader ) \ +{ \ + (_pt) = (reader).pt; \ + if( (reader).ptr ) \ + { \ + CV_READ_SEQ_ELEM( (reader).code, (reader)); \ + assert( ((reader).code & ~7) == 0 ); \ + (reader).pt.x += (reader).deltas[(int)(reader).code][0]; \ + (reader).pt.y += (reader).deltas[(int)(reader).code][1]; \ + } \ +} + +#define CV_CURRENT_POINT( reader ) (*((CvPoint*)((reader).ptr))) +#define CV_PREV_POINT( reader ) (*((CvPoint*)((reader).prev_elem))) + +#define CV_READ_EDGE( pt1, pt2, reader ) \ +{ \ + assert( sizeof(pt1) == sizeof(CvPoint) && \ + sizeof(pt2) == sizeof(CvPoint) && \ + reader.seq->elem_size == sizeof(CvPoint)); \ + (pt1) = CV_PREV_POINT( reader ); \ + (pt2) = CV_CURRENT_POINT( reader ); \ + (reader).prev_elem = (reader).ptr; \ + CV_NEXT_SEQ_ELEM( sizeof(CvPoint), (reader)); \ +} + +/************ Graph macros ************/ + +/** Return next graph edge for given vertex: */ +#define CV_NEXT_GRAPH_EDGE( edge, vertex ) \ + (assert((edge)->vtx[0] == (vertex) || (edge)->vtx[1] == (vertex)), \ + (edge)->next[(edge)->vtx[1] == (vertex)]) + + + +/****************************************************************************************\ +* Data structures for persistence (a.k.a serialization) functionality * +\****************************************************************************************/ + +#if 0 + +/** "black box" file storage */ +typedef struct CvFileStorage CvFileStorage; + +/** Storage flags: */ +#define CV_STORAGE_READ 0 +#define CV_STORAGE_WRITE 1 +#define CV_STORAGE_WRITE_TEXT CV_STORAGE_WRITE +#define CV_STORAGE_WRITE_BINARY CV_STORAGE_WRITE +#define CV_STORAGE_APPEND 2 +#define CV_STORAGE_MEMORY 4 +#define CV_STORAGE_FORMAT_MASK (7<<3) +#define CV_STORAGE_FORMAT_AUTO 0 +#define CV_STORAGE_FORMAT_XML 8 +#define CV_STORAGE_FORMAT_YAML 16 +#define CV_STORAGE_FORMAT_JSON 24 +#define CV_STORAGE_BASE64 64 +#define CV_STORAGE_WRITE_BASE64 (CV_STORAGE_BASE64 | CV_STORAGE_WRITE) + +/** @brief List of attributes. : + +In the current implementation, attributes are used to pass extra parameters when writing user +objects (see cvWrite). XML attributes inside tags are not supported, aside from the object type +specification (type_id attribute). +@see cvAttrList, cvAttrValue + */ +typedef struct CvAttrList +{ + const char** attr; /**< NULL-terminated array of (attribute_name,attribute_value) pairs. */ + struct CvAttrList* next; /**< Pointer to next chunk of the attributes list. */ +} +CvAttrList; + +/** initializes CvAttrList structure */ +CV_INLINE CvAttrList cvAttrList( const char** attr CV_DEFAULT(NULL), + CvAttrList* next CV_DEFAULT(NULL) ) +{ + CvAttrList l; + l.attr = attr; + l.next = next; + + return l; +} + +struct CvTypeInfo; + +#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 + +#define CV_NODE_TYPE(flags) ((flags) & CV_NODE_TYPE_MASK) + +/** file node flags */ +#define CV_NODE_FLOW 8 /**= CV_NODE_SEQ) +#define CV_NODE_IS_FLOW(flags) (((flags) & CV_NODE_FLOW) != 0) +#define CV_NODE_IS_EMPTY(flags) (((flags) & CV_NODE_EMPTY) != 0) +#define CV_NODE_IS_USER(flags) (((flags) & CV_NODE_USER) != 0) +#define CV_NODE_HAS_NAME(flags) (((flags) & 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 read file storage + are stored in the hash to speed up the lookup operations: */ +typedef struct CvStringHashNode +{ + unsigned hashval; + CvString str; + struct CvStringHashNode* next; +} +CvStringHashNode; + +typedef struct CvGenericHash CvFileNodeHash; + +/** 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) */ + CvFileNodeHash* map; /**< map (collection of named file nodes) */ + } data; +} +CvFileNode; + +#ifdef __cplusplus +extern "C" { +#endif +typedef int (CV_CDECL *CvIsInstanceFunc)( const void* struct_ptr ); +typedef void (CV_CDECL *CvReleaseFunc)( void** struct_dblptr ); +typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node ); +typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, const char* name, + const void* struct_ptr, CvAttrList attributes ); +typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr ); +#ifdef __cplusplus +} +#endif + +/** @brief Type information + +The structure contains information about one of the standard or user-defined types. Instances of the +type may or may not contain a pointer to the corresponding CvTypeInfo structure. In any case, there +is a way to find the type info structure for a given object using the cvTypeOf function. +Alternatively, type info can be found by type name using cvFindType, which is used when an object +is read from file storage. The user can register a new type with cvRegisterType that adds the type +information structure into the beginning of the type list. Thus, it is possible to create +specialized types from generic standard types and override the basic methods. + */ +typedef struct CvTypeInfo +{ + int flags; /**< not used */ + int header_size; /**< sizeof(CvTypeInfo) */ + struct CvTypeInfo* prev; /**< previous registered type in the list */ + struct CvTypeInfo* next; /**< next registered type in the list */ + const char* type_name; /**< type name, written to file storage */ + CvIsInstanceFunc is_instance; /**< checks if the passed object belongs to the type */ + CvReleaseFunc release; /**< releases object (memory etc.) */ + CvReadFunc read; /**< reads object from file storage */ + CvWriteFunc write; /**< writes object to file storage */ + CvCloneFunc clone; /**< creates a copy of the object */ +} +CvTypeInfo; +#endif + +/** @} */ + +#endif /*OPENCV_CORE_TYPES_H*/ + +/* End of file. */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utility.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utility.hpp new file mode 100755 index 0000000..3cbe295 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utility.hpp @@ -0,0 +1,1318 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2015, Itseez Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_UTILITY_H +#define OPENCV_CORE_UTILITY_H + +#ifndef __cplusplus +# error utility.hpp header must be compiled as C++ +#endif + +#if defined(check) +# warning Detected Apple 'check' macro definition, it can cause build conflicts. Please, include this header before any Apple headers. +#endif + +#include "opencv2/core.hpp" +#include + +#include + +#if !defined(_M_CEE) +#include // std::mutex, std::lock_guard +#endif + +namespace cv +{ + +#ifdef CV_COLLECT_IMPL_DATA +CV_EXPORTS void setImpl(int flags); // set implementation flags and reset storage arrays +CV_EXPORTS void addImpl(int flag, const char* func = 0); // add implementation and function name to storage arrays +// Get stored implementation flags and functions names arrays +// Each implementation entry correspond to function name entry, so you can find which implementation was executed in which function +CV_EXPORTS int getImpl(std::vector &impl, std::vector &funName); + +CV_EXPORTS bool useCollection(); // return implementation collection state +CV_EXPORTS void setUseCollection(bool flag); // set implementation collection state + +#define CV_IMPL_PLAIN 0x01 // native CPU OpenCV implementation +#define CV_IMPL_OCL 0x02 // OpenCL implementation +#define CV_IMPL_IPP 0x04 // IPP implementation +#define CV_IMPL_MT 0x10 // multithreaded implementation + +#define CV_IMPL_ADD(impl) \ + if(cv::useCollection()) \ + { \ + cv::addImpl(impl, CV_Func); \ + } +#else +#define CV_IMPL_ADD(impl) +#endif + +//! @addtogroup core_utils +//! @{ + +/** @brief Automatically Allocated Buffer Class + + The class is used for temporary buffers in functions and methods. + If a temporary buffer is usually small (a few K's of memory), + but its size depends on the parameters, it makes sense to create a small + fixed-size array on stack and use it if it's large enough. If the required buffer size + is larger than the fixed size, another buffer of sufficient size is allocated dynamically + and released after the processing. Therefore, in typical cases, when the buffer size is small, + there is no overhead associated with malloc()/free(). + At the same time, there is no limit on the size of processed data. + + This is what AutoBuffer does. The template takes 2 parameters - type of the buffer elements and + the number of stack-allocated elements. Here is how the class is used: + + \code + void my_func(const cv::Mat& m) + { + cv::AutoBuffer buf(1000); // create automatic buffer containing 1000 floats + + buf.allocate(m.rows); // if m.rows <= 1000, the pre-allocated buffer is used, + // otherwise the buffer of "m.rows" floats will be allocated + // dynamically and deallocated in cv::AutoBuffer destructor + ... + } + \endcode +*/ +#ifdef OPENCV_ENABLE_MEMORY_SANITIZER +template class AutoBuffer +#else +template class AutoBuffer +#endif +{ +public: + typedef _Tp value_type; + + //! the default constructor + AutoBuffer(); + //! constructor taking the real buffer size + explicit AutoBuffer(size_t _size); + + //! the copy constructor + AutoBuffer(const AutoBuffer<_Tp, fixed_size>& buf); + //! the assignment operator + AutoBuffer<_Tp, fixed_size>& operator = (const AutoBuffer<_Tp, fixed_size>& buf); + + //! destructor. calls deallocate() + ~AutoBuffer(); + + //! allocates the new buffer of size _size. if the _size is small enough, stack-allocated buffer is used + void allocate(size_t _size); + //! deallocates the buffer if it was dynamically allocated + void deallocate(); + //! resizes the buffer and preserves the content + void resize(size_t _size); + //! returns the current buffer size + size_t size() const; + //! returns pointer to the real buffer, stack-allocated or heap-allocated + inline _Tp* data() { return ptr; } + //! returns read-only pointer to the real buffer, stack-allocated or heap-allocated + inline const _Tp* data() const { return ptr; } + +#if !defined(OPENCV_DISABLE_DEPRECATED_COMPATIBILITY) // use to .data() calls instead + //! returns pointer to the real buffer, stack-allocated or heap-allocated + operator _Tp* () { return ptr; } + //! returns read-only pointer to the real buffer, stack-allocated or heap-allocated + operator const _Tp* () const { return ptr; } +#else + //! returns a reference to the element at specified location. No bounds checking is performed in Release builds. + inline _Tp& operator[] (size_t i) { CV_DbgCheckLT(i, sz, "out of range"); return ptr[i]; } + //! returns a reference to the element at specified location. No bounds checking is performed in Release builds. + inline const _Tp& operator[] (size_t i) const { CV_DbgCheckLT(i, sz, "out of range"); return ptr[i]; } +#endif + +protected: + //! pointer to the real buffer, can point to buf if the buffer is small enough + _Tp* ptr; + //! size of the real buffer + size_t sz; + //! pre-allocated buffer. At least 1 element to confirm C++ standard requirements + _Tp buf[(fixed_size > 0) ? fixed_size : 1]; +}; + +/** @brief Sets/resets the break-on-error mode. + +When the break-on-error mode is set, the default error handler issues a hardware exception, which +can make debugging more convenient. + +\return the previous state + */ +CV_EXPORTS bool setBreakOnError(bool flag); + +extern "C" typedef int (*ErrorCallback)( int status, const char* func_name, + const char* err_msg, const char* file_name, + int line, void* userdata ); + + +/** @brief Sets the new error handler and the optional user data. + + The function sets the new error handler, called from cv::error(). + + \param errCallback the new error handler. If NULL, the default error handler is used. + \param userdata the optional user data pointer, passed to the callback. + \param prevUserdata the optional output parameter where the previous user data pointer is stored + + \return the previous error handler +*/ +CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback, void* userdata=0, void** prevUserdata=0); + +CV_EXPORTS String tempfile( const char* suffix = 0); +CV_EXPORTS void glob(String pattern, std::vector& result, bool recursive = false); + +/** @brief OpenCV will try to set the number of threads for the next parallel region. + +If threads == 0, OpenCV will disable threading optimizations and run all it's functions +sequentially. Passing threads \< 0 will reset threads number to system default. This function must +be called outside of parallel region. + +OpenCV will try to run its functions with specified threads number, but some behaviour differs from +framework: +- `TBB` - User-defined parallel constructions will run with the same threads number, if + another is not specified. If later on user creates his own scheduler, OpenCV will use it. +- `OpenMP` - No special defined behaviour. +- `Concurrency` - If threads == 1, OpenCV will disable threading optimizations and run its + functions sequentially. +- `GCD` - Supports only values \<= 0. +- `C=` - No special defined behaviour. +@param nthreads Number of threads used by OpenCV. +@sa getNumThreads, getThreadNum + */ +CV_EXPORTS_W void setNumThreads(int nthreads); + +/** @brief Returns the number of threads used by OpenCV for parallel regions. + +Always returns 1 if OpenCV is built without threading support. + +The exact meaning of return value depends on the threading framework used by OpenCV library: +- `TBB` - The number of threads, that OpenCV will try to use for parallel regions. If there is + any tbb::thread_scheduler_init in user code conflicting with OpenCV, then function returns + default number of threads used by TBB library. +- `OpenMP` - An upper bound on the number of threads that could be used to form a new team. +- `Concurrency` - The number of threads, that OpenCV will try to use for parallel regions. +- `GCD` - Unsupported; returns the GCD thread pool limit (512) for compatibility. +- `C=` - The number of threads, that OpenCV will try to use for parallel regions, if before + called setNumThreads with threads \> 0, otherwise returns the number of logical CPUs, + available for the process. +@sa setNumThreads, getThreadNum + */ +CV_EXPORTS_W int getNumThreads(); + +/** @brief Returns the index of the currently executed thread within the current parallel region. Always +returns 0 if called outside of parallel region. + +@deprecated Current implementation doesn't corresponding to this documentation. + +The exact meaning of the return value depends on the threading framework used by OpenCV library: +- `TBB` - Unsupported with current 4.1 TBB release. Maybe will be supported in future. +- `OpenMP` - The thread number, within the current team, of the calling thread. +- `Concurrency` - An ID for the virtual processor that the current context is executing on (0 + for master thread and unique number for others, but not necessary 1,2,3,...). +- `GCD` - System calling thread's ID. Never returns 0 inside parallel region. +- `C=` - The index of the current parallel task. +@sa setNumThreads, getNumThreads + */ +CV_EXPORTS_W int getThreadNum(); + +/** @brief Returns full configuration time cmake output. + +Returned value is raw cmake output including version control system revision, compiler version, +compiler flags, enabled modules and third party libraries, etc. Output format depends on target +architecture. + */ +CV_EXPORTS_W const String& getBuildInformation(); + +/** @brief Returns library version string + +For example "3.4.1-dev". + +@sa getMajorVersion, getMinorVersion, getRevisionVersion +*/ +CV_EXPORTS_W String getVersionString(); + +/** @brief Returns major library version */ +CV_EXPORTS_W int getVersionMajor(); + +/** @brief Returns minor library version */ +CV_EXPORTS_W int getVersionMinor(); + +/** @brief Returns revision field of the library version */ +CV_EXPORTS_W int getVersionRevision(); + +/** @brief Returns the number of ticks. + +The function returns the number of ticks after the certain event (for example, when the machine was +turned on). It can be used to initialize RNG or to measure a function execution time by reading the +tick count before and after the function call. +@sa getTickFrequency, TickMeter + */ +CV_EXPORTS_W int64 getTickCount(); + +/** @brief Returns the number of ticks per second. + +The function returns the number of ticks per second. That is, the following code computes the +execution time in seconds: +@code + double t = (double)getTickCount(); + // do something ... + t = ((double)getTickCount() - t)/getTickFrequency(); +@endcode +@sa getTickCount, TickMeter + */ +CV_EXPORTS_W double getTickFrequency(); + +/** @brief a Class to measure passing time. + +The class computes passing time by counting the number of ticks per second. That is, the following code computes the +execution time in seconds: +@code +TickMeter tm; +tm.start(); +// do something ... +tm.stop(); +std::cout << tm.getTimeSec(); +@endcode + +It is also possible to compute the average time over multiple runs: +@code +TickMeter tm; +for (int i = 0; i < 100; i++) +{ + tm.start(); + // do something ... + tm.stop(); +} +double average_time = tm.getTimeSec() / tm.getCounter(); +std::cout << "Average time in second per iteration is: " << average_time << std::endl; +@endcode +@sa getTickCount, getTickFrequency +*/ + +class CV_EXPORTS_W TickMeter +{ +public: + //! the default constructor + CV_WRAP TickMeter() + { + reset(); + } + + /** + starts counting ticks. + */ + CV_WRAP void start() + { + startTime = cv::getTickCount(); + } + + /** + stops counting ticks. + */ + CV_WRAP void stop() + { + int64 time = cv::getTickCount(); + if (startTime == 0) + return; + ++counter; + sumTime += (time - startTime); + startTime = 0; + } + + /** + returns counted ticks. + */ + CV_WRAP int64 getTimeTicks() const + { + return sumTime; + } + + /** + returns passed time in microseconds. + */ + CV_WRAP double getTimeMicro() const + { + return getTimeMilli()*1e3; + } + + /** + returns passed time in milliseconds. + */ + CV_WRAP double getTimeMilli() const + { + return getTimeSec()*1e3; + } + + /** + returns passed time in seconds. + */ + CV_WRAP double getTimeSec() const + { + return (double)getTimeTicks() / getTickFrequency(); + } + + /** + returns internal counter value. + */ + CV_WRAP int64 getCounter() const + { + return counter; + } + + /** + resets internal values. + */ + CV_WRAP void reset() + { + startTime = 0; + sumTime = 0; + counter = 0; + } + +private: + int64 counter; + int64 sumTime; + int64 startTime; +}; + +/** @brief output operator +@code +TickMeter tm; +tm.start(); +// do something ... +tm.stop(); +std::cout << tm; +@endcode +*/ + +static inline +std::ostream& operator << (std::ostream& out, const TickMeter& tm) +{ + return out << tm.getTimeSec() << "sec"; +} + +/** @brief Returns the number of CPU ticks. + +The function returns the current number of CPU ticks on some architectures (such as x86, x64, +PowerPC). On other platforms the function is equivalent to getTickCount. It can also be used for +very accurate time measurements, as well as for RNG initialization. Note that in case of multi-CPU +systems a thread, from which getCPUTickCount is called, can be suspended and resumed at another CPU +with its own counter. So, theoretically (and practically) the subsequent calls to the function do +not necessary return the monotonously increasing values. Also, since a modern CPU varies the CPU +frequency depending on the load, the number of CPU clocks spent in some code cannot be directly +converted to time units. Therefore, getTickCount is generally a preferable solution for measuring +execution time. + */ +CV_EXPORTS_W int64 getCPUTickCount(); + +/** @brief Returns true if the specified feature is supported by the host hardware. + +The function returns true if the host hardware supports the specified feature. When user calls +setUseOptimized(false), the subsequent calls to checkHardwareSupport() will return false until +setUseOptimized(true) is called. This way user can dynamically switch on and off the optimized code +in OpenCV. +@param feature The feature of interest, one of cv::CpuFeatures + */ +CV_EXPORTS_W bool checkHardwareSupport(int feature); + +/** @brief Returns feature name by ID + +Returns empty string if feature is not defined +*/ +CV_EXPORTS_W String getHardwareFeatureName(int feature); + +/** @brief Returns list of CPU features enabled during compilation. + +Returned value is a string containing space separated list of CPU features with following markers: + +- no markers - baseline features +- prefix `*` - features enabled in dispatcher +- suffix `?` - features enabled but not available in HW + +Example: `SSE SSE2 SSE3 *SSE4.1 *SSE4.2 *FP16 *AVX *AVX2 *AVX512-SKX?` +*/ +CV_EXPORTS std::string getCPUFeaturesLine(); + +/** @brief Returns the number of logical CPUs available for the process. + */ +CV_EXPORTS_W int getNumberOfCPUs(); + + +/** @brief Aligns a pointer to the specified number of bytes. + +The function returns the aligned pointer of the same type as the input pointer: +\f[\texttt{(_Tp*)(((size_t)ptr + n-1) & -n)}\f] +@param ptr Aligned pointer. +@param n Alignment size that must be a power of two. + */ +template static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp)) +{ + CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2 + return (_Tp*)(((size_t)ptr + n-1) & -n); +} + +/** @brief Aligns a buffer size to the specified number of bytes. + +The function returns the minimum number that is greater than or equal to sz and is divisible by n : +\f[\texttt{(sz + n-1) & -n}\f] +@param sz Buffer size to align. +@param n Alignment size that must be a power of two. + */ +static inline size_t alignSize(size_t sz, int n) +{ + CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2 + return (sz + n-1) & -n; +} + +/** @brief Integer division with result round up. + +Use this function instead of `ceil((float)a / b)` expressions. + +@sa alignSize +*/ +static inline int divUp(int a, unsigned int b) +{ + CV_DbgAssert(a >= 0); + return (a + b - 1) / b; +} +/** @overload */ +static inline size_t divUp(size_t a, unsigned int b) +{ + return (a + b - 1) / b; +} + +/** @brief Round first value up to the nearest multiple of second value. + +Use this function instead of `ceil((float)a / b) * b` expressions. + +@sa divUp +*/ +static inline int roundUp(int a, unsigned int b) +{ + CV_DbgAssert(a >= 0); + return a + b - 1 - (a + b -1) % b; +} +/** @overload */ +static inline size_t roundUp(size_t a, unsigned int b) +{ + return a + b - 1 - (a + b - 1) % b; +} + +/** @brief Enables or disables the optimized code. + +The function can be used to dynamically turn on and off optimized dispatched code (code that uses SSE4.2, AVX/AVX2, +and other instructions on the platforms that support it). It sets a global flag that is further +checked by OpenCV functions. Since the flag is not checked in the inner OpenCV loops, it is only +safe to call the function on the very top level in your application where you can be sure that no +other OpenCV function is currently executed. + +By default, the optimized code is enabled unless you disable it in CMake. The current status can be +retrieved using useOptimized. +@param onoff The boolean flag specifying whether the optimized code should be used (onoff=true) +or not (onoff=false). + */ +CV_EXPORTS_W void setUseOptimized(bool onoff); + +/** @brief Returns the status of optimized code usage. + +The function returns true if the optimized code is enabled. Otherwise, it returns false. + */ +CV_EXPORTS_W bool useOptimized(); + +static inline size_t getElemSize(int type) { return (size_t)CV_ELEM_SIZE(type); } + +/////////////////////////////// Parallel Primitives ////////////////////////////////// + +/** @brief Base class for parallel data processors +*/ +class CV_EXPORTS ParallelLoopBody +{ +public: + virtual ~ParallelLoopBody(); + virtual void operator() (const Range& range) const = 0; +}; + +/** @brief Parallel data processor +*/ +CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.); + +class ParallelLoopBodyLambdaWrapper : public ParallelLoopBody +{ +private: + std::function m_functor; +public: + ParallelLoopBodyLambdaWrapper(std::function functor) : + m_functor(functor) + { } + + virtual void operator() (const cv::Range& range) const CV_OVERRIDE + { + m_functor(range); + } +}; + +inline void parallel_for_(const Range& range, std::function functor, double nstripes=-1.) +{ + parallel_for_(range, ParallelLoopBodyLambdaWrapper(functor), nstripes); +} + +/////////////////////////////// forEach method of cv::Mat //////////////////////////// +template inline +void Mat::forEach_impl(const Functor& operation) { + if (false) { + operation(*reinterpret_cast<_Tp*>(0), reinterpret_cast(0)); + // If your compiler fails in this line. + // Please check that your functor signature is + // (_Tp&, const int*) <- multi-dimensional + // or (_Tp&, void*) <- in case you don't need current idx. + } + + CV_Assert(this->total() / this->size[this->dims - 1] <= INT_MAX); + const int LINES = static_cast(this->total() / this->size[this->dims - 1]); + + class PixelOperationWrapper :public ParallelLoopBody + { + public: + PixelOperationWrapper(Mat_<_Tp>* const frame, const Functor& _operation) + : mat(frame), op(_operation) {} + virtual ~PixelOperationWrapper(){} + // ! Overloaded virtual operator + // convert range call to row call. + virtual void operator()(const Range &range) const CV_OVERRIDE + { + const int DIMS = mat->dims; + const int COLS = mat->size[DIMS - 1]; + if (DIMS <= 2) { + for (int row = range.start; row < range.end; ++row) { + this->rowCall2(row, COLS); + } + } else { + std::vector idx(DIMS); /// idx is modified in this->rowCall + idx[DIMS - 2] = range.start - 1; + + for (int line_num = range.start; line_num < range.end; ++line_num) { + idx[DIMS - 2]++; + for (int i = DIMS - 2; i >= 0; --i) { + if (idx[i] >= mat->size[i]) { + idx[i - 1] += idx[i] / mat->size[i]; + idx[i] %= mat->size[i]; + continue; // carry-over; + } + else { + break; + } + } + this->rowCall(&idx[0], COLS, DIMS); + } + } + } + private: + Mat_<_Tp>* const mat; + const Functor op; + // ! Call operator for each elements in this row. + inline void rowCall(int* const idx, const int COLS, const int DIMS) const { + int &col = idx[DIMS - 1]; + col = 0; + _Tp* pixel = &(mat->template at<_Tp>(idx)); + + while (col < COLS) { + op(*pixel, const_cast(idx)); + pixel++; col++; + } + col = 0; + } + // ! Call operator for each elements in this row. 2d mat special version. + inline void rowCall2(const int row, const int COLS) const { + union Index{ + int body[2]; + operator const int*() const { + return reinterpret_cast(this); + } + int& operator[](const int i) { + return body[i]; + } + } idx = {{row, 0}}; + // Special union is needed to avoid + // "error: array subscript is above array bounds [-Werror=array-bounds]" + // when call the functor `op` such that access idx[3]. + + _Tp* pixel = &(mat->template at<_Tp>(idx)); + const _Tp* const pixel_end = pixel + COLS; + while(pixel < pixel_end) { + op(*pixel++, static_cast(idx)); + idx[1]++; + } + } + PixelOperationWrapper& operator=(const PixelOperationWrapper &) { + CV_Assert(false); + // We can not remove this implementation because Visual Studio warning C4822. + return *this; + } + }; + + parallel_for_(cv::Range(0, LINES), PixelOperationWrapper(reinterpret_cast*>(this), operation)); +} + +/////////////////////////// Synchronization Primitives /////////////////////////////// + +#if !defined(_M_CEE) +typedef std::recursive_mutex Mutex; +typedef std::lock_guard AutoLock; +#endif + +// TLS interface +class CV_EXPORTS TLSDataContainer +{ +protected: + TLSDataContainer(); + virtual ~TLSDataContainer(); + + void gatherData(std::vector &data) const; + void* getData() const; + void release(); + +private: + virtual void* createDataInstance() const = 0; + virtual void deleteDataInstance(void* pData) const = 0; + + int key_; + +public: + void cleanup(); //! Release created TLS data container objects. It is similar to release() call, but it keeps TLS container valid. +}; + +// Main TLS data class +template +class TLSData : protected TLSDataContainer +{ +public: + inline TLSData() {} + inline ~TLSData() { release(); } // Release key and delete associated data + inline T* get() const { return (T*)getData(); } // Get data associated with key + inline T& getRef() const { T* ptr = (T*)getData(); CV_Assert(ptr); return *ptr; } // Get data associated with key + + // Get data from all threads + inline void gather(std::vector &data) const + { + std::vector &dataVoid = reinterpret_cast&>(data); + gatherData(dataVoid); + } + + inline void cleanup() { TLSDataContainer::cleanup(); } + +private: + virtual void* createDataInstance() const CV_OVERRIDE {return new T;} // Wrapper to allocate data by template + virtual void deleteDataInstance(void* pData) const CV_OVERRIDE {delete (T*)pData;} // Wrapper to release data by template + + // Disable TLS copy operations + TLSData(TLSData &) {} + TLSData& operator =(const TLSData &) {return *this;} +}; + +/** @brief Designed for command line parsing + +The sample below demonstrates how to use CommandLineParser: +@code + CommandLineParser parser(argc, argv, keys); + parser.about("Application name v1.0.0"); + + if (parser.has("help")) + { + parser.printMessage(); + return 0; + } + + int N = parser.get("N"); + double fps = parser.get("fps"); + String path = parser.get("path"); + + use_time_stamp = parser.has("timestamp"); + + String img1 = parser.get(0); + String img2 = parser.get(1); + + int repeat = parser.get(2); + + if (!parser.check()) + { + parser.printErrors(); + return 0; + } +@endcode + +### Keys syntax + +The keys parameter is a string containing several blocks, each one is enclosed in curly braces and +describes one argument. Each argument contains three parts separated by the `|` symbol: + +-# argument names is a space-separated list of option synonyms (to mark argument as positional, prefix it with the `@` symbol) +-# default value will be used if the argument was not provided (can be empty) +-# help message (can be empty) + +For example: + +@code{.cpp} + const String keys = + "{help h usage ? | | print this message }" + "{@image1 | | image1 for compare }" + "{@image2 || image2 for compare }" + "{@repeat |1 | number }" + "{path |. | path to file }" + "{fps | -1.0 | fps for output video }" + "{N count |100 | count of objects }" + "{ts timestamp | | use time stamp }" + ; +} +@endcode + +Note that there are no default values for `help` and `timestamp` so we can check their presence using the `has()` method. +Arguments with default values are considered to be always present. Use the `get()` method in these cases to check their +actual value instead. + +String keys like `get("@image1")` return the empty string `""` by default - even with an empty default value. +Use the special `` default value to enforce that the returned string must not be empty. (like in `get("@image2")`) + +### Usage + +For the described keys: + +@code{.sh} + # Good call (3 positional parameters: image1, image2 and repeat; N is 200, ts is true) + $ ./app -N=200 1.png 2.jpg 19 -ts + + # Bad call + $ ./app -fps=aaa + ERRORS: + Parameter 'fps': can not convert: [aaa] to [double] +@endcode + */ +class CV_EXPORTS CommandLineParser +{ +public: + + /** @brief Constructor + + Initializes command line parser object + + @param argc number of command line arguments (from main()) + @param argv array of command line arguments (from main()) + @param keys string describing acceptable command line parameters (see class description for syntax) + */ + CommandLineParser(int argc, const char* const argv[], const String& keys); + + /** @brief Copy constructor */ + CommandLineParser(const CommandLineParser& parser); + + /** @brief Assignment operator */ + CommandLineParser& operator = (const CommandLineParser& parser); + + /** @brief Destructor */ + ~CommandLineParser(); + + /** @brief Returns application path + + This method returns the path to the executable from the command line (`argv[0]`). + + For example, if the application has been started with such a command: + @code{.sh} + $ ./bin/my-executable + @endcode + this method will return `./bin`. + */ + String getPathToApplication() const; + + /** @brief Access arguments by name + + Returns argument converted to selected type. If the argument is not known or can not be + converted to selected type, the error flag is set (can be checked with @ref check). + + For example, define: + @code{.cpp} + String keys = "{N count||}"; + @endcode + + Call: + @code{.sh} + $ ./my-app -N=20 + # or + $ ./my-app --count=20 + @endcode + + Access: + @code{.cpp} + int N = parser.get("N"); + @endcode + + @param name name of the argument + @param space_delete remove spaces from the left and right of the string + @tparam T the argument will be converted to this type if possible + + @note You can access positional arguments by their `@`-prefixed name: + @code{.cpp} + parser.get("@image"); + @endcode + */ + template + T get(const String& name, bool space_delete = true) const + { + T val = T(); + getByName(name, space_delete, ParamType::type, (void*)&val); + return val; + } + + /** @brief Access positional arguments by index + + Returns argument converted to selected type. Indexes are counted from zero. + + For example, define: + @code{.cpp} + String keys = "{@arg1||}{@arg2||}" + @endcode + + Call: + @code{.sh} + ./my-app abc qwe + @endcode + + Access arguments: + @code{.cpp} + String val_1 = parser.get(0); // returns "abc", arg1 + String val_2 = parser.get(1); // returns "qwe", arg2 + @endcode + + @param index index of the argument + @param space_delete remove spaces from the left and right of the string + @tparam T the argument will be converted to this type if possible + */ + template + T get(int index, bool space_delete = true) const + { + T val = T(); + getByIndex(index, space_delete, ParamType::type, (void*)&val); + return val; + } + + /** @brief Check if field was provided in the command line + + @param name argument name to check + */ + bool has(const String& name) const; + + /** @brief Check for parsing errors + + Returns false if error occurred while accessing the parameters (bad conversion, missing arguments, + etc.). Call @ref printErrors to print error messages list. + */ + bool check() const; + + /** @brief Set the about message + + The about message will be shown when @ref printMessage is called, right before arguments table. + */ + void about(const String& message); + + /** @brief Print help message + + This method will print standard help message containing the about message and arguments description. + + @sa about + */ + void printMessage() const; + + /** @brief Print list of errors occurred + + @sa check + */ + void printErrors() const; + +protected: + void getByName(const String& name, bool space_delete, Param type, void* dst) const; + void getByIndex(int index, bool space_delete, Param type, void* dst) const; + + struct Impl; + Impl* impl; +}; + +//! @} core_utils + +//! @cond IGNORED + +/////////////////////////////// AutoBuffer implementation //////////////////////////////////////// + +template inline +AutoBuffer<_Tp, fixed_size>::AutoBuffer() +{ + ptr = buf; + sz = fixed_size; +} + +template inline +AutoBuffer<_Tp, fixed_size>::AutoBuffer(size_t _size) +{ + ptr = buf; + sz = fixed_size; + allocate(_size); +} + +template inline +AutoBuffer<_Tp, fixed_size>::AutoBuffer(const AutoBuffer<_Tp, fixed_size>& abuf ) +{ + ptr = buf; + sz = fixed_size; + allocate(abuf.size()); + for( size_t i = 0; i < sz; i++ ) + ptr[i] = abuf.ptr[i]; +} + +template inline AutoBuffer<_Tp, fixed_size>& +AutoBuffer<_Tp, fixed_size>::operator = (const AutoBuffer<_Tp, fixed_size>& abuf) +{ + if( this != &abuf ) + { + deallocate(); + allocate(abuf.size()); + for( size_t i = 0; i < sz; i++ ) + ptr[i] = abuf.ptr[i]; + } + return *this; +} + +template inline +AutoBuffer<_Tp, fixed_size>::~AutoBuffer() +{ deallocate(); } + +template inline void +AutoBuffer<_Tp, fixed_size>::allocate(size_t _size) +{ + if(_size <= sz) + { + sz = _size; + return; + } + deallocate(); + sz = _size; + if(_size > fixed_size) + { + ptr = new _Tp[_size]; + } +} + +template inline void +AutoBuffer<_Tp, fixed_size>::deallocate() +{ + if( ptr != buf ) + { + delete[] ptr; + ptr = buf; + sz = fixed_size; + } +} + +template inline void +AutoBuffer<_Tp, fixed_size>::resize(size_t _size) +{ + if(_size <= sz) + { + sz = _size; + return; + } + size_t i, prevsize = sz, minsize = MIN(prevsize, _size); + _Tp* prevptr = ptr; + + ptr = _size > fixed_size ? new _Tp[_size] : buf; + sz = _size; + + if( ptr != prevptr ) + for( i = 0; i < minsize; i++ ) + ptr[i] = prevptr[i]; + for( i = prevsize; i < _size; i++ ) + ptr[i] = _Tp(); + + if( prevptr != buf ) + delete[] prevptr; +} + +template inline size_t +AutoBuffer<_Tp, fixed_size>::size() const +{ return sz; } + +//! @endcond + + +// Basic Node class for tree building +template +class CV_EXPORTS Node +{ +public: + Node() + { + m_pParent = 0; + } + Node(OBJECT& payload) : m_payload(payload) + { + m_pParent = 0; + } + ~Node() + { + removeChilds(); + if (m_pParent) + { + int idx = m_pParent->findChild(this); + if (idx >= 0) + m_pParent->m_childs.erase(m_pParent->m_childs.begin() + idx); + } + } + + Node* findChild(OBJECT& payload) const + { + for(size_t i = 0; i < this->m_childs.size(); i++) + { + if(this->m_childs[i]->m_payload == payload) + return this->m_childs[i]; + } + return NULL; + } + + int findChild(Node *pNode) const + { + for (size_t i = 0; i < this->m_childs.size(); i++) + { + if(this->m_childs[i] == pNode) + return (int)i; + } + return -1; + } + + void addChild(Node *pNode) + { + if(!pNode) + return; + + CV_Assert(pNode->m_pParent == 0); + pNode->m_pParent = this; + this->m_childs.push_back(pNode); + } + + void removeChilds() + { + for(size_t i = 0; i < m_childs.size(); i++) + { + m_childs[i]->m_pParent = 0; // avoid excessive parent vector trimming + delete m_childs[i]; + } + m_childs.clear(); + } + + int getDepth() + { + int count = 0; + Node *pParent = m_pParent; + while(pParent) count++, pParent = pParent->m_pParent; + return count; + } + +public: + OBJECT m_payload; + Node* m_pParent; + std::vector*> m_childs; +}; + +// Instrumentation external interface +namespace instr +{ + +#if !defined OPENCV_ABI_CHECK + +enum TYPE +{ + TYPE_GENERAL = 0, // OpenCV API function, e.g. exported function + TYPE_MARKER, // Information marker + TYPE_WRAPPER, // Wrapper function for implementation + TYPE_FUN, // Simple function call +}; + +enum IMPL +{ + IMPL_PLAIN = 0, + IMPL_IPP, + IMPL_OPENCL, +}; + +struct NodeDataTls +{ + NodeDataTls() + { + m_ticksTotal = 0; + } + uint64 m_ticksTotal; +}; + +class CV_EXPORTS NodeData +{ +public: + NodeData(const char* funName = 0, const char* fileName = NULL, int lineNum = 0, void* retAddress = NULL, bool alwaysExpand = false, cv::instr::TYPE instrType = TYPE_GENERAL, cv::instr::IMPL implType = IMPL_PLAIN); + NodeData(NodeData &ref); + ~NodeData(); + NodeData& operator=(const NodeData&); + + cv::String m_funName; + cv::instr::TYPE m_instrType; + cv::instr::IMPL m_implType; + const char* m_fileName; + int m_lineNum; + void* m_retAddress; + bool m_alwaysExpand; + bool m_funError; + + volatile int m_counter; + volatile uint64 m_ticksTotal; + TLSData m_tls; + int m_threads; + + // No synchronization + double getTotalMs() const { return ((double)m_ticksTotal / cv::getTickFrequency()) * 1000; } + double getMeanMs() const { return (((double)m_ticksTotal/m_counter) / cv::getTickFrequency()) * 1000; } +}; +bool operator==(const NodeData& lhs, const NodeData& rhs); + +typedef Node InstrNode; + +CV_EXPORTS InstrNode* getTrace(); + +#endif // !defined OPENCV_ABI_CHECK + + +CV_EXPORTS bool useInstrumentation(); +CV_EXPORTS void setUseInstrumentation(bool flag); +CV_EXPORTS void resetTrace(); + +enum FLAGS +{ + FLAGS_NONE = 0, + FLAGS_MAPPING = 0x01, + FLAGS_EXPAND_SAME_NAMES = 0x02, +}; + +CV_EXPORTS void setFlags(FLAGS modeFlags); +static inline void setFlags(int modeFlags) { setFlags((FLAGS)modeFlags); } +CV_EXPORTS FLAGS getFlags(); + +} // namespace instr + + +namespace samples { + +//! @addtogroup core_utils_samples +// This section describes utility functions for OpenCV samples. +// +// @note Implementation of these utilities is not thread-safe. +// +//! @{ + +/** @brief Try to find requested data file + +Search directories: + +1. Directories passed via `addSamplesDataSearchPath()` +2. OPENCV_SAMPLES_DATA_PATH_HINT environment variable +3. OPENCV_SAMPLES_DATA_PATH environment variable + If parameter value is not empty and nothing is found then stop searching. +4. Detects build/install path based on: + a. current working directory (CWD) + b. and/or binary module location (opencv_core/opencv_world, doesn't work with static linkage) +5. Scan `/{,data,samples/data}` directories if build directory is detected or the current directory is in source tree. +6. Scan `/share/OpenCV` directory if install directory is detected. + +@see cv::utils::findDataFile + +@param relative_path Relative path to data file +@param required Specify "file not found" handling. + If true, function prints information message and raises cv::Exception. + If false, function returns empty result +@param silentMode Disables messages +@return Returns path (absolute or relative to the current directory) or empty string if file is not found +*/ +CV_EXPORTS_W cv::String findFile(const cv::String& relative_path, bool required = true, bool silentMode = false); + +CV_EXPORTS_W cv::String findFileOrKeep(const cv::String& relative_path, bool silentMode = false); + +inline cv::String findFileOrKeep(const cv::String& relative_path, bool silentMode) +{ + cv::String res = findFile(relative_path, false, silentMode); + if (res.empty()) + return relative_path; + return res; +} + +/** @brief Override search data path by adding new search location + +Use this only to override default behavior +Passed paths are used in LIFO order. + +@param path Path to used samples data +*/ +CV_EXPORTS_W void addSamplesDataSearchPath(const cv::String& path); + +/** @brief Append samples search data sub directory + +General usage is to add OpenCV modules name (`/modules//samples/data` -> `/samples/data` + `modules//samples/data`). +Passed subdirectories are used in LIFO order. + +@param subdir samples data sub directory +*/ +CV_EXPORTS_W void addSamplesDataSearchSubDirectory(const cv::String& subdir); + +//! @} +} // namespace samples + +namespace utils { + +CV_EXPORTS int getThreadID(); + +} // namespace + +} //namespace cv + +#endif //OPENCV_CORE_UTILITY_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.hpp new file mode 100755 index 0000000..79e9338 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.hpp @@ -0,0 +1,29 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_ALLOCATOR_STATS_HPP +#define OPENCV_CORE_ALLOCATOR_STATS_HPP + +#include "../cvdef.h" + +namespace cv { namespace utils { + +class AllocatorStatisticsInterface +{ +protected: + AllocatorStatisticsInterface() {} + virtual ~AllocatorStatisticsInterface() {} +public: + virtual uint64_t getCurrentUsage() const = 0; + virtual uint64_t getTotalUsage() const = 0; + virtual uint64_t getNumberOfAllocations() const = 0; + virtual uint64_t getPeakUsage() const = 0; + + /** set peak usage = current usage */ + virtual void resetPeakUsage() = 0; +}; + +}} // namespace + +#endif // OPENCV_CORE_ALLOCATOR_STATS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.impl.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.impl.hpp new file mode 100755 index 0000000..b77493d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utils/allocator_stats.impl.hpp @@ -0,0 +1,117 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_ALLOCATOR_STATS_IMPL_HPP +#define OPENCV_CORE_ALLOCATOR_STATS_IMPL_HPP + +#include "./allocator_stats.hpp" + +#ifdef CV_CXX11 +#include +#endif + +namespace cv { namespace utils { + +#ifdef CV__ALLOCATOR_STATS_LOG +namespace { +#endif + +class AllocatorStatistics : public AllocatorStatisticsInterface +{ +protected: +#ifdef CV_CXX11 + std::atomic curr, total, total_allocs, peak; +#else + volatile long long curr, total, total_allocs, peak; // overflow is possible, CV_XADD operates with 'int' only +#endif + +public: + AllocatorStatistics() +#ifndef CV_CXX11 + : curr(0), total(0), total_allocs(0), peak(0) +#endif + {} + ~AllocatorStatistics() CV_OVERRIDE {} + + // AllocatorStatisticsInterface + +#ifdef CV_CXX11 + uint64_t getCurrentUsage() const CV_OVERRIDE { return (uint64_t)curr.load(); } + uint64_t getTotalUsage() const CV_OVERRIDE { return (uint64_t)total.load(); } + uint64_t getNumberOfAllocations() const CV_OVERRIDE { return (uint64_t)total_allocs.load(); } + uint64_t getPeakUsage() const CV_OVERRIDE { return (uint64_t)peak.load(); } + + /** set peak usage = current usage */ + void resetPeakUsage() CV_OVERRIDE { peak.store(curr.load()); } + + // Controller interface + void onAllocate(size_t sz) + { +#ifdef CV__ALLOCATOR_STATS_LOG + CV__ALLOCATOR_STATS_LOG(cv::format("allocate: %lld (curr=%lld)", (long long int)sz, (long long int)curr.load())); +#endif + + long long new_curr = curr.fetch_add((long long)sz) + (long long)sz; + + // peak = std::max((uint64_t)peak, new_curr); + auto prev_peak = peak.load(); + while (prev_peak < new_curr) + { + if (peak.compare_exchange_weak(prev_peak, new_curr)) + break; + } + // end of peak = max(...) + + total += (long long)sz; + total_allocs++; + } + void onFree(size_t sz) + { +#ifdef CV__ALLOCATOR_STATS_LOG + CV__ALLOCATOR_STATS_LOG(cv::format("free: %lld (curr=%lld)", (long long int)sz, (long long int)curr.load())); +#endif + curr -= (long long)sz; + } + +#else + uint64_t getCurrentUsage() const CV_OVERRIDE { return (uint64_t)curr; } + uint64_t getTotalUsage() const CV_OVERRIDE { return (uint64_t)total; } + uint64_t getNumberOfAllocations() const CV_OVERRIDE { return (uint64_t)total_allocs; } + uint64_t getPeakUsage() const CV_OVERRIDE { return (uint64_t)peak; } + + void resetPeakUsage() CV_OVERRIDE { peak = curr; } + + // Controller interface + void onAllocate(size_t sz) + { +#ifdef CV__ALLOCATOR_STATS_LOG + CV__ALLOCATOR_STATS_LOG(cv::format("allocate: %lld (curr=%lld)", (long long int)sz, (long long int)curr)); +#endif + + uint64_t new_curr = (uint64_t)CV_XADD(&curr, (uint64_t)sz) + sz; + + peak = std::max((uint64_t)peak, new_curr); // non-thread safe + + //CV_XADD(&total, (uint64_t)sz); // overflow with int, non-reliable... + total += sz; + + CV_XADD(&total_allocs, (uint64_t)1); + } + void onFree(size_t sz) + { +#ifdef CV__ALLOCATOR_STATS_LOG + CV__ALLOCATOR_STATS_LOG(cv::format("free: %lld (curr=%lld)", (long long int)sz, (long long int)curr)); +#endif + CV_XADD(&curr, (uint64_t)-sz); + } +#endif +}; + +#ifdef CV__ALLOCATOR_STATS_LOG +} // namespace +#endif + +}} // namespace + +#endif // OPENCV_CORE_ALLOCATOR_STATS_IMPL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utils/filesystem.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utils/filesystem.hpp new file mode 100755 index 0000000..a98d220 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utils/filesystem.hpp @@ -0,0 +1,82 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_UTILS_FILESYSTEM_HPP +#define OPENCV_UTILS_FILESYSTEM_HPP + +namespace cv { namespace utils { namespace fs { + + +CV_EXPORTS bool exists(const cv::String& path); +CV_EXPORTS bool isDirectory(const cv::String& path); + +CV_EXPORTS void remove_all(const cv::String& path); + + +CV_EXPORTS cv::String getcwd(); + +/** @brief Converts path p to a canonical absolute path + * Symlinks are processed if there is support for them on running platform. + * + * @param path input path. Target file/directory should exist. + */ +CV_EXPORTS cv::String canonical(const cv::String& path); + +/** Join path components */ +CV_EXPORTS cv::String join(const cv::String& base, const cv::String& path); + +/** Get parent directory */ +CV_EXPORTS cv::String getParent(const cv::String &path); +CV_EXPORTS std::wstring getParent(const std::wstring& path); + +/** + * Generate a list of all files that match the globbing pattern. + * + * Result entries are prefixed by base directory path. + * + * @param directory base directory + * @param pattern filter pattern (based on '*'/'?' symbols). Use empty string to disable filtering and return all results + * @param[out] result result of globing. + * @param recursive scan nested directories too + * @param includeDirectories include directories into results list + */ +CV_EXPORTS void glob(const cv::String& directory, const cv::String& pattern, + CV_OUT std::vector& result, + bool recursive = false, bool includeDirectories = false); + +/** + * Generate a list of all files that match the globbing pattern. + * + * @param directory base directory + * @param pattern filter pattern (based on '*'/'?' symbols). Use empty string to disable filtering and return all results + * @param[out] result globbing result with relative paths from base directory + * @param recursive scan nested directories too + * @param includeDirectories include directories into results list + */ +CV_EXPORTS void glob_relative(const cv::String& directory, const cv::String& pattern, + CV_OUT std::vector& result, + bool recursive = false, bool includeDirectories = false); + + +CV_EXPORTS bool createDirectory(const cv::String& path); +CV_EXPORTS bool createDirectories(const cv::String& path); + +#ifdef __OPENCV_BUILD +// TODO +//CV_EXPORTS cv::String getTempDirectory(); + +/** + * @brief Returns directory to store OpenCV cache files + * Create sub-directory in common OpenCV cache directory if it doesn't exist. + * @param sub_directory_name name of sub-directory. NULL or "" value asks to return root cache directory. + * @param configuration_name optional name of configuration parameter name which overrides default behavior. + * @return Path to cache directory. Returns empty string if cache directories support is not available. Returns "disabled" if cache disabled by user. + */ +CV_EXPORTS cv::String getCacheDirectory(const char* sub_directory_name, const char* configuration_name = NULL); + +#endif + +}}} // namespace + +#endif // OPENCV_UTILS_FILESYSTEM_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.defines.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.defines.hpp new file mode 100755 index 0000000..7d73f02 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.defines.hpp @@ -0,0 +1,42 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_LOGGER_DEFINES_HPP +#define OPENCV_LOGGER_DEFINES_HPP + +//! @addtogroup core_logging +//! @{ + +// Supported logging levels and their semantic +#define CV_LOG_LEVEL_SILENT 0 //!< for using in setLogLevel() call +#define CV_LOG_LEVEL_FATAL 1 //!< Fatal (critical) error (unrecoverable internal error) +#define CV_LOG_LEVEL_ERROR 2 //!< Error message +#define CV_LOG_LEVEL_WARN 3 //!< Warning message +#define CV_LOG_LEVEL_INFO 4 //!< Info message +#define CV_LOG_LEVEL_DEBUG 5 //!< Debug message. Disabled in the "Release" build. +#define CV_LOG_LEVEL_VERBOSE 6 //!< Verbose (trace) messages. Requires verbosity level. Disabled in the "Release" build. + +namespace cv { +namespace utils { +namespace logging { + +//! Supported logging levels and their semantic +enum LogLevel { + LOG_LEVEL_SILENT = 0, //!< for using in setLogVevel() call + LOG_LEVEL_FATAL = 1, //!< Fatal (critical) error (unrecoverable internal error) + LOG_LEVEL_ERROR = 2, //!< Error message + LOG_LEVEL_WARNING = 3, //!< Warning message + LOG_LEVEL_INFO = 4, //!< Info message + LOG_LEVEL_DEBUG = 5, //!< Debug message. Disabled in the "Release" build. + LOG_LEVEL_VERBOSE = 6, //!< Verbose (trace) messages. Requires verbosity level. Disabled in the "Release" build. +#ifndef CV_DOXYGEN + ENUM_LOG_LEVEL_FORCE_INT = INT_MAX +#endif +}; + +}}} // namespace + +//! @} + +#endif // OPENCV_LOGGER_DEFINES_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.hpp new file mode 100755 index 0000000..b00a552 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utils/logger.hpp @@ -0,0 +1,155 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_LOGGER_HPP +#define OPENCV_LOGGER_HPP + +#include +#include +#include // INT_MAX + +#include "logger.defines.hpp" +#include "logtag.hpp" + +//! @addtogroup core_logging +// This section describes OpenCV logging utilities. +// +//! @{ + +namespace cv { +namespace utils { +namespace logging { + +/** Set global logging level +@return previous logging level +*/ +CV_EXPORTS LogLevel setLogLevel(LogLevel logLevel); +/** Get global logging level */ +CV_EXPORTS LogLevel getLogLevel(); + +CV_EXPORTS void registerLogTag(cv::utils::logging::LogTag* plogtag); + +CV_EXPORTS void setLogTagLevel(const char* tag, cv::utils::logging::LogLevel level); + +CV_EXPORTS cv::utils::logging::LogLevel getLogTagLevel(const char* tag); + +namespace internal { + +/** Get global log tag */ +CV_EXPORTS cv::utils::logging::LogTag* getGlobalLogTag(); + +/** Write log message */ +CV_EXPORTS void writeLogMessage(LogLevel logLevel, const char* message); + +/** Write log message */ +CV_EXPORTS void writeLogMessageEx(LogLevel logLevel, const char* tag, const char* file, int line, const char* func, const char* message); + +} // namespace + +struct LogTagAuto + : public LogTag +{ + inline LogTagAuto(const char* _name, LogLevel _level) + : LogTag(_name, _level) + { + registerLogTag(this); + } +}; + +/** + * \def CV_LOG_STRIP_LEVEL + * + * Define CV_LOG_STRIP_LEVEL=CV_LOG_LEVEL_[DEBUG|INFO|WARN|ERROR|FATAL|SILENT] to compile out anything at that and before that logging level + */ +#ifndef CV_LOG_STRIP_LEVEL +# if defined NDEBUG +# define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG +# else +# define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE +# endif +#endif + +#define CV_LOGTAG_PTR_CAST(expr) static_cast(expr) + +// CV_LOGTAG_EXPAND_NAME is intended to be re-defined (undef and then define again) +// to allows logging users to use a shorter name argument when calling +// CV_LOG_WITH_TAG or its related macros such as CV_LOG_INFO. +// +// This macro is intended to modify the tag argument as a string (token), via +// preprocessor token pasting or metaprogramming techniques. A typical usage +// is to apply a prefix, such as +// ...... #define CV_LOGTAG_EXPAND_NAME(tag) cv_logtag_##tag +// +// It is permitted to re-define to a hard-coded expression, ignoring the tag. +// This would work identically like the CV_LOGTAG_FALLBACK macro. +// +// Important: When the logging macro is called with tag being NULL, a user-defined +// CV_LOGTAG_EXPAND_NAME may expand it into cv_logtag_0, cv_logtag_NULL, or +// cv_logtag_nullptr. Use with care. Also be mindful of C++ symbol redefinitions. +// +// If there is significant amount of logging code with tag being NULL, it is +// recommended to use (re-define) CV_LOGTAG_FALLBACK to inject locally a default +// tag at the beginning of a compilation unit, to minimize lines of code changes. +// +#define CV_LOGTAG_EXPAND_NAME(tag) tag + +// CV_LOGTAG_FALLBACK is intended to be re-defined (undef and then define again) +// by any other compilation units to provide a log tag when the logging statement +// does not specify one. The macro needs to expand into a C++ expression that can +// be static_cast into (cv::utils::logging::LogTag*). Null (nullptr) is permitted. +#define CV_LOGTAG_FALLBACK nullptr + +// CV_LOGTAG_GLOBAL is the tag used when a log tag is not specified in the logging +// statement nor the compilation unit. The macro needs to expand into a C++ +// expression that can be static_cast into (cv::utils::logging::LogTag*). Must be +// non-null. Do not re-define. +#define CV_LOGTAG_GLOBAL cv::utils::logging::internal::getGlobalLogTag() + +#define CV_LOG_WITH_TAG(tag, msgLevel, ...) \ + for(;;) { \ + const auto cv_temp_msglevel = (cv::utils::logging::LogLevel)(msgLevel); \ + if (cv_temp_msglevel >= (CV_LOG_STRIP_LEVEL)) break; \ + auto cv_temp_logtagptr = CV_LOGTAG_PTR_CAST(CV_LOGTAG_EXPAND_NAME(tag)); \ + if (!cv_temp_logtagptr) cv_temp_logtagptr = CV_LOGTAG_PTR_CAST(CV_LOGTAG_FALLBACK); \ + if (!cv_temp_logtagptr) cv_temp_logtagptr = CV_LOGTAG_PTR_CAST(CV_LOGTAG_GLOBAL); \ + if (cv_temp_logtagptr && (cv_temp_msglevel > cv_temp_logtagptr->level)) break; \ + std::stringstream cv_temp_logstream; \ + cv_temp_logstream << __VA_ARGS__; \ + cv::utils::logging::internal::writeLogMessageEx( \ + cv_temp_msglevel, \ + (cv_temp_logtagptr ? cv_temp_logtagptr->name : nullptr), \ + __FILE__, \ + __LINE__, \ + CV_Func, \ + cv_temp_logstream.str().c_str()); \ + break; \ + } + +#define CV_LOG_FATAL(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_FATAL, __VA_ARGS__) +#define CV_LOG_ERROR(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_ERROR, __VA_ARGS__) +#define CV_LOG_WARNING(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_WARNING, __VA_ARGS__) +#define CV_LOG_INFO(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_INFO, __VA_ARGS__) +#define CV_LOG_DEBUG(tag, ...) CV_LOG_WITH_TAG(tag, cv::utils::logging::LOG_LEVEL_DEBUG, __VA_ARGS__) +#define CV_LOG_VERBOSE(tag, v, ...) CV_LOG_WITH_TAG(tag, (cv::utils::logging::LOG_LEVEL_VERBOSE + (int)(v)), __VA_ARGS__) + +#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_INFO +# undef CV_LOG_INFO +# define CV_LOG_INFO(tag, ...) +#endif + +#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_DEBUG +# undef CV_LOG_DEBUG +# define CV_LOG_DEBUG(tag, ...) +#endif + +#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_VERBOSE +# undef CV_LOG_VERBOSE +# define CV_LOG_VERBOSE(tag, v, ...) +#endif + +}}} // namespace + +//! @} + +#endif // OPENCV_LOGGER_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utils/logtag.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utils/logtag.hpp new file mode 100755 index 0000000..4089720 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utils/logtag.hpp @@ -0,0 +1,28 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_CORE_LOGTAG_HPP +#define OPENCV_CORE_LOGTAG_HPP + +#include "opencv2/core/cvstd.hpp" +#include "logger.defines.hpp" + +namespace cv { +namespace utils { +namespace logging { + +struct LogTag +{ + const char* name; + LogLevel level; + + inline LogTag(const char* _name, LogLevel _level) + : name(_name) + , level(_level) + {} +}; + +}}} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/utils/trace.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/utils/trace.hpp new file mode 100755 index 0000000..858e973 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/utils/trace.hpp @@ -0,0 +1,254 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_TRACE_HPP +#define OPENCV_TRACE_HPP + +#include + +//! @addtogroup core_logging +// This section describes OpenCV tracing utilities. +// +//! @{ + +namespace cv { +namespace utils { +namespace trace { + +//! Macro to trace function +#define CV_TRACE_FUNCTION() + +#define CV_TRACE_FUNCTION_SKIP_NESTED() + +//! Trace code scope. +//! @note Dynamic names are not supported in this macro (on stack or heap). Use string literals here only, like "initialize". +#define CV_TRACE_REGION(name_as_static_string_literal) +//! mark completed of the current opened region and create new one +//! @note Dynamic names are not supported in this macro (on stack or heap). Use string literals here only, like "step1". +#define CV_TRACE_REGION_NEXT(name_as_static_string_literal) + +//! Macro to trace argument value +#define CV_TRACE_ARG(arg_id) + +//! Macro to trace argument value (expanded version) +#define CV_TRACE_ARG_VALUE(arg_id, arg_name, value) + +//! @cond IGNORED +#define CV_TRACE_NS cv::utils::trace + +#if !defined(OPENCV_DISABLE_TRACE) && defined(__EMSCRIPTEN__) +#define OPENCV_DISABLE_TRACE 1 +#endif + +namespace details { + +#ifndef __OPENCV_TRACE +# if defined __OPENCV_BUILD && !defined __OPENCV_TESTS && !defined __OPENCV_APPS +# define __OPENCV_TRACE 1 +# else +# define __OPENCV_TRACE 0 +# endif +#endif + +#ifndef CV_TRACE_FILENAME +# define CV_TRACE_FILENAME __FILE__ +#endif + +#ifndef CV__TRACE_FUNCTION +# if defined _MSC_VER +# define CV__TRACE_FUNCTION __FUNCSIG__ +# elif defined __GNUC__ +# define CV__TRACE_FUNCTION __PRETTY_FUNCTION__ +# else +# define CV__TRACE_FUNCTION "" +# endif +#endif + +//! Thread-local instance (usually allocated on stack) +class CV_EXPORTS Region +{ +public: + struct LocationExtraData; + struct LocationStaticStorage + { + LocationExtraData** ppExtra; //< implementation specific data + const char* name; //< region name (function name or other custom name) + const char* filename; //< source code filename + int line; //< source code line + int flags; //< flags (implementation code path: Plain, IPP, OpenCL) + }; + + Region(const LocationStaticStorage& location); + inline ~Region() + { + if (implFlags != 0) + destroy(); + CV_DbgAssert(implFlags == 0); + CV_DbgAssert(pImpl == NULL); + } + + class Impl; + Impl* pImpl; // NULL if current region is not active + int implFlags; // see RegionFlag, 0 if region is ignored + + bool isActive() const { return pImpl != NULL; } + + void destroy(); +private: + Region(const Region&); // disabled + Region& operator= (const Region&); // disabled +}; + +//! Specify region flags +enum RegionLocationFlag { + REGION_FLAG_FUNCTION = (1 << 0), //< region is function (=1) / nested named region (=0) + REGION_FLAG_APP_CODE = (1 << 1), //< region is Application code (=1) / OpenCV library code (=0) + REGION_FLAG_SKIP_NESTED = (1 << 2), //< avoid processing of nested regions + + REGION_FLAG_IMPL_IPP = (1 << 16), //< region is part of IPP code path + REGION_FLAG_IMPL_OPENCL = (2 << 16), //< region is part of OpenCL code path + REGION_FLAG_IMPL_OPENVX = (3 << 16), //< region is part of OpenVX code path + + REGION_FLAG_IMPL_MASK = (15 << 16), + + REGION_FLAG_REGION_FORCE = (1 << 30), + REGION_FLAG_REGION_NEXT = (1 << 31), //< close previous region (see #CV_TRACE_REGION_NEXT macro) + + ENUM_REGION_FLAG_FORCE_INT = INT_MAX +}; + +struct CV_EXPORTS TraceArg { +public: + struct ExtraData; + ExtraData** ppExtra; + const char* name; + int flags; +}; +/** @brief Add meta information to current region (function) + * See CV_TRACE_ARG macro + * @param arg argument information structure (global static cache) + * @param value argument value (can by dynamic string literal in case of string, static allocation is not required) + */ +CV_EXPORTS void traceArg(const TraceArg& arg, const char* value); +//! @overload +CV_EXPORTS void traceArg(const TraceArg& arg, int value); +//! @overload +CV_EXPORTS void traceArg(const TraceArg& arg, int64 value); +//! @overload +CV_EXPORTS void traceArg(const TraceArg& arg, double value); + +#define CV__TRACE_LOCATION_VARNAME(loc_id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_trace_location_, loc_id), __LINE__) +#define CV__TRACE_LOCATION_EXTRA_VARNAME(loc_id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_trace_location_extra_, loc_id) , __LINE__) + +#define CV__TRACE_DEFINE_LOCATION_(loc_id, name, flags) \ + static CV_TRACE_NS::details::Region::LocationExtraData* CV__TRACE_LOCATION_EXTRA_VARNAME(loc_id) = 0; \ + static const CV_TRACE_NS::details::Region::LocationStaticStorage \ + CV__TRACE_LOCATION_VARNAME(loc_id) = { &(CV__TRACE_LOCATION_EXTRA_VARNAME(loc_id)), name, CV_TRACE_FILENAME, __LINE__, flags}; + +#define CV__TRACE_DEFINE_LOCATION_FN(name, flags) CV__TRACE_DEFINE_LOCATION_(fn, name, ((flags) | CV_TRACE_NS::details::REGION_FLAG_FUNCTION)) + + +#define CV__TRACE_OPENCV_FUNCTION() \ + CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, 0); \ + const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn)); + +#define CV__TRACE_OPENCV_FUNCTION_NAME(name) \ + CV__TRACE_DEFINE_LOCATION_FN(name, 0); \ + const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn)); + +#define CV__TRACE_APP_FUNCTION() \ + CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, CV_TRACE_NS::details::REGION_FLAG_APP_CODE); \ + const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn)); + +#define CV__TRACE_APP_FUNCTION_NAME(name) \ + CV__TRACE_DEFINE_LOCATION_FN(name, CV_TRACE_NS::details::REGION_FLAG_APP_CODE); \ + const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn)); + + +#define CV__TRACE_OPENCV_FUNCTION_SKIP_NESTED() \ + CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, CV_TRACE_NS::details::REGION_FLAG_SKIP_NESTED); \ + const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn)); + +#define CV__TRACE_OPENCV_FUNCTION_NAME_SKIP_NESTED(name) \ + CV__TRACE_DEFINE_LOCATION_FN(name, CV_TRACE_NS::details::REGION_FLAG_SKIP_NESTED); \ + const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn)); + +#define CV__TRACE_APP_FUNCTION_SKIP_NESTED() \ + CV__TRACE_DEFINE_LOCATION_FN(CV__TRACE_FUNCTION, CV_TRACE_NS::details::REGION_FLAG_SKIP_NESTED | CV_TRACE_NS::details::REGION_FLAG_APP_CODE); \ + const CV_TRACE_NS::details::Region __region_fn(CV__TRACE_LOCATION_VARNAME(fn)); + + +#define CV__TRACE_REGION_(name_as_static_string_literal, flags) \ + CV__TRACE_DEFINE_LOCATION_(region, name_as_static_string_literal, flags); \ + CV_TRACE_NS::details::Region CVAUX_CONCAT(__region_, __LINE__)(CV__TRACE_LOCATION_VARNAME(region)); + +#define CV__TRACE_REGION(name_as_static_string_literal) CV__TRACE_REGION_(name_as_static_string_literal, 0) +#define CV__TRACE_REGION_NEXT(name_as_static_string_literal) CV__TRACE_REGION_(name_as_static_string_literal, CV_TRACE_NS::details::REGION_FLAG_REGION_NEXT) + +#define CV__TRACE_ARG_VARNAME(arg_id) CVAUX_CONCAT(__cv_trace_arg_ ## arg_id, __LINE__) +#define CV__TRACE_ARG_EXTRA_VARNAME(arg_id) CVAUX_CONCAT(__cv_trace_arg_extra_ ## arg_id, __LINE__) + +#define CV__TRACE_DEFINE_ARG_(arg_id, name, flags) \ + static CV_TRACE_NS::details::TraceArg::ExtraData* CV__TRACE_ARG_EXTRA_VARNAME(arg_id) = 0; \ + static const CV_TRACE_NS::details::TraceArg \ + CV__TRACE_ARG_VARNAME(arg_id) = { &(CV__TRACE_ARG_EXTRA_VARNAME(arg_id)), name, flags }; + +#define CV__TRACE_ARG_VALUE(arg_id, arg_name, value) \ + CV__TRACE_DEFINE_ARG_(arg_id, arg_name, 0); \ + CV_TRACE_NS::details::traceArg((CV__TRACE_ARG_VARNAME(arg_id)), value); + +#define CV__TRACE_ARG(arg_id) CV_TRACE_ARG_VALUE(arg_id, #arg_id, (arg_id)) + +} // namespace + +#ifndef OPENCV_DISABLE_TRACE +#undef CV_TRACE_FUNCTION +#undef CV_TRACE_FUNCTION_SKIP_NESTED +#if __OPENCV_TRACE +#define CV_TRACE_FUNCTION CV__TRACE_OPENCV_FUNCTION +#define CV_TRACE_FUNCTION_SKIP_NESTED CV__TRACE_OPENCV_FUNCTION_SKIP_NESTED +#else +#define CV_TRACE_FUNCTION CV__TRACE_APP_FUNCTION +#define CV_TRACE_FUNCTION_SKIP_NESTED CV__TRACE_APP_FUNCTION_SKIP_NESTED +#endif + +#undef CV_TRACE_REGION +#define CV_TRACE_REGION CV__TRACE_REGION + +#undef CV_TRACE_REGION_NEXT +#define CV_TRACE_REGION_NEXT CV__TRACE_REGION_NEXT + +#undef CV_TRACE_ARG_VALUE +#define CV_TRACE_ARG_VALUE(arg_id, arg_name, value) \ + if (__region_fn.isActive()) \ + { \ + CV__TRACE_ARG_VALUE(arg_id, arg_name, value); \ + } + +#undef CV_TRACE_ARG +#define CV_TRACE_ARG CV__TRACE_ARG + +#endif // OPENCV_DISABLE_TRACE + +#ifdef OPENCV_TRACE_VERBOSE +#define CV_TRACE_FUNCTION_VERBOSE CV_TRACE_FUNCTION +#define CV_TRACE_REGION_VERBOSE CV_TRACE_REGION +#define CV_TRACE_REGION_NEXT_VERBOSE CV_TRACE_REGION_NEXT +#define CV_TRACE_ARG_VALUE_VERBOSE CV_TRACE_ARG_VALUE +#define CV_TRACE_ARG_VERBOSE CV_TRACE_ARG +#else +#define CV_TRACE_FUNCTION_VERBOSE(...) +#define CV_TRACE_REGION_VERBOSE(...) +#define CV_TRACE_REGION_NEXT_VERBOSE(...) +#define CV_TRACE_ARG_VALUE_VERBOSE(...) +#define CV_TRACE_ARG_VERBOSE(...) +#endif + +//! @endcond + +}}} // namespace + +//! @} + +#endif // OPENCV_TRACE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/va_intel.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/va_intel.hpp new file mode 100755 index 0000000..f665470 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/va_intel.hpp @@ -0,0 +1,78 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +// Copyright (C) 2015, Itseez, Inc., all rights reserved. +// Third party copyrights are property of their respective owners. + +#ifndef OPENCV_CORE_VA_INTEL_HPP +#define OPENCV_CORE_VA_INTEL_HPP + +#ifndef __cplusplus +# error va_intel.hpp header must be compiled as C++ +#endif + +#include "opencv2/core.hpp" +#include "ocl.hpp" + +#if defined(HAVE_VA) +# include "va/va.h" +#else // HAVE_VA +# if !defined(_VA_H_) + typedef void* VADisplay; + typedef unsigned int VASurfaceID; +# endif // !_VA_H_ +#endif // HAVE_VA + +namespace cv { namespace va_intel { + +/** @addtogroup core_va_intel +This section describes Intel VA-API/OpenCL (CL-VA) interoperability. + +To enable CL-VA interoperability support, configure OpenCV using CMake with WITH_VA_INTEL=ON . Currently VA-API is +supported on Linux only. You should also install Intel Media Server Studio (MSS) to use this feature. You may +have to specify the path(s) to MSS components for cmake in environment variables: + +- VA_INTEL_IOCL_ROOT for Intel OpenCL (default is "/opt/intel/opencl"). + +To use CL-VA interoperability you should first create VADisplay (libva), and then call initializeContextFromVA() +function to create OpenCL context and set up interoperability. +*/ +//! @{ + +/////////////////// CL-VA Interoperability Functions /////////////////// + +namespace ocl { +using namespace cv::ocl; + +// TODO static functions in the Context class +/** @brief Creates OpenCL context from VA. +@param display - VADisplay for which CL interop should be established. +@param tryInterop - try to set up for interoperability, if true; set up for use slow copy if false. +@return Returns reference to OpenCL Context + */ +CV_EXPORTS Context& initializeContextFromVA(VADisplay display, bool tryInterop = true); + +} // namespace cv::va_intel::ocl + +/** @brief Converts InputArray to VASurfaceID object. +@param display - VADisplay object. +@param src - source InputArray. +@param surface - destination VASurfaceID object. +@param size - size of image represented by VASurfaceID object. + */ +CV_EXPORTS void convertToVASurface(VADisplay display, InputArray src, VASurfaceID surface, Size size); + +/** @brief Converts VASurfaceID object to OutputArray. +@param display - VADisplay object. +@param surface - source VASurfaceID object. +@param size - size of image represented by VASurfaceID object. +@param dst - destination OutputArray. + */ +CV_EXPORTS void convertFromVASurface(VADisplay display, VASurfaceID surface, Size size, OutputArray dst); + +//! @} + +}} // namespace cv::va_intel + +#endif /* OPENCV_CORE_VA_INTEL_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/version.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/version.hpp new file mode 100755 index 0000000..82a6867 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/version.hpp @@ -0,0 +1,26 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_VERSION_HPP +#define OPENCV_VERSION_HPP + +#define CV_VERSION_MAJOR 4 +#define CV_VERSION_MINOR 1 +#define CV_VERSION_REVISION 1 +#define CV_VERSION_STATUS "-pre" + +#define CVAUX_STR_EXP(__A) #__A +#define CVAUX_STR(__A) CVAUX_STR_EXP(__A) + +#define CVAUX_STRW_EXP(__A) L ## #__A +#define CVAUX_STRW(__A) CVAUX_STRW_EXP(__A) + +#define CV_VERSION CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) "." CVAUX_STR(CV_VERSION_REVISION) CV_VERSION_STATUS + +/* old style version constants*/ +#define CV_MAJOR_VERSION CV_VERSION_MAJOR +#define CV_MINOR_VERSION CV_VERSION_MINOR +#define CV_SUBMINOR_VERSION CV_VERSION_REVISION + +#endif // OPENCV_VERSION_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/core/vsx_utils.hpp b/Prj-Win/3rd/opencv/include/opencv2/core/vsx_utils.hpp new file mode 100755 index 0000000..6e2baea --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/core/vsx_utils.hpp @@ -0,0 +1,1013 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#ifndef OPENCV_HAL_VSX_UTILS_HPP +#define OPENCV_HAL_VSX_UTILS_HPP + +#include "opencv2/core/cvdef.h" + +#ifndef SKIP_INCLUDES +# include +#endif + +//! @addtogroup core_utils_vsx +//! @{ +#if CV_VSX + +#define __VSX_S16__(c, v) (c){v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v} +#define __VSX_S8__(c, v) (c){v, v, v, v, v, v, v, v} +#define __VSX_S4__(c, v) (c){v, v, v, v} +#define __VSX_S2__(c, v) (c){v, v} + +typedef __vector unsigned char vec_uchar16; +#define vec_uchar16_set(...) (vec_uchar16){__VA_ARGS__} +#define vec_uchar16_sp(c) (__VSX_S16__(vec_uchar16, (unsigned char)c)) +#define vec_uchar16_c(v) ((vec_uchar16)(v)) +#define vec_uchar16_z vec_uchar16_sp(0) + +typedef __vector signed char vec_char16; +#define vec_char16_set(...) (vec_char16){__VA_ARGS__} +#define vec_char16_sp(c) (__VSX_S16__(vec_char16, (signed char)c)) +#define vec_char16_c(v) ((vec_char16)(v)) +#define vec_char16_z vec_char16_sp(0) + +typedef __vector unsigned short vec_ushort8; +#define vec_ushort8_set(...) (vec_ushort8){__VA_ARGS__} +#define vec_ushort8_sp(c) (__VSX_S8__(vec_ushort8, (unsigned short)c)) +#define vec_ushort8_c(v) ((vec_ushort8)(v)) +#define vec_ushort8_z vec_ushort8_sp(0) + +typedef __vector signed short vec_short8; +#define vec_short8_set(...) (vec_short8){__VA_ARGS__} +#define vec_short8_sp(c) (__VSX_S8__(vec_short8, (signed short)c)) +#define vec_short8_c(v) ((vec_short8)(v)) +#define vec_short8_z vec_short8_sp(0) + +typedef __vector unsigned int vec_uint4; +#define vec_uint4_set(...) (vec_uint4){__VA_ARGS__} +#define vec_uint4_sp(c) (__VSX_S4__(vec_uint4, (unsigned int)c)) +#define vec_uint4_c(v) ((vec_uint4)(v)) +#define vec_uint4_z vec_uint4_sp(0) + +typedef __vector signed int vec_int4; +#define vec_int4_set(...) (vec_int4){__VA_ARGS__} +#define vec_int4_sp(c) (__VSX_S4__(vec_int4, (signed int)c)) +#define vec_int4_c(v) ((vec_int4)(v)) +#define vec_int4_z vec_int4_sp(0) + +typedef __vector float vec_float4; +#define vec_float4_set(...) (vec_float4){__VA_ARGS__} +#define vec_float4_sp(c) (__VSX_S4__(vec_float4, c)) +#define vec_float4_c(v) ((vec_float4)(v)) +#define vec_float4_z vec_float4_sp(0) + +typedef __vector unsigned long long vec_udword2; +#define vec_udword2_set(...) (vec_udword2){__VA_ARGS__} +#define vec_udword2_sp(c) (__VSX_S2__(vec_udword2, (unsigned long long)c)) +#define vec_udword2_c(v) ((vec_udword2)(v)) +#define vec_udword2_z vec_udword2_sp(0) + +typedef __vector signed long long vec_dword2; +#define vec_dword2_set(...) (vec_dword2){__VA_ARGS__} +#define vec_dword2_sp(c) (__VSX_S2__(vec_dword2, (signed long long)c)) +#define vec_dword2_c(v) ((vec_dword2)(v)) +#define vec_dword2_z vec_dword2_sp(0) + +typedef __vector double vec_double2; +#define vec_double2_set(...) (vec_double2){__VA_ARGS__} +#define vec_double2_c(v) ((vec_double2)(v)) +#define vec_double2_sp(c) (__VSX_S2__(vec_double2, c)) +#define vec_double2_z vec_double2_sp(0) + +#define vec_bchar16 __vector __bool char +#define vec_bchar16_set(...) (vec_bchar16){__VA_ARGS__} +#define vec_bchar16_c(v) ((vec_bchar16)(v)) + +#define vec_bshort8 __vector __bool short +#define vec_bshort8_set(...) (vec_bshort8){__VA_ARGS__} +#define vec_bshort8_c(v) ((vec_bshort8)(v)) + +#define vec_bint4 __vector __bool int +#define vec_bint4_set(...) (vec_bint4){__VA_ARGS__} +#define vec_bint4_c(v) ((vec_bint4)(v)) + +#define vec_bdword2 __vector __bool long long +#define vec_bdword2_set(...) (vec_bdword2){__VA_ARGS__} +#define vec_bdword2_c(v) ((vec_bdword2)(v)) + +#define VSX_FINLINE(tp) extern inline tp __attribute__((always_inline)) + +#define VSX_REDIRECT_1RG(rt, rg, fnm, fn2) \ +VSX_FINLINE(rt) fnm(const rg& a) { return fn2(a); } + +#define VSX_REDIRECT_2RG(rt, rg, fnm, fn2) \ +VSX_FINLINE(rt) fnm(const rg& a, const rg& b) { return fn2(a, b); } + +/* + * GCC VSX compatibility +**/ +#if defined(__GNUG__) && !defined(__clang__) + +// inline asm helper +#define VSX_IMPL_1RG(rt, rto, rg, rgo, opc, fnm) \ +VSX_FINLINE(rt) fnm(const rg& a) \ +{ rt rs; __asm__ __volatile__(#opc" %x0,%x1" : "="#rto (rs) : #rgo (a)); return rs; } + +#define VSX_IMPL_1VRG(rt, rg, opc, fnm) \ +VSX_FINLINE(rt) fnm(const rg& a) \ +{ rt rs; __asm__ __volatile__(#opc" %0,%1" : "=v" (rs) : "v" (a)); return rs; } + +#define VSX_IMPL_2VRG_F(rt, rg, fopc, fnm) \ +VSX_FINLINE(rt) fnm(const rg& a, const rg& b) \ +{ rt rs; __asm__ __volatile__(fopc : "=v" (rs) : "v" (a), "v" (b)); return rs; } + +#define VSX_IMPL_2VRG(rt, rg, opc, fnm) VSX_IMPL_2VRG_F(rt, rg, #opc" %0,%1,%2", fnm) + +#if __GNUG__ < 7 +// up to GCC 6 vec_mul only supports precisions and llong +# ifdef vec_mul +# undef vec_mul +# endif +/* + * there's no a direct instruction for supporting 8-bit, 16-bit multiplication in ISA 2.07, + * XLC Implement it by using instruction "multiply even", "multiply odd" and "permute" +**/ +# define VSX_IMPL_MULH(Tvec, cperm) \ + VSX_FINLINE(Tvec) vec_mul(const Tvec& a, const Tvec& b) \ + { \ + static const vec_uchar16 ev_od = {cperm}; \ + return vec_perm((Tvec)vec_mule(a, b), (Tvec)vec_mulo(a, b), ev_od); \ + } + #define VSX_IMPL_MULH_P16 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30 + VSX_IMPL_MULH(vec_char16, VSX_IMPL_MULH_P16) + VSX_IMPL_MULH(vec_uchar16, VSX_IMPL_MULH_P16) + #define VSX_IMPL_MULH_P8 0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29 + VSX_IMPL_MULH(vec_short8, VSX_IMPL_MULH_P8) + VSX_IMPL_MULH(vec_ushort8, VSX_IMPL_MULH_P8) + // vmuluwm can be used for unsigned or signed integers, that's what they said + VSX_IMPL_2VRG(vec_int4, vec_int4, vmuluwm, vec_mul) + VSX_IMPL_2VRG(vec_uint4, vec_uint4, vmuluwm, vec_mul) + // redirect to GCC builtin vec_mul, since it already supports precisions and llong + VSX_REDIRECT_2RG(vec_float4, vec_float4, vec_mul, __builtin_vec_mul) + VSX_REDIRECT_2RG(vec_double2, vec_double2, vec_mul, __builtin_vec_mul) + VSX_REDIRECT_2RG(vec_dword2, vec_dword2, vec_mul, __builtin_vec_mul) + VSX_REDIRECT_2RG(vec_udword2, vec_udword2, vec_mul, __builtin_vec_mul) +#endif // __GNUG__ < 7 + +#if __GNUG__ < 6 +/* + * Instruction "compare greater than or equal" in ISA 2.07 only supports single + * and double precision. + * In XLC and new versions of GCC implement integers by using instruction "greater than" and NOR. +**/ +# ifdef vec_cmpge +# undef vec_cmpge +# endif +# ifdef vec_cmple +# undef vec_cmple +# endif +# define vec_cmple(a, b) vec_cmpge(b, a) +# define VSX_IMPL_CMPGE(rt, rg, opc, fnm) \ + VSX_IMPL_2VRG_F(rt, rg, #opc" %0,%2,%1\n\t xxlnor %x0,%x0,%x0", fnm) + + VSX_IMPL_CMPGE(vec_bchar16, vec_char16, vcmpgtsb, vec_cmpge) + VSX_IMPL_CMPGE(vec_bchar16, vec_uchar16, vcmpgtub, vec_cmpge) + VSX_IMPL_CMPGE(vec_bshort8, vec_short8, vcmpgtsh, vec_cmpge) + VSX_IMPL_CMPGE(vec_bshort8, vec_ushort8, vcmpgtuh, vec_cmpge) + VSX_IMPL_CMPGE(vec_bint4, vec_int4, vcmpgtsw, vec_cmpge) + VSX_IMPL_CMPGE(vec_bint4, vec_uint4, vcmpgtuw, vec_cmpge) + VSX_IMPL_CMPGE(vec_bdword2, vec_dword2, vcmpgtsd, vec_cmpge) + VSX_IMPL_CMPGE(vec_bdword2, vec_udword2, vcmpgtud, vec_cmpge) + +// redirect to GCC builtin cmpge, since it already supports precisions + VSX_REDIRECT_2RG(vec_bint4, vec_float4, vec_cmpge, __builtin_vec_cmpge) + VSX_REDIRECT_2RG(vec_bdword2, vec_double2, vec_cmpge, __builtin_vec_cmpge) + +// up to gcc5 vec_nor doesn't support bool long long +# undef vec_nor + template + VSX_REDIRECT_2RG(T, T, vec_nor, __builtin_vec_nor) + + VSX_FINLINE(vec_bdword2) vec_nor(const vec_bdword2& a, const vec_bdword2& b) + { return vec_bdword2_c(__builtin_vec_nor(vec_dword2_c(a), vec_dword2_c(b))); } + +// vec_packs doesn't support double words in gcc4 and old versions of gcc5 +# undef vec_packs + VSX_REDIRECT_2RG(vec_char16, vec_short8, vec_packs, __builtin_vec_packs) + VSX_REDIRECT_2RG(vec_uchar16, vec_ushort8, vec_packs, __builtin_vec_packs) + VSX_REDIRECT_2RG(vec_short8, vec_int4, vec_packs, __builtin_vec_packs) + VSX_REDIRECT_2RG(vec_ushort8, vec_uint4, vec_packs, __builtin_vec_packs) + + VSX_IMPL_2VRG_F(vec_int4, vec_dword2, "vpksdss %0,%2,%1", vec_packs) + VSX_IMPL_2VRG_F(vec_uint4, vec_udword2, "vpkudus %0,%2,%1", vec_packs) +#endif // __GNUG__ < 6 + +#if __GNUG__ < 5 +// vec_xxpermdi in gcc4 missing little-endian supports just like clang +# define vec_permi(a, b, c) vec_xxpermdi(b, a, (3 ^ (((c) & 1) << 1 | (c) >> 1))) +#else +# define vec_permi vec_xxpermdi +#endif // __GNUG__ < 5 + +// shift left double by word immediate +#ifndef vec_sldw +# define vec_sldw __builtin_vsx_xxsldwi +#endif + +// vector population count +VSX_IMPL_1VRG(vec_uchar16, vec_uchar16, vpopcntb, vec_popcntu) +VSX_IMPL_1VRG(vec_uchar16, vec_char16, vpopcntb, vec_popcntu) +VSX_IMPL_1VRG(vec_ushort8, vec_ushort8, vpopcnth, vec_popcntu) +VSX_IMPL_1VRG(vec_ushort8, vec_short8, vpopcnth, vec_popcntu) +VSX_IMPL_1VRG(vec_uint4, vec_uint4, vpopcntw, vec_popcntu) +VSX_IMPL_1VRG(vec_uint4, vec_int4, vpopcntw, vec_popcntu) +VSX_IMPL_1VRG(vec_udword2, vec_udword2, vpopcntd, vec_popcntu) +VSX_IMPL_1VRG(vec_udword2, vec_dword2, vpopcntd, vec_popcntu) + +// converts between single and double-precision +VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, __builtin_vsx_xvcvdpsp) +VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, __builtin_vsx_xvcvspdp) + +// converts word and doubleword to double-precision +#ifdef vec_ctd +# undef vec_ctd +#endif +VSX_IMPL_1RG(vec_double2, wd, vec_int4, wa, xvcvsxwdp, vec_ctdo) +VSX_IMPL_1RG(vec_double2, wd, vec_uint4, wa, xvcvuxwdp, vec_ctdo) +VSX_IMPL_1RG(vec_double2, wd, vec_dword2, wi, xvcvsxddp, vec_ctd) +VSX_IMPL_1RG(vec_double2, wd, vec_udword2, wi, xvcvuxddp, vec_ctd) + +// converts word and doubleword to single-precision +#undef vec_ctf +VSX_IMPL_1RG(vec_float4, wf, vec_int4, wa, xvcvsxwsp, vec_ctf) +VSX_IMPL_1RG(vec_float4, wf, vec_uint4, wa, xvcvuxwsp, vec_ctf) +VSX_IMPL_1RG(vec_float4, wf, vec_dword2, wi, xvcvsxdsp, vec_ctfo) +VSX_IMPL_1RG(vec_float4, wf, vec_udword2, wi, xvcvuxdsp, vec_ctfo) + +// converts single and double precision to signed word +#undef vec_cts +VSX_IMPL_1RG(vec_int4, wa, vec_double2, wd, xvcvdpsxws, vec_ctso) +VSX_IMPL_1RG(vec_int4, wa, vec_float4, wf, xvcvspsxws, vec_cts) + +// converts single and double precision to unsigned word +#undef vec_ctu +VSX_IMPL_1RG(vec_uint4, wa, vec_double2, wd, xvcvdpuxws, vec_ctuo) +VSX_IMPL_1RG(vec_uint4, wa, vec_float4, wf, xvcvspuxws, vec_ctu) + +// converts single and double precision to signed doubleword +#ifdef vec_ctsl +# undef vec_ctsl +#endif +VSX_IMPL_1RG(vec_dword2, wi, vec_double2, wd, xvcvdpsxds, vec_ctsl) +VSX_IMPL_1RG(vec_dword2, wi, vec_float4, wf, xvcvspsxds, vec_ctslo) + +// converts single and double precision to unsigned doubleword +#ifdef vec_ctul +# undef vec_ctul +#endif +VSX_IMPL_1RG(vec_udword2, wi, vec_double2, wd, xvcvdpuxds, vec_ctul) +VSX_IMPL_1RG(vec_udword2, wi, vec_float4, wf, xvcvspuxds, vec_ctulo) + +// just in case if GCC doesn't define it +#ifndef vec_xl +# define vec_xl vec_vsx_ld +# define vec_xst vec_vsx_st +#endif + +#endif // GCC VSX compatibility + +/* + * CLANG VSX compatibility +**/ +#if defined(__clang__) && !defined(__IBMCPP__) + +/* + * CLANG doesn't support %x in the inline asm template which fixes register number + * when using any of the register constraints wa, wd, wf + * + * For more explanation checkout PowerPC and IBM RS6000 in https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html + * Also there's already an open bug https://bugs.llvm.org/show_bug.cgi?id=31837 + * + * So we're not able to use inline asm and only use built-in functions that CLANG supports + * and use __builtin_convertvector if clang missng any of vector conversions built-in functions + * + * todo: clang asm template bug is fixed, need to reconsider the current workarounds. +*/ + +// convert vector helper +#define VSX_IMPL_CONVERT(rt, rg, fnm) \ +VSX_FINLINE(rt) fnm(const rg& a) { return __builtin_convertvector(a, rt); } + +#if __clang_major__ < 5 +// implement vec_permi in a dirty way +# define VSX_IMPL_CLANG_4_PERMI(Tvec) \ + VSX_FINLINE(Tvec) vec_permi(const Tvec& a, const Tvec& b, unsigned const char c) \ + { \ + switch (c) \ + { \ + case 0: \ + return vec_mergeh(a, b); \ + case 1: \ + return vec_mergel(vec_mergeh(a, a), b); \ + case 2: \ + return vec_mergeh(vec_mergel(a, a), b); \ + default: \ + return vec_mergel(a, b); \ + } \ + } + VSX_IMPL_CLANG_4_PERMI(vec_udword2) + VSX_IMPL_CLANG_4_PERMI(vec_dword2) + VSX_IMPL_CLANG_4_PERMI(vec_double2) + +// vec_xxsldwi is missing in clang 4 +# define vec_xxsldwi(a, b, c) vec_sld(a, b, (c) * 4) +#else +// vec_xxpermdi is missing little-endian supports in clang 4 just like gcc4 +# define vec_permi(a, b, c) vec_xxpermdi(b, a, (3 ^ (((c) & 1) << 1 | (c) >> 1))) +#endif // __clang_major__ < 5 + +// shift left double by word immediate +#ifndef vec_sldw +# define vec_sldw vec_xxsldwi +#endif + +// Implement vec_rsqrt since clang only supports vec_rsqrte +#ifndef vec_rsqrt + VSX_FINLINE(vec_float4) vec_rsqrt(const vec_float4& a) + { return vec_div(vec_float4_sp(1), vec_sqrt(a)); } + + VSX_FINLINE(vec_double2) vec_rsqrt(const vec_double2& a) + { return vec_div(vec_double2_sp(1), vec_sqrt(a)); } +#endif + +// vec_promote missing support for doubleword +VSX_FINLINE(vec_dword2) vec_promote(long long a, int b) +{ + vec_dword2 ret = vec_dword2_z; + ret[b & 1] = a; + return ret; +} + +VSX_FINLINE(vec_udword2) vec_promote(unsigned long long a, int b) +{ + vec_udword2 ret = vec_udword2_z; + ret[b & 1] = a; + return ret; +} + +// vec_popcnt should return unsigned but clang has different thought just like gcc in vec_vpopcnt +#define VSX_IMPL_POPCNTU(Tvec, Tvec2, ucast) \ +VSX_FINLINE(Tvec) vec_popcntu(const Tvec2& a) \ +{ return ucast(vec_popcnt(a)); } +VSX_IMPL_POPCNTU(vec_uchar16, vec_char16, vec_uchar16_c); +VSX_IMPL_POPCNTU(vec_ushort8, vec_short8, vec_ushort8_c); +VSX_IMPL_POPCNTU(vec_uint4, vec_int4, vec_uint4_c); +// redirect unsigned types +VSX_REDIRECT_1RG(vec_uchar16, vec_uchar16, vec_popcntu, vec_popcnt) +VSX_REDIRECT_1RG(vec_ushort8, vec_ushort8, vec_popcntu, vec_popcnt) +VSX_REDIRECT_1RG(vec_uint4, vec_uint4, vec_popcntu, vec_popcnt) + +// converts between single and double precision +VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, __builtin_vsx_xvcvdpsp) +VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, __builtin_vsx_xvcvspdp) + +// converts word and doubleword to double-precision +#ifdef vec_ctd +# undef vec_ctd +#endif +VSX_REDIRECT_1RG(vec_double2, vec_int4, vec_ctdo, __builtin_vsx_xvcvsxwdp) +VSX_REDIRECT_1RG(vec_double2, vec_uint4, vec_ctdo, __builtin_vsx_xvcvuxwdp) + +VSX_IMPL_CONVERT(vec_double2, vec_dword2, vec_ctd) +VSX_IMPL_CONVERT(vec_double2, vec_udword2, vec_ctd) + +// converts word and doubleword to single-precision +#if __clang_major__ > 4 +# undef vec_ctf +#endif +VSX_IMPL_CONVERT(vec_float4, vec_int4, vec_ctf) +VSX_IMPL_CONVERT(vec_float4, vec_uint4, vec_ctf) +VSX_REDIRECT_1RG(vec_float4, vec_dword2, vec_ctfo, __builtin_vsx_xvcvsxdsp) +VSX_REDIRECT_1RG(vec_float4, vec_udword2, vec_ctfo, __builtin_vsx_xvcvuxdsp) + +// converts single and double precision to signed word +#if __clang_major__ > 4 +# undef vec_cts +#endif +VSX_REDIRECT_1RG(vec_int4, vec_double2, vec_ctso, __builtin_vsx_xvcvdpsxws) +VSX_IMPL_CONVERT(vec_int4, vec_float4, vec_cts) + +// converts single and double precision to unsigned word +#if __clang_major__ > 4 +# undef vec_ctu +#endif +VSX_REDIRECT_1RG(vec_uint4, vec_double2, vec_ctuo, __builtin_vsx_xvcvdpuxws) +VSX_IMPL_CONVERT(vec_uint4, vec_float4, vec_ctu) + +// converts single and double precision to signed doubleword +#ifdef vec_ctsl +# undef vec_ctsl +#endif +VSX_IMPL_CONVERT(vec_dword2, vec_double2, vec_ctsl) +// __builtin_convertvector unable to convert, xvcvspsxds is missing on it +VSX_FINLINE(vec_dword2) vec_ctslo(const vec_float4& a) +{ return vec_ctsl(vec_cvfo(a)); } + +// converts single and double precision to unsigned doubleword +#ifdef vec_ctul +# undef vec_ctul +#endif +VSX_IMPL_CONVERT(vec_udword2, vec_double2, vec_ctul) +// __builtin_convertvector unable to convert, xvcvspuxds is missing on it +VSX_FINLINE(vec_udword2) vec_ctulo(const vec_float4& a) +{ return vec_ctul(vec_cvfo(a)); } + +#endif // CLANG VSX compatibility + +/* + * Common GCC, CLANG compatibility +**/ +#if defined(__GNUG__) && !defined(__IBMCPP__) + +#ifdef vec_cvf +# undef vec_cvf +#endif + +#define VSX_IMPL_CONV_EVEN_4_2(rt, rg, fnm, fn2) \ +VSX_FINLINE(rt) fnm(const rg& a) \ +{ return fn2(vec_sldw(a, a, 1)); } + +VSX_IMPL_CONV_EVEN_4_2(vec_double2, vec_float4, vec_cvf, vec_cvfo) +VSX_IMPL_CONV_EVEN_4_2(vec_double2, vec_int4, vec_ctd, vec_ctdo) +VSX_IMPL_CONV_EVEN_4_2(vec_double2, vec_uint4, vec_ctd, vec_ctdo) + +VSX_IMPL_CONV_EVEN_4_2(vec_dword2, vec_float4, vec_ctsl, vec_ctslo) +VSX_IMPL_CONV_EVEN_4_2(vec_udword2, vec_float4, vec_ctul, vec_ctulo) + +#define VSX_IMPL_CONV_EVEN_2_4(rt, rg, fnm, fn2) \ +VSX_FINLINE(rt) fnm(const rg& a) \ +{ \ + rt v4 = fn2(a); \ + return vec_sldw(v4, v4, 3); \ +} + +VSX_IMPL_CONV_EVEN_2_4(vec_float4, vec_double2, vec_cvf, vec_cvfo) +VSX_IMPL_CONV_EVEN_2_4(vec_float4, vec_dword2, vec_ctf, vec_ctfo) +VSX_IMPL_CONV_EVEN_2_4(vec_float4, vec_udword2, vec_ctf, vec_ctfo) + +VSX_IMPL_CONV_EVEN_2_4(vec_int4, vec_double2, vec_cts, vec_ctso) +VSX_IMPL_CONV_EVEN_2_4(vec_uint4, vec_double2, vec_ctu, vec_ctuo) + +// Only for Eigen! +/* + * changing behavior of conversion intrinsics for gcc has effect on Eigen + * so we redfine old behavior again only on gcc, clang +*/ +#if !defined(__clang__) || __clang_major__ > 4 + // ignoring second arg since Eigen only truncates toward zero +# define VSX_IMPL_CONV_2VARIANT(rt, rg, fnm, fn2) \ + VSX_FINLINE(rt) fnm(const rg& a, int only_truncate) \ + { \ + assert(only_truncate == 0); \ + CV_UNUSED(only_truncate); \ + return fn2(a); \ + } + VSX_IMPL_CONV_2VARIANT(vec_int4, vec_float4, vec_cts, vec_cts) + VSX_IMPL_CONV_2VARIANT(vec_float4, vec_int4, vec_ctf, vec_ctf) + // define vec_cts for converting double precision to signed doubleword + // which isn't combitable with xlc but its okay since Eigen only use it for gcc + VSX_IMPL_CONV_2VARIANT(vec_dword2, vec_double2, vec_cts, vec_ctsl) +#endif // Eigen + +#endif // Common GCC, CLANG compatibility + +/* + * XLC VSX compatibility +**/ +#if defined(__IBMCPP__) + +// vector population count +#define vec_popcntu vec_popcnt + +// overload and redirect with setting second arg to zero +// since we only support conversions without the second arg +#define VSX_IMPL_OVERLOAD_Z2(rt, rg, fnm) \ +VSX_FINLINE(rt) fnm(const rg& a) { return fnm(a, 0); } + +VSX_IMPL_OVERLOAD_Z2(vec_double2, vec_int4, vec_ctd) +VSX_IMPL_OVERLOAD_Z2(vec_double2, vec_uint4, vec_ctd) +VSX_IMPL_OVERLOAD_Z2(vec_double2, vec_dword2, vec_ctd) +VSX_IMPL_OVERLOAD_Z2(vec_double2, vec_udword2, vec_ctd) + +VSX_IMPL_OVERLOAD_Z2(vec_float4, vec_int4, vec_ctf) +VSX_IMPL_OVERLOAD_Z2(vec_float4, vec_uint4, vec_ctf) +VSX_IMPL_OVERLOAD_Z2(vec_float4, vec_dword2, vec_ctf) +VSX_IMPL_OVERLOAD_Z2(vec_float4, vec_udword2, vec_ctf) + +VSX_IMPL_OVERLOAD_Z2(vec_int4, vec_double2, vec_cts) +VSX_IMPL_OVERLOAD_Z2(vec_int4, vec_float4, vec_cts) + +VSX_IMPL_OVERLOAD_Z2(vec_uint4, vec_double2, vec_ctu) +VSX_IMPL_OVERLOAD_Z2(vec_uint4, vec_float4, vec_ctu) + +VSX_IMPL_OVERLOAD_Z2(vec_dword2, vec_double2, vec_ctsl) +VSX_IMPL_OVERLOAD_Z2(vec_dword2, vec_float4, vec_ctsl) + +VSX_IMPL_OVERLOAD_Z2(vec_udword2, vec_double2, vec_ctul) +VSX_IMPL_OVERLOAD_Z2(vec_udword2, vec_float4, vec_ctul) + +// fixme: implement conversions of odd-numbered elements in a dirty way +// since xlc doesn't support VSX registers operand in inline asm. +#define VSX_IMPL_CONV_ODD_4_2(rt, rg, fnm, fn2) \ +VSX_FINLINE(rt) fnm(const rg& a) { return fn2(vec_sldw(a, a, 3)); } + +VSX_IMPL_CONV_ODD_4_2(vec_double2, vec_float4, vec_cvfo, vec_cvf) +VSX_IMPL_CONV_ODD_4_2(vec_double2, vec_int4, vec_ctdo, vec_ctd) +VSX_IMPL_CONV_ODD_4_2(vec_double2, vec_uint4, vec_ctdo, vec_ctd) + +VSX_IMPL_CONV_ODD_4_2(vec_dword2, vec_float4, vec_ctslo, vec_ctsl) +VSX_IMPL_CONV_ODD_4_2(vec_udword2, vec_float4, vec_ctulo, vec_ctul) + +#define VSX_IMPL_CONV_ODD_2_4(rt, rg, fnm, fn2) \ +VSX_FINLINE(rt) fnm(const rg& a) \ +{ \ + rt v4 = fn2(a); \ + return vec_sldw(v4, v4, 1); \ +} + +VSX_IMPL_CONV_ODD_2_4(vec_float4, vec_double2, vec_cvfo, vec_cvf) +VSX_IMPL_CONV_ODD_2_4(vec_float4, vec_dword2, vec_ctfo, vec_ctf) +VSX_IMPL_CONV_ODD_2_4(vec_float4, vec_udword2, vec_ctfo, vec_ctf) + +VSX_IMPL_CONV_ODD_2_4(vec_int4, vec_double2, vec_ctso, vec_cts) +VSX_IMPL_CONV_ODD_2_4(vec_uint4, vec_double2, vec_ctuo, vec_ctu) + +#endif // XLC VSX compatibility + +// ignore GCC warning that caused by -Wunused-but-set-variable in rare cases +#if defined(__GNUG__) && !defined(__clang__) +# define VSX_UNUSED(Tvec) Tvec __attribute__((__unused__)) +#else // CLANG, XLC +# define VSX_UNUSED(Tvec) Tvec +#endif + +// gcc can find his way in casting log int and XLC, CLANG ambiguous +#if defined(__clang__) || defined(__IBMCPP__) + VSX_FINLINE(vec_udword2) vec_splats(uint64 v) + { return vec_splats((unsigned long long) v); } + + VSX_FINLINE(vec_dword2) vec_splats(int64 v) + { return vec_splats((long long) v); } + + VSX_FINLINE(vec_udword2) vec_promote(uint64 a, int b) + { return vec_promote((unsigned long long) a, b); } + + VSX_FINLINE(vec_dword2) vec_promote(int64 a, int b) + { return vec_promote((long long) a, b); } +#endif + +/* + * implement vsx_ld(offset, pointer), vsx_st(vector, offset, pointer) + * load and set using offset depend on the pointer type + * + * implement vsx_ldf(offset, pointer), vsx_stf(vector, offset, pointer) + * load and set using offset depend on fixed bytes size + * + * Note: In clang vec_xl and vec_xst fails to load unaligned addresses + * so we are using vec_vsx_ld, vec_vsx_st instead +*/ + +#if defined(__clang__) && !defined(__IBMCPP__) +# define vsx_ldf vec_vsx_ld +# define vsx_stf vec_vsx_st +#else // GCC , XLC +# define vsx_ldf vec_xl +# define vsx_stf vec_xst +#endif + +#define VSX_OFFSET(o, p) ((o) * sizeof(*(p))) +#define vsx_ld(o, p) vsx_ldf(VSX_OFFSET(o, p), p) +#define vsx_st(v, o, p) vsx_stf(v, VSX_OFFSET(o, p), p) + +/* + * implement vsx_ld2(offset, pointer), vsx_st2(vector, offset, pointer) to load and store double words + * In GCC vec_xl and vec_xst it maps to vec_vsx_ld, vec_vsx_st which doesn't support long long + * and in CLANG we are using vec_vsx_ld, vec_vsx_st because vec_xl, vec_xst fails to load unaligned addresses + * + * In XLC vec_xl and vec_xst fail to cast int64(long int) to long long +*/ +#if (defined(__GNUG__) || defined(__clang__)) && !defined(__IBMCPP__) + VSX_FINLINE(vec_udword2) vsx_ld2(long o, const uint64* p) + { return vec_udword2_c(vsx_ldf(VSX_OFFSET(o, p), (unsigned int*)p)); } + + VSX_FINLINE(vec_dword2) vsx_ld2(long o, const int64* p) + { return vec_dword2_c(vsx_ldf(VSX_OFFSET(o, p), (int*)p)); } + + VSX_FINLINE(void) vsx_st2(const vec_udword2& vec, long o, uint64* p) + { vsx_stf(vec_uint4_c(vec), VSX_OFFSET(o, p), (unsigned int*)p); } + + VSX_FINLINE(void) vsx_st2(const vec_dword2& vec, long o, int64* p) + { vsx_stf(vec_int4_c(vec), VSX_OFFSET(o, p), (int*)p); } +#else // XLC + VSX_FINLINE(vec_udword2) vsx_ld2(long o, const uint64* p) + { return vsx_ldf(VSX_OFFSET(o, p), (unsigned long long*)p); } + + VSX_FINLINE(vec_dword2) vsx_ld2(long o, const int64* p) + { return vsx_ldf(VSX_OFFSET(o, p), (long long*)p); } + + VSX_FINLINE(void) vsx_st2(const vec_udword2& vec, long o, uint64* p) + { vsx_stf(vec, VSX_OFFSET(o, p), (unsigned long long*)p); } + + VSX_FINLINE(void) vsx_st2(const vec_dword2& vec, long o, int64* p) + { vsx_stf(vec, VSX_OFFSET(o, p), (long long*)p); } +#endif + +// Store lower 8 byte +#define vec_st_l8(v, p) *((uint64*)(p)) = vec_extract(vec_udword2_c(v), 0) + +// Store higher 8 byte +#define vec_st_h8(v, p) *((uint64*)(p)) = vec_extract(vec_udword2_c(v), 1) + +// Load 64-bits of integer data to lower part +#define VSX_IMPL_LOAD_L8(Tvec, Tp) \ +VSX_FINLINE(Tvec) vec_ld_l8(const Tp *p) \ +{ return ((Tvec)vec_promote(*((uint64*)p), 0)); } + +VSX_IMPL_LOAD_L8(vec_uchar16, uchar) +VSX_IMPL_LOAD_L8(vec_char16, schar) +VSX_IMPL_LOAD_L8(vec_ushort8, ushort) +VSX_IMPL_LOAD_L8(vec_short8, short) +VSX_IMPL_LOAD_L8(vec_uint4, uint) +VSX_IMPL_LOAD_L8(vec_int4, int) +VSX_IMPL_LOAD_L8(vec_float4, float) +VSX_IMPL_LOAD_L8(vec_udword2, uint64) +VSX_IMPL_LOAD_L8(vec_dword2, int64) +VSX_IMPL_LOAD_L8(vec_double2, double) + +// logical not +#define vec_not(a) vec_nor(a, a) + +// power9 yaya +// not equal +#ifndef vec_cmpne +# define vec_cmpne(a, b) vec_not(vec_cmpeq(a, b)) +#endif + +// absolute difference +#ifndef vec_absd +# define vec_absd(a, b) vec_sub(vec_max(a, b), vec_min(a, b)) +#endif + +/* + * Implement vec_unpacklu and vec_unpackhu + * since vec_unpackl, vec_unpackh only support signed integers +**/ +#define VSX_IMPL_UNPACKU(rt, rg, zero) \ +VSX_FINLINE(rt) vec_unpacklu(const rg& a) \ +{ return (rt)(vec_mergel(a, zero)); } \ +VSX_FINLINE(rt) vec_unpackhu(const rg& a) \ +{ return (rt)(vec_mergeh(a, zero)); } + +VSX_IMPL_UNPACKU(vec_ushort8, vec_uchar16, vec_uchar16_z) +VSX_IMPL_UNPACKU(vec_uint4, vec_ushort8, vec_ushort8_z) +VSX_IMPL_UNPACKU(vec_udword2, vec_uint4, vec_uint4_z) + +/* + * Implement vec_mergesqe and vec_mergesqo + * Merges the sequence values of even and odd elements of two vectors +*/ +#define VSX_IMPL_PERM(rt, fnm, ...) \ +VSX_FINLINE(rt) fnm(const rt& a, const rt& b) \ +{ static const vec_uchar16 perm = {__VA_ARGS__}; return vec_perm(a, b, perm); } + +// 16 +#define perm16_mergesqe 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 +#define perm16_mergesqo 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 +VSX_IMPL_PERM(vec_uchar16, vec_mergesqe, perm16_mergesqe) +VSX_IMPL_PERM(vec_uchar16, vec_mergesqo, perm16_mergesqo) +VSX_IMPL_PERM(vec_char16, vec_mergesqe, perm16_mergesqe) +VSX_IMPL_PERM(vec_char16, vec_mergesqo, perm16_mergesqo) +// 8 +#define perm8_mergesqe 0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29 +#define perm8_mergesqo 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 +VSX_IMPL_PERM(vec_ushort8, vec_mergesqe, perm8_mergesqe) +VSX_IMPL_PERM(vec_ushort8, vec_mergesqo, perm8_mergesqo) +VSX_IMPL_PERM(vec_short8, vec_mergesqe, perm8_mergesqe) +VSX_IMPL_PERM(vec_short8, vec_mergesqo, perm8_mergesqo) +// 4 +#define perm4_mergesqe 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27 +#define perm4_mergesqo 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 +VSX_IMPL_PERM(vec_uint4, vec_mergesqe, perm4_mergesqe) +VSX_IMPL_PERM(vec_uint4, vec_mergesqo, perm4_mergesqo) +VSX_IMPL_PERM(vec_int4, vec_mergesqe, perm4_mergesqe) +VSX_IMPL_PERM(vec_int4, vec_mergesqo, perm4_mergesqo) +VSX_IMPL_PERM(vec_float4, vec_mergesqe, perm4_mergesqe) +VSX_IMPL_PERM(vec_float4, vec_mergesqo, perm4_mergesqo) +// 2 +VSX_REDIRECT_2RG(vec_double2, vec_double2, vec_mergesqe, vec_mergeh) +VSX_REDIRECT_2RG(vec_double2, vec_double2, vec_mergesqo, vec_mergel) +VSX_REDIRECT_2RG(vec_dword2, vec_dword2, vec_mergesqe, vec_mergeh) +VSX_REDIRECT_2RG(vec_dword2, vec_dword2, vec_mergesqo, vec_mergel) +VSX_REDIRECT_2RG(vec_udword2, vec_udword2, vec_mergesqe, vec_mergeh) +VSX_REDIRECT_2RG(vec_udword2, vec_udword2, vec_mergesqo, vec_mergel) + +/* + * Implement vec_mergesqh and vec_mergesql + * Merges the sequence most and least significant halves of two vectors +*/ +#define VSX_IMPL_MERGESQHL(Tvec) \ +VSX_FINLINE(Tvec) vec_mergesqh(const Tvec& a, const Tvec& b) \ +{ return (Tvec)vec_mergeh(vec_udword2_c(a), vec_udword2_c(b)); } \ +VSX_FINLINE(Tvec) vec_mergesql(const Tvec& a, const Tvec& b) \ +{ return (Tvec)vec_mergel(vec_udword2_c(a), vec_udword2_c(b)); } +VSX_IMPL_MERGESQHL(vec_uchar16) +VSX_IMPL_MERGESQHL(vec_char16) +VSX_IMPL_MERGESQHL(vec_ushort8) +VSX_IMPL_MERGESQHL(vec_short8) +VSX_IMPL_MERGESQHL(vec_uint4) +VSX_IMPL_MERGESQHL(vec_int4) +VSX_IMPL_MERGESQHL(vec_float4) +VSX_REDIRECT_2RG(vec_udword2, vec_udword2, vec_mergesqh, vec_mergeh) +VSX_REDIRECT_2RG(vec_udword2, vec_udword2, vec_mergesql, vec_mergel) +VSX_REDIRECT_2RG(vec_dword2, vec_dword2, vec_mergesqh, vec_mergeh) +VSX_REDIRECT_2RG(vec_dword2, vec_dword2, vec_mergesql, vec_mergel) +VSX_REDIRECT_2RG(vec_double2, vec_double2, vec_mergesqh, vec_mergeh) +VSX_REDIRECT_2RG(vec_double2, vec_double2, vec_mergesql, vec_mergel) + + +// 2 and 4 channels interleave for all types except 2 lanes +#define VSX_IMPL_ST_INTERLEAVE(Tp, Tvec) \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, Tp* ptr) \ +{ \ + vsx_stf(vec_mergeh(a, b), 0, ptr); \ + vsx_stf(vec_mergel(a, b), 16, ptr); \ +} \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, \ + const Tvec& c, const Tvec& d, Tp* ptr) \ +{ \ + Tvec ac = vec_mergeh(a, c); \ + Tvec bd = vec_mergeh(b, d); \ + vsx_stf(vec_mergeh(ac, bd), 0, ptr); \ + vsx_stf(vec_mergel(ac, bd), 16, ptr); \ + ac = vec_mergel(a, c); \ + bd = vec_mergel(b, d); \ + vsx_stf(vec_mergeh(ac, bd), 32, ptr); \ + vsx_stf(vec_mergel(ac, bd), 48, ptr); \ +} +VSX_IMPL_ST_INTERLEAVE(uchar, vec_uchar16) +VSX_IMPL_ST_INTERLEAVE(schar, vec_char16) +VSX_IMPL_ST_INTERLEAVE(ushort, vec_ushort8) +VSX_IMPL_ST_INTERLEAVE(short, vec_short8) +VSX_IMPL_ST_INTERLEAVE(uint, vec_uint4) +VSX_IMPL_ST_INTERLEAVE(int, vec_int4) +VSX_IMPL_ST_INTERLEAVE(float, vec_float4) + +// 2 and 4 channels deinterleave for 16 lanes +#define VSX_IMPL_ST_DINTERLEAVE_8(Tp, Tvec) \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b) \ +{ \ + Tvec v0 = vsx_ld(0, ptr); \ + Tvec v1 = vsx_ld(16, ptr); \ + a = vec_mergesqe(v0, v1); \ + b = vec_mergesqo(v0, v1); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b, \ + Tvec& c, Tvec& d) \ +{ \ + Tvec v0 = vsx_ld(0, ptr); \ + Tvec v1 = vsx_ld(16, ptr); \ + Tvec v2 = vsx_ld(32, ptr); \ + Tvec v3 = vsx_ld(48, ptr); \ + Tvec m0 = vec_mergesqe(v0, v1); \ + Tvec m1 = vec_mergesqe(v2, v3); \ + a = vec_mergesqe(m0, m1); \ + c = vec_mergesqo(m0, m1); \ + m0 = vec_mergesqo(v0, v1); \ + m1 = vec_mergesqo(v2, v3); \ + b = vec_mergesqe(m0, m1); \ + d = vec_mergesqo(m0, m1); \ +} +VSX_IMPL_ST_DINTERLEAVE_8(uchar, vec_uchar16) +VSX_IMPL_ST_DINTERLEAVE_8(schar, vec_char16) + +// 2 and 4 channels deinterleave for 8 lanes +#define VSX_IMPL_ST_DINTERLEAVE_16(Tp, Tvec) \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b) \ +{ \ + Tvec v0 = vsx_ld(0, ptr); \ + Tvec v1 = vsx_ld(8, ptr); \ + a = vec_mergesqe(v0, v1); \ + b = vec_mergesqo(v0, v1); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b, \ + Tvec& c, Tvec& d) \ +{ \ + Tvec v0 = vsx_ld(0, ptr); \ + Tvec v1 = vsx_ld(8, ptr); \ + Tvec m0 = vec_mergeh(v0, v1); \ + Tvec m1 = vec_mergel(v0, v1); \ + Tvec ab0 = vec_mergeh(m0, m1); \ + Tvec cd0 = vec_mergel(m0, m1); \ + v0 = vsx_ld(16, ptr); \ + v1 = vsx_ld(24, ptr); \ + m0 = vec_mergeh(v0, v1); \ + m1 = vec_mergel(v0, v1); \ + Tvec ab1 = vec_mergeh(m0, m1); \ + Tvec cd1 = vec_mergel(m0, m1); \ + a = vec_mergesqh(ab0, ab1); \ + b = vec_mergesql(ab0, ab1); \ + c = vec_mergesqh(cd0, cd1); \ + d = vec_mergesql(cd0, cd1); \ +} +VSX_IMPL_ST_DINTERLEAVE_16(ushort, vec_ushort8) +VSX_IMPL_ST_DINTERLEAVE_16(short, vec_short8) + +// 2 and 4 channels deinterleave for 4 lanes +#define VSX_IMPL_ST_DINTERLEAVE_32(Tp, Tvec) \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b) \ +{ \ + a = vsx_ld(0, ptr); \ + b = vsx_ld(4, ptr); \ + Tvec m0 = vec_mergeh(a, b); \ + Tvec m1 = vec_mergel(a, b); \ + a = vec_mergeh(m0, m1); \ + b = vec_mergel(m0, m1); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b, \ + Tvec& c, Tvec& d) \ +{ \ + Tvec v0 = vsx_ld(0, ptr); \ + Tvec v1 = vsx_ld(4, ptr); \ + Tvec v2 = vsx_ld(8, ptr); \ + Tvec v3 = vsx_ld(12, ptr); \ + Tvec m0 = vec_mergeh(v0, v2); \ + Tvec m1 = vec_mergeh(v1, v3); \ + a = vec_mergeh(m0, m1); \ + b = vec_mergel(m0, m1); \ + m0 = vec_mergel(v0, v2); \ + m1 = vec_mergel(v1, v3); \ + c = vec_mergeh(m0, m1); \ + d = vec_mergel(m0, m1); \ +} +VSX_IMPL_ST_DINTERLEAVE_32(uint, vec_uint4) +VSX_IMPL_ST_DINTERLEAVE_32(int, vec_int4) +VSX_IMPL_ST_DINTERLEAVE_32(float, vec_float4) + +// 2 and 4 channels interleave and deinterleave for 2 lanes +#define VSX_IMPL_ST_D_INTERLEAVE_64(Tp, Tvec, ld_func, st_func) \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, Tp* ptr) \ +{ \ + st_func(vec_mergeh(a, b), 0, ptr); \ + st_func(vec_mergel(a, b), 2, ptr); \ +} \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, \ + const Tvec& c, const Tvec& d, Tp* ptr) \ +{ \ + st_func(vec_mergeh(a, b), 0, ptr); \ + st_func(vec_mergeh(c, d), 2, ptr); \ + st_func(vec_mergel(a, b), 4, ptr); \ + st_func(vec_mergel(c, d), 6, ptr); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b) \ +{ \ + Tvec m0 = ld_func(0, ptr); \ + Tvec m1 = ld_func(2, ptr); \ + a = vec_mergeh(m0, m1); \ + b = vec_mergel(m0, m1); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b, \ + Tvec& c, Tvec& d) \ +{ \ + Tvec v0 = ld_func(0, ptr); \ + Tvec v1 = ld_func(2, ptr); \ + Tvec v2 = ld_func(4, ptr); \ + Tvec v3 = ld_func(6, ptr); \ + a = vec_mergeh(v0, v2); \ + b = vec_mergel(v0, v2); \ + c = vec_mergeh(v1, v3); \ + d = vec_mergel(v1, v3); \ +} +VSX_IMPL_ST_D_INTERLEAVE_64(int64, vec_dword2, vsx_ld2, vsx_st2) +VSX_IMPL_ST_D_INTERLEAVE_64(uint64, vec_udword2, vsx_ld2, vsx_st2) +VSX_IMPL_ST_D_INTERLEAVE_64(double, vec_double2, vsx_ld, vsx_st) + +/* 3 channels */ +#define VSX_IMPL_ST_INTERLEAVE_3CH_16(Tp, Tvec) \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, \ + const Tvec& c, Tp* ptr) \ +{ \ + static const vec_uchar16 a12 = {0, 16, 0, 1, 17, 0, 2, 18, 0, 3, 19, 0, 4, 20, 0, 5}; \ + static const vec_uchar16 a123 = {0, 1, 16, 3, 4, 17, 6, 7, 18, 9, 10, 19, 12, 13, 20, 15}; \ + vsx_st(vec_perm(vec_perm(a, b, a12), c, a123), 0, ptr); \ + static const vec_uchar16 b12 = {21, 0, 6, 22, 0, 7, 23, 0, 8, 24, 0, 9, 25, 0, 10, 26}; \ + static const vec_uchar16 b123 = {0, 21, 2, 3, 22, 5, 6, 23, 8, 9, 24, 11, 12, 25, 14, 15}; \ + vsx_st(vec_perm(vec_perm(a, b, b12), c, b123), 16, ptr); \ + static const vec_uchar16 c12 = {0, 11, 27, 0, 12, 28, 0, 13, 29, 0, 14, 30, 0, 15, 31, 0}; \ + static const vec_uchar16 c123 = {26, 1, 2, 27, 4, 5, 28, 7, 8, 29, 10, 11, 30, 13, 14, 31}; \ + vsx_st(vec_perm(vec_perm(a, b, c12), c, c123), 32, ptr); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b, Tvec& c) \ +{ \ + Tvec v1 = vsx_ld(0, ptr); \ + Tvec v2 = vsx_ld(16, ptr); \ + Tvec v3 = vsx_ld(32, ptr); \ + static const vec_uchar16 a12_perm = {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 0, 0, 0, 0, 0}; \ + static const vec_uchar16 a123_perm = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 17, 20, 23, 26, 29}; \ + a = vec_perm(vec_perm(v1, v2, a12_perm), v3, a123_perm); \ + static const vec_uchar16 b12_perm = {1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 0, 0, 0, 0, 0}; \ + static const vec_uchar16 b123_perm = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18, 21, 24, 27, 30}; \ + b = vec_perm(vec_perm(v1, v2, b12_perm), v3, b123_perm); \ + static const vec_uchar16 c12_perm = {2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 0, 0, 0, 0, 0, 0}; \ + static const vec_uchar16 c123_perm = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 19, 22, 25, 28, 31}; \ + c = vec_perm(vec_perm(v1, v2, c12_perm), v3, c123_perm); \ +} +VSX_IMPL_ST_INTERLEAVE_3CH_16(uchar, vec_uchar16) +VSX_IMPL_ST_INTERLEAVE_3CH_16(schar, vec_char16) + +#define VSX_IMPL_ST_INTERLEAVE_3CH_8(Tp, Tvec) \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, \ + const Tvec& c, Tp* ptr) \ +{ \ + static const vec_uchar16 a12 = {0, 1, 16, 17, 0, 0, 2, 3, 18, 19, 0, 0, 4, 5, 20, 21}; \ + static const vec_uchar16 a123 = {0, 1, 2, 3, 16, 17, 6, 7, 8, 9, 18, 19, 12, 13, 14, 15}; \ + vsx_st(vec_perm(vec_perm(a, b, a12), c, a123), 0, ptr); \ + static const vec_uchar16 b12 = {0, 0, 6, 7, 22, 23, 0, 0, 8, 9, 24, 25, 0, 0, 10, 11}; \ + static const vec_uchar16 b123 = {20, 21, 2, 3, 4, 5, 22, 23, 8, 9, 10, 11, 24, 25, 14, 15}; \ + vsx_st(vec_perm(vec_perm(a, b, b12), c, b123), 8, ptr); \ + static const vec_uchar16 c12 = {26, 27, 0, 0, 12, 13, 28, 29, 0, 0, 14, 15, 30, 31, 0, 0}; \ + static const vec_uchar16 c123 = {0, 1, 26, 27, 4, 5, 6, 7, 28, 29, 10, 11, 12, 13, 30, 31}; \ + vsx_st(vec_perm(vec_perm(a, b, c12), c, c123), 16, ptr); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b, Tvec& c) \ +{ \ + Tvec v1 = vsx_ld(0, ptr); \ + Tvec v2 = vsx_ld(8, ptr); \ + Tvec v3 = vsx_ld(16, ptr); \ + static const vec_uchar16 a12_perm = {0, 1, 6, 7, 12, 13, 18, 19, 24, 25, 30, 31, 0, 0, 0, 0}; \ + static const vec_uchar16 a123_perm = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, 21, 26, 27}; \ + a = vec_perm(vec_perm(v1, v2, a12_perm), v3, a123_perm); \ + static const vec_uchar16 b12_perm = {2, 3, 8, 9, 14, 15, 20, 21, 26, 27, 0, 0, 0, 0, 0, 0}; \ + static const vec_uchar16 b123_perm = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 22, 23, 28, 29}; \ + b = vec_perm(vec_perm(v1, v2, b12_perm), v3, b123_perm); \ + static const vec_uchar16 c12_perm = {4, 5, 10, 11, 16, 17, 22, 23, 28, 29, 0, 0, 0, 0, 0, 0}; \ + static const vec_uchar16 c123_perm = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 18, 19, 24, 25, 30, 31}; \ + c = vec_perm(vec_perm(v1, v2, c12_perm), v3, c123_perm); \ +} +VSX_IMPL_ST_INTERLEAVE_3CH_8(ushort, vec_ushort8) +VSX_IMPL_ST_INTERLEAVE_3CH_8(short, vec_short8) + +#define VSX_IMPL_ST_INTERLEAVE_3CH_4(Tp, Tvec) \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, \ + const Tvec& c, Tp* ptr) \ +{ \ + Tvec hbc = vec_mergeh(b, c); \ + static const vec_uchar16 ahbc = {0, 1, 2, 3, 16, 17, 18, 19, 20, 21, 22, 23, 4, 5, 6, 7}; \ + vsx_st(vec_perm(a, hbc, ahbc), 0, ptr); \ + Tvec lab = vec_mergel(a, b); \ + vsx_st(vec_sld(lab, hbc, 8), 4, ptr); \ + static const vec_uchar16 clab = {8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31, 12, 13, 14, 15};\ + vsx_st(vec_perm(c, lab, clab), 8, ptr); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, Tvec& b, Tvec& c) \ +{ \ + Tvec v1 = vsx_ld(0, ptr); \ + Tvec v2 = vsx_ld(4, ptr); \ + Tvec v3 = vsx_ld(8, ptr); \ + static const vec_uchar16 flp = {0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, 30, 31}; \ + a = vec_perm(v1, vec_sld(v3, v2, 8), flp); \ + static const vec_uchar16 flp2 = {28, 29, 30, 31, 0, 1, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19}; \ + b = vec_perm(v2, vec_sld(v1, v3, 8), flp2); \ + c = vec_perm(vec_sld(v2, v1, 8), v3, flp); \ +} +VSX_IMPL_ST_INTERLEAVE_3CH_4(uint, vec_uint4) +VSX_IMPL_ST_INTERLEAVE_3CH_4(int, vec_int4) +VSX_IMPL_ST_INTERLEAVE_3CH_4(float, vec_float4) + +#define VSX_IMPL_ST_INTERLEAVE_3CH_2(Tp, Tvec, ld_func, st_func) \ +VSX_FINLINE(void) vec_st_interleave(const Tvec& a, const Tvec& b, \ + const Tvec& c, Tp* ptr) \ +{ \ + st_func(vec_mergeh(a, b), 0, ptr); \ + st_func(vec_permi(c, a, 1), 2, ptr); \ + st_func(vec_mergel(b, c), 4, ptr); \ +} \ +VSX_FINLINE(void) vec_ld_deinterleave(const Tp* ptr, Tvec& a, \ + Tvec& b, Tvec& c) \ +{ \ + Tvec v1 = ld_func(0, ptr); \ + Tvec v2 = ld_func(2, ptr); \ + Tvec v3 = ld_func(4, ptr); \ + a = vec_permi(v1, v2, 1); \ + b = vec_permi(v1, v3, 2); \ + c = vec_permi(v2, v3, 1); \ +} +VSX_IMPL_ST_INTERLEAVE_3CH_2(int64, vec_dword2, vsx_ld2, vsx_st2) +VSX_IMPL_ST_INTERLEAVE_3CH_2(uint64, vec_udword2, vsx_ld2, vsx_st2) +VSX_IMPL_ST_INTERLEAVE_3CH_2(double, vec_double2, vsx_ld, vsx_st) + +#endif // CV_VSX + +//! @} + +#endif // OPENCV_HAL_VSX_UTILS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/cvconfig.h b/Prj-Win/3rd/opencv/include/opencv2/cvconfig.h new file mode 100755 index 0000000..56e2cef --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/cvconfig.h @@ -0,0 +1,167 @@ +#ifndef OPENCV_CVCONFIG_H_INCLUDED +#define OPENCV_CVCONFIG_H_INCLUDED + +/* OpenCV compiled as static or dynamic libs */ +#define BUILD_SHARED_LIBS + +/* OpenCV intrinsics optimized code */ +#define CV_ENABLE_INTRINSICS + +/* OpenCV additional optimized code */ +/* #undef CV_DISABLE_OPTIMIZATION */ + +/* Compile for 'real' NVIDIA GPU architectures */ +#define CUDA_ARCH_BIN "" + +/* Create PTX or BIN for 1.0 compute capability */ +/* #undef CUDA_ARCH_BIN_OR_PTX_10 */ + +/* NVIDIA GPU features are used */ +#define CUDA_ARCH_FEATURES "" + +/* Compile for 'virtual' NVIDIA PTX architectures */ +#define CUDA_ARCH_PTX "" + +/* AMD's Basic Linear Algebra Subprograms Library*/ +/* #undef HAVE_CLAMDBLAS */ + +/* AMD's OpenCL Fast Fourier Transform Library*/ +/* #undef HAVE_CLAMDFFT */ + +/* Clp support */ +/* #undef HAVE_CLP */ + +/* Cocoa API */ +/* #undef HAVE_COCOA */ + +/* NVIDIA CUDA Runtime API*/ +/* #undef HAVE_CUDA */ + +/* NVIDIA CUDA Basic Linear Algebra Subprograms (BLAS) API*/ +/* #undef HAVE_CUBLAS */ + +/* NVIDIA CUDA Deep Neural Network (cuDNN) API*/ +/* #undef HAVE_CUDNN */ + +/* NVIDIA CUDA Fast Fourier Transform (FFT) API*/ +/* #undef HAVE_CUFFT */ + +/* DirectX */ +#define HAVE_DIRECTX +#define HAVE_DIRECTX_NV12 +#define HAVE_D3D11 +#define HAVE_D3D10 +#define HAVE_D3D9 + +/* Eigen Matrix & Linear Algebra Library */ +/* #undef HAVE_EIGEN */ + +/* Geospatial Data Abstraction Library */ +/* #undef HAVE_GDAL */ + +/* GTK+ 2.0 Thread support */ +/* #undef HAVE_GTHREAD */ + +/* GTK+ 2.x toolkit */ +/* #undef HAVE_GTK */ + +/* Halide support */ +/* #undef HAVE_HALIDE */ + +/* Vulkan support */ +/* #undef HAVE_VULKAN */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Intel Integrated Performance Primitives */ +#define HAVE_IPP +#define HAVE_IPP_ICV +#define HAVE_IPP_IW +#define HAVE_IPP_IW_LL + +/* JPEG-2000 codec */ +#define HAVE_JASPER + +/* IJG JPEG codec */ +#define HAVE_JPEG + +/* libpng/png.h needs to be included */ +/* #undef HAVE_LIBPNG_PNG_H */ + +/* GDCM DICOM codec */ +/* #undef HAVE_GDCM */ + +/* NVIDIA Video Decoding API*/ +/* #undef HAVE_NVCUVID */ + +/* NVIDIA Video Encoding API*/ +/* #undef HAVE_NVCUVENC */ + +/* OpenCL Support */ +#define HAVE_OPENCL +/* #undef HAVE_OPENCL_STATIC */ +/* #undef HAVE_OPENCL_SVM */ + +/* NVIDIA OpenCL D3D Extensions support */ +#define HAVE_OPENCL_D3D11_NV + +/* OpenEXR codec */ +#define HAVE_OPENEXR + +/* OpenGL support*/ +/* #undef HAVE_OPENGL */ + +/* PNG codec */ +#define HAVE_PNG + +/* Posix threads (pthreads) */ +/* #undef HAVE_PTHREAD */ + +/* parallel_for with pthreads */ +/* #undef HAVE_PTHREADS_PF */ + +/* Qt support */ +/* #undef HAVE_QT */ + +/* Qt OpenGL support */ +/* #undef HAVE_QT_OPENGL */ + +/* Intel Threading Building Blocks */ +/* #undef HAVE_TBB */ + +/* Ste||ar Group High Performance ParallelX */ +/* #undef HAVE_HPX */ + +/* TIFF codec */ +#define HAVE_TIFF + +/* Win32 UI */ +#define HAVE_WIN32UI + +/* Define if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* VA library (libva) */ +/* #undef HAVE_VA */ + +/* Intel VA-API/OpenCL */ +/* #undef HAVE_VA_INTEL */ + +/* Lapack */ +/* #undef HAVE_LAPACK */ + +/* Library was compiled with functions instrumentation */ +/* #undef ENABLE_INSTRUMENTATION */ + +/* OpenVX */ +/* #undef HAVE_OPENVX */ + +/* OpenCV trace utilities */ +#define OPENCV_TRACE + +/* Library QR-code decoding */ +#define HAVE_QUIRC + +#endif // OPENCV_CVCONFIG_H_INCLUDED diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn.hpp new file mode 100755 index 0000000..97f2fe3 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn.hpp @@ -0,0 +1,78 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_DNN_HPP +#define OPENCV_DNN_HPP + +// This is an umbrella header to include into you project. +// We are free to change headers layout in dnn subfolder, so please include +// this header for future compatibility + + +/** @defgroup dnn Deep Neural Network module + @{ + This module contains: + - API for new layers creation, layers are building bricks of neural networks; + - set of built-in most-useful Layers; + - API to construct and modify comprehensive neural networks from layers; + - functionality for loading serialized networks models from different frameworks. + + Functionality of this module is designed only for forward pass computations (i.e. network testing). + A network training is in principle not supported. + @} +*/ +/** @example samples/dnn/classification.cpp +Check @ref tutorial_dnn_googlenet "the corresponding tutorial" for more details +*/ +/** @example samples/dnn/colorization.cpp +*/ +/** @example samples/dnn/object_detection.cpp +Check @ref tutorial_dnn_yolo "the corresponding tutorial" for more details +*/ +/** @example samples/dnn/openpose.cpp +*/ +/** @example samples/dnn/segmentation.cpp +*/ +/** @example samples/dnn/text_detection.cpp +*/ +#include + +#endif /* OPENCV_DNN_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/all_layers.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/all_layers.hpp new file mode 100755 index 0000000..c1844d8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/all_layers.hpp @@ -0,0 +1,635 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_DNN_DNN_ALL_LAYERS_HPP +#define OPENCV_DNN_DNN_ALL_LAYERS_HPP +#include + +namespace cv { +namespace dnn { +CV__DNN_INLINE_NS_BEGIN +//! @addtogroup dnn +//! @{ + +/** @defgroup dnnLayerList Partial List of Implemented Layers + @{ + This subsection of dnn module contains information about built-in layers and their descriptions. + + Classes listed here, in fact, provides C++ API for creating instances of built-in layers. + In addition to this way of layers instantiation, there is a more common factory API (see @ref dnnLayerFactory), it allows to create layers dynamically (by name) and register new ones. + You can use both API, but factory API is less convenient for native C++ programming and basically designed for use inside importers (see @ref readNetFromCaffe(), @ref readNetFromTorch(), @ref readNetFromTensorflow()). + + Built-in layers partially reproduce functionality of corresponding Caffe and Torch7 layers. + In particular, the following layers and Caffe importer were tested to reproduce Caffe functionality: + - Convolution + - Deconvolution + - Pooling + - InnerProduct + - TanH, ReLU, Sigmoid, BNLL, Power, AbsVal + - Softmax + - Reshape, Flatten, Slice, Split + - LRN + - MVN + - Dropout (since it does nothing on forward pass -)) +*/ + + class CV_EXPORTS BlankLayer : public Layer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + /** + * Constant layer produces the same data blob at an every forward pass. + */ + class CV_EXPORTS ConstLayer : public Layer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + //! LSTM recurrent layer + class CV_EXPORTS LSTMLayer : public Layer + { + public: + /** Creates instance of LSTM layer */ + static Ptr create(const LayerParams& params); + + /** @deprecated Use LayerParams::blobs instead. + @brief Set trained weights for LSTM layer. + + LSTM behavior on each step is defined by current input, previous output, previous cell state and learned weights. + + Let @f$x_t@f$ be current input, @f$h_t@f$ be current output, @f$c_t@f$ be current state. + Than current output and current cell state is computed as follows: + @f{eqnarray*}{ + h_t &= o_t \odot tanh(c_t), \\ + c_t &= f_t \odot c_{t-1} + i_t \odot g_t, \\ + @f} + where @f$\odot@f$ is per-element multiply operation and @f$i_t, f_t, o_t, g_t@f$ is internal gates that are computed using learned wights. + + Gates are computed as follows: + @f{eqnarray*}{ + i_t &= sigmoid&(W_{xi} x_t + W_{hi} h_{t-1} + b_i), \\ + f_t &= sigmoid&(W_{xf} x_t + W_{hf} h_{t-1} + b_f), \\ + o_t &= sigmoid&(W_{xo} x_t + W_{ho} h_{t-1} + b_o), \\ + g_t &= tanh &(W_{xg} x_t + W_{hg} h_{t-1} + b_g), \\ + @f} + where @f$W_{x?}@f$, @f$W_{h?}@f$ and @f$b_{?}@f$ are learned weights represented as matrices: + @f$W_{x?} \in R^{N_h \times N_x}@f$, @f$W_{h?} \in R^{N_h \times N_h}@f$, @f$b_? \in R^{N_h}@f$. + + For simplicity and performance purposes we use @f$ W_x = [W_{xi}; W_{xf}; W_{xo}, W_{xg}] @f$ + (i.e. @f$W_x@f$ is vertical concatenation of @f$ W_{x?} @f$), @f$ W_x \in R^{4N_h \times N_x} @f$. + The same for @f$ W_h = [W_{hi}; W_{hf}; W_{ho}, W_{hg}], W_h \in R^{4N_h \times N_h} @f$ + and for @f$ b = [b_i; b_f, b_o, b_g]@f$, @f$b \in R^{4N_h} @f$. + + @param Wh is matrix defining how previous output is transformed to internal gates (i.e. according to above mentioned notation is @f$ W_h @f$) + @param Wx is matrix defining how current input is transformed to internal gates (i.e. according to above mentioned notation is @f$ W_x @f$) + @param b is bias vector (i.e. according to above mentioned notation is @f$ b @f$) + */ + CV_DEPRECATED virtual void setWeights(const Mat &Wh, const Mat &Wx, const Mat &b) = 0; + + /** @brief Specifies shape of output blob which will be [[`T`], `N`] + @p outTailShape. + * @details If this parameter is empty or unset then @p outTailShape = [`Wh`.size(0)] will be used, + * where `Wh` is parameter from setWeights(). + */ + virtual void setOutShape(const MatShape &outTailShape = MatShape()) = 0; + + /** @deprecated Use flag `produce_cell_output` in LayerParams. + * @brief Specifies either interpret first dimension of input blob as timestamp dimenion either as sample. + * + * If flag is set to true then shape of input blob will be interpreted as [`T`, `N`, `[data dims]`] where `T` specifies number of timestamps, `N` is number of independent streams. + * In this case each forward() call will iterate through `T` timestamps and update layer's state `T` times. + * + * If flag is set to false then shape of input blob will be interpreted as [`N`, `[data dims]`]. + * In this case each forward() call will make one iteration and produce one timestamp with shape [`N`, `[out dims]`]. + */ + CV_DEPRECATED virtual void setUseTimstampsDim(bool use = true) = 0; + + /** @deprecated Use flag `use_timestamp_dim` in LayerParams. + * @brief If this flag is set to true then layer will produce @f$ c_t @f$ as second output. + * @details Shape of the second output is the same as first output. + */ + CV_DEPRECATED virtual void setProduceCellOutput(bool produce = false) = 0; + + /* In common case it use single input with @f$x_t@f$ values to compute output(s) @f$h_t@f$ (and @f$c_t@f$). + * @param input should contain packed values @f$x_t@f$ + * @param output contains computed outputs: @f$h_t@f$ (and @f$c_t@f$ if setProduceCellOutput() flag was set to true). + * + * If setUseTimstampsDim() is set to true then @p input[0] should has at least two dimensions with the following shape: [`T`, `N`, `[data dims]`], + * where `T` specifies number of timestamps, `N` is number of independent streams (i.e. @f$ x_{t_0 + t}^{stream} @f$ is stored inside @p input[0][t, stream, ...]). + * + * If setUseTimstampsDim() is set to false then @p input[0] should contain single timestamp, its shape should has form [`N`, `[data dims]`] with at least one dimension. + * (i.e. @f$ x_{t}^{stream} @f$ is stored inside @p input[0][stream, ...]). + */ + + int inputNameToIndex(String inputName) CV_OVERRIDE; + int outputNameToIndex(const String& outputName) CV_OVERRIDE; + }; + + /** @brief Classical recurrent layer + + Accepts two inputs @f$x_t@f$ and @f$h_{t-1}@f$ and compute two outputs @f$o_t@f$ and @f$h_t@f$. + + - input: should contain packed input @f$x_t@f$. + - output: should contain output @f$o_t@f$ (and @f$h_t@f$ if setProduceHiddenOutput() is set to true). + + input[0] should have shape [`T`, `N`, `data_dims`] where `T` and `N` is number of timestamps and number of independent samples of @f$x_t@f$ respectively. + + output[0] will have shape [`T`, `N`, @f$N_o@f$], where @f$N_o@f$ is number of rows in @f$ W_{xo} @f$ matrix. + + If setProduceHiddenOutput() is set to true then @p output[1] will contain a Mat with shape [`T`, `N`, @f$N_h@f$], where @f$N_h@f$ is number of rows in @f$ W_{hh} @f$ matrix. + */ + class CV_EXPORTS RNNLayer : public Layer + { + public: + /** Creates instance of RNNLayer */ + static Ptr create(const LayerParams& params); + + /** Setups learned weights. + + Recurrent-layer behavior on each step is defined by current input @f$ x_t @f$, previous state @f$ h_t @f$ and learned weights as follows: + @f{eqnarray*}{ + h_t &= tanh&(W_{hh} h_{t-1} + W_{xh} x_t + b_h), \\ + o_t &= tanh&(W_{ho} h_t + b_o), + @f} + + @param Wxh is @f$ W_{xh} @f$ matrix + @param bh is @f$ b_{h} @f$ vector + @param Whh is @f$ W_{hh} @f$ matrix + @param Who is @f$ W_{xo} @f$ matrix + @param bo is @f$ b_{o} @f$ vector + */ + virtual void setWeights(const Mat &Wxh, const Mat &bh, const Mat &Whh, const Mat &Who, const Mat &bo) = 0; + + /** @brief If this flag is set to true then layer will produce @f$ h_t @f$ as second output. + * @details Shape of the second output is the same as first output. + */ + virtual void setProduceHiddenOutput(bool produce = false) = 0; + + }; + + class CV_EXPORTS BaseConvolutionLayer : public Layer + { + public: + CV_DEPRECATED_EXTERNAL Size kernel, stride, pad, dilation, adjustPad; + std::vector adjust_pads; + std::vector kernel_size, strides, dilations; + std::vector pads_begin, pads_end; + String padMode; + int numOutput; + }; + + class CV_EXPORTS ConvolutionLayer : public BaseConvolutionLayer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS DeconvolutionLayer : public BaseConvolutionLayer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS LRNLayer : public Layer + { + public: + int type; + + int size; + float alpha, beta, bias; + bool normBySize; + + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS PoolingLayer : public Layer + { + public: + int type; + std::vector kernel_size, strides; + std::vector pads_begin, pads_end; + CV_DEPRECATED_EXTERNAL Size kernel, stride, pad; + CV_DEPRECATED_EXTERNAL int pad_l, pad_t, pad_r, pad_b; + bool globalPooling; + bool computeMaxIdx; + String padMode; + bool ceilMode; + // If true for average pooling with padding, divide an every output region + // by a whole kernel area. Otherwise exclude zero padded values and divide + // by number of real values. + bool avePoolPaddedArea; + // ROIPooling parameters. + Size pooledSize; + float spatialScale; + // PSROIPooling parameters. + int psRoiOutChannels; + + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS SoftmaxLayer : public Layer + { + public: + bool logSoftMax; + + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS InnerProductLayer : public Layer + { + public: + int axis; + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS MVNLayer : public Layer + { + public: + float eps; + bool normVariance, acrossChannels; + + static Ptr create(const LayerParams& params); + }; + + /* Reshaping */ + + class CV_EXPORTS ReshapeLayer : public Layer + { + public: + MatShape newShapeDesc; + Range newShapeRange; + + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS FlattenLayer : public Layer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS ConcatLayer : public Layer + { + public: + int axis; + /** + * @brief Add zero padding in case of concatenation of blobs with different + * spatial sizes. + * + * Details: https://github.com/torch/nn/blob/master/doc/containers.md#depthconcat + */ + bool padding; + + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS SplitLayer : public Layer + { + public: + int outputsCount; //!< Number of copies that will be produced (is ignored when negative). + + static Ptr create(const LayerParams ¶ms); + }; + + /** + * Slice layer has several modes: + * 1. Caffe mode + * @param[in] axis Axis of split operation + * @param[in] slice_point Array of split points + * + * Number of output blobs equals to number of split points plus one. The + * first blob is a slice on input from 0 to @p slice_point[0] - 1 by @p axis, + * the second output blob is a slice of input from @p slice_point[0] to + * @p slice_point[1] - 1 by @p axis and the last output blob is a slice of + * input from @p slice_point[-1] up to the end of @p axis size. + * + * 2. TensorFlow mode + * @param begin Vector of start indices + * @param size Vector of sizes + * + * More convenient numpy-like slice. One and only output blob + * is a slice `input[begin[0]:begin[0]+size[0], begin[1]:begin[1]+size[1], ...]` + * + * 3. Torch mode + * @param axis Axis of split operation + * + * Split input blob on the equal parts by @p axis. + */ + class CV_EXPORTS SliceLayer : public Layer + { + public: + /** + * @brief Vector of slice ranges. + * + * The first dimension equals number of output blobs. + * Inner vector has slice ranges for the first number of input dimensions. + */ + std::vector > sliceRanges; + int axis; + + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS PermuteLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + /** + * Permute channels of 4-dimensional input blob. + * @param group Number of groups to split input channels and pick in turns + * into output blob. + * + * \f[ groupSize = \frac{number\ of\ channels}{group} \f] + * \f[ output(n, c, h, w) = input(n, groupSize \times (c \% group) + \lfloor \frac{c}{group} \rfloor, h, w) \f] + * Read more at https://arxiv.org/pdf/1707.01083.pdf + */ + class CV_EXPORTS ShuffleChannelLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + + int group; + }; + + /** + * @brief Adds extra values for specific axes. + * @param paddings Vector of paddings in format + * @code + * [ pad_before, pad_after, // [0]th dimension + * pad_before, pad_after, // [1]st dimension + * ... + * pad_before, pad_after ] // [n]th dimension + * @endcode + * that represents number of padded values at every dimension + * starting from the first one. The rest of dimensions won't + * be padded. + * @param value Value to be padded. Defaults to zero. + * @param type Padding type: 'constant', 'reflect' + * @param input_dims Torch's parameter. If @p input_dims is not equal to the + * actual input dimensionality then the `[0]th` dimension + * is considered as a batch dimension and @p paddings are shifted + * to a one dimension. Defaults to `-1` that means padding + * corresponding to @p paddings. + */ + class CV_EXPORTS PaddingLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + /* Activations */ + class CV_EXPORTS ActivationLayer : public Layer + { + public: + virtual void forwardSlice(const float* src, float* dst, int len, + size_t outPlaneSize, int cn0, int cn1) const = 0; + }; + + class CV_EXPORTS ReLULayer : public ActivationLayer + { + public: + float negativeSlope; + + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS ReLU6Layer : public ActivationLayer + { + public: + float minValue, maxValue; + + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS ChannelsPReLULayer : public ActivationLayer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS ELULayer : public ActivationLayer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS TanHLayer : public ActivationLayer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS SigmoidLayer : public ActivationLayer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS BNLLLayer : public ActivationLayer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS AbsLayer : public ActivationLayer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS PowerLayer : public ActivationLayer + { + public: + float power, scale, shift; + + static Ptr create(const LayerParams ¶ms); + }; + + /* Layers used in semantic segmentation */ + + class CV_EXPORTS CropLayer : public Layer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS EltwiseLayer : public Layer + { + public: + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS BatchNormLayer : public ActivationLayer + { + public: + bool hasWeights, hasBias; + float epsilon; + + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS MaxUnpoolLayer : public Layer + { + public: + Size poolKernel; + Size poolPad; + Size poolStride; + + static Ptr create(const LayerParams ¶ms); + }; + + class CV_EXPORTS ScaleLayer : public Layer + { + public: + bool hasBias; + int axis; + + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS ShiftLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS PriorBoxLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS ReorgLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS RegionLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS DetectionOutputLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + /** + * @brief \f$ L_p \f$ - normalization layer. + * @param p Normalization factor. The most common `p = 1` for \f$ L_1 \f$ - + * normalization or `p = 2` for \f$ L_2 \f$ - normalization or a custom one. + * @param eps Parameter \f$ \epsilon \f$ to prevent a division by zero. + * @param across_spatial If true, normalize an input across all non-batch dimensions. + * Otherwise normalize an every channel separately. + * + * Across spatial: + * @f[ + * norm = \sqrt[p]{\epsilon + \sum_{x, y, c} |src(x, y, c)|^p } \\ + * dst(x, y, c) = \frac{ src(x, y, c) }{norm} + * @f] + * + * Channel wise normalization: + * @f[ + * norm(c) = \sqrt[p]{\epsilon + \sum_{x, y} |src(x, y, c)|^p } \\ + * dst(x, y, c) = \frac{ src(x, y, c) }{norm(c)} + * @f] + * + * Where `x, y` - spatial coordinates, `c` - channel. + * + * An every sample in the batch is normalized separately. Optionally, + * output is scaled by the trained parameters. + */ + class CV_EXPORTS NormalizeBBoxLayer : public Layer + { + public: + float pnorm, epsilon; + CV_DEPRECATED_EXTERNAL bool acrossSpatial; + + static Ptr create(const LayerParams& params); + }; + + /** + * @brief Resize input 4-dimensional blob by nearest neighbor or bilinear strategy. + * + * Layer is used to support TensorFlow's resize_nearest_neighbor and resize_bilinear ops. + */ + class CV_EXPORTS ResizeLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + /** + * @brief Bilinear resize layer from https://github.com/cdmh/deeplab-public-ver2 + * + * It differs from @ref ResizeLayer in output shape and resize scales computations. + */ + class CV_EXPORTS InterpLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS ProposalLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + + class CV_EXPORTS CropAndResizeLayer : public Layer + { + public: + static Ptr create(const LayerParams& params); + }; + +//! @} +//! @} +CV__DNN_INLINE_NS_END +} +} +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/dict.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/dict.hpp new file mode 100755 index 0000000..463d314 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/dict.hpp @@ -0,0 +1,160 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include +#include +#include + +#include + +#ifndef OPENCV_DNN_DNN_DICT_HPP +#define OPENCV_DNN_DNN_DICT_HPP + +namespace cv { +namespace dnn { +CV__DNN_INLINE_NS_BEGIN +//! @addtogroup dnn +//! @{ + +/** @brief This struct stores the scalar value (or array) of one of the following type: double, cv::String or int64. + * @todo Maybe int64 is useless because double type exactly stores at least 2^52 integers. + */ +struct CV_EXPORTS_W DictValue +{ + DictValue(const DictValue &r); + DictValue(bool i) : type(Param::INT), pi(new AutoBuffer) { (*pi)[0] = i ? 1 : 0; } //!< Constructs integer scalar + DictValue(int64 i = 0) : type(Param::INT), pi(new AutoBuffer) { (*pi)[0] = i; } //!< Constructs integer scalar + CV_WRAP DictValue(int i) : type(Param::INT), pi(new AutoBuffer) { (*pi)[0] = i; } //!< Constructs integer scalar + DictValue(unsigned p) : type(Param::INT), pi(new AutoBuffer) { (*pi)[0] = p; } //!< Constructs integer scalar + CV_WRAP DictValue(double p) : type(Param::REAL), pd(new AutoBuffer) { (*pd)[0] = p; } //!< Constructs floating point scalar + CV_WRAP DictValue(const String &s) : type(Param::STRING), ps(new AutoBuffer) { (*ps)[0] = s; } //!< Constructs string scalar + DictValue(const char *s) : type(Param::STRING), ps(new AutoBuffer) { (*ps)[0] = s; } //!< @overload + + template + static DictValue arrayInt(TypeIter begin, int size); //!< Constructs integer array + template + static DictValue arrayReal(TypeIter begin, int size); //!< Constructs floating point array + template + static DictValue arrayString(TypeIter begin, int size); //!< Constructs array of strings + + template + T get(int idx = -1) const; //!< Tries to convert array element with specified index to requested type and returns its. + + int size() const; + + CV_WRAP bool isInt() const; + CV_WRAP bool isString() const; + CV_WRAP bool isReal() const; + + CV_WRAP int getIntValue(int idx = -1) const; + CV_WRAP double getRealValue(int idx = -1) const; + CV_WRAP String getStringValue(int idx = -1) const; + + DictValue &operator=(const DictValue &r); + + friend std::ostream &operator<<(std::ostream &stream, const DictValue &dictv); + + ~DictValue(); + +private: + + Param type; + + union + { + AutoBuffer *pi; + AutoBuffer *pd; + AutoBuffer *ps; + void *pv; + }; + + DictValue(Param _type, void *_p) : type(_type), pv(_p) {} + void release(); +}; + +/** @brief This class implements name-value dictionary, values are instances of DictValue. */ +class CV_EXPORTS Dict +{ + typedef std::map _Dict; + _Dict dict; + +public: + + //! Checks a presence of the @p key in the dictionary. + bool has(const String &key) const; + + //! If the @p key in the dictionary then returns pointer to its value, else returns NULL. + DictValue *ptr(const String &key); + + /** @overload */ + const DictValue *ptr(const String &key) const; + + //! If the @p key in the dictionary then returns its value, else an error will be generated. + const DictValue &get(const String &key) const; + + /** @overload */ + template + T get(const String &key) const; + + //! If the @p key in the dictionary then returns its value, else returns @p defaultValue. + template + T get(const String &key, const T &defaultValue) const; + + //! Sets new @p value for the @p key, or adds new key-value pair into the dictionary. + template + const T &set(const String &key, const T &value); + + //! Erase @p key from the dictionary. + void erase(const String &key); + + friend std::ostream &operator<<(std::ostream &stream, const Dict &dict); + + std::map::const_iterator begin() const; + + std::map::const_iterator end() const; +}; + +//! @} +CV__DNN_INLINE_NS_END +} +} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.hpp new file mode 100755 index 0000000..9bc017c --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.hpp @@ -0,0 +1,1006 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_DNN_DNN_HPP +#define OPENCV_DNN_DNN_HPP + +#include +#include +#include "opencv2/core/async.hpp" + +#include "../dnn/version.hpp" + +#include + +namespace cv { +namespace dnn { +CV__DNN_INLINE_NS_BEGIN +//! @addtogroup dnn +//! @{ + + typedef std::vector MatShape; + + /** + * @brief Enum of computation backends supported by layers. + * @see Net::setPreferableBackend + */ + enum Backend + { + //! DNN_BACKEND_DEFAULT equals to DNN_BACKEND_INFERENCE_ENGINE if + //! OpenCV is built with Intel's Inference Engine library or + //! DNN_BACKEND_OPENCV otherwise. + DNN_BACKEND_DEFAULT, + DNN_BACKEND_HALIDE, + DNN_BACKEND_INFERENCE_ENGINE, //!< Intel's Inference Engine computational backend. + DNN_BACKEND_OPENCV, + DNN_BACKEND_VKCOM + }; + + /** + * @brief Enum of target devices for computations. + * @see Net::setPreferableTarget + */ + enum Target + { + DNN_TARGET_CPU, + DNN_TARGET_OPENCL, + DNN_TARGET_OPENCL_FP16, + DNN_TARGET_MYRIAD, + DNN_TARGET_VULKAN, + DNN_TARGET_FPGA //!< FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin. + }; + + CV_EXPORTS std::vector< std::pair > getAvailableBackends(); + CV_EXPORTS std::vector getAvailableTargets(Backend be); + + /** @brief This class provides all data needed to initialize layer. + * + * It includes dictionary with scalar params (which can be read by using Dict interface), + * blob params #blobs and optional meta information: #name and #type of layer instance. + */ + class CV_EXPORTS LayerParams : public Dict + { + public: + //TODO: Add ability to name blob params + std::vector blobs; //!< List of learned parameters stored as blobs. + + String name; //!< Name of the layer instance (optional, can be used internal purposes). + String type; //!< Type name which was used for creating layer by layer factory (optional). + }; + + /** + * @brief Derivatives of this class encapsulates functions of certain backends. + */ + class BackendNode + { + public: + BackendNode(int backendId); + + virtual ~BackendNode(); //!< Virtual destructor to make polymorphism. + + int backendId; //!< Backend identifier. + }; + + /** + * @brief Derivatives of this class wraps cv::Mat for different backends and targets. + */ + class BackendWrapper + { + public: + BackendWrapper(int backendId, int targetId); + + /** + * @brief Wrap cv::Mat for specific backend and target. + * @param[in] targetId Target identifier. + * @param[in] m cv::Mat for wrapping. + * + * Make CPU->GPU data transfer if it's require for the target. + */ + BackendWrapper(int targetId, const cv::Mat& m); + + /** + * @brief Make wrapper for reused cv::Mat. + * @param[in] base Wrapper of cv::Mat that will be reused. + * @param[in] shape Specific shape. + * + * Initialize wrapper from another one. It'll wrap the same host CPU + * memory and mustn't allocate memory on device(i.e. GPU). It might + * has different shape. Use in case of CPU memory reusing for reuse + * associated memory on device too. + */ + BackendWrapper(const Ptr& base, const MatShape& shape); + + virtual ~BackendWrapper(); //!< Virtual destructor to make polymorphism. + + /** + * @brief Transfer data to CPU host memory. + */ + virtual void copyToHost() = 0; + + /** + * @brief Indicate that an actual data is on CPU. + */ + virtual void setHostDirty() = 0; + + int backendId; //!< Backend identifier. + int targetId; //!< Target identifier. + }; + + class CV_EXPORTS ActivationLayer; + + /** @brief This interface class allows to build new Layers - are building blocks of networks. + * + * Each class, derived from Layer, must implement allocate() methods to declare own outputs and forward() to compute outputs. + * Also before using the new layer into networks you must register your layer by using one of @ref dnnLayerFactory "LayerFactory" macros. + */ + class CV_EXPORTS_W Layer : public Algorithm + { + public: + + //! List of learned parameters must be stored here to allow read them by using Net::getParam(). + CV_PROP_RW std::vector blobs; + + /** @brief Computes and sets internal parameters according to inputs, outputs and blobs. + * @deprecated Use Layer::finalize(InputArrayOfArrays, OutputArrayOfArrays) instead + * @param[in] input vector of already allocated input blobs + * @param[out] output vector of already allocated output blobs + * + * If this method is called after network has allocated all memory for input and output blobs + * and before inferencing. + */ + CV_DEPRECATED_EXTERNAL + virtual void finalize(const std::vector &input, std::vector &output); + + /** @brief Computes and sets internal parameters according to inputs, outputs and blobs. + * @param[in] inputs vector of already allocated input blobs + * @param[out] outputs vector of already allocated output blobs + * + * If this method is called after network has allocated all memory for input and output blobs + * and before inferencing. + */ + CV_WRAP virtual void finalize(InputArrayOfArrays inputs, OutputArrayOfArrays outputs); + + /** @brief Given the @p input blobs, computes the output @p blobs. + * @deprecated Use Layer::forward(InputArrayOfArrays, OutputArrayOfArrays, OutputArrayOfArrays) instead + * @param[in] input the input blobs. + * @param[out] output allocated output blobs, which will store results of the computation. + * @param[out] internals allocated internal blobs + */ + CV_DEPRECATED_EXTERNAL + virtual void forward(std::vector &input, std::vector &output, std::vector &internals); + + /** @brief Given the @p input blobs, computes the output @p blobs. + * @param[in] inputs the input blobs. + * @param[out] outputs allocated output blobs, which will store results of the computation. + * @param[out] internals allocated internal blobs + */ + virtual void forward(InputArrayOfArrays inputs, OutputArrayOfArrays outputs, OutputArrayOfArrays internals); + + /** @brief Given the @p input blobs, computes the output @p blobs. + * @param[in] inputs the input blobs. + * @param[out] outputs allocated output blobs, which will store results of the computation. + * @param[out] internals allocated internal blobs + */ + void forward_fallback(InputArrayOfArrays inputs, OutputArrayOfArrays outputs, OutputArrayOfArrays internals); + + /** @brief + * @overload + * @deprecated Use Layer::finalize(InputArrayOfArrays, OutputArrayOfArrays) instead + */ + CV_DEPRECATED_EXTERNAL + void finalize(const std::vector &inputs, CV_OUT std::vector &outputs); + + /** @brief + * @overload + * @deprecated Use Layer::finalize(InputArrayOfArrays, OutputArrayOfArrays) instead + */ + CV_DEPRECATED std::vector finalize(const std::vector &inputs); + + /** @brief Allocates layer and computes output. + * @deprecated This method will be removed in the future release. + */ + CV_DEPRECATED CV_WRAP void run(const std::vector &inputs, CV_OUT std::vector &outputs, + CV_IN_OUT std::vector &internals); + + /** @brief Returns index of input blob into the input array. + * @param inputName label of input blob + * + * Each layer input and output can be labeled to easily identify them using "%[.output_name]" notation. + * This method maps label of input blob to its index into input vector. + */ + virtual int inputNameToIndex(String inputName); + /** @brief Returns index of output blob in output array. + * @see inputNameToIndex() + */ + CV_WRAP virtual int outputNameToIndex(const String& outputName); + + /** + * @brief Ask layer if it support specific backend for doing computations. + * @param[in] backendId computation backend identifier. + * @see Backend + */ + virtual bool supportBackend(int backendId); + + /** + * @brief Returns Halide backend node. + * @param[in] inputs Input Halide buffers. + * @see BackendNode, BackendWrapper + * + * Input buffers should be exactly the same that will be used in forward invocations. + * Despite we can use Halide::ImageParam based on input shape only, + * it helps prevent some memory management issues (if something wrong, + * Halide tests will be failed). + */ + virtual Ptr initHalide(const std::vector > &inputs); + + virtual Ptr initInfEngine(const std::vector > &inputs); + + virtual Ptr initVkCom(const std::vector > &inputs); + /** + * @brief Automatic Halide scheduling based on layer hyper-parameters. + * @param[in] node Backend node with Halide functions. + * @param[in] inputs Blobs that will be used in forward invocations. + * @param[in] outputs Blobs that will be used in forward invocations. + * @param[in] targetId Target identifier + * @see BackendNode, Target + * + * Layer don't use own Halide::Func members because we can have applied + * layers fusing. In this way the fused function should be scheduled. + */ + virtual void applyHalideScheduler(Ptr& node, + const std::vector &inputs, + const std::vector &outputs, + int targetId) const; + + /** + * @brief Implement layers fusing. + * @param[in] node Backend node of bottom layer. + * @see BackendNode + * + * Actual for graph-based backends. If layer attached successfully, + * returns non-empty cv::Ptr to node of the same backend. + * Fuse only over the last function. + */ + virtual Ptr tryAttach(const Ptr& node); + + /** + * @brief Tries to attach to the layer the subsequent activation layer, i.e. do the layer fusion in a partial case. + * @param[in] layer The subsequent activation layer. + * + * Returns true if the activation layer has been attached successfully. + */ + virtual bool setActivation(const Ptr& layer); + + /** + * @brief Try to fuse current layer with a next one + * @param[in] top Next layer to be fused. + * @returns True if fusion was performed. + */ + virtual bool tryFuse(Ptr& top); + + /** + * @brief Returns parameters of layers with channel-wise multiplication and addition. + * @param[out] scale Channel-wise multipliers. Total number of values should + * be equal to number of channels. + * @param[out] shift Channel-wise offsets. Total number of values should + * be equal to number of channels. + * + * Some layers can fuse their transformations with further layers. + * In example, convolution + batch normalization. This way base layer + * use weights from layer after it. Fused layer is skipped. + * By default, @p scale and @p shift are empty that means layer has no + * element-wise multiplications or additions. + */ + virtual void getScaleShift(Mat& scale, Mat& shift) const; + + /** + * @brief "Deattaches" all the layers, attached to particular layer. + */ + virtual void unsetAttached(); + + virtual bool getMemoryShapes(const std::vector &inputs, + const int requiredOutputs, + std::vector &outputs, + std::vector &internals) const; + virtual int64 getFLOPS(const std::vector &inputs, + const std::vector &outputs) const {CV_UNUSED(inputs); CV_UNUSED(outputs); return 0;} + + CV_PROP String name; //!< Name of the layer instance, can be used for logging or other internal purposes. + CV_PROP String type; //!< Type name which was used for creating layer by layer factory. + CV_PROP int preferableTarget; //!< prefer target for layer forwarding + + Layer(); + explicit Layer(const LayerParams ¶ms); //!< Initializes only #name, #type and #blobs fields. + void setParamsFrom(const LayerParams ¶ms); //!< Initializes only #name, #type and #blobs fields. + virtual ~Layer(); + }; + + /** @brief This class allows to create and manipulate comprehensive artificial neural networks. + * + * Neural network is presented as directed acyclic graph (DAG), where vertices are Layer instances, + * and edges specify relationships between layers inputs and outputs. + * + * Each network layer has unique integer id and unique string name inside its network. + * LayerId can store either layer name or layer id. + * + * This class supports reference counting of its instances, i. e. copies point to the same instance. + */ + class CV_EXPORTS_W_SIMPLE Net + { + public: + + CV_WRAP Net(); //!< Default constructor. + CV_WRAP ~Net(); //!< Destructor frees the net only if there aren't references to the net anymore. + + /** @brief Create a network from Intel's Model Optimizer intermediate representation. + * @param[in] xml XML configuration file with network's topology. + * @param[in] bin Binary file with trained weights. + * Networks imported from Intel's Model Optimizer are launched in Intel's Inference Engine + * backend. + */ + CV_WRAP static Net readFromModelOptimizer(const String& xml, const String& bin); + + /** Returns true if there are no layers in the network. */ + CV_WRAP bool empty() const; + + /** @brief Dump net to String + * @returns String with structure, hyperparameters, backend, target and fusion + * To see correct backend, target and fusion run after forward(). + */ + CV_WRAP String dump(); + /** @brief Dump net structure, hyperparameters, backend, target and fusion to dot file + * @param path path to output file with .dot extension + * @see dump() + */ + CV_WRAP void dumpToFile(const String& path); + /** @brief Adds new layer to the net. + * @param name unique name of the adding layer. + * @param type typename of the adding layer (type must be registered in LayerRegister). + * @param params parameters which will be used to initialize the creating layer. + * @returns unique identifier of created layer, or -1 if a failure will happen. + */ + int addLayer(const String &name, const String &type, LayerParams ¶ms); + /** @brief Adds new layer and connects its first input to the first output of previously added layer. + * @see addLayer() + */ + int addLayerToPrev(const String &name, const String &type, LayerParams ¶ms); + + /** @brief Converts string name of the layer to the integer identifier. + * @returns id of the layer, or -1 if the layer wasn't found. + */ + CV_WRAP int getLayerId(const String &layer); + + CV_WRAP std::vector getLayerNames() const; + + /** @brief Container for strings and integers. */ + typedef DictValue LayerId; + + /** @brief Returns pointer to layer with specified id or name which the network use. */ + CV_WRAP Ptr getLayer(LayerId layerId); + + /** @brief Returns pointers to input layers of specific layer. */ + std::vector > getLayerInputs(LayerId layerId); // FIXIT: CV_WRAP + + /** @brief Connects output of the first layer to input of the second layer. + * @param outPin descriptor of the first layer output. + * @param inpPin descriptor of the second layer input. + * + * Descriptors have the following template <layer_name>[.input_number]: + * - the first part of the template layer_name is sting name of the added layer. + * If this part is empty then the network input pseudo layer will be used; + * - the second optional part of the template input_number + * is either number of the layer input, either label one. + * If this part is omitted then the first layer input will be used. + * + * @see setNetInputs(), Layer::inputNameToIndex(), Layer::outputNameToIndex() + */ + CV_WRAP void connect(String outPin, String inpPin); + + /** @brief Connects #@p outNum output of the first layer to #@p inNum input of the second layer. + * @param outLayerId identifier of the first layer + * @param outNum number of the first layer output + * @param inpLayerId identifier of the second layer + * @param inpNum number of the second layer input + */ + void connect(int outLayerId, int outNum, int inpLayerId, int inpNum); + + /** @brief Sets outputs names of the network input pseudo layer. + * + * Each net always has special own the network input pseudo layer with id=0. + * This layer stores the user blobs only and don't make any computations. + * In fact, this layer provides the only way to pass user data into the network. + * As any other layer, this layer can label its outputs and this function provides an easy way to do this. + */ + CV_WRAP void setInputsNames(const std::vector &inputBlobNames); + + /** @brief Runs forward pass to compute output of layer with name @p outputName. + * @param outputName name for layer which output is needed to get + * @return blob for first output of specified layer. + * @details By default runs forward pass for the whole network. + */ + CV_WRAP Mat forward(const String& outputName = String()); + + /** @brief Runs forward pass to compute output of layer with name @p outputName. + * @param outputName name for layer which output is needed to get + * @details By default runs forward pass for the whole network. + * + * This is an asynchronous version of forward(const String&). + * dnn::DNN_BACKEND_INFERENCE_ENGINE backend is required. + */ + CV_WRAP AsyncArray forwardAsync(const String& outputName = String()); + + /** @brief Runs forward pass to compute output of layer with name @p outputName. + * @param outputBlobs contains all output blobs for specified layer. + * @param outputName name for layer which output is needed to get + * @details If @p outputName is empty, runs forward pass for the whole network. + */ + CV_WRAP void forward(OutputArrayOfArrays outputBlobs, const String& outputName = String()); + + /** @brief Runs forward pass to compute outputs of layers listed in @p outBlobNames. + * @param outputBlobs contains blobs for first outputs of specified layers. + * @param outBlobNames names for layers which outputs are needed to get + */ + CV_WRAP void forward(OutputArrayOfArrays outputBlobs, + const std::vector& outBlobNames); + + /** @brief Runs forward pass to compute outputs of layers listed in @p outBlobNames. + * @param outputBlobs contains all output blobs for each layer specified in @p outBlobNames. + * @param outBlobNames names for layers which outputs are needed to get + */ + CV_WRAP_AS(forwardAndRetrieve) void forward(CV_OUT std::vector >& outputBlobs, + const std::vector& outBlobNames); + + /** + * @brief Compile Halide layers. + * @param[in] scheduler Path to YAML file with scheduling directives. + * @see setPreferableBackend + * + * Schedule layers that support Halide backend. Then compile them for + * specific target. For layers that not represented in scheduling file + * or if no manual scheduling used at all, automatic scheduling will be applied. + */ + CV_WRAP void setHalideScheduler(const String& scheduler); + + /** + * @brief Ask network to use specific computation backend where it supported. + * @param[in] backendId backend identifier. + * @see Backend + * + * If OpenCV is compiled with Intel's Inference Engine library, DNN_BACKEND_DEFAULT + * means DNN_BACKEND_INFERENCE_ENGINE. Otherwise it equals to DNN_BACKEND_OPENCV. + */ + CV_WRAP void setPreferableBackend(int backendId); + + /** + * @brief Ask network to make computations on specific target device. + * @param[in] targetId target identifier. + * @see Target + * + * List of supported combinations backend / target: + * | | DNN_BACKEND_OPENCV | DNN_BACKEND_INFERENCE_ENGINE | DNN_BACKEND_HALIDE | + * |------------------------|--------------------|------------------------------|--------------------| + * | DNN_TARGET_CPU | + | + | + | + * | DNN_TARGET_OPENCL | + | + | + | + * | DNN_TARGET_OPENCL_FP16 | + | + | | + * | DNN_TARGET_MYRIAD | | + | | + * | DNN_TARGET_FPGA | | + | | + */ + CV_WRAP void setPreferableTarget(int targetId); + + /** @brief Sets the new input value for the network + * @param blob A new blob. Should have CV_32F or CV_8U depth. + * @param name A name of input layer. + * @param scalefactor An optional normalization scale. + * @param mean An optional mean subtraction values. + * @see connect(String, String) to know format of the descriptor. + * + * If scale or mean values are specified, a final input blob is computed + * as: + * \f[input(n,c,h,w) = scalefactor \times (blob(n,c,h,w) - mean_c)\f] + */ + CV_WRAP void setInput(InputArray blob, const String& name = "", + double scalefactor = 1.0, const Scalar& mean = Scalar()); + + /** @brief Sets the new value for the learned param of the layer. + * @param layer name or id of the layer. + * @param numParam index of the layer parameter in the Layer::blobs array. + * @param blob the new value. + * @see Layer::blobs + * @note If shape of the new blob differs from the previous shape, + * then the following forward pass may fail. + */ + CV_WRAP void setParam(LayerId layer, int numParam, const Mat &blob); + + /** @brief Returns parameter blob of the layer. + * @param layer name or id of the layer. + * @param numParam index of the layer parameter in the Layer::blobs array. + * @see Layer::blobs + */ + CV_WRAP Mat getParam(LayerId layer, int numParam = 0); + + /** @brief Returns indexes of layers with unconnected outputs. + */ + CV_WRAP std::vector getUnconnectedOutLayers() const; + + /** @brief Returns names of layers with unconnected outputs. + */ + CV_WRAP std::vector getUnconnectedOutLayersNames() const; + + /** @brief Returns input and output shapes for all layers in loaded model; + * preliminary inferencing isn't necessary. + * @param netInputShapes shapes for all input blobs in net input layer. + * @param layersIds output parameter for layer IDs. + * @param inLayersShapes output parameter for input layers shapes; + * order is the same as in layersIds + * @param outLayersShapes output parameter for output layers shapes; + * order is the same as in layersIds + */ + CV_WRAP void getLayersShapes(const std::vector& netInputShapes, + CV_OUT std::vector& layersIds, + CV_OUT std::vector >& inLayersShapes, + CV_OUT std::vector >& outLayersShapes) const; + + /** @overload */ + CV_WRAP void getLayersShapes(const MatShape& netInputShape, + CV_OUT std::vector& layersIds, + CV_OUT std::vector >& inLayersShapes, + CV_OUT std::vector >& outLayersShapes) const; + + /** @brief Returns input and output shapes for layer with specified + * id in loaded model; preliminary inferencing isn't necessary. + * @param netInputShape shape input blob in net input layer. + * @param layerId id for layer. + * @param inLayerShapes output parameter for input layers shapes; + * order is the same as in layersIds + * @param outLayerShapes output parameter for output layers shapes; + * order is the same as in layersIds + */ + void getLayerShapes(const MatShape& netInputShape, + const int layerId, + CV_OUT std::vector& inLayerShapes, + CV_OUT std::vector& outLayerShapes) const; // FIXIT: CV_WRAP + + /** @overload */ + void getLayerShapes(const std::vector& netInputShapes, + const int layerId, + CV_OUT std::vector& inLayerShapes, + CV_OUT std::vector& outLayerShapes) const; // FIXIT: CV_WRAP + + /** @brief Computes FLOP for whole loaded model with specified input shapes. + * @param netInputShapes vector of shapes for all net inputs. + * @returns computed FLOP. + */ + CV_WRAP int64 getFLOPS(const std::vector& netInputShapes) const; + /** @overload */ + CV_WRAP int64 getFLOPS(const MatShape& netInputShape) const; + /** @overload */ + CV_WRAP int64 getFLOPS(const int layerId, + const std::vector& netInputShapes) const; + /** @overload */ + CV_WRAP int64 getFLOPS(const int layerId, + const MatShape& netInputShape) const; + + /** @brief Returns list of types for layer used in model. + * @param layersTypes output parameter for returning types. + */ + CV_WRAP void getLayerTypes(CV_OUT std::vector& layersTypes) const; + + /** @brief Returns count of layers of specified type. + * @param layerType type. + * @returns count of layers + */ + CV_WRAP int getLayersCount(const String& layerType) const; + + /** @brief Computes bytes number which are required to store + * all weights and intermediate blobs for model. + * @param netInputShapes vector of shapes for all net inputs. + * @param weights output parameter to store resulting bytes for weights. + * @param blobs output parameter to store resulting bytes for intermediate blobs. + */ + void getMemoryConsumption(const std::vector& netInputShapes, + CV_OUT size_t& weights, CV_OUT size_t& blobs) const; // FIXIT: CV_WRAP + /** @overload */ + CV_WRAP void getMemoryConsumption(const MatShape& netInputShape, + CV_OUT size_t& weights, CV_OUT size_t& blobs) const; + /** @overload */ + CV_WRAP void getMemoryConsumption(const int layerId, + const std::vector& netInputShapes, + CV_OUT size_t& weights, CV_OUT size_t& blobs) const; + /** @overload */ + CV_WRAP void getMemoryConsumption(const int layerId, + const MatShape& netInputShape, + CV_OUT size_t& weights, CV_OUT size_t& blobs) const; + + /** @brief Computes bytes number which are required to store + * all weights and intermediate blobs for each layer. + * @param netInputShapes vector of shapes for all net inputs. + * @param layerIds output vector to save layer IDs. + * @param weights output parameter to store resulting bytes for weights. + * @param blobs output parameter to store resulting bytes for intermediate blobs. + */ + void getMemoryConsumption(const std::vector& netInputShapes, + CV_OUT std::vector& layerIds, + CV_OUT std::vector& weights, + CV_OUT std::vector& blobs) const; // FIXIT: CV_WRAP + /** @overload */ + void getMemoryConsumption(const MatShape& netInputShape, + CV_OUT std::vector& layerIds, + CV_OUT std::vector& weights, + CV_OUT std::vector& blobs) const; // FIXIT: CV_WRAP + + /** @brief Enables or disables layer fusion in the network. + * @param fusion true to enable the fusion, false to disable. The fusion is enabled by default. + */ + CV_WRAP void enableFusion(bool fusion); + + /** @brief Returns overall time for inference and timings (in ticks) for layers. + * Indexes in returned vector correspond to layers ids. Some layers can be fused with others, + * in this case zero ticks count will be return for that skipped layers. + * @param timings vector for tick timings for all layers. + * @return overall ticks for model inference. + */ + CV_WRAP int64 getPerfProfile(CV_OUT std::vector& timings); + + private: + struct Impl; + Ptr impl; + }; + + /** @brief Reads a network model stored in Darknet model files. + * @param cfgFile path to the .cfg file with text description of the network architecture. + * @param darknetModel path to the .weights file with learned network. + * @returns Network object that ready to do forward, throw an exception in failure cases. + * @returns Net object. + */ + CV_EXPORTS_W Net readNetFromDarknet(const String &cfgFile, const String &darknetModel = String()); + + /** @brief Reads a network model stored in Darknet model files. + * @param bufferCfg A buffer contains a content of .cfg file with text description of the network architecture. + * @param bufferModel A buffer contains a content of .weights file with learned network. + * @returns Net object. + */ + CV_EXPORTS_W Net readNetFromDarknet(const std::vector& bufferCfg, + const std::vector& bufferModel = std::vector()); + + /** @brief Reads a network model stored in Darknet model files. + * @param bufferCfg A buffer contains a content of .cfg file with text description of the network architecture. + * @param lenCfg Number of bytes to read from bufferCfg + * @param bufferModel A buffer contains a content of .weights file with learned network. + * @param lenModel Number of bytes to read from bufferModel + * @returns Net object. + */ + CV_EXPORTS Net readNetFromDarknet(const char *bufferCfg, size_t lenCfg, + const char *bufferModel = NULL, size_t lenModel = 0); + + /** @brief Reads a network model stored in Caffe framework's format. + * @param prototxt path to the .prototxt file with text description of the network architecture. + * @param caffeModel path to the .caffemodel file with learned network. + * @returns Net object. + */ + CV_EXPORTS_W Net readNetFromCaffe(const String &prototxt, const String &caffeModel = String()); + + /** @brief Reads a network model stored in Caffe model in memory. + * @param bufferProto buffer containing the content of the .prototxt file + * @param bufferModel buffer containing the content of the .caffemodel file + * @returns Net object. + */ + CV_EXPORTS_W Net readNetFromCaffe(const std::vector& bufferProto, + const std::vector& bufferModel = std::vector()); + + /** @brief Reads a network model stored in Caffe model in memory. + * @details This is an overloaded member function, provided for convenience. + * It differs from the above function only in what argument(s) it accepts. + * @param bufferProto buffer containing the content of the .prototxt file + * @param lenProto length of bufferProto + * @param bufferModel buffer containing the content of the .caffemodel file + * @param lenModel length of bufferModel + * @returns Net object. + */ + CV_EXPORTS Net readNetFromCaffe(const char *bufferProto, size_t lenProto, + const char *bufferModel = NULL, size_t lenModel = 0); + + /** @brief Reads a network model stored in TensorFlow framework's format. + * @param model path to the .pb file with binary protobuf description of the network architecture + * @param config path to the .pbtxt file that contains text graph definition in protobuf format. + * Resulting Net object is built by text graph using weights from a binary one that + * let us make it more flexible. + * @returns Net object. + */ + CV_EXPORTS_W Net readNetFromTensorflow(const String &model, const String &config = String()); + + /** @brief Reads a network model stored in TensorFlow framework's format. + * @param bufferModel buffer containing the content of the pb file + * @param bufferConfig buffer containing the content of the pbtxt file + * @returns Net object. + */ + CV_EXPORTS_W Net readNetFromTensorflow(const std::vector& bufferModel, + const std::vector& bufferConfig = std::vector()); + + /** @brief Reads a network model stored in TensorFlow framework's format. + * @details This is an overloaded member function, provided for convenience. + * It differs from the above function only in what argument(s) it accepts. + * @param bufferModel buffer containing the content of the pb file + * @param lenModel length of bufferModel + * @param bufferConfig buffer containing the content of the pbtxt file + * @param lenConfig length of bufferConfig + */ + CV_EXPORTS Net readNetFromTensorflow(const char *bufferModel, size_t lenModel, + const char *bufferConfig = NULL, size_t lenConfig = 0); + + /** + * @brief Reads a network model stored in Torch7 framework's format. + * @param model path to the file, dumped from Torch by using torch.save() function. + * @param isBinary specifies whether the network was serialized in ascii mode or binary. + * @param evaluate specifies testing phase of network. If true, it's similar to evaluate() method in Torch. + * @returns Net object. + * + * @note Ascii mode of Torch serializer is more preferable, because binary mode extensively use `long` type of C language, + * which has various bit-length on different systems. + * + * The loading file must contain serialized nn.Module object + * with importing network. Try to eliminate a custom objects from serialazing data to avoid importing errors. + * + * List of supported layers (i.e. object instances derived from Torch nn.Module class): + * - nn.Sequential + * - nn.Parallel + * - nn.Concat + * - nn.Linear + * - nn.SpatialConvolution + * - nn.SpatialMaxPooling, nn.SpatialAveragePooling + * - nn.ReLU, nn.TanH, nn.Sigmoid + * - nn.Reshape + * - nn.SoftMax, nn.LogSoftMax + * + * Also some equivalents of these classes from cunn, cudnn, and fbcunn may be successfully imported. + */ + CV_EXPORTS_W Net readNetFromTorch(const String &model, bool isBinary = true, bool evaluate = true); + + /** + * @brief Read deep learning network represented in one of the supported formats. + * @param[in] model Binary file contains trained weights. The following file + * extensions are expected for models from different frameworks: + * * `*.caffemodel` (Caffe, http://caffe.berkeleyvision.org/) + * * `*.pb` (TensorFlow, https://www.tensorflow.org/) + * * `*.t7` | `*.net` (Torch, http://torch.ch/) + * * `*.weights` (Darknet, https://pjreddie.com/darknet/) + * * `*.bin` (DLDT, https://software.intel.com/openvino-toolkit) + * * `*.onnx` (ONNX, https://onnx.ai/) + * @param[in] config Text file contains network configuration. It could be a + * file with the following extensions: + * * `*.prototxt` (Caffe, http://caffe.berkeleyvision.org/) + * * `*.pbtxt` (TensorFlow, https://www.tensorflow.org/) + * * `*.cfg` (Darknet, https://pjreddie.com/darknet/) + * * `*.xml` (DLDT, https://software.intel.com/openvino-toolkit) + * @param[in] framework Explicit framework name tag to determine a format. + * @returns Net object. + * + * This function automatically detects an origin framework of trained model + * and calls an appropriate function such @ref readNetFromCaffe, @ref readNetFromTensorflow, + * @ref readNetFromTorch or @ref readNetFromDarknet. An order of @p model and @p config + * arguments does not matter. + */ + CV_EXPORTS_W Net readNet(const String& model, const String& config = "", const String& framework = ""); + + /** + * @brief Read deep learning network represented in one of the supported formats. + * @details This is an overloaded member function, provided for convenience. + * It differs from the above function only in what argument(s) it accepts. + * @param[in] framework Name of origin framework. + * @param[in] bufferModel A buffer with a content of binary file with weights + * @param[in] bufferConfig A buffer with a content of text file contains network configuration. + * @returns Net object. + */ + CV_EXPORTS_W Net readNet(const String& framework, const std::vector& bufferModel, + const std::vector& bufferConfig = std::vector()); + + /** @brief Loads blob which was serialized as torch.Tensor object of Torch7 framework. + * @warning This function has the same limitations as readNetFromTorch(). + */ + CV_EXPORTS_W Mat readTorchBlob(const String &filename, bool isBinary = true); + + /** @brief Load a network from Intel's Model Optimizer intermediate representation. + * @param[in] xml XML configuration file with network's topology. + * @param[in] bin Binary file with trained weights. + * @returns Net object. + * Networks imported from Intel's Model Optimizer are launched in Intel's Inference Engine + * backend. + */ + CV_EXPORTS_W Net readNetFromModelOptimizer(const String &xml, const String &bin); + + /** @brief Reads a network model ONNX. + * @param onnxFile path to the .onnx file with text description of the network architecture. + * @returns Network object that ready to do forward, throw an exception in failure cases. + */ + CV_EXPORTS_W Net readNetFromONNX(const String &onnxFile); + + /** @brief Reads a network model from ONNX + * in-memory buffer. + * @param buffer memory address of the first byte of the buffer. + * @param sizeBuffer size of the buffer. + * @returns Network object that ready to do forward, throw an exception + * in failure cases. + */ + CV_EXPORTS Net readNetFromONNX(const char* buffer, size_t sizeBuffer); + + /** @brief Reads a network model from ONNX + * in-memory buffer. + * @param buffer in-memory buffer that stores the ONNX model bytes. + * @returns Network object that ready to do forward, throw an exception + * in failure cases. + */ + CV_EXPORTS_W Net readNetFromONNX(const std::vector& buffer); + + /** @brief Creates blob from .pb file. + * @param path to the .pb file with input tensor. + * @returns Mat. + */ + CV_EXPORTS_W Mat readTensorFromONNX(const String& path); + + /** @brief Creates 4-dimensional blob from image. Optionally resizes and crops @p image from center, + * subtract @p mean values, scales values by @p scalefactor, swap Blue and Red channels. + * @param image input image (with 1-, 3- or 4-channels). + * @param size spatial size for output image + * @param mean scalar with mean values which are subtracted from channels. Values are intended + * to be in (mean-R, mean-G, mean-B) order if @p image has BGR ordering and @p swapRB is true. + * @param scalefactor multiplier for @p image values. + * @param swapRB flag which indicates that swap first and last channels + * in 3-channel image is necessary. + * @param crop flag which indicates whether image will be cropped after resize or not + * @param ddepth Depth of output blob. Choose CV_32F or CV_8U. + * @details if @p crop is true, input image is resized so one side after resize is equal to corresponding + * dimension in @p size and another one is equal or larger. Then, crop from the center is performed. + * If @p crop is false, direct resize without cropping and preserving aspect ratio is performed. + * @returns 4-dimensional Mat with NCHW dimensions order. + */ + CV_EXPORTS_W Mat blobFromImage(InputArray image, double scalefactor=1.0, const Size& size = Size(), + const Scalar& mean = Scalar(), bool swapRB=false, bool crop=false, + int ddepth=CV_32F); + + /** @brief Creates 4-dimensional blob from image. + * @details This is an overloaded member function, provided for convenience. + * It differs from the above function only in what argument(s) it accepts. + */ + CV_EXPORTS void blobFromImage(InputArray image, OutputArray blob, double scalefactor=1.0, + const Size& size = Size(), const Scalar& mean = Scalar(), + bool swapRB=false, bool crop=false, int ddepth=CV_32F); + + + /** @brief Creates 4-dimensional blob from series of images. Optionally resizes and + * crops @p images from center, subtract @p mean values, scales values by @p scalefactor, + * swap Blue and Red channels. + * @param images input images (all with 1-, 3- or 4-channels). + * @param size spatial size for output image + * @param mean scalar with mean values which are subtracted from channels. Values are intended + * to be in (mean-R, mean-G, mean-B) order if @p image has BGR ordering and @p swapRB is true. + * @param scalefactor multiplier for @p images values. + * @param swapRB flag which indicates that swap first and last channels + * in 3-channel image is necessary. + * @param crop flag which indicates whether image will be cropped after resize or not + * @param ddepth Depth of output blob. Choose CV_32F or CV_8U. + * @details if @p crop is true, input image is resized so one side after resize is equal to corresponding + * dimension in @p size and another one is equal or larger. Then, crop from the center is performed. + * If @p crop is false, direct resize without cropping and preserving aspect ratio is performed. + * @returns 4-dimensional Mat with NCHW dimensions order. + */ + CV_EXPORTS_W Mat blobFromImages(InputArrayOfArrays images, double scalefactor=1.0, + Size size = Size(), const Scalar& mean = Scalar(), bool swapRB=false, bool crop=false, + int ddepth=CV_32F); + + /** @brief Creates 4-dimensional blob from series of images. + * @details This is an overloaded member function, provided for convenience. + * It differs from the above function only in what argument(s) it accepts. + */ + CV_EXPORTS void blobFromImages(InputArrayOfArrays images, OutputArray blob, + double scalefactor=1.0, Size size = Size(), + const Scalar& mean = Scalar(), bool swapRB=false, bool crop=false, + int ddepth=CV_32F); + + /** @brief Parse a 4D blob and output the images it contains as 2D arrays through a simpler data structure + * (std::vector). + * @param[in] blob_ 4 dimensional array (images, channels, height, width) in floating point precision (CV_32F) from + * which you would like to extract the images. + * @param[out] images_ array of 2D Mat containing the images extracted from the blob in floating point precision + * (CV_32F). They are non normalized neither mean added. The number of returned images equals the first dimension + * of the blob (batch size). Every image has a number of channels equals to the second dimension of the blob (depth). + */ + CV_EXPORTS_W void imagesFromBlob(const cv::Mat& blob_, OutputArrayOfArrays images_); + + /** @brief Convert all weights of Caffe network to half precision floating point. + * @param src Path to origin model from Caffe framework contains single + * precision floating point weights (usually has `.caffemodel` extension). + * @param dst Path to destination model with updated weights. + * @param layersTypes Set of layers types which parameters will be converted. + * By default, converts only Convolutional and Fully-Connected layers' + * weights. + * + * @note Shrinked model has no origin float32 weights so it can't be used + * in origin Caffe framework anymore. However the structure of data + * is taken from NVidia's Caffe fork: https://github.com/NVIDIA/caffe. + * So the resulting model may be used there. + */ + CV_EXPORTS_W void shrinkCaffeModel(const String& src, const String& dst, + const std::vector& layersTypes = std::vector()); + + /** @brief Create a text representation for a binary network stored in protocol buffer format. + * @param[in] model A path to binary network. + * @param[in] output A path to output text file to be created. + * + * @note To reduce output file size, trained weights are not included. + */ + CV_EXPORTS_W void writeTextGraph(const String& model, const String& output); + + /** @brief Performs non maximum suppression given boxes and corresponding scores. + + * @param bboxes a set of bounding boxes to apply NMS. + * @param scores a set of corresponding confidences. + * @param score_threshold a threshold used to filter boxes by score. + * @param nms_threshold a threshold used in non maximum suppression. + * @param indices the kept indices of bboxes after NMS. + * @param eta a coefficient in adaptive threshold formula: \f$nms\_threshold_{i+1}=eta\cdot nms\_threshold_i\f$. + * @param top_k if `>0`, keep at most @p top_k picked indices. + */ + CV_EXPORTS_W void NMSBoxes(const std::vector& bboxes, const std::vector& scores, + const float score_threshold, const float nms_threshold, + CV_OUT std::vector& indices, + const float eta = 1.f, const int top_k = 0); + + CV_EXPORTS_W void NMSBoxes(const std::vector& bboxes, const std::vector& scores, + const float score_threshold, const float nms_threshold, + CV_OUT std::vector& indices, + const float eta = 1.f, const int top_k = 0); + + CV_EXPORTS_AS(NMSBoxesRotated) void NMSBoxes(const std::vector& bboxes, const std::vector& scores, + const float score_threshold, const float nms_threshold, + CV_OUT std::vector& indices, + const float eta = 1.f, const int top_k = 0); + +//! @} +CV__DNN_INLINE_NS_END +} +} + +#include +#include + +/// @deprecated Include this header directly from application. Automatic inclusion will be removed +#include + +#endif /* OPENCV_DNN_DNN_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.inl.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.inl.hpp new file mode 100755 index 0000000..d6809ce --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/dnn.inl.hpp @@ -0,0 +1,411 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_DNN_DNN_INL_HPP +#define OPENCV_DNN_DNN_INL_HPP + +#include + +namespace cv { +namespace dnn { +CV__DNN_INLINE_NS_BEGIN + +template +DictValue DictValue::arrayInt(TypeIter begin, int size) +{ + DictValue res(Param::INT, new AutoBuffer(size)); + for (int j = 0; j < size; begin++, j++) + (*res.pi)[j] = *begin; + return res; +} + +template +DictValue DictValue::arrayReal(TypeIter begin, int size) +{ + DictValue res(Param::REAL, new AutoBuffer(size)); + for (int j = 0; j < size; begin++, j++) + (*res.pd)[j] = *begin; + return res; +} + +template +DictValue DictValue::arrayString(TypeIter begin, int size) +{ + DictValue res(Param::STRING, new AutoBuffer(size)); + for (int j = 0; j < size; begin++, j++) + (*res.ps)[j] = *begin; + return res; +} + +template<> +inline DictValue DictValue::get(int idx) const +{ + CV_Assert(idx == -1); + return *this; +} + +template<> +inline int64 DictValue::get(int idx) const +{ + CV_Assert((idx == -1 && size() == 1) || (idx >= 0 && idx < size())); + idx = (idx == -1) ? 0 : idx; + + if (type == Param::INT) + { + return (*pi)[idx]; + } + else if (type == Param::REAL) + { + double doubleValue = (*pd)[idx]; + + double fracpart, intpart; + fracpart = std::modf(doubleValue, &intpart); + CV_Assert(fracpart == 0.0); + + return (int64)doubleValue; + } + else if (type == Param::STRING) + { + return std::atoi((*ps)[idx].c_str()); + } + else + { + CV_Assert(isInt() || isReal() || isString()); + return 0; + } +} + +template<> +inline int DictValue::get(int idx) const +{ + return (int)get(idx); +} + +inline int DictValue::getIntValue(int idx) const +{ + return (int)get(idx); +} + +template<> +inline unsigned DictValue::get(int idx) const +{ + return (unsigned)get(idx); +} + +template<> +inline bool DictValue::get(int idx) const +{ + return (get(idx) != 0); +} + +template<> +inline double DictValue::get(int idx) const +{ + CV_Assert((idx == -1 && size() == 1) || (idx >= 0 && idx < size())); + idx = (idx == -1) ? 0 : idx; + + if (type == Param::REAL) + { + return (*pd)[idx]; + } + else if (type == Param::INT) + { + return (double)(*pi)[idx]; + } + else if (type == Param::STRING) + { + return std::atof((*ps)[idx].c_str()); + } + else + { + CV_Assert(isReal() || isInt() || isString()); + return 0; + } +} + +inline double DictValue::getRealValue(int idx) const +{ + return get(idx); +} + +template<> +inline float DictValue::get(int idx) const +{ + return (float)get(idx); +} + +template<> +inline String DictValue::get(int idx) const +{ + CV_Assert(isString()); + CV_Assert((idx == -1 && ps->size() == 1) || (idx >= 0 && idx < (int)ps->size())); + return (*ps)[(idx == -1) ? 0 : idx]; +} + + +inline String DictValue::getStringValue(int idx) const +{ + return get(idx); +} + +inline void DictValue::release() +{ + switch (type) + { + case Param::INT: + delete pi; + break; + case Param::STRING: + delete ps; + break; + case Param::REAL: + delete pd; + break; + case Param::BOOLEAN: + case Param::MAT: + case Param::MAT_VECTOR: + case Param::ALGORITHM: + case Param::FLOAT: + case Param::UNSIGNED_INT: + case Param::UINT64: + case Param::UCHAR: + case Param::SCALAR: + break; // unhandled + } +} + +inline DictValue::~DictValue() +{ + release(); +} + +inline DictValue & DictValue::operator=(const DictValue &r) +{ + if (&r == this) + return *this; + + if (r.type == Param::INT) + { + AutoBuffer *tmp = new AutoBuffer(*r.pi); + release(); + pi = tmp; + } + else if (r.type == Param::STRING) + { + AutoBuffer *tmp = new AutoBuffer(*r.ps); + release(); + ps = tmp; + } + else if (r.type == Param::REAL) + { + AutoBuffer *tmp = new AutoBuffer(*r.pd); + release(); + pd = tmp; + } + + type = r.type; + + return *this; +} + +inline DictValue::DictValue(const DictValue &r) +{ + type = r.type; + + if (r.type == Param::INT) + pi = new AutoBuffer(*r.pi); + else if (r.type == Param::STRING) + ps = new AutoBuffer(*r.ps); + else if (r.type == Param::REAL) + pd = new AutoBuffer(*r.pd); +} + +inline bool DictValue::isString() const +{ + return (type == Param::STRING); +} + +inline bool DictValue::isInt() const +{ + return (type == Param::INT); +} + +inline bool DictValue::isReal() const +{ + return (type == Param::REAL || type == Param::INT); +} + +inline int DictValue::size() const +{ + switch (type) + { + case Param::INT: + return (int)pi->size(); + case Param::STRING: + return (int)ps->size(); + case Param::REAL: + return (int)pd->size(); + case Param::BOOLEAN: + case Param::MAT: + case Param::MAT_VECTOR: + case Param::ALGORITHM: + case Param::FLOAT: + case Param::UNSIGNED_INT: + case Param::UINT64: + case Param::UCHAR: + case Param::SCALAR: + break; // unhandled + } + CV_Error_(Error::StsInternal, ("Unhandled type (%d)", static_cast(type))); +} + +inline std::ostream &operator<<(std::ostream &stream, const DictValue &dictv) +{ + int i; + + if (dictv.isInt()) + { + for (i = 0; i < dictv.size() - 1; i++) + stream << dictv.get(i) << ", "; + stream << dictv.get(i); + } + else if (dictv.isReal()) + { + for (i = 0; i < dictv.size() - 1; i++) + stream << dictv.get(i) << ", "; + stream << dictv.get(i); + } + else if (dictv.isString()) + { + for (i = 0; i < dictv.size() - 1; i++) + stream << "\"" << dictv.get(i) << "\", "; + stream << dictv.get(i); + } + + return stream; +} + +///////////////////////////////////////////////////////////////// + +inline bool Dict::has(const String &key) const +{ + return dict.count(key) != 0; +} + +inline DictValue *Dict::ptr(const String &key) +{ + _Dict::iterator i = dict.find(key); + return (i == dict.end()) ? NULL : &i->second; +} + +inline const DictValue *Dict::ptr(const String &key) const +{ + _Dict::const_iterator i = dict.find(key); + return (i == dict.end()) ? NULL : &i->second; +} + +inline const DictValue &Dict::get(const String &key) const +{ + _Dict::const_iterator i = dict.find(key); + if (i == dict.end()) + CV_Error(Error::StsObjectNotFound, "Required argument \"" + key + "\" not found into dictionary"); + return i->second; +} + +template +inline T Dict::get(const String &key) const +{ + return this->get(key).get(); +} + +template +inline T Dict::get(const String &key, const T &defaultValue) const +{ + _Dict::const_iterator i = dict.find(key); + + if (i != dict.end()) + return i->second.get(); + else + return defaultValue; +} + +template +inline const T &Dict::set(const String &key, const T &value) +{ + _Dict::iterator i = dict.find(key); + + if (i != dict.end()) + i->second = DictValue(value); + else + dict.insert(std::make_pair(key, DictValue(value))); + + return value; +} + +inline void Dict::erase(const String &key) +{ + dict.erase(key); +} + +inline std::ostream &operator<<(std::ostream &stream, const Dict &dict) +{ + Dict::_Dict::const_iterator it; + for (it = dict.dict.begin(); it != dict.dict.end(); it++) + stream << it->first << " : " << it->second << "\n"; + + return stream; +} + +inline std::map::const_iterator Dict::begin() const +{ + return dict.begin(); +} + +inline std::map::const_iterator Dict::end() const +{ + return dict.end(); +} + +CV__DNN_INLINE_NS_END +} +} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/layer.details.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/layer.details.hpp new file mode 100755 index 0000000..1133da5 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/layer.details.hpp @@ -0,0 +1,78 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +#ifndef OPENCV_DNN_LAYER_DETAILS_HPP +#define OPENCV_DNN_LAYER_DETAILS_HPP + +#include + +namespace cv { +namespace dnn { +CV__DNN_INLINE_NS_BEGIN + +/** @brief Registers layer constructor in runtime. +* @param type string, containing type name of the layer. +* @param constructorFunc pointer to the function of type LayerRegister::Constructor, which creates the layer. +* @details This macros must be placed inside the function code. +*/ +#define CV_DNN_REGISTER_LAYER_FUNC(type, constructorFunc) \ + cv::dnn::LayerFactory::registerLayer(#type, constructorFunc); + +/** @brief Registers layer class in runtime. + * @param type string, containing type name of the layer. + * @param class C++ class, derived from Layer. + * @details This macros must be placed inside the function code. + */ +#define CV_DNN_REGISTER_LAYER_CLASS(type, class) \ + cv::dnn::LayerFactory::registerLayer(#type, cv::dnn::details::_layerDynamicRegisterer); + +/** @brief Registers layer constructor on module load time. +* @param type string, containing type name of the layer. +* @param constructorFunc pointer to the function of type LayerRegister::Constructor, which creates the layer. +* @details This macros must be placed outside the function code. +*/ +#define CV_DNN_REGISTER_LAYER_FUNC_STATIC(type, constructorFunc) \ +static cv::dnn::details::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, constructorFunc); + +/** @brief Registers layer class on module load time. + * @param type string, containing type name of the layer. + * @param class C++ class, derived from Layer. + * @details This macros must be placed outside the function code. + */ +#define CV_DNN_REGISTER_LAYER_CLASS_STATIC(type, class) \ +Ptr __LayerStaticRegisterer_func_##type(LayerParams ¶ms) \ + { return Ptr(new class(params)); } \ +static cv::dnn::details::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, __LayerStaticRegisterer_func_##type); + +namespace details { + +template +Ptr _layerDynamicRegisterer(LayerParams ¶ms) +{ + return Ptr(LayerClass::create(params)); +} + +//allows automatically register created layer on module load time +class _LayerStaticRegisterer +{ + String type; +public: + + _LayerStaticRegisterer(const String &layerType, LayerFactory::Constructor layerConstructor) + { + this->type = layerType; + LayerFactory::registerLayer(layerType, layerConstructor); + } + + ~_LayerStaticRegisterer() + { + LayerFactory::unregisterLayer(type); + } +}; + +} // namespace +CV__DNN_INLINE_NS_END +}} // namespace + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/layer.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/layer.hpp new file mode 100755 index 0000000..8500599 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/layer.hpp @@ -0,0 +1,85 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_DNN_LAYER_HPP +#define OPENCV_DNN_LAYER_HPP +#include + +namespace cv { +namespace dnn { +CV__DNN_INLINE_NS_BEGIN +//! @addtogroup dnn +//! @{ +//! +//! @defgroup dnnLayerFactory Utilities for New Layers Registration +//! @{ + +/** @brief %Layer factory allows to create instances of registered layers. */ +class CV_EXPORTS LayerFactory +{ +public: + + //! Each Layer class must provide this function to the factory + typedef Ptr(*Constructor)(LayerParams ¶ms); + + //! Registers the layer class with typename @p type and specified @p constructor. Thread-safe. + static void registerLayer(const String &type, Constructor constructor); + + //! Unregisters registered layer with specified type name. Thread-safe. + static void unregisterLayer(const String &type); + + /** @brief Creates instance of registered layer. + * @param type type name of creating layer. + * @param params parameters which will be used for layer initialization. + * @note Thread-safe. + */ + static Ptr createLayerInstance(const String &type, LayerParams& params); + +private: + LayerFactory(); +}; + +//! @} +//! @} +CV__DNN_INLINE_NS_END +} +} +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/shape_utils.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/shape_utils.hpp new file mode 100755 index 0000000..98adcc3 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/shape_utils.hpp @@ -0,0 +1,219 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_DNN_DNN_SHAPE_UTILS_HPP +#define OPENCV_DNN_DNN_SHAPE_UTILS_HPP + +#include +#include // CV_MAX_DIM +#include +#include +#include + +namespace cv { +namespace dnn { +CV__DNN_INLINE_NS_BEGIN + +//Slicing + +struct _Range : public cv::Range +{ + _Range(const Range &r) : cv::Range(r) {} + _Range(int start_, int size_ = 1) : cv::Range(start_, start_ + size_) {} +}; + +static inline Mat slice(const Mat &m, const _Range &r0) +{ + Range ranges[CV_MAX_DIM]; + for (int i = 1; i < m.dims; i++) + ranges[i] = Range::all(); + ranges[0] = r0; + return m(&ranges[0]); +} + +static inline Mat slice(const Mat &m, const _Range &r0, const _Range &r1) +{ + CV_Assert(m.dims >= 2); + Range ranges[CV_MAX_DIM]; + for (int i = 2; i < m.dims; i++) + ranges[i] = Range::all(); + ranges[0] = r0; + ranges[1] = r1; + return m(&ranges[0]); +} + +static inline Mat slice(const Mat &m, const _Range &r0, const _Range &r1, const _Range &r2) +{ + CV_Assert(m.dims >= 3); + Range ranges[CV_MAX_DIM]; + for (int i = 3; i < m.dims; i++) + ranges[i] = Range::all(); + ranges[0] = r0; + ranges[1] = r1; + ranges[2] = r2; + return m(&ranges[0]); +} + +static inline Mat slice(const Mat &m, const _Range &r0, const _Range &r1, const _Range &r2, const _Range &r3) +{ + CV_Assert(m.dims >= 4); + Range ranges[CV_MAX_DIM]; + for (int i = 4; i < m.dims; i++) + ranges[i] = Range::all(); + ranges[0] = r0; + ranges[1] = r1; + ranges[2] = r2; + ranges[3] = r3; + return m(&ranges[0]); +} + +static inline Mat getPlane(const Mat &m, int n, int cn) +{ + CV_Assert(m.dims > 2); + int sz[CV_MAX_DIM]; + for(int i = 2; i < m.dims; i++) + { + sz[i-2] = m.size.p[i]; + } + return Mat(m.dims - 2, sz, m.type(), (void*)m.ptr(n, cn)); +} + +static inline MatShape shape(const int* dims, const int n) +{ + MatShape shape; + shape.assign(dims, dims + n); + return shape; +} + +static inline MatShape shape(const Mat& mat) +{ + return shape(mat.size.p, mat.dims); +} + +static inline MatShape shape(const MatSize& sz) +{ + return shape(sz.p, sz.dims()); +} + +static inline MatShape shape(const UMat& mat) +{ + return shape(mat.size.p, mat.dims); +} + +namespace {inline bool is_neg(int i) { return i < 0; }} + +static inline MatShape shape(int a0, int a1=-1, int a2=-1, int a3=-1) +{ + int dims[] = {a0, a1, a2, a3}; + MatShape s = shape(dims, 4); + s.erase(std::remove_if(s.begin(), s.end(), is_neg), s.end()); + return s; +} + +static inline int total(const MatShape& shape, int start = -1, int end = -1) +{ + if (start == -1) start = 0; + if (end == -1) end = (int)shape.size(); + + if (shape.empty()) + return 0; + + int elems = 1; + CV_Assert(start <= (int)shape.size() && end <= (int)shape.size() && + start <= end); + for(int i = start; i < end; i++) + { + elems *= shape[i]; + } + return elems; +} + +static inline MatShape concat(const MatShape& a, const MatShape& b) +{ + MatShape c = a; + c.insert(c.end(), b.begin(), b.end()); + + return c; +} + +static inline std::string toString(const MatShape& shape, const String& name = "") +{ + std::ostringstream ss; + if (!name.empty()) + ss << name << ' '; + ss << '['; + for(size_t i = 0, n = shape.size(); i < n; ++i) + ss << ' ' << shape[i]; + ss << " ]"; + return ss.str(); +} +static inline void print(const MatShape& shape, const String& name = "") +{ + std::cout << toString(shape, name) << std::endl; +} +static inline std::ostream& operator<<(std::ostream &out, const MatShape& shape) +{ + out << toString(shape); + return out; +} + +inline int clamp(int ax, int dims) +{ + return ax < 0 ? ax + dims : ax; +} + +inline int clamp(int ax, const MatShape& shape) +{ + return clamp(ax, (int)shape.size()); +} + +inline Range clamp(const Range& r, int axisSize) +{ + Range clamped(std::max(r.start, 0), + r.end > 0 ? std::min(r.end, axisSize) : axisSize + r.end + 1); + CV_Assert_N(clamped.start < clamped.end, clamped.end <= axisSize); + return clamped; +} + +CV__DNN_INLINE_NS_END +} +} +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/utils/inference_engine.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/utils/inference_engine.hpp new file mode 100755 index 0000000..564e526 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/utils/inference_engine.hpp @@ -0,0 +1,43 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018-2019, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. + +#ifndef OPENCV_DNN_UTILS_INF_ENGINE_HPP +#define OPENCV_DNN_UTILS_INF_ENGINE_HPP + +#include "../dnn.hpp" + +namespace cv { namespace dnn { +CV__DNN_INLINE_NS_BEGIN + + +/** @brief Release a Myriad device (binded by OpenCV). + * + * Single Myriad device cannot be shared across multiple processes which uses + * Inference Engine's Myriad plugin. + */ +CV_EXPORTS_W void resetMyriadDevice(); + + +/* Values for 'OPENCV_DNN_IE_VPU_TYPE' parameter */ +#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_UNSPECIFIED "" +/// Intel(R) Movidius(TM) Neural Compute Stick, NCS (USB 03e7:2150), Myriad2 (https://software.intel.com/en-us/movidius-ncs) +#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2 "Myriad2" +/// Intel(R) Neural Compute Stick 2, NCS2 (USB 03e7:2485), MyriadX (https://software.intel.com/ru-ru/neural-compute-stick) +#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X "MyriadX" + + +/** @brief Returns Inference Engine VPU type. + * + * See values of `CV_DNN_INFERENCE_ENGINE_VPU_TYPE_*` macros. + */ +CV_EXPORTS_W cv::String getInferenceEngineVPUType(); + + +CV__DNN_INLINE_NS_END +}} // namespace + +#endif // OPENCV_DNN_UTILS_INF_ENGINE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/dnn/version.hpp b/Prj-Win/3rd/opencv/include/opencv2/dnn/version.hpp new file mode 100755 index 0000000..ecf0f24 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/dnn/version.hpp @@ -0,0 +1,21 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_DNN_VERSION_HPP +#define OPENCV_DNN_VERSION_HPP + +/// Use with major OpenCV version only. +#define OPENCV_DNN_API_VERSION 20190621 + +#if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_INLINE_NS +#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION) +#define CV__DNN_INLINE_NS_BEGIN namespace CV__DNN_INLINE_NS { +#define CV__DNN_INLINE_NS_END } +namespace cv { namespace dnn { namespace CV__DNN_INLINE_NS { } using namespace CV__DNN_INLINE_NS; }} +#else +#define CV__DNN_INLINE_NS_BEGIN +#define CV__DNN_INLINE_NS_END +#endif + +#endif // OPENCV_DNN_VERSION_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/features2d.hpp b/Prj-Win/3rd/opencv/include/opencv2/features2d.hpp new file mode 100755 index 0000000..c18f80f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/features2d.hpp @@ -0,0 +1,1451 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_FEATURES_2D_HPP +#define OPENCV_FEATURES_2D_HPP + +#include "opencv2/opencv_modules.hpp" +#include "opencv2/core.hpp" + +#ifdef HAVE_OPENCV_FLANN +#include "opencv2/flann/miniflann.hpp" +#endif + +/** + @defgroup features2d 2D Features Framework + @{ + @defgroup features2d_main Feature Detection and Description + @defgroup features2d_match Descriptor Matchers + +Matchers of keypoint descriptors in OpenCV have wrappers with a common interface that enables you to +easily switch between different algorithms solving the same problem. This section is devoted to +matching descriptors that are represented as vectors in a multidimensional space. All objects that +implement vector descriptor matchers inherit the DescriptorMatcher interface. + +@note + - An example explaining keypoint matching can be found at + opencv_source_code/samples/cpp/descriptor_extractor_matcher.cpp + - An example on descriptor matching evaluation can be found at + opencv_source_code/samples/cpp/detector_descriptor_matcher_evaluation.cpp + - An example on one to many image matching can be found at + opencv_source_code/samples/cpp/matching_to_many_images.cpp + + @defgroup features2d_draw Drawing Function of Keypoints and Matches + @defgroup features2d_category Object Categorization + +This section describes approaches based on local 2D features and used to categorize objects. + +@note + - A complete Bag-Of-Words sample can be found at + opencv_source_code/samples/cpp/bagofwords_classification.cpp + - (Python) An example using the features2D framework to perform object categorization can be + found at opencv_source_code/samples/python/find_obj.py + + @} + */ + +namespace cv +{ + +//! @addtogroup features2d +//! @{ + +// //! writes vector of keypoints to the file storage +// CV_EXPORTS void write(FileStorage& fs, const String& name, const std::vector& keypoints); +// //! reads vector of keypoints from the specified file storage node +// CV_EXPORTS void read(const FileNode& node, CV_OUT std::vector& keypoints); + +/** @brief A class filters a vector of keypoints. + + Because now it is difficult to provide a convenient interface for all usage scenarios of the + keypoints filter class, it has only several needed by now static methods. + */ +class CV_EXPORTS KeyPointsFilter +{ +public: + KeyPointsFilter(){} + + /* + * Remove keypoints within borderPixels of an image edge. + */ + static void runByImageBorder( std::vector& keypoints, Size imageSize, int borderSize ); + /* + * Remove keypoints of sizes out of range. + */ + static void runByKeypointSize( std::vector& keypoints, float minSize, + float maxSize=FLT_MAX ); + /* + * Remove keypoints from some image by mask for pixels of this image. + */ + static void runByPixelsMask( std::vector& keypoints, const Mat& mask ); + /* + * Remove duplicated keypoints. + */ + static void removeDuplicated( std::vector& keypoints ); + /* + * Remove duplicated keypoints and sort the remaining keypoints + */ + static void removeDuplicatedSorted( std::vector& keypoints ); + + /* + * Retain the specified number of the best keypoints (according to the response) + */ + static void retainBest( std::vector& keypoints, int npoints ); +}; + + +/************************************ Base Classes ************************************/ + +/** @brief Abstract base class for 2D image feature detectors and descriptor extractors +*/ +#ifdef __EMSCRIPTEN__ +class CV_EXPORTS_W Feature2D : public Algorithm +#else +class CV_EXPORTS_W Feature2D : public virtual Algorithm +#endif +{ +public: + virtual ~Feature2D(); + + /** @brief Detects keypoints in an image (first variant) or image set (second variant). + + @param image Image. + @param keypoints The detected keypoints. In the second variant of the method keypoints[i] is a set + of keypoints detected in images[i] . + @param mask Mask specifying where to look for keypoints (optional). It must be a 8-bit integer + matrix with non-zero values in the region of interest. + */ + CV_WRAP virtual void detect( InputArray image, + CV_OUT std::vector& keypoints, + InputArray mask=noArray() ); + + /** @overload + @param images Image set. + @param keypoints The detected keypoints. In the second variant of the method keypoints[i] is a set + of keypoints detected in images[i] . + @param masks Masks for each input image specifying where to look for keypoints (optional). + masks[i] is a mask for images[i]. + */ + CV_WRAP virtual void detect( InputArrayOfArrays images, + CV_OUT std::vector >& keypoints, + InputArrayOfArrays masks=noArray() ); + + /** @brief Computes the descriptors for a set of keypoints detected in an image (first variant) or image set + (second variant). + + @param image Image. + @param keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be + computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint + with several dominant orientations (for each orientation). + @param descriptors Computed descriptors. In the second variant of the method descriptors[i] are + descriptors computed for a keypoints[i]. Row j is the keypoints (or keypoints[i]) is the + descriptor for keypoint j-th keypoint. + */ + CV_WRAP virtual void compute( InputArray image, + CV_OUT CV_IN_OUT std::vector& keypoints, + OutputArray descriptors ); + + /** @overload + + @param images Image set. + @param keypoints Input collection of keypoints. Keypoints for which a descriptor cannot be + computed are removed. Sometimes new keypoints can be added, for example: SIFT duplicates keypoint + with several dominant orientations (for each orientation). + @param descriptors Computed descriptors. In the second variant of the method descriptors[i] are + descriptors computed for a keypoints[i]. Row j is the keypoints (or keypoints[i]) is the + descriptor for keypoint j-th keypoint. + */ + CV_WRAP virtual void compute( InputArrayOfArrays images, + CV_OUT CV_IN_OUT std::vector >& keypoints, + OutputArrayOfArrays descriptors ); + + /** Detects keypoints and computes the descriptors */ + CV_WRAP virtual void detectAndCompute( InputArray image, InputArray mask, + CV_OUT std::vector& keypoints, + OutputArray descriptors, + bool useProvidedKeypoints=false ); + + CV_WRAP virtual int descriptorSize() const; + CV_WRAP virtual int descriptorType() const; + CV_WRAP virtual int defaultNorm() const; + + CV_WRAP void write( const String& fileName ) const; + + CV_WRAP void read( const String& fileName ); + + virtual void write( FileStorage&) const CV_OVERRIDE; + + // see corresponding cv::Algorithm method + CV_WRAP virtual void read( const FileNode&) CV_OVERRIDE; + + //! Return true if detector object is empty + CV_WRAP virtual bool empty() const CV_OVERRIDE; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; + + // see corresponding cv::Algorithm method + CV_WRAP inline void write(const Ptr& fs, const String& name = String()) const { Algorithm::write(fs, name); } +}; + +/** Feature detectors in OpenCV have wrappers with a common interface that enables you to easily switch +between different algorithms solving the same problem. All objects that implement keypoint detectors +inherit the FeatureDetector interface. */ +typedef Feature2D FeatureDetector; + +/** Extractors of keypoint descriptors in OpenCV have wrappers with a common interface that enables you +to easily switch between different algorithms solving the same problem. This section is devoted to +computing descriptors represented as vectors in a multidimensional space. All objects that implement +the vector descriptor extractors inherit the DescriptorExtractor interface. + */ +typedef Feature2D DescriptorExtractor; + +//! @addtogroup features2d_main +//! @{ + +/** @brief Class implementing the BRISK keypoint detector and descriptor extractor, described in @cite LCS11 . + */ +class CV_EXPORTS_W BRISK : public Feature2D +{ +public: + /** @brief The BRISK constructor + + @param thresh AGAST detection threshold score. + @param octaves detection octaves. Use 0 to do single scale. + @param patternScale apply this scale to the pattern used for sampling the neighbourhood of a + keypoint. + */ + CV_WRAP static Ptr create(int thresh=30, int octaves=3, float patternScale=1.0f); + + /** @brief The BRISK constructor for a custom pattern + + @param radiusList defines the radii (in pixels) where the samples around a keypoint are taken (for + keypoint scale 1). + @param numberList defines the number of sampling points on the sampling circle. Must be the same + size as radiusList.. + @param dMax threshold for the short pairings used for descriptor formation (in pixels for keypoint + scale 1). + @param dMin threshold for the long pairings used for orientation determination (in pixels for + keypoint scale 1). + @param indexChange index remapping of the bits. */ + CV_WRAP static Ptr create(const std::vector &radiusList, const std::vector &numberList, + float dMax=5.85f, float dMin=8.2f, const std::vector& indexChange=std::vector()); + + /** @brief The BRISK constructor for a custom pattern, detection threshold and octaves + + @param thresh AGAST detection threshold score. + @param octaves detection octaves. Use 0 to do single scale. + @param radiusList defines the radii (in pixels) where the samples around a keypoint are taken (for + keypoint scale 1). + @param numberList defines the number of sampling points on the sampling circle. Must be the same + size as radiusList.. + @param dMax threshold for the short pairings used for descriptor formation (in pixels for keypoint + scale 1). + @param dMin threshold for the long pairings used for orientation determination (in pixels for + keypoint scale 1). + @param indexChange index remapping of the bits. */ + CV_WRAP static Ptr create(int thresh, int octaves, const std::vector &radiusList, + const std::vector &numberList, float dMax=5.85f, float dMin=8.2f, + const std::vector& indexChange=std::vector()); + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; + + /** @brief Set detection threshold. + @param threshold AGAST detection threshold score. + */ + CV_WRAP virtual void setThreshold(int threshold) { CV_UNUSED(threshold); return; } + CV_WRAP virtual int getThreshold() const { return -1; } + + /** @brief Set detection octaves. + @param octaves detection octaves. Use 0 to do single scale. + */ + CV_WRAP virtual void setOctaves(int octaves) { CV_UNUSED(octaves); return; } + CV_WRAP virtual int getOctaves() const { return -1; } +}; + +/** @brief Class implementing the ORB (*oriented BRIEF*) keypoint detector and descriptor extractor + +described in @cite RRKB11 . The algorithm uses FAST in pyramids to detect stable keypoints, selects +the strongest features using FAST or Harris response, finds their orientation using first-order +moments and computes the descriptors using BRIEF (where the coordinates of random point pairs (or +k-tuples) are rotated according to the measured orientation). + */ +class CV_EXPORTS_W ORB : public Feature2D +{ +public: + enum ScoreType { HARRIS_SCORE=0, FAST_SCORE=1 }; + static const int kBytes = 32; + + /** @brief The ORB constructor + + @param nfeatures The maximum number of features to retain. + @param scaleFactor Pyramid decimation ratio, greater than 1. scaleFactor==2 means the classical + pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor + will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor + will mean that to cover certain scale range you will need more pyramid levels and so the speed + will suffer. + @param nlevels The number of pyramid levels. The smallest level will have linear size equal to + input_image_linear_size/pow(scaleFactor, nlevels - firstLevel). + @param edgeThreshold This is size of the border where the features are not detected. It should + roughly match the patchSize parameter. + @param firstLevel The level of pyramid to put source image to. Previous layers are filled + with upscaled source image. + @param WTA_K The number of points that produce each element of the oriented BRIEF descriptor. The + default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, + so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 + random points (of course, those point coordinates are random, but they are generated from the + pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel + rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such + output will occupy 2 bits, and therefore it will need a special variant of Hamming distance, + denoted as NORM_HAMMING2 (2 bits per bin). When WTA_K=4, we take 4 random points to compute each + bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3). + @param scoreType The default HARRIS_SCORE means that Harris algorithm is used to rank features + (the score is written to KeyPoint::score and is used to retain best nfeatures features); + FAST_SCORE is alternative value of the parameter that produces slightly less stable keypoints, + but it is a little faster to compute. + @param patchSize size of the patch used by the oriented BRIEF descriptor. Of course, on smaller + pyramid layers the perceived image area covered by a feature will be larger. + @param fastThreshold the fast threshold + */ + CV_WRAP static Ptr create(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31, + int firstLevel=0, int WTA_K=2, ORB::ScoreType scoreType=ORB::HARRIS_SCORE, int patchSize=31, int fastThreshold=20); + + CV_WRAP virtual void setMaxFeatures(int maxFeatures) = 0; + CV_WRAP virtual int getMaxFeatures() const = 0; + + CV_WRAP virtual void setScaleFactor(double scaleFactor) = 0; + CV_WRAP virtual double getScaleFactor() const = 0; + + CV_WRAP virtual void setNLevels(int nlevels) = 0; + CV_WRAP virtual int getNLevels() const = 0; + + CV_WRAP virtual void setEdgeThreshold(int edgeThreshold) = 0; + CV_WRAP virtual int getEdgeThreshold() const = 0; + + CV_WRAP virtual void setFirstLevel(int firstLevel) = 0; + CV_WRAP virtual int getFirstLevel() const = 0; + + CV_WRAP virtual void setWTA_K(int wta_k) = 0; + CV_WRAP virtual int getWTA_K() const = 0; + + CV_WRAP virtual void setScoreType(ORB::ScoreType scoreType) = 0; + CV_WRAP virtual ORB::ScoreType getScoreType() const = 0; + + CV_WRAP virtual void setPatchSize(int patchSize) = 0; + CV_WRAP virtual int getPatchSize() const = 0; + + CV_WRAP virtual void setFastThreshold(int fastThreshold) = 0; + CV_WRAP virtual int getFastThreshold() const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +/** @brief Maximally stable extremal region extractor + +The class encapsulates all the parameters of the %MSER extraction algorithm (see [wiki +article](http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions)). + +- there are two different implementation of %MSER: one for grey image, one for color image + +- the grey image algorithm is taken from: @cite nister2008linear ; the paper claims to be faster +than union-find method; it actually get 1.5~2m/s on my centrino L7200 1.2GHz laptop. + +- the color image algorithm is taken from: @cite forssen2007maximally ; it should be much slower +than grey image method ( 3~4 times ); the chi_table.h file is taken directly from paper's source +code which is distributed under GPL. + +- (Python) A complete example showing the use of the %MSER detector can be found at samples/python/mser.py +*/ +class CV_EXPORTS_W MSER : public Feature2D +{ +public: + /** @brief Full consturctor for %MSER detector + + @param _delta it compares \f$(size_{i}-size_{i-delta})/size_{i-delta}\f$ + @param _min_area prune the area which smaller than minArea + @param _max_area prune the area which bigger than maxArea + @param _max_variation prune the area have similar size to its children + @param _min_diversity for color image, trace back to cut off mser with diversity less than min_diversity + @param _max_evolution for color image, the evolution steps + @param _area_threshold for color image, the area threshold to cause re-initialize + @param _min_margin for color image, ignore too small margin + @param _edge_blur_size for color image, the aperture size for edge blur + */ + CV_WRAP static Ptr create( int _delta=5, int _min_area=60, int _max_area=14400, + double _max_variation=0.25, double _min_diversity=.2, + int _max_evolution=200, double _area_threshold=1.01, + double _min_margin=0.003, int _edge_blur_size=5 ); + + /** @brief Detect %MSER regions + + @param image input image (8UC1, 8UC3 or 8UC4, must be greater or equal than 3x3) + @param msers resulting list of point sets + @param bboxes resulting bounding boxes + */ + CV_WRAP virtual void detectRegions( InputArray image, + CV_OUT std::vector >& msers, + CV_OUT std::vector& bboxes ) = 0; + + CV_WRAP virtual void setDelta(int delta) = 0; + CV_WRAP virtual int getDelta() const = 0; + + CV_WRAP virtual void setMinArea(int minArea) = 0; + CV_WRAP virtual int getMinArea() const = 0; + + CV_WRAP virtual void setMaxArea(int maxArea) = 0; + CV_WRAP virtual int getMaxArea() const = 0; + + CV_WRAP virtual void setPass2Only(bool f) = 0; + CV_WRAP virtual bool getPass2Only() const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +//! @} features2d_main + +//! @addtogroup features2d_main +//! @{ + +/** @brief Wrapping class for feature detection using the FAST method. : + */ +class CV_EXPORTS_W FastFeatureDetector : public Feature2D +{ +public: + enum DetectorType + { + TYPE_5_8 = 0, TYPE_7_12 = 1, TYPE_9_16 = 2 + }; + enum + { + THRESHOLD = 10000, NONMAX_SUPPRESSION=10001, FAST_N=10002 + }; + + + CV_WRAP static Ptr create( int threshold=10, + bool nonmaxSuppression=true, + FastFeatureDetector::DetectorType type=FastFeatureDetector::TYPE_9_16 ); + + CV_WRAP virtual void setThreshold(int threshold) = 0; + CV_WRAP virtual int getThreshold() const = 0; + + CV_WRAP virtual void setNonmaxSuppression(bool f) = 0; + CV_WRAP virtual bool getNonmaxSuppression() const = 0; + + CV_WRAP virtual void setType(FastFeatureDetector::DetectorType type) = 0; + CV_WRAP virtual FastFeatureDetector::DetectorType getType() const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +/** @overload */ +CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector& keypoints, + int threshold, bool nonmaxSuppression=true ); + +/** @brief Detects corners using the FAST algorithm + +@param image grayscale image where keypoints (corners) are detected. +@param keypoints keypoints detected on the image. +@param threshold threshold on difference between intensity of the central pixel and pixels of a +circle around this pixel. +@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners +(keypoints). +@param type one of the three neighborhoods as defined in the paper: +FastFeatureDetector::TYPE_9_16, FastFeatureDetector::TYPE_7_12, +FastFeatureDetector::TYPE_5_8 + +Detects corners using the FAST algorithm by @cite Rosten06 . + +@note In Python API, types are given as cv.FAST_FEATURE_DETECTOR_TYPE_5_8, +cv.FAST_FEATURE_DETECTOR_TYPE_7_12 and cv.FAST_FEATURE_DETECTOR_TYPE_9_16. For corner +detection, use cv.FAST.detect() method. + */ +CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector& keypoints, + int threshold, bool nonmaxSuppression, FastFeatureDetector::DetectorType type ); + +//! @} features2d_main + +//! @addtogroup features2d_main +//! @{ + +/** @brief Wrapping class for feature detection using the AGAST method. : + */ +class CV_EXPORTS_W AgastFeatureDetector : public Feature2D +{ +public: + enum DetectorType + { + AGAST_5_8 = 0, AGAST_7_12d = 1, AGAST_7_12s = 2, OAST_9_16 = 3, + }; + + enum + { + THRESHOLD = 10000, NONMAX_SUPPRESSION = 10001, + }; + + CV_WRAP static Ptr create( int threshold=10, + bool nonmaxSuppression=true, + AgastFeatureDetector::DetectorType type = AgastFeatureDetector::OAST_9_16); + + CV_WRAP virtual void setThreshold(int threshold) = 0; + CV_WRAP virtual int getThreshold() const = 0; + + CV_WRAP virtual void setNonmaxSuppression(bool f) = 0; + CV_WRAP virtual bool getNonmaxSuppression() const = 0; + + CV_WRAP virtual void setType(AgastFeatureDetector::DetectorType type) = 0; + CV_WRAP virtual AgastFeatureDetector::DetectorType getType() const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +/** @overload */ +CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector& keypoints, + int threshold, bool nonmaxSuppression=true ); + +/** @brief Detects corners using the AGAST algorithm + +@param image grayscale image where keypoints (corners) are detected. +@param keypoints keypoints detected on the image. +@param threshold threshold on difference between intensity of the central pixel and pixels of a +circle around this pixel. +@param nonmaxSuppression if true, non-maximum suppression is applied to detected corners +(keypoints). +@param type one of the four neighborhoods as defined in the paper: +AgastFeatureDetector::AGAST_5_8, AgastFeatureDetector::AGAST_7_12d, +AgastFeatureDetector::AGAST_7_12s, AgastFeatureDetector::OAST_9_16 + +For non-Intel platforms, there is a tree optimised variant of AGAST with same numerical results. +The 32-bit binary tree tables were generated automatically from original code using perl script. +The perl script and examples of tree generation are placed in features2d/doc folder. +Detects corners using the AGAST algorithm by @cite mair2010_agast . + + */ +CV_EXPORTS void AGAST( InputArray image, CV_OUT std::vector& keypoints, + int threshold, bool nonmaxSuppression, AgastFeatureDetector::DetectorType type ); + +/** @brief Wrapping class for feature detection using the goodFeaturesToTrack function. : + */ +class CV_EXPORTS_W GFTTDetector : public Feature2D +{ +public: + CV_WRAP static Ptr create( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1, + int blockSize=3, bool useHarrisDetector=false, double k=0.04 ); + CV_WRAP static Ptr create( int maxCorners, double qualityLevel, double minDistance, + int blockSize, int gradiantSize, bool useHarrisDetector=false, double k=0.04 ); + CV_WRAP virtual void setMaxFeatures(int maxFeatures) = 0; + CV_WRAP virtual int getMaxFeatures() const = 0; + + CV_WRAP virtual void setQualityLevel(double qlevel) = 0; + CV_WRAP virtual double getQualityLevel() const = 0; + + CV_WRAP virtual void setMinDistance(double minDistance) = 0; + CV_WRAP virtual double getMinDistance() const = 0; + + CV_WRAP virtual void setBlockSize(int blockSize) = 0; + CV_WRAP virtual int getBlockSize() const = 0; + + CV_WRAP virtual void setHarrisDetector(bool val) = 0; + CV_WRAP virtual bool getHarrisDetector() const = 0; + + CV_WRAP virtual void setK(double k) = 0; + CV_WRAP virtual double getK() const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +/** @brief Class for extracting blobs from an image. : + +The class implements a simple algorithm for extracting blobs from an image: + +1. Convert the source image to binary images by applying thresholding with several thresholds from + minThreshold (inclusive) to maxThreshold (exclusive) with distance thresholdStep between + neighboring thresholds. +2. Extract connected components from every binary image by findContours and calculate their + centers. +3. Group centers from several binary images by their coordinates. Close centers form one group that + corresponds to one blob, which is controlled by the minDistBetweenBlobs parameter. +4. From the groups, estimate final centers of blobs and their radiuses and return as locations and + sizes of keypoints. + +This class performs several filtrations of returned blobs. You should set filterBy\* to true/false +to turn on/off corresponding filtration. Available filtrations: + +- **By color**. This filter compares the intensity of a binary image at the center of a blob to +blobColor. If they differ, the blob is filtered out. Use blobColor = 0 to extract dark blobs +and blobColor = 255 to extract light blobs. +- **By area**. Extracted blobs have an area between minArea (inclusive) and maxArea (exclusive). +- **By circularity**. Extracted blobs have circularity +(\f$\frac{4*\pi*Area}{perimeter * perimeter}\f$) between minCircularity (inclusive) and +maxCircularity (exclusive). +- **By ratio of the minimum inertia to maximum inertia**. Extracted blobs have this ratio +between minInertiaRatio (inclusive) and maxInertiaRatio (exclusive). +- **By convexity**. Extracted blobs have convexity (area / area of blob convex hull) between +minConvexity (inclusive) and maxConvexity (exclusive). + +Default values of parameters are tuned to extract dark circular blobs. + */ +class CV_EXPORTS_W SimpleBlobDetector : public Feature2D +{ +public: + struct CV_EXPORTS_W_SIMPLE Params + { + CV_WRAP Params(); + CV_PROP_RW float thresholdStep; + CV_PROP_RW float minThreshold; + CV_PROP_RW float maxThreshold; + CV_PROP_RW size_t minRepeatability; + CV_PROP_RW float minDistBetweenBlobs; + + CV_PROP_RW bool filterByColor; + CV_PROP_RW uchar blobColor; + + CV_PROP_RW bool filterByArea; + CV_PROP_RW float minArea, maxArea; + + CV_PROP_RW bool filterByCircularity; + CV_PROP_RW float minCircularity, maxCircularity; + + CV_PROP_RW bool filterByInertia; + CV_PROP_RW float minInertiaRatio, maxInertiaRatio; + + CV_PROP_RW bool filterByConvexity; + CV_PROP_RW float minConvexity, maxConvexity; + + void read( const FileNode& fn ); + void write( FileStorage& fs ) const; + }; + + CV_WRAP static Ptr + create(const SimpleBlobDetector::Params ¶meters = SimpleBlobDetector::Params()); + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +//! @} features2d_main + +//! @addtogroup features2d_main +//! @{ + +/** @brief Class implementing the KAZE keypoint detector and descriptor extractor, described in @cite ABD12 . + +@note AKAZE descriptor can only be used with KAZE or AKAZE keypoints .. [ABD12] KAZE Features. Pablo +F. Alcantarilla, Adrien Bartoli and Andrew J. Davison. In European Conference on Computer Vision +(ECCV), Fiorenze, Italy, October 2012. +*/ +class CV_EXPORTS_W KAZE : public Feature2D +{ +public: + enum DiffusivityType + { + DIFF_PM_G1 = 0, + DIFF_PM_G2 = 1, + DIFF_WEICKERT = 2, + DIFF_CHARBONNIER = 3 + }; + + /** @brief The KAZE constructor + + @param extended Set to enable extraction of extended (128-byte) descriptor. + @param upright Set to enable use of upright descriptors (non rotation-invariant). + @param threshold Detector response threshold to accept point + @param nOctaves Maximum octave evolution of the image + @param nOctaveLayers Default number of sublevels per scale level + @param diffusivity Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or + DIFF_CHARBONNIER + */ + CV_WRAP static Ptr create(bool extended=false, bool upright=false, + float threshold = 0.001f, + int nOctaves = 4, int nOctaveLayers = 4, + KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2); + + CV_WRAP virtual void setExtended(bool extended) = 0; + CV_WRAP virtual bool getExtended() const = 0; + + CV_WRAP virtual void setUpright(bool upright) = 0; + CV_WRAP virtual bool getUpright() const = 0; + + CV_WRAP virtual void setThreshold(double threshold) = 0; + CV_WRAP virtual double getThreshold() const = 0; + + CV_WRAP virtual void setNOctaves(int octaves) = 0; + CV_WRAP virtual int getNOctaves() const = 0; + + CV_WRAP virtual void setNOctaveLayers(int octaveLayers) = 0; + CV_WRAP virtual int getNOctaveLayers() const = 0; + + CV_WRAP virtual void setDiffusivity(KAZE::DiffusivityType diff) = 0; + CV_WRAP virtual KAZE::DiffusivityType getDiffusivity() const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +/** @brief Class implementing the AKAZE keypoint detector and descriptor extractor, described in @cite ANB13. + +@details AKAZE descriptors can only be used with KAZE or AKAZE keypoints. This class is thread-safe. + +@note When you need descriptors use Feature2D::detectAndCompute, which +provides better performance. When using Feature2D::detect followed by +Feature2D::compute scale space pyramid is computed twice. + +@note AKAZE implements T-API. When image is passed as UMat some parts of the algorithm +will use OpenCL. + +@note [ANB13] Fast Explicit Diffusion for Accelerated Features in Nonlinear +Scale Spaces. Pablo F. Alcantarilla, Jesús Nuevo and Adrien Bartoli. In +British Machine Vision Conference (BMVC), Bristol, UK, September 2013. + +*/ +class CV_EXPORTS_W AKAZE : public Feature2D +{ +public: + // AKAZE descriptor type + enum DescriptorType + { + DESCRIPTOR_KAZE_UPRIGHT = 2, ///< Upright descriptors, not invariant to rotation + DESCRIPTOR_KAZE = 3, + DESCRIPTOR_MLDB_UPRIGHT = 4, ///< Upright descriptors, not invariant to rotation + DESCRIPTOR_MLDB = 5 + }; + + /** @brief The AKAZE constructor + + @param descriptor_type Type of the extracted descriptor: DESCRIPTOR_KAZE, + DESCRIPTOR_KAZE_UPRIGHT, DESCRIPTOR_MLDB or DESCRIPTOR_MLDB_UPRIGHT. + @param descriptor_size Size of the descriptor in bits. 0 -\> Full size + @param descriptor_channels Number of channels in the descriptor (1, 2, 3) + @param threshold Detector response threshold to accept point + @param nOctaves Maximum octave evolution of the image + @param nOctaveLayers Default number of sublevels per scale level + @param diffusivity Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or + DIFF_CHARBONNIER + */ + CV_WRAP static Ptr create(AKAZE::DescriptorType descriptor_type = AKAZE::DESCRIPTOR_MLDB, + int descriptor_size = 0, int descriptor_channels = 3, + float threshold = 0.001f, int nOctaves = 4, + int nOctaveLayers = 4, KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2); + + CV_WRAP virtual void setDescriptorType(AKAZE::DescriptorType dtype) = 0; + CV_WRAP virtual AKAZE::DescriptorType getDescriptorType() const = 0; + + CV_WRAP virtual void setDescriptorSize(int dsize) = 0; + CV_WRAP virtual int getDescriptorSize() const = 0; + + CV_WRAP virtual void setDescriptorChannels(int dch) = 0; + CV_WRAP virtual int getDescriptorChannels() const = 0; + + CV_WRAP virtual void setThreshold(double threshold) = 0; + CV_WRAP virtual double getThreshold() const = 0; + + CV_WRAP virtual void setNOctaves(int octaves) = 0; + CV_WRAP virtual int getNOctaves() const = 0; + + CV_WRAP virtual void setNOctaveLayers(int octaveLayers) = 0; + CV_WRAP virtual int getNOctaveLayers() const = 0; + + CV_WRAP virtual void setDiffusivity(KAZE::DiffusivityType diff) = 0; + CV_WRAP virtual KAZE::DiffusivityType getDiffusivity() const = 0; + CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; +}; + +//! @} features2d_main + +/****************************************************************************************\ +* Distance * +\****************************************************************************************/ + +template +struct CV_EXPORTS Accumulator +{ + typedef T Type; +}; + +template<> struct Accumulator { typedef float Type; }; +template<> struct Accumulator { typedef float Type; }; +template<> struct Accumulator { typedef float Type; }; +template<> struct Accumulator { typedef float Type; }; + +/* + * Squared Euclidean distance functor + */ +template +struct CV_EXPORTS SL2 +{ + static const NormTypes normType = NORM_L2SQR; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T* a, const T* b, int size ) const + { + return normL2Sqr(a, b, size); + } +}; + +/* + * Euclidean distance functor + */ +template +struct L2 +{ + static const NormTypes normType = NORM_L2; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T* a, const T* b, int size ) const + { + return (ResultType)std::sqrt((double)normL2Sqr(a, b, size)); + } +}; + +/* + * Manhattan distance (city block distance) functor + */ +template +struct L1 +{ + static const NormTypes normType = NORM_L1; + typedef T ValueType; + typedef typename Accumulator::Type ResultType; + + ResultType operator()( const T* a, const T* b, int size ) const + { + return normL1(a, b, size); + } +}; + +/****************************************************************************************\ +* DescriptorMatcher * +\****************************************************************************************/ + +//! @addtogroup features2d_match +//! @{ + +/** @brief Abstract base class for matching keypoint descriptors. + +It has two groups of match methods: for matching descriptors of an image with another image or with +an image set. + */ +class CV_EXPORTS_W DescriptorMatcher : public Algorithm +{ +public: + enum MatcherType + { + FLANNBASED = 1, + BRUTEFORCE = 2, + BRUTEFORCE_L1 = 3, + BRUTEFORCE_HAMMING = 4, + BRUTEFORCE_HAMMINGLUT = 5, + BRUTEFORCE_SL2 = 6 + }; + + virtual ~DescriptorMatcher(); + + /** @brief Adds descriptors to train a CPU(trainDescCollectionis) or GPU(utrainDescCollectionis) descriptor + collection. + + If the collection is not empty, the new descriptors are added to existing train descriptors. + + @param descriptors Descriptors to add. Each descriptors[i] is a set of descriptors from the same + train image. + */ + CV_WRAP virtual void add( InputArrayOfArrays descriptors ); + + /** @brief Returns a constant link to the train descriptor collection trainDescCollection . + */ + CV_WRAP const std::vector& getTrainDescriptors() const; + + /** @brief Clears the train descriptor collections. + */ + CV_WRAP virtual void clear() CV_OVERRIDE; + + /** @brief Returns true if there are no train descriptors in the both collections. + */ + CV_WRAP virtual bool empty() const CV_OVERRIDE; + + /** @brief Returns true if the descriptor matcher supports masking permissible matches. + */ + CV_WRAP virtual bool isMaskSupported() const = 0; + + /** @brief Trains a descriptor matcher + + Trains a descriptor matcher (for example, the flann index). In all methods to match, the method + train() is run every time before matching. Some descriptor matchers (for example, BruteForceMatcher) + have an empty implementation of this method. Other matchers really train their inner structures (for + example, FlannBasedMatcher trains flann::Index ). + */ + CV_WRAP virtual void train(); + + /** @brief Finds the best match for each descriptor from a query set. + + @param queryDescriptors Query set of descriptors. + @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors + collection stored in the class object. + @param matches Matches. If a query descriptor is masked out in mask , no match is added for this + descriptor. So, matches size may be smaller than the query descriptors count. + @param mask Mask specifying permissible matches between an input query and train matrices of + descriptors. + + In the first variant of this method, the train descriptors are passed as an input argument. In the + second variant of the method, train descriptors collection that was set by DescriptorMatcher::add is + used. Optional mask (or masks) can be passed to specify which query and training descriptors can be + matched. Namely, queryDescriptors[i] can be matched with trainDescriptors[j] only if + mask.at\(i,j) is non-zero. + */ + CV_WRAP void match( InputArray queryDescriptors, InputArray trainDescriptors, + CV_OUT std::vector& matches, InputArray mask=noArray() ) const; + + /** @brief Finds the k best matches for each descriptor from a query set. + + @param queryDescriptors Query set of descriptors. + @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors + collection stored in the class object. + @param mask Mask specifying permissible matches between an input query and train matrices of + descriptors. + @param matches Matches. Each matches[i] is k or less matches for the same query descriptor. + @param k Count of best matches found per each query descriptor or less if a query descriptor has + less than k possible matches in total. + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, + the matches vector does not contain matches for fully masked-out query descriptors. + + These extended variants of DescriptorMatcher::match methods find several best matches for each query + descriptor. The matches are returned in the distance increasing order. See DescriptorMatcher::match + for the details about query and train descriptors. + */ + CV_WRAP void knnMatch( InputArray queryDescriptors, InputArray trainDescriptors, + CV_OUT std::vector >& matches, int k, + InputArray mask=noArray(), bool compactResult=false ) const; + + /** @brief For each query descriptor, finds the training descriptors not farther than the specified distance. + + @param queryDescriptors Query set of descriptors. + @param trainDescriptors Train set of descriptors. This set is not added to the train descriptors + collection stored in the class object. + @param matches Found matches. + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, + the matches vector does not contain matches for fully masked-out query descriptors. + @param maxDistance Threshold for the distance between matched descriptors. Distance means here + metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured + in Pixels)! + @param mask Mask specifying permissible matches between an input query and train matrices of + descriptors. + + For each query descriptor, the methods find such training descriptors that the distance between the + query descriptor and the training descriptor is equal or smaller than maxDistance. Found matches are + returned in the distance increasing order. + */ + CV_WRAP void radiusMatch( InputArray queryDescriptors, InputArray trainDescriptors, + CV_OUT std::vector >& matches, float maxDistance, + InputArray mask=noArray(), bool compactResult=false ) const; + + /** @overload + @param queryDescriptors Query set of descriptors. + @param matches Matches. If a query descriptor is masked out in mask , no match is added for this + descriptor. So, matches size may be smaller than the query descriptors count. + @param masks Set of masks. Each masks[i] specifies permissible matches between the input query + descriptors and stored train descriptors from the i-th image trainDescCollection[i]. + */ + CV_WRAP void match( InputArray queryDescriptors, CV_OUT std::vector& matches, + InputArrayOfArrays masks=noArray() ); + /** @overload + @param queryDescriptors Query set of descriptors. + @param matches Matches. Each matches[i] is k or less matches for the same query descriptor. + @param k Count of best matches found per each query descriptor or less if a query descriptor has + less than k possible matches in total. + @param masks Set of masks. Each masks[i] specifies permissible matches between the input query + descriptors and stored train descriptors from the i-th image trainDescCollection[i]. + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, + the matches vector does not contain matches for fully masked-out query descriptors. + */ + CV_WRAP void knnMatch( InputArray queryDescriptors, CV_OUT std::vector >& matches, int k, + InputArrayOfArrays masks=noArray(), bool compactResult=false ); + /** @overload + @param queryDescriptors Query set of descriptors. + @param matches Found matches. + @param maxDistance Threshold for the distance between matched descriptors. Distance means here + metric distance (e.g. Hamming distance), not the distance between coordinates (which is measured + in Pixels)! + @param masks Set of masks. Each masks[i] specifies permissible matches between the input query + descriptors and stored train descriptors from the i-th image trainDescCollection[i]. + @param compactResult Parameter used when the mask (or masks) is not empty. If compactResult is + false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, + the matches vector does not contain matches for fully masked-out query descriptors. + */ + CV_WRAP void radiusMatch( InputArray queryDescriptors, CV_OUT std::vector >& matches, float maxDistance, + InputArrayOfArrays masks=noArray(), bool compactResult=false ); + + + CV_WRAP void write( const String& fileName ) const + { + FileStorage fs(fileName, FileStorage::WRITE); + write(fs); + } + + CV_WRAP void read( const String& fileName ) + { + FileStorage fs(fileName, FileStorage::READ); + read(fs.root()); + } + // Reads matcher object from a file node + // see corresponding cv::Algorithm method + CV_WRAP virtual void read( const FileNode& ) CV_OVERRIDE; + // Writes matcher object to a file storage + virtual void write( FileStorage& ) const CV_OVERRIDE; + + /** @brief Clones the matcher. + + @param emptyTrainData If emptyTrainData is false, the method creates a deep copy of the object, + that is, copies both parameters and train data. If emptyTrainData is true, the method creates an + object copy with the current parameters but with empty train data. + */ + CV_WRAP virtual Ptr clone( bool emptyTrainData=false ) const = 0; + + /** @brief Creates a descriptor matcher of a given type with the default parameters (using default + constructor). + + @param descriptorMatcherType Descriptor matcher type. Now the following matcher types are + supported: + - `BruteForce` (it uses L2 ) + - `BruteForce-L1` + - `BruteForce-Hamming` + - `BruteForce-Hamming(2)` + - `FlannBased` + */ + CV_WRAP static Ptr create( const String& descriptorMatcherType ); + + CV_WRAP static Ptr create( const DescriptorMatcher::MatcherType& matcherType ); + + + // see corresponding cv::Algorithm method + CV_WRAP inline void write(const Ptr& fs, const String& name = String()) const { Algorithm::write(fs, name); } + +protected: + /** + * Class to work with descriptors from several images as with one merged matrix. + * It is used e.g. in FlannBasedMatcher. + */ + class CV_EXPORTS DescriptorCollection + { + public: + DescriptorCollection(); + DescriptorCollection( const DescriptorCollection& collection ); + virtual ~DescriptorCollection(); + + // Vector of matrices "descriptors" will be merged to one matrix "mergedDescriptors" here. + void set( const std::vector& descriptors ); + virtual void clear(); + + const Mat& getDescriptors() const; + const Mat getDescriptor( int imgIdx, int localDescIdx ) const; + const Mat getDescriptor( int globalDescIdx ) const; + void getLocalIdx( int globalDescIdx, int& imgIdx, int& localDescIdx ) const; + + int size() const; + + protected: + Mat mergedDescriptors; + std::vector startIdxs; + }; + + //! In fact the matching is implemented only by the following two methods. These methods suppose + //! that the class object has been trained already. Public match methods call these methods + //! after calling train(). + virtual void knnMatchImpl( InputArray queryDescriptors, std::vector >& matches, int k, + InputArrayOfArrays masks=noArray(), bool compactResult=false ) = 0; + virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector >& matches, float maxDistance, + InputArrayOfArrays masks=noArray(), bool compactResult=false ) = 0; + + static bool isPossibleMatch( InputArray mask, int queryIdx, int trainIdx ); + static bool isMaskedOut( InputArrayOfArrays masks, int queryIdx ); + + static Mat clone_op( Mat m ) { return m.clone(); } + void checkMasks( InputArrayOfArrays masks, int queryDescriptorsCount ) const; + + //! Collection of descriptors from train images. + std::vector trainDescCollection; + std::vector utrainDescCollection; +}; + +/** @brief Brute-force descriptor matcher. + +For each descriptor in the first set, this matcher finds the closest descriptor in the second set +by trying each one. This descriptor matcher supports masking permissible matches of descriptor +sets. + */ +class CV_EXPORTS_W BFMatcher : public DescriptorMatcher +{ +public: + /** @brief Brute-force matcher constructor (obsolete). Please use BFMatcher.create() + * + * + */ + CV_WRAP BFMatcher( int normType=NORM_L2, bool crossCheck=false ); + + virtual ~BFMatcher() {} + + virtual bool isMaskSupported() const CV_OVERRIDE { return true; } + + /** @brief Brute-force matcher create method. + @param normType One of NORM_L1, NORM_L2, NORM_HAMMING, NORM_HAMMING2. L1 and L2 norms are + preferable choices for SIFT and SURF descriptors, NORM_HAMMING should be used with ORB, BRISK and + BRIEF, NORM_HAMMING2 should be used with ORB when WTA_K==3 or 4 (see ORB::ORB constructor + description). + @param crossCheck If it is false, this is will be default BFMatcher behaviour when it finds the k + nearest neighbors for each query descriptor. If crossCheck==true, then the knnMatch() method with + k=1 will only return pairs (i,j) such that for i-th query descriptor the j-th descriptor in the + matcher's collection is the nearest and vice versa, i.e. the BFMatcher will only return consistent + pairs. Such technique usually produces best results with minimal number of outliers when there are + enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper. + */ + CV_WRAP static Ptr create( int normType=NORM_L2, bool crossCheck=false ) ; + + virtual Ptr clone( bool emptyTrainData=false ) const CV_OVERRIDE; +protected: + virtual void knnMatchImpl( InputArray queryDescriptors, std::vector >& matches, int k, + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; + virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector >& matches, float maxDistance, + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; + + int normType; + bool crossCheck; +}; + +#if defined(HAVE_OPENCV_FLANN) || defined(CV_DOXYGEN) + +/** @brief Flann-based descriptor matcher. + +This matcher trains cv::flann::Index on a train descriptor collection and calls its nearest search +methods to find the best matches. So, this matcher may be faster when matching a large train +collection than the brute force matcher. FlannBasedMatcher does not support masking permissible +matches of descriptor sets because flann::Index does not support this. : + */ +class CV_EXPORTS_W FlannBasedMatcher : public DescriptorMatcher +{ +public: + CV_WRAP FlannBasedMatcher( const Ptr& indexParams=makePtr(), + const Ptr& searchParams=makePtr() ); + + virtual void add( InputArrayOfArrays descriptors ) CV_OVERRIDE; + virtual void clear() CV_OVERRIDE; + + // Reads matcher object from a file node + virtual void read( const FileNode& ) CV_OVERRIDE; + // Writes matcher object to a file storage + virtual void write( FileStorage& ) const CV_OVERRIDE; + + virtual void train() CV_OVERRIDE; + virtual bool isMaskSupported() const CV_OVERRIDE; + + CV_WRAP static Ptr create(); + + virtual Ptr clone( bool emptyTrainData=false ) const CV_OVERRIDE; +protected: + static void convertToDMatches( const DescriptorCollection& descriptors, + const Mat& indices, const Mat& distances, + std::vector >& matches ); + + virtual void knnMatchImpl( InputArray queryDescriptors, std::vector >& matches, int k, + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; + virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector >& matches, float maxDistance, + InputArrayOfArrays masks=noArray(), bool compactResult=false ) CV_OVERRIDE; + + Ptr indexParams; + Ptr searchParams; + Ptr flannIndex; + + DescriptorCollection mergedDescriptors; + int addedDescCount; +}; + +#endif + +//! @} features2d_match + +/****************************************************************************************\ +* Drawing functions * +\****************************************************************************************/ + +//! @addtogroup features2d_draw +//! @{ + +enum struct DrawMatchesFlags +{ + DEFAULT = 0, //!< Output image matrix will be created (Mat::create), + //!< i.e. existing memory of output image may be reused. + //!< Two source image, matches and single keypoints will be drawn. + //!< For each keypoint only the center point will be drawn (without + //!< the circle around keypoint with keypoint size and orientation). + DRAW_OVER_OUTIMG = 1, //!< Output image matrix will not be created (Mat::create). + //!< Matches will be drawn on existing content of output image. + NOT_DRAW_SINGLE_POINTS = 2, //!< Single keypoints will not be drawn. + DRAW_RICH_KEYPOINTS = 4 //!< For each keypoint the circle around keypoint with keypoint size and + //!< orientation will be drawn. +}; +CV_ENUM_FLAGS(DrawMatchesFlags) + +/** @brief Draws keypoints. + +@param image Source image. +@param keypoints Keypoints from the source image. +@param outImage Output image. Its content depends on the flags value defining what is drawn in the +output image. See possible flags bit values below. +@param color Color of keypoints. +@param flags Flags setting drawing features. Possible flags bit values are defined by +DrawMatchesFlags. See details above in drawMatches . + +@note +For Python API, flags are modified as cv.DRAW_MATCHES_FLAGS_DEFAULT, +cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG, +cv.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS + */ +CV_EXPORTS_W void drawKeypoints( InputArray image, const std::vector& keypoints, InputOutputArray outImage, + const Scalar& color=Scalar::all(-1), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); + +/** @brief Draws the found matches of keypoints from two images. + +@param img1 First source image. +@param keypoints1 Keypoints from the first source image. +@param img2 Second source image. +@param keypoints2 Keypoints from the second source image. +@param matches1to2 Matches from the first image to the second one, which means that keypoints1[i] +has a corresponding point in keypoints2[matches[i]] . +@param outImg Output image. Its content depends on the flags value defining what is drawn in the +output image. See possible flags bit values below. +@param matchColor Color of matches (lines and connected keypoints). If matchColor==Scalar::all(-1) +, the color is generated randomly. +@param singlePointColor Color of single keypoints (circles), which means that keypoints do not +have the matches. If singlePointColor==Scalar::all(-1) , the color is generated randomly. +@param matchesMask Mask determining which matches are drawn. If the mask is empty, all matches are +drawn. +@param flags Flags setting drawing features. Possible flags bit values are defined by +DrawMatchesFlags. + +This function draws matches of keypoints from two images in the output image. Match is a line +connecting two keypoints (circles). See cv::DrawMatchesFlags. + */ +CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector& keypoints1, + InputArray img2, const std::vector& keypoints2, + const std::vector& matches1to2, InputOutputArray outImg, + const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1), + const std::vector& matchesMask=std::vector(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); + +/** @overload */ +CV_EXPORTS_AS(drawMatchesKnn) void drawMatches( InputArray img1, const std::vector& keypoints1, + InputArray img2, const std::vector& keypoints2, + const std::vector >& matches1to2, InputOutputArray outImg, + const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1), + const std::vector >& matchesMask=std::vector >(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT ); + +//! @} features2d_draw + +/****************************************************************************************\ +* Functions to evaluate the feature detectors and [generic] descriptor extractors * +\****************************************************************************************/ + +CV_EXPORTS void evaluateFeatureDetector( const Mat& img1, const Mat& img2, const Mat& H1to2, + std::vector* keypoints1, std::vector* keypoints2, + float& repeatability, int& correspCount, + const Ptr& fdetector=Ptr() ); + +CV_EXPORTS void computeRecallPrecisionCurve( const std::vector >& matches1to2, + const std::vector >& correctMatches1to2Mask, + std::vector& recallPrecisionCurve ); + +CV_EXPORTS float getRecall( const std::vector& recallPrecisionCurve, float l_precision ); +CV_EXPORTS int getNearestPoint( const std::vector& recallPrecisionCurve, float l_precision ); + +/****************************************************************************************\ +* Bag of visual words * +\****************************************************************************************/ + +//! @addtogroup features2d_category +//! @{ + +/** @brief Abstract base class for training the *bag of visual words* vocabulary from a set of descriptors. + +For details, see, for example, *Visual Categorization with Bags of Keypoints* by Gabriella Csurka, +Christopher R. Dance, Lixin Fan, Jutta Willamowski, Cedric Bray, 2004. : + */ +class CV_EXPORTS_W BOWTrainer +{ +public: + BOWTrainer(); + virtual ~BOWTrainer(); + + /** @brief Adds descriptors to a training set. + + @param descriptors Descriptors to add to a training set. Each row of the descriptors matrix is a + descriptor. + + The training set is clustered using clustermethod to construct the vocabulary. + */ + CV_WRAP void add( const Mat& descriptors ); + + /** @brief Returns a training set of descriptors. + */ + CV_WRAP const std::vector& getDescriptors() const; + + /** @brief Returns the count of all descriptors stored in the training set. + */ + CV_WRAP int descriptorsCount() const; + + CV_WRAP virtual void clear(); + + /** @overload */ + CV_WRAP virtual Mat cluster() const = 0; + + /** @brief Clusters train descriptors. + + @param descriptors Descriptors to cluster. Each row of the descriptors matrix is a descriptor. + Descriptors are not added to the inner train descriptor set. + + The vocabulary consists of cluster centers. So, this method returns the vocabulary. In the first + variant of the method, train descriptors stored in the object are clustered. In the second variant, + input descriptors are clustered. + */ + CV_WRAP virtual Mat cluster( const Mat& descriptors ) const = 0; + +protected: + std::vector descriptors; + int size; +}; + +/** @brief kmeans -based class to train visual vocabulary using the *bag of visual words* approach. : + */ +class CV_EXPORTS_W BOWKMeansTrainer : public BOWTrainer +{ +public: + /** @brief The constructor. + + @see cv::kmeans + */ + CV_WRAP BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(), + int attempts=3, int flags=KMEANS_PP_CENTERS ); + virtual ~BOWKMeansTrainer(); + + // Returns trained vocabulary (i.e. cluster centers). + CV_WRAP virtual Mat cluster() const CV_OVERRIDE; + CV_WRAP virtual Mat cluster( const Mat& descriptors ) const CV_OVERRIDE; + +protected: + + int clusterCount; + TermCriteria termcrit; + int attempts; + int flags; +}; + +/** @brief Class to compute an image descriptor using the *bag of visual words*. + +Such a computation consists of the following steps: + +1. Compute descriptors for a given image and its keypoints set. +2. Find the nearest visual words from the vocabulary for each keypoint descriptor. +3. Compute the bag-of-words image descriptor as is a normalized histogram of vocabulary words +encountered in the image. The i-th bin of the histogram is a frequency of i-th word of the +vocabulary in the given image. + */ +class CV_EXPORTS_W BOWImgDescriptorExtractor +{ +public: + /** @brief The constructor. + + @param dextractor Descriptor extractor that is used to compute descriptors for an input image and + its keypoints. + @param dmatcher Descriptor matcher that is used to find the nearest word of the trained vocabulary + for each keypoint descriptor of the image. + */ + CV_WRAP BOWImgDescriptorExtractor( const Ptr& dextractor, + const Ptr& dmatcher ); + /** @overload */ + BOWImgDescriptorExtractor( const Ptr& dmatcher ); + virtual ~BOWImgDescriptorExtractor(); + + /** @brief Sets a visual vocabulary. + + @param vocabulary Vocabulary (can be trained using the inheritor of BOWTrainer ). Each row of the + vocabulary is a visual word (cluster center). + */ + CV_WRAP void setVocabulary( const Mat& vocabulary ); + + /** @brief Returns the set vocabulary. + */ + CV_WRAP const Mat& getVocabulary() const; + + /** @brief Computes an image descriptor using the set visual vocabulary. + + @param image Image, for which the descriptor is computed. + @param keypoints Keypoints detected in the input image. + @param imgDescriptor Computed output image descriptor. + @param pointIdxsOfClusters Indices of keypoints that belong to the cluster. This means that + pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster (word of vocabulary) + returned if it is non-zero. + @param descriptors Descriptors of the image keypoints that are returned if they are non-zero. + */ + void compute( InputArray image, std::vector& keypoints, OutputArray imgDescriptor, + std::vector >* pointIdxsOfClusters=0, Mat* descriptors=0 ); + /** @overload + @param keypointDescriptors Computed descriptors to match with vocabulary. + @param imgDescriptor Computed output image descriptor. + @param pointIdxsOfClusters Indices of keypoints that belong to the cluster. This means that + pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster (word of vocabulary) + returned if it is non-zero. + */ + void compute( InputArray keypointDescriptors, OutputArray imgDescriptor, + std::vector >* pointIdxsOfClusters=0 ); + // compute() is not constant because DescriptorMatcher::match is not constant + + CV_WRAP_AS(compute) void compute2( const Mat& image, std::vector& keypoints, CV_OUT Mat& imgDescriptor ) + { compute(image,keypoints,imgDescriptor); } + + /** @brief Returns an image descriptor size if the vocabulary is set. Otherwise, it returns 0. + */ + CV_WRAP int descriptorSize() const; + + /** @brief Returns an image descriptor type. + */ + CV_WRAP int descriptorType() const; + +protected: + Mat vocabulary; + Ptr dextractor; + Ptr dmatcher; +}; + +//! @} features2d_category + +//! @} features2d + +} /* namespace cv */ + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/features2d/features2d.hpp b/Prj-Win/3rd/opencv/include/opencv2/features2d/features2d.hpp new file mode 100755 index 0000000..e81df0a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/features2d/features2d.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/features2d.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/features2d/hal/interface.h b/Prj-Win/3rd/opencv/include/opencv2/features2d/hal/interface.h new file mode 100755 index 0000000..bcc6577 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/features2d/hal/interface.h @@ -0,0 +1,33 @@ +#ifndef OPENCV_FEATURE2D_HAL_INTERFACE_H +#define OPENCV_FEATURE2D_HAL_INTERFACE_H + +#include "opencv2/core/cvdef.h" +//! @addtogroup featrure2d_hal_interface +//! @{ + +//! @name Fast feature detector types +//! @sa cv::FastFeatureDetector +//! @{ +#define CV_HAL_TYPE_5_8 0 +#define CV_HAL_TYPE_7_12 1 +#define CV_HAL_TYPE_9_16 2 +//! @} + +//! @name Key point +//! @sa cv::KeyPoint +//! @{ +struct CV_EXPORTS cvhalKeyPoint +{ + float x; + float y; + float size; + float angle; + float response; + int octave; + int class_id; +}; +//! @} + +//! @} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann.hpp b/Prj-Win/3rd/opencv/include/opencv2/flann.hpp new file mode 100755 index 0000000..050b5f7 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann.hpp @@ -0,0 +1,596 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_FLANN_HPP +#define OPENCV_FLANN_HPP + +#include "opencv2/core.hpp" +#include "opencv2/flann/miniflann.hpp" +#include "opencv2/flann/flann_base.hpp" + +/** +@defgroup flann Clustering and Search in Multi-Dimensional Spaces + +This section documents OpenCV's interface to the FLANN library. FLANN (Fast Library for Approximate +Nearest Neighbors) is a library that contains a collection of algorithms optimized for fast nearest +neighbor search in large datasets and for high dimensional features. More information about FLANN +can be found in @cite Muja2009 . +*/ + +namespace cvflann +{ + CV_EXPORTS flann_distance_t flann_distance_type(); + CV_DEPRECATED CV_EXPORTS void set_distance_type(flann_distance_t distance_type, int order); +} + + +namespace cv +{ +namespace flann +{ + + +//! @addtogroup flann +//! @{ + +template struct CvType {}; +template <> struct CvType { static int type() { return CV_8U; } }; +template <> struct CvType { static int type() { return CV_8S; } }; +template <> struct CvType { static int type() { return CV_16U; } }; +template <> struct CvType { static int type() { return CV_16S; } }; +template <> struct CvType { static int type() { return CV_32S; } }; +template <> struct CvType { static int type() { return CV_32F; } }; +template <> struct CvType { static int type() { return CV_64F; } }; + + +// bring the flann parameters into this namespace +using ::cvflann::get_param; +using ::cvflann::print_params; + +// bring the flann distances into this namespace +using ::cvflann::L2_Simple; +using ::cvflann::L2; +using ::cvflann::L1; +using ::cvflann::MinkowskiDistance; +using ::cvflann::MaxDistance; +using ::cvflann::HammingLUT; +using ::cvflann::Hamming; +using ::cvflann::Hamming2; +using ::cvflann::HistIntersectionDistance; +using ::cvflann::HellingerDistance; +using ::cvflann::ChiSquareDistance; +using ::cvflann::KL_Divergence; + + +/** @brief The FLANN nearest neighbor index class. This class is templated with the type of elements for which +the index is built. + +`Distance` functor specifies the metric to be used to calculate the distance between two points. +There are several `Distance` functors that are readily available: + +@link cvflann::L2_Simple cv::flann::L2_Simple @endlink- Squared Euclidean distance functor. +This is the simpler, unrolled version. This is preferable for very low dimensionality data (eg 3D points) + +@link cvflann::L2 cv::flann::L2 @endlink- Squared Euclidean distance functor, optimized version. + +@link cvflann::L1 cv::flann::L1 @endlink - Manhattan distance functor, optimized version. + +@link cvflann::MinkowskiDistance cv::flann::MinkowskiDistance @endlink - The Minkowsky distance functor. +This is highly optimised with loop unrolling. +The computation of squared root at the end is omitted for efficiency. + +@link cvflann::MaxDistance cv::flann::MaxDistance @endlink - The max distance functor. It computes the +maximum distance between two vectors. This distance is not a valid kdtree distance, it's not +dimensionwise additive. + +@link cvflann::HammingLUT cv::flann::HammingLUT @endlink - %Hamming distance functor. It counts the bit +differences between two strings using a lookup table implementation. + +@link cvflann::Hamming cv::flann::Hamming @endlink - %Hamming distance functor. Population count is +performed using library calls, if available. Lookup table implementation is used as a fallback. + +@link cvflann::Hamming2 cv::flann::Hamming2 @endlink- %Hamming distance functor. Population count is +implemented in 12 arithmetic operations (one of which is multiplication). + +@link cvflann::HistIntersectionDistance cv::flann::HistIntersectionDistance @endlink - The histogram +intersection distance functor. + +@link cvflann::HellingerDistance cv::flann::HellingerDistance @endlink - The Hellinger distance functor. + +@link cvflann::ChiSquareDistance cv::flann::ChiSquareDistance @endlink - The chi-square distance functor. + +@link cvflann::KL_Divergence cv::flann::KL_Divergence @endlink - The Kullback-Leibler divergence functor. + +Although the provided implementations cover a vast range of cases, it is also possible to use +a custom implementation. The distance functor is a class whose `operator()` computes the distance +between two features. If the distance is also a kd-tree compatible distance, it should also provide an +`accum_dist()` method that computes the distance between individual feature dimensions. + +In addition to `operator()` and `accum_dist()`, a distance functor should also define the +`ElementType` and the `ResultType` as the types of the elements it operates on and the type of the +result it computes. If a distance functor can be used as a kd-tree distance (meaning that the full +distance between a pair of features can be accumulated from the partial distances between the +individual dimensions) a typedef `is_kdtree_distance` should be present inside the distance functor. +If the distance is not a kd-tree distance, but it's a distance in a vector space (the individual +dimensions of the elements it operates on can be accessed independently) a typedef +`is_vector_space_distance` should be defined inside the functor. If neither typedef is defined, the +distance is assumed to be a metric distance and will only be used with indexes operating on +generic metric distances. + */ +template +class GenericIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + /** @brief Constructs a nearest neighbor search index for a given dataset. + + @param features Matrix of containing the features(points) to index. The size of the matrix is + num_features x feature_dimensionality and the data type of the elements in the matrix must + coincide with the type of the index. + @param params Structure containing the index parameters. The type of index that will be + constructed depends on the type of this parameter. See the description. + @param distance + + The method constructs a fast search structure from a set of features using the specified algorithm + with specified parameters, as defined by params. params is a reference to one of the following class + IndexParams descendants: + + - **LinearIndexParams** When passing an object of this type, the index will perform a linear, + brute-force search. : + @code + struct LinearIndexParams : public IndexParams + { + }; + @endcode + - **KDTreeIndexParams** When passing an object of this type the index constructed will consist of + a set of randomized kd-trees which will be searched in parallel. : + @code + struct KDTreeIndexParams : public IndexParams + { + KDTreeIndexParams( int trees = 4 ); + }; + @endcode + - **KMeansIndexParams** When passing an object of this type the index constructed will be a + hierarchical k-means tree. : + @code + struct KMeansIndexParams : public IndexParams + { + KMeansIndexParams( + int branching = 32, + int iterations = 11, + flann_centers_init_t centers_init = CENTERS_RANDOM, + float cb_index = 0.2 ); + }; + @endcode + - **CompositeIndexParams** When using a parameters object of this type the index created + combines the randomized kd-trees and the hierarchical k-means tree. : + @code + struct CompositeIndexParams : public IndexParams + { + CompositeIndexParams( + int trees = 4, + int branching = 32, + int iterations = 11, + flann_centers_init_t centers_init = CENTERS_RANDOM, + float cb_index = 0.2 ); + }; + @endcode + - **LshIndexParams** When using a parameters object of this type the index created uses + multi-probe LSH (by Multi-Probe LSH: Efficient Indexing for High-Dimensional Similarity Search + by Qin Lv, William Josephson, Zhe Wang, Moses Charikar, Kai Li., Proceedings of the 33rd + International Conference on Very Large Data Bases (VLDB). Vienna, Austria. September 2007) : + @code + struct LshIndexParams : public IndexParams + { + LshIndexParams( + unsigned int table_number, + unsigned int key_size, + unsigned int multi_probe_level ); + }; + @endcode + - **AutotunedIndexParams** When passing an object of this type the index created is + automatically tuned to offer the best performance, by choosing the optimal index type + (randomized kd-trees, hierarchical kmeans, linear) and parameters for the dataset provided. : + @code + struct AutotunedIndexParams : public IndexParams + { + AutotunedIndexParams( + float target_precision = 0.9, + float build_weight = 0.01, + float memory_weight = 0, + float sample_fraction = 0.1 ); + }; + @endcode + - **SavedIndexParams** This object type is used for loading a previously saved index from the + disk. : + @code + struct SavedIndexParams : public IndexParams + { + SavedIndexParams( String filename ); + }; + @endcode + */ + GenericIndex(const Mat& features, const ::cvflann::IndexParams& params, Distance distance = Distance()); + + ~GenericIndex(); + + /** @brief Performs a K-nearest neighbor search for a given query point using the index. + + @param query The query point + @param indices Vector that will contain the indices of the K-nearest neighbors found. It must have + at least knn size. + @param dists Vector that will contain the distances to the K-nearest neighbors found. It must have + at least knn size. + @param knn Number of nearest neighbors to search for. + @param params SearchParams + */ + void knnSearch(const std::vector& query, std::vector& indices, + std::vector& dists, int knn, const ::cvflann::SearchParams& params); + void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params); + + /** @brief Performs a radius nearest neighbor search for a given query point using the index. + + @param query The query point. + @param indices Vector that will contain the indices of the nearest neighbors found. + @param dists Vector that will contain the distances to the nearest neighbors found. It has the same + number of elements as indices. + @param radius The search radius. + @param params SearchParams + + This function returns the number of nearest neighbors found. + */ + int radiusSearch(const std::vector& query, std::vector& indices, + std::vector& dists, DistanceType radius, const ::cvflann::SearchParams& params); + int radiusSearch(const Mat& query, Mat& indices, Mat& dists, + DistanceType radius, const ::cvflann::SearchParams& params); + + void save(String filename) { nnIndex->save(filename); } + + int veclen() const { return nnIndex->veclen(); } + + int size() const { return (int)nnIndex->size(); } + + ::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); } + + CV_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() { return nnIndex->getIndexParameters(); } + +private: + ::cvflann::Index* nnIndex; + Mat _dataset; +}; + +//! @cond IGNORED + +#define FLANN_DISTANCE_CHECK \ + if ( ::cvflann::flann_distance_type() != cvflann::FLANN_DIST_L2) { \ + printf("[WARNING] You are using cv::flann::Index (or cv::flann::GenericIndex) and have also changed "\ + "the distance using cvflann::set_distance_type. This is no longer working as expected "\ + "(cv::flann::Index always uses L2). You should create the index templated on the distance, "\ + "for example for L1 distance use: GenericIndex< L1 > \n"); \ + } + + +template +GenericIndex::GenericIndex(const Mat& dataset, const ::cvflann::IndexParams& params, Distance distance) +: _dataset(dataset) +{ + CV_Assert(dataset.type() == CvType::type()); + CV_Assert(dataset.isContinuous()); + ::cvflann::Matrix m_dataset((ElementType*)_dataset.ptr(0), _dataset.rows, _dataset.cols); + + nnIndex = new ::cvflann::Index(m_dataset, params, distance); + + FLANN_DISTANCE_CHECK + + nnIndex->buildIndex(); +} + +template +GenericIndex::~GenericIndex() +{ + delete nnIndex; +} + +template +void GenericIndex::knnSearch(const std::vector& query, std::vector& indices, std::vector& dists, int knn, const ::cvflann::SearchParams& searchParams) +{ + ::cvflann::Matrix m_query((ElementType*)&query[0], 1, query.size()); + ::cvflann::Matrix m_indices(&indices[0], 1, indices.size()); + ::cvflann::Matrix m_dists(&dists[0], 1, dists.size()); + + FLANN_DISTANCE_CHECK + + nnIndex->knnSearch(m_query,m_indices,m_dists,knn,searchParams); +} + + +template +void GenericIndex::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams) +{ + CV_Assert(queries.type() == CvType::type()); + CV_Assert(queries.isContinuous()); + ::cvflann::Matrix m_queries((ElementType*)queries.ptr(0), queries.rows, queries.cols); + + CV_Assert(indices.type() == CV_32S); + CV_Assert(indices.isContinuous()); + ::cvflann::Matrix m_indices((int*)indices.ptr(0), indices.rows, indices.cols); + + CV_Assert(dists.type() == CvType::type()); + CV_Assert(dists.isContinuous()); + ::cvflann::Matrix m_dists((DistanceType*)dists.ptr(0), dists.rows, dists.cols); + + FLANN_DISTANCE_CHECK + + nnIndex->knnSearch(m_queries,m_indices,m_dists,knn, searchParams); +} + +template +int GenericIndex::radiusSearch(const std::vector& query, std::vector& indices, std::vector& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) +{ + ::cvflann::Matrix m_query((ElementType*)&query[0], 1, query.size()); + ::cvflann::Matrix m_indices(&indices[0], 1, indices.size()); + ::cvflann::Matrix m_dists(&dists[0], 1, dists.size()); + + FLANN_DISTANCE_CHECK + + return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); +} + +template +int GenericIndex::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) +{ + CV_Assert(query.type() == CvType::type()); + CV_Assert(query.isContinuous()); + ::cvflann::Matrix m_query((ElementType*)query.ptr(0), query.rows, query.cols); + + CV_Assert(indices.type() == CV_32S); + CV_Assert(indices.isContinuous()); + ::cvflann::Matrix m_indices((int*)indices.ptr(0), indices.rows, indices.cols); + + CV_Assert(dists.type() == CvType::type()); + CV_Assert(dists.isContinuous()); + ::cvflann::Matrix m_dists((DistanceType*)dists.ptr(0), dists.rows, dists.cols); + + FLANN_DISTANCE_CHECK + + return nnIndex->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); +} + +//! @endcond + +/** + * @deprecated Use GenericIndex class instead + */ +template +class Index_ +{ +public: + typedef typename L2::ElementType ElementType; + typedef typename L2::ResultType DistanceType; + + CV_DEPRECATED Index_(const Mat& dataset, const ::cvflann::IndexParams& params) + { + printf("[WARNING] The cv::flann::Index_ class is deperecated, use cv::flann::GenericIndex instead\n"); + + CV_Assert(dataset.type() == CvType::type()); + CV_Assert(dataset.isContinuous()); + ::cvflann::Matrix m_dataset((ElementType*)dataset.ptr(0), dataset.rows, dataset.cols); + + if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) { + nnIndex_L1 = NULL; + nnIndex_L2 = new ::cvflann::Index< L2 >(m_dataset, params); + } + else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) { + nnIndex_L1 = new ::cvflann::Index< L1 >(m_dataset, params); + nnIndex_L2 = NULL; + } + else { + printf("[ERROR] cv::flann::Index_ only provides backwards compatibility for the L1 and L2 distances. " + "For other distance types you must use cv::flann::GenericIndex\n"); + CV_Assert(0); + } + if (nnIndex_L1) nnIndex_L1->buildIndex(); + if (nnIndex_L2) nnIndex_L2->buildIndex(); + } + CV_DEPRECATED ~Index_() + { + if (nnIndex_L1) delete nnIndex_L1; + if (nnIndex_L2) delete nnIndex_L2; + } + + CV_DEPRECATED void knnSearch(const std::vector& query, std::vector& indices, std::vector& dists, int knn, const ::cvflann::SearchParams& searchParams) + { + ::cvflann::Matrix m_query((ElementType*)&query[0], 1, query.size()); + ::cvflann::Matrix m_indices(&indices[0], 1, indices.size()); + ::cvflann::Matrix m_dists(&dists[0], 1, dists.size()); + + if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams); + if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams); + } + CV_DEPRECATED void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams) + { + CV_Assert(queries.type() == CvType::type()); + CV_Assert(queries.isContinuous()); + ::cvflann::Matrix m_queries((ElementType*)queries.ptr(0), queries.rows, queries.cols); + + CV_Assert(indices.type() == CV_32S); + CV_Assert(indices.isContinuous()); + ::cvflann::Matrix m_indices((int*)indices.ptr(0), indices.rows, indices.cols); + + CV_Assert(dists.type() == CvType::type()); + CV_Assert(dists.isContinuous()); + ::cvflann::Matrix m_dists((DistanceType*)dists.ptr(0), dists.rows, dists.cols); + + if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams); + if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams); + } + + CV_DEPRECATED int radiusSearch(const std::vector& query, std::vector& indices, std::vector& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) + { + ::cvflann::Matrix m_query((ElementType*)&query[0], 1, query.size()); + ::cvflann::Matrix m_indices(&indices[0], 1, indices.size()); + ::cvflann::Matrix m_dists(&dists[0], 1, dists.size()); + + if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); + if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); + } + + CV_DEPRECATED int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams) + { + CV_Assert(query.type() == CvType::type()); + CV_Assert(query.isContinuous()); + ::cvflann::Matrix m_query((ElementType*)query.ptr(0), query.rows, query.cols); + + CV_Assert(indices.type() == CV_32S); + CV_Assert(indices.isContinuous()); + ::cvflann::Matrix m_indices((int*)indices.ptr(0), indices.rows, indices.cols); + + CV_Assert(dists.type() == CvType::type()); + CV_Assert(dists.isContinuous()); + ::cvflann::Matrix m_dists((DistanceType*)dists.ptr(0), dists.rows, dists.cols); + + if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); + if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams); + } + + CV_DEPRECATED void save(String filename) + { + if (nnIndex_L1) nnIndex_L1->save(filename); + if (nnIndex_L2) nnIndex_L2->save(filename); + } + + CV_DEPRECATED int veclen() const + { + if (nnIndex_L1) return nnIndex_L1->veclen(); + if (nnIndex_L2) return nnIndex_L2->veclen(); + } + + CV_DEPRECATED int size() const + { + if (nnIndex_L1) return nnIndex_L1->size(); + if (nnIndex_L2) return nnIndex_L2->size(); + } + + CV_DEPRECATED ::cvflann::IndexParams getParameters() + { + if (nnIndex_L1) return nnIndex_L1->getParameters(); + if (nnIndex_L2) return nnIndex_L2->getParameters(); + + } + + CV_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() + { + if (nnIndex_L1) return nnIndex_L1->getIndexParameters(); + if (nnIndex_L2) return nnIndex_L2->getIndexParameters(); + } + +private: + // providing backwards compatibility for L2 and L1 distances (most common) + ::cvflann::Index< L2 >* nnIndex_L2; + ::cvflann::Index< L1 >* nnIndex_L1; +}; + + +/** @brief Clusters features using hierarchical k-means algorithm. + +@param features The points to be clustered. The matrix must have elements of type +Distance::ElementType. +@param centers The centers of the clusters obtained. The matrix must have type +Distance::ResultType. The number of rows in this matrix represents the number of clusters desired, +however, because of the way the cut in the hierarchical tree is chosen, the number of clusters +computed will be the highest number of the form (branching-1)\*k+1 that's lower than the number of +clusters desired, where branching is the tree's branching factor (see description of the +KMeansIndexParams). +@param params Parameters used in the construction of the hierarchical k-means tree. +@param d Distance to be used for clustering. + +The method clusters the given feature vectors by constructing a hierarchical k-means tree and +choosing a cut in the tree that minimizes the cluster's variance. It returns the number of clusters +found. + */ +template +int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params, + Distance d = Distance()) +{ + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + CV_Assert(features.type() == CvType::type()); + CV_Assert(features.isContinuous()); + ::cvflann::Matrix m_features((ElementType*)features.ptr(0), features.rows, features.cols); + + CV_Assert(centers.type() == CvType::type()); + CV_Assert(centers.isContinuous()); + ::cvflann::Matrix m_centers((DistanceType*)centers.ptr(0), centers.rows, centers.cols); + + return ::cvflann::hierarchicalClustering(m_features, m_centers, params, d); +} + +/** @deprecated +*/ +template +CV_DEPRECATED int hierarchicalClustering(const Mat& features, Mat& centers, const ::cvflann::KMeansIndexParams& params) +{ + printf("[WARNING] cv::flann::hierarchicalClustering is deprecated, use " + "cv::flann::hierarchicalClustering instead\n"); + + if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) { + return hierarchicalClustering< L2 >(features, centers, params); + } + else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) { + return hierarchicalClustering< L1 >(features, centers, params); + } + else { + printf("[ERROR] cv::flann::hierarchicalClustering only provides backwards " + "compatibility for the L1 and L2 distances. " + "For other distance types you must use cv::flann::hierarchicalClustering\n"); + CV_Assert(0); + } +} + +//! @} flann + +} } // namespace cv::flann + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/all_indices.h b/Prj-Win/3rd/opencv/include/opencv2/flann/all_indices.h new file mode 100755 index 0000000..ff53fd8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/all_indices.h @@ -0,0 +1,155 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + + +#ifndef OPENCV_FLANN_ALL_INDICES_H_ +#define OPENCV_FLANN_ALL_INDICES_H_ + +#include "general.h" + +#include "nn_index.h" +#include "kdtree_index.h" +#include "kdtree_single_index.h" +#include "kmeans_index.h" +#include "composite_index.h" +#include "linear_index.h" +#include "hierarchical_clustering_index.h" +#include "lsh_index.h" +#include "autotuned_index.h" + + +namespace cvflann +{ + +template +struct index_creator +{ + static NNIndex* create(const Matrix& dataset, const IndexParams& params, const Distance& distance) + { + flann_algorithm_t index_type = get_param(params, "algorithm"); + + NNIndex* nnIndex; + switch (index_type) { + case FLANN_INDEX_LINEAR: + nnIndex = new LinearIndex(dataset, params, distance); + break; + case FLANN_INDEX_KDTREE_SINGLE: + nnIndex = new KDTreeSingleIndex(dataset, params, distance); + break; + case FLANN_INDEX_KDTREE: + nnIndex = new KDTreeIndex(dataset, params, distance); + break; + case FLANN_INDEX_KMEANS: + nnIndex = new KMeansIndex(dataset, params, distance); + break; + case FLANN_INDEX_COMPOSITE: + nnIndex = new CompositeIndex(dataset, params, distance); + break; + case FLANN_INDEX_AUTOTUNED: + nnIndex = new AutotunedIndex(dataset, params, distance); + break; + case FLANN_INDEX_HIERARCHICAL: + nnIndex = new HierarchicalClusteringIndex(dataset, params, distance); + break; + case FLANN_INDEX_LSH: + nnIndex = new LshIndex(dataset, params, distance); + break; + default: + throw FLANNException("Unknown index type"); + } + + return nnIndex; + } +}; + +template +struct index_creator +{ + static NNIndex* create(const Matrix& dataset, const IndexParams& params, const Distance& distance) + { + flann_algorithm_t index_type = get_param(params, "algorithm"); + + NNIndex* nnIndex; + switch (index_type) { + case FLANN_INDEX_LINEAR: + nnIndex = new LinearIndex(dataset, params, distance); + break; + case FLANN_INDEX_KMEANS: + nnIndex = new KMeansIndex(dataset, params, distance); + break; + case FLANN_INDEX_HIERARCHICAL: + nnIndex = new HierarchicalClusteringIndex(dataset, params, distance); + break; + case FLANN_INDEX_LSH: + nnIndex = new LshIndex(dataset, params, distance); + break; + default: + throw FLANNException("Unknown index type"); + } + + return nnIndex; + } +}; + +template +struct index_creator +{ + static NNIndex* create(const Matrix& dataset, const IndexParams& params, const Distance& distance) + { + flann_algorithm_t index_type = get_param(params, "algorithm"); + + NNIndex* nnIndex; + switch (index_type) { + case FLANN_INDEX_LINEAR: + nnIndex = new LinearIndex(dataset, params, distance); + break; + case FLANN_INDEX_HIERARCHICAL: + nnIndex = new HierarchicalClusteringIndex(dataset, params, distance); + break; + case FLANN_INDEX_LSH: + nnIndex = new LshIndex(dataset, params, distance); + break; + default: + throw FLANNException("Unknown index type"); + } + + return nnIndex; + } +}; + +template +NNIndex* create_index_by_type(const Matrix& dataset, const IndexParams& params, const Distance& distance) +{ + return index_creator::create(dataset, params,distance); +} + +} + +#endif /* OPENCV_FLANN_ALL_INDICES_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/allocator.h b/Prj-Win/3rd/opencv/include/opencv2/flann/allocator.h new file mode 100755 index 0000000..f347f88 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/allocator.h @@ -0,0 +1,192 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_ALLOCATOR_H_ +#define OPENCV_FLANN_ALLOCATOR_H_ + +#include +#include + + +namespace cvflann +{ + +/** + * Allocates (using C's malloc) a generic type T. + * + * Params: + * count = number of instances to allocate. + * Returns: pointer (of type T*) to memory buffer + */ +template +T* allocate(size_t count = 1) +{ + T* mem = (T*) ::malloc(sizeof(T)*count); + return mem; +} + + +/** + * Pooled storage allocator + * + * The following routines allow for the efficient allocation of storage in + * small chunks from a specified pool. Rather than allowing each structure + * to be freed individually, an entire pool of storage is freed at once. + * This method has two advantages over just using malloc() and free(). First, + * it is far more efficient for allocating small objects, as there is + * no overhead for remembering all the information needed to free each + * object or consolidating fragmented memory. Second, the decision about + * how long to keep an object is made at the time of allocation, and there + * is no need to track down all the objects to free them. + * + */ + +const size_t WORDSIZE=16; +const size_t BLOCKSIZE=8192; + +class PooledAllocator +{ + /* We maintain memory alignment to word boundaries by requiring that all + allocations be in multiples of the machine wordsize. */ + /* Size of machine word in bytes. Must be power of 2. */ + /* Minimum number of bytes requested at a time from the system. Must be multiple of WORDSIZE. */ + + + int remaining; /* Number of bytes left in current block of storage. */ + void* base; /* Pointer to base of current block of storage. */ + void* loc; /* Current location in block to next allocate memory. */ + int blocksize; + + +public: + int usedMemory; + int wastedMemory; + + /** + Default constructor. Initializes a new pool. + */ + PooledAllocator(int blockSize = BLOCKSIZE) + { + blocksize = blockSize; + remaining = 0; + base = NULL; + loc = NULL; + + usedMemory = 0; + wastedMemory = 0; + } + + /** + * Destructor. Frees all the memory allocated in this pool. + */ + ~PooledAllocator() + { + void* prev; + + while (base != NULL) { + prev = *((void**) base); /* Get pointer to prev block. */ + ::free(base); + base = prev; + } + } + + /** + * Returns a pointer to a piece of new memory of the given size in bytes + * allocated from the pool. + */ + void* allocateMemory(int size) + { + int blockSize; + + /* Round size up to a multiple of wordsize. The following expression + only works for WORDSIZE that is a power of 2, by masking last bits of + incremented size to zero. + */ + size = (size + (WORDSIZE - 1)) & ~(WORDSIZE - 1); + + /* Check whether a new block must be allocated. Note that the first word + of a block is reserved for a pointer to the previous block. + */ + if (size > remaining) { + + wastedMemory += remaining; + + /* Allocate new storage. */ + blockSize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ? + size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE; + + // use the standard C malloc to allocate memory + void* m = ::malloc(blockSize); + if (!m) { + fprintf(stderr,"Failed to allocate memory.\n"); + return NULL; + } + + /* Fill first word of new block with pointer to previous block. */ + ((void**) m)[0] = base; + base = m; + + int shift = 0; + //int shift = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1); + + remaining = blockSize - sizeof(void*) - shift; + loc = ((char*)m + sizeof(void*) + shift); + } + void* rloc = loc; + loc = (char*)loc + size; + remaining -= size; + + usedMemory += size; + + return rloc; + } + + /** + * Allocates (using this pool) a generic type T. + * + * Params: + * count = number of instances to allocate. + * Returns: pointer (of type T*) to memory buffer + */ + template + T* allocate(size_t count = 1) + { + T* mem = (T*) this->allocateMemory((int)(sizeof(T)*count)); + return mem; + } + +private: + PooledAllocator(const PooledAllocator &); // copy disabled + PooledAllocator& operator=(const PooledAllocator &); // assign disabled +}; + +} + +#endif //OPENCV_FLANN_ALLOCATOR_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/any.h b/Prj-Win/3rd/opencv/include/opencv2/flann/any.h new file mode 100755 index 0000000..5b57aa3 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/any.h @@ -0,0 +1,330 @@ +#ifndef OPENCV_FLANN_ANY_H_ +#define OPENCV_FLANN_ANY_H_ +/* + * (C) Copyright Christopher Diggins 2005-2011 + * (C) Copyright Pablo Aguilar 2005 + * (C) Copyright Kevlin Henney 2001 + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt + * + * Adapted for FLANN by Marius Muja + */ + +#include "defines.h" +#include +#include +#include + +namespace cvflann +{ + +namespace anyimpl +{ + +struct bad_any_cast +{ +}; + +struct empty_any +{ +}; + +inline std::ostream& operator <<(std::ostream& out, const empty_any&) +{ + out << "[empty_any]"; + return out; +} + +struct base_any_policy +{ + virtual void static_delete(void** x) = 0; + virtual void copy_from_value(void const* src, void** dest) = 0; + virtual void clone(void* const* src, void** dest) = 0; + virtual void move(void* const* src, void** dest) = 0; + virtual void* get_value(void** src) = 0; + virtual const void* get_value(void* const * src) = 0; + virtual ::size_t get_size() = 0; + virtual const std::type_info& type() = 0; + virtual void print(std::ostream& out, void* const* src) = 0; + virtual ~base_any_policy() {} +}; + +template +struct typed_base_any_policy : base_any_policy +{ + virtual ::size_t get_size() CV_OVERRIDE { return sizeof(T); } + virtual const std::type_info& type() CV_OVERRIDE { return typeid(T); } + +}; + +template +struct small_any_policy CV_FINAL : typed_base_any_policy +{ + virtual void static_delete(void**) CV_OVERRIDE { } + virtual void copy_from_value(void const* src, void** dest) CV_OVERRIDE + { + new (dest) T(* reinterpret_cast(src)); + } + virtual void clone(void* const* src, void** dest) CV_OVERRIDE { *dest = *src; } + virtual void move(void* const* src, void** dest) CV_OVERRIDE { *dest = *src; } + virtual void* get_value(void** src) CV_OVERRIDE { return reinterpret_cast(src); } + virtual const void* get_value(void* const * src) CV_OVERRIDE { return reinterpret_cast(src); } + virtual void print(std::ostream& out, void* const* src) CV_OVERRIDE { out << *reinterpret_cast(src); } +}; + +template +struct big_any_policy CV_FINAL : typed_base_any_policy +{ + virtual void static_delete(void** x) CV_OVERRIDE + { + if (* x) delete (* reinterpret_cast(x)); + *x = NULL; + } + virtual void copy_from_value(void const* src, void** dest) CV_OVERRIDE + { + *dest = new T(*reinterpret_cast(src)); + } + virtual void clone(void* const* src, void** dest) CV_OVERRIDE + { + *dest = new T(**reinterpret_cast(src)); + } + virtual void move(void* const* src, void** dest) CV_OVERRIDE + { + (*reinterpret_cast(dest))->~T(); + **reinterpret_cast(dest) = **reinterpret_cast(src); + } + virtual void* get_value(void** src) CV_OVERRIDE { return *src; } + virtual const void* get_value(void* const * src) CV_OVERRIDE { return *src; } + virtual void print(std::ostream& out, void* const* src) CV_OVERRIDE { out << *reinterpret_cast(*src); } +}; + +template<> inline void big_any_policy::print(std::ostream& out, void* const* src) +{ + out << int(*reinterpret_cast(*src)); +} + +template<> inline void big_any_policy::print(std::ostream& out, void* const* src) +{ + out << int(*reinterpret_cast(*src)); +} + +template<> inline void big_any_policy::print(std::ostream& out, void* const* src) +{ + out << (*reinterpret_cast(*src)).c_str(); +} + +template +struct choose_policy +{ + typedef big_any_policy type; +}; + +template +struct choose_policy +{ + typedef small_any_policy type; +}; + +struct any; + +/// Choosing the policy for an any type is illegal, but should never happen. +/// This is designed to throw a compiler error. +template<> +struct choose_policy +{ + typedef void type; +}; + +/// Specializations for small types. +#define SMALL_POLICY(TYPE) \ + template<> \ + struct choose_policy { typedef small_any_policy type; \ + } + +SMALL_POLICY(signed char); +SMALL_POLICY(unsigned char); +SMALL_POLICY(signed short); +SMALL_POLICY(unsigned short); +SMALL_POLICY(signed int); +SMALL_POLICY(unsigned int); +SMALL_POLICY(signed long); +SMALL_POLICY(unsigned long); +SMALL_POLICY(float); +SMALL_POLICY(bool); + +#undef SMALL_POLICY + +template +class SinglePolicy +{ + SinglePolicy(); + SinglePolicy(const SinglePolicy& other); + SinglePolicy& operator=(const SinglePolicy& other); + +public: + static base_any_policy* get_policy(); + +private: + static typename choose_policy::type policy; +}; + +template +typename choose_policy::type SinglePolicy::policy; + +/// This function will return a different policy for each type. +template +inline base_any_policy* SinglePolicy::get_policy() { return &policy; } + +} // namespace anyimpl + +struct any +{ +private: + // fields + anyimpl::base_any_policy* policy; + void* object; + +public: + /// Initializing constructor. + template + any(const T& x) + : policy(anyimpl::SinglePolicy::get_policy()), object(NULL) + { + assign(x); + } + + /// Empty constructor. + any() + : policy(anyimpl::SinglePolicy::get_policy()), object(NULL) + { } + + /// Special initializing constructor for string literals. + any(const char* x) + : policy(anyimpl::SinglePolicy::get_policy()), object(NULL) + { + assign(x); + } + + /// Copy constructor. + any(const any& x) + : policy(anyimpl::SinglePolicy::get_policy()), object(NULL) + { + assign(x); + } + + /// Destructor. + ~any() + { + policy->static_delete(&object); + } + + /// Assignment function from another any. + any& assign(const any& x) + { + reset(); + policy = x.policy; + policy->clone(&x.object, &object); + return *this; + } + + /// Assignment function. + template + any& assign(const T& x) + { + reset(); + policy = anyimpl::SinglePolicy::get_policy(); + policy->copy_from_value(&x, &object); + return *this; + } + + /// Assignment operator. + template + any& operator=(const T& x) + { + return assign(x); + } + + /// Assignment operator. Template-based version above doesn't work as expected. We need regular assignment operator here. + any& operator=(const any& x) + { + return assign(x); + } + + /// Assignment operator, specialed for literal strings. + /// They have types like const char [6] which don't work as expected. + any& operator=(const char* x) + { + return assign(x); + } + + /// Utility functions + any& swap(any& x) + { + std::swap(policy, x.policy); + std::swap(object, x.object); + return *this; + } + + /// Cast operator. You can only cast to the original type. + template + T& cast() + { + if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast(); + T* r = reinterpret_cast(policy->get_value(&object)); + return *r; + } + + /// Cast operator. You can only cast to the original type. + template + const T& cast() const + { + if (policy->type() != typeid(T)) throw anyimpl::bad_any_cast(); + const T* r = reinterpret_cast(policy->get_value(&object)); + return *r; + } + + /// Returns true if the any contains no value. + bool empty() const + { + return policy->type() == typeid(anyimpl::empty_any); + } + + /// Frees any allocated memory, and sets the value to NULL. + void reset() + { + policy->static_delete(&object); + policy = anyimpl::SinglePolicy::get_policy(); + } + + /// Returns true if the two types are the same. + bool compatible(const any& x) const + { + return policy->type() == x.policy->type(); + } + + /// Returns if the type is compatible with the policy + template + bool has_type() + { + return policy->type() == typeid(T); + } + + const std::type_info& type() const + { + return policy->type(); + } + + friend std::ostream& operator <<(std::ostream& out, const any& any_val); +}; + +inline std::ostream& operator <<(std::ostream& out, const any& any_val) +{ + any_val.policy->print(out,&any_val.object); + return out; +} + +} + +#endif // OPENCV_FLANN_ANY_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/autotuned_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/autotuned_index.h new file mode 100755 index 0000000..2fbc6c9 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/autotuned_index.h @@ -0,0 +1,591 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ +#ifndef OPENCV_FLANN_AUTOTUNED_INDEX_H_ +#define OPENCV_FLANN_AUTOTUNED_INDEX_H_ + +#include + +#include "general.h" +#include "nn_index.h" +#include "ground_truth.h" +#include "index_testing.h" +#include "sampling.h" +#include "kdtree_index.h" +#include "kdtree_single_index.h" +#include "kmeans_index.h" +#include "composite_index.h" +#include "linear_index.h" +#include "logger.h" + +namespace cvflann +{ + +template +NNIndex* create_index_by_type(const Matrix& dataset, const IndexParams& params, const Distance& distance); + + +struct AutotunedIndexParams : public IndexParams +{ + AutotunedIndexParams(float target_precision = 0.8, float build_weight = 0.01, float memory_weight = 0, float sample_fraction = 0.1) + { + (*this)["algorithm"] = FLANN_INDEX_AUTOTUNED; + // precision desired (used for autotuning, -1 otherwise) + (*this)["target_precision"] = target_precision; + // build tree time weighting factor + (*this)["build_weight"] = build_weight; + // index memory weighting factor + (*this)["memory_weight"] = memory_weight; + // what fraction of the dataset to use for autotuning + (*this)["sample_fraction"] = sample_fraction; + } +}; + + +template +class AutotunedIndex : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + AutotunedIndex(const Matrix& inputData, const IndexParams& params = AutotunedIndexParams(), Distance d = Distance()) : + dataset_(inputData), distance_(d) + { + target_precision_ = get_param(params, "target_precision",0.8f); + build_weight_ = get_param(params,"build_weight", 0.01f); + memory_weight_ = get_param(params, "memory_weight", 0.0f); + sample_fraction_ = get_param(params,"sample_fraction", 0.1f); + bestIndex_ = NULL; + speedup_ = 0; + } + + AutotunedIndex(const AutotunedIndex&); + AutotunedIndex& operator=(const AutotunedIndex&); + + virtual ~AutotunedIndex() + { + if (bestIndex_ != NULL) { + delete bestIndex_; + bestIndex_ = NULL; + } + } + + /** + * Method responsible with building the index. + */ + virtual void buildIndex() CV_OVERRIDE + { + std::ostringstream stream; + bestParams_ = estimateBuildParams(); + print_params(bestParams_, stream); + Logger::info("----------------------------------------------------\n"); + Logger::info("Autotuned parameters:\n"); + Logger::info("%s", stream.str().c_str()); + Logger::info("----------------------------------------------------\n"); + + bestIndex_ = create_index_by_type(dataset_, bestParams_, distance_); + bestIndex_->buildIndex(); + speedup_ = estimateSearchParams(bestSearchParams_); + stream.str(std::string()); + print_params(bestSearchParams_, stream); + Logger::info("----------------------------------------------------\n"); + Logger::info("Search parameters:\n"); + Logger::info("%s", stream.str().c_str()); + Logger::info("----------------------------------------------------\n"); + } + + /** + * Saves the index to a stream + */ + virtual void saveIndex(FILE* stream) CV_OVERRIDE + { + save_value(stream, (int)bestIndex_->getType()); + bestIndex_->saveIndex(stream); + save_value(stream, get_param(bestSearchParams_, "checks")); + } + + /** + * Loads the index from a stream + */ + virtual void loadIndex(FILE* stream) CV_OVERRIDE + { + int index_type; + + load_value(stream, index_type); + IndexParams params; + params["algorithm"] = (flann_algorithm_t)index_type; + bestIndex_ = create_index_by_type(dataset_, params, distance_); + bestIndex_->loadIndex(stream); + int checks; + load_value(stream, checks); + bestSearchParams_["checks"] = checks; + } + + /** + * Method that searches for nearest-neighbors + */ + virtual void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE + { + int checks = get_param(searchParams,"checks",FLANN_CHECKS_AUTOTUNED); + if (checks == FLANN_CHECKS_AUTOTUNED) { + bestIndex_->findNeighbors(result, vec, bestSearchParams_); + } + else { + bestIndex_->findNeighbors(result, vec, searchParams); + } + } + + + IndexParams getParameters() const CV_OVERRIDE + { + return bestIndex_->getParameters(); + } + + SearchParams getSearchParameters() const + { + return bestSearchParams_; + } + + float getSpeedup() const + { + return speedup_; + } + + + /** + * Number of features in this index. + */ + virtual size_t size() const CV_OVERRIDE + { + return bestIndex_->size(); + } + + /** + * The length of each vector in this index. + */ + virtual size_t veclen() const CV_OVERRIDE + { + return bestIndex_->veclen(); + } + + /** + * The amount of memory (in bytes) this index uses. + */ + virtual int usedMemory() const CV_OVERRIDE + { + return bestIndex_->usedMemory(); + } + + /** + * Algorithm name + */ + virtual flann_algorithm_t getType() const CV_OVERRIDE + { + return FLANN_INDEX_AUTOTUNED; + } + +private: + + struct CostData + { + float searchTimeCost; + float buildTimeCost; + float memoryCost; + float totalCost; + IndexParams params; + }; + + void evaluate_kmeans(CostData& cost) + { + StartStopTimer t; + int checks; + const int nn = 1; + + Logger::info("KMeansTree using params: max_iterations=%d, branching=%d\n", + get_param(cost.params,"iterations"), + get_param(cost.params,"branching")); + KMeansIndex kmeans(sampledDataset_, cost.params, distance_); + // measure index build time + t.start(); + kmeans.buildIndex(); + t.stop(); + float buildTime = (float)t.value; + + // measure search time + float searchTime = test_index_precision(kmeans, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn); + + float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float)); + cost.memoryCost = (kmeans.usedMemory() + datasetMemory) / datasetMemory; + cost.searchTimeCost = searchTime; + cost.buildTimeCost = buildTime; + Logger::info("KMeansTree buildTime=%g, searchTime=%g, build_weight=%g\n", buildTime, searchTime, build_weight_); + } + + + void evaluate_kdtree(CostData& cost) + { + StartStopTimer t; + int checks; + const int nn = 1; + + Logger::info("KDTree using params: trees=%d\n", get_param(cost.params,"trees")); + KDTreeIndex kdtree(sampledDataset_, cost.params, distance_); + + t.start(); + kdtree.buildIndex(); + t.stop(); + float buildTime = (float)t.value; + + //measure search time + float searchTime = test_index_precision(kdtree, sampledDataset_, testDataset_, gt_matches_, target_precision_, checks, distance_, nn); + + float datasetMemory = float(sampledDataset_.rows * sampledDataset_.cols * sizeof(float)); + cost.memoryCost = (kdtree.usedMemory() + datasetMemory) / datasetMemory; + cost.searchTimeCost = searchTime; + cost.buildTimeCost = buildTime; + Logger::info("KDTree buildTime=%g, searchTime=%g\n", buildTime, searchTime); + } + + + // struct KMeansSimpleDownhillFunctor { + // + // Autotune& autotuner; + // KMeansSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {} + // + // float operator()(int* params) { + // + // float maxFloat = numeric_limits::max(); + // + // if (params[0]<2) return maxFloat; + // if (params[1]<0) return maxFloat; + // + // CostData c; + // c.params["algorithm"] = KMEANS; + // c.params["centers-init"] = CENTERS_RANDOM; + // c.params["branching"] = params[0]; + // c.params["max-iterations"] = params[1]; + // + // autotuner.evaluate_kmeans(c); + // + // return c.timeCost; + // + // } + // }; + // + // struct KDTreeSimpleDownhillFunctor { + // + // Autotune& autotuner; + // KDTreeSimpleDownhillFunctor(Autotune& autotuner_) : autotuner(autotuner_) {} + // + // float operator()(int* params) { + // float maxFloat = numeric_limits::max(); + // + // if (params[0]<1) return maxFloat; + // + // CostData c; + // c.params["algorithm"] = KDTREE; + // c.params["trees"] = params[0]; + // + // autotuner.evaluate_kdtree(c); + // + // return c.timeCost; + // + // } + // }; + + + + void optimizeKMeans(std::vector& costs) + { + Logger::info("KMEANS, Step 1: Exploring parameter space\n"); + + // explore kmeans parameters space using combinations of the parameters below + int maxIterations[] = { 1, 5, 10, 15 }; + int branchingFactors[] = { 16, 32, 64, 128, 256 }; + + int kmeansParamSpaceSize = FLANN_ARRAY_LEN(maxIterations) * FLANN_ARRAY_LEN(branchingFactors); + costs.reserve(costs.size() + kmeansParamSpaceSize); + + // evaluate kmeans for all parameter combinations + for (size_t i = 0; i < FLANN_ARRAY_LEN(maxIterations); ++i) { + for (size_t j = 0; j < FLANN_ARRAY_LEN(branchingFactors); ++j) { + CostData cost; + cost.params["algorithm"] = FLANN_INDEX_KMEANS; + cost.params["centers_init"] = FLANN_CENTERS_RANDOM; + cost.params["iterations"] = maxIterations[i]; + cost.params["branching"] = branchingFactors[j]; + + evaluate_kmeans(cost); + costs.push_back(cost); + } + } + + // Logger::info("KMEANS, Step 2: simplex-downhill optimization\n"); + // + // const int n = 2; + // // choose initial simplex points as the best parameters so far + // int kmeansNMPoints[n*(n+1)]; + // float kmeansVals[n+1]; + // for (int i=0;i& costs) + { + Logger::info("KD-TREE, Step 1: Exploring parameter space\n"); + + // explore kd-tree parameters space using the parameters below + int testTrees[] = { 1, 4, 8, 16, 32 }; + + // evaluate kdtree for all parameter combinations + for (size_t i = 0; i < FLANN_ARRAY_LEN(testTrees); ++i) { + CostData cost; + cost.params["algorithm"] = FLANN_INDEX_KDTREE; + cost.params["trees"] = testTrees[i]; + + evaluate_kdtree(cost); + costs.push_back(cost); + } + + // Logger::info("KD-TREE, Step 2: simplex-downhill optimization\n"); + // + // const int n = 1; + // // choose initial simplex points as the best parameters so far + // int kdtreeNMPoints[n*(n+1)]; + // float kdtreeVals[n+1]; + // for (int i=0;i costs; + + int sampleSize = int(sample_fraction_ * dataset_.rows); + int testSampleSize = std::min(sampleSize / 10, 1000); + + Logger::info("Entering autotuning, dataset size: %d, sampleSize: %d, testSampleSize: %d, target precision: %g\n", dataset_.rows, sampleSize, testSampleSize, target_precision_); + + // For a very small dataset, it makes no sense to build any fancy index, just + // use linear search + if (testSampleSize < 10) { + Logger::info("Choosing linear, dataset too small\n"); + return LinearIndexParams(); + } + + // We use a fraction of the original dataset to speedup the autotune algorithm + sampledDataset_ = random_sample(dataset_, sampleSize); + // We use a cross-validation approach, first we sample a testset from the dataset + testDataset_ = random_sample(sampledDataset_, testSampleSize, true); + + // We compute the ground truth using linear search + Logger::info("Computing ground truth... \n"); + gt_matches_ = Matrix(new int[testDataset_.rows], testDataset_.rows, 1); + StartStopTimer t; + t.start(); + compute_ground_truth(sampledDataset_, testDataset_, gt_matches_, 0, distance_); + t.stop(); + + CostData linear_cost; + linear_cost.searchTimeCost = (float)t.value; + linear_cost.buildTimeCost = 0; + linear_cost.memoryCost = 0; + linear_cost.params["algorithm"] = FLANN_INDEX_LINEAR; + + costs.push_back(linear_cost); + + // Start parameter autotune process + Logger::info("Autotuning parameters...\n"); + + optimizeKMeans(costs); + optimizeKDTree(costs); + + float bestTimeCost = costs[0].searchTimeCost; + for (size_t i = 0; i < costs.size(); ++i) { + float timeCost = costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost; + if (timeCost < bestTimeCost) { + bestTimeCost = timeCost; + } + } + + float bestCost = costs[0].searchTimeCost / bestTimeCost; + IndexParams bestParams = costs[0].params; + if (bestTimeCost > 0) { + for (size_t i = 0; i < costs.size(); ++i) { + float crtCost = (costs[i].buildTimeCost * build_weight_ + costs[i].searchTimeCost) / bestTimeCost + + memory_weight_ * costs[i].memoryCost; + if (crtCost < bestCost) { + bestCost = crtCost; + bestParams = costs[i].params; + } + } + } + + delete[] gt_matches_.data; + delete[] testDataset_.data; + delete[] sampledDataset_.data; + + return bestParams; + } + + + + /** + * Estimates the search time parameters needed to get the desired precision. + * Precondition: the index is built + * Postcondition: the searchParams will have the optimum params set, also the speedup obtained over linear search. + */ + float estimateSearchParams(SearchParams& searchParams) + { + const int nn = 1; + const size_t SAMPLE_COUNT = 1000; + + assert(bestIndex_ != NULL); // must have a valid index + + float speedup = 0; + + int samples = (int)std::min(dataset_.rows / 10, SAMPLE_COUNT); + if (samples > 0) { + Matrix testDataset = random_sample(dataset_, samples); + + Logger::info("Computing ground truth\n"); + + // we need to compute the ground truth first + Matrix gt_matches(new int[testDataset.rows], testDataset.rows, 1); + StartStopTimer t; + t.start(); + compute_ground_truth(dataset_, testDataset, gt_matches, 1, distance_); + t.stop(); + float linear = (float)t.value; + + int checks; + Logger::info("Estimating number of checks\n"); + + float searchTime; + float cb_index; + if (bestIndex_->getType() == FLANN_INDEX_KMEANS) { + Logger::info("KMeans algorithm, estimating cluster border factor\n"); + KMeansIndex* kmeans = (KMeansIndex*)bestIndex_; + float bestSearchTime = -1; + float best_cb_index = -1; + int best_checks = -1; + for (cb_index = 0; cb_index < 1.1f; cb_index += 0.2f) { + kmeans->set_cb_index(cb_index); + searchTime = test_index_precision(*kmeans, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1); + if ((searchTime < bestSearchTime) || (bestSearchTime == -1)) { + bestSearchTime = searchTime; + best_cb_index = cb_index; + best_checks = checks; + } + } + searchTime = bestSearchTime; + cb_index = best_cb_index; + checks = best_checks; + + kmeans->set_cb_index(best_cb_index); + Logger::info("Optimum cb_index: %g\n", cb_index); + bestParams_["cb_index"] = cb_index; + } + else { + searchTime = test_index_precision(*bestIndex_, dataset_, testDataset, gt_matches, target_precision_, checks, distance_, nn, 1); + } + + Logger::info("Required number of checks: %d \n", checks); + searchParams["checks"] = checks; + + speedup = linear / searchTime; + + delete[] gt_matches.data; + delete[] testDataset.data; + } + + return speedup; + } + +private: + NNIndex* bestIndex_; + + IndexParams bestParams_; + SearchParams bestSearchParams_; + + Matrix sampledDataset_; + Matrix testDataset_; + Matrix gt_matches_; + + float speedup_; + + /** + * The dataset used by this index + */ + const Matrix dataset_; + + /** + * Index parameters + */ + float target_precision_; + float build_weight_; + float memory_weight_; + float sample_fraction_; + + Distance distance_; + + +}; +} + +#endif /* OPENCV_FLANN_AUTOTUNED_INDEX_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/composite_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/composite_index.h new file mode 100755 index 0000000..5e12a17 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/composite_index.h @@ -0,0 +1,194 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_COMPOSITE_INDEX_H_ +#define OPENCV_FLANN_COMPOSITE_INDEX_H_ + +#include "general.h" +#include "nn_index.h" +#include "kdtree_index.h" +#include "kmeans_index.h" + +namespace cvflann +{ + +/** + * Index parameters for the CompositeIndex. + */ +struct CompositeIndexParams : public IndexParams +{ + CompositeIndexParams(int trees = 4, int branching = 32, int iterations = 11, + flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, float cb_index = 0.2 ) + { + (*this)["algorithm"] = FLANN_INDEX_KMEANS; + // number of randomized trees to use (for kdtree) + (*this)["trees"] = trees; + // branching factor + (*this)["branching"] = branching; + // max iterations to perform in one kmeans clustering (kmeans tree) + (*this)["iterations"] = iterations; + // algorithm used for picking the initial cluster centers for kmeans tree + (*this)["centers_init"] = centers_init; + // cluster boundary index. Used when searching the kmeans tree + (*this)["cb_index"] = cb_index; + } +}; + + +/** + * This index builds a kd-tree index and a k-means index and performs nearest + * neighbour search both indexes. This gives a slight boost in search performance + * as some of the neighbours that are missed by one index are found by the other. + */ +template +class CompositeIndex : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + /** + * Index constructor + * @param inputData dataset containing the points to index + * @param params Index parameters + * @param d Distance functor + * @return + */ + CompositeIndex(const Matrix& inputData, const IndexParams& params = CompositeIndexParams(), + Distance d = Distance()) : index_params_(params) + { + kdtree_index_ = new KDTreeIndex(inputData, params, d); + kmeans_index_ = new KMeansIndex(inputData, params, d); + + } + + CompositeIndex(const CompositeIndex&); + CompositeIndex& operator=(const CompositeIndex&); + + virtual ~CompositeIndex() + { + delete kdtree_index_; + delete kmeans_index_; + } + + /** + * @return The index type + */ + flann_algorithm_t getType() const CV_OVERRIDE + { + return FLANN_INDEX_COMPOSITE; + } + + /** + * @return Size of the index + */ + size_t size() const CV_OVERRIDE + { + return kdtree_index_->size(); + } + + /** + * \returns The dimensionality of the features in this index. + */ + size_t veclen() const CV_OVERRIDE + { + return kdtree_index_->veclen(); + } + + /** + * \returns The amount of memory (in bytes) used by the index. + */ + int usedMemory() const CV_OVERRIDE + { + return kmeans_index_->usedMemory() + kdtree_index_->usedMemory(); + } + + /** + * \brief Builds the index + */ + void buildIndex() CV_OVERRIDE + { + Logger::info("Building kmeans tree...\n"); + kmeans_index_->buildIndex(); + Logger::info("Building kdtree tree...\n"); + kdtree_index_->buildIndex(); + } + + /** + * \brief Saves the index to a stream + * \param stream The stream to save the index to + */ + void saveIndex(FILE* stream) CV_OVERRIDE + { + kmeans_index_->saveIndex(stream); + kdtree_index_->saveIndex(stream); + } + + /** + * \brief Loads the index from a stream + * \param stream The stream from which the index is loaded + */ + void loadIndex(FILE* stream) CV_OVERRIDE + { + kmeans_index_->loadIndex(stream); + kdtree_index_->loadIndex(stream); + } + + /** + * \returns The index parameters + */ + IndexParams getParameters() const CV_OVERRIDE + { + return index_params_; + } + + /** + * \brief Method that searches for nearest-neighbours + */ + void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE + { + kmeans_index_->findNeighbors(result, vec, searchParams); + kdtree_index_->findNeighbors(result, vec, searchParams); + } + +private: + /** The k-means index */ + KMeansIndex* kmeans_index_; + + /** The kd-tree index */ + KDTreeIndex* kdtree_index_; + + /** The index parameters */ + const IndexParams index_params_; +}; + +} + +#endif //OPENCV_FLANN_COMPOSITE_INDEX_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/config.h b/Prj-Win/3rd/opencv/include/opencv2/flann/config.h new file mode 100755 index 0000000..56832fd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/config.h @@ -0,0 +1,38 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + + +#ifndef OPENCV_FLANN_CONFIG_H_ +#define OPENCV_FLANN_CONFIG_H_ + +#ifdef FLANN_VERSION_ +#undef FLANN_VERSION_ +#endif +#define FLANN_VERSION_ "1.6.10" + +#endif /* OPENCV_FLANN_CONFIG_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/defines.h b/Prj-Win/3rd/opencv/include/opencv2/flann/defines.h new file mode 100755 index 0000000..6fd53c2 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/defines.h @@ -0,0 +1,164 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + + +#ifndef OPENCV_FLANN_DEFINES_H_ +#define OPENCV_FLANN_DEFINES_H_ + +#include "config.h" + +#ifdef FLANN_EXPORT +#undef FLANN_EXPORT +#endif +#ifdef _WIN32 +/* win32 dll export/import directives */ + #ifdef FLANN_EXPORTS + #define FLANN_EXPORT __declspec(dllexport) + #elif defined(FLANN_STATIC) + #define FLANN_EXPORT + #else + #define FLANN_EXPORT __declspec(dllimport) + #endif +#else +/* unix needs nothing */ + #define FLANN_EXPORT +#endif + + +#undef FLANN_PLATFORM_32_BIT +#undef FLANN_PLATFORM_64_BIT +#if defined __amd64__ || defined __x86_64__ || defined _WIN64 || defined _M_X64 +#define FLANN_PLATFORM_64_BIT +#else +#define FLANN_PLATFORM_32_BIT +#endif + + +#undef FLANN_ARRAY_LEN +#define FLANN_ARRAY_LEN(a) (sizeof(a)/sizeof(a[0])) + +namespace cvflann { + +/* Nearest neighbour index algorithms */ +enum flann_algorithm_t +{ + FLANN_INDEX_LINEAR = 0, + FLANN_INDEX_KDTREE = 1, + FLANN_INDEX_KMEANS = 2, + FLANN_INDEX_COMPOSITE = 3, + FLANN_INDEX_KDTREE_SINGLE = 4, + FLANN_INDEX_HIERARCHICAL = 5, + FLANN_INDEX_LSH = 6, + FLANN_INDEX_SAVED = 254, + FLANN_INDEX_AUTOTUNED = 255, + + // deprecated constants, should use the FLANN_INDEX_* ones instead + LINEAR = 0, + KDTREE = 1, + KMEANS = 2, + COMPOSITE = 3, + KDTREE_SINGLE = 4, + SAVED = 254, + AUTOTUNED = 255 +}; + + + +enum flann_centers_init_t +{ + FLANN_CENTERS_RANDOM = 0, + FLANN_CENTERS_GONZALES = 1, + FLANN_CENTERS_KMEANSPP = 2, + FLANN_CENTERS_GROUPWISE = 3, + + // deprecated constants, should use the FLANN_CENTERS_* ones instead + CENTERS_RANDOM = 0, + CENTERS_GONZALES = 1, + CENTERS_KMEANSPP = 2 +}; + +enum flann_log_level_t +{ + FLANN_LOG_NONE = 0, + FLANN_LOG_FATAL = 1, + FLANN_LOG_ERROR = 2, + FLANN_LOG_WARN = 3, + FLANN_LOG_INFO = 4 +}; + +enum flann_distance_t +{ + FLANN_DIST_EUCLIDEAN = 1, + FLANN_DIST_L2 = 1, + FLANN_DIST_MANHATTAN = 2, + FLANN_DIST_L1 = 2, + FLANN_DIST_MINKOWSKI = 3, + FLANN_DIST_MAX = 4, + FLANN_DIST_HIST_INTERSECT = 5, + FLANN_DIST_HELLINGER = 6, + FLANN_DIST_CHI_SQUARE = 7, + FLANN_DIST_CS = 7, + FLANN_DIST_KULLBACK_LEIBLER = 8, + FLANN_DIST_KL = 8, + FLANN_DIST_HAMMING = 9, + + // deprecated constants, should use the FLANN_DIST_* ones instead + EUCLIDEAN = 1, + MANHATTAN = 2, + MINKOWSKI = 3, + MAX_DIST = 4, + HIST_INTERSECT = 5, + HELLINGER = 6, + CS = 7, + KL = 8, + KULLBACK_LEIBLER = 8 +}; + +enum flann_datatype_t +{ + FLANN_INT8 = 0, + FLANN_INT16 = 1, + FLANN_INT32 = 2, + FLANN_INT64 = 3, + FLANN_UINT8 = 4, + FLANN_UINT16 = 5, + FLANN_UINT32 = 6, + FLANN_UINT64 = 7, + FLANN_FLOAT32 = 8, + FLANN_FLOAT64 = 9 +}; + +enum +{ + FLANN_CHECKS_UNLIMITED = -1, + FLANN_CHECKS_AUTOTUNED = -2 +}; + +} + +#endif /* OPENCV_FLANN_DEFINES_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/dist.h b/Prj-Win/3rd/opencv/include/opencv2/flann/dist.h new file mode 100755 index 0000000..0670122 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/dist.h @@ -0,0 +1,904 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_DIST_H_ +#define OPENCV_FLANN_DIST_H_ + +#include +#include +#include +#ifdef _MSC_VER +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +#include "defines.h" + +#if defined _WIN32 && defined(_M_ARM) +# include +#endif + +#if defined(__ARM_NEON__) && !defined(__CUDACC__) +# include "arm_neon.h" +#endif + +namespace cvflann +{ + +template +inline T abs(T x) { return (x<0) ? -x : x; } + +template<> +inline int abs(int x) { return ::abs(x); } + +template<> +inline float abs(float x) { return fabsf(x); } + +template<> +inline double abs(double x) { return fabs(x); } + +template +struct Accumulator { typedef T Type; }; +template<> +struct Accumulator { typedef float Type; }; +template<> +struct Accumulator { typedef float Type; }; +template<> +struct Accumulator { typedef float Type; }; +template<> +struct Accumulator { typedef float Type; }; +template<> +struct Accumulator { typedef float Type; }; +template<> +struct Accumulator { typedef float Type; }; + +#undef True +#undef False + +class True +{ +}; + +class False +{ +}; + + +/** + * Squared Euclidean distance functor. + * + * This is the simpler, unrolled version. This is preferable for + * very low dimensionality data (eg 3D points) + */ +template +struct L2_Simple +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const + { + ResultType result = ResultType(); + ResultType diff; + for(size_t i = 0; i < size; ++i ) { + diff = (ResultType)(*a++ - *b++); + result += diff*diff; + } + return result; + } + + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + return (a-b)*(a-b); + } +}; + + + +/** + * Squared Euclidean distance functor, optimized version + */ +template +struct L2 +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + /** + * Compute the squared Euclidean distance between two vectors. + * + * This is highly optimised, with loop unrolling, as it is one + * of the most expensive inner loops. + * + * The computation of squared root at the end is omitted for + * efficiency. + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const + { + ResultType result = ResultType(); + ResultType diff0, diff1, diff2, diff3; + Iterator1 last = a + size; + Iterator1 lastgroup = last - 3; + + /* Process 4 items with each loop for efficiency. */ + while (a < lastgroup) { + diff0 = (ResultType)(a[0] - b[0]); + diff1 = (ResultType)(a[1] - b[1]); + diff2 = (ResultType)(a[2] - b[2]); + diff3 = (ResultType)(a[3] - b[3]); + result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3; + a += 4; + b += 4; + + if ((worst_dist>0)&&(result>worst_dist)) { + return result; + } + } + /* Process last 0-3 pixels. Not needed for standard vector lengths. */ + while (a < last) { + diff0 = (ResultType)(*a++ - *b++); + result += diff0 * diff0; + } + return result; + } + + /** + * Partial euclidean distance, using just one dimension. This is used by the + * kd-tree when computing partial distances while traversing the tree. + * + * Squared root is omitted for efficiency. + */ + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + return (a-b)*(a-b); + } +}; + + +/* + * Manhattan distance functor, optimized version + */ +template +struct L1 +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + /** + * Compute the Manhattan (L_1) distance between two vectors. + * + * This is highly optimised, with loop unrolling, as it is one + * of the most expensive inner loops. + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const + { + ResultType result = ResultType(); + ResultType diff0, diff1, diff2, diff3; + Iterator1 last = a + size; + Iterator1 lastgroup = last - 3; + + /* Process 4 items with each loop for efficiency. */ + while (a < lastgroup) { + diff0 = (ResultType)abs(a[0] - b[0]); + diff1 = (ResultType)abs(a[1] - b[1]); + diff2 = (ResultType)abs(a[2] - b[2]); + diff3 = (ResultType)abs(a[3] - b[3]); + result += diff0 + diff1 + diff2 + diff3; + a += 4; + b += 4; + + if ((worst_dist>0)&&(result>worst_dist)) { + return result; + } + } + /* Process last 0-3 pixels. Not needed for standard vector lengths. */ + while (a < last) { + diff0 = (ResultType)abs(*a++ - *b++); + result += diff0; + } + return result; + } + + /** + * Partial distance, used by the kd-tree. + */ + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + return abs(a-b); + } +}; + + + +template +struct MinkowskiDistance +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + int order; + + MinkowskiDistance(int order_) : order(order_) {} + + /** + * Compute the Minkowsky (L_p) distance between two vectors. + * + * This is highly optimised, with loop unrolling, as it is one + * of the most expensive inner loops. + * + * The computation of squared root at the end is omitted for + * efficiency. + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const + { + ResultType result = ResultType(); + ResultType diff0, diff1, diff2, diff3; + Iterator1 last = a + size; + Iterator1 lastgroup = last - 3; + + /* Process 4 items with each loop for efficiency. */ + while (a < lastgroup) { + diff0 = (ResultType)abs(a[0] - b[0]); + diff1 = (ResultType)abs(a[1] - b[1]); + diff2 = (ResultType)abs(a[2] - b[2]); + diff3 = (ResultType)abs(a[3] - b[3]); + result += pow(diff0,order) + pow(diff1,order) + pow(diff2,order) + pow(diff3,order); + a += 4; + b += 4; + + if ((worst_dist>0)&&(result>worst_dist)) { + return result; + } + } + /* Process last 0-3 pixels. Not needed for standard vector lengths. */ + while (a < last) { + diff0 = (ResultType)abs(*a++ - *b++); + result += pow(diff0,order); + } + return result; + } + + /** + * Partial distance, used by the kd-tree. + */ + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + return pow(static_cast(abs(a-b)),order); + } +}; + + + +template +struct MaxDistance +{ + typedef False is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + /** + * Compute the max distance (L_infinity) between two vectors. + * + * This distance is not a valid kdtree distance, it's not dimensionwise additive. + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const + { + ResultType result = ResultType(); + ResultType diff0, diff1, diff2, diff3; + Iterator1 last = a + size; + Iterator1 lastgroup = last - 3; + + /* Process 4 items with each loop for efficiency. */ + while (a < lastgroup) { + diff0 = abs(a[0] - b[0]); + diff1 = abs(a[1] - b[1]); + diff2 = abs(a[2] - b[2]); + diff3 = abs(a[3] - b[3]); + if (diff0>result) {result = diff0; } + if (diff1>result) {result = diff1; } + if (diff2>result) {result = diff2; } + if (diff3>result) {result = diff3; } + a += 4; + b += 4; + + if ((worst_dist>0)&&(result>worst_dist)) { + return result; + } + } + /* Process last 0-3 pixels. Not needed for standard vector lengths. */ + while (a < last) { + diff0 = abs(*a++ - *b++); + result = (diff0>result) ? diff0 : result; + } + return result; + } + + /* This distance functor is not dimension-wise additive, which + * makes it an invalid kd-tree distance, not implementing the accum_dist method */ + +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Hamming distance functor - counts the bit differences between two strings - useful for the Brief descriptor + * bit count of A exclusive XOR'ed with B + */ +struct HammingLUT +{ + typedef False is_kdtree_distance; + typedef False is_vector_space_distance; + + typedef unsigned char ElementType; + typedef int ResultType; + + /** this will count the bits in a ^ b + */ + ResultType operator()(const unsigned char* a, const unsigned char* b, size_t size) const + { + static const uchar popCountTable[] = + { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + }; + ResultType result = 0; + for (size_t i = 0; i < size; i++) { + result += popCountTable[a[i] ^ b[i]]; + } + return result; + } +}; + +/** + * Hamming distance functor (pop count between two binary vectors, i.e. xor them and count the number of bits set) + * That code was taken from brief.cpp in OpenCV + */ +template +struct Hamming +{ + typedef False is_kdtree_distance; + typedef False is_vector_space_distance; + + + typedef T ElementType; + typedef int ResultType; + + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const + { + ResultType result = 0; +#if defined(__ARM_NEON__) && !defined(__CUDACC__) + { + uint32x4_t bits = vmovq_n_u32(0); + for (size_t i = 0; i < size; i += 16) { + uint8x16_t A_vec = vld1q_u8 (a + i); + uint8x16_t B_vec = vld1q_u8 (b + i); + uint8x16_t AxorB = veorq_u8 (A_vec, B_vec); + uint8x16_t bitsSet = vcntq_u8 (AxorB); + uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet); + uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8); + bits = vaddq_u32(bits, bitSet4); + } + uint64x2_t bitSet2 = vpaddlq_u32 (bits); + result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0); + result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2); + } +#elif __GNUC__ + { + //for portability just use unsigned long -- and use the __builtin_popcountll (see docs for __builtin_popcountll) + typedef unsigned long long pop_t; + const size_t modulo = size % sizeof(pop_t); + const pop_t* a2 = reinterpret_cast (a); + const pop_t* b2 = reinterpret_cast (b); + const pop_t* a2_end = a2 + (size / sizeof(pop_t)); + + for (; a2 != a2_end; ++a2, ++b2) result += __builtin_popcountll((*a2) ^ (*b2)); + + if (modulo) { + //in the case where size is not dividable by sizeof(size_t) + //need to mask off the bits at the end + pop_t a_final = 0, b_final = 0; + memcpy(&a_final, a2, modulo); + memcpy(&b_final, b2, modulo); + result += __builtin_popcountll(a_final ^ b_final); + } + } +#else // NO NEON and NOT GNUC + HammingLUT lut; + result = lut(reinterpret_cast (a), + reinterpret_cast (b), size); +#endif + return result; + } +}; + +template +struct Hamming2 +{ + typedef False is_kdtree_distance; + typedef False is_vector_space_distance; + + typedef T ElementType; + typedef int ResultType; + + /** This is popcount_3() from: + * http://en.wikipedia.org/wiki/Hamming_weight */ + unsigned int popcnt32(uint32_t n) const + { + n -= ((n >> 1) & 0x55555555); + n = (n & 0x33333333) + ((n >> 2) & 0x33333333); + return (((n + (n >> 4))& 0xF0F0F0F)* 0x1010101) >> 24; + } + +#ifdef FLANN_PLATFORM_64_BIT + unsigned int popcnt64(uint64_t n) const + { + n -= ((n >> 1) & 0x5555555555555555); + n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333); + return (((n + (n >> 4))& 0x0f0f0f0f0f0f0f0f)* 0x0101010101010101) >> 56; + } +#endif + + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const + { +#ifdef FLANN_PLATFORM_64_BIT + const uint64_t* pa = reinterpret_cast(a); + const uint64_t* pb = reinterpret_cast(b); + ResultType result = 0; + size /= (sizeof(uint64_t)/sizeof(unsigned char)); + for(size_t i = 0; i < size; ++i ) { + result += popcnt64(*pa ^ *pb); + ++pa; + ++pb; + } +#else + const uint32_t* pa = reinterpret_cast(a); + const uint32_t* pb = reinterpret_cast(b); + ResultType result = 0; + size /= (sizeof(uint32_t)/sizeof(unsigned char)); + for(size_t i = 0; i < size; ++i ) { + result += popcnt32(*pa ^ *pb); + ++pa; + ++pb; + } +#endif + return result; + } +}; + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct HistIntersectionDistance +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + /** + * Compute the histogram intersection distance + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const + { + ResultType result = ResultType(); + ResultType min0, min1, min2, min3; + Iterator1 last = a + size; + Iterator1 lastgroup = last - 3; + + /* Process 4 items with each loop for efficiency. */ + while (a < lastgroup) { + min0 = (ResultType)(a[0] < b[0] ? a[0] : b[0]); + min1 = (ResultType)(a[1] < b[1] ? a[1] : b[1]); + min2 = (ResultType)(a[2] < b[2] ? a[2] : b[2]); + min3 = (ResultType)(a[3] < b[3] ? a[3] : b[3]); + result += min0 + min1 + min2 + min3; + a += 4; + b += 4; + if ((worst_dist>0)&&(result>worst_dist)) { + return result; + } + } + /* Process last 0-3 pixels. Not needed for standard vector lengths. */ + while (a < last) { + min0 = (ResultType)(*a < *b ? *a : *b); + result += min0; + ++a; + ++b; + } + return result; + } + + /** + * Partial distance, used by the kd-tree. + */ + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + return a +struct HellingerDistance +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + /** + * Compute the Hellinger distance + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const + { + ResultType result = ResultType(); + ResultType diff0, diff1, diff2, diff3; + Iterator1 last = a + size; + Iterator1 lastgroup = last - 3; + + /* Process 4 items with each loop for efficiency. */ + while (a < lastgroup) { + diff0 = sqrt(static_cast(a[0])) - sqrt(static_cast(b[0])); + diff1 = sqrt(static_cast(a[1])) - sqrt(static_cast(b[1])); + diff2 = sqrt(static_cast(a[2])) - sqrt(static_cast(b[2])); + diff3 = sqrt(static_cast(a[3])) - sqrt(static_cast(b[3])); + result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3; + a += 4; + b += 4; + } + while (a < last) { + diff0 = sqrt(static_cast(*a++)) - sqrt(static_cast(*b++)); + result += diff0 * diff0; + } + return result; + } + + /** + * Partial distance, used by the kd-tree. + */ + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + ResultType diff = sqrt(static_cast(a)) - sqrt(static_cast(b)); + return diff * diff; + } +}; + + +template +struct ChiSquareDistance +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + /** + * Compute the chi-square distance + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const + { + ResultType result = ResultType(); + ResultType sum, diff; + Iterator1 last = a + size; + + while (a < last) { + sum = (ResultType)(*a + *b); + if (sum>0) { + diff = (ResultType)(*a - *b); + result += diff*diff/sum; + } + ++a; + ++b; + + if ((worst_dist>0)&&(result>worst_dist)) { + return result; + } + } + return result; + } + + /** + * Partial distance, used by the kd-tree. + */ + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + ResultType result = ResultType(); + ResultType sum, diff; + + sum = (ResultType)(a+b); + if (sum>0) { + diff = (ResultType)(a-b); + result = diff*diff/sum; + } + return result; + } +}; + + +template +struct KL_Divergence +{ + typedef True is_kdtree_distance; + typedef True is_vector_space_distance; + + typedef T ElementType; + typedef typename Accumulator::Type ResultType; + + /** + * Compute the Kullback-Leibler divergence + */ + template + ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType worst_dist = -1) const + { + ResultType result = ResultType(); + Iterator1 last = a + size; + + while (a < last) { + if (* b != 0) { + ResultType ratio = (ResultType)(*a / *b); + if (ratio>0) { + result += *a * log(ratio); + } + } + ++a; + ++b; + + if ((worst_dist>0)&&(result>worst_dist)) { + return result; + } + } + return result; + } + + /** + * Partial distance, used by the kd-tree. + */ + template + inline ResultType accum_dist(const U& a, const V& b, int) const + { + ResultType result = ResultType(); + if( *b != 0 ) { + ResultType ratio = (ResultType)(a / b); + if (ratio>0) { + result = a * log(ratio); + } + } + return result; + } +}; + + + +/* + * This is a "zero iterator". It basically behaves like a zero filled + * array to all algorithms that use arrays as iterators (STL style). + * It's useful when there's a need to compute the distance between feature + * and origin it and allows for better compiler optimisation than using a + * zero-filled array. + */ +template +struct ZeroIterator +{ + + T operator*() + { + return 0; + } + + T operator[](int) + { + return 0; + } + + const ZeroIterator& operator ++() + { + return *this; + } + + ZeroIterator operator ++(int) + { + return *this; + } + + ZeroIterator& operator+=(int) + { + return *this; + } + +}; + + +/* + * Depending on processed distances, some of them are already squared (e.g. L2) + * and some are not (e.g.Hamming). In KMeans++ for instance we want to be sure + * we are working on ^2 distances, thus following templates to ensure that. + */ +template +struct squareDistance +{ + typedef typename Distance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return dist*dist; } +}; + + +template +struct squareDistance, ElementType> +{ + typedef typename L2_Simple::ResultType ResultType; + ResultType operator()( ResultType dist ) { return dist; } +}; + +template +struct squareDistance, ElementType> +{ + typedef typename L2::ResultType ResultType; + ResultType operator()( ResultType dist ) { return dist; } +}; + + +template +struct squareDistance, ElementType> +{ + typedef typename MinkowskiDistance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return dist; } +}; + +template +struct squareDistance, ElementType> +{ + typedef typename HellingerDistance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return dist; } +}; + +template +struct squareDistance, ElementType> +{ + typedef typename ChiSquareDistance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return dist; } +}; + + +template +typename Distance::ResultType ensureSquareDistance( typename Distance::ResultType dist ) +{ + typedef typename Distance::ElementType ElementType; + + squareDistance dummy; + return dummy( dist ); +} + + +/* + * ...and a template to ensure the user that he will process the normal distance, + * and not squared distance, without losing processing time calling sqrt(ensureSquareDistance) + * that will result in doing actually sqrt(dist*dist) for L1 distance for instance. + */ +template +struct simpleDistance +{ + typedef typename Distance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return dist; } +}; + + +template +struct simpleDistance, ElementType> +{ + typedef typename L2_Simple::ResultType ResultType; + ResultType operator()( ResultType dist ) { return sqrt(dist); } +}; + +template +struct simpleDistance, ElementType> +{ + typedef typename L2::ResultType ResultType; + ResultType operator()( ResultType dist ) { return sqrt(dist); } +}; + + +template +struct simpleDistance, ElementType> +{ + typedef typename MinkowskiDistance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return sqrt(dist); } +}; + +template +struct simpleDistance, ElementType> +{ + typedef typename HellingerDistance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return sqrt(dist); } +}; + +template +struct simpleDistance, ElementType> +{ + typedef typename ChiSquareDistance::ResultType ResultType; + ResultType operator()( ResultType dist ) { return sqrt(dist); } +}; + + +template +typename Distance::ResultType ensureSimpleDistance( typename Distance::ResultType dist ) +{ + typedef typename Distance::ElementType ElementType; + + simpleDistance dummy; + return dummy( dist ); +} + +} + +#endif //OPENCV_FLANN_DIST_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/dummy.h b/Prj-Win/3rd/opencv/include/opencv2/flann/dummy.h new file mode 100755 index 0000000..d6837e5 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/dummy.h @@ -0,0 +1,13 @@ + +#ifndef OPENCV_FLANN_DUMMY_H_ +#define OPENCV_FLANN_DUMMY_H_ + +namespace cvflann +{ + +CV_DEPRECATED inline void dummyfunc() {} + +} + + +#endif /* OPENCV_FLANN_DUMMY_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/dynamic_bitset.h b/Prj-Win/3rd/opencv/include/opencv2/flann/dynamic_bitset.h new file mode 100755 index 0000000..923b658 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/dynamic_bitset.h @@ -0,0 +1,159 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +/*********************************************************************** + * Author: Vincent Rabaud + *************************************************************************/ + +#ifndef OPENCV_FLANN_DYNAMIC_BITSET_H_ +#define OPENCV_FLANN_DYNAMIC_BITSET_H_ + +#ifndef FLANN_USE_BOOST +# define FLANN_USE_BOOST 0 +#endif +//#define FLANN_USE_BOOST 1 +#if FLANN_USE_BOOST +#include +typedef boost::dynamic_bitset<> DynamicBitset; +#else + +#include + +#include "dist.h" + +namespace cvflann { + +/** Class re-implementing the boost version of it + * This helps not depending on boost, it also does not do the bound checks + * and has a way to reset a block for speed + */ +class DynamicBitset +{ +public: + /** default constructor + */ + DynamicBitset() : size_(0) + { + } + + /** only constructor we use in our code + * @param sz the size of the bitset (in bits) + */ + DynamicBitset(size_t sz) + { + resize(sz); + reset(); + } + + /** Sets all the bits to 0 + */ + void clear() + { + std::fill(bitset_.begin(), bitset_.end(), 0); + } + + /** @brief checks if the bitset is empty + * @return true if the bitset is empty + */ + bool empty() const + { + return bitset_.empty(); + } + + /** set all the bits to 0 + */ + void reset() + { + std::fill(bitset_.begin(), bitset_.end(), 0); + } + + /** @brief set one bit to 0 + * @param index + */ + void reset(size_t index) + { + bitset_[index / cell_bit_size_] &= ~(size_t(1) << (index % cell_bit_size_)); + } + + /** @brief sets a specific bit to 0, and more bits too + * This function is useful when resetting a given set of bits so that the + * whole bitset ends up being 0: if that's the case, we don't care about setting + * other bits to 0 + * @param index + */ + void reset_block(size_t index) + { + bitset_[index / cell_bit_size_] = 0; + } + + /** resize the bitset so that it contains at least sz bits + * @param sz + */ + void resize(size_t sz) + { + size_ = sz; + bitset_.resize(sz / cell_bit_size_ + 1); + } + + /** set a bit to true + * @param index the index of the bit to set to 1 + */ + void set(size_t index) + { + bitset_[index / cell_bit_size_] |= size_t(1) << (index % cell_bit_size_); + } + + /** gives the number of contained bits + */ + size_t size() const + { + return size_; + } + + /** check if a bit is set + * @param index the index of the bit to check + * @return true if the bit is set + */ + bool test(size_t index) const + { + return (bitset_[index / cell_bit_size_] & (size_t(1) << (index % cell_bit_size_))) != 0; + } + +private: + std::vector bitset_; + size_t size_; + static const unsigned int cell_bit_size_ = CHAR_BIT * sizeof(size_t); +}; + +} // namespace cvflann + +#endif + +#endif // OPENCV_FLANN_DYNAMIC_BITSET_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/flann.hpp b/Prj-Win/3rd/opencv/include/opencv2/flann/flann.hpp new file mode 100755 index 0000000..227683f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/flann.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/flann.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/flann_base.hpp b/Prj-Win/3rd/opencv/include/opencv2/flann/flann_base.hpp new file mode 100755 index 0000000..0ffb857 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/flann_base.hpp @@ -0,0 +1,295 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_BASE_HPP_ +#define OPENCV_FLANN_BASE_HPP_ + +#include +#include +#include + +#include "general.h" +#include "matrix.h" +#include "params.h" +#include "saving.h" + +#include "all_indices.h" + +namespace cvflann +{ + +/** + * Sets the log level used for all flann functions + * @param level Verbosity level + */ +inline void log_verbosity(int level) +{ + if (level >= 0) { + Logger::setLevel(level); + } +} + +/** + * (Deprecated) Index parameters for creating a saved index. + */ +struct SavedIndexParams : public IndexParams +{ + SavedIndexParams(cv::String filename) + { + (* this)["algorithm"] = FLANN_INDEX_SAVED; + (*this)["filename"] = filename; + } +}; + + +template +NNIndex* load_saved_index(const Matrix& dataset, const cv::String& filename, Distance distance) +{ + typedef typename Distance::ElementType ElementType; + + FILE* fin = fopen(filename.c_str(), "rb"); + if (fin == NULL) { + return NULL; + } + IndexHeader header = load_header(fin); + if (header.data_type != Datatype::type()) { + fclose(fin); + throw FLANNException("Datatype of saved index is different than of the one to be created."); + } + if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) { + fclose(fin); + throw FLANNException("The index saved belongs to a different dataset"); + } + + IndexParams params; + params["algorithm"] = header.index_type; + NNIndex* nnIndex = create_index_by_type(dataset, params, distance); + nnIndex->loadIndex(fin); + fclose(fin); + + return nnIndex; +} + + +template +class Index : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + Index(const Matrix& features, const IndexParams& params, Distance distance = Distance() ) + : index_params_(params) + { + flann_algorithm_t index_type = get_param(params,"algorithm"); + loaded_ = false; + + if (index_type == FLANN_INDEX_SAVED) { + nnIndex_ = load_saved_index(features, get_param(params,"filename"), distance); + loaded_ = true; + } + else { + nnIndex_ = create_index_by_type(features, params, distance); + } + } + + ~Index() + { + delete nnIndex_; + } + + /** + * Builds the index. + */ + void buildIndex() CV_OVERRIDE + { + if (!loaded_) { + nnIndex_->buildIndex(); + } + } + + void save(cv::String filename) + { + FILE* fout = fopen(filename.c_str(), "wb"); + if (fout == NULL) { + throw FLANNException("Cannot open file"); + } + save_header(fout, *nnIndex_); + saveIndex(fout); + fclose(fout); + } + + /** + * \brief Saves the index to a stream + * \param stream The stream to save the index to + */ + virtual void saveIndex(FILE* stream) CV_OVERRIDE + { + nnIndex_->saveIndex(stream); + } + + /** + * \brief Loads the index from a stream + * \param stream The stream from which the index is loaded + */ + virtual void loadIndex(FILE* stream) CV_OVERRIDE + { + nnIndex_->loadIndex(stream); + } + + /** + * \returns number of features in this index. + */ + size_t veclen() const CV_OVERRIDE + { + return nnIndex_->veclen(); + } + + /** + * \returns The dimensionality of the features in this index. + */ + size_t size() const CV_OVERRIDE + { + return nnIndex_->size(); + } + + /** + * \returns The index type (kdtree, kmeans,...) + */ + flann_algorithm_t getType() const CV_OVERRIDE + { + return nnIndex_->getType(); + } + + /** + * \returns The amount of memory (in bytes) used by the index. + */ + virtual int usedMemory() const CV_OVERRIDE + { + return nnIndex_->usedMemory(); + } + + + /** + * \returns The index parameters + */ + IndexParams getParameters() const CV_OVERRIDE + { + return nnIndex_->getParameters(); + } + + /** + * \brief Perform k-nearest neighbor search + * \param[in] queries The query points for which to find the nearest neighbors + * \param[out] indices The indices of the nearest neighbors found + * \param[out] dists Distances to the nearest neighbors found + * \param[in] knn Number of nearest neighbors to return + * \param[in] params Search parameters + */ + void knnSearch(const Matrix& queries, Matrix& indices, Matrix& dists, int knn, const SearchParams& params) CV_OVERRIDE + { + nnIndex_->knnSearch(queries, indices, dists, knn, params); + } + + /** + * \brief Perform radius search + * \param[in] query The query point + * \param[out] indices The indinces of the neighbors found within the given radius + * \param[out] dists The distances to the nearest neighbors found + * \param[in] radius The radius used for search + * \param[in] params Search parameters + * \returns Number of neighbors found + */ + int radiusSearch(const Matrix& query, Matrix& indices, Matrix& dists, float radius, const SearchParams& params) CV_OVERRIDE + { + return nnIndex_->radiusSearch(query, indices, dists, radius, params); + } + + /** + * \brief Method that searches for nearest-neighbours + */ + void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE + { + nnIndex_->findNeighbors(result, vec, searchParams); + } + + /** + * \brief Returns actual index + */ + CV_DEPRECATED NNIndex* getIndex() + { + return nnIndex_; + } + + /** + * \brief Returns index parameters. + * \deprecated use getParameters() instead. + */ + CV_DEPRECATED const IndexParams* getIndexParameters() + { + return &index_params_; + } + +private: + /** Pointer to actual index class */ + NNIndex* nnIndex_; + /** Indices if the index was loaded from a file */ + bool loaded_; + /** Parameters passed to the index */ + IndexParams index_params_; + + Index(const Index &); // copy disabled + Index& operator=(const Index &); // assign disabled +}; + +/** + * Performs a hierarchical clustering of the points passed as argument and then takes a cut in the + * the clustering tree to return a flat clustering. + * @param[in] points Points to be clustered + * @param centers The computed cluster centres. Matrix should be preallocated and centers.rows is the + * number of clusters requested. + * @param params Clustering parameters (The same as for cvflann::KMeansIndex) + * @param d Distance to be used for clustering (eg: cvflann::L2) + * @return number of clusters computed (can be different than clusters.rows and is the highest number + * of the form (branching-1)*K+1 smaller than clusters.rows). + */ +template +int hierarchicalClustering(const Matrix& points, Matrix& centers, + const KMeansIndexParams& params, Distance d = Distance()) +{ + KMeansIndex kmeans(points, params, d); + kmeans.buildIndex(); + + int clusterNum = kmeans.getClusterCenters(centers); + return clusterNum; +} + +} +#endif /* OPENCV_FLANN_BASE_HPP_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/general.h b/Prj-Win/3rd/opencv/include/opencv2/flann/general.h new file mode 100755 index 0000000..9d5402a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/general.h @@ -0,0 +1,50 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_GENERAL_H_ +#define OPENCV_FLANN_GENERAL_H_ + +#include "opencv2/core.hpp" + +namespace cvflann +{ + +class FLANNException : public cv::Exception +{ +public: + FLANNException(const char* message) : cv::Exception(0, message, "", __FILE__, __LINE__) { } + + FLANNException(const cv::String& message) : cv::Exception(0, message, "", __FILE__, __LINE__) { } +}; + +} + + +#endif /* OPENCV_FLANN_GENERAL_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/ground_truth.h b/Prj-Win/3rd/opencv/include/opencv2/flann/ground_truth.h new file mode 100755 index 0000000..fd8f3ae --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/ground_truth.h @@ -0,0 +1,94 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_GROUND_TRUTH_H_ +#define OPENCV_FLANN_GROUND_TRUTH_H_ + +#include "dist.h" +#include "matrix.h" + + +namespace cvflann +{ + +template +void find_nearest(const Matrix& dataset, typename Distance::ElementType* query, int* matches, int nn, + int skip = 0, Distance distance = Distance()) +{ + typedef typename Distance::ResultType DistanceType; + int n = nn + skip; + + std::vector match(n); + std::vector dists(n); + + dists[0] = distance(dataset[0], query, dataset.cols); + match[0] = 0; + int dcnt = 1; + + for (size_t i=1; i=1 && dists[j] +void compute_ground_truth(const Matrix& dataset, const Matrix& testset, Matrix& matches, + int skip=0, Distance d = Distance()) +{ + for (size_t i=0; i(dataset, testset[i], matches[i], (int)matches.cols, skip, d); + } +} + + +} + +#endif //OPENCV_FLANN_GROUND_TRUTH_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/heap.h b/Prj-Win/3rd/opencv/include/opencv2/flann/heap.h new file mode 100755 index 0000000..92a6ea6 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/heap.h @@ -0,0 +1,165 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_HEAP_H_ +#define OPENCV_FLANN_HEAP_H_ + +#include +#include + +namespace cvflann +{ + +/** + * Priority Queue Implementation + * + * The priority queue is implemented with a heap. A heap is a complete + * (full) binary tree in which each parent is less than both of its + * children, but the order of the children is unspecified. + */ +template +class Heap +{ + + /** + * Storage array for the heap. + * Type T must be comparable. + */ + std::vector heap; + int length; + + /** + * Number of element in the heap + */ + int count; + + + +public: + /** + * Constructor. + * + * Params: + * sz = heap size + */ + + Heap(int sz) + { + length = sz; + heap.reserve(length); + count = 0; + } + + /** + * + * Returns: heap size + */ + int size() + { + return count; + } + + /** + * Tests if the heap is empty + * + * Returns: true is heap empty, false otherwise + */ + bool empty() + { + return size()==0; + } + + /** + * Clears the heap. + */ + void clear() + { + heap.clear(); + count = 0; + } + + struct CompareT + { + bool operator()(const T& t_1, const T& t_2) const + { + return t_2 < t_1; + } + }; + + /** + * Insert a new element in the heap. + * + * We select the next empty leaf node, and then keep moving any larger + * parents down until the right location is found to store this element. + * + * Params: + * value = the new element to be inserted in the heap + */ + void insert(T value) + { + /* If heap is full, then return without adding this element. */ + if (count == length) { + return; + } + + heap.push_back(value); + static CompareT compareT; + std::push_heap(heap.begin(), heap.end(), compareT); + ++count; + } + + + + /** + * Returns the node of minimum value from the heap (top of the heap). + * + * Params: + * value = out parameter used to return the min element + * Returns: false if heap empty + */ + bool popMin(T& value) + { + if (count == 0) { + return false; + } + + value = heap[0]; + static CompareT compareT; + std::pop_heap(heap.begin(), heap.end(), compareT); + heap.pop_back(); + --count; + + return true; /* Return old last node. */ + } +}; + +} + +#endif //OPENCV_FLANN_HEAP_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/hierarchical_clustering_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/hierarchical_clustering_index.h new file mode 100755 index 0000000..2a947da --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/hierarchical_clustering_index.h @@ -0,0 +1,848 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_HIERARCHICAL_CLUSTERING_INDEX_H_ +#define OPENCV_FLANN_HIERARCHICAL_CLUSTERING_INDEX_H_ + +#include +#include +#include +#include +#include + +#include "general.h" +#include "nn_index.h" +#include "dist.h" +#include "matrix.h" +#include "result_set.h" +#include "heap.h" +#include "allocator.h" +#include "random.h" +#include "saving.h" + + +namespace cvflann +{ + +struct HierarchicalClusteringIndexParams : public IndexParams +{ + HierarchicalClusteringIndexParams(int branching = 32, + flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, + int trees = 4, int leaf_size = 100) + { + (*this)["algorithm"] = FLANN_INDEX_HIERARCHICAL; + // The branching factor used in the hierarchical clustering + (*this)["branching"] = branching; + // Algorithm used for picking the initial cluster centers + (*this)["centers_init"] = centers_init; + // number of parallel trees to build + (*this)["trees"] = trees; + // maximum leaf size + (*this)["leaf_size"] = leaf_size; + } +}; + + +/** + * Hierarchical index + * + * Contains a tree constructed through a hierarchical clustering + * and other information for indexing a set of points for nearest-neighbour matching. + */ +template +class HierarchicalClusteringIndex : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + +private: + + + typedef void (HierarchicalClusteringIndex::* centersAlgFunction)(int, int*, int, int*, int&); + + /** + * The function used for choosing the cluster centers. + */ + centersAlgFunction chooseCenters; + + + + /** + * Chooses the initial centers in the k-means clustering in a random manner. + * + * Params: + * k = number of centers + * vecs = the dataset of points + * indices = indices in the dataset + * indices_length = length of indices vector + * + */ + void chooseCentersRandom(int k, int* dsindices, int indices_length, int* centers, int& centers_length) + { + UniqueRandom r(indices_length); + + int index; + for (index=0; index=0 && rnd < n); + + centers[0] = dsindices[rnd]; + + int index; + for (index=1; indexbest_val) { + best_val = dist; + best_index = j; + } + } + if (best_index!=-1) { + centers[index] = dsindices[best_index]; + } + else { + break; + } + } + centers_length = index; + } + + + /** + * Chooses the initial centers in the k-means using the algorithm + * proposed in the KMeans++ paper: + * Arthur, David; Vassilvitskii, Sergei - k-means++: The Advantages of Careful Seeding + * + * Implementation of this function was converted from the one provided in Arthur's code. + * + * Params: + * k = number of centers + * vecs = the dataset of points + * indices = indices in the dataset + * Returns: + */ + void chooseCentersKMeanspp(int k, int* dsindices, int indices_length, int* centers, int& centers_length) + { + int n = indices_length; + + double currentPot = 0; + DistanceType* closestDistSq = new DistanceType[n]; + + // Choose one random center and set the closestDistSq values + int index = rand_int(n); + assert(index >=0 && index < n); + centers[0] = dsindices[index]; + + // Computing distance^2 will have the advantage of even higher probability further to pick new centers + // far from previous centers (and this complies to "k-means++: the advantages of careful seeding" article) + for (int i = 0; i < n; i++) { + closestDistSq[i] = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols); + closestDistSq[i] = ensureSquareDistance( closestDistSq[i] ); + currentPot += closestDistSq[i]; + } + + + const int numLocalTries = 1; + + // Choose each center + int centerCount; + for (centerCount = 1; centerCount < k; centerCount++) { + + // Repeat several trials + double bestNewPot = -1; + int bestNewIndex = 0; + for (int localTrial = 0; localTrial < numLocalTries; localTrial++) { + + // Choose our center - have to be slightly careful to return a valid answer even accounting + // for possible rounding errors + double randVal = rand_double(currentPot); + for (index = 0; index < n-1; index++) { + if (randVal <= closestDistSq[index]) break; + else randVal -= closestDistSq[index]; + } + + // Compute the new potential + double newPot = 0; + for (int i = 0; i < n; i++) { + DistanceType dist = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols); + newPot += std::min( ensureSquareDistance(dist), closestDistSq[i] ); + } + + // Store the best result + if ((bestNewPot < 0)||(newPot < bestNewPot)) { + bestNewPot = newPot; + bestNewIndex = index; + } + } + + // Add the appropriate center + centers[centerCount] = dsindices[bestNewIndex]; + currentPot = bestNewPot; + for (int i = 0; i < n; i++) { + DistanceType dist = distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols); + closestDistSq[i] = std::min( ensureSquareDistance(dist), closestDistSq[i] ); + } + } + + centers_length = centerCount; + + delete[] closestDistSq; + } + + + /** + * Chooses the initial centers in a way inspired by Gonzales (by Pierre-Emmanuel Viel): + * select the first point of the list as a candidate, then parse the points list. If another + * point is further than current candidate from the other centers, test if it is a good center + * of a local aggregation. If it is, replace current candidate by this point. And so on... + * + * Used with KMeansIndex that computes centers coordinates by averaging positions of clusters points, + * this doesn't make a real difference with previous methods. But used with HierarchicalClusteringIndex + * class that pick centers among existing points instead of computing the barycenters, there is a real + * improvement. + * + * Params: + * k = number of centers + * vecs = the dataset of points + * indices = indices in the dataset + * Returns: + */ + void GroupWiseCenterChooser(int k, int* dsindices, int indices_length, int* centers, int& centers_length) + { + const float kSpeedUpFactor = 1.3f; + + int n = indices_length; + + DistanceType* closestDistSq = new DistanceType[n]; + + // Choose one random center and set the closestDistSq values + int index = rand_int(n); + assert(index >=0 && index < n); + centers[0] = dsindices[index]; + + for (int i = 0; i < n; i++) { + closestDistSq[i] = distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols); + } + + + // Choose each center + int centerCount; + for (centerCount = 1; centerCount < k; centerCount++) { + + // Repeat several trials + double bestNewPot = -1; + int bestNewIndex = 0; + DistanceType furthest = 0; + for (index = 0; index < n; index++) { + + // We will test only the potential of the points further than current candidate + if( closestDistSq[index] > kSpeedUpFactor * (float)furthest ) { + + // Compute the new potential + double newPot = 0; + for (int i = 0; i < n; i++) { + newPot += std::min( distance(dataset[dsindices[i]], dataset[dsindices[index]], dataset.cols) + , closestDistSq[i] ); + } + + // Store the best result + if ((bestNewPot < 0)||(newPot <= bestNewPot)) { + bestNewPot = newPot; + bestNewIndex = index; + furthest = closestDistSq[index]; + } + } + } + + // Add the appropriate center + centers[centerCount] = dsindices[bestNewIndex]; + for (int i = 0; i < n; i++) { + closestDistSq[i] = std::min( distance(dataset[dsindices[i]], dataset[dsindices[bestNewIndex]], dataset.cols) + , closestDistSq[i] ); + } + } + + centers_length = centerCount; + + delete[] closestDistSq; + } + + +public: + + + /** + * Index constructor + * + * Params: + * inputData = dataset with the input features + * params = parameters passed to the hierarchical k-means algorithm + */ + HierarchicalClusteringIndex(const Matrix& inputData, const IndexParams& index_params = HierarchicalClusteringIndexParams(), + Distance d = Distance()) + : dataset(inputData), params(index_params), root(NULL), indices(NULL), distance(d) + { + memoryCounter = 0; + + size_ = dataset.rows; + veclen_ = dataset.cols; + + branching_ = get_param(params,"branching",32); + centers_init_ = get_param(params,"centers_init", FLANN_CENTERS_RANDOM); + trees_ = get_param(params,"trees",4); + leaf_size_ = get_param(params,"leaf_size",100); + + if (centers_init_==FLANN_CENTERS_RANDOM) { + chooseCenters = &HierarchicalClusteringIndex::chooseCentersRandom; + } + else if (centers_init_==FLANN_CENTERS_GONZALES) { + chooseCenters = &HierarchicalClusteringIndex::chooseCentersGonzales; + } + else if (centers_init_==FLANN_CENTERS_KMEANSPP) { + chooseCenters = &HierarchicalClusteringIndex::chooseCentersKMeanspp; + } + else if (centers_init_==FLANN_CENTERS_GROUPWISE) { + chooseCenters = &HierarchicalClusteringIndex::GroupWiseCenterChooser; + } + else { + throw FLANNException("Unknown algorithm for choosing initial centers."); + } + + trees_ = get_param(params,"trees",4); + root = new NodePtr[trees_]; + indices = new int*[trees_]; + + for (int i=0; i(); + computeClustering(root[i], indices[i], (int)size_, branching_,0); + } + } + + + flann_algorithm_t getType() const CV_OVERRIDE + { + return FLANN_INDEX_HIERARCHICAL; + } + + + void saveIndex(FILE* stream) CV_OVERRIDE + { + save_value(stream, branching_); + save_value(stream, trees_); + save_value(stream, centers_init_); + save_value(stream, leaf_size_); + save_value(stream, memoryCounter); + for (int i=0; i& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE + { + + int maxChecks = get_param(searchParams,"checks",32); + + // Priority queue storing intermediate branches in the best-bin-first search + Heap* heap = new Heap((int)size_); + + std::vector checked(size_,false); + int checks = 0; + for (int i=0; ipopMin(branch) && (checks BranchSt; + + + + void save_tree(FILE* stream, NodePtr node, int num) + { + save_value(stream, *node); + if (node->childs==NULL) { + int indices_offset = (int)(node->indices - indices[num]); + save_value(stream, indices_offset); + } + else { + for(int i=0; ichilds[i], num); + } + } + } + + + void load_tree(FILE* stream, NodePtr& node, int num) + { + node = pool.allocate(); + load_value(stream, *node); + if (node->childs==NULL) { + int indices_offset; + load_value(stream, indices_offset); + node->indices = indices[num] + indices_offset; + } + else { + node->childs = pool.allocate(branching_); + for(int i=0; ichilds[i], num); + } + } + } + + + + + void computeLabels(int* dsindices, int indices_length, int* centers, int centers_length, int* labels, DistanceType& cost) + { + cost = 0; + for (int i=0; inew_dist) { + labels[i] = j; + dist = new_dist; + } + } + cost += dist; + } + } + + /** + * The method responsible with actually doing the recursive hierarchical + * clustering + * + * Params: + * node = the node to cluster + * indices = indices of the points belonging to the current node + * branching = the branching factor to use in the clustering + * + * TODO: for 1-sized clusters don't store a cluster center (it's the same as the single cluster point) + */ + void computeClustering(NodePtr node, int* dsindices, int indices_length, int branching, int level) + { + node->size = indices_length; + node->level = level; + + if (indices_length < leaf_size_) { // leaf node + node->indices = dsindices; + std::sort(node->indices,node->indices+indices_length); + node->childs = NULL; + return; + } + + std::vector centers(branching); + std::vector labels(indices_length); + + int centers_length; + (this->*chooseCenters)(branching, dsindices, indices_length, ¢ers[0], centers_length); + + if (centers_lengthindices = dsindices; + std::sort(node->indices,node->indices+indices_length); + node->childs = NULL; + return; + } + + + // assign points to clusters + DistanceType cost; + computeLabels(dsindices, indices_length, ¢ers[0], centers_length, &labels[0], cost); + + node->childs = pool.allocate(branching); + int start = 0; + int end = start; + for (int i=0; ichilds[i] = pool.allocate(); + node->childs[i]->pivot = centers[i]; + node->childs[i]->indices = NULL; + computeClustering(node->childs[i],dsindices+start, end-start, branching, level+1); + start=end; + } + } + + + + /** + * Performs one descent in the hierarchical k-means tree. The branches not + * visited are stored in a priority queue. + * + * Params: + * node = node to explore + * result = container for the k-nearest neighbors found + * vec = query points + * checks = how many points in the dataset have been checked so far + * maxChecks = maximum dataset points to checks + */ + + + void findNN(NodePtr node, ResultSet& result, const ElementType* vec, int& checks, int maxChecks, + Heap* heap, std::vector& checked) + { + if (node->childs==NULL) { + if (checks>=maxChecks) { + if (result.full()) return; + } + for (int i=0; isize; ++i) { + int index = node->indices[i]; + if (!checked[index]) { + DistanceType dist = distance(dataset[index], vec, veclen_); + result.addPoint(dist, index); + checked[index] = true; + ++checks; + } + } + } + else { + DistanceType* domain_distances = new DistanceType[branching_]; + int best_index = 0; + domain_distances[best_index] = distance(vec, dataset[node->childs[best_index]->pivot], veclen_); + for (int i=1; ichilds[i]->pivot], veclen_); + if (domain_distances[i]insert(BranchSt(node->childs[i],domain_distances[i])); + } + } + delete[] domain_distances; + findNN(node->childs[best_index],result,vec, checks, maxChecks, heap, checked); + } + } + +private: + + + /** + * The dataset used by this index + */ + const Matrix dataset; + + /** + * Parameters used by this index + */ + IndexParams params; + + + /** + * Number of features in the dataset. + */ + size_t size_; + + /** + * Length of each feature. + */ + size_t veclen_; + + /** + * The root node in the tree. + */ + NodePtr* root; + + /** + * Array of indices to vectors in the dataset. + */ + int** indices; + + + /** + * The distance + */ + Distance distance; + + /** + * Pooled memory allocator. + * + * Using a pooled memory allocator is more efficient + * than allocating memory directly when there is a large + * number small of memory allocations. + */ + PooledAllocator pool; + + /** + * Memory occupied by the index. + */ + int memoryCounter; + + /** index parameters */ + int branching_; + int trees_; + flann_centers_init_t centers_init_; + int leaf_size_; + + +}; + +} + +#endif /* OPENCV_FLANN_HIERARCHICAL_CLUSTERING_INDEX_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/index_testing.h b/Prj-Win/3rd/opencv/include/opencv2/flann/index_testing.h new file mode 100755 index 0000000..d764004 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/index_testing.h @@ -0,0 +1,318 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_INDEX_TESTING_H_ +#define OPENCV_FLANN_INDEX_TESTING_H_ + +#include +#include +#include + +#include "matrix.h" +#include "nn_index.h" +#include "result_set.h" +#include "logger.h" +#include "timer.h" + + +namespace cvflann +{ + +inline int countCorrectMatches(int* neighbors, int* groundTruth, int n) +{ + int count = 0; + for (int i=0; i +typename Distance::ResultType computeDistanceRaport(const Matrix& inputData, typename Distance::ElementType* target, + int* neighbors, int* groundTruth, int veclen, int n, const Distance& distance) +{ + typedef typename Distance::ResultType DistanceType; + + DistanceType ret = 0; + for (int i=0; i +float search_with_ground_truth(NNIndex& index, const Matrix& inputData, + const Matrix& testData, const Matrix& matches, int nn, int checks, + float& time, typename Distance::ResultType& dist, const Distance& distance, int skipMatches) +{ + typedef typename Distance::ResultType DistanceType; + + if (matches.cols resultSet(nn+skipMatches); + SearchParams searchParams(checks); + + std::vector indices(nn+skipMatches); + std::vector dists(nn+skipMatches); + int* neighbors = &indices[skipMatches]; + + int correct = 0; + DistanceType distR = 0; + StartStopTimer t; + int repeats = 0; + while (t.value<0.2) { + repeats++; + t.start(); + correct = 0; + distR = 0; + for (size_t i = 0; i < testData.rows; i++) { + resultSet.init(&indices[0], &dists[0]); + index.findNeighbors(resultSet, testData[i], searchParams); + + correct += countCorrectMatches(neighbors,matches[i], nn); + distR += computeDistanceRaport(inputData, testData[i], neighbors, matches[i], (int)testData.cols, nn, distance); + } + t.stop(); + } + time = float(t.value/repeats); + + float precicion = (float)correct/(nn*testData.rows); + + dist = distR/(testData.rows*nn); + + Logger::info("%8d %10.4g %10.5g %10.5g %10.5g\n", + checks, precicion, time, 1000.0 * time / testData.rows, dist); + + return precicion; +} + + +template +float test_index_checks(NNIndex& index, const Matrix& inputData, + const Matrix& testData, const Matrix& matches, + int checks, float& precision, const Distance& distance, int nn = 1, int skipMatches = 0) +{ + typedef typename Distance::ResultType DistanceType; + + Logger::info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n"); + Logger::info("---------------------------------------------------------\n"); + + float time = 0; + DistanceType dist = 0; + precision = search_with_ground_truth(index, inputData, testData, matches, nn, checks, time, dist, distance, skipMatches); + + return time; +} + +template +float test_index_precision(NNIndex& index, const Matrix& inputData, + const Matrix& testData, const Matrix& matches, + float precision, int& checks, const Distance& distance, int nn = 1, int skipMatches = 0) +{ + typedef typename Distance::ResultType DistanceType; + const float SEARCH_EPS = 0.001f; + + Logger::info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n"); + Logger::info("---------------------------------------------------------\n"); + + int c2 = 1; + float p2; + int c1 = 1; + //float p1; + float time; + DistanceType dist; + + p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, distance, skipMatches); + + if (p2>precision) { + Logger::info("Got as close as I can\n"); + checks = c2; + return time; + } + + while (p2SEARCH_EPS) { + Logger::info("Start linear estimation\n"); + // after we got to values in the vecinity of the desired precision + // use linear approximation get a better estimation + + cx = (c1+c2)/2; + realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, distance, skipMatches); + while (fabs(realPrecision-precision)>SEARCH_EPS) { + + if (realPrecision +void test_index_precisions(NNIndex& index, const Matrix& inputData, + const Matrix& testData, const Matrix& matches, + float* precisions, int precisions_length, const Distance& distance, int nn = 1, int skipMatches = 0, float maxTime = 0) +{ + typedef typename Distance::ResultType DistanceType; + + const float SEARCH_EPS = 0.001; + + // make sure precisions array is sorted + std::sort(precisions, precisions+precisions_length); + + int pindex = 0; + float precision = precisions[pindex]; + + Logger::info(" Nodes Precision(%) Time(s) Time/vec(ms) Mean dist\n"); + Logger::info("---------------------------------------------------------\n"); + + int c2 = 1; + float p2; + + int c1 = 1; + float p1; + + float time; + DistanceType dist; + + p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, distance, skipMatches); + + // if precision for 1 run down the tree is already + // better then some of the requested precisions, then + // skip those + while (precisions[pindex] 0)&&(time > maxTime)&&(p2SEARCH_EPS) { + Logger::info("Start linear estimation\n"); + // after we got to values in the vecinity of the desired precision + // use linear approximation get a better estimation + + cx = (c1+c2)/2; + realPrecision = search_with_ground_truth(index, inputData, testData, matches, nn, cx, time, dist, distance, skipMatches); + while (fabs(realPrecision-precision)>SEARCH_EPS) { + + if (realPrecision +#include +#include +#include + +#include "general.h" +#include "nn_index.h" +#include "dynamic_bitset.h" +#include "matrix.h" +#include "result_set.h" +#include "heap.h" +#include "allocator.h" +#include "random.h" +#include "saving.h" + + +namespace cvflann +{ + +struct KDTreeIndexParams : public IndexParams +{ + KDTreeIndexParams(int trees = 4) + { + (*this)["algorithm"] = FLANN_INDEX_KDTREE; + (*this)["trees"] = trees; + } +}; + + +/** + * Randomized kd-tree index + * + * Contains the k-d trees and other information for indexing a set of points + * for nearest-neighbor matching. + */ +template +class KDTreeIndex : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + + /** + * KDTree constructor + * + * Params: + * inputData = dataset with the input features + * params = parameters passed to the kdtree algorithm + */ + KDTreeIndex(const Matrix& inputData, const IndexParams& params = KDTreeIndexParams(), + Distance d = Distance() ) : + dataset_(inputData), index_params_(params), distance_(d) + { + size_ = dataset_.rows; + veclen_ = dataset_.cols; + + trees_ = get_param(index_params_,"trees",4); + tree_roots_ = new NodePtr[trees_]; + + // Create a permutable array of indices to the input vectors. + vind_.resize(size_); + for (size_t i = 0; i < size_; ++i) { + vind_[i] = int(i); + } + + mean_ = new DistanceType[veclen_]; + var_ = new DistanceType[veclen_]; + } + + + KDTreeIndex(const KDTreeIndex&); + KDTreeIndex& operator=(const KDTreeIndex&); + + /** + * Standard destructor + */ + ~KDTreeIndex() + { + if (tree_roots_!=NULL) { + delete[] tree_roots_; + } + delete[] mean_; + delete[] var_; + } + + /** + * Builds the index + */ + void buildIndex() CV_OVERRIDE + { + /* Construct the randomized trees. */ + for (int i = 0; i < trees_; i++) { + /* Randomize the order of vectors to allow for unbiased sampling. */ +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::randShuffle(vind_); +#else + std::random_shuffle(vind_.begin(), vind_.end()); +#endif + + tree_roots_[i] = divideTree(&vind_[0], int(size_) ); + } + } + + + flann_algorithm_t getType() const CV_OVERRIDE + { + return FLANN_INDEX_KDTREE; + } + + + void saveIndex(FILE* stream) CV_OVERRIDE + { + save_value(stream, trees_); + for (int i=0; i& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE + { + int maxChecks = get_param(searchParams,"checks", 32); + float epsError = 1+get_param(searchParams,"eps",0.0f); + + if (maxChecks==FLANN_CHECKS_UNLIMITED) { + getExactNeighbors(result, vec, epsError); + } + else { + getNeighbors(result, vec, maxChecks, epsError); + } + } + + IndexParams getParameters() const CV_OVERRIDE + { + return index_params_; + } + +private: + + + /*--------------------- Internal Data Structures --------------------------*/ + struct Node + { + /** + * Dimension used for subdivision. + */ + int divfeat; + /** + * The values used for subdivision. + */ + DistanceType divval; + /** + * The child nodes. + */ + Node* child1, * child2; + }; + typedef Node* NodePtr; + typedef BranchStruct BranchSt; + typedef BranchSt* Branch; + + + + void save_tree(FILE* stream, NodePtr tree) + { + save_value(stream, *tree); + if (tree->child1!=NULL) { + save_tree(stream, tree->child1); + } + if (tree->child2!=NULL) { + save_tree(stream, tree->child2); + } + } + + + void load_tree(FILE* stream, NodePtr& tree) + { + tree = pool_.allocate(); + load_value(stream, *tree); + if (tree->child1!=NULL) { + load_tree(stream, tree->child1); + } + if (tree->child2!=NULL) { + load_tree(stream, tree->child2); + } + } + + + /** + * Create a tree node that subdivides the list of vecs from vind[first] + * to vind[last]. The routine is called recursively on each sublist. + * Place a pointer to this new tree node in the location pTree. + * + * Params: pTree = the new node to create + * first = index of the first vector + * last = index of the last vector + */ + NodePtr divideTree(int* ind, int count) + { + NodePtr node = pool_.allocate(); // allocate memory + + /* If too few exemplars remain, then make this a leaf node. */ + if ( count == 1) { + node->child1 = node->child2 = NULL; /* Mark as leaf node. */ + node->divfeat = *ind; /* Store index of this vec. */ + } + else { + int idx; + int cutfeat; + DistanceType cutval; + meanSplit(ind, count, idx, cutfeat, cutval); + + node->divfeat = cutfeat; + node->divval = cutval; + node->child1 = divideTree(ind, idx); + node->child2 = divideTree(ind+idx, count-idx); + } + + return node; + } + + + /** + * Choose which feature to use in order to subdivide this set of vectors. + * Make a random choice among those with the highest variance, and use + * its variance as the threshold value. + */ + void meanSplit(int* ind, int count, int& index, int& cutfeat, DistanceType& cutval) + { + memset(mean_,0,veclen_*sizeof(DistanceType)); + memset(var_,0,veclen_*sizeof(DistanceType)); + + /* Compute mean values. Only the first SAMPLE_MEAN values need to be + sampled to get a good estimate. + */ + int cnt = std::min((int)SAMPLE_MEAN+1, count); + for (int j = 0; j < cnt; ++j) { + ElementType* v = dataset_[ind[j]]; + for (size_t k=0; kcount/2) index = lim1; + else if (lim2 v[topind[num-1]])) { + /* Put this element at end of topind. */ + if (num < RAND_DIM) { + topind[num++] = i; /* Add to list. */ + } + else { + topind[num-1] = i; /* Replace last element. */ + } + /* Bubble end value down to right location by repeated swapping. */ + int j = num - 1; + while (j > 0 && v[topind[j]] > v[topind[j-1]]) { + std::swap(topind[j], topind[j-1]); + --j; + } + } + } + /* Select a random integer in range [0,num-1], and return that index. */ + int rnd = rand_int(num); + return (int)topind[rnd]; + } + + + /** + * Subdivide the list of points by a plane perpendicular on axe corresponding + * to the 'cutfeat' dimension at 'cutval' position. + * + * On return: + * dataset[ind[0..lim1-1]][cutfeat]cutval + */ + void planeSplit(int* ind, int count, int cutfeat, DistanceType cutval, int& lim1, int& lim2) + { + /* Move vector indices for left subtree to front of list. */ + int left = 0; + int right = count-1; + for (;; ) { + while (left<=right && dataset_[ind[left]][cutfeat]=cutval) --right; + if (left>right) break; + std::swap(ind[left], ind[right]); ++left; --right; + } + lim1 = left; + right = count-1; + for (;; ) { + while (left<=right && dataset_[ind[left]][cutfeat]<=cutval) ++left; + while (left<=right && dataset_[ind[right]][cutfeat]>cutval) --right; + if (left>right) break; + std::swap(ind[left], ind[right]); ++left; --right; + } + lim2 = left; + } + + /** + * Performs an exact nearest neighbor search. The exact search performs a full + * traversal of the tree. + */ + void getExactNeighbors(ResultSet& result, const ElementType* vec, float epsError) + { + // checkID -= 1; /* Set a different unique ID for each search. */ + + if (trees_ > 1) { + fprintf(stderr,"It doesn't make any sense to use more than one tree for exact search"); + } + if (trees_>0) { + searchLevelExact(result, vec, tree_roots_[0], 0.0, epsError); + } + assert(result.full()); + } + + /** + * Performs the approximate nearest-neighbor search. The search is approximate + * because the tree traversal is abandoned after a given number of descends in + * the tree. + */ + void getNeighbors(ResultSet& result, const ElementType* vec, int maxCheck, float epsError) + { + int i; + BranchSt branch; + + int checkCount = 0; + Heap* heap = new Heap((int)size_); + DynamicBitset checked(size_); + + /* Search once through each tree down to root. */ + for (i = 0; i < trees_; ++i) { + searchLevel(result, vec, tree_roots_[i], 0, checkCount, maxCheck, epsError, heap, checked); + } + + /* Keep searching other branches from heap until finished. */ + while ( heap->popMin(branch) && (checkCount < maxCheck || !result.full() )) { + searchLevel(result, vec, branch.node, branch.mindist, checkCount, maxCheck, epsError, heap, checked); + } + + delete heap; + + assert(result.full()); + } + + + /** + * Search starting from a given node of the tree. Based on any mismatches at + * higher levels, all exemplars below this level must have a distance of + * at least "mindistsq". + */ + void searchLevel(ResultSet& result_set, const ElementType* vec, NodePtr node, DistanceType mindist, int& checkCount, int maxCheck, + float epsError, Heap* heap, DynamicBitset& checked) + { + if (result_set.worstDist()child1 == NULL)&&(node->child2 == NULL)) { + /* Do not check same node more than once when searching multiple trees. + Once a vector is checked, we set its location in vind to the + current checkID. + */ + int index = node->divfeat; + if ( checked.test(index) || ((checkCount>=maxCheck)&& result_set.full()) ) return; + checked.set(index); + checkCount++; + + DistanceType dist = distance_(dataset_[index], vec, veclen_); + result_set.addPoint(dist,index); + + return; + } + + /* Which child branch should be taken first? */ + ElementType val = vec[node->divfeat]; + DistanceType diff = val - node->divval; + NodePtr bestChild = (diff < 0) ? node->child1 : node->child2; + NodePtr otherChild = (diff < 0) ? node->child2 : node->child1; + + /* Create a branch record for the branch not taken. Add distance + of this feature boundary (we don't attempt to correct for any + use of this feature in a parent node, which is unlikely to + happen and would have only a small effect). Don't bother + adding more branches to heap after halfway point, as cost of + adding exceeds their value. + */ + + DistanceType new_distsq = mindist + distance_.accum_dist(val, node->divval, node->divfeat); + // if (2 * checkCount < maxCheck || !result.full()) { + if ((new_distsq*epsError < result_set.worstDist())|| !result_set.full()) { + heap->insert( BranchSt(otherChild, new_distsq) ); + } + + /* Call recursively to search next level down. */ + searchLevel(result_set, vec, bestChild, mindist, checkCount, maxCheck, epsError, heap, checked); + } + + /** + * Performs an exact search in the tree starting from a node. + */ + void searchLevelExact(ResultSet& result_set, const ElementType* vec, const NodePtr node, DistanceType mindist, const float epsError) + { + /* If this is a leaf node, then do check and return. */ + if ((node->child1 == NULL)&&(node->child2 == NULL)) { + int index = node->divfeat; + DistanceType dist = distance_(dataset_[index], vec, veclen_); + result_set.addPoint(dist,index); + return; + } + + /* Which child branch should be taken first? */ + ElementType val = vec[node->divfeat]; + DistanceType diff = val - node->divval; + NodePtr bestChild = (diff < 0) ? node->child1 : node->child2; + NodePtr otherChild = (diff < 0) ? node->child2 : node->child1; + + /* Create a branch record for the branch not taken. Add distance + of this feature boundary (we don't attempt to correct for any + use of this feature in a parent node, which is unlikely to + happen and would have only a small effect). Don't bother + adding more branches to heap after halfway point, as cost of + adding exceeds their value. + */ + + DistanceType new_distsq = mindist + distance_.accum_dist(val, node->divval, node->divfeat); + + /* Call recursively to search next level down. */ + searchLevelExact(result_set, vec, bestChild, mindist, epsError); + + if (new_distsq*epsError<=result_set.worstDist()) { + searchLevelExact(result_set, vec, otherChild, new_distsq, epsError); + } + } + + +private: + + enum + { + /** + * To improve efficiency, only SAMPLE_MEAN random values are used to + * compute the mean and variance at each level when building a tree. + * A value of 100 seems to perform as well as using all values. + */ + SAMPLE_MEAN = 100, + /** + * Top random dimensions to consider + * + * When creating random trees, the dimension on which to subdivide is + * selected at random from among the top RAND_DIM dimensions with the + * highest variance. A value of 5 works well. + */ + RAND_DIM=5 + }; + + + /** + * Number of randomized trees that are used + */ + int trees_; + + /** + * Array of indices to vectors in the dataset. + */ + std::vector vind_; + + /** + * The dataset used by this index + */ + const Matrix dataset_; + + IndexParams index_params_; + + size_t size_; + size_t veclen_; + + + DistanceType* mean_; + DistanceType* var_; + + + /** + * Array of k-d trees used to find neighbours. + */ + NodePtr* tree_roots_; + + /** + * Pooled memory allocator. + * + * Using a pooled memory allocator is more efficient + * than allocating memory directly when there is a large + * number small of memory allocations. + */ + PooledAllocator pool_; + + Distance distance_; + + +}; // class KDTreeForest + +} + +#endif //OPENCV_FLANN_KDTREE_INDEX_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/kdtree_single_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/kdtree_single_index.h new file mode 100755 index 0000000..22a28d0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/kdtree_single_index.h @@ -0,0 +1,635 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_KDTREE_SINGLE_INDEX_H_ +#define OPENCV_FLANN_KDTREE_SINGLE_INDEX_H_ + +#include +#include +#include +#include + +#include "general.h" +#include "nn_index.h" +#include "matrix.h" +#include "result_set.h" +#include "heap.h" +#include "allocator.h" +#include "random.h" +#include "saving.h" + +namespace cvflann +{ + +struct KDTreeSingleIndexParams : public IndexParams +{ + KDTreeSingleIndexParams(int leaf_max_size = 10, bool reorder = true, int dim = -1) + { + (*this)["algorithm"] = FLANN_INDEX_KDTREE_SINGLE; + (*this)["leaf_max_size"] = leaf_max_size; + (*this)["reorder"] = reorder; + (*this)["dim"] = dim; + } +}; + + +/** + * Randomized kd-tree index + * + * Contains the k-d trees and other information for indexing a set of points + * for nearest-neighbor matching. + */ +template +class KDTreeSingleIndex : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + + /** + * KDTree constructor + * + * Params: + * inputData = dataset with the input features + * params = parameters passed to the kdtree algorithm + */ + KDTreeSingleIndex(const Matrix& inputData, const IndexParams& params = KDTreeSingleIndexParams(), + Distance d = Distance() ) : + dataset_(inputData), index_params_(params), distance_(d) + { + size_ = dataset_.rows; + dim_ = dataset_.cols; + root_node_ = 0; + int dim_param = get_param(params,"dim",-1); + if (dim_param>0) dim_ = dim_param; + leaf_max_size_ = get_param(params,"leaf_max_size",10); + reorder_ = get_param(params,"reorder",true); + + // Create a permutable array of indices to the input vectors. + vind_.resize(size_); + for (size_t i = 0; i < size_; i++) { + vind_[i] = (int)i; + } + } + + KDTreeSingleIndex(const KDTreeSingleIndex&); + KDTreeSingleIndex& operator=(const KDTreeSingleIndex&); + + /** + * Standard destructor + */ + ~KDTreeSingleIndex() + { + if (reorder_) delete[] data_.data; + } + + /** + * Builds the index + */ + void buildIndex() CV_OVERRIDE + { + computeBoundingBox(root_bbox_); + root_node_ = divideTree(0, (int)size_, root_bbox_ ); // construct the tree + + if (reorder_) { + delete[] data_.data; + data_ = cvflann::Matrix(new ElementType[size_*dim_], size_, dim_); + for (size_t i=0; i& queries, Matrix& indices, Matrix& dists, int knn, const SearchParams& params) CV_OVERRIDE + { + assert(queries.cols == veclen()); + assert(indices.rows >= queries.rows); + assert(dists.rows >= queries.rows); + assert(int(indices.cols) >= knn); + assert(int(dists.cols) >= knn); + + KNNSimpleResultSet resultSet(knn); + for (size_t i = 0; i < queries.rows; i++) { + resultSet.init(indices[i], dists[i]); + findNeighbors(resultSet, queries[i], params); + } + } + + IndexParams getParameters() const CV_OVERRIDE + { + return index_params_; + } + + /** + * Find set of nearest neighbors to vec. Their indices are stored inside + * the result object. + * + * Params: + * result = the result object in which the indices of the nearest-neighbors are stored + * vec = the vector for which to search the nearest neighbors + * maxCheck = the maximum number of restarts (in a best-bin-first manner) + */ + void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE + { + float epsError = 1+get_param(searchParams,"eps",0.0f); + + std::vector dists(dim_,0); + DistanceType distsq = computeInitialDistances(vec, dists); + searchLevel(result, vec, root_node_, distsq, dists, epsError); + } + +private: + + + /*--------------------- Internal Data Structures --------------------------*/ + struct Node + { + /** + * Indices of points in leaf node + */ + int left, right; + /** + * Dimension used for subdivision. + */ + int divfeat; + /** + * The values used for subdivision. + */ + DistanceType divlow, divhigh; + /** + * The child nodes. + */ + Node* child1, * child2; + }; + typedef Node* NodePtr; + + + struct Interval + { + DistanceType low, high; + }; + + typedef std::vector BoundingBox; + + typedef BranchStruct BranchSt; + typedef BranchSt* Branch; + + + + + void save_tree(FILE* stream, NodePtr tree) + { + save_value(stream, *tree); + if (tree->child1!=NULL) { + save_tree(stream, tree->child1); + } + if (tree->child2!=NULL) { + save_tree(stream, tree->child2); + } + } + + + void load_tree(FILE* stream, NodePtr& tree) + { + tree = pool_.allocate(); + load_value(stream, *tree); + if (tree->child1!=NULL) { + load_tree(stream, tree->child1); + } + if (tree->child2!=NULL) { + load_tree(stream, tree->child2); + } + } + + + void computeBoundingBox(BoundingBox& bbox) + { + bbox.resize(dim_); + for (size_t i=0; ibbox[i].high) bbox[i].high = (DistanceType)dataset_[k][i]; + } + } + } + + + /** + * Create a tree node that subdivides the list of vecs from vind[first] + * to vind[last]. The routine is called recursively on each sublist. + * Place a pointer to this new tree node in the location pTree. + * + * Params: pTree = the new node to create + * first = index of the first vector + * last = index of the last vector + */ + NodePtr divideTree(int left, int right, BoundingBox& bbox) + { + NodePtr node = pool_.allocate(); // allocate memory + + /* If too few exemplars remain, then make this a leaf node. */ + if ( (right-left) <= leaf_max_size_) { + node->child1 = node->child2 = NULL; /* Mark as leaf node. */ + node->left = left; + node->right = right; + + // compute bounding-box of leaf points + for (size_t i=0; idataset_[vind_[k]][i]) bbox[i].low=(DistanceType)dataset_[vind_[k]][i]; + if (bbox[i].highdivfeat = cutfeat; + + BoundingBox left_bbox(bbox); + left_bbox[cutfeat].high = cutval; + node->child1 = divideTree(left, left+idx, left_bbox); + + BoundingBox right_bbox(bbox); + right_bbox[cutfeat].low = cutval; + node->child2 = divideTree(left+idx, right, right_bbox); + + node->divlow = left_bbox[cutfeat].high; + node->divhigh = right_bbox[cutfeat].low; + + for (size_t i=0; imax_elem) max_elem = val; + } + } + + void middleSplit(int* ind, int count, int& index, int& cutfeat, DistanceType& cutval, const BoundingBox& bbox) + { + // find the largest span from the approximate bounding box + ElementType max_span = bbox[0].high-bbox[0].low; + cutfeat = 0; + cutval = (bbox[0].high+bbox[0].low)/2; + for (size_t i=1; imax_span) { + max_span = span; + cutfeat = i; + cutval = (bbox[i].high+bbox[i].low)/2; + } + } + + // compute exact span on the found dimension + ElementType min_elem, max_elem; + computeMinMax(ind, count, cutfeat, min_elem, max_elem); + cutval = (min_elem+max_elem)/2; + max_span = max_elem - min_elem; + + // check if a dimension of a largest span exists + size_t k = cutfeat; + for (size_t i=0; imax_span) { + computeMinMax(ind, count, i, min_elem, max_elem); + span = max_elem - min_elem; + if (span>max_span) { + max_span = span; + cutfeat = i; + cutval = (min_elem+max_elem)/2; + } + } + } + int lim1, lim2; + planeSplit(ind, count, cutfeat, cutval, lim1, lim2); + + if (lim1>count/2) index = lim1; + else if (lim2max_span) { + max_span = span; + } + } + DistanceType max_spread = -1; + cutfeat = 0; + for (size_t i=0; i(DistanceType)((1-EPS)*max_span)) { + ElementType min_elem, max_elem; + computeMinMax(ind, count, cutfeat, min_elem, max_elem); + DistanceType spread = (DistanceType)(max_elem-min_elem); + if (spread>max_spread) { + cutfeat = (int)i; + max_spread = spread; + } + } + } + // split in the middle + DistanceType split_val = (bbox[cutfeat].low+bbox[cutfeat].high)/2; + ElementType min_elem, max_elem; + computeMinMax(ind, count, cutfeat, min_elem, max_elem); + + if (split_valmax_elem) cutval = (DistanceType)max_elem; + else cutval = split_val; + + int lim1, lim2; + planeSplit(ind, count, cutfeat, cutval, lim1, lim2); + + if (lim1>count/2) index = lim1; + else if (lim2cutval + */ + void planeSplit(int* ind, int count, int cutfeat, DistanceType cutval, int& lim1, int& lim2) + { + /* Move vector indices for left subtree to front of list. */ + int left = 0; + int right = count-1; + for (;; ) { + while (left<=right && dataset_[ind[left]][cutfeat]=cutval) --right; + if (left>right) break; + std::swap(ind[left], ind[right]); ++left; --right; + } + /* If either list is empty, it means that all remaining features + * are identical. Split in the middle to maintain a balanced tree. + */ + lim1 = left; + right = count-1; + for (;; ) { + while (left<=right && dataset_[ind[left]][cutfeat]<=cutval) ++left; + while (left<=right && dataset_[ind[right]][cutfeat]>cutval) --right; + if (left>right) break; + std::swap(ind[left], ind[right]); ++left; --right; + } + lim2 = left; + } + + DistanceType computeInitialDistances(const ElementType* vec, std::vector& dists) + { + DistanceType distsq = 0.0; + + for (size_t i = 0; i < dim_; ++i) { + if (vec[i] < root_bbox_[i].low) { + dists[i] = distance_.accum_dist(vec[i], root_bbox_[i].low, (int)i); + distsq += dists[i]; + } + if (vec[i] > root_bbox_[i].high) { + dists[i] = distance_.accum_dist(vec[i], root_bbox_[i].high, (int)i); + distsq += dists[i]; + } + } + + return distsq; + } + + /** + * Performs an exact search in the tree starting from a node. + */ + void searchLevel(ResultSet& result_set, const ElementType* vec, const NodePtr node, DistanceType mindistsq, + std::vector& dists, const float epsError) + { + /* If this is a leaf node, then do check and return. */ + if ((node->child1 == NULL)&&(node->child2 == NULL)) { + DistanceType worst_dist = result_set.worstDist(); + for (int i=node->left; iright; ++i) { + int index = reorder_ ? i : vind_[i]; + DistanceType dist = distance_(vec, data_[index], dim_, worst_dist); + if (distdivfeat; + ElementType val = vec[idx]; + DistanceType diff1 = val - node->divlow; + DistanceType diff2 = val - node->divhigh; + + NodePtr bestChild; + NodePtr otherChild; + DistanceType cut_dist; + if ((diff1+diff2)<0) { + bestChild = node->child1; + otherChild = node->child2; + cut_dist = distance_.accum_dist(val, node->divhigh, idx); + } + else { + bestChild = node->child2; + otherChild = node->child1; + cut_dist = distance_.accum_dist( val, node->divlow, idx); + } + + /* Call recursively to search next level down. */ + searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError); + + DistanceType dst = dists[idx]; + mindistsq = mindistsq + cut_dist - dst; + dists[idx] = cut_dist; + if (mindistsq*epsError<=result_set.worstDist()) { + searchLevel(result_set, vec, otherChild, mindistsq, dists, epsError); + } + dists[idx] = dst; + } + +private: + + /** + * The dataset used by this index + */ + const Matrix dataset_; + + IndexParams index_params_; + + int leaf_max_size_; + bool reorder_; + + + /** + * Array of indices to vectors in the dataset. + */ + std::vector vind_; + + Matrix data_; + + size_t size_; + size_t dim_; + + /** + * Array of k-d trees used to find neighbours. + */ + NodePtr root_node_; + + BoundingBox root_bbox_; + + /** + * Pooled memory allocator. + * + * Using a pooled memory allocator is more efficient + * than allocating memory directly when there is a large + * number small of memory allocations. + */ + PooledAllocator pool_; + + Distance distance_; +}; // class KDTree + +} + +#endif //OPENCV_FLANN_KDTREE_SINGLE_INDEX_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/kmeans_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/kmeans_index.h new file mode 100755 index 0000000..fe91ddd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/kmeans_index.h @@ -0,0 +1,1172 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_KMEANS_INDEX_H_ +#define OPENCV_FLANN_KMEANS_INDEX_H_ + +#include +#include +#include +#include +#include + +#include "general.h" +#include "nn_index.h" +#include "dist.h" +#include "matrix.h" +#include "result_set.h" +#include "heap.h" +#include "allocator.h" +#include "random.h" +#include "saving.h" +#include "logger.h" + + +namespace cvflann +{ + +struct KMeansIndexParams : public IndexParams +{ + KMeansIndexParams(int branching = 32, int iterations = 11, + flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM, float cb_index = 0.2 ) + { + (*this)["algorithm"] = FLANN_INDEX_KMEANS; + // branching factor + (*this)["branching"] = branching; + // max iterations to perform in one kmeans clustering (kmeans tree) + (*this)["iterations"] = iterations; + // algorithm used for picking the initial cluster centers for kmeans tree + (*this)["centers_init"] = centers_init; + // cluster boundary index. Used when searching the kmeans tree + (*this)["cb_index"] = cb_index; + } +}; + + +/** + * Hierarchical kmeans index + * + * Contains a tree constructed through a hierarchical kmeans clustering + * and other information for indexing a set of points for nearest-neighbour matching. + */ +template +class KMeansIndex : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + + + typedef void (KMeansIndex::* centersAlgFunction)(int, int*, int, int*, int&); + + /** + * The function used for choosing the cluster centers. + */ + centersAlgFunction chooseCenters; + + + + /** + * Chooses the initial centers in the k-means clustering in a random manner. + * + * Params: + * k = number of centers + * vecs = the dataset of points + * indices = indices in the dataset + * indices_length = length of indices vector + * + */ + void chooseCentersRandom(int k, int* indices, int indices_length, int* centers, int& centers_length) + { + UniqueRandom r(indices_length); + + int index; + for (index=0; index=0 && rnd < n); + + centers[0] = indices[rnd]; + + int index; + for (index=1; indexbest_val) { + best_val = dist; + best_index = j; + } + } + if (best_index!=-1) { + centers[index] = indices[best_index]; + } + else { + break; + } + } + centers_length = index; + } + + + /** + * Chooses the initial centers in the k-means using the algorithm + * proposed in the KMeans++ paper: + * Arthur, David; Vassilvitskii, Sergei - k-means++: The Advantages of Careful Seeding + * + * Implementation of this function was converted from the one provided in Arthur's code. + * + * Params: + * k = number of centers + * vecs = the dataset of points + * indices = indices in the dataset + * Returns: + */ + void chooseCentersKMeanspp(int k, int* indices, int indices_length, int* centers, int& centers_length) + { + int n = indices_length; + + double currentPot = 0; + DistanceType* closestDistSq = new DistanceType[n]; + + // Choose one random center and set the closestDistSq values + int index = rand_int(n); + assert(index >=0 && index < n); + centers[0] = indices[index]; + + for (int i = 0; i < n; i++) { + closestDistSq[i] = distance_(dataset_[indices[i]], dataset_[indices[index]], dataset_.cols); + closestDistSq[i] = ensureSquareDistance( closestDistSq[i] ); + currentPot += closestDistSq[i]; + } + + + const int numLocalTries = 1; + + // Choose each center + int centerCount; + for (centerCount = 1; centerCount < k; centerCount++) { + + // Repeat several trials + double bestNewPot = -1; + int bestNewIndex = -1; + for (int localTrial = 0; localTrial < numLocalTries; localTrial++) { + + // Choose our center - have to be slightly careful to return a valid answer even accounting + // for possible rounding errors + double randVal = rand_double(currentPot); + for (index = 0; index < n-1; index++) { + if (randVal <= closestDistSq[index]) break; + else randVal -= closestDistSq[index]; + } + + // Compute the new potential + double newPot = 0; + for (int i = 0; i < n; i++) { + DistanceType dist = distance_(dataset_[indices[i]], dataset_[indices[index]], dataset_.cols); + newPot += std::min( ensureSquareDistance(dist), closestDistSq[i] ); + } + + // Store the best result + if ((bestNewPot < 0)||(newPot < bestNewPot)) { + bestNewPot = newPot; + bestNewIndex = index; + } + } + + // Add the appropriate center + centers[centerCount] = indices[bestNewIndex]; + currentPot = bestNewPot; + for (int i = 0; i < n; i++) { + DistanceType dist = distance_(dataset_[indices[i]], dataset_[indices[bestNewIndex]], dataset_.cols); + closestDistSq[i] = std::min( ensureSquareDistance(dist), closestDistSq[i] ); + } + } + + centers_length = centerCount; + + delete[] closestDistSq; + } + + + +public: + + flann_algorithm_t getType() const CV_OVERRIDE + { + return FLANN_INDEX_KMEANS; + } + + class KMeansDistanceComputer : public cv::ParallelLoopBody + { + public: + KMeansDistanceComputer(Distance _distance, const Matrix& _dataset, + const int _branching, const int* _indices, const Matrix& _dcenters, const size_t _veclen, + std::vector &_new_centroids, std::vector &_sq_dists) + : distance(_distance) + , dataset(_dataset) + , branching(_branching) + , indices(_indices) + , dcenters(_dcenters) + , veclen(_veclen) + , new_centroids(_new_centroids) + , sq_dists(_sq_dists) + { + } + + void operator()(const cv::Range& range) const CV_OVERRIDE + { + const int begin = range.start; + const int end = range.end; + + for( int i = begin; inew_sq_dist) { + new_centroid = j; + sq_dist = new_sq_dist; + } + } + sq_dists[i] = sq_dist; + new_centroids[i] = new_centroid; + } + } + + private: + Distance distance; + const Matrix& dataset; + const int branching; + const int* indices; + const Matrix& dcenters; + const size_t veclen; + std::vector &new_centroids; + std::vector &sq_dists; + KMeansDistanceComputer& operator=( const KMeansDistanceComputer & ) { return *this; } + }; + + /** + * Index constructor + * + * Params: + * inputData = dataset with the input features + * params = parameters passed to the hierarchical k-means algorithm + */ + KMeansIndex(const Matrix& inputData, const IndexParams& params = KMeansIndexParams(), + Distance d = Distance()) + : dataset_(inputData), index_params_(params), root_(NULL), indices_(NULL), distance_(d) + { + memoryCounter_ = 0; + + size_ = dataset_.rows; + veclen_ = dataset_.cols; + + branching_ = get_param(params,"branching",32); + iterations_ = get_param(params,"iterations",11); + if (iterations_<0) { + iterations_ = (std::numeric_limits::max)(); + } + centers_init_ = get_param(params,"centers_init",FLANN_CENTERS_RANDOM); + + if (centers_init_==FLANN_CENTERS_RANDOM) { + chooseCenters = &KMeansIndex::chooseCentersRandom; + } + else if (centers_init_==FLANN_CENTERS_GONZALES) { + chooseCenters = &KMeansIndex::chooseCentersGonzales; + } + else if (centers_init_==FLANN_CENTERS_KMEANSPP) { + chooseCenters = &KMeansIndex::chooseCentersKMeanspp; + } + else { + throw FLANNException("Unknown algorithm for choosing initial centers."); + } + cb_index_ = 0.4f; + + } + + + KMeansIndex(const KMeansIndex&); + KMeansIndex& operator=(const KMeansIndex&); + + + /** + * Index destructor. + * + * Release the memory used by the index. + */ + virtual ~KMeansIndex() + { + if (root_ != NULL) { + free_centers(root_); + } + if (indices_!=NULL) { + delete[] indices_; + } + } + + /** + * Returns size of index. + */ + size_t size() const CV_OVERRIDE + { + return size_; + } + + /** + * Returns the length of an index feature. + */ + size_t veclen() const CV_OVERRIDE + { + return veclen_; + } + + + void set_cb_index( float index) + { + cb_index_ = index; + } + + /** + * Computes the inde memory usage + * Returns: memory used by the index + */ + int usedMemory() const CV_OVERRIDE + { + return pool_.usedMemory+pool_.wastedMemory+memoryCounter_; + } + + /** + * Builds the index + */ + void buildIndex() CV_OVERRIDE + { + if (branching_<2) { + throw FLANNException("Branching factor must be at least 2"); + } + + indices_ = new int[size_]; + for (size_t i=0; i(); + std::memset(root_, 0, sizeof(KMeansNode)); + + computeNodeStatistics(root_, indices_, (int)size_); + computeClustering(root_, indices_, (int)size_, branching_,0); + } + + + void saveIndex(FILE* stream) CV_OVERRIDE + { + save_value(stream, branching_); + save_value(stream, iterations_); + save_value(stream, memoryCounter_); + save_value(stream, cb_index_); + save_value(stream, *indices_, (int)size_); + + save_tree(stream, root_); + } + + + void loadIndex(FILE* stream) CV_OVERRIDE + { + load_value(stream, branching_); + load_value(stream, iterations_); + load_value(stream, memoryCounter_); + load_value(stream, cb_index_); + if (indices_!=NULL) { + delete[] indices_; + } + indices_ = new int[size_]; + load_value(stream, *indices_, size_); + + if (root_!=NULL) { + free_centers(root_); + } + load_tree(stream, root_); + + index_params_["algorithm"] = getType(); + index_params_["branching"] = branching_; + index_params_["iterations"] = iterations_; + index_params_["centers_init"] = centers_init_; + index_params_["cb_index"] = cb_index_; + + } + + + /** + * Find set of nearest neighbors to vec. Their indices are stored inside + * the result object. + * + * Params: + * result = the result object in which the indices of the nearest-neighbors are stored + * vec = the vector for which to search the nearest neighbors + * searchParams = parameters that influence the search algorithm (checks, cb_index) + */ + void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) CV_OVERRIDE + { + + int maxChecks = get_param(searchParams,"checks",32); + + if (maxChecks==FLANN_CHECKS_UNLIMITED) { + findExactNN(root_, result, vec); + } + else { + // Priority queue storing intermediate branches in the best-bin-first search + Heap* heap = new Heap((int)size_); + + int checks = 0; + findNN(root_, result, vec, checks, maxChecks, heap); + + BranchSt branch; + while (heap->popMin(branch) && (checks& centers) + { + int numClusters = centers.rows; + if (numClusters<1) { + throw FLANNException("Number of clusters must be at least 1"); + } + + DistanceType variance; + KMeansNodePtr* clusters = new KMeansNodePtr[numClusters]; + + int clusterCount = getMinVarianceClusters(root_, clusters, numClusters, variance); + + Logger::info("Clusters requested: %d, returning %d\n",numClusters, clusterCount); + + for (int i=0; ipivot; + for (size_t j=0; j BranchSt; + + + + + void save_tree(FILE* stream, KMeansNodePtr node) + { + save_value(stream, *node); + save_value(stream, *(node->pivot), (int)veclen_); + if (node->childs==NULL) { + int indices_offset = (int)(node->indices - indices_); + save_value(stream, indices_offset); + } + else { + for(int i=0; ichilds[i]); + } + } + } + + + void load_tree(FILE* stream, KMeansNodePtr& node) + { + node = pool_.allocate(); + load_value(stream, *node); + node->pivot = new DistanceType[veclen_]; + load_value(stream, *(node->pivot), (int)veclen_); + if (node->childs==NULL) { + int indices_offset; + load_value(stream, indices_offset); + node->indices = indices_ + indices_offset; + } + else { + node->childs = pool_.allocate(branching_); + for(int i=0; ichilds[i]); + } + } + } + + + /** + * Helper function + */ + void free_centers(KMeansNodePtr node) + { + delete[] node->pivot; + if (node->childs!=NULL) { + for (int k=0; kchilds[k]); + } + } + } + + /** + * Computes the statistics of a node (mean, radius, variance). + * + * Params: + * node = the node to use + * indices = the indices of the points belonging to the node + */ + void computeNodeStatistics(KMeansNodePtr node, int* indices, int indices_length) + { + + DistanceType radius = 0; + DistanceType variance = 0; + DistanceType* mean = new DistanceType[veclen_]; + memoryCounter_ += int(veclen_*sizeof(DistanceType)); + + memset(mean,0,veclen_*sizeof(DistanceType)); + + for (size_t i=0; i(), veclen_); + } + for (size_t j=0; j(), veclen_); + + DistanceType tmp = 0; + for (int i=0; iradius) { + radius = tmp; + } + } + + node->variance = variance; + node->radius = radius; + node->pivot = mean; + } + + + /** + * The method responsible with actually doing the recursive hierarchical + * clustering + * + * Params: + * node = the node to cluster + * indices = indices of the points belonging to the current node + * branching = the branching factor to use in the clustering + * + * TODO: for 1-sized clusters don't store a cluster center (it's the same as the single cluster point) + */ + void computeClustering(KMeansNodePtr node, int* indices, int indices_length, int branching, int level) + { + node->size = indices_length; + node->level = level; + + if (indices_length < branching) { + node->indices = indices; + std::sort(node->indices,node->indices+indices_length); + node->childs = NULL; + return; + } + + cv::AutoBuffer centers_idx_buf(branching); + int* centers_idx = centers_idx_buf.data(); + int centers_length; + (this->*chooseCenters)(branching, indices, indices_length, centers_idx, centers_length); + + if (centers_lengthindices = indices; + std::sort(node->indices,node->indices+indices_length); + node->childs = NULL; + return; + } + + + cv::AutoBuffer dcenters_buf(branching*veclen_); + Matrix dcenters(dcenters_buf.data(), branching, veclen_); + for (int i=0; i radiuses(branching); + cv::AutoBuffer count_buf(branching); + int* count = count_buf.data(); + for (int i=0; i belongs_to_buf(indices_length); + int* belongs_to = belongs_to_buf.data(); + for (int i=0; inew_sq_dist) { + belongs_to[i] = j; + sq_dist = new_sq_dist; + } + } + if (sq_dist>radiuses[belongs_to[i]]) { + radiuses[belongs_to[i]] = sq_dist; + } + count[belongs_to[i]]++; + } + + bool converged = false; + int iteration = 0; + while (!converged && iteration new_centroids(indices_length); + std::vector sq_dists(indices_length); + + // reassign points to clusters + KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, new_centroids, sq_dists); + parallel_for_(cv::Range(0, (int)indices_length), invoker); + + for (int i=0; i < (int)indices_length; ++i) { + DistanceType sq_dist(sq_dists[i]); + int new_centroid(new_centroids[i]); + if (sq_dist > radiuses[new_centroid]) { + radiuses[new_centroid] = sq_dist; + } + if (new_centroid != belongs_to[i]) { + count[belongs_to[i]]--; + count[new_centroid]++; + belongs_to[i] = new_centroid; + converged = false; + } + } + + for (int i=0; ichilds = pool_.allocate(branching); + int start = 0; + int end = start; + for (int c=0; c(), veclen_); + variance += d; + mean_radius += sqrt(d); + std::swap(indices[i],indices[end]); + std::swap(belongs_to[i],belongs_to[end]); + end++; + } + } + variance /= s; + mean_radius /= s; + variance -= distance_(centers[c], ZeroIterator(), veclen_); + + node->childs[c] = pool_.allocate(); + std::memset(node->childs[c], 0, sizeof(KMeansNode)); + node->childs[c]->radius = radiuses[c]; + node->childs[c]->pivot = centers[c]; + node->childs[c]->variance = variance; + node->childs[c]->mean_radius = mean_radius; + computeClustering(node->childs[c],indices+start, end-start, branching, level+1); + start=end; + } + + delete[] centers; + } + + + + /** + * Performs one descent in the hierarchical k-means tree. The branches not + * visited are stored in a priority queue. + * + * Params: + * node = node to explore + * result = container for the k-nearest neighbors found + * vec = query points + * checks = how many points in the dataset have been checked so far + * maxChecks = maximum dataset points to checks + */ + + + void findNN(KMeansNodePtr node, ResultSet& result, const ElementType* vec, int& checks, int maxChecks, + Heap* heap) + { + // Ignore those clusters that are too far away + { + DistanceType bsq = distance_(vec, node->pivot, veclen_); + DistanceType rsq = node->radius; + DistanceType wsq = result.worstDist(); + + DistanceType val = bsq-rsq-wsq; + DistanceType val2 = val*val-4*rsq*wsq; + + //if (val>0) { + if ((val>0)&&(val2>0)) { + return; + } + } + + if (node->childs==NULL) { + if (checks>=maxChecks) { + if (result.full()) return; + } + checks += node->size; + for (int i=0; isize; ++i) { + int index = node->indices[i]; + DistanceType dist = distance_(dataset_[index], vec, veclen_); + result.addPoint(dist, index); + } + } + else { + DistanceType* domain_distances = new DistanceType[branching_]; + int closest_center = exploreNodeBranches(node, vec, domain_distances, heap); + delete[] domain_distances; + findNN(node->childs[closest_center],result,vec, checks, maxChecks, heap); + } + } + + /** + * Helper function that computes the nearest childs of a node to a given query point. + * Params: + * node = the node + * q = the query point + * distances = array with the distances to each child node. + * Returns: + */ + int exploreNodeBranches(KMeansNodePtr node, const ElementType* q, DistanceType* domain_distances, Heap* heap) + { + + int best_index = 0; + domain_distances[best_index] = distance_(q, node->childs[best_index]->pivot, veclen_); + for (int i=1; ichilds[i]->pivot, veclen_); + if (domain_distances[i]childs[best_index]->pivot; + for (int i=0; ichilds[i]->variance; + + // float dist_to_border = getDistanceToBorder(node.childs[i].pivot,best_center,q); + // if (domain_distances[i]insert(BranchSt(node->childs[i],domain_distances[i])); + } + } + + return best_index; + } + + + /** + * Function the performs exact nearest neighbor search by traversing the entire tree. + */ + void findExactNN(KMeansNodePtr node, ResultSet& result, const ElementType* vec) + { + // Ignore those clusters that are too far away + { + DistanceType bsq = distance_(vec, node->pivot, veclen_); + DistanceType rsq = node->radius; + DistanceType wsq = result.worstDist(); + + DistanceType val = bsq-rsq-wsq; + DistanceType val2 = val*val-4*rsq*wsq; + + // if (val>0) { + if ((val>0)&&(val2>0)) { + return; + } + } + + + if (node->childs==NULL) { + for (int i=0; isize; ++i) { + int index = node->indices[i]; + DistanceType dist = distance_(dataset_[index], vec, veclen_); + result.addPoint(dist, index); + } + } + else { + int* sort_indices = new int[branching_]; + + getCenterOrdering(node, vec, sort_indices); + + for (int i=0; ichilds[sort_indices[i]],result,vec); + } + + delete[] sort_indices; + } + } + + + /** + * Helper function. + * + * I computes the order in which to traverse the child nodes of a particular node. + */ + void getCenterOrdering(KMeansNodePtr node, const ElementType* q, int* sort_indices) + { + DistanceType* domain_distances = new DistanceType[branching_]; + for (int i=0; ichilds[i]->pivot, veclen_); + + int j=0; + while (domain_distances[j]j; --k) { + domain_distances[k] = domain_distances[k-1]; + sort_indices[k] = sort_indices[k-1]; + } + domain_distances[j] = dist; + sort_indices[j] = i; + } + delete[] domain_distances; + } + + /** + * Method that computes the squared distance from the query point q + * from inside region with center c to the border between this + * region and the region with center p + */ + DistanceType getDistanceToBorder(DistanceType* p, DistanceType* c, DistanceType* q) + { + DistanceType sum = 0; + DistanceType sum2 = 0; + + for (int i=0; ivariance*root->size; + + while (clusterCount::max)(); + int splitIndex = -1; + + for (int i=0; ichilds != NULL) { + + DistanceType variance = meanVariance - clusters[i]->variance*clusters[i]->size; + + for (int j=0; jchilds[j]->variance*clusters[i]->childs[j]->size; + } + if (variance clusters_length) break; + + meanVariance = minVariance; + + // split node + KMeansNodePtr toSplit = clusters[splitIndex]; + clusters[splitIndex] = toSplit->childs[0]; + for (int i=1; ichilds[i]; + } + } + + varianceValue = meanVariance/root->size; + return clusterCount; + } + +private: + /** The branching factor used in the hierarchical k-means clustering */ + int branching_; + + /** Maximum number of iterations to use when performing k-means clustering */ + int iterations_; + + /** Algorithm for choosing the cluster centers */ + flann_centers_init_t centers_init_; + + /** + * Cluster border index. This is used in the tree search phase when determining + * the closest cluster to explore next. A zero value takes into account only + * the cluster centres, a value greater then zero also take into account the size + * of the cluster. + */ + float cb_index_; + + /** + * The dataset used by this index + */ + const Matrix dataset_; + + /** Index parameters */ + IndexParams index_params_; + + /** + * Number of features in the dataset. + */ + size_t size_; + + /** + * Length of each feature. + */ + size_t veclen_; + + /** + * The root node in the tree. + */ + KMeansNodePtr root_; + + /** + * Array of indices to vectors in the dataset. + */ + int* indices_; + + /** + * The distance + */ + Distance distance_; + + /** + * Pooled memory allocator. + */ + PooledAllocator pool_; + + /** + * Memory occupied by the index. + */ + int memoryCounter_; +}; + +} + +#endif //OPENCV_FLANN_KMEANS_INDEX_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/linear_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/linear_index.h new file mode 100755 index 0000000..ca3f44d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/linear_index.h @@ -0,0 +1,132 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_LINEAR_INDEX_H_ +#define OPENCV_FLANN_LINEAR_INDEX_H_ + +#include "general.h" +#include "nn_index.h" + +namespace cvflann +{ + +struct LinearIndexParams : public IndexParams +{ + LinearIndexParams() + { + (* this)["algorithm"] = FLANN_INDEX_LINEAR; + } +}; + +template +class LinearIndex : public NNIndex +{ +public: + + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + + LinearIndex(const Matrix& inputData, const IndexParams& params = LinearIndexParams(), + Distance d = Distance()) : + dataset_(inputData), index_params_(params), distance_(d) + { + } + + LinearIndex(const LinearIndex&); + LinearIndex& operator=(const LinearIndex&); + + flann_algorithm_t getType() const CV_OVERRIDE + { + return FLANN_INDEX_LINEAR; + } + + + size_t size() const CV_OVERRIDE + { + return dataset_.rows; + } + + size_t veclen() const CV_OVERRIDE + { + return dataset_.cols; + } + + + int usedMemory() const CV_OVERRIDE + { + return 0; + } + + void buildIndex() CV_OVERRIDE + { + /* nothing to do here for linear search */ + } + + void saveIndex(FILE*) CV_OVERRIDE + { + /* nothing to do here for linear search */ + } + + + void loadIndex(FILE*) CV_OVERRIDE + { + /* nothing to do here for linear search */ + + index_params_["algorithm"] = getType(); + } + + void findNeighbors(ResultSet& resultSet, const ElementType* vec, const SearchParams& /*searchParams*/) CV_OVERRIDE + { + ElementType* data = dataset_.data; + for (size_t i = 0; i < dataset_.rows; ++i, data += dataset_.cols) { + DistanceType dist = distance_(data, vec, dataset_.cols); + resultSet.addPoint(dist, (int)i); + } + } + + IndexParams getParameters() const CV_OVERRIDE + { + return index_params_; + } + +private: + /** The dataset */ + const Matrix dataset_; + /** Index parameters */ + IndexParams index_params_; + /** Index distance */ + Distance distance_; + +}; + +} + +#endif // OPENCV_FLANN_LINEAR_INDEX_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/logger.h b/Prj-Win/3rd/opencv/include/opencv2/flann/logger.h new file mode 100755 index 0000000..32618db --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/logger.h @@ -0,0 +1,135 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_LOGGER_H +#define OPENCV_FLANN_LOGGER_H + +#include +#include + +#include "defines.h" + + +namespace cvflann +{ + +class Logger +{ + Logger() : stream(stdout), logLevel(FLANN_LOG_WARN) {} + + ~Logger() + { + if ((stream!=NULL)&&(stream!=stdout)) { + fclose(stream); + } + } + + static Logger& instance() + { + static Logger logger; + return logger; + } + + void _setDestination(const char* name) + { + if (name==NULL) { + stream = stdout; + } + else { +#ifdef _MSC_VER + if (fopen_s(&stream, name, "w") != 0) + stream = NULL; +#else + stream = fopen(name,"w"); +#endif + if (stream == NULL) { + stream = stdout; + } + } + } + + int _log(int level, const char* fmt, va_list arglist) + { + if (level > logLevel ) return -1; + int ret = vfprintf(stream, fmt, arglist); + return ret; + } + +public: + /** + * Sets the logging level. All messages with lower priority will be ignored. + * @param level Logging level + */ + static void setLevel(int level) { instance().logLevel = level; } + + /** + * Sets the logging destination + * @param name Filename or NULL for console + */ + static void setDestination(const char* name) { instance()._setDestination(name); } + + /** + * Print log message + * @param level Log level + * @param fmt Message format + * @return + */ + static int log(int level, const char* fmt, ...) + { + va_list arglist; + va_start(arglist, fmt); + int ret = instance()._log(level,fmt,arglist); + va_end(arglist); + return ret; + } + +#define LOG_METHOD(NAME,LEVEL) \ + static int NAME(const char* fmt, ...) \ + { \ + va_list ap; \ + va_start(ap, fmt); \ + int ret = instance()._log(LEVEL, fmt, ap); \ + va_end(ap); \ + return ret; \ + } + + LOG_METHOD(fatal, FLANN_LOG_FATAL) + LOG_METHOD(error, FLANN_LOG_ERROR) + LOG_METHOD(warn, FLANN_LOG_WARN) + LOG_METHOD(info, FLANN_LOG_INFO) + +private: + FILE* stream; + int logLevel; +}; + +} + +#endif //OPENCV_FLANN_LOGGER_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/lsh_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/lsh_index.h new file mode 100755 index 0000000..42afe89 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/lsh_index.h @@ -0,0 +1,392 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +/*********************************************************************** + * Author: Vincent Rabaud + *************************************************************************/ + +#ifndef OPENCV_FLANN_LSH_INDEX_H_ +#define OPENCV_FLANN_LSH_INDEX_H_ + +#include +#include +#include +#include +#include + +#include "general.h" +#include "nn_index.h" +#include "matrix.h" +#include "result_set.h" +#include "heap.h" +#include "lsh_table.h" +#include "allocator.h" +#include "random.h" +#include "saving.h" + +namespace cvflann +{ + +struct LshIndexParams : public IndexParams +{ + LshIndexParams(unsigned int table_number = 12, unsigned int key_size = 20, unsigned int multi_probe_level = 2) + { + (* this)["algorithm"] = FLANN_INDEX_LSH; + // The number of hash tables to use + (*this)["table_number"] = table_number; + // The length of the key in the hash tables + (*this)["key_size"] = key_size; + // Number of levels to use in multi-probe (0 for standard LSH) + (*this)["multi_probe_level"] = multi_probe_level; + } +}; + +/** + * Randomized kd-tree index + * + * Contains the k-d trees and other information for indexing a set of points + * for nearest-neighbor matching. + */ +template +class LshIndex : public NNIndex +{ +public: + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + + /** Constructor + * @param input_data dataset with the input features + * @param params parameters passed to the LSH algorithm + * @param d the distance used + */ + LshIndex(const Matrix& input_data, const IndexParams& params = LshIndexParams(), + Distance d = Distance()) : + dataset_(input_data), index_params_(params), distance_(d) + { + // cv::flann::IndexParams sets integer params as 'int', so it is used with get_param + // in place of 'unsigned int' + table_number_ = (unsigned int)get_param(index_params_,"table_number",12); + key_size_ = (unsigned int)get_param(index_params_,"key_size",20); + multi_probe_level_ = (unsigned int)get_param(index_params_,"multi_probe_level",2); + + feature_size_ = (unsigned)dataset_.cols; + fill_xor_mask(0, key_size_, multi_probe_level_, xor_masks_); + } + + + LshIndex(const LshIndex&); + LshIndex& operator=(const LshIndex&); + + /** + * Builds the index + */ + void buildIndex() CV_OVERRIDE + { + tables_.resize(table_number_); + for (unsigned int i = 0; i < table_number_; ++i) { + lsh::LshTable& table = tables_[i]; + table = lsh::LshTable(feature_size_, key_size_); + + // Add the features to the table + table.add(dataset_); + } + } + + flann_algorithm_t getType() const CV_OVERRIDE + { + return FLANN_INDEX_LSH; + } + + + void saveIndex(FILE* stream) CV_OVERRIDE + { + save_value(stream,table_number_); + save_value(stream,key_size_); + save_value(stream,multi_probe_level_); + save_value(stream, dataset_); + } + + void loadIndex(FILE* stream) CV_OVERRIDE + { + load_value(stream, table_number_); + load_value(stream, key_size_); + load_value(stream, multi_probe_level_); + load_value(stream, dataset_); + // Building the index is so fast we can afford not storing it + buildIndex(); + + index_params_["algorithm"] = getType(); + index_params_["table_number"] = table_number_; + index_params_["key_size"] = key_size_; + index_params_["multi_probe_level"] = multi_probe_level_; + } + + /** + * Returns size of index. + */ + size_t size() const CV_OVERRIDE + { + return dataset_.rows; + } + + /** + * Returns the length of an index feature. + */ + size_t veclen() const CV_OVERRIDE + { + return feature_size_; + } + + /** + * Computes the index memory usage + * Returns: memory used by the index + */ + int usedMemory() const CV_OVERRIDE + { + return (int)(dataset_.rows * sizeof(int)); + } + + + IndexParams getParameters() const CV_OVERRIDE + { + return index_params_; + } + + /** + * \brief Perform k-nearest neighbor search + * \param[in] queries The query points for which to find the nearest neighbors + * \param[out] indices The indices of the nearest neighbors found + * \param[out] dists Distances to the nearest neighbors found + * \param[in] knn Number of nearest neighbors to return + * \param[in] params Search parameters + */ + virtual void knnSearch(const Matrix& queries, Matrix& indices, Matrix& dists, int knn, const SearchParams& params) CV_OVERRIDE + { + assert(queries.cols == veclen()); + assert(indices.rows >= queries.rows); + assert(dists.rows >= queries.rows); + assert(int(indices.cols) >= knn); + assert(int(dists.cols) >= knn); + + + KNNUniqueResultSet resultSet(knn); + for (size_t i = 0; i < queries.rows; i++) { + resultSet.clear(); + std::fill_n(indices[i], knn, -1); + std::fill_n(dists[i], knn, std::numeric_limits::max()); + findNeighbors(resultSet, queries[i], params); + if (get_param(params,"sorted",true)) resultSet.sortAndCopy(indices[i], dists[i], knn); + else resultSet.copy(indices[i], dists[i], knn); + } + } + + + /** + * Find set of nearest neighbors to vec. Their indices are stored inside + * the result object. + * + * Params: + * result = the result object in which the indices of the nearest-neighbors are stored + * vec = the vector for which to search the nearest neighbors + * maxCheck = the maximum number of restarts (in a best-bin-first manner) + */ + void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& /*searchParams*/) CV_OVERRIDE + { + getNeighbors(vec, result); + } + +private: + /** Defines the comparator on score and index + */ + typedef std::pair ScoreIndexPair; + struct SortScoreIndexPairOnSecond + { + bool operator()(const ScoreIndexPair& left, const ScoreIndexPair& right) const + { + return left.second < right.second; + } + }; + + /** Fills the different xor masks to use when getting the neighbors in multi-probe LSH + * @param key the key we build neighbors from + * @param lowest_index the lowest index of the bit set + * @param level the multi-probe level we are at + * @param xor_masks all the xor mask + */ + void fill_xor_mask(lsh::BucketKey key, int lowest_index, unsigned int level, + std::vector& xor_masks) + { + xor_masks.push_back(key); + if (level == 0) return; + for (int index = lowest_index - 1; index >= 0; --index) { + // Create a new key + lsh::BucketKey new_key = key | (1 << index); + fill_xor_mask(new_key, index, level - 1, xor_masks); + } + } + + /** Performs the approximate nearest-neighbor search. + * @param vec the feature to analyze + * @param do_radius flag indicating if we check the radius too + * @param radius the radius if it is a radius search + * @param do_k flag indicating if we limit the number of nn + * @param k_nn the number of nearest neighbors + * @param checked_average used for debugging + */ + void getNeighbors(const ElementType* vec, bool /*do_radius*/, float radius, bool do_k, unsigned int k_nn, + float& /*checked_average*/) + { + static std::vector score_index_heap; + + if (do_k) { + unsigned int worst_score = std::numeric_limits::max(); + typename std::vector >::const_iterator table = tables_.begin(); + typename std::vector >::const_iterator table_end = tables_.end(); + for (; table != table_end; ++table) { + size_t key = table->getKey(vec); + std::vector::const_iterator xor_mask = xor_masks_.begin(); + std::vector::const_iterator xor_mask_end = xor_masks_.end(); + for (; xor_mask != xor_mask_end; ++xor_mask) { + size_t sub_key = key ^ (*xor_mask); + const lsh::Bucket* bucket = table->getBucketFromKey(sub_key); + if (bucket == 0) continue; + + // Go over each descriptor index + std::vector::const_iterator training_index = bucket->begin(); + std::vector::const_iterator last_training_index = bucket->end(); + DistanceType hamming_distance; + + // Process the rest of the candidates + for (; training_index < last_training_index; ++training_index) { + hamming_distance = distance_(vec, dataset_[*training_index], dataset_.cols); + + if (hamming_distance < worst_score) { + // Insert the new element + score_index_heap.push_back(ScoreIndexPair(hamming_distance, training_index)); + std::push_heap(score_index_heap.begin(), score_index_heap.end()); + + if (score_index_heap.size() > (unsigned int)k_nn) { + // Remove the highest distance value as we have too many elements + std::pop_heap(score_index_heap.begin(), score_index_heap.end()); + score_index_heap.pop_back(); + // Keep track of the worst score + worst_score = score_index_heap.front().first; + } + } + } + } + } + } + else { + typename std::vector >::const_iterator table = tables_.begin(); + typename std::vector >::const_iterator table_end = tables_.end(); + for (; table != table_end; ++table) { + size_t key = table->getKey(vec); + std::vector::const_iterator xor_mask = xor_masks_.begin(); + std::vector::const_iterator xor_mask_end = xor_masks_.end(); + for (; xor_mask != xor_mask_end; ++xor_mask) { + size_t sub_key = key ^ (*xor_mask); + const lsh::Bucket* bucket = table->getBucketFromKey(sub_key); + if (bucket == 0) continue; + + // Go over each descriptor index + std::vector::const_iterator training_index = bucket->begin(); + std::vector::const_iterator last_training_index = bucket->end(); + DistanceType hamming_distance; + + // Process the rest of the candidates + for (; training_index < last_training_index; ++training_index) { + // Compute the Hamming distance + hamming_distance = distance_(vec, dataset_[*training_index], dataset_.cols); + if (hamming_distance < radius) score_index_heap.push_back(ScoreIndexPair(hamming_distance, training_index)); + } + } + } + } + } + + /** Performs the approximate nearest-neighbor search. + * This is a slower version than the above as it uses the ResultSet + * @param vec the feature to analyze + */ + void getNeighbors(const ElementType* vec, ResultSet& result) + { + typename std::vector >::const_iterator table = tables_.begin(); + typename std::vector >::const_iterator table_end = tables_.end(); + for (; table != table_end; ++table) { + size_t key = table->getKey(vec); + std::vector::const_iterator xor_mask = xor_masks_.begin(); + std::vector::const_iterator xor_mask_end = xor_masks_.end(); + for (; xor_mask != xor_mask_end; ++xor_mask) { + size_t sub_key = key ^ (*xor_mask); + const lsh::Bucket* bucket = table->getBucketFromKey((lsh::BucketKey)sub_key); + if (bucket == 0) continue; + + // Go over each descriptor index + std::vector::const_iterator training_index = bucket->begin(); + std::vector::const_iterator last_training_index = bucket->end(); + DistanceType hamming_distance; + + // Process the rest of the candidates + for (; training_index < last_training_index; ++training_index) { + // Compute the Hamming distance + hamming_distance = distance_(vec, dataset_[*training_index], (int)dataset_.cols); + result.addPoint(hamming_distance, *training_index); + } + } + } + } + + /** The different hash tables */ + std::vector > tables_; + + /** The data the LSH tables where built from */ + Matrix dataset_; + + /** The size of the features (as ElementType[]) */ + unsigned int feature_size_; + + IndexParams index_params_; + + /** table number */ + unsigned int table_number_; + /** key size */ + unsigned int key_size_; + /** How far should we look for neighbors in multi-probe LSH */ + unsigned int multi_probe_level_; + + /** The XOR masks to apply to a key to get the neighboring buckets */ + std::vector xor_masks_; + + Distance distance_; +}; +} + +#endif //OPENCV_FLANN_LSH_INDEX_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/lsh_table.h b/Prj-Win/3rd/opencv/include/opencv2/flann/lsh_table.h new file mode 100755 index 0000000..b07a9d5 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/lsh_table.h @@ -0,0 +1,513 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +/*********************************************************************** + * Author: Vincent Rabaud + *************************************************************************/ + +#ifndef OPENCV_FLANN_LSH_TABLE_H_ +#define OPENCV_FLANN_LSH_TABLE_H_ + +#include +#include +#include +#include +// TODO as soon as we use C++0x, use the code in USE_UNORDERED_MAP +#ifdef __GXX_EXPERIMENTAL_CXX0X__ +# define USE_UNORDERED_MAP 1 +#else +# define USE_UNORDERED_MAP 0 +#endif +#if USE_UNORDERED_MAP +#include +#else +#include +#endif +#include +#include + +#include "dynamic_bitset.h" +#include "matrix.h" + +namespace cvflann +{ + +namespace lsh +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** What is stored in an LSH bucket + */ +typedef uint32_t FeatureIndex; +/** The id from which we can get a bucket back in an LSH table + */ +typedef unsigned int BucketKey; + +/** A bucket in an LSH table + */ +typedef std::vector Bucket; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** POD for stats about an LSH table + */ +struct LshStats +{ + std::vector bucket_sizes_; + size_t n_buckets_; + size_t bucket_size_mean_; + size_t bucket_size_median_; + size_t bucket_size_min_; + size_t bucket_size_max_; + size_t bucket_size_std_dev; + /** Each contained vector contains three value: beginning/end for interval, number of elements in the bin + */ + std::vector > size_histogram_; +}; + +/** Overload the << operator for LshStats + * @param out the streams + * @param stats the stats to display + * @return the streams + */ +inline std::ostream& operator <<(std::ostream& out, const LshStats& stats) +{ + int w = 20; + out << "Lsh Table Stats:\n" << std::setw(w) << std::setiosflags(std::ios::right) << "N buckets : " + << stats.n_buckets_ << "\n" << std::setw(w) << std::setiosflags(std::ios::right) << "mean size : " + << std::setiosflags(std::ios::left) << stats.bucket_size_mean_ << "\n" << std::setw(w) + << std::setiosflags(std::ios::right) << "median size : " << stats.bucket_size_median_ << "\n" << std::setw(w) + << std::setiosflags(std::ios::right) << "min size : " << std::setiosflags(std::ios::left) + << stats.bucket_size_min_ << "\n" << std::setw(w) << std::setiosflags(std::ios::right) << "max size : " + << std::setiosflags(std::ios::left) << stats.bucket_size_max_; + + // Display the histogram + out << std::endl << std::setw(w) << std::setiosflags(std::ios::right) << "histogram : " + << std::setiosflags(std::ios::left); + for (std::vector >::const_iterator iterator = stats.size_histogram_.begin(), end = + stats.size_histogram_.end(); iterator != end; ++iterator) out << (*iterator)[0] << "-" << (*iterator)[1] << ": " << (*iterator)[2] << ", "; + + return out; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** Lsh hash table. As its key is a sub-feature, and as usually + * the size of it is pretty small, we keep it as a continuous memory array. + * The value is an index in the corpus of features (we keep it as an unsigned + * int for pure memory reasons, it could be a size_t) + */ +template +class LshTable +{ +public: + /** A container of all the feature indices. Optimized for space + */ +#if USE_UNORDERED_MAP + typedef std::unordered_map BucketsSpace; +#else + typedef std::map BucketsSpace; +#endif + + /** A container of all the feature indices. Optimized for speed + */ + typedef std::vector BucketsSpeed; + + /** Default constructor + */ + LshTable() + { + key_size_ = 0; + feature_size_ = 0; + speed_level_ = kArray; + } + + /** Default constructor + * Create the mask and allocate the memory + * @param feature_size is the size of the feature (considered as a ElementType[]) + * @param key_size is the number of bits that are turned on in the feature + */ + LshTable(unsigned int feature_size, unsigned int key_size) + { + feature_size_ = feature_size; + CV_UNUSED(key_size); + std::cerr << "LSH is not implemented for that type" << std::endl; + assert(0); + } + + /** Add a feature to the table + * @param value the value to store for that feature + * @param feature the feature itself + */ + void add(unsigned int value, const ElementType* feature) + { + // Add the value to the corresponding bucket + BucketKey key = (lsh::BucketKey)getKey(feature); + + switch (speed_level_) { + case kArray: + // That means we get the buckets from an array + buckets_speed_[key].push_back(value); + break; + case kBitsetHash: + // That means we can check the bitset for the presence of a key + key_bitset_.set(key); + buckets_space_[key].push_back(value); + break; + case kHash: + { + // That means we have to check for the hash table for the presence of a key + buckets_space_[key].push_back(value); + break; + } + } + } + + /** Add a set of features to the table + * @param dataset the values to store + */ + void add(Matrix dataset) + { +#if USE_UNORDERED_MAP + buckets_space_.rehash((buckets_space_.size() + dataset.rows) * 1.2); +#endif + // Add the features to the table + for (unsigned int i = 0; i < dataset.rows; ++i) add(i, dataset[i]); + // Now that the table is full, optimize it for speed/space + optimize(); + } + + /** Get a bucket given the key + * @param key + * @return + */ + inline const Bucket* getBucketFromKey(BucketKey key) const + { + // Generate other buckets + switch (speed_level_) { + case kArray: + // That means we get the buckets from an array + return &buckets_speed_[key]; + break; + case kBitsetHash: + // That means we can check the bitset for the presence of a key + if (key_bitset_.test(key)) return &buckets_space_.find(key)->second; + else return 0; + break; + case kHash: + { + // That means we have to check for the hash table for the presence of a key + BucketsSpace::const_iterator bucket_it, bucket_end = buckets_space_.end(); + bucket_it = buckets_space_.find(key); + // Stop here if that bucket does not exist + if (bucket_it == bucket_end) return 0; + else return &bucket_it->second; + break; + } + } + return 0; + } + + /** Compute the sub-signature of a feature + */ + size_t getKey(const ElementType* /*feature*/) const + { + std::cerr << "LSH is not implemented for that type" << std::endl; + assert(0); + return 1; + } + + /** Get statistics about the table + * @return + */ + LshStats getStats() const; + +private: + /** defines the speed fo the implementation + * kArray uses a vector for storing data + * kBitsetHash uses a hash map but checks for the validity of a key with a bitset + * kHash uses a hash map only + */ + enum SpeedLevel + { + kArray, kBitsetHash, kHash + }; + + /** Initialize some variables + */ + void initialize(size_t key_size) + { + const size_t key_size_lower_bound = 1; + //a value (size_t(1) << key_size) must fit the size_t type so key_size has to be strictly less than size of size_t + const size_t key_size_upper_bound = (std::min)(sizeof(BucketKey) * CHAR_BIT + 1, sizeof(size_t) * CHAR_BIT); + if (key_size < key_size_lower_bound || key_size >= key_size_upper_bound) + { + CV_Error(cv::Error::StsBadArg, cv::format("Invalid key_size (=%d). Valid values for your system are %d <= key_size < %d.", (int)key_size, (int)key_size_lower_bound, (int)key_size_upper_bound)); + } + + speed_level_ = kHash; + key_size_ = (unsigned)key_size; + } + + /** Optimize the table for speed/space + */ + void optimize() + { + // If we are already using the fast storage, no need to do anything + if (speed_level_ == kArray) return; + + // Use an array if it will be more than half full + if (buckets_space_.size() > ((size_t(1) << key_size_) / 2)) { + speed_level_ = kArray; + // Fill the array version of it + buckets_speed_.resize(size_t(1) << key_size_); + for (BucketsSpace::const_iterator key_bucket = buckets_space_.begin(); key_bucket != buckets_space_.end(); ++key_bucket) buckets_speed_[key_bucket->first] = key_bucket->second; + + // Empty the hash table + buckets_space_.clear(); + return; + } + + // If the bitset is going to use less than 10% of the RAM of the hash map (at least 1 size_t for the key and two + // for the vector) or less than 512MB (key_size_ <= 30) + if (((std::max(buckets_space_.size(), buckets_speed_.size()) * CHAR_BIT * 3 * sizeof(BucketKey)) / 10 + >= (size_t(1) << key_size_)) || (key_size_ <= 32)) { + speed_level_ = kBitsetHash; + key_bitset_.resize(size_t(1) << key_size_); + key_bitset_.reset(); + // Try with the BucketsSpace + for (BucketsSpace::const_iterator key_bucket = buckets_space_.begin(); key_bucket != buckets_space_.end(); ++key_bucket) key_bitset_.set(key_bucket->first); + } + else { + speed_level_ = kHash; + key_bitset_.clear(); + } + } + + /** The vector of all the buckets if they are held for speed + */ + BucketsSpeed buckets_speed_; + + /** The hash table of all the buckets in case we cannot use the speed version + */ + BucketsSpace buckets_space_; + + /** What is used to store the data */ + SpeedLevel speed_level_; + + /** If the subkey is small enough, it will keep track of which subkeys are set through that bitset + * That is just a speedup so that we don't look in the hash table (which can be mush slower that checking a bitset) + */ + DynamicBitset key_bitset_; + + /** The size of the sub-signature in bits + */ + unsigned int key_size_; + + unsigned int feature_size_; + + // Members only used for the unsigned char specialization + /** The mask to apply to a feature to get the hash key + * Only used in the unsigned char case + */ + std::vector mask_; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Specialization for unsigned char + +template<> +inline LshTable::LshTable(unsigned int feature_size, unsigned int subsignature_size) +{ + feature_size_ = feature_size; + initialize(subsignature_size); + // Allocate the mask + mask_ = std::vector((feature_size * sizeof(char) + sizeof(size_t) - 1) / sizeof(size_t), 0); + + // A bit brutal but fast to code + std::vector indices(feature_size * CHAR_BIT); + for (size_t i = 0; i < feature_size * CHAR_BIT; ++i) indices[i] = (int)i; +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::randShuffle(indices); +#else + std::random_shuffle(indices.begin(), indices.end()); +#endif + + // Generate a random set of order of subsignature_size_ bits + for (unsigned int i = 0; i < key_size_; ++i) { + size_t index = indices[i]; + + // Set that bit in the mask + size_t divisor = CHAR_BIT * sizeof(size_t); + size_t idx = index / divisor; //pick the right size_t index + mask_[idx] |= size_t(1) << (index % divisor); //use modulo to find the bit offset + } + + // Set to 1 if you want to display the mask for debug +#if 0 + { + size_t bcount = 0; + BOOST_FOREACH(size_t mask_block, mask_){ + out << std::setw(sizeof(size_t) * CHAR_BIT / 4) << std::setfill('0') << std::hex << mask_block + << std::endl; + bcount += __builtin_popcountll(mask_block); + } + out << "bit count : " << std::dec << bcount << std::endl; + out << "mask size : " << mask_.size() << std::endl; + return out; + } +#endif +} + +/** Return the Subsignature of a feature + * @param feature the feature to analyze + */ +template<> +inline size_t LshTable::getKey(const unsigned char* feature) const +{ + // no need to check if T is dividable by sizeof(size_t) like in the Hamming + // distance computation as we have a mask + // FIXIT: This is bad assumption, because we reading tail bytes after of the allocated features buffer + const size_t* feature_block_ptr = reinterpret_cast ((const void*)feature); + + // Figure out the subsignature of the feature + // Given the feature ABCDEF, and the mask 001011, the output will be + // 000CEF + size_t subsignature = 0; + size_t bit_index = 1; + + for (unsigned i = 0; i < feature_size_; i += sizeof(size_t)) { + // get the mask and signature blocks + size_t feature_block; + if (i <= feature_size_ - sizeof(size_t)) + { + feature_block = *feature_block_ptr; + } + else + { + size_t tmp = 0; + memcpy(&tmp, feature_block_ptr, feature_size_ - i); // preserve bytes order + feature_block = tmp; + } + size_t mask_block = mask_[i / sizeof(size_t)]; + while (mask_block) { + // Get the lowest set bit in the mask block + size_t lowest_bit = mask_block & (-(ptrdiff_t)mask_block); + // Add it to the current subsignature if necessary + subsignature += (feature_block & lowest_bit) ? bit_index : 0; + // Reset the bit in the mask block + mask_block ^= lowest_bit; + // increment the bit index for the subsignature + bit_index <<= 1; + } + // Check the next feature block + ++feature_block_ptr; + } + return subsignature; +} + +template<> +inline LshStats LshTable::getStats() const +{ + LshStats stats; + stats.bucket_size_mean_ = 0; + if ((buckets_speed_.empty()) && (buckets_space_.empty())) { + stats.n_buckets_ = 0; + stats.bucket_size_median_ = 0; + stats.bucket_size_min_ = 0; + stats.bucket_size_max_ = 0; + return stats; + } + + if (!buckets_speed_.empty()) { + for (BucketsSpeed::const_iterator pbucket = buckets_speed_.begin(); pbucket != buckets_speed_.end(); ++pbucket) { + stats.bucket_sizes_.push_back((lsh::FeatureIndex)pbucket->size()); + stats.bucket_size_mean_ += pbucket->size(); + } + stats.bucket_size_mean_ /= buckets_speed_.size(); + stats.n_buckets_ = buckets_speed_.size(); + } + else { + for (BucketsSpace::const_iterator x = buckets_space_.begin(); x != buckets_space_.end(); ++x) { + stats.bucket_sizes_.push_back((lsh::FeatureIndex)x->second.size()); + stats.bucket_size_mean_ += x->second.size(); + } + stats.bucket_size_mean_ /= buckets_space_.size(); + stats.n_buckets_ = buckets_space_.size(); + } + + std::sort(stats.bucket_sizes_.begin(), stats.bucket_sizes_.end()); + + // BOOST_FOREACH(int size, stats.bucket_sizes_) + // std::cout << size << " "; + // std::cout << std::endl; + stats.bucket_size_median_ = stats.bucket_sizes_[stats.bucket_sizes_.size() / 2]; + stats.bucket_size_min_ = stats.bucket_sizes_.front(); + stats.bucket_size_max_ = stats.bucket_sizes_.back(); + + // TODO compute mean and std + /*float mean, stddev; + stats.bucket_size_mean_ = mean; + stats.bucket_size_std_dev = stddev;*/ + + // Include a histogram of the buckets + unsigned int bin_start = 0; + unsigned int bin_end = 20; + bool is_new_bin = true; + for (std::vector::iterator iterator = stats.bucket_sizes_.begin(), end = stats.bucket_sizes_.end(); iterator + != end; ) + if (*iterator < bin_end) { + if (is_new_bin) { + stats.size_histogram_.push_back(std::vector(3, 0)); + stats.size_histogram_.back()[0] = bin_start; + stats.size_histogram_.back()[1] = bin_end - 1; + is_new_bin = false; + } + ++stats.size_histogram_.back()[2]; + ++iterator; + } + else { + bin_start += 20; + bin_end += 20; + is_new_bin = true; + } + + return stats; +} + +// End the two namespaces +} +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif /* OPENCV_FLANN_LSH_TABLE_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/matrix.h b/Prj-Win/3rd/opencv/include/opencv2/flann/matrix.h new file mode 100755 index 0000000..f6092d1 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/matrix.h @@ -0,0 +1,116 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_DATASET_H_ +#define OPENCV_FLANN_DATASET_H_ + +#include + +#include "general.h" + +namespace cvflann +{ + +/** + * Class that implements a simple rectangular matrix stored in a memory buffer and + * provides convenient matrix-like access using the [] operators. + */ +template +class Matrix +{ +public: + typedef T type; + + size_t rows; + size_t cols; + size_t stride; + T* data; + + Matrix() : rows(0), cols(0), stride(0), data(NULL) + { + } + + Matrix(T* data_, size_t rows_, size_t cols_, size_t stride_ = 0) : + rows(rows_), cols(cols_), stride(stride_), data(data_) + { + if (stride==0) stride = cols; + } + + /** + * Convenience function for deallocating the storage data. + */ + CV_DEPRECATED void free() + { + fprintf(stderr, "The cvflann::Matrix::free() method is deprecated " + "and it does not do any memory deallocation any more. You are" + "responsible for deallocating the matrix memory (by doing" + "'delete[] matrix.data' for example)"); + } + + /** + * Operator that return a (pointer to a) row of the data. + */ + T* operator[](size_t index) const + { + return data+index*stride; + } +}; + + +class UntypedMatrix +{ +public: + size_t rows; + size_t cols; + void* data; + flann_datatype_t type; + + UntypedMatrix(void* data_, long rows_, long cols_) : + rows(rows_), cols(cols_), data(data_) + { + } + + ~UntypedMatrix() + { + } + + + template + Matrix as() + { + return Matrix((T*)data, rows, cols); + } +}; + + + +} + +#endif //OPENCV_FLANN_DATASET_H_ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/miniflann.hpp b/Prj-Win/3rd/opencv/include/opencv2/flann/miniflann.hpp new file mode 100755 index 0000000..2590ad7 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/miniflann.hpp @@ -0,0 +1,177 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_MINIFLANN_HPP +#define OPENCV_MINIFLANN_HPP + +#include "opencv2/core.hpp" +#include "opencv2/flann/defines.h" + +namespace cv +{ + +namespace flann +{ + +enum FlannIndexType { + FLANN_INDEX_TYPE_8U = CV_8U, + FLANN_INDEX_TYPE_8S = CV_8S, + FLANN_INDEX_TYPE_16U = CV_16U, + FLANN_INDEX_TYPE_16S = CV_16S, + FLANN_INDEX_TYPE_32S = CV_32S, + FLANN_INDEX_TYPE_32F = CV_32F, + FLANN_INDEX_TYPE_64F = CV_64F, + FLANN_INDEX_TYPE_STRING, + FLANN_INDEX_TYPE_BOOL, + FLANN_INDEX_TYPE_ALGORITHM, + LAST_VALUE_FLANN_INDEX_TYPE = FLANN_INDEX_TYPE_ALGORITHM +}; + +struct CV_EXPORTS IndexParams +{ + IndexParams(); + ~IndexParams(); + + String getString(const String& key, const String& defaultVal=String()) const; + int getInt(const String& key, int defaultVal=-1) const; + double getDouble(const String& key, double defaultVal=-1) const; + + void setString(const String& key, const String& value); + void setInt(const String& key, int value); + void setDouble(const String& key, double value); + void setFloat(const String& key, float value); + void setBool(const String& key, bool value); + void setAlgorithm(int value); + + // FIXIT: replace by void write(FileStorage& fs) const + read() + void getAll(std::vector& names, + std::vector& types, + std::vector& strValues, + std::vector& numValues) const; + + void* params; + +private: + IndexParams(const IndexParams &); // copy disabled + IndexParams& operator=(const IndexParams &); // assign disabled +}; + +struct CV_EXPORTS KDTreeIndexParams : public IndexParams +{ + KDTreeIndexParams(int trees=4); +}; + +struct CV_EXPORTS LinearIndexParams : public IndexParams +{ + LinearIndexParams(); +}; + +struct CV_EXPORTS CompositeIndexParams : public IndexParams +{ + CompositeIndexParams(int trees = 4, int branching = 32, int iterations = 11, + cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2f ); +}; + +struct CV_EXPORTS AutotunedIndexParams : public IndexParams +{ + AutotunedIndexParams(float target_precision = 0.8f, float build_weight = 0.01f, + float memory_weight = 0, float sample_fraction = 0.1f); +}; + +struct CV_EXPORTS HierarchicalClusteringIndexParams : public IndexParams +{ + HierarchicalClusteringIndexParams(int branching = 32, + cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, int trees = 4, int leaf_size = 100 ); +}; + +struct CV_EXPORTS KMeansIndexParams : public IndexParams +{ + KMeansIndexParams(int branching = 32, int iterations = 11, + cvflann::flann_centers_init_t centers_init = cvflann::FLANN_CENTERS_RANDOM, float cb_index = 0.2f ); +}; + +struct CV_EXPORTS LshIndexParams : public IndexParams +{ + LshIndexParams(int table_number, int key_size, int multi_probe_level); +}; + +struct CV_EXPORTS SavedIndexParams : public IndexParams +{ + SavedIndexParams(const String& filename); +}; + +struct CV_EXPORTS SearchParams : public IndexParams +{ + SearchParams( int checks = 32, float eps = 0, bool sorted = true ); +}; + +class CV_EXPORTS_W Index +{ +public: + CV_WRAP Index(); + CV_WRAP Index(InputArray features, const IndexParams& params, cvflann::flann_distance_t distType=cvflann::FLANN_DIST_L2); + virtual ~Index(); + + CV_WRAP virtual void build(InputArray features, const IndexParams& params, cvflann::flann_distance_t distType=cvflann::FLANN_DIST_L2); + CV_WRAP virtual void knnSearch(InputArray query, OutputArray indices, + OutputArray dists, int knn, const SearchParams& params=SearchParams()); + + CV_WRAP virtual int radiusSearch(InputArray query, OutputArray indices, + OutputArray dists, double radius, int maxResults, + const SearchParams& params=SearchParams()); + + CV_WRAP virtual void save(const String& filename) const; + CV_WRAP virtual bool load(InputArray features, const String& filename); + CV_WRAP virtual void release(); + CV_WRAP cvflann::flann_distance_t getDistance() const; + CV_WRAP cvflann::flann_algorithm_t getAlgorithm() const; + +protected: + cvflann::flann_distance_t distType; + cvflann::flann_algorithm_t algo; + int featureType; + void* index; +}; + +} } // namespace cv::flann + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/nn_index.h b/Prj-Win/3rd/opencv/include/opencv2/flann/nn_index.h new file mode 100755 index 0000000..381d4bc --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/nn_index.h @@ -0,0 +1,177 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_NNINDEX_H +#define OPENCV_FLANN_NNINDEX_H + +#include "general.h" +#include "matrix.h" +#include "result_set.h" +#include "params.h" + +namespace cvflann +{ + +/** + * Nearest-neighbour index base class + */ +template +class NNIndex +{ + typedef typename Distance::ElementType ElementType; + typedef typename Distance::ResultType DistanceType; + +public: + + virtual ~NNIndex() {} + + /** + * \brief Builds the index + */ + virtual void buildIndex() = 0; + + /** + * \brief Perform k-nearest neighbor search + * \param[in] queries The query points for which to find the nearest neighbors + * \param[out] indices The indices of the nearest neighbors found + * \param[out] dists Distances to the nearest neighbors found + * \param[in] knn Number of nearest neighbors to return + * \param[in] params Search parameters + */ + virtual void knnSearch(const Matrix& queries, Matrix& indices, Matrix& dists, int knn, const SearchParams& params) + { + assert(queries.cols == veclen()); + assert(indices.rows >= queries.rows); + assert(dists.rows >= queries.rows); + assert(int(indices.cols) >= knn); + assert(int(dists.cols) >= knn); + +#if 0 + KNNResultSet resultSet(knn); + for (size_t i = 0; i < queries.rows; i++) { + resultSet.init(indices[i], dists[i]); + findNeighbors(resultSet, queries[i], params); + } +#else + KNNUniqueResultSet resultSet(knn); + for (size_t i = 0; i < queries.rows; i++) { + resultSet.clear(); + findNeighbors(resultSet, queries[i], params); + if (get_param(params,"sorted",true)) resultSet.sortAndCopy(indices[i], dists[i], knn); + else resultSet.copy(indices[i], dists[i], knn); + } +#endif + } + + /** + * \brief Perform radius search + * \param[in] query The query point + * \param[out] indices The indinces of the neighbors found within the given radius + * \param[out] dists The distances to the nearest neighbors found + * \param[in] radius The radius used for search + * \param[in] params Search parameters + * \returns Number of neighbors found + */ + virtual int radiusSearch(const Matrix& query, Matrix& indices, Matrix& dists, float radius, const SearchParams& params) + { + if (query.rows != 1) { + fprintf(stderr, "I can only search one feature at a time for range search\n"); + return -1; + } + assert(query.cols == veclen()); + assert(indices.cols == dists.cols); + + int n = 0; + int* indices_ptr = NULL; + DistanceType* dists_ptr = NULL; + if (indices.cols > 0) { + n = (int)indices.cols; + indices_ptr = indices[0]; + dists_ptr = dists[0]; + } + + RadiusUniqueResultSet resultSet((DistanceType)radius); + resultSet.clear(); + findNeighbors(resultSet, query[0], params); + if (n>0) { + if (get_param(params,"sorted",true)) resultSet.sortAndCopy(indices_ptr, dists_ptr, n); + else resultSet.copy(indices_ptr, dists_ptr, n); + } + + return (int)resultSet.size(); + } + + /** + * \brief Saves the index to a stream + * \param stream The stream to save the index to + */ + virtual void saveIndex(FILE* stream) = 0; + + /** + * \brief Loads the index from a stream + * \param stream The stream from which the index is loaded + */ + virtual void loadIndex(FILE* stream) = 0; + + /** + * \returns number of features in this index. + */ + virtual size_t size() const = 0; + + /** + * \returns The dimensionality of the features in this index. + */ + virtual size_t veclen() const = 0; + + /** + * \returns The amount of memory (in bytes) used by the index. + */ + virtual int usedMemory() const = 0; + + /** + * \returns The index type (kdtree, kmeans,...) + */ + virtual flann_algorithm_t getType() const = 0; + + /** + * \returns The index parameters + */ + virtual IndexParams getParameters() const = 0; + + + /** + * \brief Method that searches for nearest-neighbours + */ + virtual void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) = 0; +}; + +} + +#endif //OPENCV_FLANN_NNINDEX_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/object_factory.h b/Prj-Win/3rd/opencv/include/opencv2/flann/object_factory.h new file mode 100755 index 0000000..7f971c5 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/object_factory.h @@ -0,0 +1,91 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_OBJECT_FACTORY_H_ +#define OPENCV_FLANN_OBJECT_FACTORY_H_ + +#include + +namespace cvflann +{ + +class CreatorNotFound +{ +}; + +template +class ObjectFactory +{ + typedef ObjectFactory ThisClass; + typedef std::map ObjectRegistry; + + // singleton class, private constructor + ObjectFactory() {} + +public: + + bool subscribe(UniqueIdType id, ObjectCreator creator) + { + if (object_registry.find(id) != object_registry.end()) return false; + + object_registry[id] = creator; + return true; + } + + bool unregister(UniqueIdType id) + { + return object_registry.erase(id) == 1; + } + + ObjectCreator create(UniqueIdType id) + { + typename ObjectRegistry::const_iterator iter = object_registry.find(id); + + if (iter == object_registry.end()) { + throw CreatorNotFound(); + } + + return iter->second; + } + + static ThisClass& instance() + { + static ThisClass the_factory; + return the_factory; + } +private: + ObjectRegistry object_registry; +}; + +} + +#endif /* OPENCV_FLANN_OBJECT_FACTORY_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/params.h b/Prj-Win/3rd/opencv/include/opencv2/flann/params.h new file mode 100755 index 0000000..95ef4cd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/params.h @@ -0,0 +1,99 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2011 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2011 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + + +#ifndef OPENCV_FLANN_PARAMS_H_ +#define OPENCV_FLANN_PARAMS_H_ + +#include "any.h" +#include "general.h" +#include +#include + + +namespace cvflann +{ + +typedef std::map IndexParams; + +struct SearchParams : public IndexParams +{ + SearchParams(int checks = 32, float eps = 0, bool sorted = true ) + { + // how many leafs to visit when searching for neighbours (-1 for unlimited) + (*this)["checks"] = checks; + // search for eps-approximate neighbours (default: 0) + (*this)["eps"] = eps; + // only for radius search, require neighbours sorted by distance (default: true) + (*this)["sorted"] = sorted; + } +}; + + +template +T get_param(const IndexParams& params, cv::String name, const T& default_value) +{ + IndexParams::const_iterator it = params.find(name); + if (it != params.end()) { + return it->second.cast(); + } + else { + return default_value; + } +} + +template +T get_param(const IndexParams& params, cv::String name) +{ + IndexParams::const_iterator it = params.find(name); + if (it != params.end()) { + return it->second.cast(); + } + else { + throw FLANNException(cv::String("Missing parameter '")+name+cv::String("' in the parameters given")); + } +} + +inline void print_params(const IndexParams& params, std::ostream& stream) +{ + IndexParams::const_iterator it; + + for(it=params.begin(); it!=params.end(); ++it) { + stream << it->first << " : " << it->second << std::endl; + } +} + +inline void print_params(const IndexParams& params) +{ + print_params(params, std::cout); +} + +} + + +#endif /* OPENCV_FLANN_PARAMS_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/random.h b/Prj-Win/3rd/opencv/include/opencv2/flann/random.h new file mode 100755 index 0000000..d678474 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/random.h @@ -0,0 +1,155 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_RANDOM_H +#define OPENCV_FLANN_RANDOM_H + +#include +#include +#include + +#include "general.h" + +namespace cvflann +{ + +inline int rand() +{ +#ifndef OPENCV_FLANN_USE_STD_RAND +# if INT_MAX == RAND_MAX + int v = cv::theRNG().next() & INT_MAX; +# else + int v = cv::theRNG().uniform(0, RAND_MAX + 1); +# endif +#else + int v = std::rand(); +#endif // OPENCV_FLANN_USE_STD_RAND + return v; +} + +/** + * Seeds the random number generator + * @param seed Random seed + */ +inline void seed_random(unsigned int seed) +{ +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::theRNG() = cv::RNG(seed); +#else + std::srand(seed); +#endif +} + +/* + * Generates a random double value. + */ +/** + * Generates a random double value. + * @param high Upper limit + * @param low Lower limit + * @return Random double value + */ +inline double rand_double(double high = 1.0, double low = 0) +{ + return low + ((high-low) * (rand() / (RAND_MAX + 1.0))); +} + +/** + * Generates a random integer value. + * @param high Upper limit + * @param low Lower limit + * @return Random integer value + */ +inline int rand_int(int high = RAND_MAX, int low = 0) +{ + return low + (int) ( double(high-low) * (rand() / (RAND_MAX + 1.0))); +} + +/** + * Random number generator that returns a distinct number from + * the [0,n) interval each time. + */ +class UniqueRandom +{ + std::vector vals_; + int size_; + int counter_; + +public: + /** + * Constructor. + * @param n Size of the interval from which to generate + * @return + */ + UniqueRandom(int n) + { + init(n); + } + + /** + * Initializes the number generator. + * @param n the size of the interval from which to generate random numbers. + */ + void init(int n) + { + // create and initialize an array of size n + vals_.resize(n); + size_ = n; + for (int i = 0; i < size_; ++i) vals_[i] = i; + + // shuffle the elements in the array +#ifndef OPENCV_FLANN_USE_STD_RAND + cv::randShuffle(vals_); +#else + std::random_shuffle(vals_.begin(), vals_.end()); +#endif + + counter_ = 0; + } + + /** + * Return a distinct random integer in greater or equal to 0 and less + * than 'n' on each call. It should be called maximum 'n' times. + * Returns: a random integer + */ + int next() + { + if (counter_ == size_) { + return -1; + } + else { + return vals_[counter_++]; + } + } +}; + +} + +#endif //OPENCV_FLANN_RANDOM_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/result_set.h b/Prj-Win/3rd/opencv/include/opencv2/flann/result_set.h new file mode 100755 index 0000000..5c69ac2 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/result_set.h @@ -0,0 +1,543 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_RESULTSET_H +#define OPENCV_FLANN_RESULTSET_H + +#include +#include +#include +#include +#include +#include + +namespace cvflann +{ + +/* This record represents a branch point when finding neighbors in + the tree. It contains a record of the minimum distance to the query + point, as well as the node at which the search resumes. + */ + +template +struct BranchStruct +{ + T node; /* Tree node at which search resumes */ + DistanceType mindist; /* Minimum distance to query for all nodes below. */ + + BranchStruct() {} + BranchStruct(const T& aNode, DistanceType dist) : node(aNode), mindist(dist) {} + + bool operator<(const BranchStruct& rhs) const + { + return mindist +class ResultSet +{ +public: + virtual ~ResultSet() {} + + virtual bool full() const = 0; + + virtual void addPoint(DistanceType dist, int index) = 0; + + virtual DistanceType worstDist() const = 0; + +}; + +/** + * KNNSimpleResultSet does not ensure that the element it holds are unique. + * Is used in those cases where the nearest neighbour algorithm used does not + * attempt to insert the same element multiple times. + */ +template +class KNNSimpleResultSet : public ResultSet +{ + int* indices; + DistanceType* dists; + int capacity; + int count; + DistanceType worst_distance_; + +public: + KNNSimpleResultSet(int capacity_) : capacity(capacity_), count(0) + { + } + + void init(int* indices_, DistanceType* dists_) + { + indices = indices_; + dists = dists_; + count = 0; + worst_distance_ = (std::numeric_limits::max)(); + dists[capacity-1] = worst_distance_; + } + + size_t size() const + { + return count; + } + + bool full() const CV_OVERRIDE + { + return count == capacity; + } + + + void addPoint(DistanceType dist, int index) CV_OVERRIDE + { + if (dist >= worst_distance_) return; + int i; + for (i=count; i>0; --i) { +#ifdef FLANN_FIRST_MATCH + if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) ) +#else + if (dists[i-1]>dist) +#endif + { + if (i +class KNNResultSet : public ResultSet +{ + int* indices; + DistanceType* dists; + int capacity; + int count; + DistanceType worst_distance_; + +public: + KNNResultSet(int capacity_) : capacity(capacity_), count(0) + { + } + + void init(int* indices_, DistanceType* dists_) + { + indices = indices_; + dists = dists_; + count = 0; + worst_distance_ = (std::numeric_limits::max)(); + dists[capacity-1] = worst_distance_; + } + + size_t size() const + { + return count; + } + + bool full() const CV_OVERRIDE + { + return count == capacity; + } + + + void addPoint(DistanceType dist, int index) CV_OVERRIDE + { + if (dist >= worst_distance_) return; + int i; + for (i = count; i > 0; --i) { +#ifdef FLANN_FIRST_MATCH + if ( (dists[i-1]<=dist) && ((dist!=dists[i-1])||(indices[i-1]<=index)) ) +#else + if (dists[i-1]<=dist) +#endif + { + // Check for duplicate indices + int j = i - 1; + while ((j >= 0) && (dists[j] == dist)) { + if (indices[j] == index) { + return; + } + --j; + } + break; + } + } + + if (count < capacity) ++count; + for (int j = count-1; j > i; --j) { + dists[j] = dists[j-1]; + indices[j] = indices[j-1]; + } + dists[i] = dist; + indices[i] = index; + worst_distance_ = dists[capacity-1]; + } + + DistanceType worstDist() const CV_OVERRIDE + { + return worst_distance_; + } +}; + + +/** + * A result-set class used when performing a radius based search. + */ +template +class RadiusResultSet : public ResultSet +{ + DistanceType radius; + int* indices; + DistanceType* dists; + size_t capacity; + size_t count; + +public: + RadiusResultSet(DistanceType radius_, int* indices_, DistanceType* dists_, int capacity_) : + radius(radius_), indices(indices_), dists(dists_), capacity(capacity_) + { + init(); + } + + ~RadiusResultSet() + { + } + + void init() + { + count = 0; + } + + size_t size() const + { + return count; + } + + bool full() const + { + return true; + } + + void addPoint(DistanceType dist, int index) + { + if (dist0)&&(count < capacity)) { + dists[count] = dist; + indices[count] = index; + } + count++; + } + } + + DistanceType worstDist() const + { + return radius; + } + +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** Class that holds the k NN neighbors + * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays + */ +template +class UniqueResultSet : public ResultSet +{ +public: + struct DistIndex + { + DistIndex(DistanceType dist, unsigned int index) : + dist_(dist), index_(index) + { + } + bool operator<(const DistIndex dist_index) const + { + return (dist_ < dist_index.dist_) || ((dist_ == dist_index.dist_) && index_ < dist_index.index_); + } + DistanceType dist_; + unsigned int index_; + }; + + /** Default cosntructor */ + UniqueResultSet() : + is_full_(false), worst_distance_(std::numeric_limits::max()) + { + } + + /** Check the status of the set + * @return true if we have k NN + */ + inline bool full() const CV_OVERRIDE + { + return is_full_; + } + + /** Remove all elements in the set + */ + virtual void clear() = 0; + + /** Copy the set to two C arrays + * @param indices pointer to a C array of indices + * @param dist pointer to a C array of distances + * @param n_neighbors the number of neighbors to copy + */ + virtual void copy(int* indices, DistanceType* dist, int n_neighbors = -1) const + { + if (n_neighbors < 0) { + for (typename std::set::const_iterator dist_index = dist_indices_.begin(), dist_index_end = + dist_indices_.end(); dist_index != dist_index_end; ++dist_index, ++indices, ++dist) { + *indices = dist_index->index_; + *dist = dist_index->dist_; + } + } + else { + int i = 0; + for (typename std::set::const_iterator dist_index = dist_indices_.begin(), dist_index_end = + dist_indices_.end(); (dist_index != dist_index_end) && (i < n_neighbors); ++dist_index, ++indices, ++dist, ++i) { + *indices = dist_index->index_; + *dist = dist_index->dist_; + } + } + } + + /** Copy the set to two C arrays but sort it according to the distance first + * @param indices pointer to a C array of indices + * @param dist pointer to a C array of distances + * @param n_neighbors the number of neighbors to copy + */ + virtual void sortAndCopy(int* indices, DistanceType* dist, int n_neighbors = -1) const + { + copy(indices, dist, n_neighbors); + } + + /** The number of neighbors in the set + * @return + */ + size_t size() const + { + return dist_indices_.size(); + } + + /** The distance of the furthest neighbor + * If we don't have enough neighbors, it returns the max possible value + * @return + */ + inline DistanceType worstDist() const CV_OVERRIDE + { + return worst_distance_; + } +protected: + /** Flag to say if the set is full */ + bool is_full_; + + /** The worst distance found so far */ + DistanceType worst_distance_; + + /** The best candidates so far */ + std::set dist_indices_; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** Class that holds the k NN neighbors + * Faster than KNNResultSet as it uses a binary heap and does not maintain two arrays + */ +template +class KNNUniqueResultSet : public UniqueResultSet +{ +public: + /** Constructor + * @param capacity the number of neighbors to store at max + */ + KNNUniqueResultSet(unsigned int capacity) : capacity_(capacity) + { + this->is_full_ = false; + this->clear(); + } + + /** Add a possible candidate to the best neighbors + * @param dist distance for that neighbor + * @param index index of that neighbor + */ + inline void addPoint(DistanceType dist, int index) CV_OVERRIDE + { + // Don't do anything if we are worse than the worst + if (dist >= worst_distance_) return; + dist_indices_.insert(DistIndex(dist, index)); + + if (is_full_) { + if (dist_indices_.size() > capacity_) { + dist_indices_.erase(*dist_indices_.rbegin()); + worst_distance_ = dist_indices_.rbegin()->dist_; + } + } + else if (dist_indices_.size() == capacity_) { + is_full_ = true; + worst_distance_ = dist_indices_.rbegin()->dist_; + } + } + + /** Remove all elements in the set + */ + void clear() CV_OVERRIDE + { + dist_indices_.clear(); + worst_distance_ = std::numeric_limits::max(); + is_full_ = false; + } + +protected: + typedef typename UniqueResultSet::DistIndex DistIndex; + using UniqueResultSet::is_full_; + using UniqueResultSet::worst_distance_; + using UniqueResultSet::dist_indices_; + + /** The number of neighbors to keep */ + unsigned int capacity_; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** Class that holds the radius nearest neighbors + * It is more accurate than RadiusResult as it is not limited in the number of neighbors + */ +template +class RadiusUniqueResultSet : public UniqueResultSet +{ +public: + /** Constructor + * @param radius the maximum distance of a neighbor + */ + RadiusUniqueResultSet(DistanceType radius) : + radius_(radius) + { + is_full_ = true; + } + + /** Add a possible candidate to the best neighbors + * @param dist distance for that neighbor + * @param index index of that neighbor + */ + void addPoint(DistanceType dist, int index) CV_OVERRIDE + { + if (dist <= radius_) dist_indices_.insert(DistIndex(dist, index)); + } + + /** Remove all elements in the set + */ + inline void clear() CV_OVERRIDE + { + dist_indices_.clear(); + } + + + /** Check the status of the set + * @return alwys false + */ + inline bool full() const CV_OVERRIDE + { + return true; + } + + /** The distance of the furthest neighbor + * If we don't have enough neighbors, it returns the max possible value + * @return + */ + inline DistanceType worstDist() const CV_OVERRIDE + { + return radius_; + } +private: + typedef typename UniqueResultSet::DistIndex DistIndex; + using UniqueResultSet::dist_indices_; + using UniqueResultSet::is_full_; + + /** The furthest distance a neighbor can be */ + DistanceType radius_; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** Class that holds the k NN neighbors within a radius distance + */ +template +class KNNRadiusUniqueResultSet : public KNNUniqueResultSet +{ +public: + /** Constructor + * @param capacity the number of neighbors to store at max + * @param radius the maximum distance of a neighbor + */ + KNNRadiusUniqueResultSet(unsigned int capacity, DistanceType radius) + { + this->capacity_ = capacity; + this->radius_ = radius; + this->dist_indices_.reserve(capacity_); + this->clear(); + } + + /** Remove all elements in the set + */ + void clear() + { + dist_indices_.clear(); + worst_distance_ = radius_; + is_full_ = false; + } +private: + using KNNUniqueResultSet::dist_indices_; + using KNNUniqueResultSet::is_full_; + using KNNUniqueResultSet::worst_distance_; + + /** The maximum number of neighbors to consider */ + unsigned int capacity_; + + /** The maximum distance of a neighbor */ + DistanceType radius_; +}; +} + +#endif //OPENCV_FLANN_RESULTSET_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/sampling.h b/Prj-Win/3rd/opencv/include/opencv2/flann/sampling.h new file mode 100755 index 0000000..396f177 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/sampling.h @@ -0,0 +1,81 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + + +#ifndef OPENCV_FLANN_SAMPLING_H_ +#define OPENCV_FLANN_SAMPLING_H_ + +#include "matrix.h" +#include "random.h" + +namespace cvflann +{ + +template +Matrix random_sample(Matrix& srcMatrix, long size, bool remove = false) +{ + Matrix newSet(new T[size * srcMatrix.cols], size,srcMatrix.cols); + + T* src,* dest; + for (long i=0; i +Matrix random_sample(const Matrix& srcMatrix, size_t size) +{ + UniqueRandom rand((int)srcMatrix.rows); + Matrix newSet(new T[size * srcMatrix.cols], size,srcMatrix.cols); + + T* src,* dest; + for (size_t i=0; i +#include + +#include "general.h" +#include "nn_index.h" + +#ifdef FLANN_SIGNATURE_ +#undef FLANN_SIGNATURE_ +#endif +#define FLANN_SIGNATURE_ "FLANN_INDEX" + +namespace cvflann +{ + +template +struct Datatype {}; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_INT8; } }; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_INT16; } }; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_INT32; } }; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_UINT8; } }; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_UINT16; } }; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_UINT32; } }; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_FLOAT32; } }; +template<> +struct Datatype { static flann_datatype_t type() { return FLANN_FLOAT64; } }; + + +/** + * Structure representing the index header. + */ +struct IndexHeader +{ + char signature[16]; + char version[16]; + flann_datatype_t data_type; + flann_algorithm_t index_type; + size_t rows; + size_t cols; +}; + +/** + * Saves index header to stream + * + * @param stream - Stream to save to + * @param index - The index to save + */ +template +void save_header(FILE* stream, const NNIndex& index) +{ + IndexHeader header; + memset(header.signature, 0, sizeof(header.signature)); + strcpy(header.signature, FLANN_SIGNATURE_); + memset(header.version, 0, sizeof(header.version)); + strcpy(header.version, FLANN_VERSION_); + header.data_type = Datatype::type(); + header.index_type = index.getType(); + header.rows = index.size(); + header.cols = index.veclen(); + + std::fwrite(&header, sizeof(header),1,stream); +} + + +/** + * + * @param stream - Stream to load from + * @return Index header + */ +inline IndexHeader load_header(FILE* stream) +{ + IndexHeader header; + size_t read_size = fread(&header,sizeof(header),1,stream); + + if (read_size!=(size_t)1) { + throw FLANNException("Invalid index file, cannot read"); + } + + if (strcmp(header.signature,FLANN_SIGNATURE_)!=0) { + throw FLANNException("Invalid index file, wrong signature"); + } + + return header; + +} + + +template +void save_value(FILE* stream, const T& value, size_t count = 1) +{ + fwrite(&value, sizeof(value),count, stream); +} + +template +void save_value(FILE* stream, const cvflann::Matrix& value) +{ + fwrite(&value, sizeof(value),1, stream); + fwrite(value.data, sizeof(T),value.rows*value.cols, stream); +} + +template +void save_value(FILE* stream, const std::vector& value) +{ + size_t size = value.size(); + fwrite(&size, sizeof(size_t), 1, stream); + fwrite(&value[0], sizeof(T), size, stream); +} + +template +void load_value(FILE* stream, T& value, size_t count = 1) +{ + size_t read_cnt = fread(&value, sizeof(value), count, stream); + if (read_cnt != count) { + throw FLANNException("Cannot read from file"); + } +} + +template +void load_value(FILE* stream, cvflann::Matrix& value) +{ + size_t read_cnt = fread(&value, sizeof(value), 1, stream); + if (read_cnt != 1) { + throw FLANNException("Cannot read from file"); + } + value.data = new T[value.rows*value.cols]; + read_cnt = fread(value.data, sizeof(T), value.rows*value.cols, stream); + if (read_cnt != (size_t)(value.rows*value.cols)) { + throw FLANNException("Cannot read from file"); + } +} + + +template +void load_value(FILE* stream, std::vector& value) +{ + size_t size; + size_t read_cnt = fread(&size, sizeof(size_t), 1, stream); + if (read_cnt!=1) { + throw FLANNException("Cannot read from file"); + } + value.resize(size); + read_cnt = fread(&value[0], sizeof(T), size, stream); + if (read_cnt != size) { + throw FLANNException("Cannot read from file"); + } +} + +} + +#endif /* OPENCV_FLANN_SAVING_H_ */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/flann/simplex_downhill.h b/Prj-Win/3rd/opencv/include/opencv2/flann/simplex_downhill.h new file mode 100755 index 0000000..145901a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/flann/simplex_downhill.h @@ -0,0 +1,186 @@ +/*********************************************************************** + * Software License Agreement (BSD License) + * + * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved. + * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved. + * + * THE BSD LICENSE + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *************************************************************************/ + +#ifndef OPENCV_FLANN_SIMPLEX_DOWNHILL_H_ +#define OPENCV_FLANN_SIMPLEX_DOWNHILL_H_ + +namespace cvflann +{ + +/** + Adds val to array vals (and point to array points) and keeping the arrays sorted by vals. + */ +template +void addValue(int pos, float val, float* vals, T* point, T* points, int n) +{ + vals[pos] = val; + for (int i=0; i0 && vals[j] +float optimizeSimplexDownhill(T* points, int n, F func, float* vals = NULL ) +{ + const int MAX_ITERATIONS = 10; + + assert(n>0); + + T* p_o = new T[n]; + T* p_r = new T[n]; + T* p_e = new T[n]; + + int alpha = 1; + + int iterations = 0; + + bool ownVals = false; + if (vals == NULL) { + ownVals = true; + vals = new float[n+1]; + for (int i=0; i MAX_ITERATIONS) break; + + // compute average of simplex points (except the highest point) + for (int j=0; j=vals[0])&&(val_r=vals[n]) { + for (int i=0; i +#include "opencv2/core.hpp" +#include "opencv2/core/utility.hpp" + +namespace cvflann +{ + +/** + * A start-stop timer class. + * + * Can be used to time portions of code. + */ +class StartStopTimer +{ + int64 startTime; + +public: + /** + * Value of the timer. + */ + double value; + + + /** + * Constructor. + */ + StartStopTimer() + { + reset(); + } + + /** + * Starts the timer. + */ + void start() + { + startTime = cv::getTickCount(); + } + + /** + * Stops the timer and updates timer value. + */ + void stop() + { + int64 stopTime = cv::getTickCount(); + value += ( (double)stopTime - startTime) / cv::getTickFrequency(); + } + + /** + * Resets the timer value to 0. + */ + void reset() + { + value = 0; + } + +}; + +} + +#endif // FLANN_TIMER_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi.hpp new file mode 100755 index 0000000..0600e24 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi.hpp @@ -0,0 +1,33 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_HPP +#define OPENCV_GAPI_HPP + +#include + +/** \defgroup gapi G-API framework +@{ + @defgroup gapi_main_classes G-API Main Classes + @defgroup gapi_data_objects G-API Data Objects + @{ + @defgroup gapi_meta_args G-API Metadata Descriptors + @} + @defgroup gapi_std_backends G-API Standard backends + @defgroup gapi_compile_args G-API Graph Compilation Arguments +@} + */ + +#include +#include +#include +#include +#include +#include +#include + +#endif // OPENCV_GAPI_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/core.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/core.hpp new file mode 100755 index 0000000..a38d747 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/core.hpp @@ -0,0 +1,1639 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_CORE_HPP +#define OPENCV_GAPI_CORE_HPP + +#include // std::tuple + +#include + +#include +#include +#include + +/** \defgroup gapi_core G-API core (basic) functionality +@{ + @defgroup gapi_math Graph API: Math operations + @defgroup gapi_pixelwise Graph API: Pixelwise operations + @defgroup gapi_matrixop Graph API: Operations on matrices + @defgroup gapi_transform Graph API: Geometric, depth and LUT-like image transformations +@} + */ +namespace cv { namespace gapi { +namespace core { + using GMat2 = std::tuple; + using GMat3 = std::tuple; // FIXME: how to avoid this? + using GMat4 = std::tuple; + using GMatScalar = std::tuple; + + G_TYPED_KERNEL(GAdd, , "org.opencv.core.math.add") { + static GMatDesc outMeta(GMatDesc a, GMatDesc b, int ddepth) { + if (ddepth == -1) + { + // OpenCV: When the input arrays in add/subtract/multiply/divide + // functions have different depths, the output array depth must be + // explicitly specified! + // See artim_op() @ arithm.cpp + GAPI_Assert(a.chan == b.chan); + GAPI_Assert(a.depth == b.depth); + return a; + } + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GAddC, , "org.opencv.core.math.addC") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc, int ddepth) { + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GSub, , "org.opencv.core.math.sub") { + static GMatDesc outMeta(GMatDesc a, GMatDesc b, int ddepth) { + if (ddepth == -1) + { + // This macro should select a larger data depth from a and b + // considering the number of channels in the same + // FIXME!!! Clarify if it is valid for sub() + GAPI_Assert(a.chan == b.chan); + ddepth = std::max(a.depth, b.depth); + } + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GSubC, , "org.opencv.core.math.subC") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc, int ddepth) { + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GSubRC,, "org.opencv.core.math.subRC") { + static GMatDesc outMeta(GScalarDesc, GMatDesc b, int ddepth) { + return b.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GMul, , "org.opencv.core.math.mul") { + static GMatDesc outMeta(GMatDesc a, GMatDesc, double, int ddepth) { + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GMulCOld, , "org.opencv.core.math.mulCOld") { + static GMatDesc outMeta(GMatDesc a, double, int ddepth) { + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GMulC, , "org.opencv.core.math.mulC"){ + static GMatDesc outMeta(GMatDesc a, GScalarDesc, int ddepth) { + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GMulS, , "org.opencv.core.math.muls") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a; + } + }; // FIXME: Merge with MulC + + G_TYPED_KERNEL(GDiv, , "org.opencv.core.math.div") { + static GMatDesc outMeta(GMatDesc a, GMatDesc b, double, int ddepth) { + if (ddepth == -1) + { + GAPI_Assert(a.depth == b.depth); + return b; + } + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GDivC, , "org.opencv.core.math.divC") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc, double, int ddepth) { + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GDivRC, , "org.opencv.core.math.divRC") { + static GMatDesc outMeta(GScalarDesc, GMatDesc b, double, int ddepth) { + return b.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GMean, , "org.opencv.core.math.mean") { + static GScalarDesc outMeta(GMatDesc) { + return empty_scalar_desc(); + } + }; + + G_TYPED_KERNEL_M(GPolarToCart, , "org.opencv.core.math.polarToCart") { + static std::tuple outMeta(GMatDesc, GMatDesc a, bool) { + return std::make_tuple(a, a); + } + }; + + G_TYPED_KERNEL_M(GCartToPolar, , "org.opencv.core.math.cartToPolar") { + static std::tuple outMeta(GMatDesc x, GMatDesc, bool) { + return std::make_tuple(x, x); + } + }; + + G_TYPED_KERNEL(GPhase, , "org.opencv.core.math.phase") { + static GMatDesc outMeta(const GMatDesc &inx, const GMatDesc &, bool) { + return inx; + } + }; + + G_TYPED_KERNEL(GMask, , "org.opencv.core.pixelwise.mask") { + static GMatDesc outMeta(GMatDesc in, GMatDesc) { + return in; + } + }; + + G_TYPED_KERNEL(GCmpGT, , "org.opencv.core.pixelwise.compare.cmpGT") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpGE, , "org.opencv.core.pixelwise.compare.cmpGE") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpLE, , "org.opencv.core.pixelwise.compare.cmpLE") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpLT, , "org.opencv.core.pixelwise.compare.cmpLT") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpEQ, , "org.opencv.core.pixelwise.compare.cmpEQ") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpNE, , "org.opencv.core.pixelwise.compare.cmpNE") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpGTScalar, , "org.opencv.core.pixelwise.compare.cmpGTScalar"){ + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpGEScalar, , "org.opencv.core.pixelwise.compare.cmpGEScalar"){ + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpLEScalar, , "org.opencv.core.pixelwise.compare.cmpLEScalar"){ + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpLTScalar, , "org.opencv.core.pixelwise.compare.cmpLTScalar"){ + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpEQScalar, , "org.opencv.core.pixelwise.compare.cmpEQScalar"){ + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GCmpNEScalar, , "org.opencv.core.pixelwise.compare.cmpNEScalar"){ + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a.withDepth(CV_8U); + } + }; + + G_TYPED_KERNEL(GAnd, , "org.opencv.core.pixelwise.bitwise_and") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GAndS, , "org.opencv.core.pixelwise.bitwise_andS") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GOr, , "org.opencv.core.pixelwise.bitwise_or") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GOrS, , "org.opencv.core.pixelwise.bitwise_orS") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GXor, , "org.opencv.core.pixelwise.bitwise_xor") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GXorS, , "org.opencv.core.pixelwise.bitwise_xorS") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GNot, , "org.opencv.core.pixelwise.bitwise_not") { + static GMatDesc outMeta(GMatDesc a) { + return a; + } + }; + + G_TYPED_KERNEL(GSelect, , "org.opencv.core.pixelwise.select") { + static GMatDesc outMeta(GMatDesc a, GMatDesc, GMatDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GMin, , "org.opencv.core.matrixop.min") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GMax, , "org.opencv.core.matrixop.max") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GAbsDiff, , "org.opencv.core.matrixop.absdiff") { + static GMatDesc outMeta(GMatDesc a, GMatDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GAbsDiffC, , "org.opencv.core.matrixop.absdiffC") { + static GMatDesc outMeta(GMatDesc a, GScalarDesc) { + return a; + } + }; + + G_TYPED_KERNEL(GSum, , "org.opencv.core.matrixop.sum") { + static GScalarDesc outMeta(GMatDesc) { + return empty_scalar_desc(); + } + }; + + G_TYPED_KERNEL(GAddW, , "org.opencv.core.matrixop.addweighted") { + static GMatDesc outMeta(GMatDesc a, double, GMatDesc b, double, double, int ddepth) { + if (ddepth == -1) + { + // OpenCV: When the input arrays in add/subtract/multiply/divide + // functions have different depths, the output array depth must be + // explicitly specified! + // See artim_op() @ arithm.cpp + GAPI_Assert(a.chan == b.chan); + GAPI_Assert(a.depth == b.depth); + return a; + } + return a.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GNormL1, , "org.opencv.core.matrixop.norml1") { + static GScalarDesc outMeta(GMatDesc) { + return empty_scalar_desc(); + } + }; + + G_TYPED_KERNEL(GNormL2, , "org.opencv.core.matrixop.norml2") { + static GScalarDesc outMeta(GMatDesc) { + return empty_scalar_desc(); + } + }; + + G_TYPED_KERNEL(GNormInf, , "org.opencv.core.matrixop.norminf") { + static GScalarDesc outMeta(GMatDesc) { + return empty_scalar_desc(); + } + }; + + G_TYPED_KERNEL_M(GIntegral, , "org.opencv.core.matrixop.integral") { + static std::tuple outMeta(GMatDesc in, int sd, int sqd) { + return std::make_tuple(in.withSizeDelta(1,1).withDepth(sd), + in.withSizeDelta(1,1).withDepth(sqd)); + } + }; + + G_TYPED_KERNEL(GThreshold, , "org.opencv.core.matrixop.threshold") { + static GMatDesc outMeta(GMatDesc in, GScalarDesc, GScalarDesc, int) { + return in; + } + }; + + + G_TYPED_KERNEL_M(GThresholdOT, , "org.opencv.core.matrixop.thresholdOT") { + static std::tuple outMeta(GMatDesc in, GScalarDesc, int) { + return std::make_tuple(in, empty_scalar_desc()); + } + }; + + G_TYPED_KERNEL(GInRange, , "org.opencv.core.matrixop.inrange") { + static GMatDesc outMeta(GMatDesc in, GScalarDesc, GScalarDesc) { + return in.withType(CV_8U, 1); + } + }; + + G_TYPED_KERNEL_M(GSplit3, , "org.opencv.core.transform.split3") { + static std::tuple outMeta(GMatDesc in) { + const auto out_depth = in.depth; + const auto out_desc = in.withType(out_depth, 1); + return std::make_tuple(out_desc, out_desc, out_desc); + } + }; + + G_TYPED_KERNEL_M(GSplit4, ,"org.opencv.core.transform.split4") { + static std::tuple outMeta(GMatDesc in) { + const auto out_depth = in.depth; + const auto out_desc = in.withType(out_depth, 1); + return std::make_tuple(out_desc, out_desc, out_desc, out_desc); + } + }; + + G_TYPED_KERNEL(GResize, , "org.opencv.core.transform.resize") { + static GMatDesc outMeta(GMatDesc in, Size sz, double fx, double fy, int) { + if (sz.width != 0 && sz.height != 0) + { + return in.withSize(sz); + } + else + { + GAPI_Assert(fx != 0. && fy != 0.); + return in.withSize + (Size(static_cast(std::round(in.size.width * fx)), + static_cast(std::round(in.size.height * fy)))); + } + } + }; + + G_TYPED_KERNEL(GResizeP, , "org.opencv.core.transform.resizeP") { + static GMatDesc outMeta(GMatDesc in, Size sz, int interp) { + GAPI_Assert(in.depth == CV_8U); + GAPI_Assert(in.chan == 3); + GAPI_Assert(in.planar); + GAPI_Assert(interp == cv::INTER_LINEAR); + return in.withSize(sz); + } + }; + + G_TYPED_KERNEL(GMerge3, , "org.opencv.core.transform.merge3") { + static GMatDesc outMeta(GMatDesc in, GMatDesc, GMatDesc) { + // Preserve depth and add channel component + return in.withType(in.depth, 3); + } + }; + + G_TYPED_KERNEL(GMerge4, , "org.opencv.core.transform.merge4") { + static GMatDesc outMeta(GMatDesc in, GMatDesc, GMatDesc, GMatDesc) { + // Preserve depth and add channel component + return in.withType(in.depth, 4); + } + }; + + G_TYPED_KERNEL(GRemap, , "org.opencv.core.transform.remap") { + static GMatDesc outMeta(GMatDesc in, Mat m1, Mat, int, int, Scalar) { + return in.withSize(m1.size()); + } + }; + + G_TYPED_KERNEL(GFlip, , "org.opencv.core.transform.flip") { + static GMatDesc outMeta(GMatDesc in, int) { + return in; + } + }; + + G_TYPED_KERNEL(GCrop, , "org.opencv.core.transform.crop") { + static GMatDesc outMeta(GMatDesc in, Rect rc) { + return in.withSize(Size(rc.width, rc.height)); + } + }; + + G_TYPED_KERNEL(GConcatHor, , "org.opencv.imgproc.transform.concatHor") { + static GMatDesc outMeta(GMatDesc l, GMatDesc r) { + return l.withSizeDelta(+r.size.width, 0); + } + }; + + G_TYPED_KERNEL(GConcatVert, , "org.opencv.imgproc.transform.concatVert") { + static GMatDesc outMeta(GMatDesc t, GMatDesc b) { + return t.withSizeDelta(0, +b.size.height); + } + }; + + G_TYPED_KERNEL(GLUT, , "org.opencv.core.transform.LUT") { + static GMatDesc outMeta(GMatDesc in, Mat) { + return in; + } + }; + + G_TYPED_KERNEL(GConvertTo, , "org.opencv.core.transform.convertTo") { + static GMatDesc outMeta(GMatDesc in, int rdepth, double, double) { + return rdepth < 0 ? in : in.withDepth(rdepth); + } + }; + + G_TYPED_KERNEL(GSqrt, , "org.opencv.core.math.sqrt") { + static GMatDesc outMeta(GMatDesc in) { + return in; + } + }; + + G_TYPED_KERNEL(GNormalize, , "org.opencv.core.normalize") { + static GMatDesc outMeta(GMatDesc in, double, double, int, int ddepth) { + // unlike opencv doesn't have a mask as a parameter + return (ddepth < 0 ? in : in.withDepth(ddepth)); + } + }; +} + +//! @addtogroup gapi_math +//! @{ + +/** @brief Calculates the per-element sum of two matrices. + +The function add calculates sum of two matrices of the same size and the same number of channels: +\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f] + +The function can be replaced with matrix expressions: + \f[\texttt{dst} = \texttt{src1} + \texttt{src2}\f] + +The input matrices and the output matrix can all have the same or different depths. For example, you +can add a 16-bit unsigned matrix to a 8-bit signed matrix and store the sum as a 32-bit +floating-point matrix. Depth of the output matrix is determined by the ddepth parameter. +If src1.depth() == src2.depth(), ddepth can be set to the default -1. In this case, the output matrix will have +the same depth as the input matrices. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.add" +@param src1 first input matrix. +@param src2 second input matrix. +@param ddepth optional depth of the output matrix. +@sa sub, addWeighted +*/ +GAPI_EXPORTS GMat add(const GMat& src1, const GMat& src2, int ddepth = -1); + +/** @brief Calculates the per-element sum of matrix and given scalar. + +The function addC adds a given scalar value to each element of given matrix. +The function can be replaced with matrix expressions: + + \f[\texttt{dst} = \texttt{src1} + \texttt{c}\f] + +Depth of the output matrix is determined by the ddepth parameter. +If ddepth is set to default -1, the depth of output matrix will be the same as the depth of input matrix. +The matrices can be single or multi channel. Output matrix must have the same size and number of channels as the input matrix. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.addC" +@param src1 first input matrix. +@param c scalar value to be added. +@param ddepth optional depth of the output matrix. +@sa sub, addWeighted +*/ +GAPI_EXPORTS GMat addC(const GMat& src1, const GScalar& c, int ddepth = -1); +//! @overload +GAPI_EXPORTS GMat addC(const GScalar& c, const GMat& src1, int ddepth = -1); + +/** @brief Calculates the per-element difference between two matrices. + +The function sub calculates difference between two matrices, when both matrices have the same size and the same number of +channels: + \f[\texttt{dst}(I) = \texttt{src1}(I) - \texttt{src2}(I)\f] + +The function can be replaced with matrix expressions: +\f[\texttt{dst} = \texttt{src1} - \texttt{src2}\f] + +The input matrices and the output matrix can all have the same or different depths. For example, you +can subtract two 8-bit unsigned matrices store the result as a 16-bit signed matrix. +Depth of the output matrix is determined by the ddepth parameter. +If src1.depth() == src2.depth(), ddepth can be set to the default -1. In this case, the output matrix will have +the same depth as the input matrices. The matrices can be single or multi channel. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.sub" +@param src1 first input matrix. +@param src2 second input matrix. +@param ddepth optional depth of the output matrix. +@sa add, addC + */ +GAPI_EXPORTS GMat sub(const GMat& src1, const GMat& src2, int ddepth = -1); + +/** @brief Calculates the per-element difference between matrix and given scalar. + +The function can be replaced with matrix expressions: + \f[\texttt{dst} = \texttt{src} - \texttt{c}\f] + +Depth of the output matrix is determined by the ddepth parameter. +If ddepth is set to default -1, the depth of output matrix will be the same as the depth of input matrix. +The matrices can be single or multi channel. Output matrix must have the same size as src. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.subC" +@param src first input matrix. +@param c scalar value to subtracted. +@param ddepth optional depth of the output matrix. +@sa add, addC, subRC + */ +GAPI_EXPORTS GMat subC(const GMat& src, const GScalar& c, int ddepth = -1); + +/** @brief Calculates the per-element difference between given scalar and the matrix. + +The function can be replaced with matrix expressions: + \f[\texttt{dst} = \texttt{val} - \texttt{src}\f] + +Depth of the output matrix is determined by the ddepth parameter. +If ddepth is set to default -1, the depth of output matrix will be the same as the depth of input matrix. +The matrices can be single or multi channel. Output matrix must have the same size as src. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.subRC" +@param c scalar value to subtract from. +@param src input matrix to be subtracted. +@param ddepth optional depth of the output matrix. +@sa add, addC, subC + */ +GAPI_EXPORTS GMat subRC(const GScalar& c, const GMat& src, int ddepth = -1); + +/** @brief Calculates the per-element scaled product of two matrices. + +The function mul calculates the per-element product of two matrices: + +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I))\f] + +If src1.depth() == src2.depth(), ddepth can be set to the default -1. In this case, the output matrix will have +the same depth as the input matrices. The matrices can be single or multi channel. +Output matrix must have the same size as input matrices. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.mul" +@param src1 first input matrix. +@param src2 second input matrix of the same size and the same depth as src1. +@param scale optional scale factor. +@param ddepth optional depth of the output matrix. +@sa add, sub, div, addWeighted +*/ +GAPI_EXPORTS GMat mul(const GMat& src1, const GMat& src2, double scale = 1.0, int ddepth = -1); + +/** @brief Multiplies matrix by scalar. + +The function mulC multiplies each element of matrix src by given scalar value: + +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I) \cdot \texttt{multiplier} )\f] + +The matrices can be single or multi channel. Output matrix must have the same size as src. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.mulC" +@param src input matrix. +@param multiplier factor to be multiplied. +@param ddepth optional depth of the output matrix. If -1, the depth of output matrix will be the same as input matrix depth. +@sa add, sub, div, addWeighted +*/ +GAPI_EXPORTS GMat mulC(const GMat& src, double multiplier, int ddepth = -1); +//! @overload +GAPI_EXPORTS GMat mulC(const GMat& src, const GScalar& multiplier, int ddepth = -1); // FIXME: merge with mulc +//! @overload +GAPI_EXPORTS GMat mulC(const GScalar& multiplier, const GMat& src, int ddepth = -1); // FIXME: merge with mulc + +/** @brief Performs per-element division of two matrices. + +The function divides one matrix by another: +\f[\texttt{dst(I) = saturate(src1(I)*scale/src2(I))}\f] + +When src2(I) is zero, dst(I) will also be zero. Different channels of +multi-channel matrices are processed independently. +The matrices can be single or multi channel. Output matrix must have the same size and depth as src. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.div" +@param src1 first input matrix. +@param src2 second input matrix of the same size and depth as src1. +@param scale scalar factor. +@param ddepth optional depth of the output matrix; you can only pass -1 when src1.depth() == src2.depth(). +@sa mul, add, sub +*/ +GAPI_EXPORTS GMat div(const GMat& src1, const GMat& src2, double scale, int ddepth = -1); + +/** @brief Divides matrix by scalar. + +The function divC divides each element of matrix src by given scalar value: + +\f[\texttt{dst(I) = saturate(src(I)*scale/divisor)}\f] + +When divisor is zero, dst(I) will also be zero. Different channels of +multi-channel matrices are processed independently. +The matrices can be single or multi channel. Output matrix must have the same size and depth as src. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.divC" +@param src input matrix. +@param divisor number to be divided by. +@param ddepth optional depth of the output matrix. If -1, the depth of output matrix will be the same as input matrix depth. +@param scale scale factor. +@sa add, sub, div, addWeighted +*/ +GAPI_EXPORTS GMat divC(const GMat& src, const GScalar& divisor, double scale, int ddepth = -1); + +/** @brief Divides scalar by matrix. + +The function divRC divides given scalar by each element of matrix src and keep the division result in new matrix of the same size and type as src: + +\f[\texttt{dst(I) = saturate(divident*scale/src(I))}\f] + +When src(I) is zero, dst(I) will also be zero. Different channels of +multi-channel matrices are processed independently. +The matrices can be single or multi channel. Output matrix must have the same size and depth as src. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.divRC" +@param src input matrix. +@param divident number to be divided. +@param ddepth optional depth of the output matrix. If -1, the depth of output matrix will be the same as input matrix depth. +@param scale scale factor +@sa add, sub, div, addWeighted +*/ +GAPI_EXPORTS GMat divRC(const GScalar& divident, const GMat& src, double scale, int ddepth = -1); + +/** @brief Applies a mask to a matrix. + +The function mask set value from given matrix if the corresponding pixel value in mask matrix set to true, +and set the matrix value to 0 overwise. + +Supported src matrix data types are @ref CV_8UC1, @ref CV_16SC1, @ref CV_16UC1. Supported mask data type is @ref CV_8UC1. + +@note Function textual ID is "org.opencv.core.math.mask" +@param src input matrix. +@param mask input mask matrix. +*/ +GAPI_EXPORTS GMat mask(const GMat& src, const GMat& mask); + +/** @brief Calculates an average (mean) of matrix elements. + +The function mean calculates the mean value M of matrix elements, +independently for each channel, and return it. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.math.mean" +@param src input matrix. +*/ +GAPI_EXPORTS GScalar mean(const GMat& src); + +/** @brief Calculates x and y coordinates of 2D vectors from their magnitude and angle. + +The function polarToCart calculates the Cartesian coordinates of each 2D +vector represented by the corresponding elements of magnitude and angle: +\f[\begin{array}{l} \texttt{x} (I) = \texttt{magnitude} (I) \cos ( \texttt{angle} (I)) \\ \texttt{y} (I) = \texttt{magnitude} (I) \sin ( \texttt{angle} (I)) \\ \end{array}\f] + +The relative accuracy of the estimated coordinates is about 1e-6. + +First output is a matrix of x-coordinates of 2D vectors. +Second output is a matrix of y-coordinates of 2D vectors. +Both output must have the same size and depth as input matrices. + +@note Function textual ID is "org.opencv.core.math.polarToCart" + +@param magnitude input floating-point @ref CV_32FC1 matrix (1xN) of magnitudes of 2D vectors; +@param angle input floating-point @ref CV_32FC1 matrix (1xN) of angles of 2D vectors. +@param angleInDegrees when true, the input angles are measured in +degrees, otherwise, they are measured in radians. +@sa cartToPolar, exp, log, pow, sqrt +*/ +GAPI_EXPORTS std::tuple polarToCart(const GMat& magnitude, const GMat& angle, + bool angleInDegrees = false); + +/** @brief Calculates the magnitude and angle of 2D vectors. + +The function cartToPolar calculates either the magnitude, angle, or both +for every 2D vector (x(I),y(I)): +\f[\begin{array}{l} \texttt{magnitude} (I)= \sqrt{\texttt{x}(I)^2+\texttt{y}(I)^2} , \\ \texttt{angle} (I)= \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))[ \cdot180 / \pi ] \end{array}\f] + +The angles are calculated with accuracy about 0.3 degrees. For the point +(0,0), the angle is set to 0. + +First output is a matrix of magnitudes of the same size and depth as input x. +Second output is a matrix of angles that has the same size and depth as +x; the angles are measured in radians (from 0 to 2\*Pi) or in degrees (0 to 360 degrees). + +@note Function textual ID is "org.opencv.core.math.cartToPolar" + +@param x matrix of @ref CV_32FC1 x-coordinates. +@param y array of @ref CV_32FC1 y-coordinates. +@param angleInDegrees a flag, indicating whether the angles are measured +in radians (which is by default), or in degrees. +@sa polarToCart +*/ +GAPI_EXPORTS std::tuple cartToPolar(const GMat& x, const GMat& y, + bool angleInDegrees = false); + +/** @brief Calculates the rotation angle of 2D vectors. + +The function cv::phase calculates the rotation angle of each 2D vector that +is formed from the corresponding elements of x and y : +\f[\texttt{angle} (I) = \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))\f] + +The angle estimation accuracy is about 0.3 degrees. When x(I)=y(I)=0 , +the corresponding angle(I) is set to 0. +@param x input floating-point array of x-coordinates of 2D vectors. +@param y input array of y-coordinates of 2D vectors; it must have the +same size and the same type as x. +@param angleInDegrees when true, the function calculates the angle in +degrees, otherwise, they are measured in radians. +@return array of vector angles; it has the same size and same type as x. +*/ +GAPI_EXPORTS GMat phase(const GMat& x, const GMat &y, bool angleInDegrees = false); + +/** @brief Calculates a square root of array elements. + +The function cv::gapi::sqrt calculates a square root of each input array element. +In case of multi-channel arrays, each channel is processed +independently. The accuracy is approximately the same as of the built-in +std::sqrt . +@param src input floating-point array. +@return output array of the same size and type as src. +*/ +GAPI_EXPORTS GMat sqrt(const GMat &src); + +//! @} gapi_math +//! +//! @addtogroup gapi_pixelwise +//! @{ + +/** @brief Performs the per-element comparison of two matrices checking if elements from first matrix are greater compare to elements in second. + +The function compares elements of two matrices src1 and src2 of the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) > \texttt{src2} (I)\f] + +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: +\f[\texttt{dst} = \texttt{src1} > \texttt{src2}\f] + +Output matrix of depth @ref CV_8U must have the same size and the same number of channels as + the input matrices/matrix. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpGT" +@param src1 first input matrix. +@param src2 second input matrix/scalar of the same depth as first input matrix. +@sa min, max, threshold, cmpLE, cmpGE, cmpLS +*/ +GAPI_EXPORTS GMat cmpGT(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpGTScalar" +*/ +GAPI_EXPORTS GMat cmpGT(const GMat& src1, const GScalar& src2); + +/** @brief Performs the per-element comparison of two matrices checking if elements from first matrix are less than elements in second. + +The function compares elements of two matrices src1 and src2 of the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) < \texttt{src2} (I)\f] + +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: + \f[\texttt{dst} = \texttt{src1} < \texttt{src2}\f] + +Output matrix of depth @ref CV_8U must have the same size and the same number of channels as + the input matrices/matrix. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpLT" +@param src1 first input matrix. +@param src2 second input matrix/scalar of the same depth as first input matrix. +@sa min, max, threshold, cmpLE, cmpGE, cmpGT +*/ +GAPI_EXPORTS GMat cmpLT(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpLTScalar" +*/ +GAPI_EXPORTS GMat cmpLT(const GMat& src1, const GScalar& src2); + +/** @brief Performs the per-element comparison of two matrices checking if elements from first matrix are greater or equal compare to elements in second. + +The function compares elements of two matrices src1 and src2 of the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) >= \texttt{src2} (I)\f] + +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: + \f[\texttt{dst} = \texttt{src1} >= \texttt{src2}\f] + +Output matrix of depth @ref CV_8U must have the same size and the same number of channels as + the input matrices. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpGE" +@param src1 first input matrix. +@param src2 second input matrix/scalar of the same depth as first input matrix. +@sa min, max, threshold, cmpLE, cmpGT, cmpLS +*/ +GAPI_EXPORTS GMat cmpGE(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpLGEcalar" +*/ +GAPI_EXPORTS GMat cmpGE(const GMat& src1, const GScalar& src2); + +/** @brief Performs the per-element comparison of two matrices checking if elements from first matrix are less or equal compare to elements in second. + +The function compares elements of two matrices src1 and src2 of the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) <= \texttt{src2} (I)\f] + +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: + \f[\texttt{dst} = \texttt{src1} <= \texttt{src2}\f] + +Output matrix of depth @ref CV_8U must have the same size and the same number of channels as + the input matrices. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpLE" +@param src1 first input matrix. +@param src2 second input matrix/scalar of the same depth as first input matrix. +@sa min, max, threshold, cmpGT, cmpGE, cmpLS +*/ +GAPI_EXPORTS GMat cmpLE(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpLEScalar" +*/ +GAPI_EXPORTS GMat cmpLE(const GMat& src1, const GScalar& src2); + +/** @brief Performs the per-element comparison of two matrices checking if elements from first matrix are equal to elements in second. + +The function compares elements of two matrices src1 and src2 of the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) == \texttt{src2} (I)\f] + +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: + \f[\texttt{dst} = \texttt{src1} == \texttt{src2}\f] + +Output matrix of depth @ref CV_8U must have the same size and the same number of channels as + the input matrices. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpEQ" +@param src1 first input matrix. +@param src2 second input matrix/scalar of the same depth as first input matrix. +@sa min, max, threshold, cmpNE +*/ +GAPI_EXPORTS GMat cmpEQ(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpEQScalar" +*/ +GAPI_EXPORTS GMat cmpEQ(const GMat& src1, const GScalar& src2); + +/** @brief Performs the per-element comparison of two matrices checking if elements from first matrix are not equal to elements in second. + +The function compares elements of two matrices src1 and src2 of the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) != \texttt{src2} (I)\f] + +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: + \f[\texttt{dst} = \texttt{src1} != \texttt{src2}\f] + +Output matrix of depth @ref CV_8U must have the same size and the same number of channels as + the input matrices. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpNE" +@param src1 first input matrix. +@param src2 second input matrix/scalar of the same depth as first input matrix. +@sa min, max, threshold, cmpEQ +*/ +GAPI_EXPORTS GMat cmpNE(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.cmpNEScalar" +*/ +GAPI_EXPORTS GMat cmpNE(const GMat& src1, const GScalar& src2); + +/** @brief computes bitwise conjunction of the two matrixes (src1 & src2) +Calculates the per-element bit-wise logical conjunction of two matrices of the same size. + +In case of floating-point matrices, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel matrices, each channel is processed +independently. Output matrix must have the same size and depth as the input +matrices. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.bitwise_and" + +@param src1 first input matrix. +@param src2 second input matrix. +*/ +GAPI_EXPORTS GMat bitwise_and(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.bitwise_andS" +@param src1 first input matrix. +@param src2 scalar, which will be per-lemenetly conjuncted with elements of src1. +*/ +GAPI_EXPORTS GMat bitwise_and(const GMat& src1, const GScalar& src2); + +/** @brief computes bitwise disjunction of the two matrixes (src1 | src2) +Calculates the per-element bit-wise logical disjunction of two matrices of the same size. + +In case of floating-point matrices, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel matrices, each channel is processed +independently. Output matrix must have the same size and depth as the input +matrices. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.bitwise_or" + +@param src1 first input matrix. +@param src2 second input matrix. +*/ +GAPI_EXPORTS GMat bitwise_or(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.bitwise_orS" +@param src1 first input matrix. +@param src2 scalar, which will be per-lemenetly disjuncted with elements of src1. +*/ +GAPI_EXPORTS GMat bitwise_or(const GMat& src1, const GScalar& src2); + + +/** @brief computes bitwise logical "exclusive or" of the two matrixes (src1 ^ src2) +Calculates the per-element bit-wise logical "exclusive or" of two matrices of the same size. + +In case of floating-point matrices, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel matrices, each channel is processed +independently. Output matrix must have the same size and depth as the input +matrices. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.bitwise_xor" + +@param src1 first input matrix. +@param src2 second input matrix. +*/ +GAPI_EXPORTS GMat bitwise_xor(const GMat& src1, const GMat& src2); +/** @overload +@note Function textual ID is "org.opencv.core.pixelwise.compare.bitwise_xorS" +@param src1 first input matrix. +@param src2 scalar, for which per-lemenet "logical or" operation on elements of src1 will be performed. +*/ +GAPI_EXPORTS GMat bitwise_xor(const GMat& src1, const GScalar& src2); + + +/** @brief Inverts every bit of an array. +The function bitwise_not calculates per-element bit-wise inversion of the input +matrix: +\f[\texttt{dst} (I) = \neg \texttt{src} (I)\f] + +In case of floating-point matrices, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel matrices, each channel is processed +independently. Output matrix must have the same size and depth as the input +matrix. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.bitwise_not" + +@param src input matrix. +*/ +GAPI_EXPORTS GMat bitwise_not(const GMat& src); + +/** @brief Select values from either first or second of input matrices by given mask. +The function set to the output matrix either the value from the first input matrix if corresponding value of mask matrix is 255, + or value from the second input matrix (if value of mask matrix set to 0). + +Input mask matrix must be of @ref CV_8UC1 type, two other inout matrices and output matrix should be of the same type. The size should +be the same for all input and output matrices. +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.pixelwise.select" + +@param src1 first input matrix. +@param src2 second input matrix. +@param mask mask input matrix. +*/ +GAPI_EXPORTS GMat select(const GMat& src1, const GMat& src2, const GMat& mask); + +//! @} gapi_pixelwise + + +//! @addtogroup gapi_matrixop +//! @{ +/** @brief Calculates per-element minimum of two matrices. + +The function min calculates the per-element minimum of two matrices of the same size, number of channels and depth: +\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I))\f] + where I is a multi-dimensional index of matrix elements. In case of + multi-channel matrices, each channel is processed independently. +Output matrix must be of the same size and depth as src1. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.min" +@param src1 first input matrix. +@param src2 second input matrix of the same size and depth as src1. +@sa max, compareEqual, compareLess, compareLessEqual +*/ +GAPI_EXPORTS GMat min(const GMat& src1, const GMat& src2); + +/** @brief Calculates per-element maximum of two matrices. + +The function max calculates the per-element maximum of two matrices of the same size, number of channels and depth: +\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I))\f] + where I is a multi-dimensional index of matrix elements. In case of + multi-channel matrices, each channel is processed independently. +Output matrix must be of the same size and depth as src1. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.max" +@param src1 first input matrix. +@param src2 second input matrix of the same size and depth as src1. +@sa min, compare, compareEqual, compareGreater, compareGreaterEqual +*/ +GAPI_EXPORTS GMat max(const GMat& src1, const GMat& src2); + +/** @brief Calculates the per-element absolute difference between two matrices. + +The function absDiff calculates absolute difference between two matrices of the same size and depth: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|)\f] + where I is a multi-dimensional index of matrix elements. In case of + multi-channel matrices, each channel is processed independently. +Output matrix must have the same size and depth as input matrices. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.absdiff" +@param src1 first input matrix. +@param src2 second input matrix. +@sa abs +*/ +GAPI_EXPORTS GMat absDiff(const GMat& src1, const GMat& src2); + +/** @brief Calculates absolute value of matrix elements. + +The function abs calculates absolute difference between matrix elements and given scalar value: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{matC}(I)|)\f] + where matC is constructed from given scalar c and has the same sizes and depth as input matrix src. + +Output matrix must be of the same size and depth as src. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.absdiffC" +@param src input matrix. +@param c scalar to be subtracted. +@sa min, max +*/ +GAPI_EXPORTS GMat absDiffC(const GMat& src, const GScalar& c); + +/** @brief Calculates sum of all matrix elements. + +The function sum calculates sum of all matrix elements, independently for each channel. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.sum" +@param src input matrix. +@sa min, max +*/ +GAPI_EXPORTS GScalar sum(const GMat& src); + +/** @brief Calculates the weighted sum of two matrices. + +The function addWeighted calculates the weighted sum of two matrices as follows: +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} )\f] +where I is a multi-dimensional index of array elements. In case of multi-channel matrices, each +channel is processed independently. + +The function can be replaced with a matrix expression: + \f[\texttt{dst}(I) = \texttt{alpha} * \texttt{src1}(I) - \texttt{beta} * \texttt{src2}(I) + \texttt{gamma} \f] + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.addweighted" +@param src1 first input matrix. +@param alpha weight of the first matrix elements. +@param src2 second input matrix of the same size and channel number as src1. +@param beta weight of the second matrix elements. +@param gamma scalar added to each sum. +@param ddepth optional depth of the output matrix. +@sa add, sub +*/ +GAPI_EXPORTS GMat addWeighted(const GMat& src1, double alpha, const GMat& src2, double beta, double gamma, int ddepth = -1); + +/** @brief Calculates the absolute L1 norm of a matrix. + +This version of normL1 calculates the absolute L1 norm of src. + +As example for one array consider the function \f$r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1]\f$. +The \f$ L_{1} \f$ norm for the sample value \f$r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix}\f$ +is calculated as follows +\f{align*} + \| r(-1) \|_{L_1} &= |-1| + |2| = 3 \\ +\f} +and for \f$r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix}\f$ the calculation is +\f{align*} + \| r(0.5) \|_{L_1} &= |0.5| + |0.5| = 1 \\ +\f} + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.norml1" +@param src input matrix. +@sa normL2, normInf +*/ +GAPI_EXPORTS GScalar normL1(const GMat& src); + +/** @brief Calculates the absolute L2 norm of a matrix. + +This version of normL2 calculates the absolute L2 norm of src. + +As example for one array consider the function \f$r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1]\f$. +The \f$ L_{2} \f$ norm for the sample value \f$r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix}\f$ +is calculated as follows +\f{align*} + \| r(-1) \|_{L_2} &= \sqrt{(-1)^{2} + (2)^{2}} = \sqrt{5} \\ +\f} +and for \f$r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix}\f$ the calculation is +\f{align*} + \| r(0.5) \|_{L_2} &= \sqrt{(0.5)^{2} + (0.5)^{2}} = \sqrt{0.5} \\ +\f} + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. +@note Function textual ID is "org.opencv.core.matrixop.norml2" +@param src input matrix. +@sa normL1, normInf +*/ +GAPI_EXPORTS GScalar normL2(const GMat& src); + +/** @brief Calculates the absolute infinite norm of a matrix. + +This version of normInf calculates the absolute infinite norm of src. + +As example for one array consider the function \f$r(x)= \begin{pmatrix} x \\ 1-x \end{pmatrix}, x \in [-1;1]\f$. +The \f$ L_{\infty} \f$ norm for the sample value \f$r(-1) = \begin{pmatrix} -1 \\ 2 \end{pmatrix}\f$ +is calculated as follows +\f{align*} + \| r(-1) \|_{L_\infty} &= \max(|-1|,|2|) = 2 +\f} +and for \f$r(0.5) = \begin{pmatrix} 0.5 \\ 0.5 \end{pmatrix}\f$ the calculation is +\f{align*} + \| r(0.5) \|_{L_\infty} &= \max(|0.5|,|0.5|) = 0.5. +\f} + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.core.matrixop.norminf" +@param src input matrix. +@sa normL1, normL2 +*/ +GAPI_EXPORTS GScalar normInf(const GMat& src); + +/** @brief Calculates the integral of an image. + +The function calculates one or more integral images for the source image as follows: + +\f[\texttt{sum} (X,Y) = \sum _{x integral(const GMat& src, int sdepth = -1, int sqdepth = -1); + +/** @brief Applies a fixed-level threshold to each matrix element. + +The function applies fixed-level thresholding to a single- or multiple-channel matrix. +The function is typically used to get a bi-level (binary) image out of a grayscale image ( cmp functions could be also used for +this purpose) or for removing a noise, that is, filtering out pixels with too small or too large +values. There are several depths of thresholding supported by the function. They are determined by +depth parameter. + +Also, the special values cv::THRESH_OTSU or cv::THRESH_TRIANGLE may be combined with one of the +above values. In these cases, the function determines the optimal threshold value using the Otsu's +or Triangle algorithm and uses it instead of the specified thresh . The function returns the +computed threshold value in addititon to thresholded matrix. +The Otsu's and Triangle methods are implemented only for 8-bit matrices. + +Input image should be single channel only in case of cv::THRESH_OTSU or cv::THRESH_TRIANGLE flags. +Output matrix must be of the same size and depth as src. + +@note Function textual ID is "org.opencv.core.matrixop.threshold" + +@param src input matrix (@ref CV_8UC1, @ref CV_8UC3, or @ref CV_32FC1). +@param thresh threshold value. +@param maxval maximum value to use with the cv::THRESH_BINARY and cv::THRESH_BINARY_INV thresholding +depths. +@param depth thresholding depth (see the cv::ThresholdTypes). + +@sa min, max, cmpGT, cmpLE, cmpGE, cmpLS + */ +GAPI_EXPORTS GMat threshold(const GMat& src, const GScalar& thresh, const GScalar& maxval, int depth); +/** @overload +This function appicable for all threshold depths except CV_THRESH_OTSU and CV_THRESH_TRIANGLE +@note Function textual ID is "org.opencv.core.matrixop.thresholdOT" +*/ +GAPI_EXPORTS std::tuple threshold(const GMat& src, const GScalar& maxval, int depth); + +/** @brief Applies a range-level threshold to each matrix element. + +The function applies range-level thresholding to a single- or multiple-channel matrix. +It sets output pixel value to OxFF if the corresponding pixel value of input matrix is in specified range,or 0 otherwise. + +Input and output matrices must be CV_8UC1. + +@note Function textual ID is "org.opencv.core.matrixop.inRange" + +@param src input matrix (CV_8UC1). +@param threshLow lower boundary value. +@param threshUp upper boundary value. + +@sa threshold + */ +GAPI_EXPORTS GMat inRange(const GMat& src, const GScalar& threshLow, const GScalar& threshUp); + +//! @} gapi_matrixop + +//! @addtogroup gapi_transform +//! @{ +/** @brief Resizes an image. + +The function resizes the image src down to or up to the specified size. + +Output image size will have the size dsize (when dsize is non-zero) or the size computed from +src.size(), fx, and fy; the depth of output is the same as of src. + +If you want to resize src so that it fits the pre-created dst, +you may call the function as follows: +@code + // explicitly specify dsize=dst.size(); fx and fy will be computed from that. + resize(src, dst, dst.size(), 0, 0, interpolation); +@endcode +If you want to decimate the image by factor of 2 in each direction, you can call the function this +way: +@code + // specify fx and fy and let the function compute the destination image size. + resize(src, dst, Size(), 0.5, 0.5, interpolation); +@endcode +To shrink an image, it will generally look best with cv::INTER_AREA interpolation, whereas to +enlarge an image, it will generally look best with cv::INTER_CUBIC (slow) or cv::INTER_LINEAR +(faster but still looks OK). + +@note Function textual ID is "org.opencv.core.transform.resize" + +@param src input image. +@param dsize output image size; if it equals zero, it is computed as: + \f[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\f] + Either dsize or both fx and fy must be non-zero. +@param fx scale factor along the horizontal axis; when it equals 0, it is computed as +\f[\texttt{(double)dsize.width/src.cols}\f] +@param fy scale factor along the vertical axis; when it equals 0, it is computed as +\f[\texttt{(double)dsize.height/src.rows}\f] +@param interpolation interpolation method, see cv::InterpolationFlags + +@sa warpAffine, warpPerspective, remap, resizeP + */ +GAPI_EXPORTS GMat resize(const GMat& src, const Size& dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR); + +/** @brief Resizes a planar image. + +The function resizes the image src down to or up to the specified size. +Planar image memory layout is three planes laying in the memory contiguously, +so the image height should be plane_height*plane_number, image type is @ref CV_8UC1. + +Output image size will have the size dsize, the depth of output is the same as of src. + +@note Function textual ID is "org.opencv.core.transform.resizeP" + +@param src input image, must be of @ref CV_8UC1 type; +@param dsize output image size; +@param interpolation interpolation method, only cv::INTER_LINEAR is supported at the moment + +@sa warpAffine, warpPerspective, remap, resize + */ +GAPI_EXPORTS GMatP resizeP(const GMatP& src, const Size& dsize, int interpolation = cv::INTER_LINEAR); + +/** @brief Creates one 3-channel (4-channel) matrix out of 3(4) single-channel ones. + +The function merges several matrices to make a single multi-channel matrix. That is, each +element of the output matrix will be a concatenation of the elements of the input matrices, where +elements of i-th input matrix are treated as mv[i].channels()-element vectors. +Input matrix must be of @ref CV_8UC3 (@ref CV_8UC4) type. + +The function split3/split4 does the reverse operation. + +@note Function textual ID for merge3 is "org.opencv.core.transform.merge3" +@note Function textual ID for merge4 is "org.opencv.core.transform.merge4" + +@param src1 first input matrix to be merged +@param src2 second input matrix to be merged +@param src3 third input matrix to be merged +@param src4 fourth input matrix to be merged +@sa split4, split3 +*/ +GAPI_EXPORTS GMat merge4(const GMat& src1, const GMat& src2, const GMat& src3, const GMat& src4); +GAPI_EXPORTS GMat merge3(const GMat& src1, const GMat& src2, const GMat& src3); + +/** @brief Divides a 3-channel (4-channel) matrix into 3(4) single-channel matrices. + +The function splits a 3-channel (4-channel) matrix into 3(4) single-channel matrices: +\f[\texttt{mv} [c](I) = \texttt{src} (I)_c\f] + +All output matrices must be in @ref CV_8UC1. + +@note Function textual for split3 ID is "org.opencv.core.transform.split3" +@note Function textual for split4 ID is "org.opencv.core.transform.split4" + +@param src input @ref CV_8UC4 (@ref CV_8UC3) matrix. +@sa merge3, merge4 +*/ +GAPI_EXPORTS std::tuple split4(const GMat& src); +GAPI_EXPORTS std::tuple split3(const GMat& src); + +/** @brief Applies a generic geometrical transformation to an image. + +The function remap transforms the source image using the specified map: + +\f[\texttt{dst} (x,y) = \texttt{src} (map_x(x,y),map_y(x,y))\f] + +where values of pixels with non-integer coordinates are computed using one of available +interpolation methods. \f$map_x\f$ and \f$map_y\f$ can be encoded as separate floating-point maps +in \f$map_1\f$ and \f$map_2\f$ respectively, or interleaved floating-point maps of \f$(x,y)\f$ in +\f$map_1\f$, or fixed-point maps created by using convertMaps. The reason you might want to +convert from floating to fixed-point representations of a map is that they can yield much faster +(\~2x) remapping operations. In the converted case, \f$map_1\f$ contains pairs (cvFloor(x), +cvFloor(y)) and \f$map_2\f$ contains indices in a table of interpolation coefficients. +Output image must be of the same size and depth as input one. + +@note Function textual ID is "org.opencv.core.transform.remap" + +@param src Source image. +@param map1 The first map of either (x,y) points or just x values having the type CV_16SC2, +CV_32FC1, or CV_32FC2. +@param map2 The second map of y values having the type CV_16UC1, CV_32FC1, or none (empty map +if map1 is (x,y) points), respectively. +@param interpolation Interpolation method (see cv::InterpolationFlags). The method INTER_AREA is +not supported by this function. +@param borderMode Pixel extrapolation method (see cv::BorderTypes). When +borderMode=BORDER_TRANSPARENT, it means that the pixels in the destination image that +corresponds to the "outliers" in the source image are not modified by the function. +@param borderValue Value used in case of a constant border. By default, it is 0. +@note +Due to current implementation limitations the size of an input and output images should be less than 32767x32767. + */ +GAPI_EXPORTS GMat remap(const GMat& src, const Mat& map1, const Mat& map2, + int interpolation, int borderMode = BORDER_CONSTANT, + const Scalar& borderValue = Scalar()); + +/** @brief Flips a 2D matrix around vertical, horizontal, or both axes. + +The function flips the matrix in one of three different ways (row +and column indices are 0-based): +\f[\texttt{dst} _{ij} = +\left\{ +\begin{array}{l l} +\texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\ +\texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\ +\texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\ +\end{array} +\right.\f] +The example scenarios of using the function are the following: +* Vertical flipping of the image (flipCode == 0) to switch between + top-left and bottom-left image origin. This is a typical operation + in video processing on Microsoft Windows\* OS. +* Horizontal flipping of the image with the subsequent horizontal + shift and absolute difference calculation to check for a + vertical-axis symmetry (flipCode \> 0). +* Simultaneous horizontal and vertical flipping of the image with + the subsequent shift and absolute difference calculation to check + for a central symmetry (flipCode \< 0). +* Reversing the order of point arrays (flipCode \> 0 or + flipCode == 0). +Output image must be of the same depth as input one, size should be correct for given flipCode. + +@note Function textual ID is "org.opencv.core.transform.flip" + +@param src input matrix. +@param flipCode a flag to specify how to flip the array; 0 means +flipping around the x-axis and positive value (for example, 1) means +flipping around y-axis. Negative value (for example, -1) means flipping +around both axes. +@sa remap +*/ +GAPI_EXPORTS GMat flip(const GMat& src, int flipCode); + +/** @brief Crops a 2D matrix. + +The function crops the matrix by given cv::Rect. + +Output matrix must be of the same depth as input one, size is specified by given rect size. + +@note Function textual ID is "org.opencv.core.transform.crop" + +@param src input matrix. +@param rect a rect to crop a matrix to +@sa resize +*/ +GAPI_EXPORTS GMat crop(const GMat& src, const Rect& rect); + +/** @brief Applies horizontal concatenation to given matrices. + +The function horizontally concatenates two GMat matrices (with the same number of rows). +@code{.cpp} + GMat A = { 1, 4, + 2, 5, + 3, 6 }; + GMat B = { 7, 10, + 8, 11, + 9, 12 }; + + GMat C = gapi::concatHor(A, B); + //C: + //[1, 4, 7, 10; + // 2, 5, 8, 11; + // 3, 6, 9, 12] +@endcode +Output matrix must the same number of rows and depth as the src1 and src2, and the sum of cols of the src1 and src2. +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.imgproc.transform.concatHor" + +@param src1 first input matrix to be considered for horizontal concatenation. +@param src2 second input matrix to be considered for horizontal concatenation. +@sa concatVert +*/ +GAPI_EXPORTS GMat concatHor(const GMat& src1, const GMat& src2); + +/** @overload +The function horizontally concatenates given number of GMat matrices (with the same number of columns). +Output matrix must the same number of columns and depth as the input matrices, and the sum of rows of input matrices. + +@param v vector of input matrices to be concatenated horizontally. +*/ +GAPI_EXPORTS GMat concatHor(const std::vector &v); + +/** @brief Applies vertical concatenation to given matrices. + +The function vertically concatenates two GMat matrices (with the same number of cols). + @code{.cpp} + GMat A = { 1, 7, + 2, 8, + 3, 9 }; + GMat B = { 4, 10, + 5, 11, + 6, 12 }; + + GMat C = gapi::concatVert(A, B); + //C: + //[1, 7; + // 2, 8; + // 3, 9; + // 4, 10; + // 5, 11; + // 6, 12] + @endcode + +Output matrix must the same number of cols and depth as the src1 and src2, and the sum of rows of the src1 and src2. +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. + +@note Function textual ID is "org.opencv.imgproc.transform.concatVert" + +@param src1 first input matrix to be considered for vertical concatenation. +@param src2 second input matrix to be considered for vertical concatenation. +@sa concatHor +*/ +GAPI_EXPORTS GMat concatVert(const GMat& src1, const GMat& src2); + +/** @overload +The function vertically concatenates given number of GMat matrices (with the same number of columns). +Output matrix must the same number of columns and depth as the input matrices, and the sum of rows of input matrices. + +@param v vector of input matrices to be concatenated vertically. +*/ +GAPI_EXPORTS GMat concatVert(const std::vector &v); + + +/** @brief Performs a look-up table transform of a matrix. + +The function LUT fills the output matrix with values from the look-up table. Indices of the entries +are taken from the input matrix. That is, the function processes each element of src as follows: +\f[\texttt{dst} (I) \leftarrow \texttt{lut(src(I))}\f] + +Supported matrix data types are @ref CV_8UC1. +Output is a matrix of the same size and number of channels as src, and the same depth as lut. + +@note Function textual ID is "org.opencv.core.transform.LUT" + +@param src input matrix of 8-bit elements. +@param lut look-up table of 256 elements; in case of multi-channel input array, the table should +either have a single channel (in this case the same table is used for all channels) or the same +number of channels as in the input matrix. +*/ +GAPI_EXPORTS GMat LUT(const GMat& src, const Mat& lut); + +/** @brief Converts a matrix to another data depth with optional scaling. + +The method converts source pixel values to the target data depth. saturate_cast\<\> is applied at +the end to avoid possible overflows: + +\f[m(x,y) = saturate \_ cast( \alpha (*this)(x,y) + \beta )\f] +Output matrix must be of the same size as input one. + +@note Function textual ID is "org.opencv.core.transform.convertTo" +@param src input matrix to be converted from. +@param rdepth desired output matrix depth or, rather, the depth since the number of channels are the +same as the input has; if rdepth is negative, the output matrix will have the same depth as the input. +@param alpha optional scale factor. +@param beta optional delta added to the scaled values. + */ +GAPI_EXPORTS GMat convertTo(const GMat& src, int rdepth, double alpha=1, double beta=0); + +/** @brief Normalizes the norm or value range of an array. + +The function normalizes scale and shift the input array elements so that +\f[\| \texttt{dst} \| _{L_p}= \texttt{alpha}\f] +(where p=Inf, 1 or 2) when normType=NORM_INF, NORM_L1, or NORM_L2, respectively; or so that +\f[\min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta}\f] +when normType=NORM_MINMAX (for dense arrays only). + +@note Function textual ID is "org.opencv.core.normalize" + +@param src input array. +@param alpha norm value to normalize to or the lower range boundary in case of the range +normalization. +@param beta upper range boundary in case of the range normalization; it is not used for the norm +normalization. +@param norm_type normalization type (see cv::NormTypes). +@param ddepth when negative, the output array has the same type as src; otherwise, it has the same +number of channels as src and the depth =ddepth. +@sa norm, Mat::convertTo +*/ +GAPI_EXPORTS GMat normalize(const GMat& src, double alpha, double beta, + int norm_type, int ddepth = -1); +//! @} gapi_transform + +} //namespace gapi +} //namespace cv + +#endif //OPENCV_GAPI_CORE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/core.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/core.hpp new file mode 100755 index 0000000..ffd3596 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/core.hpp @@ -0,0 +1,27 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_CPU_CORE_API_HPP +#define OPENCV_GAPI_CPU_CORE_API_HPP + +#include // GKernelPackage +#include // GAPI_EXPORTS + +namespace cv { +namespace gapi { +namespace core { +namespace cpu { + +GAPI_EXPORTS GKernelPackage kernels(); + +} // namespace cpu +} // namespace core +} // namespace gapi +} // namespace cv + + +#endif // OPENCV_GAPI_CPU_CORE_API_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/gcpukernel.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/gcpukernel.hpp new file mode 100755 index 0000000..4205776 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/gcpukernel.hpp @@ -0,0 +1,278 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018-2019 Intel Corporation + + +#ifndef OPENCV_GAPI_GCPUKERNEL_HPP +#define OPENCV_GAPI_GCPUKERNEL_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include //to_ocv +#include //suppress_unused_warning +#include + +// FIXME: namespace scheme for backends? +namespace cv { + +namespace gimpl +{ + // Forward-declare an internal class + class GCPUExecutable; +} // namespace gimpl + +namespace gapi +{ +namespace cpu +{ + /** + * \addtogroup gapi_std_backends + * @{ + * + * @brief G-API backends available in this OpenCV version + * + * G-API backends play a corner stone role in G-API execution + * stack. Every backend is hardware-oriented and thus can run its + * kernels efficiently on the target platform. + * + * Backends are usually "black boxes" for G-API users -- on the API + * side, all backends are represented as different objects of the + * same class cv::gapi::GBackend. + * User can manipulate with backends by specifying which kernels to use. + * + * @sa @ref gapi_hld + */ + + /** + * @brief Get a reference to CPU (OpenCV) backend. + * + * This is the default backend in G-API at the moment, providing + * broader functional coverage but losing some graph model + * advantages. Provided mostly for reference and prototyping + * purposes. + * + * @sa gapi_std_backends + */ + GAPI_EXPORTS cv::gapi::GBackend backend(); + /** @} */ +} // namespace cpu +} // namespace gapi + +// Represents arguments which are passed to a wrapped CPU function +// FIXME: put into detail? +class GAPI_EXPORTS GCPUContext +{ +public: + // Generic accessor API + template + const T& inArg(int input) { return m_args.at(input).get(); } + + // Syntax sugar + const cv::gapi::own::Mat& inMat(int input); + cv::gapi::own::Mat& outMatR(int output); // FIXME: Avoid cv::gapi::own::Mat m = ctx.outMatR() + + const cv::gapi::own::Scalar& inVal(int input); + cv::gapi::own::Scalar& outValR(int output); // FIXME: Avoid cv::gapi::own::Scalar s = ctx.outValR() + template std::vector& outVecR(int output) // FIXME: the same issue + { + return outVecRef(output).wref(); + } + +protected: + detail::VectorRef& outVecRef(int output); + + std::vector m_args; + + //FIXME: avoid conversion of arguments from internal representaion to OpenCV one on each call + //to OCV kernel. (This can be achieved by a two single time conversions in GCPUExecutable::run, + //once on enter for input and output arguments, and once before return for output arguments only + std::unordered_map m_results; + + friend class gimpl::GCPUExecutable; +}; + +class GAPI_EXPORTS GCPUKernel +{ +public: + // This function is kernel's execution entry point (does the processing work) + using F = std::function; + + GCPUKernel(); + explicit GCPUKernel(const F& f); + + void apply(GCPUContext &ctx); + +protected: + F m_f; +}; + +// FIXME: This is an ugly ad-hoc imlpementation. TODO: refactor + +namespace detail +{ +template struct get_in; +template<> struct get_in +{ + static cv::Mat get(GCPUContext &ctx, int idx) { return to_ocv(ctx.inMat(idx)); } +}; +template<> struct get_in +{ + static cv::Mat get(GCPUContext &ctx, int idx) { return get_in::get(ctx, idx); } +}; +template<> struct get_in +{ + static cv::Scalar get(GCPUContext &ctx, int idx) { return to_ocv(ctx.inVal(idx)); } +}; +template struct get_in > +{ + static const std::vector& get(GCPUContext &ctx, int idx) { return ctx.inArg(idx).rref(); } +}; +template struct get_in +{ + static T get(GCPUContext &ctx, int idx) { return ctx.inArg(idx); } +}; + +struct tracked_cv_mat{ + tracked_cv_mat(cv::gapi::own::Mat& m) : r{to_ocv(m)}, original_data{m.data} {} + cv::Mat r; + uchar* original_data; + + operator cv::Mat& (){ return r;} + void validate() const{ + if (r.data != original_data) + { + util::throw_error + (std::logic_error + ("OpenCV kernel output parameter was reallocated. \n" + "Incorrect meta data was provided ?")); + } + } +}; + +struct scalar_wrapper +{ + scalar_wrapper(cv::gapi::own::Scalar& s) : m_s{cv::gapi::own::to_ocv(s)}, m_org_s(s) {}; + operator cv::Scalar& () { return m_s; } + void writeBack() const { m_org_s = to_own(m_s); } + + cv::Scalar m_s; + cv::gapi::own::Scalar& m_org_s; +}; + +template +void postprocess(Outputs&... outs) +{ + struct + { + void operator()(tracked_cv_mat* bm) { bm->validate(); } + void operator()(scalar_wrapper* sw) { sw->writeBack(); } + void operator()(...) { } + + } validate; + //dummy array to unfold parameter pack + int dummy[] = { 0, (validate(&outs), 0)... }; + cv::util::suppress_unused_warning(dummy); +} + +template struct get_out; +template<> struct get_out +{ + static tracked_cv_mat get(GCPUContext &ctx, int idx) + { + auto& r = ctx.outMatR(idx); + return {r}; + } +}; +template<> struct get_out +{ + static tracked_cv_mat get(GCPUContext &ctx, int idx) + { + return get_out::get(ctx, idx); + } +}; +template<> struct get_out +{ + static scalar_wrapper get(GCPUContext &ctx, int idx) + { + auto& s = ctx.outValR(idx); + return {s}; + } +}; +template struct get_out> +{ + static std::vector& get(GCPUContext &ctx, int idx) + { + return ctx.outVecR(idx); + } +}; + +template +struct OCVCallHelper; + +// FIXME: probably can be simplified with std::apply or analogue. +template +struct OCVCallHelper, std::tuple > +{ + template + struct call_and_postprocess + { + template + static void call(Inputs&&... ins, Outputs&&... outs) + { + //not using a std::forward on outs is deliberate in order to + //cause compilation error, by tring to bind rvalue references to lvalue references + Impl::run(std::forward(ins)..., outs...); + + postprocess(outs...); + } + }; + + template + static void call_impl(GCPUContext &ctx, detail::Seq, detail::Seq) + { + //Make sure that OpenCV kernels do not reallocate memory for output parameters + //by comparing it's state (data ptr) before and after the call. + //This is done by converting each output Mat into tracked_cv_mat object, and binding + //them to parameters of ad-hoc function + //Convert own::Scalar to cv::Scalar before call kernel and run kernel + //convert cv::Scalar to own::Scalar after call kernel and write back results + call_and_postprocess::get(ctx, IIs))...>::call(get_in::get(ctx, IIs)..., get_out::get(ctx, OIs)...); + } + + static void call(GCPUContext &ctx) + { + call_impl(ctx, + typename detail::MkSeq::type(), + typename detail::MkSeq::type()); + } +}; + +} // namespace detail + +template +class GCPUKernelImpl: public cv::detail::OCVCallHelper, + public cv::detail::KernelTag +{ + using P = detail::OCVCallHelper; + +public: + using API = K; + + static cv::gapi::GBackend backend() { return cv::gapi::cpu::backend(); } + static cv::GCPUKernel kernel() { return GCPUKernel(&P::call); } +}; + +#define GAPI_OCV_KERNEL(Name, API) struct Name: public cv::GCPUKernelImpl + +} // namespace cv + +#endif // OPENCV_GAPI_GCPUKERNEL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/imgproc.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/imgproc.hpp new file mode 100755 index 0000000..0b96db0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/cpu/imgproc.hpp @@ -0,0 +1,27 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_CPU_IMGPROC_API_HPP +#define OPENCV_GAPI_CPU_IMGPROC_API_HPP + +#include // GAPI_EXPORTS +#include // GKernelPackage + +namespace cv { +namespace gapi { +namespace imgproc { +namespace cpu { + +GAPI_EXPORTS GKernelPackage kernels(); + +} // namespace cpu +} // namespace imgproc +} // namespace gapi +} // namespace cv + + +#endif // OPENCV_GAPI_CPU_IMGPROC_API_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/core.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/core.hpp new file mode 100755 index 0000000..8c21f57 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/core.hpp @@ -0,0 +1,20 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_FLUID_CORE_HPP +#define OPENCV_GAPI_FLUID_CORE_HPP + +#include // GKernelPackage +#include // GAPI_EXPORTS + +namespace cv { namespace gapi { namespace core { namespace fluid { + +GAPI_EXPORTS GKernelPackage kernels(); + +}}}} + +#endif // OPENCV_GAPI_FLUID_CORE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidbuffer.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidbuffer.hpp new file mode 100755 index 0000000..a5dd4a6 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidbuffer.hpp @@ -0,0 +1,154 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_FLUID_BUFFER_HPP +#define OPENCV_GAPI_FLUID_BUFFER_HPP + +#include +#include // accumulate +#include // ostream +#include // uint8_t + +#include +#include +#include + +#include +#include +#include + +namespace cv { +namespace gapi { +namespace fluid { + +struct Border +{ +#if !defined(GAPI_STANDALONE) + // This constructor is required to support existing kernels which are part of G-API + Border(int _type, cv::Scalar _val) : type(_type), value(to_own(_val)) {}; +#endif // !defined(GAPI_STANDALONE) + Border(int _type, cv::gapi::own::Scalar _val) : type(_type), value(_val) {}; + int type; + cv::gapi::own::Scalar value; +}; + +using BorderOpt = util::optional; + +bool operator == (const Border& b1, const Border& b2); + +class GAPI_EXPORTS Buffer; + +class GAPI_EXPORTS View +{ +public: + struct Cache + { + std::vector m_linePtrs; + GMatDesc m_desc; + int m_border_size = 0; + + inline const uint8_t* linePtr(int index) const + { + // "out_of_window" check: + // user must not request the lines which are outside of specified kernel window + GAPI_DbgAssert(index >= -m_border_size + && index < -m_border_size + static_cast(m_linePtrs.size())); + return m_linePtrs[index + m_border_size]; + } + }; + + View() = default; + + const inline uint8_t* InLineB(int index) const // -(w-1)/2...0...+(w-1)/2 for Filters + { + return m_cache->linePtr(index); + } + + template const inline T* InLine(int i) const + { + const uint8_t* ptr = this->InLineB(i); + return reinterpret_cast(ptr); + } + + inline operator bool() const { return m_priv != nullptr; } + bool ready() const; + inline int length() const { return m_cache->m_desc.size.width; } + int y() const; + + inline const GMatDesc& meta() const { return m_cache->m_desc; } + + class GAPI_EXPORTS Priv; // internal use only + Priv& priv(); // internal use only + const Priv& priv() const; // internal use only + + View(Priv* p); + +private: + std::shared_ptr m_priv; + const Cache* m_cache; +}; + +class GAPI_EXPORTS Buffer +{ +public: + struct Cache + { + std::vector m_linePtrs; + GMatDesc m_desc; + }; + + // Default constructor (executable creation stage, + // all following initialization performed in Priv::init()) + Buffer(); + // Scratch constructor (user kernels) + Buffer(const cv::GMatDesc &desc); + + // Constructor for intermediate buffers (for tests) + Buffer(const cv::GMatDesc &desc, + int max_line_consumption, int border_size, + int skew, + int wlpi, + BorderOpt border); + // Constructor for in/out buffers (for tests) + Buffer(const cv::gapi::own::Mat &data, bool is_input); + + inline uint8_t* OutLineB(int index = 0) + { + return m_cache->m_linePtrs[index]; + } + + template inline T* OutLine(int index = 0) + { + uint8_t* ptr = this->OutLineB(index); + return reinterpret_cast(ptr); + } + + int y() const; + + int linesReady() const; + void debug(std::ostream &os) const; + inline int length() const { return m_cache->m_desc.size.width; } + int lpi() const; // LPI for WRITER + + inline const GMatDesc& meta() const { return m_cache->m_desc; } + + View mkView(int borderSize, bool ownStorage); + + class GAPI_EXPORTS Priv; // internal use only + Priv& priv(); // internal use only + const Priv& priv() const; // internal use only + +private: + std::shared_ptr m_priv; + const Cache* m_cache; +}; + +} // namespace cv::gapi::fluid +} // namespace cv::gapi +} // namespace cv + +#endif // OPENCV_GAPI_FLUID_BUFFER_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidkernel.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidkernel.hpp new file mode 100755 index 0000000..1d8bfd8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/gfluidkernel.hpp @@ -0,0 +1,303 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018-2019 Intel Corporation + + +#ifndef OPENCV_GAPI_FLUID_KERNEL_HPP +#define OPENCV_GAPI_FLUID_KERNEL_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// FIXME: namespace scheme for backends? +namespace cv { + +namespace gapi +{ +namespace fluid +{ + /** + * \addtogroup gapi_std_backends G-API Standard backends + * @{ + */ + /** + * @brief Get a reference to Fluid backend. + * + * @sa gapi_std_backends + */ + GAPI_EXPORTS cv::gapi::GBackend backend(); + /** @} */ +} // namespace flud +} // namespace gapi + + +class GAPI_EXPORTS GFluidKernel +{ +public: + enum class Kind + { + Filter, + Resize, + NV12toRGB + }; + + // This function is a generic "doWork" callback + using F = std::function &)>; + + // This function is a generic "initScratch" callback + using IS = std::function; + + // This function is a generic "resetScratch" callback + using RS = std::function; + + // This function describes kernel metadata inference rule. + using M = std::function; + + // This function is a generic "getBorder" callback (extracts border-related data from kernel's input parameters) + using B = std::function; + + // FIXME: move implementations out of header file + GFluidKernel() {} + GFluidKernel(int w, Kind k, int l, bool scratch, const F& f, const IS &is, const RS &rs, const B& b) + : m_window(w) + , m_kind(k) + , m_lpi(l) + , m_scratch(scratch) + , m_f(f) + , m_is(is) + , m_rs(rs) + , m_b(b) {} + + int m_window = -1; + Kind m_kind; + const int m_lpi = -1; + const bool m_scratch = false; + + const F m_f; + const IS m_is; + const RS m_rs; + const B m_b; +}; + +// FIXME!!! +// This is the temporary and experimental API +// which should be replaced by runtime roi-based scheduling +struct GFluidOutputRois +{ + std::vector rois; +}; + +namespace detail +{ +template<> struct CompileArgTag +{ + static const char* tag() { return "gapi.fluid.outputRois"; } +}; +} // namespace detail + +namespace detail +{ +template struct fluid_get_in; +template<> struct fluid_get_in +{ + static const cv::gapi::fluid::View& get(const cv::GArgs &in_args, int idx) + { + return in_args[idx].unsafe_get(); + } +}; + +template<> struct fluid_get_in +{ + // FIXME: change to return by reference when moved to own::Scalar +#if !defined(GAPI_STANDALONE) + static const cv::Scalar get(const cv::GArgs &in_args, int idx) + { + return cv::gapi::own::to_ocv(in_args[idx].unsafe_get()); + } +#else + static const cv::gapi::own::Scalar get(const cv::GArgs &in_args, int idx) + { + return in_args[idx].get(); + } +#endif // !defined(GAPI_STANDALONE) +}; +template struct fluid_get_in +{ + static const T& get(const cv::GArgs &in_args, int idx) + { + return in_args[idx].unsafe_get(); + } +}; + +template +struct scratch_helper; + +template +struct scratch_helper +{ + // Init + template + static void help_init_impl(const cv::GMetaArgs &metas, + const cv::GArgs &in_args, + gapi::fluid::Buffer &scratch_buf, + detail::Seq) + { + Impl::initScratch(get_in_meta(metas, in_args, IIs)..., scratch_buf); + } + + static void help_init(const cv::GMetaArgs &metas, + const cv::GArgs &in_args, + gapi::fluid::Buffer &b) + { + help_init_impl(metas, in_args, b, typename detail::MkSeq::type()); + } + + // Reset + static void help_reset(gapi::fluid::Buffer &b) + { + Impl::resetScratch(b); + } +}; + +template +struct scratch_helper +{ + static void help_init(const cv::GMetaArgs &, + const cv::GArgs &, + gapi::fluid::Buffer &) + { + GAPI_Assert(false); + } + static void help_reset(gapi::fluid::Buffer &) + { + GAPI_Assert(false); + } +}; + +template struct is_gmat_type +{ + static const constexpr bool value = std::is_same::value; +}; + +template +struct get_border_helper; + +template +struct get_border_helper +{ + template + static gapi::fluid::BorderOpt get_border_impl(const GMetaArgs &metas, + const cv::GArgs &in_args, + cv::detail::Seq) + { + return util::make_optional(Impl::getBorder(cv::detail::get_in_meta(metas, in_args, IIs)...)); + } + + static gapi::fluid::BorderOpt help(const GMetaArgs &metas, + const cv::GArgs &in_args) + { + return get_border_impl(metas, in_args, typename detail::MkSeq::type()); + } +}; + +template +struct get_border_helper +{ + static gapi::fluid::BorderOpt help(const cv::GMetaArgs &, + const cv::GArgs &) + { + return {}; + } +}; + +template +struct FluidCallHelper; + +template +struct FluidCallHelper, std::tuple, UseScratch> +{ + static_assert(all_satisfy::value, "return type must be GMat"); + + // Execution dispatcher //////////////////////////////////////////////////// + template + static void call_impl(const cv::GArgs &in_args, + const std::vector &out_bufs, + detail::Seq, + detail::Seq) + { + Impl::run(fluid_get_in::get(in_args, IIs)..., *out_bufs[OIs]...); + } + + static void call(const cv::GArgs &in_args, + const std::vector &out_bufs) + { + constexpr int numOuts = (sizeof...(Outs)) + (UseScratch ? 1 : 0); + call_impl(in_args, out_bufs, + typename detail::MkSeq::type(), + typename detail::MkSeq::type()); + } + + // Scratch buffer initialization dispatcher //////////////////////////////// + static void init_scratch(const GMetaArgs &metas, + const cv::GArgs &in_args, + gapi::fluid::Buffer &b) + { + scratch_helper::help_init(metas, in_args, b); + } + + // Scratch buffer reset dispatcher ///////////////////////////////////////// + static void reset_scratch(gapi::fluid::Buffer &scratch_buf) + { + scratch_helper::help_reset(scratch_buf); + } + + static gapi::fluid::BorderOpt getBorder(const GMetaArgs &metas, const cv::GArgs &in_args) + { + // User must provide "init" callback if Window != 1 + // TODO: move to constexpr if when we enable C++17 + constexpr bool callCustomGetBorder = (Impl::Window != 1); + return get_border_helper::help(metas, in_args); + } +}; +} // namespace detail + + +template +class GFluidKernelImpl : public cv::detail::KernelTag +{ + static const int LPI = 1; + static const auto Kind = GFluidKernel::Kind::Filter; + using P = detail::FluidCallHelper; + +public: + using API = K; + + static GFluidKernel kernel() + { + // FIXME: call() and getOutMeta() needs to be renamed so it is clear these + // functions are internal wrappers, not user API + return GFluidKernel(Impl::Window, Impl::Kind, Impl::LPI, + UseScratch, + &P::call, &P::init_scratch, &P::reset_scratch, &P::getBorder); + } + + static cv::gapi::GBackend backend() { return cv::gapi::fluid::backend(); } +}; + +#define GAPI_FLUID_KERNEL(Name, API, Scratch) struct Name: public cv::GFluidKernelImpl + +} // namespace cv + +#endif // OPENCV_GAPI_GCPUKERNEL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/imgproc.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/imgproc.hpp new file mode 100755 index 0000000..dedfa9d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/fluid/imgproc.hpp @@ -0,0 +1,20 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_FLUID_IMGPROC_HPP +#define OPENCV_GAPI_FLUID_IMGPROC_HPP + +#include // GKernelPackage +#include // GAPI_EXPORTS + +namespace cv { namespace gapi { namespace imgproc { namespace fluid { + +GAPI_EXPORTS GKernelPackage kernels(); + +}}}} + +#endif // OPENCV_GAPI_FLUID_IMGPROC_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/garg.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/garg.hpp new file mode 100755 index 0000000..8f912aa --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/garg.hpp @@ -0,0 +1,126 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GARG_HPP +#define OPENCV_GAPI_GARG_HPP + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace cv { + +class GArg; + +namespace detail { + template + using is_garg = std::is_same::type>; +} + +// Parameter holder class for a node +// Depending on platform capabilities, can either support arbitrary types +// (as `boost::any`) or a limited number of types (as `boot::variant`). +// FIXME: put into "details" as a user shouldn't use it in his code +class GAPI_EXPORTS GArg +{ +public: + GArg() {} + + template::value, int>::type = 0> + explicit GArg(const T &t) + : kind(detail::GTypeTraits::kind) + , value(detail::wrap_gapi_helper::wrap(t)) + { + } + + template::value, int>::type = 0> + explicit GArg(T &&t) + : kind(detail::GTypeTraits::type>::kind) + , value(detail::wrap_gapi_helper::wrap(t)) + { + } + + template inline T& get() + { + return util::any_cast::type>(value); + } + + template inline const T& get() const + { + return util::any_cast::type>(value); + } + + template inline T& unsafe_get() + { + return util::unsafe_any_cast::type>(value); + } + + template inline const T& unsafe_get() const + { + return util::unsafe_any_cast::type>(value); + } + + detail::ArgKind kind = detail::ArgKind::OPAQUE; + +protected: + util::any value; +}; + +using GArgs = std::vector; + +// FIXME: Express as M::type +// FIXME: Move to a separate file! +using GRunArg = util::variant< +#if !defined(GAPI_STANDALONE) + cv::Mat, + cv::Scalar, + cv::UMat, +#endif // !defined(GAPI_STANDALONE) + cv::gapi::own::Mat, + cv::gapi::own::Scalar, + cv::detail::VectorRef + >; +using GRunArgs = std::vector; + +using GRunArgP = util::variant< +#if !defined(GAPI_STANDALONE) + cv::Mat*, + cv::Scalar*, + cv::UMat*, +#endif // !defined(GAPI_STANDALONE) + cv::gapi::own::Mat*, + cv::gapi::own::Scalar*, + cv::detail::VectorRef + >; +using GRunArgsP = std::vector; + + +template inline GRunArgs gin(const Ts&... args) +{ + return GRunArgs{ GRunArg(detail::wrap_host_helper::wrap_in(args))... }; +} + +template inline GRunArgsP gout(Ts&... args) +{ + return GRunArgsP{ GRunArgP(detail::wrap_host_helper::wrap_out(args))... }; +} + +} // namespace cv + +#endif // OPENCV_GAPI_GARG_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/garray.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/garray.hpp new file mode 100755 index 0000000..e818f0a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/garray.hpp @@ -0,0 +1,251 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GARRAY_HPP +#define OPENCV_GAPI_GARRAY_HPP + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace cv +{ +// Forward declaration; GNode and GOrigin are an internal +// (user-inaccessible) classes. +class GNode; +struct GOrigin; + +template class GArray; + +/** + * \addtogroup gapi_meta_args + * @{ + */ +struct GArrayDesc +{ + // FIXME: Body + // FIXME: Also implement proper operator== then + bool operator== (const GArrayDesc&) const { return true; } +}; +template GArrayDesc descr_of(const std::vector &) { return {};} +static inline GArrayDesc empty_array_desc() {return {}; } +/** @} */ + +std::ostream& operator<<(std::ostream& os, const cv::GArrayDesc &desc); + +namespace detail +{ + // ConstructVec is a callback which stores information about T and is used by + // G-API runtime to construct arrays in host memory (T remains opaque for G-API). + // ConstructVec is carried into G-API internals by GArrayU. + // Currently it is suitable for Host (CPU) plugins only, real offload may require + // more information for manual memory allocation on-device. + class VectorRef; + using ConstructVec = std::function; + + + // This class strips type information from GArray and makes it usable + // in the G-API graph compiler (expression unrolling, graph generation, etc). + // Part of GProtoArg. + class GAPI_EXPORTS GArrayU + { + public: + GArrayU(const GNode &n, std::size_t out); // Operation result constructor + + GOrigin& priv(); // Internal use only + const GOrigin& priv() const; // Internal use only + + protected: + GArrayU(); // Default constructor + template friend class cv::GArray; // (avialable to GArray only) + + void setConstructFcn(ConstructVec &&cv); // Store T-aware constructor + + std::shared_ptr m_priv; + }; + + // This class represents a typed STL vector reference. + // Depending on origins, this reference may be either "just a" reference to + // an object created externally, OR actually own the underlying object + // (be value holder). + class BasicVectorRef + { + public: + std::size_t m_elemSize = 0ul; + cv::GArrayDesc m_desc; + virtual ~BasicVectorRef() {} + }; + + template class VectorRefT: public BasicVectorRef + { + using empty_t = util::monostate; + using ro_ext_t = const std::vector *; + using rw_ext_t = std::vector *; + using rw_own_t = std::vector ; + util::variant m_ref; + + inline bool isEmpty() const { return util::holds_alternative(m_ref); } + inline bool isROExt() const { return util::holds_alternative(m_ref); } + inline bool isRWExt() const { return util::holds_alternative(m_ref); } + inline bool isRWOwn() const { return util::holds_alternative(m_ref); } + + void init(const std::vector* vec = nullptr) + { + m_elemSize = sizeof(T); + if (vec) m_desc = cv::descr_of(*vec); + } + + public: + VectorRefT() { init(); } + virtual ~VectorRefT() {} + + explicit VectorRefT(const std::vector& vec) : m_ref(&vec) { init(&vec); } + explicit VectorRefT(std::vector& vec) : m_ref(&vec) { init(&vec); } + explicit VectorRefT(std::vector&& vec) : m_ref(std::move(vec)) { init(&vec); } + + // Reset a VectorRefT. Called only for objects instantiated + // internally in G-API (e.g. temporary GArray's within a + // computation). Reset here means both initialization + // (creating an object) and reset (discarding its existing + // content before the next execution). Must never be called + // for external VectorRefTs. + void reset() + { + if (isEmpty()) + { + std::vector empty_vector; + m_desc = cv::descr_of(empty_vector); + m_ref = std::move(empty_vector); + GAPI_Assert(isRWOwn()); + } + else if (isRWOwn()) + { + util::get(m_ref).clear(); + } + else GAPI_Assert(false); // shouldn't be called in *EXT modes + } + + // Obtain a WRITE reference to underlying object + // Used by CPU kernel API wrappers when a kernel execution frame + // is created + std::vector& wref() + { + GAPI_Assert(isRWExt() || isRWOwn()); + if (isRWExt()) return *util::get(m_ref); + if (isRWOwn()) return util::get(m_ref); + util::throw_error(std::logic_error("Impossible happened")); + } + + // Obtain a READ reference to underlying object + // Used by CPU kernel API wrappers when a kernel execution frame + // is created + const std::vector& rref() const + { + // ANY vector can be accessed for reading, even if it declared for + // output. Example -- a GComputation from [in] to [out1,out2] + // where [out2] is a result of operation applied to [out1]: + // + // GComputation boundary + // . . . . . . . + // . . + // [in] ----> foo() ----> [out1] + // . . : + // . . . .:. . . + // . V . + // . bar() ---> [out2] + // . . . . . . . . . . . . + // + if (isROExt()) return *util::get(m_ref); + if (isRWExt()) return *util::get(m_ref); + if (isRWOwn()) return util::get(m_ref); + util::throw_error(std::logic_error("Impossible happened")); + } + }; + + // This class strips type information from VectorRefT<> and makes it usable + // in the G-API executables (carrying run-time data/information to kernels). + // Part of GRunArg. + // Its methods are typed proxies to VectorRefT. + // VectorRef maintains "reference" semantics so two copies of VectoRef refer + // to the same underlying object. + // FIXME: Put a good explanation on why cv::OutputArray doesn't fit this role + class VectorRef + { + std::shared_ptr m_ref; + + template inline void check() const + { + GAPI_DbgAssert(dynamic_cast*>(m_ref.get()) != nullptr); + GAPI_Assert(sizeof(T) == m_ref->m_elemSize); + } + + public: + VectorRef() = default; + template explicit VectorRef(const std::vector& vec) : m_ref(new VectorRefT(vec)) {} + template explicit VectorRef(std::vector& vec) : m_ref(new VectorRefT(vec)) {} + template explicit VectorRef(std::vector&& vec) : m_ref(new VectorRefT(vec)) {} + + template void reset() + { + if (!m_ref) m_ref.reset(new VectorRefT()); + + check(); + static_cast&>(*m_ref).reset(); + } + + template std::vector& wref() + { + check(); + return static_cast&>(*m_ref).wref(); + } + + template const std::vector& rref() const + { + check(); + return static_cast&>(*m_ref).rref(); + } + + cv::GArrayDesc descr_of() const + { + return m_ref->m_desc; + } + }; +} // namespace detail + +/** \addtogroup gapi_data_objects + * @{ + */ + +template class GArray +{ +public: + GArray() { putDetails(); } // Empty constructor + explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor + : m_ref(ref) { putDetails(); } // (used by GCall, not for users) + + detail::GArrayU strip() const { return m_ref; } + +private: + static void VCTor(detail::VectorRef& vref) { vref.reset(); } + void putDetails() {m_ref.setConstructFcn(&VCTor); } + + detail::GArrayU m_ref; +}; + +/** @} */ + +} // namespace cv + +#endif // OPENCV_GAPI_GARRAY_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gasync_context.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gasync_context.hpp new file mode 100755 index 0000000..3e01577 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gasync_context.hpp @@ -0,0 +1,38 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2019 Intel Corporation + +#ifndef OPENCV_GAPI_GASYNC_CONTEXT_HPP +#define OPENCV_GAPI_GASYNC_CONTEXT_HPP + +#if !defined(GAPI_STANDALONE) +# include +#else // Without OpenCV +# include +#endif // !defined(GAPI_STANDALONE) + +#include + +namespace cv { +namespace gapi{ +namespace wip { + +class GAPI_EXPORTS GAsyncContext{ + std::atomic cancelation_requested = {false}; +public: + //returns true if it was a first request to cancel the context + bool cancel(); + bool isCanceled() const; +}; + +class GAPI_EXPORTS GAsyncCanceled : public std::exception { +public: + virtual const char* what() const noexcept CV_OVERRIDE; +}; +} // namespace wip +} // namespace gapi +} // namespace cv + +#endif //OPENCV_GAPI_GASYNC_CONTEXT_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gcall.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcall.hpp new file mode 100755 index 0000000..87cba52 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcall.hpp @@ -0,0 +1,64 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GCALL_HPP +#define OPENCV_GAPI_GCALL_HPP + +#include // GArg +#include // GMat +#include // GScalar +#include // GArray + +namespace cv { + +struct GKernel; + +// The whole idea of this class is to represent an operation +// which is applied to arguments. This is part of public API, +// since it is what users should use to define kernel interfaces. + +class GAPI_EXPORTS GCall final +{ +public: + class Priv; + + explicit GCall(const GKernel &k); + ~GCall(); + + template + GCall& pass(Ts&&... args) + { + setArgs({cv::GArg(std::move(args))...}); + return *this; + } + + // A generic yield method - obtain a link to operator's particular GMat output + GMat yield (int output = 0); + GMatP yieldP (int output = 0); + GScalar yieldScalar(int output = 0); + + template GArray yieldArray(int output = 0) + { + return GArray(yieldArray(output)); + } + + // Internal use only + Priv& priv(); + const Priv& priv() const; + +protected: + std::shared_ptr m_priv; + + void setArgs(std::vector &&args); + + // Public version returns a typed array, this one is implementation detail + detail::GArrayU yieldArray(int output = 0); +}; + +} // namespace cv + +#endif // OPENCV_GAPI_GCALL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gcommon.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcommon.hpp new file mode 100755 index 0000000..dac640a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcommon.hpp @@ -0,0 +1,172 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GCOMMON_HPP +#define OPENCV_GAPI_GCOMMON_HPP + +#include // std::hash +#include // std::vector +#include // decay + +#include + +#include +#include +#include + +namespace cv { + +namespace detail +{ + // This is a trait-like structure to mark backend-specific compile arguments + // with tags + template struct CompileArgTag; + template struct CompileArgTag + { + static const char* tag() { return ""; }; + }; + + // These structures are tags which separate kernels and transformations + struct KernelTag + {}; + struct TransformTag + {}; +} + +// This definition is here because it is reused by both public(?) and internal +// modules. Keeping it here wouldn't expose public details (e.g., API-level) +// to components which are internal and operate on a lower-level entities +// (e.g., compiler, backends). +// FIXME: merge with ArgKind? +// FIXME: replace with variant[format desc]? +enum class GShape: int +{ + GMAT, + GSCALAR, + GARRAY, +}; + +struct GCompileArg; + +namespace detail { + template + using is_compile_arg = std::is_same::type>; +} +// CompileArg is an unified interface over backend-specific compilation +// information +// FIXME: Move to a separate file? +/** \addtogroup gapi_compile_args + * @{ + * + * @brief Compilation arguments: a set of data structures which can be + * passed to control compilation process + * + * G-API comes with a number of graph compilation options which can be + * passed to cv::GComputation::apply() or + * cv::GComputation::compile(). Known compilation options are listed + * in this page, while extra backends may introduce their own + * compilation options (G-API transparently accepts _everything_ which + * can be passed to cv::compile_args(), it depends on underlying + * backends if an option would be interpreted or not). + * + * For example, if an example computation is executed like this: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_decl_apply + * + * Extra parameter specifying which kernels to compile with can be + * passed like this: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp apply_with_param + */ + +/** + * @brief Represents an arbitrary compilation argument. + * + * Any value can be wrapped into cv::GCompileArg, but only known ones + * (to G-API or its backends) can be interpreted correctly. + * + * Normally objects of this class shouldn't be created manually, use + * cv::compile_args() function which automatically wraps everything + * passed in (a variadic template parameter pack) into a vector of + * cv::GCompileArg objects. + */ +struct GAPI_EXPORTS GCompileArg +{ +public: + std::string tag; + + // FIXME: use decay in GArg/other trait-based wrapper before leg is shot! + template::value, int>::type = 0> + explicit GCompileArg(T &&t) + : tag(detail::CompileArgTag::type>::tag()) + , arg(t) + { + } + + template T& get() + { + return util::any_cast(arg); + } + + template const T& get() const + { + return util::any_cast(arg); + } + +private: + util::any arg; +}; + +using GCompileArgs = std::vector; + +/** + * Wraps a list of arguments (a parameter pack) into a vector of + * compilation arguments (cv::GCompileArg). + */ +template GCompileArgs compile_args(Ts&&... args) +{ + return GCompileArgs{ GCompileArg(args)... }; +} + +/** + * @brief Ask G-API to dump compiled graph in Graphviz format under + * the given file name. + * + * Specifies a graph dump path (path to .dot file to be generated). + * G-API will dump a .dot file under specified path during a + * compilation process if this flag is passed. + */ +struct graph_dump_path +{ + std::string m_dump_path; +}; +/** @} */ + +namespace detail +{ + template<> struct CompileArgTag + { + static const char* tag() { return "gapi.graph_dump_path"; } + }; +} + +} // namespace cv + +// std::hash overload for GShape +namespace std +{ +template<> struct hash +{ + size_t operator() (cv::GShape sh) const + { + return std::hash()(static_cast(sh)); + } +}; +} // namespace std + + +#endif // OPENCV_GAPI_GCOMMON_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled.hpp new file mode 100755 index 0000000..c825edf --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled.hpp @@ -0,0 +1,217 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GCOMPILED_HPP +#define OPENCV_GAPI_GCOMPILED_HPP + +#include + +#include +#include +#include + +namespace cv { + +// This class represents a compiled computation. +// In theory (and ideally), it can be used w/o the rest of APIs. +// In theory (and ideally), it can be serialized/deserialized. +// It can enable scenarious like deployment to an autonomous devince, FuSa, etc. +// +// Currently GCompiled assumes all GMats you used to pass data to G-API +// are valid and not destroyed while you use a GCompiled object. +// +// FIXME: In future, there should be a way to name I/O objects and specify it +// to GCompiled externally (for example, when it is loaded on the target system). + +/** + * \addtogroup gapi_main_classes + * @{ + */ +/** + * @brief Represents a compiled computation (graph). Can only be used + * with image / data formats & resolutions it was compiled for, with + * some exceptions. + * + * This class represents a product of graph compilation (calling + * cv::GComputation::compile()). Objects of this class actually do + * data processing, and graph execution is incapsulated into objects + * of this class. Execution model itself depends on kernels and + * backends which were using during the compilation, see @ref + * gapi_compile_args for details. + * + * In a general case, GCompiled objects can be applied to data only in + * that formats/resolutions they were compiled for (see @ref + * gapi_meta_args). However, if the underlying backends allow, a + * compiled object can be _reshaped_ to handle data (images) of + * different resolution, though formats and types must remain the same. + * + * GCompiled is very similar to `std::function<>` in its semantics -- + * running it looks like a function call in the user code. + * + * At the moment, GCompiled objects are not reentrant -- generally, + * the objects are stateful since graph execution itself is a stateful + * process and this state is now maintained in GCompiled's own memory + * (not on the process stack). + * + * At the same time, two different GCompiled objects produced from the + * single cv::GComputation are completely independent and can be used + * concurrently. + */ +class GAPI_EXPORTS GCompiled +{ +public: + /// @private + class GAPI_EXPORTS Priv; + + /** + * @brief Constructs an empty object + */ + GCompiled(); + + /** + * @brief Run the compiled computation, a generic version. + * + * @param ins vector of inputs to process. + * @param outs vector of outputs to produce. + * + * Input/output vectors must have the same number of elements as + * defined in the cv::GComputation protocol (at the moment of its + * construction). Shapes of elements also must conform to protocol + * (e.g. cv::Mat needs to be passed where cv::GMat has been + * declared as input, and so on). Run-time exception is generated + * otherwise. + * + * Objects in output vector may remain empty (like cv::Mat) -- + * G-API will automatically initialize output objects to proper formats. + * + * @note Don't construct GRunArgs/GRunArgsP objects manually, use + * cv::gin()/cv::gout() wrappers instead. + */ + void operator() (GRunArgs &&ins, GRunArgsP &&outs); // Generic arg-to-arg +#if !defined(GAPI_STANDALONE) + + /** + * @brief Execute an unary computation + * + * @overload + * @param in input cv::Mat for unary computation + * @param out output cv::Mat for unary computation + * process. + */ + void operator() (cv::Mat in, cv::Mat &out); // Unary overload + + /** + * @brief Execute an unary computation + * + * @overload + * @param in input cv::Mat for unary computation + * @param out output cv::Scalar for unary computation + * process. + */ + void operator() (cv::Mat in, cv::Scalar &out); // Unary overload (scalar) + + /** + * @brief Execute a binary computation + * + * @overload + * @param in1 first input cv::Mat for binary computation + * @param in2 second input cv::Mat for binary computation + * @param out output cv::Mat for binary computation + * process. + */ + void operator() (cv::Mat in1, cv::Mat in2, cv::Mat &out); // Binary overload + + /** + * @brief Execute an binary computation + * + * @overload + * @param in1 first input cv::Mat for binary computation + * @param in2 second input cv::Mat for binary computation + * @param out output cv::Scalar for binary computation + * process. + */ + void operator() (cv::Mat in1, cv::Mat in2, cv::Scalar &out); // Binary overload (scalar) + + /** + * @brief Execute a computation with arbitrary number of + * inputs/outputs. + * + * @overload + * @param ins vector of input cv::Mat objects to process by the + * computation. + * @param outs vector of output cv::Mat objects to produce by the + * computation. + * + * Numbers of elements in ins/outs vectos must match numbers of + * inputs/outputs which were used to define the source GComputation. + */ + void operator() (const std::vector &ins, // Compatibility overload + const std::vector &outs); +#endif // !defined(GAPI_STANDALONE) + /// @private + Priv& priv(); + + /** + * @brief Check if compiled object is valid (non-empty) + * + * @return true if the object is runnable (valid), false otherwise + */ + explicit operator bool () const; + + /** + * @brief Vector of metadata this graph was compiled for. + * + * @return Unless _reshape_ is not supported, return value is the + * same vector which was passed to cv::GComputation::compile() to + * produce this compiled object. Otherwise, it is the latest + * metadata vector passed to reshape() (if that call was + * successful). + */ + const GMetaArgs& metas() const; // Meta passed to compile() + + /** + * @brief Vector of metadata descriptions of graph outputs + * + * @return vector with formats/resolutions of graph's output + * objects, auto-inferred from input metadata vector by + * operations which form this computation. + * + * @note GCompiled objects produced from the same + * cv::GComputiation graph with different input metas may return + * different values in this vector. + */ + const GMetaArgs& outMetas() const; + + /** + * @brief Check if the underlying backends support reshape or not. + * + * @return true if supported, false otherwise. + */ + bool canReshape() const; + + /** + * @brief Reshape a compiled graph to support new image + * resolutions. + * + * Throws an exception if an error occurs. + * + * @param inMetas new metadata to reshape on. Vector size and + * metadata shapes must match the computation's protocol. + * @param args compilation arguments to use. + */ + // FIXME: Why it requires compile args? + void reshape(const GMetaArgs& inMetas, const GCompileArgs& args); + +protected: + /// @private + std::shared_ptr m_priv; +}; +/** @} */ + +} + +#endif // OPENCV_GAPI_GCOMPILED_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled_async.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled_async.hpp new file mode 100755 index 0000000..96da0d7 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompiled_async.hpp @@ -0,0 +1,41 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2019 Intel Corporation + + +#ifndef OPENCV_GAPI_GCOMPILED_ASYNC_HPP +#define OPENCV_GAPI_GCOMPILED_ASYNC_HPP + +#include //for std::future +#include //for std::exception_ptr +#include //for std::function +#include +#include + +namespace cv { + //fwd declaration + class GCompiled; + +namespace gapi{ +namespace wip { + class GAsyncContext; + //These functions asynchronously (i.e. probably on a separate thread of execution) call operator() member function of their first argument with copies of rest of arguments (except callback) passed in. + //The difference between the function is the way to get the completion notification (via callback or a waiting on std::future object) + //If exception is occurred during execution of apply it is transfered to the callback (via function parameter) or passed to future (and will be thrown on call to std::future::get) + + //N.B. : + //Input arguments are copied on call to async function (actually on call to cv::gin) and thus do not have to outlive the actual completion of asynchronous activity. + //While Output arguments are "captured" by reference(pointer) and therefore _must_ outlive the asynchronous activity + //(i.e. live at least until callback is called or future is unblocked) + GAPI_EXPORTS void async(GCompiled& gcmpld, std::function&& callback, GRunArgs &&ins, GRunArgsP &&outs); + GAPI_EXPORTS void async(GCompiled& gcmpld, std::function&& callback, GRunArgs &&ins, GRunArgsP &&outs, GAsyncContext& ctx); + + GAPI_EXPORTS std::future async(GCompiled& gcmpld, GRunArgs &&ins, GRunArgsP &&outs); + GAPI_EXPORTS std::future async(GCompiled& gcmpld, GRunArgs &&ins, GRunArgsP &&outs, GAsyncContext& ctx); +} // namespace wip +} // namespace gapi +} // namespace cv + +#endif // OPENCV_GAPI_GCOMPILED_ASYNC_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompoundkernel.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompoundkernel.hpp new file mode 100755 index 0000000..7d960cd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcompoundkernel.hpp @@ -0,0 +1,108 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018-2019 Intel Corporation + + +#ifndef OPENCV_GAPI_GCOMPOUNDKERNEL_HPP +#define OPENCV_GAPI_GCOMPOUNDKERNEL_HPP + +#include +#include +#include +#include + +namespace cv { +namespace gapi +{ +namespace compound +{ + // FIXME User does not need to know about this function + // Needs that user may define compound kernels(as cpu kernels) + GAPI_EXPORTS cv::gapi::GBackend backend(); +} // namespace compound +} // namespace gapi + +namespace detail +{ + +struct GCompoundContext +{ + explicit GCompoundContext(const GArgs& in_args); + template + const T& inArg(int input) { return m_args.at(input).get(); } + + GArgs m_args; + GArgs m_results; +}; + +class GAPI_EXPORTS GCompoundKernel +{ +// Compound kernel must use all of it's inputs +public: + using F = std::function; + + explicit GCompoundKernel(const F& f); + void apply(GCompoundContext& ctx); + +protected: + F m_f; +}; + +template struct get_compound_in +{ + static T get(GCompoundContext &ctx, int idx) { return ctx.inArg(idx); } +}; + +template struct get_compound_in> +{ + static cv::GArray get(GCompoundContext &ctx, int idx) + { + auto array = cv::GArray(); + ctx.m_args[idx] = GArg(array); + return array; + } +}; + +template +struct GCompoundCallHelper; + +template +struct GCompoundCallHelper, std::tuple > +{ + template + static void expand_impl(GCompoundContext &ctx, detail::Seq, detail::Seq) + { + auto result = Impl::expand(get_compound_in::get(ctx, IIs)...); + auto tuple_return = tuple_wrap_helper::get(std::move(result)); + ctx.m_results = { cv::GArg(std::get(tuple_return))... }; + } + + static void expand(GCompoundContext &ctx) + { + expand_impl(ctx, + typename detail::MkSeq::type(), + typename detail::MkSeq::type()); + } +}; + +template +class GCompoundKernelImpl: public cv::detail::GCompoundCallHelper, + public cv::detail::KernelTag +{ + using P = cv::detail::GCompoundCallHelper; + +public: + using API = K; + + static cv::gapi::GBackend backend() { return cv::gapi::compound::backend(); } + static GCompoundKernel kernel() { return GCompoundKernel(&P::expand); } +}; + +} // namespace detail +#define GAPI_COMPOUND_KERNEL(Name, API) struct Name: public cv::detail::GCompoundKernelImpl + +} // namespace cv + +#endif // OPENCV_GAPI_GCOMPOUNDKERNEL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation.hpp new file mode 100755 index 0000000..fdeef86 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation.hpp @@ -0,0 +1,456 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GCOMPUTATION_HPP +#define OPENCV_GAPI_GCOMPUTATION_HPP + +#include + +#include +#include +#include +#include +#include + +namespace cv { + +namespace detail +{ + // FIXME: move to algorithm, cover with separate tests + // FIXME: replace with O(1) version (both memory and compilation time) + template + struct last_type; + + template + struct last_type { using type = T;}; + + template + struct last_type { using type = typename last_type::type; }; + + template + using last_type_t = typename last_type::type; +} + +/** + * \addtogroup gapi_main_classes + * @{ + */ +/** + * @brief GComputation class represents a captured computation + * graph. GComputation objects form boundaries for expression code + * user writes with G-API, allowing to compile and execute it. + * + * G-API computations are defined with input/output data + * objects. G-API will track automatically which operations connect + * specified outputs to the inputs, forming up a call graph to be + * executed. The below example expresses calculation of Sobel operator + * for edge detection (\f$G = \sqrt{G_x^2 + G_y^2}\f$): + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_def + * + * Full pipeline can be now captured with this object declaration: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_full + * + * Input/output data objects on which a call graph should be + * reconstructed are passed using special wrappers cv::GIn and + * cv::GOut. G-API will track automatically which operations form a + * path from inputs to outputs and build the execution graph appropriately. + * + * Note that cv::GComputation doesn't take ownership on data objects + * it is defined. Moreover, multiple GComputation objects may be + * defined on the same expressions, e.g. a smaller pipeline which + * expects that image gradients are already pre-calculated may be + * defined like this: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_sub + * + * The resulting graph would expect two inputs and produce one + * output. In this case, it doesn't matter if gx/gy data objects are + * results of cv::gapi::Sobel operators -- G-API will stop unrolling + * expressions and building the underlying graph one reaching this + * data objects. + * + * The way how GComputation is defined is important as its definition + * specifies graph _protocol_ -- the way how the graph should be + * used. Protocol is defined by number of inputs, number of outputs, + * and shapes of inputs and outputs. + * + * In the above example, sobelEdge expects one Mat on input and + * produces one Mat; while sobelEdgeSub expects two Mats on input and + * produces one Mat. GComputation's protocol defines how other + * computaion methods should be used -- cv::GComputation::compile() and + * cv::GComputation::apply(). For example, if a graph is defined on + * two GMat inputs, two cv::Mat objects have to be passed to apply() + * for execution. GComputation checks protocol correctness in runtime + * so passing a different number of objects in apply() or passing + * cv::Scalar instead of cv::Mat there would compile well as a C++ + * source but raise an exception in run-time. G-API also comes with a + * typed wrapper cv::GComputationT<> which introduces this type-checking in + * compile-time. + * + * cv::GComputation itself is a thin object which just captures what + * the graph is. The compiled graph (which actually process data) is + * represented by class GCompiled. Use compile() method to generate a + * compiled graph with given compile options. cv::GComputation can + * also be used to process data with implicit graph compilation + * on-the-fly, see apply() for details. + * + * GComputation is a reference-counted object -- once defined, all its + * copies will refer to the same instance. + * + * @sa GCompiled + */ +class GAPI_EXPORTS GComputation +{ +public: + class Priv; + typedef std::function Generator; + + // Various constructors enable different ways to define a computation: ///// + // 1. Generic constructors + /** + * @brief Define a computation using a generator function. + * + * Graph can be defined in-place directly at the moment of its + * construction with a lambda: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_gen + * + * This may be useful since all temporary objects (cv::GMats) and + * namespaces can be localized to scope of lambda, without + * contaminating the parent scope with probably unnecessary objects + * and information. + * + * @param gen generator function which returns a cv::GComputation, + * see Generator. + */ + GComputation(const Generator& gen); // Generator + // overload + + /** + * @brief Generic GComputation constructor. + * + * Constructs a new graph with a given protocol, specified as a + * flow of operations connecting input/output objects. Throws if + * the passed boundaries are invalid, e.g. if there's no + * functional dependency (path) between given outputs and inputs. + * + * @param ins Input data vector. + * @param outs Output data vector. + * + * @note Don't construct GProtoInputArgs/GProtoOutputArgs objects + * directly, use cv::GIn()/cv::GOut() wrapper functions instead. + * + * @sa @ref gapi_data_objects + */ + GComputation(GProtoInputArgs &&ins, + GProtoOutputArgs &&outs); // Arg-to-arg overload + + // 2. Syntax sugar and compatibility overloads + /** + * @brief Defines an unary (one input -- one output) computation + * + * @overload + * @param in input GMat of the defined unary computation + * @param out output GMat of the defined unary computation + */ + GComputation(GMat in, GMat out); // Unary overload + + /** + * @brief Defines an unary (one input -- one output) computation + * + * @overload + * @param in input GMat of the defined unary computation + * @param out output GScalar of the defined unary computation + */ + GComputation(GMat in, GScalar out); // Unary overload (scalar) + + /** + * @brief Defines a binary (two inputs -- one output) computation + * + * @overload + * @param in1 first input GMat of the defined binary computation + * @param in2 second input GMat of the defined binary computation + * @param out output GMat of the defined binary computation + */ + GComputation(GMat in1, GMat in2, GMat out); // Binary overload + + /** + * @brief Defines a binary (two inputs -- one output) computation + * + * @overload + * @param in1 first input GMat of the defined binary computation + * @param in2 second input GMat of the defined binary computation + * @param out output GScalar of the defined binary computation + */ + GComputation(GMat in1, GMat in2, GScalar out); // Binary + // overload + // (scalar) + + /** + * @brief Defines a computation with arbitrary input/output number. + * + * @overload + * @param ins vector of inputs GMats for this computation + * @param outs vector of outputs GMats for this computation + * + * Use this overload for cases when number of computation + * inputs/outputs is not known in compile-time -- e.g. when graph + * is programmatically generated to build an image pyramid with + * the given number of levels, etc. + */ + GComputation(const std::vector &ins, // Compatibility overload + const std::vector &outs); + + // Various versions of apply(): //////////////////////////////////////////// + // 1. Generic apply() + /** + * @brief Compile graph on-the-fly and immediately execute it on + * the inputs data vectors. + * + * Number of input/output data objects must match GComputation's + * protocol, also types of host data objects (cv::Mat, cv::Scalar) + * must match the shapes of data objects from protocol (cv::GMat, + * cv::GScalar). If there's a mismatch, a run-time exception will + * be generated. + * + * Internally, a cv::GCompiled object is created for the given + * input format configuration, which then is executed on the input + * data immediately. cv::GComputation caches compiled objects + * produced within apply() -- if this method would be called next + * time with the same input parameters (image formats, image + * resolution, etc), the underlying compiled graph will be reused + * without recompilation. If new metadata doesn't match the cached + * one, the underlying compiled graph is regenerated. + * + * @note compile() always triggers a compilation process and + * produces a new GCompiled object regardless if a similar one has + * been cached via apply() or not. + * + * @param ins vector of input data to process. Don't create + * GRunArgs object manually, use cv::gin() wrapper instead. + * @param outs vector of output data to fill results in. cv::Mat + * objects may be empty in this vector, G-API will automatically + * initialize it with the required format & dimensions. Don't + * create GRunArgsP object manually, use cv::gout() wrapper instead. + * @param args a list of compilation arguments to pass to the + * underlying compilation process. Don't create GCompileArgs + * object manually, use cv::compile_args() wrapper instead. + * + * @sa @ref gapi_data_objects, @ref gapi_compile_args + */ + void apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {}); // Arg-to-arg overload + + /// @private -- Exclude this function from OpenCV documentation + void apply(const std::vector& ins, // Compatibility overload + const std::vector& outs, + GCompileArgs &&args = {}); + + // 2. Syntax sugar and compatibility overloads +#if !defined(GAPI_STANDALONE) + /** + * @brief Execute an unary computation (with compilation on the fly) + * + * @overload + * @param in input cv::Mat for unary computation + * @param out output cv::Mat for unary computation + * @param args compilation arguments for underlying compilation + * process. + */ + void apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args = {}); // Unary overload + + /** + * @brief Execute an unary computation (with compilation on the fly) + * + * @overload + * @param in input cv::Mat for unary computation + * @param out output cv::Scalar for unary computation + * @param args compilation arguments for underlying compilation + * process. + */ + void apply(cv::Mat in, cv::Scalar &out, GCompileArgs &&args = {}); // Unary overload (scalar) + + /** + * @brief Execute a binary computation (with compilation on the fly) + * + * @overload + * @param in1 first input cv::Mat for binary computation + * @param in2 second input cv::Mat for binary computation + * @param out output cv::Mat for binary computation + * @param args compilation arguments for underlying compilation + * process. + */ + void apply(cv::Mat in1, cv::Mat in2, cv::Mat &out, GCompileArgs &&args = {}); // Binary overload + + /** + * @brief Execute an binary computation (with compilation on the fly) + * + * @overload + * @param in1 first input cv::Mat for binary computation + * @param in2 second input cv::Mat for binary computation + * @param out output cv::Scalar for binary computation + * @param args compilation arguments for underlying compilation + * process. + */ + void apply(cv::Mat in1, cv::Mat in2, cv::Scalar &out, GCompileArgs &&args = {}); // Binary overload (scalar) + + /** + * @brief Execute a computation with arbitrary number of + * inputs/outputs (with compilation on-the-fly). + * + * @overload + * @param ins vector of input cv::Mat objects to process by the + * computation. + * @param outs vector of output cv::Mat objects to produce by the + * computation. + * @param args compilation arguments for underlying compilation + * process. + * + * Numbers of elements in ins/outs vectos must match numbers of + * inputs/outputs which were used to define this GComputation. + */ + void apply(const std::vector& ins, // Compatibility overload + std::vector& outs, + GCompileArgs &&args = {}); +#endif // !defined(GAPI_STANDALONE) + // Various versions of compile(): ////////////////////////////////////////// + // 1. Generic compile() - requires metas to be passed as vector + /** + * @brief Compile the computation for specific input format(s). + * + * This method triggers compilation process and produces a new + * GCompiled object which then can process data of the given + * format. Passing data with different format to the compiled + * computation will generate a run-time exception. + * + * @param in_metas vector of input metadata configuration. Grab + * metadata from real data objects (like cv::Mat or cv::Scalar) + * using cv::descr_of(), or create it on your own. + * @param args compilation arguments for this compilation + * process. Compilation arguments directly affect what kind of + * executable object would be produced, e.g. which kernels (and + * thus, devices) would be used to execute computation. + * + * @return GCompiled, an executable computation compiled + * specifically for the given input parameters. + * + * @sa @ref gapi_compile_args + */ + GCompiled compile(GMetaArgs &&in_metas, GCompileArgs &&args = {}); + + // 2. Syntax sugar - variadic list of metas, no extra compile args + // FIXME: SFINAE looks ugly in the generated documentation + /** + * @overload + * + * Takes a variadic parameter pack with metadata + * descriptors for which a compiled object needs to be produced. + * + * @return GCompiled, an executable computation compiled + * specifically for the given input parameters. + */ + template + auto compile(const Ts&... metas) -> + typename std::enable_if::value, GCompiled>::type + { + return compile(GMetaArgs{GMetaArg(metas)...}, GCompileArgs()); + } + + // 3. Syntax sugar - variadic list of metas, extra compile args + // (seems optional parameters don't work well when there's an variadic template + // comes first) + // + // Ideally it should look like: + // + // template + // GCompiled compile(const Ts&... metas, GCompileArgs &&args) + // + // But not all compilers can hande this (and seems they shouldn't be able to). + // FIXME: SFINAE looks ugly in the generated documentation + /** + * @overload + * + * Takes a variadic parameter pack with metadata + * descriptors for which a compiled object needs to be produced, + * followed by GCompileArgs object representing compilation + * arguments for this process. + * + * @return GCompiled, an executable computation compiled + * specifically for the given input parameters. + */ + template + auto compile(const Ts&... meta_and_compile_args) -> + typename std::enable_if::value + && std::is_same >::value, + GCompiled>::type + { + //FIXME: wrapping meta_and_compile_args into a tuple to unwrap them inside a helper function is the overkill + return compile(std::make_tuple(meta_and_compile_args...), + typename detail::MkSeq::type()); + } + + // Internal use only + /// @private + Priv& priv(); + /// @private + const Priv& priv() const; + +protected: + + // 4. Helper method for (3) + /// @private + template + GCompiled compile(const std::tuple &meta_and_compile_args, detail::Seq) + { + GMetaArgs meta_args = {GMetaArg(std::get(meta_and_compile_args))...}; + GCompileArgs comp_args = std::get(meta_and_compile_args); + return compile(std::move(meta_args), std::move(comp_args)); + } + /// @private + std::shared_ptr m_priv; +}; +/** @} */ + +namespace gapi +{ + // FIXME: all these standalone functions need to be added to some + // common documentation section + /** + * @brief Define an tagged island (subgraph) within a computation. + * + * Declare an Island tagged with `name` and defined from `ins` to `outs` + * (exclusively, as ins/outs are data objects, and regioning is done on + * operations level). + * Throws if any operation between `ins` and `outs` are already assigned + * to another island. + * + * Islands allow to partition graph into subgraphs, fine-tuning + * the way it is scheduled by the underlying executor. + * + * @param name name of the Island to create + * @param ins vector of input data objects where the subgraph + * begins + * @param outs vector of output data objects where the subgraph + * ends. + * + * The way how an island is defined is similar to how + * cv::GComputation is defined on input/output data objects. + * Same rules apply here as well -- if there's no functional + * dependency between inputs and outputs or there's not enough + * input data objects were specified to properly calculate all + * outputs, an exception is thrown. + * + * Use cv::GIn() / cv::GOut() to specify input/output vectors. + */ + void GAPI_EXPORTS island(const std::string &name, + GProtoInputArgs &&ins, + GProtoOutputArgs &&outs); +} // namespace gapi + +} // namespace cv +#endif // OPENCV_GAPI_GCOMPUTATION_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation_async.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation_async.hpp new file mode 100755 index 0000000..661e097 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gcomputation_async.hpp @@ -0,0 +1,43 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2019 Intel Corporation + +#ifndef OPENCV_GAPI_GCOMPUTATION_ASYNC_HPP +#define OPENCV_GAPI_GCOMPUTATION_ASYNC_HPP + + +#include //for std::future +#include //for std::exception_ptr +#include //for std::function +#include //for GRunArgs, GRunArgsP +#include //for GCompileArgs +#include + + +namespace cv { + //fwd declaration + class GComputation; +namespace gapi { +namespace wip { + class GAsyncContext; + //These functions asynchronously (i.e. probably on a separate thread of execution) call apply member function of their first argument with copies of rest of arguments (except callback) passed in. + //The difference between the function is the way to get the completion notification (via callback or a waiting on std::future object) + //If exception is occurred during execution of apply it is transfered to the callback (via function parameter) or passed to future (and will be thrown on call to std::future::get) + + //N.B. : + //Input arguments are copied on call to async function (actually on call to cv::gin) and thus do not have to outlive the actual completion of asynchronous activity. + //While Output arguments are "captured" by reference(pointer) and therefore _must_ outlive the asynchronous activity + //(i.e. live at least until callback is called or future is unblocked) + GAPI_EXPORTS void async_apply(GComputation& gcomp, std::function&& callback, GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {}); + GAPI_EXPORTS void async_apply(GComputation& gcomp, std::function&& callback, GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args, GAsyncContext& ctx); + + GAPI_EXPORTS std::future async_apply(GComputation& gcomp, GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {}); + GAPI_EXPORTS std::future async_apply(GComputation& gcomp, GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args, GAsyncContext& ctx); +} // namespace wip +} // namespace gapi +} // namespace cv + + +#endif //OPENCV_GAPI_GCOMPUTATION_ASYNC_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gkernel.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gkernel.hpp new file mode 100755 index 0000000..b8d1dbb --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gkernel.hpp @@ -0,0 +1,557 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018-2019 Intel Corporation + + +#ifndef OPENCV_GAPI_GKERNEL_HPP +#define OPENCV_GAPI_GKERNEL_HPP + +#include +#include +#include // string +#include // false_type, true_type +#include // map (for GKernelPackage) +#include // tuple + +#include // CompileArgTag +#include // Seq +#include +#include // GArg +#include // GMetaArg +#include // GTypeTraits +#include //suppress_unused_warning +#include + +namespace cv { + +using GShapes = std::vector; + +// GKernel describes kernel API to the system +// FIXME: add attributes of a kernel, (e.g. number and types +// of inputs, etc) +struct GAPI_EXPORTS GKernel +{ + using M = std::function; + + const std::string name; // kernel ID, defined by its API (signature) + const M outMeta; // generic adaptor to API::outMeta(...) + const GShapes outShapes; // types (shapes) kernel's outputs +}; + +// GKernelImpl describes particular kernel implementation to the system +struct GAPI_EXPORTS GKernelImpl +{ + util::any opaque; // backend-specific opaque info +}; + +template class GKernelTypeM; + +namespace detail +{ + //////////////////////////////////////////////////////////////////////////// + // yield() is used in graph construction time as a generic method to obtain + // lazy "return value" of G-API operations + // + namespace + { + template struct Yield; + template<> struct Yield + { + static inline cv::GMat yield(cv::GCall &call, int i) { return call.yield(i); } + }; + template<> struct Yield + { + static inline cv::GMatP yield(cv::GCall &call, int i) { return call.yieldP(i); } + }; + template<> struct Yield + { + static inline cv::GScalar yield(cv::GCall &call, int i) { return call.yieldScalar(i); } + }; + template struct Yield > + { + static inline cv::GArray yield(cv::GCall &call, int i) { return call.yieldArray(i); } + }; + } // anonymous namespace + + //////////////////////////////////////////////////////////////////////////// + // Helper classes which brings outputMeta() marshalling to kernel + // implementations + // + // 1. MetaType establishes G#Type -> G#Meta mapping between G-API dynamic + // types and its metadata descriptor types. + // This mapping is used to transform types to call outMeta() callback. + template struct MetaType; + template<> struct MetaType { using type = GMatDesc; }; + template<> struct MetaType { using type = GMatDesc; }; + template<> struct MetaType { using type = GScalarDesc; }; + template struct MetaType > { using type = GArrayDesc; }; + template struct MetaType { using type = T; }; // opaque args passed as-is + + // 2. Hacky test based on MetaType to check if we operate on G-* type or not + template using is_nongapi_type = std::is_same::type>; + + // 3. Two ways to transform input arguments to its meta - for G-* and non-G* types: + template + typename std::enable_if::value, typename MetaType::type> + ::type get_in_meta(const GMetaArgs &in_meta, const GArgs &, int idx) + { + return util::get::type>(in_meta.at(idx)); + } + + template + typename std::enable_if::value, T> + ::type get_in_meta(const GMetaArgs &, const GArgs &in_args, int idx) + { + return in_args.at(idx).template get(); + } + + // 4. The MetaHelper itself: an entity which generates outMeta() call + // based on kernel signature, with arguments properly substituted. + // 4.1 - case for multiple return values + // FIXME: probably can be simplified with std::apply or analogue. + template + struct MetaHelper; + + template + struct MetaHelper, std::tuple > + { + template + static GMetaArgs getOutMeta_impl(const GMetaArgs &in_meta, + const GArgs &in_args, + detail::Seq, + detail::Seq) + { + // FIXME: decay? + using R = std::tuple::type...>; + const R r = K::outMeta( get_in_meta(in_meta, in_args, IIs)... ); + return GMetaArgs{ GMetaArg(std::get(r))... }; + } + // FIXME: help users identify how outMeta must look like (via default impl w/static_assert?) + + static GMetaArgs getOutMeta(const GMetaArgs &in_meta, + const GArgs &in_args) + { + return getOutMeta_impl(in_meta, + in_args, + typename detail::MkSeq::type(), + typename detail::MkSeq::type()); + } + }; + + // 4.1 - case for a single return value + // FIXME: How to avoid duplication here? + template + struct MetaHelper, Out > + { + template + static GMetaArgs getOutMeta_impl(const GMetaArgs &in_meta, + const GArgs &in_args, + detail::Seq) + { + // FIXME: decay? + using R = typename MetaType::type; + const R r = K::outMeta( get_in_meta(in_meta, in_args, IIs)... ); + return GMetaArgs{ GMetaArg(r) }; + } + // FIXME: help users identify how outMeta must look like (via default impl w/static_assert?) + + static GMetaArgs getOutMeta(const GMetaArgs &in_meta, + const GArgs &in_args) + { + return getOutMeta_impl(in_meta, + in_args, + typename detail::MkSeq::type()); + } + }; + +} // namespace detail + +// GKernelType and GKernelTypeM are base classes which implement typed ::on() +// method based on kernel signature. GKernelTypeM stands for multiple-return-value kernels +// +// G_TYPED_KERNEL and G_TYPED_KERNEL_M macros inherit user classes from GKernelType and +// GKernelTypeM respectively. + +template +class GKernelTypeM(Args...)> >: + public detail::MetaHelper, std::tuple> +{ + template + static std::tuple yield(cv::GCall &call, detail::Seq) + { + return std::make_tuple(detail::Yield::yield(call, IIs)...); + } + +public: + using InArgs = std::tuple; + using OutArgs = std::tuple; + + static std::tuple on(Args... args) + { + cv::GCall call(GKernel{K::id(), &K::getOutMeta, {detail::GTypeTraits::shape...}}); + call.pass(args...); + return yield(call, typename detail::MkSeq::type()); + } +}; + +template class GKernelType; + +template +class GKernelType >: + public detail::MetaHelper, R> +{ +public: + using InArgs = std::tuple; + using OutArgs = std::tuple; + + static R on(Args... args) + { + cv::GCall call(GKernel{K::id(), &K::getOutMeta, {detail::GTypeTraits::shape}}); + call.pass(args...); + return detail::Yield::yield(call, 0); + } +}; + +} // namespace cv + + +// FIXME: I don't know a better way so far. Feel free to suggest one +// The problem is that every typed kernel should have ::id() but body +// of the class is defined by user (with outMeta, other stuff) + +#define G_ID_HELPER_CLASS(Class) Class##IdHelper + +#define G_ID_HELPER_BODY(Class, Id) \ + namespace detail \ + { \ + struct G_ID_HELPER_CLASS(Class) \ + { \ + static constexpr const char * id() {return Id;}; \ + }; \ + } + +#define G_TYPED_KERNEL(Class, API, Id) \ + G_ID_HELPER_BODY(Class, Id) \ + struct Class final: public cv::GKernelType, \ + public detail::G_ID_HELPER_CLASS(Class) +// {body} is to be defined by user + +#define G_TYPED_KERNEL_M(Class, API, Id) \ + G_ID_HELPER_BODY(Class, Id) \ + struct Class final: public cv::GKernelTypeM, \ + public detail::G_ID_HELPER_CLASS(Class) +// {body} is to be defined by user + +namespace cv +{ +namespace gapi +{ + // Prework: model "Device" API before it gets to G-API headers. + // FIXME: Don't mix with internal Backends class! + class GAPI_EXPORTS GBackend + { + public: + class Priv; + + // TODO: make it template (call `new` within??) + GBackend(); + explicit GBackend(std::shared_ptr &&p); + + Priv& priv(); + const Priv& priv() const; + std::size_t hash() const; + + bool operator== (const GBackend &rhs) const; + + private: + std::shared_ptr m_priv; + }; + + inline bool operator != (const GBackend &lhs, const GBackend &rhs) + { + return !(lhs == rhs); + } +} // namespace gapi +} // namespace cv + +namespace std +{ + template<> struct hash + { + std::size_t operator() (const cv::gapi::GBackend &b) const + { + return b.hash(); + } + }; +} // namespace std + + +namespace cv { +namespace gapi { + /** \addtogroup gapi_compile_args + * @{ + */ + + // FIXME: Hide implementation + /** + * @brief A container class for heterogeneous kernel + * implementation collections and graph transformations. + * + * GKernelPackage is a special container class which stores kernel + * _implementations_ and graph _transformations_. Objects of this class + * are created and passed to cv::GComputation::compile() to specify + * which kernels to use and which transformations to apply in the + * compiled graph. GKernelPackage may contain kernels of + * different backends, e.g. be heterogeneous. + * + * The most easy way to create a kernel package is to use function + * cv::gapi::kernels(). This template functions takes kernel + * implementations in form of type list (variadic template) and + * generates a kernel package atop of that. + * + * Kernel packages can be also generated programatically, starting + * with an empty package (created with the default constructor) + * and then by populating it with kernels via call to + * GKernelPackage::include(). Note this method is also a template + * one since G-API kernel and transformation implementations are _types_, + * not objects. + * + * Finally, two kernel packages can be combined into a new one + * with function cv::gapi::combine(). + */ + class GAPI_EXPORTS GKernelPackage + { + + /// @private + using M = std::unordered_map>; + + /// @private + M m_id_kernels; + + /// @private + std::vector m_transformations; + + protected: + /// @private + // Check if package contains ANY implementation of a kernel API + // by API textual id. + bool includesAPI(const std::string &id) const; + + /// @private + // Remove ALL implementations of the given API (identified by ID) + void removeAPI(const std::string &id); + + /// @private + // Partial include() specialization for kernels + template + typename std::enable_if<(std::is_base_of::value), void>::type + includeHelper() + { + auto backend = KImpl::backend(); + auto kernel_id = KImpl::API::id(); + auto kernel_impl = GKernelImpl{KImpl::kernel()}; + removeAPI(kernel_id); + + m_id_kernels[kernel_id] = std::make_pair(backend, kernel_impl); + } + + /// @private + // Partial include() specialization for transformations + template + typename std::enable_if<(std::is_base_of::value), void>::type + includeHelper() + { + m_transformations.emplace_back(TImpl::transformation()); + } + + public: + /** + * @brief Returns total number of kernels + * in the package (across all backends included) + * + * @return a number of kernels in the package + */ + std::size_t size() const; + + /** + * @brief Returns vector of transformations included in the package + * + * @return vector of transformations included in the package + */ + const std::vector& get_transformations() const; + + /** + * @brief Test if a particular kernel _implementation_ KImpl is + * included in this kernel package. + * + * @sa includesAPI() + * + * @note cannot be applied to transformations + * + * @return true if there is such kernel, false otherwise. + */ + template + bool includes() const + { + static_assert(std::is_base_of::value, + "includes() can be applied to kernels only"); + + auto kernel_it = m_id_kernels.find(KImpl::API::id()); + return kernel_it != m_id_kernels.end() && + kernel_it->second.first == KImpl::backend(); + } + + /** + * @brief Remove all kernels associated with the given backend + * from the package. + * + * Does nothing if there's no kernels of this backend in the package. + * + * @param backend backend which kernels to remove + */ + void remove(const GBackend& backend); + + /** + * @brief Remove all kernels implementing the given API from + * the package. + * + * Does nothing if there's no kernels implementing the given interface. + */ + template + void remove() + { + removeAPI(KAPI::id()); + } + + // FIXME: Rename to includes() and distinguish API/impl case by + // statically? + /** + * Check if package contains ANY implementation of a kernel API + * by API type. + */ + template + bool includesAPI() const + { + return includesAPI(KAPI::id()); + } + + /** + * @brief Find a kernel (by its API) + * + * Returns implementation corresponding id. + * Throws if nothing found. + * + * @return Backend which hosts matching kernel implementation. + * + */ + template + GBackend lookup() const + { + return lookup(KAPI::id()).first; + } + + /// @private + std::pair + lookup(const std::string &id) const; + + // FIXME: No overwrites allowed? + /** + * @brief Put a new kernel implementation or a new transformation + * KImpl into the package. + */ + template + void include() + { + includeHelper(); + } + + /** + * @brief Lists all backends which are included into package + * + * @return vector of backends + */ + std::vector backends() const; + + // TODO: Doxygen bug -- it wants me to place this comment + // here, not below. + /** + * @brief Create a new package based on `lhs` and `rhs`. + * + * @param lhs "Left-hand-side" package in the process + * @param rhs "Right-hand-side" package in the process + * @return a new kernel package. + */ + friend GAPI_EXPORTS GKernelPackage combine(const GKernelPackage &lhs, + const GKernelPackage &rhs); + }; + + /** + * @brief Create a kernel package object containing kernels + * and transformations specified in variadic template argument. + * + * In G-API, kernel implementations and transformations are _types_. + * Every backend has its own kernel API (like GAPI_OCV_KERNEL() and + * GAPI_FLUID_KERNEL()) but all of that APIs define a new type for + * each kernel implementation. + * + * Use this function to pass kernel implementations (defined in + * either way) and transformations to the system. Example: + * + * @snippet modules/gapi/samples/api_ref_snippets.cpp kernels_snippet + * + * Note that kernels() itself is a function returning object, not + * a type, so having `()` at the end is important -- it must be a + * function call. + */ + template GKernelPackage kernels() + { + // FIXME: currently there is no check that transformations' signatures are unique + // and won't be any intersection in graph compilation stage + static_assert(detail::all_unique::value, "Kernels API must be unique"); + + GKernelPackage pkg; + + // For those who wonder - below is a trick to call a number of + // methods based on parameter pack (zeroes just help hiding these + // calls into a sequence which helps to expand this parameter pack). + // Just note that `f(),a` always equals to `a` (with f() called!) + // and parentheses are used to hide function call in the expanded sequence. + // Leading 0 helps to handle case when KK is an empty list (kernels<>()). + int unused[] = { 0, (pkg.include(), 0)... }; + cv::util::suppress_unused_warning(unused); + return pkg; + }; + + /** @} */ + + GAPI_EXPORTS GKernelPackage combine(const GKernelPackage &lhs, + const GKernelPackage &rhs); + /** + * @brief cv::use_only() is a special combinator which hints G-API to use only + * kernels specified in cv::GComputation::compile() (and not to extend kernels available by + * default with that package). + */ + struct GAPI_EXPORTS use_only + { + GKernelPackage pkg; + }; + +} // namespace gapi + +namespace detail +{ + template<> struct CompileArgTag + { + static const char* tag() { return "gapi.kernel_package"; } + }; + + template<> struct CompileArgTag + { + static const char* tag() { return "gapi.use_only"; } + }; +} // namespace detail +} // namespace cv + +#endif // OPENCV_GAPI_GKERNEL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gmat.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gmat.hpp new file mode 100755 index 0000000..d6b6e72 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gmat.hpp @@ -0,0 +1,209 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GMAT_HPP +#define OPENCV_GAPI_GMAT_HPP + +#include +#include // std::shared_ptr + +#include +#include // GShape + +#include // cv::gapi::own::Size +#include // to_own +#include + +// TODO GAPI_EXPORTS or so +namespace cv +{ +// Forward declaration; GNode and GOrigin are an internal +// (user-inaccessible) classes. +class GNode; +struct GOrigin; + +/** \addtogroup gapi_data_objects + * @{ + * + * @brief Data-representing objects which can be used to build G-API + * expressions. + */ + +class GAPI_EXPORTS GMat +{ +public: + GMat(); // Empty constructor + GMat(const GNode &n, std::size_t out); // Operation result constructor + + GOrigin& priv(); // Internal use only + const GOrigin& priv() const; // Internal use only + +private: + std::shared_ptr m_priv; +}; + +class GAPI_EXPORTS GMatP : public GMat +{ +public: + using GMat::GMat; +}; + +namespace gapi { namespace own { + class Mat; +}}//gapi::own + +/** @} */ + +/** + * \addtogroup gapi_meta_args + * @{ + */ +struct GAPI_EXPORTS GMatDesc +{ + // FIXME: Default initializers in C++14 + int depth; + int chan; + cv::gapi::own::Size size; // NB.: no multi-dimensional cases covered yet + bool planar; + + GMatDesc(int d, int c, cv::gapi::own::Size s, bool p = false) + : depth(d), chan(c), size(s), planar(p) {} + + GMatDesc() : GMatDesc(-1, -1, {-1,-1}) {} + + inline bool operator== (const GMatDesc &rhs) const + { + return depth == rhs.depth && chan == rhs.chan && size == rhs.size && planar == rhs.planar; + } + + inline bool operator!= (const GMatDesc &rhs) const + { + return !(*this == rhs); + } + + // Checks if the passed mat can be described by this descriptor + // (it handles the case when + // 1-channel mat can be reinterpreted as is (1-channel mat) + // and as a 3-channel planar mat with height divided by 3) + bool canDescribe(const cv::gapi::own::Mat& mat) const; + + // Meta combinator: return a new GMatDesc which differs in size by delta + // (all other fields are taken unchanged from this GMatDesc) + // FIXME: a better name? + GMatDesc withSizeDelta(cv::gapi::own::Size delta) const + { + GMatDesc desc(*this); + desc.size += delta; + return desc; + } +#if !defined(GAPI_STANDALONE) + GMatDesc withSizeDelta(cv::Size delta) const + { + return withSizeDelta(to_own(delta)); + } + + GMatDesc withSize(cv::Size sz) const + { + return withSize(to_own(sz)); + } + + bool canDescribe(const cv::Mat& mat) const; +#endif // !defined(GAPI_STANDALONE) + // Meta combinator: return a new GMatDesc which differs in size by delta + // (all other fields are taken unchanged from this GMatDesc) + // + // This is an overload. + GMatDesc withSizeDelta(int dx, int dy) const + { + return withSizeDelta(cv::gapi::own::Size{dx,dy}); + } + + GMatDesc withSize(cv::gapi::own::Size sz) const + { + GMatDesc desc(*this); + desc.size = sz; + return desc; + } + + // Meta combinator: return a new GMatDesc with specified data depth. + // (all other fields are taken unchanged from this GMatDesc) + GMatDesc withDepth(int ddepth) const + { + GAPI_Assert(CV_MAT_CN(ddepth) == 1 || ddepth == -1); + GMatDesc desc(*this); + if (ddepth != -1) desc.depth = ddepth; + return desc; + } + + // Meta combinator: return a new GMatDesc with specified data depth + // and number of channels. + // (all other fields are taken unchanged from this GMatDesc) + GMatDesc withType(int ddepth, int dchan) const + { + GAPI_Assert(CV_MAT_CN(ddepth) == 1 || ddepth == -1); + GMatDesc desc = withDepth(ddepth); + desc.chan = dchan; + return desc; + } + + // Meta combinator: return a new GMatDesc with planar flag set + // (no size changes are performed, only channel interpretation is changed + // (interleaved -> planar) + GMatDesc asPlanar() const + { + GAPI_Assert(planar == false); + GMatDesc desc(*this); + desc.planar = true; + return desc; + } + + // Meta combinator: return a new GMatDesc + // reinterpreting 1-channel input as planar image + // (size height is divided by plane number) + GMatDesc asPlanar(int planes) const + { + GAPI_Assert(planar == false); + GAPI_Assert(chan == 1); + GAPI_Assert(planes > 1); + GAPI_Assert(size.height % planes == 0); + GMatDesc desc(*this); + desc.size.height /= planes; + desc.chan = planes; + return desc.asPlanar(); + } + + // Meta combinator: return a new GMatDesc with planar flag set to false + // (no size changes are performed, only channel interpretation is changed + // (planar -> interleaved) + GMatDesc asInterleaved() const + { + GAPI_Assert(planar == true); + GMatDesc desc(*this); + desc.planar = false; + return desc; + } +}; + +static inline GMatDesc empty_gmat_desc() { return GMatDesc{-1,-1,{-1,-1}}; } + +#if !defined(GAPI_STANDALONE) +class Mat; +GAPI_EXPORTS GMatDesc descr_of(const cv::Mat &mat); +GAPI_EXPORTS GMatDesc descr_of(const cv::UMat &mat); +#endif // !defined(GAPI_STANDALONE) + +/** @} */ + +namespace gapi { namespace own { + GAPI_EXPORTS GMatDesc descr_of(const Mat &mat); +}}//gapi::own + +GAPI_EXPORTS std::ostream& operator<<(std::ostream& os, const cv::GMatDesc &desc); + +} // namespace cv + +#endif // OPENCV_GAPI_GMAT_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gmetaarg.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gmetaarg.hpp new file mode 100755 index 0000000..5b6e2ad --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gmetaarg.hpp @@ -0,0 +1,75 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GMETAARG_HPP +#define OPENCV_GAPI_GMETAARG_HPP + +#include +#include + +#include +#include + +#include +#include +#include + +namespace cv +{ +// FIXME: Rename to GMeta? +// FIXME: user shouldn't deal with it - put to detail? +// GMetaArg is an union type over descriptions of G-types which can serve as +// GComputation's in/output slots. +// +// GMetaArg objects are passed as arguments to GComputation::compile() +// to specify which data a compiled computation should be specialized on. +// For manual compile(), user must supply this metadata, in case of apply() +// this metadata is taken from arguments computation should operate on. +// +// The first type (monostate) is equal to "uninitialized"/"unresolved" meta. +using GMetaArg = util::variant + < util::monostate + , GMatDesc + , GScalarDesc + , GArrayDesc + >; +GAPI_EXPORTS std::ostream& operator<<(std::ostream& os, const GMetaArg &); + +using GMetaArgs = std::vector; + +namespace detail +{ + // These traits are used by GComputation::compile() + + // FIXME: is_constructible doesn't work as variant doesn't do any SFINAE + // in its current template constructor + + template struct is_meta_descr : std::false_type {}; + template<> struct is_meta_descr : std::true_type {}; + template<> struct is_meta_descr : std::true_type {}; + template<> struct is_meta_descr : std::true_type {}; + + template + using are_meta_descrs = all_satisfy; + + template + using are_meta_descrs_but_last = all_satisfy::type>; + +} // namespace detail + +class Mat; +class UMat; +GAPI_EXPORTS cv::GMetaArgs descr_of(const std::vector &vec); +GAPI_EXPORTS cv::GMetaArgs descr_of(const std::vector &vec); +namespace gapi { namespace own { + class Mat; + GAPI_EXPORTS cv::GMetaArgs descr_of(const std::vector &vec); +}} // namespace gapi::own + +} // namespace cv + +#endif // OPENCV_GAPI_GMETAARG_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gproto.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gproto.hpp new file mode 100755 index 0000000..b9e206a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gproto.hpp @@ -0,0 +1,129 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GPROTO_HPP +#define OPENCV_GAPI_GPROTO_HPP + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace cv { + +// FIXME: user shouldn't deal with it - put to detail? +// GProtoArg is an union type over G-types which can serve as +// GComputation's in/output slots. In other words, GProtoArg +// wraps any type which can serve as G-API exchange type. +// +// In Runtime, GProtoArgs are substituted with appropriate GRunArgs. +// +// GProtoArg objects are constructed in-place when user describes +// (captures) computations, user doesn't interact with these types +// directly. +using GProtoArg = util::variant + < GMat + , GMatP + , GScalar + , detail::GArrayU // instead of GArray + >; + +using GProtoArgs = std::vector; + +namespace detail +{ +template inline GProtoArgs packArgs(Ts... args) +{ + return GProtoArgs{ GProtoArg(wrap_gapi_helper::wrap(args))... }; +} + +} + +template +struct GIOProtoArgs +{ +public: + explicit GIOProtoArgs(const GProtoArgs& args) : m_args(args) {} + explicit GIOProtoArgs(GProtoArgs &&args) : m_args(std::move(args)) {} + + GProtoArgs m_args; +}; + +struct In_Tag{}; +struct Out_Tag{}; + +using GProtoInputArgs = GIOProtoArgs; +using GProtoOutputArgs = GIOProtoArgs; + +// Perfect forwarding +template inline GProtoInputArgs GIn(Ts&&... ts) +{ + return GProtoInputArgs(detail::packArgs(std::forward(ts)...)); +} + +template inline GProtoOutputArgs GOut(Ts&&... ts) +{ + return GProtoOutputArgs(detail::packArgs(std::forward(ts)...)); +} + +namespace detail +{ + // Extract elements form tuple + // FIXME: Someday utilize a generic tuple_to_vec<> routine + template + static GProtoOutputArgs getGOut_impl(const std::tuple& ts, detail::Seq) + { + return GProtoOutputArgs{ detail::packArgs(std::get(ts)...)}; + } +} + +template inline GProtoOutputArgs GOut(const std::tuple& ts) +{ + // TODO: think of std::forward(ts) + return detail::getGOut_impl(ts, typename detail::MkSeq::type()); +} + +// Takes rvalue as input arg +template inline GProtoOutputArgs GOut(std::tuple&& ts) +{ + // TODO: think of std::forward(ts) + return detail::getGOut_impl(ts, typename detail::MkSeq::type()); +} + +// Extract run-time arguments from node origin +// Can be used to extract constant values associated with G-objects +// (like GScalar) at graph construction time +GRunArg value_of(const GOrigin &origin); + +// Transform run-time computation arguments into a collection of metadata +// extracted from that arguments +GMetaArg GAPI_EXPORTS descr_of(const GRunArg &arg ); +GMetaArgs GAPI_EXPORTS descr_of(const GRunArgs &args); + +// Transform run-time operation result argument into metadata extracted from that argument +// Used to compare the metadata, which generated at compile time with the metadata result operation in run time +GMetaArg GAPI_EXPORTS descr_of(const GRunArgP& argp); + +// Checks if run-time computation argument can be described by metadata +bool GAPI_EXPORTS can_describe(const GMetaArg& meta, const GRunArg& arg); +bool GAPI_EXPORTS can_describe(const GMetaArgs& metas, const GRunArgs& args); + +// Checks if run-time computation result argument can be described by metadata. +// Used to check if the metadata generated at compile time +// coincides with output arguments passed to computation in cpu and ocl backends +bool GAPI_EXPORTS can_describe(const GMetaArg& meta, const GRunArgP& argp); + +} // namespace cv + +#endif // OPENCV_GAPI_GPROTO_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/core.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/core.hpp new file mode 100755 index 0000000..a7ee595 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/core.hpp @@ -0,0 +1,27 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GPU_CORE_API_HPP +#define OPENCV_GAPI_GPU_CORE_API_HPP +/** @file +* @deprecated Use instead. +*/ + +#include + +namespace cv { +namespace gapi { +namespace core { +namespace gpu { + using namespace ocl; +} // namespace gpu +} // namespace core +} // namespace gapi +} // namespace cv + + +#endif // OPENCV_GAPI_GPU_CORE_API_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/ggpukernel.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/ggpukernel.hpp new file mode 100755 index 0000000..b52c21d --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/ggpukernel.hpp @@ -0,0 +1,18 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GGPUKERNEL_HPP +#define OPENCV_GAPI_GGPUKERNEL_HPP +/** @file +* @deprecated Use instead. +*/ + +#include +#define GAPI_GPU_KERNEL GAPI_OCL_KERNEL + + +#endif // OPENCV_GAPI_GGPUKERNEL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/imgproc.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/imgproc.hpp new file mode 100755 index 0000000..b0df7ae --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gpu/imgproc.hpp @@ -0,0 +1,28 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GPU_IMGPROC_API_HPP +#define OPENCV_GAPI_GPU_IMGPROC_API_HPP +/** @file +* @deprecated Use instead. +*/ + +#include + + +namespace cv { +namespace gapi { +namespace imgproc { +namespace gpu { + using namespace ocl; +} // namespace gpu +} // namespace imgproc +} // namespace gapi +} // namespace cv + + +#endif // OPENCV_GAPI_GPU_IMGPROC_API_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gscalar.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gscalar.hpp new file mode 100755 index 0000000..f65741e --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gscalar.hpp @@ -0,0 +1,83 @@ +// This file is part of OpenCV project. + +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GSCALAR_HPP +#define OPENCV_GAPI_GSCALAR_HPP + +#include + +#include +#include // GShape +#include +#include + +namespace cv +{ +// Forward declaration; GNode and GOrigin are an internal +// (user-inaccessible) classes. +class GNode; +struct GOrigin; + +/** \addtogroup gapi_data_objects + * @{ + */ + +class GAPI_EXPORTS GScalar +{ +public: + GScalar(); // Empty constructor + explicit GScalar(const cv::gapi::own::Scalar& s); // Constant value constructor from cv::gapi::own::Scalar + explicit GScalar(cv::gapi::own::Scalar&& s); // Constant value move-constructor from cv::gapi::own::Scalar +#if !defined(GAPI_STANDALONE) + explicit GScalar(const cv::Scalar& s); // Constant value constructor from cv::Scalar +#endif // !defined(GAPI_STANDALONE) + GScalar(double v0); // Constant value constructor from double + GScalar(const GNode &n, std::size_t out); // Operation result constructor + + GOrigin& priv(); // Internal use only + const GOrigin& priv() const; // Internal use only + +private: + std::shared_ptr m_priv; +}; + +/** @} */ + +/** + * \addtogroup gapi_meta_args + * @{ + */ +struct GScalarDesc +{ + // NB.: right now it is empty + + inline bool operator== (const GScalarDesc &) const + { + return true; // NB: implement this method if GScalar meta appears + } + + inline bool operator!= (const GScalarDesc &rhs) const + { + return !(*this == rhs); + } +}; + +static inline GScalarDesc empty_scalar_desc() { return GScalarDesc(); } + +#if !defined(GAPI_STANDALONE) +GAPI_EXPORTS GScalarDesc descr_of(const cv::Scalar &scalar); +#endif // !defined(GAPI_STANDALONE) +/** @} */ + +GAPI_EXPORTS GScalarDesc descr_of(const cv::gapi::own::Scalar &scalar); + +std::ostream& operator<<(std::ostream& os, const cv::GScalarDesc &desc); + +} // namespace cv + +#endif // OPENCV_GAPI_GSCALAR_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gtransform.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gtransform.hpp new file mode 100755 index 0000000..e8ce161 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gtransform.hpp @@ -0,0 +1,98 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2019 Intel Corporation + +#ifndef OPENCV_GAPI_GTRANSFORM_HPP +#define OPENCV_GAPI_GTRANSFORM_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace cv +{ + +struct GAPI_EXPORTS GTransform +{ + using F = std::function; + + std::string description; + F pattern; + F substitute; + + GTransform(const std::string& d, const F &p, const F &s) : description(d), pattern(p), substitute(s){}; +}; + +namespace detail +{ + +template +struct TransHelper; + +template +struct TransHelper, Out> +{ + template + static GArgs invoke(Callable f, const GArgs &in_args, Seq, Seq) + { + const auto r = tuple_wrap_helper::get(f(in_args.at(IIs).template get()...)); + return GArgs{GArg(std::get(r))...}; + } + + static GArgs get_pattern(const GArgs &in_args) + { + return invoke(K::pattern, in_args, typename MkSeq::type(), + typename MkSeq::type>::value>::type()); + } + static GArgs get_substitute(const GArgs &in_args) + { + return invoke(K::substitute, in_args, typename MkSeq::type(), + typename MkSeq::type>::value>::type()); + } +}; +} // namespace detail + +template +class GTransformImpl; + +template +class GTransformImpl> : public cv::detail::TransHelper, R>, + public cv::detail::TransformTag +{ +public: + // FIXME: currently there is no check that transformations' signatures are unique + // and won't be any intersection in graph compilation stage + using API = K; + + static GTransform transformation() + { + return GTransform(K::descr(), &K::get_pattern, &K::get_substitute); + } +}; +} // namespace cv + +#define G_DESCR_HELPER_CLASS(Class) Class##DescrHelper + +#define G_DESCR_HELPER_BODY(Class, Descr) \ + namespace detail \ + { \ + struct G_DESCR_HELPER_CLASS(Class) \ + { \ + static constexpr const char *descr() { return Descr; }; \ + }; \ + } + +#define GAPI_TRANSFORM(Class, API, Descr) \ + G_DESCR_HELPER_BODY(Class, Descr) \ + struct Class final : public cv::GTransformImpl, \ + public detail::G_DESCR_HELPER_CLASS(Class) + +#endif // OPENCV_GAPI_GTRANSFORM_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gtype_traits.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gtype_traits.hpp new file mode 100755 index 0000000..b11a044 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gtype_traits.hpp @@ -0,0 +1,163 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GTYPE_TRAITS_HPP +#define OPENCV_GAPI_GTYPE_TRAITS_HPP + +#include +#include + +#include +#include +#include +#include +#include + +namespace cv +{ +namespace detail +{ + // FIXME: These traits and enum and possible numerous switch(kind) + // block may be replaced with a special Handler object or with + // a double dispatch + enum class ArgKind: int + { + OPAQUE, // Unknown, generic, opaque-to-GAPI data type - STATIC + GOBJREF, // reference to object + GMAT, // a cv::GMat + GMATP, // a cv::GMatP + GSCALAR, // a cv::GScalar + GARRAY, // a cv::GArrayU (note - exactly GArrayU, not GArray!) + }; + + // Describe G-API types (G-types) with traits. Mostly used by + // cv::GArg to store meta information about types passed into + // operation arguments. Please note that cv::GComputation is + // defined on GProtoArgs, not GArgs! + template struct GTypeTraits; + template struct GTypeTraits + { + static constexpr const ArgKind kind = ArgKind::OPAQUE; + }; + template<> struct GTypeTraits + { + static constexpr const ArgKind kind = ArgKind::GMAT; + static constexpr const GShape shape = GShape::GMAT; + }; + template<> struct GTypeTraits + { + static constexpr const ArgKind kind = ArgKind::GMATP; + static constexpr const GShape shape = GShape::GMAT; + }; + template<> struct GTypeTraits + { + static constexpr const ArgKind kind = ArgKind::GSCALAR; + static constexpr const GShape shape = GShape::GSCALAR; + }; + template struct GTypeTraits > + { + static constexpr const ArgKind kind = ArgKind::GARRAY; + static constexpr const GShape shape = GShape::GARRAY; + using host_type = std::vector; + using strip_type = cv::detail::VectorRef; + static cv::detail::GArrayU wrap_value(const cv::GArray &t) { return t.strip();} + static cv::detail::VectorRef wrap_in (const std::vector &t) { return detail::VectorRef(t); } + static cv::detail::VectorRef wrap_out ( std::vector &t) { return detail::VectorRef(t); } + }; + + // Tests if Trait for type T requires extra marshalling ("custom wrap") or not. + // If Traits has wrap_value() defined, it does. + template struct has_custom_wrap + { + template class check; + template static std::true_type test(check::wrap_value)> *); + template static std::false_type test(...); + using type = decltype(test(nullptr)); + static const constexpr bool value = std::is_same(nullptr))>::value; + }; + + // Resolve a Host type back to its associated G-Type. + // FIXME: Probably it can be avoided + // FIXME: GMatP is not present here. + // (Actually these traits is used only to check + // if associated G-type has custom wrap functions + // and GMat behavior is correct for GMatP) + template struct GTypeOf; +#if !defined(GAPI_STANDALONE) + template<> struct GTypeOf { using type = cv::GMat; }; + template<> struct GTypeOf { using type = cv::GMat; }; + template<> struct GTypeOf { using type = cv::GScalar; }; +#endif // !defined(GAPI_STANDALONE) + template<> struct GTypeOf { using type = cv::GMat; }; + template<> struct GTypeOf { using type = cv::GScalar; }; + template struct GTypeOf > { using type = cv::GArray; }; + template using g_type_of_t = typename GTypeOf::type; + + // Marshalling helper for G-types and its Host types. Helps G-API + // to store G types in internal generic containers for further + // processing. Implements the following callbacks: + // + // * wrap() - converts user-facing G-type into an internal one + // for internal storage. + // Used when G-API operation is instantiated (G::on(), + // etc) during expressing a pipeline. Mostly returns input + // value "as is" except the case when G-type is a template. For + // template G-classes, calls custom wrap() from Traits. + // The value returned by wrap() is then wrapped into GArg() and + // stored in G-API metadata. + // + // Example: + // - cv::GMat arguments are passed as-is. + // - integers, pointers, STL containers, user types are passed as-is. + // - cv::GArray is converted to cv::GArrayU. + // + // * wrap_in() / wrap_out() - convert Host type associated with + // G-type to internal representation type. + // + // - For "simple" (non-template) G-types, returns value as-is. + // Example: cv::GMat has host type cv::Mat, when user passes a + // cv::Mat, system stores it internally as cv::Mat. + // + // - For "complex" (template) G-types, utilizes custom + // wrap_in()/wrap_out() as described in Traits. + // Example: cv::GArray has host type std::vector, when + // user passes a std::vector, system stores it + // internally as VectorRef (with stripped away). + template struct WrapValue + { + static auto wrap(const T& t) -> + typename std::remove_reference::type + { + return static_cast::type>(t); + } + + template static U wrap_in (const U &u) { return u; } + template static U* wrap_out(U &u) { return &u; } + }; + template struct WrapValue::value>::type> + { + static auto wrap(const T& t) -> decltype(GTypeTraits::wrap_value(t)) + { + return GTypeTraits::wrap_value(t); + } + template static auto wrap_in (const U &u) -> typename GTypeTraits::strip_type + { + return GTypeTraits::wrap_in(u); + } + template static auto wrap_out(U &u) -> typename GTypeTraits::strip_type + { + return GTypeTraits::wrap_out(u); + } + }; + + template using wrap_gapi_helper = WrapValue::type>; + template using wrap_host_helper = WrapValue >::type>; + +} // namespace detail +} // namespace cv + +#endif // OPENCV_GAPI_GTYPE_TRAITS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/gtyped.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/gtyped.hpp new file mode 100755 index 0000000..8e48e91 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/gtyped.hpp @@ -0,0 +1,187 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GTYPED_HPP +#define OPENCV_GAPI_GTYPED_HPP +#if !defined(GAPI_STANDALONE) + +#include + +#include +#include +#include +#include + +namespace cv { + +namespace detail +{ + // FIXME: How to prevent coolhackers from extending it by their own types? + // FIXME: ...Should we care? + template struct ProtoToParam; + template<> struct ProtoToParam { using type = cv::Mat; }; + template<> struct ProtoToParam { using type = cv::Scalar; }; + template struct ProtoToParam > { using type = std::vector; }; + template using ProtoToParamT = typename ProtoToParam::type; + + template struct ProtoToMeta; + template<> struct ProtoToMeta { using type = cv::GMatDesc; }; + template<> struct ProtoToMeta { using type = cv::GScalarDesc; }; + template struct ProtoToMeta > { using type = cv::GArrayDesc; }; + template using ProtoToMetaT = typename ProtoToMeta::type; + + //workaround for MSVC 19.0 bug + template + auto make_default()->decltype(T{}) {return {};} +}; // detail + +template class GComputationT; + +// Single return value implementation +template class GComputationT +{ +public: + typedef std::function Gen; + + class GCompiledT + { + private: + friend class GComputationT; + + cv::GCompiled m_comp; + + explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {} + + public: + GCompiledT() {} + + void operator()(detail::ProtoToParamT... inArgs, + detail::ProtoToParamT &outArg) + { + m_comp(cv::gin(inArgs...), cv::gout(outArg)); + } + + explicit operator bool() const + { + return static_cast(m_comp); + } + }; + +private: + typedef std::pair Captured; + + Captured capture(const Gen& g, Args... args) + { + return Captured(g(args...), cv::GIn(args...)); + } + + Captured m_capture; + cv::GComputation m_comp; + +public: + GComputationT(const Gen &generator) + : m_capture(capture(generator, detail::make_default()...)) + , m_comp(cv::GProtoInputArgs(std::move(m_capture.second)), + cv::GOut(m_capture.first)) + { + } + + void apply(detail::ProtoToParamT... inArgs, + detail::ProtoToParamT &outArg) + { + m_comp.apply(cv::gin(inArgs...), cv::gout(outArg)); + } + + GCompiledT compile(detail::ProtoToMetaT... inDescs) + { + GMetaArgs inMetas = { GMetaArg(inDescs)... }; + return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs())); + } + + GCompiledT compile(detail::ProtoToMetaT... inDescs, GCompileArgs &&args) + { + GMetaArgs inMetas = { GMetaArg(inDescs)... }; + return GCompiledT(m_comp.compile(std::move(inMetas), std::move(args))); + } +}; + +// Multiple (fixed) return value implementation. FIXME: How to avoid copy-paste? +template class GComputationT(Args...)> +{ +public: + typedef std::function(Args...)> Gen; + + class GCompiledT + { + private: + friend class GComputationT(Args...)>; + + cv::GCompiled m_comp; + explicit GCompiledT(const cv::GCompiled &comp) : m_comp(comp) {} + + public: + GCompiledT() {} + + void operator()(detail::ProtoToParamT... inArgs, + detail::ProtoToParamT&... outArgs) + { + m_comp(cv::gin(inArgs...), cv::gout(outArgs...)); + } + + explicit operator bool() const + { + return static_cast(m_comp); + } + }; + +private: + typedef std::pair Captured; + + template + Captured capture(GProtoArgs &&args, const std::tuple &rr, detail::Seq) + { + return Captured(cv::GOut(std::get(rr)...).m_args, args); + } + + Captured capture(const Gen& g, Args... args) + { + return capture(cv::GIn(args...).m_args, g(args...), typename detail::MkSeq::type()); + } + + Captured m_capture; + cv::GComputation m_comp; + +public: + GComputationT(const Gen &generator) + : m_capture(capture(generator, detail::make_default()...)) + , m_comp(cv::GProtoInputArgs(std::move(m_capture.second)), + cv::GProtoOutputArgs(std::move(m_capture.first))) + { + } + + void apply(detail::ProtoToParamT... inArgs, + detail::ProtoToParamT&... outArgs) + { + m_comp.apply(cv::gin(inArgs...), cv::gout(outArgs...)); + } + + GCompiledT compile(detail::ProtoToMetaT... inDescs) + { + GMetaArgs inMetas = { GMetaArg(inDescs)... }; + return GCompiledT(m_comp.compile(std::move(inMetas), GCompileArgs())); + } + + GCompiledT compile(detail::ProtoToMetaT... inDescs, GCompileArgs &&args) + { + GMetaArgs inMetas = { GMetaArg(inDescs)... }; + return GCompiledT(m_comp.compile(std::move(inMetas), std::move(args))); + } +}; + +} // namespace cv +#endif // !defined(GAPI_STANDALONE) +#endif // OPENCV_GAPI_GTYPED_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/imgproc.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/imgproc.hpp new file mode 100755 index 0000000..ad3f7c1 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/imgproc.hpp @@ -0,0 +1,919 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_IMGPROC_HPP +#define OPENCV_GAPI_IMGPROC_HPP + +#include + +#include // std::tuple + +#include +#include +#include + + +/** \defgroup gapi_imgproc G-API image processing functionality +@{ + @defgroup gapi_filters Graph API: Image filters + @defgroup gapi_colorconvert Graph API: Converting image from one color space to another +@} + */ + +namespace cv { namespace gapi { + +namespace imgproc { + using GMat2 = std::tuple; + using GMat3 = std::tuple; // FIXME: how to avoid this? + + G_TYPED_KERNEL(GFilter2D, ,"org.opencv.imgproc.filters.filter2D") { + static GMatDesc outMeta(GMatDesc in, int ddepth, Mat, Point, Scalar, int, Scalar) { + return in.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GSepFilter, , "org.opencv.imgproc.filters.sepfilter") { + static GMatDesc outMeta(GMatDesc in, int ddepth, Mat, Mat, Point, Scalar, int, Scalar) { + return in.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GBoxFilter, , "org.opencv.imgproc.filters.boxfilter") { + static GMatDesc outMeta(GMatDesc in, int ddepth, Size, Point, bool, int, Scalar) { + return in.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL(GBlur, , "org.opencv.imgproc.filters.blur"){ + static GMatDesc outMeta(GMatDesc in, Size, Point, int, Scalar) { + return in; + } + }; + + G_TYPED_KERNEL(GGaussBlur, , "org.opencv.imgproc.filters.gaussianBlur") { + static GMatDesc outMeta(GMatDesc in, Size, double, double, int, Scalar) { + return in; + } + }; + + G_TYPED_KERNEL(GMedianBlur, , "org.opencv.imgproc.filters.medianBlur") { + static GMatDesc outMeta(GMatDesc in, int) { + return in; + } + }; + + G_TYPED_KERNEL(GErode, , "org.opencv.imgproc.filters.erode") { + static GMatDesc outMeta(GMatDesc in, Mat, Point, int, int, Scalar) { + return in; + } + }; + + G_TYPED_KERNEL(GDilate, , "org.opencv.imgproc.filters.dilate") { + static GMatDesc outMeta(GMatDesc in, Mat, Point, int, int, Scalar) { + return in; + } + }; + + G_TYPED_KERNEL(GSobel, , "org.opencv.imgproc.filters.sobel") { + static GMatDesc outMeta(GMatDesc in, int ddepth, int, int, int, double, double, int, Scalar) { + return in.withDepth(ddepth); + } + }; + + G_TYPED_KERNEL_M(GSobelXY, , "org.opencv.imgproc.filters.sobelxy") { + static std::tuple outMeta(GMatDesc in, int ddepth, int, int, double, double, int, Scalar) { + return std::make_tuple(in.withDepth(ddepth), in.withDepth(ddepth)); + } + }; + + G_TYPED_KERNEL(GEqHist, , "org.opencv.imgproc.equalizeHist"){ + static GMatDesc outMeta(GMatDesc in) { + return in.withType(CV_8U, 1); + } + }; + + G_TYPED_KERNEL(GCanny, , "org.opencv.imgproc.canny"){ + static GMatDesc outMeta(GMatDesc in, double, double, int, bool) { + return in.withType(CV_8U, 1); + } + }; + + G_TYPED_KERNEL(GRGB2YUV, , "org.opencv.imgproc.colorconvert.rgb2yuv") { + static GMatDesc outMeta(GMatDesc in) { + return in; // type still remains CV_8UC3; + } + }; + + G_TYPED_KERNEL(GYUV2RGB, , "org.opencv.imgproc.colorconvert.yuv2rgb") { + static GMatDesc outMeta(GMatDesc in) { + return in; // type still remains CV_8UC3; + } + }; + + G_TYPED_KERNEL(GNV12toRGB, , "org.opencv.imgproc.colorconvert.nv12torgb") { + static GMatDesc outMeta(GMatDesc in_y, GMatDesc in_uv) { + GAPI_Assert(in_y.chan == 1); + GAPI_Assert(in_uv.chan == 2); + GAPI_Assert(in_y.depth == CV_8U); + GAPI_Assert(in_uv.depth == CV_8U); + // UV size should be aligned with Y + GAPI_Assert(in_y.size.width == 2 * in_uv.size.width); + GAPI_Assert(in_y.size.height == 2 * in_uv.size.height); + return in_y.withType(CV_8U, 3); // type will be CV_8UC3; + } + }; + + G_TYPED_KERNEL(GNV12toBGR, , "org.opencv.imgproc.colorconvert.nv12tobgr") { + static GMatDesc outMeta(GMatDesc in_y, GMatDesc in_uv) { + GAPI_Assert(in_y.chan == 1); + GAPI_Assert(in_uv.chan == 2); + GAPI_Assert(in_y.depth == CV_8U); + GAPI_Assert(in_uv.depth == CV_8U); + // UV size should be aligned with Y + GAPI_Assert(in_y.size.width == 2 * in_uv.size.width); + GAPI_Assert(in_y.size.height == 2 * in_uv.size.height); + return in_y.withType(CV_8U, 3); // type will be CV_8UC3; + } + }; + + G_TYPED_KERNEL(GRGB2Lab, , "org.opencv.imgproc.colorconvert.rgb2lab") { + static GMatDesc outMeta(GMatDesc in) { + return in; // type still remains CV_8UC3; + } + }; + + G_TYPED_KERNEL(GBGR2LUV, , "org.opencv.imgproc.colorconvert.bgr2luv") { + static GMatDesc outMeta(GMatDesc in) { + return in; // type still remains CV_8UC3; + } + }; + + G_TYPED_KERNEL(GLUV2BGR, , "org.opencv.imgproc.colorconvert.luv2bgr") { + static GMatDesc outMeta(GMatDesc in) { + return in; // type still remains CV_8UC3; + } + }; + + G_TYPED_KERNEL(GYUV2BGR, , "org.opencv.imgproc.colorconvert.yuv2bgr") { + static GMatDesc outMeta(GMatDesc in) { + return in; // type still remains CV_8UC3; + } + }; + + G_TYPED_KERNEL(GBGR2YUV, , "org.opencv.imgproc.colorconvert.bgr2yuv") { + static GMatDesc outMeta(GMatDesc in) { + return in; // type still remains CV_8UC3; + } + }; + + G_TYPED_KERNEL(GRGB2Gray, , "org.opencv.imgproc.colorconvert.rgb2gray") { + static GMatDesc outMeta(GMatDesc in) { + return in.withType(CV_8U, 1); + } + }; + + G_TYPED_KERNEL(GRGB2GrayCustom, , "org.opencv.imgproc.colorconvert.rgb2graycustom") { + static GMatDesc outMeta(GMatDesc in, float, float, float) { + return in.withType(CV_8U, 1); + } + }; + + G_TYPED_KERNEL(GBGR2Gray, , "org.opencv.imgproc.colorconvert.bgr2gray") { + static GMatDesc outMeta(GMatDesc in) { + return in.withType(CV_8U, 1); + } + }; + + G_TYPED_KERNEL(GBayerGR2RGB, , "org.opencv.imgproc.colorconvert.bayergr2rgb") { + static cv::GMatDesc outMeta(cv::GMatDesc in) { + return in.withType(CV_8U, 3); + } + }; + + G_TYPED_KERNEL(GRGB2HSV, , "org.opencv.imgproc.colorconvert.rgb2hsv") { + static cv::GMatDesc outMeta(cv::GMatDesc in) { + return in; + } + }; + + G_TYPED_KERNEL(GRGB2YUV422, , "org.opencv.imgproc.colorconvert.rgb2yuv422") { + static cv::GMatDesc outMeta(cv::GMatDesc in) { + GAPI_Assert(in.depth == CV_8U); + GAPI_Assert(in.chan == 3); + return in.withType(in.depth, 2); + } + }; + + G_TYPED_KERNEL(GNV12toRGBp, , "org.opencv.colorconvert.imgproc.nv12torgbp") { + static GMatDesc outMeta(GMatDesc inY, GMatDesc inUV) { + GAPI_Assert(inY.depth == CV_8U); + GAPI_Assert(inUV.depth == CV_8U); + GAPI_Assert(inY.chan == 1); + GAPI_Assert(inY.planar == false); + GAPI_Assert(inUV.chan == 2); + GAPI_Assert(inUV.planar == false); + GAPI_Assert(inY.size.width == 2 * inUV.size.width); + GAPI_Assert(inY.size.height == 2 * inUV.size.height); + return inY.withType(CV_8U, 3).asPlanar(); + } + }; + + G_TYPED_KERNEL(GNV12toBGRp, , "org.opencv.colorconvert.imgproc.nv12tobgrp") { + static GMatDesc outMeta(GMatDesc inY, GMatDesc inUV) { + GAPI_Assert(inY.depth == CV_8U); + GAPI_Assert(inUV.depth == CV_8U); + GAPI_Assert(inY.chan == 1); + GAPI_Assert(inY.planar == false); + GAPI_Assert(inUV.chan == 2); + GAPI_Assert(inUV.planar == false); + GAPI_Assert(inY.size.width == 2 * inUV.size.width); + GAPI_Assert(inY.size.height == 2 * inUV.size.height); + return inY.withType(CV_8U, 3).asPlanar(); + } + }; + +} + + +//! @addtogroup gapi_filters +//! @{ +/** @brief Applies a separable linear filter to a matrix(image). + +The function applies a separable linear filter to the matrix. That is, first, every row of src is +filtered with the 1D kernel kernelX. Then, every column of the result is filtered with the 1D +kernel kernelY. The final result is returned. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note In case of floating-point computation, rounding to nearest even is procedeed +if hardware supports it (if not - to nearest value). + +@note Function textual ID is "org.opencv.imgproc.filters.sepfilter" +@param src Source image. +@param ddepth desired depth of the destination image (the following combinations of src.depth() and ddepth are supported: + + src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F + src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F + src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F + src.depth() = CV_64F, ddepth = -1/CV_64F + +when ddepth=-1, the output image will have the same depth as the source) +@param kernelX Coefficients for filtering each row. +@param kernelY Coefficients for filtering each column. +@param anchor Anchor position within the kernel. The default value \f$(-1,-1)\f$ means that the anchor +is at the kernel center. +@param delta Value added to the filtered results before storing them. +@param borderType Pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of constant border type +@sa boxFilter, gaussianBlur, medianBlur + */ +GAPI_EXPORTS GMat sepFilter(const GMat& src, int ddepth, const Mat& kernelX, const Mat& kernelY, const Point& anchor /*FIXME: = Point(-1,-1)*/, + const Scalar& delta /*FIXME = GScalar(0)*/, int borderType = BORDER_DEFAULT, + const Scalar& borderValue = Scalar(0)); + +/** @brief Convolves an image with the kernel. + +The function applies an arbitrary linear filter to an image. When +the aperture is partially outside the image, the function interpolates outlier pixel values +according to the specified border mode. + +The function does actually compute correlation, not the convolution: + +\f[\texttt{dst} (x,y) = \sum _{ \stackrel{0\leq x' < \texttt{kernel.cols},}{0\leq y' < \texttt{kernel.rows}} } \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} )\f] + +That is, the kernel is not mirrored around the anchor point. If you need a real convolution, flip +the kernel using flip and set the new anchor to `(kernel.cols - anchor.x - 1, kernel.rows - +anchor.y - 1)`. + +Supported matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. +Output image must have the same size and number of channels an input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.filter2D" + +@param src input image. +@param ddepth desired depth of the destination image +@param kernel convolution kernel (or rather a correlation 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 split and process them individually. +@param anchor anchor of the kernel that indicates the relative position of a filtered point within +the kernel; the anchor should lie within the kernel; default value (-1,-1) means that the anchor +is at the kernel center. +@param delta optional value added to the filtered pixels before storing them in dst. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of constant border type +@sa sepFilter + */ +GAPI_EXPORTS GMat filter2D(const GMat& src, int ddepth, const Mat& kernel, const Point& anchor = Point(-1,-1), const Scalar& delta = Scalar(0), + int borderType = BORDER_DEFAULT, const Scalar& borderValue = Scalar(0)); + + +/** @brief Blurs an image using the box filter. + +The function smooths an image using the kernel: + +\f[\texttt{K} = \alpha \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \end{bmatrix}\f] + +where + +\f[\alpha = \fork{\frac{1}{\texttt{ksize.width*ksize.height}}}{when \texttt{normalize=true}}{1}{otherwise}\f] + +Unnormalized box filter is useful for computing various integral characteristics over each pixel +neighborhood, such as covariance matrices of image derivatives (used in dense optical flow +algorithms, and so on). If you need to compute pixel sums over variable-size windows, use cv::integral. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.boxfilter" + +@param src Source image. +@param dtype the output image depth (-1 to set the input image data type). +@param ksize blurring kernel size. +@param anchor Anchor position within the kernel. The default value \f$(-1,-1)\f$ means that the anchor +is at the kernel center. +@param normalize flag, specifying whether the kernel is normalized by its area or not. +@param borderType Pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of constant border type +@sa sepFilter, gaussianBlur, medianBlur, integral + */ +GAPI_EXPORTS GMat boxFilter(const GMat& src, int dtype, const Size& ksize, const Point& anchor = Point(-1,-1), + bool normalize = true, int borderType = BORDER_DEFAULT, + const Scalar& borderValue = Scalar(0)); + +/** @brief Blurs an image using the normalized box filter. + +The function smooths an image using the kernel: + +\f[\texttt{K} = \frac{1}{\texttt{ksize.width*ksize.height}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \end{bmatrix}\f] + +The call `blur(src, dst, ksize, anchor, borderType)` is equivalent to `boxFilter(src, dst, src.type(), +anchor, true, borderType)`. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.blur" + +@param src Source image. +@param ksize blurring kernel size. +@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel +center. +@param borderType border mode used to extrapolate pixels outside of the image, see cv::BorderTypes +@param borderValue border value in case of constant border type +@sa boxFilter, bilateralFilter, GaussianBlur, medianBlur + */ +GAPI_EXPORTS GMat blur(const GMat& src, const Size& ksize, const Point& anchor = Point(-1,-1), + int borderType = BORDER_DEFAULT, const Scalar& borderValue = Scalar(0)); + + +//GAPI_EXPORTS_W void blur( InputArray src, OutputArray dst, + // Size ksize, Point anchor = Point(-1,-1), + // int borderType = BORDER_DEFAULT ); + + +/** @brief Blurs an image using a Gaussian filter. + +The function filter2Ds the source image with the specified Gaussian kernel. +Output image must have the same type and number of channels an input image. + +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.gaussianBlur" + +@param src input image; +@param ksize Gaussian kernel size. ksize.width and ksize.height can differ but they both must be +positive and odd. Or, they can be zero's and then they are computed from sigma. +@param sigmaX Gaussian kernel standard deviation in X direction. +@param sigmaY Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be +equal to sigmaX, if both sigmas are zeros, they are computed from ksize.width and ksize.height, +respectively (see cv::getGaussianKernel for details); to fully control the result regardless of +possible future modifications of all this semantics, it is recommended to specify all of ksize, +sigmaX, and sigmaY. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of constant border type +@sa sepFilter, boxFilter, medianBlur + */ +GAPI_EXPORTS GMat gaussianBlur(const GMat& src, const Size& ksize, double sigmaX, double sigmaY = 0, + int borderType = BORDER_DEFAULT, const Scalar& borderValue = Scalar(0)); + +/** @brief Blurs an image using the median filter. + +The function smoothes an image using the median filter with the \f$\texttt{ksize} \times +\texttt{ksize}\f$ aperture. Each channel of a multi-channel image is processed independently. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. +The median filter uses cv::BORDER_REPLICATE internally to cope with border pixels, see cv::BorderTypes + +@note Function textual ID is "org.opencv.imgproc.filters.medianBlur" + +@param src input matrix (image) +@param ksize aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ... +@sa boxFilter, gaussianBlur + */ +GAPI_EXPORTS GMat medianBlur(const GMat& src, int ksize); + +/** @brief Erodes an image by using a specific structuring element. + +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: + +\f[\texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f] + +Erosion can be applied several (iterations) times. In case of multi-channel images, each channel is processed independently. +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, and @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.erode" + +@param src input image +@param kernel structuring element used for erosion; if `element=Mat()`, a `3 x 3` rectangular +structuring element is used. Kernel can be created using getStructuringElement. +@param anchor position of the anchor within the element; default value (-1, -1) means that the +anchor is at the element center. +@param iterations number of times erosion is applied. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of a constant border +@sa dilate + */ +GAPI_EXPORTS GMat erode(const GMat& src, const Mat& kernel, const Point& anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue()); + +/** @brief Erodes an image by using 3 by 3 rectangular structuring element. + +The function erodes the source image using the rectangular structuring element with rectangle center as an anchor. +Erosion can be applied several (iterations) times. In case of multi-channel images, each channel is processed independently. +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, and @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@param src input image +@param iterations number of times erosion is applied. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of a constant border +@sa erode, dilate3x3 + */ +GAPI_EXPORTS GMat erode3x3(const GMat& src, int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue()); + +/** @brief Dilates an image by using a specific structuring element. + +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: +\f[\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f] + +Dilation can be applied several (iterations) times. In case of multi-channel images, each channel is processed independently. +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, and @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.dilate" + +@param src input image. +@param kernel structuring element used for dilation; if elemenat=Mat(), a 3 x 3 rectangular +structuring element is used. Kernel can be created using getStructuringElement +@param anchor position of the anchor within the element; default value (-1, -1) means that the +anchor is at the element center. +@param iterations number of times dilation is applied. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of a constant border +@sa erode, morphologyEx, getStructuringElement + */ +GAPI_EXPORTS GMat dilate(const GMat& src, const Mat& kernel, const Point& anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue()); + +/** @brief Dilates an image by using 3 by 3 rectangular structuring element. + +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: +\f[\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f] + +Dilation can be applied several (iterations) times. In case of multi-channel images, each channel is processed independently. +Supported input matrix data types are @ref CV_8UC1, @ref CV_8UC3, @ref CV_16UC1, @ref CV_16SC1, and @ref CV_32FC1. +Output image must have the same type, size, and number of channels as the input image. +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.dilate" + +@param src input image. +@param iterations number of times dilation is applied. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of a constant border +@sa dilate, erode3x3 + */ + +GAPI_EXPORTS GMat dilate3x3(const GMat& src, int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue()); + +/** @brief Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator. + +In all cases except one, the \f$\texttt{ksize} \times \texttt{ksize}\f$ separable kernel is used to +calculate the derivative. When \f$\texttt{ksize = 1}\f$, the \f$3 \times 1\f$ or \f$1 \times 3\f$ +kernel is used (that is, no Gaussian smoothing is done). `ksize = 1` can only be used for the first +or the second x- or y- derivatives. + +There is also the special value `ksize = FILTER_SCHARR (-1)` that corresponds to the \f$3\times3\f$ Scharr +filter that may give more accurate results than the \f$3\times3\f$ Sobel. The Scharr aperture is + +\f[\vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3}\f] + +for the x-derivative, or transposed for the y-derivative. + +The function calculates an image derivative by convolving the image with the appropriate kernel: + +\f[\texttt{dst} = \frac{\partial^{xorder+yorder} \texttt{src}}{\partial x^{xorder} \partial y^{yorder}}\f] + +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, ksize = 3) +or ( xorder = 0, yorder = 1, ksize = 3) to calculate the first x- or y- image derivative. The first +case corresponds to a kernel of: + +\f[\vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1}\f] + +The second case corresponds to a kernel of: + +\f[\vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1}\f] + +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.sobel" + +@param src input image. +@param ddepth output image depth, see @ref filter_depths "combinations"; in the case of + 8-bit input images it will result in truncated derivatives. +@param dx order of the derivative x. +@param dy order of the derivative y. +@param ksize size of the extended Sobel kernel; it must be odd. +@param scale optional scale factor for the computed derivative values; by default, no scaling is +applied (see cv::getDerivKernels for details). +@param delta optional delta value that is added to the results prior to storing them in dst. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of constant border type +@sa filter2D, gaussianBlur, cartToPolar + */ +GAPI_EXPORTS GMat Sobel(const GMat& src, int ddepth, int dx, int dy, int ksize = 3, + double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT, + const Scalar& borderValue = Scalar(0)); + +/** @brief Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator. + +In all cases except one, the \f$\texttt{ksize} \times \texttt{ksize}\f$ separable kernel is used to +calculate the derivative. When \f$\texttt{ksize = 1}\f$, the \f$3 \times 1\f$ or \f$1 \times 3\f$ +kernel is used (that is, no Gaussian smoothing is done). `ksize = 1` can only be used for the first +or the second x- or y- derivatives. + +There is also the special value `ksize = FILTER_SCHARR (-1)` that corresponds to the \f$3\times3\f$ Scharr +filter that may give more accurate results than the \f$3\times3\f$ Sobel. The Scharr aperture is + +\f[\vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3}\f] + +for the x-derivative, or transposed for the y-derivative. + +The function calculates an image derivative by convolving the image with the appropriate kernel: + +\f[\texttt{dst} = \frac{\partial^{xorder+yorder} \texttt{src}}{\partial x^{xorder} \partial y^{yorder}}\f] + +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, ksize = 3) +or ( xorder = 0, yorder = 1, ksize = 3) to calculate the first x- or y- image derivative. The first +case corresponds to a kernel of: + +\f[\vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1}\f] + +The second case corresponds to a kernel of: + +\f[\vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1}\f] + +@note First returned matrix correspons to dx derivative while the second one to dy. + +@note Rounding to nearest even is procedeed if hardware supports it, if not - to nearest. + +@note Function textual ID is "org.opencv.imgproc.filters.sobelxy" + +@param src input image. +@param ddepth output image depth, see @ref filter_depths "combinations"; in the case of + 8-bit input images it will result in truncated derivatives. +@param order order of the derivatives. +@param ksize size of the extended Sobel kernel; it must be odd. +@param scale optional scale factor for the computed derivative values; by default, no scaling is +applied (see cv::getDerivKernels for details). +@param delta optional delta value that is added to the results prior to storing them in dst. +@param borderType pixel extrapolation method, see cv::BorderTypes +@param borderValue border value in case of constant border type +@sa filter2D, gaussianBlur, cartToPolar + */ +GAPI_EXPORTS std::tuple SobelXY(const GMat& src, int ddepth, int order, int ksize = 3, + double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT, + const Scalar& borderValue = Scalar(0)); + +/** @brief Finds edges in an image using the Canny algorithm. + +The function finds edges in the input image and marks them in the output map edges using the +Canny algorithm. The smallest value between threshold1 and threshold2 is used for edge linking. The +largest value is used to find initial segments of strong edges. See + + +@note Function textual ID is "org.opencv.imgproc.filters.canny" + +@param image 8-bit input image. +@param threshold1 first threshold for the hysteresis procedure. +@param threshold2 second threshold for the hysteresis procedure. +@param apertureSize aperture size for the Sobel operator. +@param L2gradient a flag, indicating whether a more accurate \f$L_2\f$ norm +\f$=\sqrt{(dI/dx)^2 + (dI/dy)^2}\f$ should be used to calculate the image gradient magnitude ( +L2gradient=true ), or whether the default \f$L_1\f$ norm \f$=|dI/dx|+|dI/dy|\f$ is enough ( +L2gradient=false ). + */ +GAPI_EXPORTS GMat Canny(const GMat& image, double threshold1, double threshold2, + int apertureSize = 3, bool L2gradient = false); + +/** @brief Equalizes the histogram of a grayscale image. + +The function equalizes the histogram of the input image using the following algorithm: + +- Calculate the histogram \f$H\f$ for src . +- Normalize the histogram so that the sum of histogram bins is 255. +- Compute the integral of the histogram: +\f[H'_i = \sum _{0 \le j < i} H(j)\f] +- Transform the image using \f$H'\f$ as a look-up table: \f$\texttt{dst}(x,y) = H'(\texttt{src}(x,y))\f$ + +The algorithm normalizes the brightness and increases the contrast of the image. +@note The returned image is of the same size and type as input. + +@note Function textual ID is "org.opencv.imgproc.equalizeHist" + +@param src Source 8-bit single channel image. + */ +GAPI_EXPORTS GMat equalizeHist(const GMat& src); + +//! @} gapi_filters + +//! @addtogroup gapi_colorconvert +//! @{ +/** @brief Converts an image from RGB color space to gray-scaled. +The conventional ranges for R, G, and B channel values are 0 to 255. +Resulting gray color value computed as +\f[\texttt{dst} (I)= \texttt{0.299} * \texttt{src}(I).R + \texttt{0.587} * \texttt{src}(I).G + \texttt{0.114} * \texttt{src}(I).B \f] + +@note Function textual ID is "org.opencv.imgproc.colorconvert.rgb2gray" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC1. +@sa RGB2YUV + */ +GAPI_EXPORTS GMat RGB2Gray(const GMat& src); + +/** @overload +Resulting gray color value computed as +\f[\texttt{dst} (I)= \texttt{rY} * \texttt{src}(I).R + \texttt{gY} * \texttt{src}(I).G + \texttt{bY} * \texttt{src}(I).B \f] + +@note Function textual ID is "org.opencv.imgproc.colorconvert.rgb2graycustom" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC1. +@param rY float multiplier for R channel. +@param gY float multiplier for G channel. +@param bY float multiplier for B channel. +@sa RGB2YUV + */ +GAPI_EXPORTS GMat RGB2Gray(const GMat& src, float rY, float gY, float bY); + +/** @brief Converts an image from BGR color space to gray-scaled. +The conventional ranges for B, G, and R channel values are 0 to 255. +Resulting gray color value computed as +\f[\texttt{dst} (I)= \texttt{0.114} * \texttt{src}(I).B + \texttt{0.587} * \texttt{src}(I).G + \texttt{0.299} * \texttt{src}(I).R \f] + +@note Function textual ID is "org.opencv.imgproc.colorconvert.bgr2gray" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC1. +@sa BGR2LUV + */ +GAPI_EXPORTS GMat BGR2Gray(const GMat& src); + +/** @brief Converts an image from RGB color space to YUV color space. + +The function converts an input image from RGB color space to YUV. +The conventional ranges for R, G, and B channel values are 0 to 255. + +In case of linear transformations, the range does not matter. But in case of a non-linear +transformation, an input RGB image should be normalized to the proper value range to get the correct +results, like here, at RGB \f$\rightarrow\f$ Y\*u\*v\* transformation. +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.rgb2yuv" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. +@sa YUV2RGB, RGB2Lab +*/ +GAPI_EXPORTS GMat RGB2YUV(const GMat& src); + +/** @brief Converts an image from BGR color space to LUV color space. + +The function converts an input image from BGR color space to LUV. +The conventional ranges for B, G, and R channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.bgr2luv" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. +@sa RGB2Lab, RGB2LUV +*/ +GAPI_EXPORTS GMat BGR2LUV(const GMat& src); + +/** @brief Converts an image from LUV color space to BGR color space. + +The function converts an input image from LUV color space to BGR. +The conventional ranges for B, G, and R channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.luv2bgr" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. +@sa BGR2LUV +*/ +GAPI_EXPORTS GMat LUV2BGR(const GMat& src); + +/** @brief Converts an image from YUV color space to BGR color space. + +The function converts an input image from YUV color space to BGR. +The conventional ranges for B, G, and R channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.yuv2bgr" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. +@sa BGR2YUV +*/ +GAPI_EXPORTS GMat YUV2BGR(const GMat& src); + +/** @brief Converts an image from BGR color space to YUV color space. + +The function converts an input image from BGR color space to YUV. +The conventional ranges for B, G, and R channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.bgr2yuv" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. +@sa YUV2BGR +*/ +GAPI_EXPORTS GMat BGR2YUV(const GMat& src); + +/** @brief Converts an image from RGB color space to Lab color space. + +The function converts an input image from BGR color space to Lab. +The conventional ranges for R, G, and B channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC1. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.rgb2lab" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC1. +@sa RGB2YUV, RGB2LUV +*/ +GAPI_EXPORTS GMat RGB2Lab(const GMat& src); + +/** @brief Converts an image from YUV color space to RGB. +The function converts an input image from YUV color space to RGB. +The conventional ranges for Y, U, and V channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.yuv2rgb" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. + +@sa RGB2Lab, RGB2YUV +*/ +GAPI_EXPORTS GMat YUV2RGB(const GMat& src); + +/** @brief Converts an image from NV12 (YUV420p) color space to RGB. +The function converts an input image from NV12 color space to RGB. +The conventional ranges for Y, U, and V channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.nv12torgb" + +@param src_y input image: 8-bit unsigned 1-channel image @ref CV_8UC1. +@param src_uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2. + +@sa YUV2RGB, NV12toBGR +*/ +GAPI_EXPORTS GMat NV12toRGB(const GMat& src_y, const GMat& src_uv); + +/** @brief Converts an image from NV12 (YUV420p) color space to BGR. +The function converts an input image from NV12 color space to RGB. +The conventional ranges for Y, U, and V channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.nv12tobgr" + +@param src_y input image: 8-bit unsigned 1-channel image @ref CV_8UC1. +@param src_uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2. + +@sa YUV2BGR, NV12toRGB +*/ +GAPI_EXPORTS GMat NV12toBGR(const GMat& src_y, const GMat& src_uv); + +/** @brief Converts an image from BayerGR color space to RGB. +The function converts an input image from BayerGR color space to RGB. +The conventional ranges for G, R, and B channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.bayergr2rgb" + +@param src_gr input image: 8-bit unsigned 1-channel image @ref CV_8UC1. + +@sa YUV2BGR, NV12toRGB +*/ +GAPI_EXPORTS GMat BayerGR2RGB(const GMat& src_gr); + +/** @brief Converts an image from RGB color space to HSV. +The function converts an input image from RGB color space to HSV. +The conventional ranges for R, G, and B channel values are 0 to 255. + +Output image must be 8-bit unsigned 3-channel image @ref CV_8UC3. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.rgb2hsv" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. + +@sa YUV2BGR, NV12toRGB +*/ +GAPI_EXPORTS GMat RGB2HSV(const GMat& src); + +/** @brief Converts an image from RGB color space to YUV422. +The function converts an input image from RGB color space to YUV422. +The conventional ranges for R, G, and B channel values are 0 to 255. + +Output image must be 8-bit unsigned 2-channel image @ref CV_8UC2. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.rgb2yuv422" + +@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3. + +@sa YUV2BGR, NV12toRGB +*/ +GAPI_EXPORTS GMat RGB2YUV422(const GMat& src); + +/** @brief Converts an image from NV12 (YUV420p) color space to RGB. +The function converts an input image from NV12 color space to RGB. +The conventional ranges for Y, U, and V channel values are 0 to 255. + +Output image must be 8-bit unsigned planar 3-channel image @ref CV_8UC1. +Planar image memory layout is three planes laying in the memory contiguously, +so the image height should be plane_height*plane_number, +image type is @ref CV_8UC1. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.nv12torgbp" + +@param src_y input image: 8-bit unsigned 1-channel image @ref CV_8UC1. +@param src_uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2. + +@sa YUV2RGB, NV12toBGRp, NV12toRGB +*/ +GAPI_EXPORTS GMatP NV12toRGBp(const GMat &src_y, const GMat &src_uv); + +/** @brief Converts an image from NV12 (YUV420p) color space to BGR. +The function converts an input image from NV12 color space to BGR. +The conventional ranges for Y, U, and V channel values are 0 to 255. + +Output image must be 8-bit unsigned planar 3-channel image @ref CV_8UC1. +Planar image memory layout is three planes laying in the memory contiguously, +so the image height should be plane_height*plane_number, +image type is @ref CV_8UC1. + +@note Function textual ID is "org.opencv.imgproc.colorconvert.nv12torgbp" + +@param src_y input image: 8-bit unsigned 1-channel image @ref CV_8UC1. +@param src_uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2. + +@sa YUV2RGB, NV12toRGBp, NV12toBGR +*/ +GAPI_EXPORTS GMatP NV12toBGRp(const GMat &src_y, const GMat &src_uv); + +//! @} gapi_colorconvert +} //namespace gapi +} //namespace cv + +#endif // OPENCV_GAPI_IMGPROC_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/core.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/core.hpp new file mode 100755 index 0000000..4ab85e2 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/core.hpp @@ -0,0 +1,27 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OCL_CORE_API_HPP +#define OPENCV_GAPI_OCL_CORE_API_HPP + +#include // GAPI_EXPORTS +#include // GKernelPackage + +namespace cv { +namespace gapi { +namespace core { +namespace ocl { + + GAPI_EXPORTS GKernelPackage kernels(); + +} // namespace ocl +} // namespace core +} // namespace gapi +} // namespace cv + + +#endif // OPENCV_GAPI_OCL_CORE_API_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/goclkernel.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/goclkernel.hpp new file mode 100755 index 0000000..6927492 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/goclkernel.hpp @@ -0,0 +1,245 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018-2019 Intel Corporation + + +#ifndef OPENCV_GAPI_GOCLKERNEL_HPP +#define OPENCV_GAPI_GOCLKERNEL_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include + +// FIXME: namespace scheme for backends? +namespace cv { + +namespace gimpl +{ + // Forward-declare an internal class + class GOCLExecutable; +} // namespace gimpl + +namespace gapi +{ +namespace ocl +{ + /** + * \addtogroup gapi_std_backends G-API Standard backends + * @{ + */ + /** + * @brief Get a reference to OCL backend. + * + * At the moment, the OCL backend is built atop of OpenCV + * "Transparent API" (T-API), see cv::UMat for details. + * + * @sa gapi_std_backends + */ + GAPI_EXPORTS cv::gapi::GBackend backend(); + /** @} */ +} // namespace ocl +} // namespace gapi + + +// Represents arguments which are passed to a wrapped OCL function +// FIXME: put into detail? +class GAPI_EXPORTS GOCLContext +{ +public: + // Generic accessor API + template + const T& inArg(int input) { return m_args.at(input).get(); } + + // Syntax sugar + const cv::UMat& inMat(int input); + cv::UMat& outMatR(int output); // FIXME: Avoid cv::Mat m = ctx.outMatR() + + const cv::gapi::own::Scalar& inVal(int input); + cv::gapi::own::Scalar& outValR(int output); // FIXME: Avoid cv::gapi::own::Scalar s = ctx.outValR() + template std::vector& outVecR(int output) // FIXME: the same issue + { + return outVecRef(output).wref(); + } + +protected: + detail::VectorRef& outVecRef(int output); + + std::vector m_args; + std::unordered_map m_results; + + + friend class gimpl::GOCLExecutable; +}; + +class GAPI_EXPORTS GOCLKernel +{ +public: + // This function is kernel's execution entry point (does the processing work) + using F = std::function; + + GOCLKernel(); + explicit GOCLKernel(const F& f); + + void apply(GOCLContext &ctx); + +protected: + F m_f; +}; + +// FIXME: This is an ugly ad-hoc imlpementation. TODO: refactor + +namespace detail +{ +template struct ocl_get_in; +template<> struct ocl_get_in +{ + static cv::UMat get(GOCLContext &ctx, int idx) { return ctx.inMat(idx); } +}; +template<> struct ocl_get_in +{ + static cv::Scalar get(GOCLContext &ctx, int idx) { return to_ocv(ctx.inVal(idx)); } +}; +template struct ocl_get_in > +{ + static const std::vector& get(GOCLContext &ctx, int idx) { return ctx.inArg(idx).rref(); } +}; +template struct ocl_get_in +{ + static T get(GOCLContext &ctx, int idx) { return ctx.inArg(idx); } +}; + +struct tracked_cv_umat{ + //TODO Think if T - API could reallocate UMat to a proper size - how do we handle this ? + //tracked_cv_umat(cv::UMat& m) : r{(m)}, original_data{m.getMat(ACCESS_RW).data} {} + tracked_cv_umat(cv::UMat& m) : r{ (m) }, original_data{ nullptr } {} + cv::UMat r; + uchar* original_data; + + operator cv::UMat& (){ return r;} + void validate() const{ + //if (r.getMat(ACCESS_RW).data != original_data) + //{ + // util::throw_error + // (std::logic_error + // ("OpenCV kernel output parameter was reallocated. \n" + // "Incorrect meta data was provided ?")); + //} + + } +}; + +struct scalar_wrapper_ocl +{ + //FIXME reuse CPU (OpenCV) plugin code + scalar_wrapper_ocl(cv::gapi::own::Scalar& s) : m_s{cv::gapi::own::to_ocv(s)}, m_org_s(s) {}; + operator cv::Scalar& () { return m_s; } + void writeBack() const { m_org_s = to_own(m_s); } + + cv::Scalar m_s; + cv::gapi::own::Scalar& m_org_s; +}; + +template +void postprocess_ocl(Outputs&... outs) +{ + struct + { + void operator()(tracked_cv_umat* bm) { bm->validate(); } + void operator()(scalar_wrapper_ocl* sw) { sw->writeBack(); } + void operator()(...) { } + + } validate; + //dummy array to unfold parameter pack + int dummy[] = { 0, (validate(&outs), 0)... }; + cv::util::suppress_unused_warning(dummy); +} + +template struct ocl_get_out; +template<> struct ocl_get_out +{ + static tracked_cv_umat get(GOCLContext &ctx, int idx) + { + auto& r = ctx.outMatR(idx); + return{ r }; + } +}; +template<> struct ocl_get_out +{ + static scalar_wrapper_ocl get(GOCLContext &ctx, int idx) + { + auto& s = ctx.outValR(idx); + return{ s }; + } +}; +template struct ocl_get_out > +{ + static std::vector& get(GOCLContext &ctx, int idx) { return ctx.outVecR(idx); } +}; + +template +struct OCLCallHelper; + +// FIXME: probably can be simplified with std::apply or analogue. +template +struct OCLCallHelper, std::tuple > +{ + template + struct call_and_postprocess + { + template + static void call(Inputs&&... ins, Outputs&&... outs) + { + //not using a std::forward on outs is deliberate in order to + //cause compilation error, by tring to bind rvalue references to lvalue references + Impl::run(std::forward(ins)..., outs...); + + postprocess_ocl(outs...); + } + }; + + template + static void call_impl(GOCLContext &ctx, detail::Seq, detail::Seq) + { + //TODO: Make sure that OpenCV kernels do not reallocate memory for output parameters + //by comparing it's state (data ptr) before and after the call. + //Convert own::Scalar to cv::Scalar before call kernel and run kernel + //convert cv::Scalar to own::Scalar after call kernel and write back results + call_and_postprocess::get(ctx, IIs))...>::call(ocl_get_in::get(ctx, IIs)..., ocl_get_out::get(ctx, OIs)...); + } + + static void call(GOCLContext &ctx) + { + call_impl(ctx, + typename detail::MkSeq::type(), + typename detail::MkSeq::type()); + } +}; + +} // namespace detail + +template +class GOCLKernelImpl: public cv::detail::OCLCallHelper, + public cv::detail::KernelTag +{ + using P = detail::OCLCallHelper; + +public: + using API = K; + + static cv::gapi::GBackend backend() { return cv::gapi::ocl::backend(); } + static cv::GOCLKernel kernel() { return GOCLKernel(&P::call); } +}; + +#define GAPI_OCL_KERNEL(Name, API) struct Name: public cv::GOCLKernelImpl + +} // namespace cv + +#endif // OPENCV_GAPI_GOCLKERNEL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/imgproc.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/imgproc.hpp new file mode 100755 index 0000000..1bb5911 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/ocl/imgproc.hpp @@ -0,0 +1,27 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OCL_IMGPROC_API_HPP +#define OPENCV_GAPI_OCL_IMGPROC_API_HPP + +#include // GAPI_EXPORTS +#include // GKernelPackage + +namespace cv { +namespace gapi { +namespace imgproc { +namespace ocl { + + GAPI_EXPORTS GKernelPackage kernels(); + +} // namespace ocl +} // namespace imgproc +} // namespace gapi +} // namespace cv + + +#endif // OPENCV_GAPI_OCL_IMGPROC_API_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/opencv_includes.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/opencv_includes.hpp new file mode 100755 index 0000000..5acf280 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/opencv_includes.hpp @@ -0,0 +1,21 @@ +// This file is part of OpenCV project. + +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OPENCV_INCLUDES_HPP +#define OPENCV_GAPI_OPENCV_INCLUDES_HPP + +#if !defined(GAPI_STANDALONE) +# include +# include +# include +# include +#else // Without OpenCV +# include +#endif // !defined(GAPI_STANDALONE) + +#endif // OPENCV_GAPI_OPENCV_INCLUDES_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/operators.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/operators.hpp new file mode 100755 index 0000000..b20062c --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/operators.hpp @@ -0,0 +1,69 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OPERATORS_HPP +#define OPENCV_GAPI_OPERATORS_HPP + +#include +#include + +GAPI_EXPORTS cv::GMat operator+(const cv::GMat& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator+(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator+(const cv::GScalar& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator-(const cv::GMat& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator-(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator-(const cv::GScalar& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator*(const cv::GMat& lhs, float rhs); +GAPI_EXPORTS cv::GMat operator*(float lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator*(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator*(const cv::GScalar& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator/(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator/(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator/(const cv::GMat& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator&(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator|(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator^(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator~(const cv::GMat& lhs); + +GAPI_EXPORTS cv::GMat operator&(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator|(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator^(const cv::GScalar& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator&(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator|(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator^(const cv::GMat& lhs, const cv::GScalar& rhs); + +GAPI_EXPORTS cv::GMat operator>(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator>=(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator<(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator<=(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator==(const cv::GMat& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator!=(const cv::GMat& lhs, const cv::GMat& rhs); + +GAPI_EXPORTS cv::GMat operator>(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator>=(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator<(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator<=(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator==(const cv::GMat& lhs, const cv::GScalar& rhs); +GAPI_EXPORTS cv::GMat operator!=(const cv::GMat& lhs, const cv::GScalar& rhs); + +GAPI_EXPORTS cv::GMat operator>(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator>=(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator<(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator<=(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator==(const cv::GScalar& lhs, const cv::GMat& rhs); +GAPI_EXPORTS cv::GMat operator!=(const cv::GScalar& lhs, const cv::GMat& rhs); + + + +#endif // OPENCV_GAPI_OPERATORS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/assert.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/assert.hpp new file mode 100755 index 0000000..92b246f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/assert.hpp @@ -0,0 +1,43 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OWN_ASSERT_HPP +#define OPENCV_GAPI_OWN_ASSERT_HPP + +#if !defined(GAPI_STANDALONE) +#include +#define GAPI_Assert CV_Assert +#define GAPI_DbgAssert CV_DbgAssert + +#else +#include +#include +#include + +namespace detail +{ + inline void assert_abort(const char* str, int line, const char* file, const char* func) + { + std::stringstream ss; + ss << file << ":" << line << ": Assertion " << str << " in function " << func << " failed\n"; + cv::util::throw_error(std::logic_error(ss.str())); + } +} + +#define GAPI_Assert(expr) \ +{ if (!(expr)) ::detail::assert_abort(#expr, __LINE__, __FILE__, __func__); } + + +#ifdef NDEBUG +# define GAPI_DbgAssert(expr) +#else +# define GAPI_DbgAssert(expr) GAPI_Assert(expr) +#endif + +#endif // GAPI_STANDALONE + +#endif // OPENCV_GAPI_OWN_ASSERT_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/convert.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/convert.hpp new file mode 100755 index 0000000..4a7394a --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/convert.hpp @@ -0,0 +1,50 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OWN_CONVERT_HPP +#define OPENCV_GAPI_OWN_CONVERT_HPP + +#if !defined(GAPI_STANDALONE) + +#include +#include +#include +#include + +namespace cv +{ + inline cv::gapi::own::Mat to_own(Mat const& m) { return {m.rows, m.cols, m.type(), m.data, m.step};}; + cv::gapi::own::Mat to_own(Mat&&) = delete; + + inline cv::gapi::own::Scalar to_own(const cv::Scalar& s) { return {s[0], s[1], s[2], s[3]}; }; + + inline cv::gapi::own::Size to_own (const Size& s) { return {s.width, s.height}; }; + + inline cv::gapi::own::Rect to_own (const Rect& r) { return {r.x, r.y, r.width, r.height}; }; + + + +namespace gapi +{ +namespace own +{ + inline cv::Mat to_ocv(Mat const& m) { return {m.rows, m.cols, m.type(), m.data, m.step};}; + cv::Mat to_ocv(Mat&&) = delete; + + inline cv::Scalar to_ocv(const Scalar& s) { return {s[0], s[1], s[2], s[3]}; }; + + inline cv::Size to_ocv (const Size& s) { return cv::Size(s.width, s.height); }; + + inline cv::Rect to_ocv (const Rect& r) { return cv::Rect(r.x, r.y, r.width, r.height); }; + +} // namespace own +} // namespace gapi +} // namespace cv + +#endif // !defined(GAPI_STANDALONE) + +#endif // OPENCV_GAPI_OWN_CONVERT_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/cvdefs.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/cvdefs.hpp new file mode 100755 index 0000000..71c2aa8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/cvdefs.hpp @@ -0,0 +1,150 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_CV_DEFS_HPP +#define OPENCV_GAPI_CV_DEFS_HPP + +#if defined(GAPI_STANDALONE) + +// Simulate OpenCV definitions taken from various +// OpenCV interface headers if G-API is built in a +// standalone mode. + +// interface.h: + +typedef unsigned char uchar; +typedef char schar; + +typedef unsigned short ushort; + +#define CV_CN_MAX 512 +#define CV_CN_SHIFT 3 +#define CV_DEPTH_MAX (1 << CV_CN_SHIFT) + + +#define CV_8U 0 +#define CV_8S 1 +#define CV_16U 2 +#define CV_16S 3 +#define CV_32S 4 +#define CV_32F 5 +#define CV_64F 6 +#define CV_USRTYPE1 7 + +#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) +#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK) + +#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT)) +#define CV_MAKE_TYPE CV_MAKETYPE + +#define CV_8UC1 CV_MAKETYPE(CV_8U,1) +#define CV_8UC2 CV_MAKETYPE(CV_8U,2) +#define CV_8UC3 CV_MAKETYPE(CV_8U,3) +#define CV_8UC4 CV_MAKETYPE(CV_8U,4) +#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n)) + +#define CV_8SC1 CV_MAKETYPE(CV_8S,1) +#define CV_8SC2 CV_MAKETYPE(CV_8S,2) +#define CV_8SC3 CV_MAKETYPE(CV_8S,3) +#define CV_8SC4 CV_MAKETYPE(CV_8S,4) +#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n)) + +#define CV_16UC1 CV_MAKETYPE(CV_16U,1) +#define CV_16UC2 CV_MAKETYPE(CV_16U,2) +#define CV_16UC3 CV_MAKETYPE(CV_16U,3) +#define CV_16UC4 CV_MAKETYPE(CV_16U,4) +#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n)) + +#define CV_16SC1 CV_MAKETYPE(CV_16S,1) +#define CV_16SC2 CV_MAKETYPE(CV_16S,2) +#define CV_16SC3 CV_MAKETYPE(CV_16S,3) +#define CV_16SC4 CV_MAKETYPE(CV_16S,4) +#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n)) + +#define CV_32SC1 CV_MAKETYPE(CV_32S,1) +#define CV_32SC2 CV_MAKETYPE(CV_32S,2) +#define CV_32SC3 CV_MAKETYPE(CV_32S,3) +#define CV_32SC4 CV_MAKETYPE(CV_32S,4) +#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n)) + +#define CV_32FC1 CV_MAKETYPE(CV_32F,1) +#define CV_32FC2 CV_MAKETYPE(CV_32F,2) +#define CV_32FC3 CV_MAKETYPE(CV_32F,3) +#define CV_32FC4 CV_MAKETYPE(CV_32F,4) +#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n)) + +#define CV_64FC1 CV_MAKETYPE(CV_64F,1) +#define CV_64FC2 CV_MAKETYPE(CV_64F,2) +#define CV_64FC3 CV_MAKETYPE(CV_64F,3) +#define CV_64FC4 CV_MAKETYPE(CV_64F,4) +#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n)) + +// cvdef.h: + +#define CV_MAT_CN_MASK ((CV_CN_MAX - 1) << CV_CN_SHIFT) +#define CV_MAT_CN(flags) ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1) +#define CV_MAT_TYPE_MASK (CV_DEPTH_MAX*CV_CN_MAX - 1) +#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK) +#define CV_MAT_CONT_FLAG_SHIFT 14 +#define CV_MAT_CONT_FLAG (1 << CV_MAT_CONT_FLAG_SHIFT) +#define CV_IS_MAT_CONT(flags) ((flags) & CV_MAT_CONT_FLAG) +#define CV_IS_CONT_MAT CV_IS_MAT_CONT +#define CV_SUBMAT_FLAG_SHIFT 15 +#define CV_SUBMAT_FLAG (1 << CV_SUBMAT_FLAG_SHIFT) +#define CV_IS_SUBMAT(flags) ((flags) & CV_MAT_SUBMAT_FLAG) + +///** Size of each channel item, +// 0x8442211 = 1000 0100 0100 0010 0010 0001 0001 ~ array of sizeof(arr_type_elem) */ +//#define CV_ELEM_SIZE1(type) \ +// ((((sizeof(size_t)<<28)|0x8442211) >> CV_MAT_DEPTH(type)*4) & 15) + +#define CV_MAT_TYPE(flags) ((flags) & CV_MAT_TYPE_MASK) + +/** 0x3a50 = 11 10 10 01 01 00 00 ~ array of log2(sizeof(arr_type_elem)) */ +#define CV_ELEM_SIZE(type) \ + (CV_MAT_CN(type) << ((((sizeof(size_t)/4+1)*16384|0x3a50) >> CV_MAT_DEPTH(type)*2) & 3)) + +#ifndef CV_OVERRIDE +# define CV_OVERRIDE override +#endif + +// base.h: +namespace cv +{ +enum BorderTypes { + BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i` + BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh` + BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb` + BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg` + BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba` + BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno` + + BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101 + BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101 + BORDER_ISOLATED = 16 //!< do not look outside of ROI +}; +// imgproc.hpp: +enum InterpolationFlags{ + INTER_NEAREST = 0, + INTER_LINEAR = 1, + INTER_CUBIC = 2, + INTER_AREA = 3, + INTER_LANCZOS4 = 4, + INTER_LINEAR_EXACT = 5, + INTER_MAX = 7, +}; +} // namespace cv + +static inline int cvFloor( double value ) +{ + int i = (int)value; + return i - (i > value); +} + +#endif // defined(GAPI_STANDALONE) + +#endif // OPENCV_GAPI_CV_DEFS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/exports.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/exports.hpp new file mode 100755 index 0000000..b1eddaa --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/exports.hpp @@ -0,0 +1,28 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OWN_TYPES_HPP +#define OPENCV_GAPI_OWN_TYPES_HPP + +# if defined(__OPENCV_BUILD) +# include +# define GAPI_EXPORTS CV_EXPORTS + +# else +# if defined _WIN32 +# define GAPI_EXPORTS __declspec(dllexport) +# elif defined __GNUC__ && __GNUC__ >= 4 +# define GAPI_EXPORTS __attribute__ ((visibility ("default"))) +# endif + +# ifndef GAPI_EXPORTS +# define GAPI_EXPORTS +# endif + +# endif + +#endif // OPENCV_GAPI_OWN_TYPES_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/mat.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/mat.hpp new file mode 100755 index 0000000..20f5b55 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/mat.hpp @@ -0,0 +1,291 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OWN_MAT_HPP +#define OPENCV_GAPI_OWN_MAT_HPP + +#include +#include +#include +#include +#include + +#include //std::shared_ptr +#include //std::memcpy +#include + +namespace cv { namespace gapi { namespace own { + namespace detail { + template + void assign_row(void* ptr, int cols, Scalar const& s) + { + auto p = static_cast(ptr); + for (int c = 0; c < cols; c++) + { + for (int ch = 0; ch < channels; ch++) + { + p[c * channels + ch] = saturate(s[ch], roundd); + } + } + } + + inline size_t default_step(int type, int cols) + { + return CV_ELEM_SIZE(type) * cols; + } + //Matrix header, i.e. fields that are unique to each Mat object. + //Devoted class is needed to implement custom behavior on move (erasing state of moved from object) + struct MatHeader{ + enum { AUTO_STEP = 0}; + enum { TYPE_MASK = 0x00000FFF }; + + MatHeader() = default; + + MatHeader(int _rows, int _cols, int type, void* _data, size_t _step) + : flags((type & TYPE_MASK)), rows(_rows), cols(_cols), data((uchar*)_data), step(_step == AUTO_STEP ? detail::default_step(type, _cols) : _step) + {} + + MatHeader(const MatHeader& ) = default; + MatHeader(MatHeader&& src) : MatHeader(src) // reuse copy constructor here + { + MatHeader empty; //give it a name to call copy(not move) assignment below + src = empty; + } + MatHeader& operator=(const MatHeader& ) = default; + MatHeader& operator=(MatHeader&& src) + { + *this = src; //calling a copy assignment here, not move one + MatHeader empty; //give it a name to call copy(not move) assignment below + src = empty; + return *this; + } + /*! includes several bit-fields: + - depth + - number of channels + */ + int flags = 0; + + //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions + int rows = 0, cols = 0; + //! pointer to the data + uchar* data = nullptr; + size_t step = 0; + }; + } + //concise version of cv::Mat suitable for GAPI needs (used when no dependence on OpenCV is required) + class Mat : public detail::MatHeader{ + public: + + Mat() = default; + + /** @overload + @param _rows Number of rows in a 2D array. + @param _cols Number of columns in a 2D array. + @param _type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param _data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param _step Number of bytes each matrix row occupies. The value should include the padding bytes at + the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed + and the actual step is calculated as cols*elemSize(). See Mat::elemSize. + */ + Mat(int _rows, int _cols, int _type, void* _data, size_t _step = AUTO_STEP) + : MatHeader (_rows, _cols, _type, _data, _step) + {} + + Mat(Mat const& src, const Rect& roi ) + : Mat(src) + { + rows = roi.height; + cols = roi.width; + data = ptr(roi.y, roi.x); + } + + Mat(Mat const& src) = default; + Mat(Mat&& src) = default; + + Mat& operator=(Mat const& src) = default; + Mat& operator=(Mat&& src) = default; + + /** @brief Sets all or some of the array elements to the specified value. + @param s Assigned scalar converted to the actual array type. + */ + Mat& operator = (const Scalar& s) + { + constexpr unsigned max_channels = 4; //Scalar can't fit more than 4 + const auto channels = static_cast(this->channels()); + GAPI_Assert(channels <= max_channels); + + using func_p_t = void (*)(void*, int, Scalar const&); + using detail::assign_row; + #define TABLE_ENTRY(type) {assign_row, assign_row, assign_row, assign_row} + static constexpr func_p_t func_tbl[][max_channels] = { + TABLE_ENTRY(uchar), + TABLE_ENTRY(schar), + TABLE_ENTRY(ushort), + TABLE_ENTRY(short), + TABLE_ENTRY(int), + TABLE_ENTRY(float), + TABLE_ENTRY(double) + }; + #undef TABLE_ENTRY + + static_assert(CV_8U == 0 && CV_8S == 1 && CV_16U == 2 && CV_16S == 3 + && CV_32S == 4 && CV_32F == 5 && CV_64F == 6, + "OCV type ids used as indexes to array, thus exact numbers are important!" + ); + + const auto depth = static_cast(this->depth()); + GAPI_Assert(depth < sizeof(func_tbl)/sizeof(func_tbl[0])); + + for (int r = 0; r < rows; ++r) + { + auto* f = func_tbl[depth][channels -1]; + (*f)(static_cast(ptr(r)), cols, s ); + } + return *this; + } + + /** @brief Returns the matrix element size in bytes. + + The method returns the matrix element size in bytes. For example, if the matrix type is CV_16SC3 , + the method returns 3\*sizeof(short) or 6. + */ + size_t elemSize() const + { + return CV_ELEM_SIZE(type()); + } + /** @brief Returns the type of a matrix element. + + The method returns a matrix element type. This is an identifier compatible with the CvMat type + system, like CV_16SC3 or 16-bit signed 3-channel array, and so on. + */ + int type() const {return CV_MAT_TYPE(flags);} + + /** @brief Returns the depth of a matrix element. + + The method returns the identifier of the matrix element depth (the type of each individual channel). + For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of + matrix types contains the following values: + - CV_8U - 8-bit unsigned integers ( 0..255 ) + - CV_8S - 8-bit signed integers ( -128..127 ) + - CV_16U - 16-bit unsigned integers ( 0..65535 ) + - CV_16S - 16-bit signed integers ( -32768..32767 ) + - CV_32S - 32-bit signed integers ( -2147483648..2147483647 ) + - CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN ) + - CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN ) + */ + int depth() const {return CV_MAT_DEPTH(flags);} + + /** @brief Returns the number of matrix channels. + + The method returns the number of matrix channels. + */ + int channels() const {return CV_MAT_CN(flags);} + + /** + @param _rows New number of rows. + @param _cols New number of columns. + @param _type New matrix type. + */ + void create(int _rows, int _cols, int _type) + { + create({_cols, _rows}, _type); + } + /** @overload + @param _size Alternative new matrix size specification: Size(cols, rows) + @param _type New matrix type. + */ + void create(Size _size, int _type) + { + if (_size != Size{cols, rows} ) + { + Mat tmp{_size.height, _size.width, _type, nullptr}; + tmp.memory.reset(new uchar[ tmp.step * tmp.rows], [](uchar * p){delete[] p;}); + tmp.data = tmp.memory.get(); + + *this = std::move(tmp); + } + } + + /** @brief Copies the matrix to another one. + + The method copies the matrix data to another matrix. Before copying the data, the method invokes : + @code + m.create(this->size(), this->type()); + @endcode + so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the + function does not handle the case of a partial overlap between the source and the destination + matrices. + */ + void copyTo(Mat& dst) const + { + dst.create(rows, cols, type()); + for (int r = 0; r < rows; ++r) + { + std::copy_n(ptr(r), detail::default_step(type(),cols), dst.ptr(r)); + } + } + + /** @brief Returns true if the array has no elements. + + The method returns true if Mat::total() is 0 or if Mat::data is NULL. Because of pop_back() and + resize() methods `M.total() == 0` does not imply that `M.data == NULL`. + */ + bool empty() const; + + /** @brief Returns the total number of array elements. + + The method returns the number of array elements (a number of pixels if the array represents an + image). + */ + size_t total() const + { + return static_cast(rows * cols); + } + + + /** @overload + @param roi Extracted submatrix specified as a rectangle. + */ + Mat operator()( const Rect& roi ) const + { + return Mat{*this, roi}; + } + + + /** @brief Returns a pointer to the specified matrix row. + + The methods return `uchar*` or typed pointer to the specified matrix row. See the sample in + Mat::isContinuous to know how to use these methods. + @param row Index along the dimension 0 + @param col Index along the dimension 1 + */ + uchar* ptr(int row, int col = 0) + { + return const_cast(const_cast(this)->ptr(row,col)); + } + /** @overload */ + const uchar* ptr(int row, int col = 0) const + { + return data + step * row + CV_ELEM_SIZE(type()) * col; + } + + + private: + //actual memory allocated for storage, or nullptr if object is non owning view to over memory + std::shared_ptr memory; + }; + +} //namespace own +} //namespace gapi +} //namespace cv + +#endif /* OPENCV_GAPI_OWN_MAT_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/saturate.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/saturate.hpp new file mode 100755 index 0000000..207dcde --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/saturate.hpp @@ -0,0 +1,90 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_OWN_SATURATE_HPP +#define OPENCV_GAPI_OWN_SATURATE_HPP + +#include + +#include +#include + +#include + +namespace cv { namespace gapi { namespace own { +//----------------------------- +// +// Numeric cast with saturation +// +//----------------------------- + +template +static inline DST saturate(SRC x) +{ + // only integral types please! + GAPI_DbgAssert(std::is_integral::value && + std::is_integral::value); + + if (std::is_same::value) + return static_cast(x); + + if (sizeof(DST) > sizeof(SRC)) + return static_cast(x); + + // compiler must recognize this saturation, + // so compile saturate(a + b) with adds + // instruction (e.g.: _mm_adds_epi16 if x86) + return x < std::numeric_limits::min()? + std::numeric_limits::min(): + x > std::numeric_limits::max()? + std::numeric_limits::max(): + static_cast(x); +} + +// Note, that OpenCV rounds differently: +// - like std::round() for add, subtract +// - like std::rint() for multiply, divide +template +static inline DST saturate(SRC x, R round) +{ + if (std::is_floating_point::value) + { + return static_cast(x); + } + else if (std::is_integral::value) + { + GAPI_DbgAssert(std::is_integral::value && + std::is_integral::value); + return saturate(x); + } + else + { + GAPI_DbgAssert(std::is_integral::value && + std::is_floating_point::value); +#ifdef _WIN32 +// Suppress warning about convering x to floating-point +// Note that x is already floating-point at this point +#pragma warning(disable: 4244) +#endif + int ix = static_cast(round(x)); +#ifdef _WIN32 +#pragma warning(default: 4244) +#endif + return saturate(ix); + } +} + +// explicit suffix 'd' for double type +inline double ceild(double x) { return std::ceil(x); } +inline double floord(double x) { return std::floor(x); } +inline double roundd(double x) { return std::round(x); } +inline double rintd(double x) { return std::rint(x); } + +} //namespace own +} //namespace gapi +} //namespace cv +#endif /* OPENCV_GAPI_OWN_SATURATE_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/scalar.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/scalar.hpp new file mode 100755 index 0000000..bda91c8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/scalar.hpp @@ -0,0 +1,47 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_GAPI_OWN_SCALAR_HPP +#define OPENCV_GAPI_GAPI_OWN_SCALAR_HPP + +#include + +namespace cv +{ +namespace gapi +{ +namespace own +{ + +class GAPI_EXPORTS Scalar +{ +public: + Scalar() = default; + explicit Scalar(double v0) { val[0] = v0; }; + Scalar(double v0, double v1, double v2 = 0, double v3 = 0) + : val{v0, v1, v2, v3} + { + } + + const double& operator[](int i) const { return val[i]; } + double& operator[](int i) { return val[i]; } + + static Scalar all(double v0) { return Scalar(v0, v0, v0, v0); } + + double val[4] = {0}; +}; + +inline bool operator==(const Scalar& lhs, const Scalar& rhs) +{ + return std::equal(std::begin(lhs.val), std::end(lhs.val), std::begin(rhs.val)); +} + +} // namespace own +} // namespace gapi +} // namespace cv + +#endif // OPENCV_GAPI_GAPI_OWN_SCALAR_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/own/types.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/types.hpp new file mode 100755 index 0000000..20445ee --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/own/types.hpp @@ -0,0 +1,135 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_TYPES_HPP +#define OPENCV_GAPI_TYPES_HPP + +#include // std::max, std::min +#include + +namespace cv +{ +namespace gapi +{ +namespace own +{ + +class Point +{ +public: + Point() = default; + Point(int _x, int _y) : x(_x), y(_y) {}; + + int x = 0; + int y = 0; +}; + +class Rect +{ +public: + Rect() = default; + Rect(int _x, int _y, int _width, int _height) : x(_x), y(_y), width(_width), height(_height) {}; +#if !defined(GAPI_STANDALONE) + Rect(const cv::Rect& other) : x(other.x), y(other.y), width(other.width), height(other.height) {}; + inline Rect& operator=(const cv::Rect& other) + { + x = other.x; + y = other.x; + width = other.width; + height = other.height; + return *this; + } +#endif // !defined(GAPI_STANDALONE) + + int x = 0; //!< x coordinate of the top-left corner + int y = 0; //!< y coordinate of the top-left corner + int width = 0; //!< width of the rectangle + int height = 0; //!< height of the rectangle +}; + +inline bool operator==(const Rect& lhs, const Rect& rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y && lhs.width == rhs.width && lhs.height == rhs.height; +} + +inline bool operator!=(const Rect& lhs, const Rect& rhs) +{ + return !(lhs == rhs); +} + +inline Rect& operator&=(Rect& lhs, const Rect& rhs) +{ + int x1 = std::max(lhs.x, rhs.x); + int y1 = std::max(lhs.y, rhs.y); + lhs.width = std::min(lhs.x + lhs.width, rhs.x + rhs.width) - x1; + lhs.height = std::min(lhs.y + lhs.height, rhs.y + rhs.height) - y1; + lhs.x = x1; + lhs.y = y1; + if( lhs.width <= 0 || lhs.height <= 0 ) + lhs = Rect(); + return lhs; +} + +inline const Rect operator&(const Rect& lhs, const Rect& rhs) +{ + Rect result = lhs; + return result &= rhs; +} + +inline std::ostream& operator<<(std::ostream& o, const Rect& rect) +{ + return o << "[" << rect.width << " x " << rect.height << " from (" << rect.x << ", " << rect.y << ")]"; +} + +class Size +{ +public: + Size() = default; + Size(int _width, int _height) : width(_width), height(_height) {}; +#if !defined(GAPI_STANDALONE) + Size(const cv::Size& other) : width(other.width), height(other.height) {}; + inline Size& operator=(const cv::Size& rhs) + { + width = rhs.width; + height = rhs.height; + return *this; + } +#endif // !defined(GAPI_STANDALONE) + + int width = 0; + int height = 0; +}; + +inline Size& operator+=(Size& lhs, const Size& rhs) +{ + lhs.width += rhs.width; + lhs.height += rhs.height; + return lhs; +} + +inline bool operator==(const Size& lhs, const Size& rhs) +{ + return lhs.width == rhs.width && lhs.height == rhs.height; +} + +inline bool operator!=(const Size& lhs, const Size& rhs) +{ + return !(lhs == rhs); +} + + +inline std::ostream& operator<<(std::ostream& o, const Size& s) +{ + o << "[" << s.width << " x " << s.height << "]"; + return o; +} + +} // namespace own +} // namespace gapi +} // namespace cv + +#endif // OPENCV_GAPI_TYPES_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/render.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/render.hpp new file mode 100755 index 0000000..2dd60da --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/render.hpp @@ -0,0 +1,113 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_RENDER_HPP +#define OPENCV_GAPI_RENDER_HPP + +#include +#include + +#include +#include +#include +#include + +namespace cv +{ +namespace gapi +{ +namespace wip +{ +namespace draw +{ + +/** + * A structure to represent parameters for drawing a text string. + */ +struct Text +{ + /*@{*/ + std::string text; //!< The text string to be drawn + cv::Point org; //!< The bottom-left corner of the text string in the image + int ff; //!< The font type, see #HersheyFonts + double fs; //!< The font scale factor that is multiplied by the font-specific base size + cv::Scalar color; //!< The text color + int thick; //!< The thickness of the lines used to draw a text + int lt; //!< The line type. See #LineTypes + bool bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner + /*@{*/ +}; + +/** + * A structure to represent parameters for drawing a rectangle + */ +struct Rect +{ + cv::Rect rect; //!< Coordinates of the rectangle + cv::Scalar color; //!< The rectangle color or brightness (grayscale image) + int thick; //!< The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle + int lt; //!< The type of the line. See #LineTypes + int shift; //!< The number of fractional bits in the point coordinates +}; + +/** + * A structure to represent parameters for drawing a circle + */ +struct Circle +{ + cv::Point center; //!< The center of the circle + int radius; //!< The radius of the circle + cv::Scalar color; //!< The color of the circle + int thick; //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn + int lt; //!< The Type of the circle boundary. See #LineTypes + int shift; //!< The Number of fractional bits in the coordinates of the center and in the radius value +}; + +/** + * A structure to represent parameters for drawing a line + */ +struct Line +{ + cv::Point pt1; //!< The first point of the line segment + cv::Point pt2; //!< The second point of the line segment + cv::Scalar color; //!< The line color + int thick; //!< The thickness of line + int lt; //!< The Type of the line. See #LineTypes + int shift; //!< The number of fractional bits in the point coordinates + +}; + +using Prim = util::variant + < Text + , Rect + , Circle + , Line + >; + +using Prims = std::vector; + +/** @brief The function renders on the input image passed drawing primitivies + +@param bgr input image: 8-bit unsigned 3-channel image @ref CV_8UC3. +@param prims vector of drawing primitivies +*/ +GAPI_EXPORTS void render(cv::Mat& bgr, const Prims& prims); + +/** @brief The function renders on two NV12 planes passed drawing primitivies + +@param y_plane input image: 8-bit unsigned 1-channel image @ref CV_8UC1. +@param uv_plane input image: 8-bit unsigned 2-channel image @ref CV_8UC2. +@param prims vector of drawing primitivies +*/ +GAPI_EXPORTS void render(cv::Mat& y_plane, cv::Mat& uv_plane , const Prims& prims); + +} // namespace draw +} // namespace wip +} // namespace gapi +} // namespace cv + +#endif // OPENCV_GAPI_RENDER_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/util/any.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/any.hpp new file mode 100755 index 0000000..5f97e95 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/any.hpp @@ -0,0 +1,186 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_UTIL_ANY_HPP +#define OPENCV_GAPI_UTIL_ANY_HPP + +#include +#include +#include +#include + +#include + +#if defined(_MSC_VER) + // disable MSVC warning on "multiple copy constructors specified" +# pragma warning(disable: 4521) +#endif + +namespace cv +{ + +namespace internal +{ + template + T down_cast(Source operand) + { +#if defined(__GXX_RTTI) || defined(_CPPRTTI) + return dynamic_cast(operand); +#else + #warning used static cast instead of dynamic because RTTI is disabled + return static_cast(operand); +#endif + } +} + +namespace util +{ + class bad_any_cast : public std::bad_cast + { + public: + virtual const char* what() const noexcept override + { + return "Bad any cast"; + } + }; + + //modeled against C++17 std::any + + class any + { + private: + struct holder; + using holder_ptr = std::unique_ptr; + struct holder + { + virtual holder_ptr clone() = 0; + virtual ~holder() = default; + }; + + template + struct holder_impl : holder + { + value_t v; + template + holder_impl(arg_t&& a) : v(std::forward(a)) {} + holder_ptr clone() override { return holder_ptr(new holder_impl (v));} + }; + + holder_ptr hldr; + public: + template + any(value_t&& arg) : hldr(new holder_impl::type>( std::forward(arg))) {} + + any(any const& src) : hldr( src.hldr ? src.hldr->clone() : nullptr) {} + //simple hack in order not to write enable_if for the template constructor + any(any & src) : any (const_cast(src)) {} + + any() = default; + any(any&& ) = default; + + any& operator=(any&&) = default; + + any& operator=(any const& src) + { + any copy(src); + swap(*this, copy); + return *this; + } + + template + friend value_t* any_cast(any* operand); + + template + friend const value_t* any_cast(const any* operand); + + template + friend value_t& unsafe_any_cast(any& operand); + + template + friend const value_t& unsafe_any_cast(const any& operand); + + friend void swap(any & lhs, any& rhs) + { + swap(lhs.hldr, rhs.hldr); + } + + }; + + template + value_t* any_cast(any* operand) + { + auto casted = internal::down_cast::type> *>(operand->hldr.get()); + if (casted){ + return & (casted->v); + } + return nullptr; + } + + template + const value_t* any_cast(const any* operand) + { + auto casted = internal::down_cast::type> *>(operand->hldr.get()); + if (casted){ + return & (casted->v); + } + return nullptr; + } + + template + value_t& any_cast(any& operand) + { + auto ptr = any_cast(&operand); + if (ptr) + { + return *ptr; + } + + throw_error(bad_any_cast()); + } + + + template + const value_t& any_cast(const any& operand) + { + auto ptr = any_cast(&operand); + if (ptr) + { + return *ptr; + } + + throw_error(bad_any_cast()); + } + + template + inline value_t& unsafe_any_cast(any& operand) + { +#ifdef DEBUG + return any_cast(operand); +#else + return static_cast::type> *>(operand.hldr.get())->v; +#endif + } + + template + inline const value_t& unsafe_any_cast(const any& operand) + { +#ifdef DEBUG + return any_cast(operand); +#else + return static_cast::type> *>(operand.hldr.get())->v; +#endif + } + +} // namespace util +} // namespace cv + +#if defined(_MSC_VER) + // Enable "multiple copy constructors specified" back +# pragma warning(default: 4521) +#endif + +#endif // OPENCV_GAPI_UTIL_ANY_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/util/compiler_hints.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/compiler_hints.hpp new file mode 100755 index 0000000..a41a971 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/compiler_hints.hpp @@ -0,0 +1,19 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + +#ifndef OPENCV_GAPI_UTIL_COMPILER_HINTS_HPP +#define OPENCV_GAPI_UTIL_COMPILER_HINTS_HPP + +namespace cv +{ +namespace util +{ + //! Utility template function to prevent "unused" warnings by various compilers. + template void suppress_unused_warning( const T& ) {} +} // namespace util +} // namespace cv + +#endif /* OPENCV_GAPI_UTIL_COMPILER_HINTS_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/util/optional.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/optional.hpp new file mode 100755 index 0000000..1aa2b26 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/optional.hpp @@ -0,0 +1,178 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_UTIL_OPTIONAL_HPP +#define OPENCV_GAPI_UTIL_OPTIONAL_HPP + +#include + +// A poor man's `optional` implementation, incompletely modeled against C++17 spec. +namespace cv +{ +namespace util +{ + class bad_optional_access: public std::exception + { + public: + virtual const char *what() const noexcept override + { + return "Bad optional access"; + } + }; + + // TODO: nullopt_t + + // Interface /////////////////////////////////////////////////////////////// + template class optional + { + public: + // Constructors + // NB.: there were issues with Clang 3.8 when =default() was used + // instead {} + optional() {}; + optional(const optional&) = default; + explicit optional(T &&value) noexcept; + explicit optional(const T &value) noexcept; + optional(optional &&) noexcept; + // TODO: optional(nullopt_t) noexcept; + // TODO: optional(const optional &) + // TODO: optional(optional &&) + // TODO: optional(Args&&...) + // TODO: optional(initializer_list) + // TODO: optional(U&& value); + + // Assignment + optional& operator=(const optional& rhs) = default; + optional& operator=(optional&& rhs); + + // Observers + T* operator-> (); + const T* operator-> () const; + T& operator* (); + const T& operator* () const; + // TODO: && versions + + operator bool() const noexcept; + bool has_value() const noexcept; + + T& value(); + const T& value() const; + // TODO: && versions + + template + T value_or(U &&default_value) const; + + void swap(optional &other) noexcept; + void reset() noexcept; + // TODO: emplace + + // TODO: operator==, !=, <, <=, >, >= + + private: + struct nothing {}; + util::variant m_holder; + }; + + template + optional::type> make_optional(T&& value); + + // TODO: Args... and initializer_list versions + + // Implementation ////////////////////////////////////////////////////////// + template optional::optional(T &&v) noexcept + : m_holder(v) + { + } + + template optional::optional(const T &v) noexcept + : m_holder(v) + { + } + + template optional::optional(optional&& rhs) noexcept + : m_holder(std::move(rhs.m_holder)) + { + rhs.reset(); + } + + template optional& optional::operator=(optional&& rhs) + { + m_holder = std::move(rhs.m_holder); + rhs.reset(); + return *this; + } + + template T* optional::operator-> () + { + return & *(*this); + } + + template const T* optional::operator-> () const + { + return & *(*this); + } + + template T& optional::operator* () + { + return this->value(); + } + + template const T& optional::operator* () const + { + return this->value(); + } + + template optional::operator bool() const noexcept + { + return this->has_value(); + } + + template bool optional::has_value() const noexcept + { + return util::holds_alternative(m_holder); + } + + template T& optional::value() + { + if (!this->has_value()) + throw_error(bad_optional_access()); + return util::get(m_holder); + } + + template const T& optional::value() const + { + if (!this->has_value()) + throw_error(bad_optional_access()); + return util::get(m_holder); + } + + template + template T optional::value_or(U &&default_value) const + { + return (this->has_value() ? this->value() : T(default_value)); + } + + template void optional::swap(optional &other) noexcept + { + m_holder.swap(other.m_holder); + } + + template void optional::reset() noexcept + { + if (this->has_value()) + m_holder = nothing{}; + } + + template + optional::type> make_optional(T&& value) + { + return optional::type>(std::forward(value)); + } +} // namespace util +} // namespace cv + +#endif // OPENCV_GAPI_UTIL_OPTIONAL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/util/throw.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/throw.hpp new file mode 100755 index 0000000..689bf58 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/throw.hpp @@ -0,0 +1,36 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_UTIL_THROW_HPP +#define OPENCV_GAPI_UTIL_THROW_HPP + +#include // std::forward + +#if !defined(__EXCEPTIONS) +#include +#include +#endif + +namespace cv +{ +namespace util +{ +template +[[noreturn]] void throw_error(ExceptionType &&e) +{ +#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) + throw std::forward(e); +#else + fprintf(stderr, "An exception thrown! %s\n" , e.what()); + fflush(stderr); + abort(); +#endif +} +} // namespace util +} // namespace cv + +#endif // OPENCV_GAPI_UTIL_THROW_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/util/util.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/util.hpp new file mode 100755 index 0000000..afcf559 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/util.hpp @@ -0,0 +1,124 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018-2019 Intel Corporation + + +#ifndef OPENCV_GAPI_UTIL_HPP +#define OPENCV_GAPI_UTIL_HPP + +#include + +// \cond HIDDEN_SYMBOLS +// This header file contains some generic utility functions which are +// used in other G-API Public API headers. +// +// PLEASE don't put any stuff here if it is NOT used in public API headers! + +namespace cv +{ +namespace detail +{ + // Recursive integer sequence type, useful for enumerating elements of + // template parameter packs. + template struct Seq { using next = Seq; }; + template struct MkSeq { using type = typename MkSeq::type::next; }; + template<> struct MkSeq<0>{ using type = Seq<>; }; + + // Checks if elements of variadic template satisfy the given Predicate. + // Implemented via tuple, with an interface to accept plain type lists + template class, typename, typename...> struct all_satisfy; + + template class F, typename T, typename... Ts> + struct all_satisfy > + { + static const constexpr bool value = F::value + && all_satisfy >::value; + }; + template class F, typename T> + struct all_satisfy > + { + static const constexpr bool value = F::value; + }; + + template class F, typename T, typename... Ts> + struct all_satisfy: public all_satisfy > {}; + + // Permute given tuple type C with given integer sequence II + // Sequence may be less than tuple C size. + template struct permute_tuple; + + template + struct permute_tuple > + { + using type = std::tuple< typename std::tuple_element::type... >; + }; + + // Given T..., generates a type sequence of sizeof...(T)-1 elements + // which is T... without its last element + // Implemented via tuple, with an interface to accept plain type lists + template struct all_but_last; + + template + struct all_but_last > + { + using C = std::tuple; + using S = typename MkSeq::value - 1>::type; + using type = typename permute_tuple::type; + }; + + template + struct all_but_last: public all_but_last > {}; + + template + using all_but_last_t = typename all_but_last::type; + + // NB.: This is here because there's no constexpr std::max in C++11 + template struct max_of_t + { + static constexpr const std::size_t rest = max_of_t::value; + static constexpr const std::size_t value = rest > S0 ? rest : S0; + }; + template struct max_of_t + { + static constexpr const std::size_t value = S; + }; + + template + struct contains : std::false_type{}; + + template + struct contains : std::integral_constant::value || + contains::value> {}; + template + struct contains> : std::integral_constant::value> {}; + + template + struct all_unique : std::true_type{}; + + template + struct all_unique : std::integral_constant::value && + all_unique::value> {}; + + template + struct tuple_wrap_helper; + + template struct tuple_wrap_helper + { + using type = std::tuple; + static type get(T&& obj) { return std::make_tuple(std::move(obj)); } + }; + + template + struct tuple_wrap_helper> + { + using type = std::tuple; + static type get(std::tuple&& objs) { return std::forward>(objs); } + }; +} // namespace detail +} // namespace cv + +// \endcond + +#endif // OPENCV_GAPI_UTIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/gapi/util/variant.hpp b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/variant.hpp new file mode 100755 index 0000000..134ba66 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/gapi/util/variant.hpp @@ -0,0 +1,379 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// +// Copyright (C) 2018 Intel Corporation + + +#ifndef OPENCV_GAPI_UTIL_VARIANT_HPP +#define OPENCV_GAPI_UTIL_VARIANT_HPP + +#include +#include + +#include +#include // max_of_t + +// A poor man's `variant` implementation, incompletely modeled against C++17 spec. +namespace cv +{ +namespace util +{ + namespace detail + { + template + struct type_list_index_helper + { + static const constexpr bool is_same = std::is_same::value; + static const constexpr std::size_t value = + std::conditional, type_list_index_helper>::type::value; + }; + + template + struct type_list_index_helper + { + static_assert(std::is_same::value, "Type not found"); + static const constexpr std::size_t value = I; + }; + + + template using are_different = + std::enable_if::type, + typename std::decay::type>::value, + V>; + } + + template + struct type_list_index + { + static const constexpr std::size_t value = detail::type_list_index_helper<0, Target, Types...>::value; + }; + + class bad_variant_access: public std::exception + { + public: + virtual const char *what() const noexcept override + { + return "Bad variant access"; + } + }; + + // Interface /////////////////////////////////////////////////////////////// + struct monostate {}; + inline bool operator==(const util::monostate&, const util::monostate&) + { + return true; + } + + template // FIXME: no references, arrays, and void + class variant + { + // FIXME: Replace with std::aligned_union after gcc4.8 support is dropped + static constexpr const std::size_t S = cv::detail::max_of_t::value; + static constexpr const std::size_t A = cv::detail::max_of_t::value; + using Memory = typename std::aligned_storage::type[1]; + + template struct cctr_h { + static void help(Memory memory, const Memory from) { + new (memory) T(*reinterpret_cast(from)); + } + }; + + template struct vctr_h { + static void help(Memory memory, const void* pval) { + new (memory) T(*reinterpret_cast(pval)); + } + }; + + template struct mctr_h { + static void help(Memory memory, void *pval) { + new (memory) T(std::move(*reinterpret_cast(pval))); + } + }; + + template struct copy_h { + static void help(Memory to, const Memory from) { + *reinterpret_cast(to) = *reinterpret_cast(from); + } + }; + + template struct move_h { + static void help(Memory to, const Memory from) { + *reinterpret_cast(to) = std::move(*reinterpret_cast(from)); + } + }; + + template struct swap_h { + static void help(Memory to, Memory from) { + std::swap(*reinterpret_cast(to), *reinterpret_cast(from)); + } + }; + + template struct dtor_h { + static void help(Memory memory) { + (void) memory; // MSCV warning + reinterpret_cast(memory)->~T(); + } + }; + + template struct equal_h { + static bool help(const Memory lhs, const Memory rhs) { + const T& t_lhs = *reinterpret_cast(lhs); + const T& t_rhs = *reinterpret_cast(rhs); + return t_lhs == t_rhs; + } + }; + + typedef void (*CCtr) (Memory, const Memory); // Copy c-tor (variant) + typedef void (*VCtr) (Memory, const void*); // Copy c-tor (value) + typedef void (*MCtr) (Memory, void*); // Generic move c-tor + typedef void (*Copy) (Memory, const Memory); // Copy assignment + typedef void (*Move) (Memory, const Memory); // Move assignment + typedef void (*Swap) (Memory, Memory); // Swap + typedef void (*Dtor) (Memory); // Destructor + + typedef bool (*Equal)(const Memory, const Memory); // Equality test (external) + + static constexpr std::array cctrs(){ return {{(&cctr_h::help)...}};} + static constexpr std::array vctrs(){ return {{(&vctr_h::help)...}};} + static constexpr std::array mctrs(){ return {{(&mctr_h::help)...}};} + static constexpr std::array cpyrs(){ return {{(©_h::help)...}};} + static constexpr std::array mvers(){ return {{(&move_h::help)...}};} + static constexpr std::array swprs(){ return {{(&swap_h::help)...}};} + static constexpr std::array dtors(){ return {{(&dtor_h::help)...}};} + + std::size_t m_index = 0; + + protected: + template friend T& get(variant &v); + template friend const T& get(const variant &v); + template friend bool operator==(const variant &lhs, + const variant &rhs); + Memory memory; + + public: + // Constructors + variant() noexcept; + variant(const variant& other); + variant(variant&& other) noexcept; + template explicit variant(const T& t); + // are_different is a SFINAE trick to avoid variant(T &&t) with T=variant + // for some reason, this version is called instead of variant(variant&& o) when + // variant is used in STL containers (examples: vector assignment) + template explicit variant(T&& t, typename detail::are_different::type = 0); + // template explicit variant(Args&&... args); + // FIXME: other constructors + + // Destructor + ~variant(); + + // Assignment + variant& operator=(const variant& rhs); + variant& operator=(variant &&rhs) noexcept; + + // SFINAE trick to avoid operator=(T&&) with T=variant<>, see comment above + template + typename detail::are_different + ::type operator=(T&& t) noexcept; + + // Observers + std::size_t index() const noexcept; + // FIXME: valueless_by_exception() + + // Modifiers + // FIXME: emplace() + void swap(variant &rhs) noexcept; + + // Non-C++17x! + template static constexpr std::size_t index_of(); + }; + + // FIMXE: visit + + template + T& get(util::variant &v); + + template + const T& get(const util::variant &v); + + template + bool holds_alternative(const util::variant &v) noexcept; + + // FIXME: T&&, const TT&& versions. + + // Implementation ////////////////////////////////////////////////////////// + template + variant::variant() noexcept + { + typedef typename std::tuple_element<0, std::tuple >::type TFirst; + new (memory) TFirst(); + } + + template + variant::variant(const variant &other) + : m_index(other.m_index) + { + (cctrs()[m_index])(memory, other.memory); + } + + template + variant::variant(variant &&other) noexcept + : m_index(other.m_index) + { + (mctrs()[m_index])(memory, other.memory); + } + + template + template + variant::variant(const T& t) + : m_index(util::type_list_index::value) + { + (vctrs()[m_index])(memory, &t); + } + + template + template + variant::variant(T&& t, typename detail::are_different::type) + : m_index(util::type_list_index::type, Ts...>::value) + { + (mctrs()[m_index])(memory, &t); + } + + template + variant::~variant() + { + (dtors()[m_index])(memory); + } + + template + variant& variant::operator=(const variant &rhs) + { + if (m_index != rhs.m_index) + { + (dtors()[ m_index])(memory); + (cctrs()[rhs.m_index])(memory, rhs.memory); + m_index = rhs.m_index; + } + else + { + (cpyrs()[rhs.m_index])(memory, rhs.memory); + } + return *this; + } + + template + variant& variant::operator=(variant &&rhs) noexcept + { + if (m_index != rhs.m_index) + { + (dtors()[ m_index])(memory); + (mctrs()[rhs.m_index])(memory, rhs.memory); + m_index = rhs.m_index; + } + else + { + (mvers()[rhs.m_index])(memory, rhs.memory); + } + return *this; + } + + template + template typename detail::are_different, T, variant&> + ::type variant::operator=(T&& t) noexcept + { + // FIXME: No version with implicit type conversion available! + static const constexpr std::size_t t_index = + util::type_list_index::value; + + if (t_index == m_index) + { + util::get(*this) = std::move(t); + return *this; + } + else return (*this = variant(std::move(t))); + } + + template + std::size_t util::variant::index() const noexcept + { + return m_index; + } + + template + void variant::swap(variant &rhs) noexcept + { + if (m_index == rhs.index()) + { + (swprs()[m_index](memory, rhs.memory)); + } + else + { + variant tmp(std::move(*this)); + *this = std::move(rhs); + rhs = std::move(tmp); + } + } + + template + template + constexpr std::size_t variant::index_of() + { + return util::type_list_index::value; // FIXME: tests! + } + + template + T& get(util::variant &v) + { + const constexpr std::size_t t_index = + util::type_list_index::value; + + if (v.index() == t_index) + return *(T*)(&v.memory); // workaround for ICC 2019 + // original code: return reinterpret_cast(v.memory); + else + throw_error(bad_variant_access()); + } + + template + const T& get(const util::variant &v) + { + const constexpr std::size_t t_index = + util::type_list_index::value; + + if (v.index() == t_index) + return *(const T*)(&v.memory); // workaround for ICC 2019 + // original code: return reinterpret_cast(v.memory); + else + throw_error(bad_variant_access()); + } + + template + bool holds_alternative(const util::variant &v) noexcept + { + return v.index() == util::variant::template index_of(); + } + + template bool operator==(const variant &lhs, + const variant &rhs) + { + using V = variant; + + // Instantiate table only here since it requires operator== for + // should have operator== only if this one is used, not in general + static const std::array eqs = { + {(&V::template equal_h::help)...} + }; + if (lhs.index() != rhs.index()) + return false; + return (eqs[lhs.index()])(lhs.memory, rhs.memory); + } + + template bool operator!=(const variant &lhs, + const variant &rhs) + { + return !(lhs == rhs); + } +} // namespace cv +} // namespace util + +#endif // OPENCV_GAPI_UTIL_VARIANT_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/highgui.hpp b/Prj-Win/3rd/opencv/include/opencv2/highgui.hpp new file mode 100755 index 0000000..dfd946c --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/highgui.hpp @@ -0,0 +1,841 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HIGHGUI_HPP +#define OPENCV_HIGHGUI_HPP + +#include "opencv2/core.hpp" +#ifdef HAVE_OPENCV_IMGCODECS +#include "opencv2/imgcodecs.hpp" +#endif +#ifdef HAVE_OPENCV_VIDEOIO +#include "opencv2/videoio.hpp" +#endif + +/** +@defgroup highgui High-level GUI + +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 +it is required to try 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 commands. + +@{ + @defgroup highgui_opengl OpenGL support + @defgroup highgui_qt Qt New Functions + + ![image](pics/qtgui.png) + + This figure explains new functionality implemented with Qt\* GUI. The new GUI provides a statusbar, + a toolbar, and a control panel. The control panel can have trackbars and buttonbars attached to it. + If you cannot see the control panel, press Ctrl+P or right-click any Qt window and select **Display + properties window**. + + - 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 to 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. + + See below the example used to generate the figure: + @code + int main(int argc, char *argv[]) + { + + int value = 50; + int value2 = 0; + + + namedWindow("main1",WINDOW_NORMAL); + namedWindow("main2",WINDOW_AUTOSIZE | CV_GUI_NORMAL); + createTrackbar( "track1", "main1", &value, 255, NULL); + + String nameb1 = "button1"; + String nameb2 = "button2"; + + createButton(nameb1,callbackButton,&nameb1,QT_CHECKBOX,1); + createButton(nameb2,callbackButton,NULL,QT_CHECKBOX,0); + createTrackbar( "track2", NULL, &value2, 255, NULL); + createButton("button5",callbackButton1,NULL,QT_RADIOBOX,0); + createButton("button6",callbackButton2,NULL,QT_RADIOBOX,1); + + setMouseCallback( "main2",on_mouse,NULL ); + + Mat img1 = imread("files/flower.jpg"); + VideoCapture video; + video.open("files/hockey.avi"); + + Mat img2,img3; + + while( waitKey(33) != 27 ) + { + img1.convertTo(img2,-1,1,value); + video >> img3; + + imshow("main1",img2); + imshow("main2",img3); + } + + destroyAllWindows(); + + return 0; + } + @endcode + + + @defgroup highgui_winrt WinRT support + + This figure explains new functionality implemented with WinRT GUI. The new GUI provides an Image control, + and a slider panel. Slider panel holds trackbars attached to it. + + Sliders are attached below the image control. Every new slider is added below the previous one. + + See below the example used to generate the figure: + @code + void sample_app::MainPage::ShowWindow() + { + static cv::String windowName("sample"); + cv::winrt_initContainer(this->cvContainer); + cv::namedWindow(windowName); // not required + + cv::Mat image = cv::imread("Assets/sample.jpg"); + cv::Mat converted = cv::Mat(image.rows, image.cols, CV_8UC4); + cv::cvtColor(image, converted, COLOR_BGR2BGRA); + cv::imshow(windowName, converted); // this will create window if it hasn't been created before + + int state = 42; + cv::TrackbarCallback callback = [](int pos, void* userdata) + { + if (pos == 0) { + cv::destroyWindow(windowName); + } + }; + cv::TrackbarCallback callbackTwin = [](int pos, void* userdata) + { + if (pos >= 70) { + cv::destroyAllWindows(); + } + }; + cv::createTrackbar("Sample trackbar", windowName, &state, 100, callback); + cv::createTrackbar("Twin brother", windowName, &state, 100, callbackTwin); + } + @endcode + + @defgroup highgui_c C API +@} +*/ + +///////////////////////// graphical user interface ////////////////////////// +namespace cv +{ + +//! @addtogroup highgui +//! @{ + +//! Flags for cv::namedWindow +enum WindowFlags { + WINDOW_NORMAL = 0x00000000, //!< the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size. + WINDOW_AUTOSIZE = 0x00000001, //!< the user cannot resize the window, the size is constrainted by the image displayed. + WINDOW_OPENGL = 0x00001000, //!< window with opengl support. + + WINDOW_FULLSCREEN = 1, //!< change the window to fullscreen. + WINDOW_FREERATIO = 0x00000100, //!< the image expends as much as it can (no ratio constraint). + WINDOW_KEEPRATIO = 0x00000000, //!< the ratio of the image is respected. + WINDOW_GUI_EXPANDED=0x00000000, //!< status bar and tool bar + WINDOW_GUI_NORMAL = 0x00000010, //!< old fashious way + }; + +//! Flags for cv::setWindowProperty / cv::getWindowProperty +enum WindowPropertyFlags { + WND_PROP_FULLSCREEN = 0, //!< fullscreen property (can be WINDOW_NORMAL or WINDOW_FULLSCREEN). + WND_PROP_AUTOSIZE = 1, //!< autosize property (can be WINDOW_NORMAL or WINDOW_AUTOSIZE). + WND_PROP_ASPECT_RATIO = 2, //!< window's aspect ration (can be set to WINDOW_FREERATIO or WINDOW_KEEPRATIO). + WND_PROP_OPENGL = 3, //!< opengl support. + WND_PROP_VISIBLE = 4 //!< checks whether the window exists and is visible + }; + +//! Mouse Events see cv::MouseCallback +enum MouseEventTypes { + EVENT_MOUSEMOVE = 0, //!< indicates that the mouse pointer has moved over the window. + EVENT_LBUTTONDOWN = 1, //!< indicates that the left mouse button is pressed. + EVENT_RBUTTONDOWN = 2, //!< indicates that the right mouse button is pressed. + EVENT_MBUTTONDOWN = 3, //!< indicates that the middle mouse button is pressed. + EVENT_LBUTTONUP = 4, //!< indicates that left mouse button is released. + EVENT_RBUTTONUP = 5, //!< indicates that right mouse button is released. + EVENT_MBUTTONUP = 6, //!< indicates that middle mouse button is released. + EVENT_LBUTTONDBLCLK = 7, //!< indicates that left mouse button is double clicked. + EVENT_RBUTTONDBLCLK = 8, //!< indicates that right mouse button is double clicked. + EVENT_MBUTTONDBLCLK = 9, //!< indicates that middle mouse button is double clicked. + EVENT_MOUSEWHEEL = 10,//!< positive and negative values mean forward and backward scrolling, respectively. + EVENT_MOUSEHWHEEL = 11 //!< positive and negative values mean right and left scrolling, respectively. + }; + +//! Mouse Event Flags see cv::MouseCallback +enum MouseEventFlags { + EVENT_FLAG_LBUTTON = 1, //!< indicates that the left mouse button is down. + EVENT_FLAG_RBUTTON = 2, //!< indicates that the right mouse button is down. + EVENT_FLAG_MBUTTON = 4, //!< indicates that the middle mouse button is down. + EVENT_FLAG_CTRLKEY = 8, //!< indicates that CTRL Key is pressed. + EVENT_FLAG_SHIFTKEY = 16,//!< indicates that SHIFT Key is pressed. + EVENT_FLAG_ALTKEY = 32 //!< indicates that ALT Key is pressed. + }; + +//! Qt font weight +enum QtFontWeights { + QT_FONT_LIGHT = 25, //!< Weight of 25 + QT_FONT_NORMAL = 50, //!< Weight of 50 + QT_FONT_DEMIBOLD = 63, //!< Weight of 63 + QT_FONT_BOLD = 75, //!< Weight of 75 + QT_FONT_BLACK = 87 //!< Weight of 87 + }; + +//! Qt font style +enum QtFontStyles { + QT_STYLE_NORMAL = 0, //!< Normal font. + QT_STYLE_ITALIC = 1, //!< Italic font. + QT_STYLE_OBLIQUE = 2 //!< Oblique font. + }; + +//! Qt "button" type +enum QtButtonTypes { + QT_PUSH_BUTTON = 0, //!< Push button. + QT_CHECKBOX = 1, //!< Checkbox button. + QT_RADIOBOX = 2, //!< Radiobox button. + QT_NEW_BUTTONBAR = 1024 //!< Button should create a new buttonbar + }; + +/** @brief Callback function for mouse events. see cv::setMouseCallback +@param event one of the cv::MouseEventTypes constants. +@param x The x-coordinate of the mouse event. +@param y The y-coordinate of the mouse event. +@param flags one of the cv::MouseEventFlags constants. +@param userdata The optional parameter. + */ +typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata); + +/** @brief Callback function for Trackbar see cv::createTrackbar +@param pos current position of the specified trackbar. +@param userdata The optional parameter. + */ +typedef void (*TrackbarCallback)(int pos, void* userdata); + +/** @brief Callback function defined to be called every frame. See cv::setOpenGlDrawCallback +@param userdata The optional parameter. + */ +typedef void (*OpenGlDrawCallback)(void* userdata); + +/** @brief Callback function for a button created by cv::createButton +@param state current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button. +@param userdata The optional parameter. + */ +typedef void (*ButtonCallback)(int state, void* userdata); + +/** @brief Creates a window. + +The function namedWindow creates a window that 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. + +You can call cv::destroyWindow or cv::destroyAllWindows to close the window and de-allocate any associated +memory usage. For a simple program, you do not really have to call these functions because all the +resources and windows of the application are closed automatically by the operating system upon exit. + +@note + +Qt backend supports additional flags: + - **WINDOW_NORMAL or WINDOW_AUTOSIZE:** WINDOW_NORMAL enables you to resize the + window, whereas WINDOW_AUTOSIZE adjusts automatically the window size to fit the + displayed image (see imshow ), and you cannot change the window size manually. + - **WINDOW_FREERATIO or WINDOW_KEEPRATIO:** WINDOW_FREERATIO adjusts the image + with no respect to its ratio, whereas WINDOW_KEEPRATIO keeps the image ratio. + - **WINDOW_GUI_NORMAL or WINDOW_GUI_EXPANDED:** WINDOW_GUI_NORMAL is the old way to draw the window + without statusbar and toolbar, whereas WINDOW_GUI_EXPANDED is a new enhanced GUI. +By default, flags == WINDOW_AUTOSIZE | WINDOW_KEEPRATIO | WINDOW_GUI_EXPANDED + +@param winname Name of the window in the window caption that may be used as a window identifier. +@param flags Flags of the window. The supported flags are: (cv::WindowFlags) + */ +CV_EXPORTS_W void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE); + +/** @brief Destroys the specified window. + +The function destroyWindow destroys the window with the given name. + +@param winname Name of the window to be destroyed. + */ +CV_EXPORTS_W void destroyWindow(const String& winname); + +/** @brief Destroys all of the HighGUI windows. + +The function destroyAllWindows destroys all of the opened HighGUI windows. + */ +CV_EXPORTS_W void destroyAllWindows(); + +CV_EXPORTS_W int startWindowThread(); + +/** @brief Similar to #waitKey, but returns full key code. + +@note + +Key code is implementation specific and depends on used backend: QT/GTK/Win32/etc + +*/ +CV_EXPORTS_W int waitKeyEx(int delay = 0); + +/** @brief Waits for a pressed key. + +The function waitKey waits for a key event infinitely (when \f$\texttt{delay}\leq 0\f$ ) or for delay +milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the +function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is +running on your computer at that time. It 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 an environment that +takes care of event processing. + +@note + +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. + +@param delay Delay in milliseconds. 0 is the special value that means "forever". + */ +CV_EXPORTS_W int waitKey(int delay = 0); + +/** @brief Displays an image in the specified window. + +The function imshow displays an image in the specified window. If the window was created with the +cv::WINDOW_AUTOSIZE flag, the image is shown with its original size, however it is still limited by the screen resolution. +Otherwise, the image is scaled to fit 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 or 64-bit floating-point, the pixel values are multiplied by 255. That is, the + value range [0,1] is mapped to [0,255]. + +If window was created with OpenGL support, cv::imshow also support ogl::Buffer , ogl::Texture2D and +cuda::GpuMat as input. + +If the window was not created before this function, it is assumed creating a window with cv::WINDOW_AUTOSIZE. + +If you need to show an image that is bigger than the screen resolution, you will need to call namedWindow("", WINDOW_NORMAL) before the imshow. + +@note This function should be followed by cv::waitKey function which displays the image for specified +milliseconds. Otherwise, it won't display the image. For example, **waitKey(0)** will display the window +infinitely until any keypress (it is suitable for image display). **waitKey(25)** will display a frame +for 25 ms, after which display will be automatically closed. (If you put it in a loop to read +videos, it will display the video frame-by-frame) + +@note + +[__Windows Backend Only__] Pressing Ctrl+C will copy the image to the clipboard. + +[__Windows Backend Only__] Pressing Ctrl+S will show a dialog to save the image. + +@param winname Name of the window. +@param mat Image to be shown. + */ +CV_EXPORTS_W void imshow(const String& winname, InputArray mat); + +/** @brief Resizes window to the specified size + +@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. + +@param winname Window name. +@param width The new window width. +@param height The new window height. + */ +CV_EXPORTS_W void resizeWindow(const String& winname, int width, int height); + +/** @overload +@param winname Window name. +@param size The new window size. +*/ +CV_EXPORTS_W void resizeWindow(const String& winname, const cv::Size& size); + +/** @brief Moves window to the specified position + +@param winname Name of the window. +@param x The new x-coordinate of the window. +@param y The new y-coordinate of the window. + */ +CV_EXPORTS_W void moveWindow(const String& winname, int x, int y); + +/** @brief Changes parameters of a window dynamically. + +The function setWindowProperty enables changing properties of a window. + +@param winname Name of the window. +@param prop_id Window property to edit. The supported operation flags are: (cv::WindowPropertyFlags) +@param prop_value New value of the window property. The supported flags are: (cv::WindowFlags) + */ +CV_EXPORTS_W void setWindowProperty(const String& winname, int prop_id, double prop_value); + +/** @brief Updates window title +@param winname Name of the window. +@param title New title. +*/ +CV_EXPORTS_W void setWindowTitle(const String& winname, const String& title); + +/** @brief Provides parameters of a window. + +The function getWindowProperty returns properties of a window. + +@param winname Name of the window. +@param prop_id Window property to retrieve. The following operation flags are available: (cv::WindowPropertyFlags) + +@sa setWindowProperty + */ +CV_EXPORTS_W double getWindowProperty(const String& winname, int prop_id); + +/** @brief Provides rectangle of image in the window. + +The function getWindowImageRect returns the client screen coordinates, width and height of the image rendering area. + +@param winname Name of the window. + +@sa resizeWindow moveWindow + */ +CV_EXPORTS_W Rect getWindowImageRect(const String& winname); + +/** @example samples/cpp/create_mask.cpp +This program demonstrates using mouse events and how to make and use a mask image (black and white) . +*/ +/** @brief Sets mouse handler for the specified window + +@param winname Name of the window. +@param onMouse Callback function for mouse events. See OpenCV samples on how to specify and use the callback. +@param userdata The optional parameter passed to the callback. + */ +CV_EXPORTS void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0); + +/** @brief Gets the mouse-wheel motion delta, when handling mouse-wheel events cv::EVENT_MOUSEWHEEL and +cv::EVENT_MOUSEHWHEEL. + +For regular mice with a scroll-wheel, delta will be a multiple of 120. The value 120 corresponds to +a one notch rotation of the wheel or the threshold for action to be taken and one such action should +occur for each delta. Some high-precision mice with higher-resolution freely-rotating wheels may +generate smaller values. + +For cv::EVENT_MOUSEWHEEL positive and negative values mean forward and backward scrolling, +respectively. For cv::EVENT_MOUSEHWHEEL, where available, positive and negative values mean right and +left scrolling, respectively. + +With the C API, the macro CV_GET_WHEEL_DELTA(flags) can be used alternatively. + +@note + +Mouse-wheel events are currently supported only on Windows. + +@param flags The mouse callback flags parameter. + */ +CV_EXPORTS int getMouseWheelDelta(int flags); + +/** @brief Selects ROI on the given image. +Function creates a window and allows user to select a ROI using mouse. +Controls: use `space` or `enter` to finish selection, use key `c` to cancel selection (function will return the zero cv::Rect). + +@param windowName name of the window where selection process will be shown. +@param img image to select a ROI. +@param showCrosshair if true crosshair of selection rectangle will be shown. +@param fromCenter if true center of selection will match initial mouse position. In opposite case a corner of +selection rectangle will correspont to the initial mouse position. +@return selected ROI or empty rect if selection canceled. + +@note The function sets it's own mouse callback for specified window using cv::setMouseCallback(windowName, ...). +After finish of work an empty callback will be set for the used window. + */ +CV_EXPORTS_W Rect selectROI(const String& windowName, InputArray img, bool showCrosshair = true, bool fromCenter = false); + +/** @overload + */ +CV_EXPORTS_W Rect selectROI(InputArray img, bool showCrosshair = true, bool fromCenter = false); + +/** @brief Selects ROIs on the given image. +Function creates a window and allows user to select a ROIs using mouse. +Controls: use `space` or `enter` to finish current selection and start a new one, +use `esc` to terminate multiple ROI selection process. + +@param windowName name of the window where selection process will be shown. +@param img image to select a ROI. +@param boundingBoxes selected ROIs. +@param showCrosshair if true crosshair of selection rectangle will be shown. +@param fromCenter if true center of selection will match initial mouse position. In opposite case a corner of +selection rectangle will correspont to the initial mouse position. + +@note The function sets it's own mouse callback for specified window using cv::setMouseCallback(windowName, ...). +After finish of work an empty callback will be set for the used window. + */ +CV_EXPORTS_W void selectROIs(const String& windowName, InputArray img, + CV_OUT std::vector& boundingBoxes, bool showCrosshair = true, bool fromCenter = false); + +/** @brief Creates a trackbar and attaches it to the specified window. + +The function createTrackbar creates a trackbar (a slider or range control) with the specified name +and range, assigns a variable value to be a position synchronized with the trackbar and specifies +the callback function onChange to be called on the trackbar position change. The created trackbar is +displayed in the specified window winname. + +@note + +[__Qt Backend Only__] winname can be empty if the trackbar should be attached to the +control panel. + +Clicking the label of each trackbar enables editing the trackbar values manually. + +@param trackbarname Name of the created trackbar. +@param winname Name of the window that will be used as a parent of the created trackbar. +@param value Optional pointer to an integer variable whose value reflects the position of the +slider. Upon creation, the slider position is defined by this variable. +@param count Maximal position of the slider. The 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,void\*); , where the first parameter is the trackbar +position and the second parameter is the user data (see the next parameter). If the callback is +the NULL pointer, no callbacks are called, but only value is updated. +@param userdata User data that is passed as is to the callback. It can be used to handle trackbar +events without using global variables. + */ +CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname, + int* value, int count, + TrackbarCallback onChange = 0, + void* userdata = 0); + +/** @brief Returns the trackbar position. + +The function returns the current position of the specified trackbar. + +@note + +[__Qt Backend Only__] winname can be empty if the trackbar is attached to the control +panel. + +@param trackbarname Name of the trackbar. +@param winname Name of the window that is the parent of the trackbar. + */ +CV_EXPORTS_W int getTrackbarPos(const String& trackbarname, const String& winname); + +/** @brief Sets the trackbar position. + +The function sets the position of the specified trackbar in the specified window. + +@note + +[__Qt Backend Only__] winname can be empty if the trackbar is attached to the control +panel. + +@param trackbarname Name of the trackbar. +@param winname Name of the window that is the parent of trackbar. +@param pos New position. + */ +CV_EXPORTS_W void setTrackbarPos(const String& trackbarname, const String& winname, int pos); + +/** @brief Sets the trackbar maximum position. + +The function sets the maximum position of the specified trackbar in the specified window. + +@note + +[__Qt Backend Only__] winname can be empty if the trackbar is attached to the control +panel. + +@param trackbarname Name of the trackbar. +@param winname Name of the window that is the parent of trackbar. +@param maxval New maximum position. + */ +CV_EXPORTS_W void setTrackbarMax(const String& trackbarname, const String& winname, int maxval); + +/** @brief Sets the trackbar minimum position. + +The function sets the minimum position of the specified trackbar in the specified window. + +@note + +[__Qt Backend Only__] winname can be empty if the trackbar is attached to the control +panel. + +@param trackbarname Name of the trackbar. +@param winname Name of the window that is the parent of trackbar. +@param minval New minimum position. + */ +CV_EXPORTS_W void setTrackbarMin(const String& trackbarname, const String& winname, int minval); + +//! @addtogroup highgui_opengl OpenGL support +//! @{ + +/** @brief Displays OpenGL 2D texture in the specified window. + +@param winname Name of the window. +@param tex OpenGL 2D texture data. + */ +CV_EXPORTS void imshow(const String& winname, const ogl::Texture2D& tex); + +/** @brief Sets a callback function to be called to draw on top of displayed image. + +The function setOpenGlDrawCallback can be used to draw 3D data on the window. See the example of +callback function below: +@code + void on_opengl(void* param) + { + 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(); + } + } +@endcode + +@param winname Name of the window. +@param onOpenGlDraw 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__) + */ +CV_EXPORTS void setOpenGlDrawCallback(const String& winname, OpenGlDrawCallback onOpenGlDraw, void* userdata = 0); + +/** @brief Sets the specified window as current OpenGL context. + +@param winname Name of the window. + */ +CV_EXPORTS void setOpenGlContext(const String& winname); + +/** @brief Force window to redraw its context and call draw callback ( See cv::setOpenGlDrawCallback ). + +@param winname Name of the window. + */ +CV_EXPORTS void updateWindow(const String& winname); + +//! @} highgui_opengl + +//! @addtogroup highgui_qt +//! @{ + +/** @brief QtFont available only for Qt. See cv::fontQt + */ +struct QtFont +{ + const char* nameFont; //!< Name of the font + Scalar color; //!< Color of the font. Scalar(blue_component, green_component, red_component[, alpha_component]) + int font_face; //!< See cv::QtFontStyles + const int* ascii; //!< font data and metrics + const int* greek; + const int* cyrillic; + float hscale, vscale; + float shear; //!< slope coefficient: 0 - normal, >0 - italic + int thickness; //!< See cv::QtFontWeights + float dx; //!< horizontal interval between letters + int line_type; //!< PointSize +}; + +/** @brief Creates the font to draw a text on an image. + +The function fontQt creates a cv::QtFont object. This cv::QtFont is not compatible with putText . + +A basic usage of this function is the following: : +@code + QtFont font = fontQt("Times"); + addText( img1, "Hello World !", Point(50,50), font); +@endcode + +@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 is 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 where A = 255 is fully transparent. Use the macro CV_RGB +for simplicity. +@param weight Font weight. Available operation flags are : cv::QtFontWeights You can also specify a positive integer for better control. +@param style Font style. Available operation flags are : cv::QtFontStyles +@param spacing Spacing between characters. It can be negative or positive. + */ +CV_EXPORTS QtFont fontQt(const String& nameFont, int pointSize = -1, + Scalar color = Scalar::all(0), int weight = QT_FONT_NORMAL, + int style = QT_STYLE_NORMAL, int spacing = 0); + +/** @brief Draws a text on the image. + +The function addText draws *text* on the image *img* using a specific font *font* (see example cv::fontQt +) + +@param img 8-bit 3-channel image where the text should be drawn. +@param text Text to write on an image. +@param org Point(x,y) where the text should start on an image. +@param font Font to use to draw a text. + */ +CV_EXPORTS void addText( const Mat& img, const String& text, Point org, const QtFont& font); + +/** @brief Draws a text on the image. + +@param img 8-bit 3-channel image where the text should be drawn. +@param text Text to write on an image. +@param org Point(x,y) where the text should start on an image. +@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 is 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 where A = 255 is fully transparent. +@param weight Font weight. Available operation flags are : cv::QtFontWeights You can also specify a positive integer for better control. +@param style Font style. Available operation flags are : cv::QtFontStyles +@param spacing Spacing between characters. It can be negative or positive. + */ +CV_EXPORTS_W void addText(const Mat& img, const String& text, Point org, const String& nameFont, int pointSize = -1, Scalar color = Scalar::all(0), + int weight = QT_FONT_NORMAL, int style = QT_STYLE_NORMAL, int spacing = 0); + +/** @brief Displays a text on a window image as an overlay for a specified duration. + +The function displayOverlay displays useful information/tips on top of the window for a certain +amount of time *delayms*. The function does not modify the image, displayed in the window, that is, +after the specified delay the original content of the window is restored. + +@param winname Name of the window. +@param text Overlay text to write on a window image. +@param delayms The period (in milliseconds), during which the overlay text is displayed. If this +function is called before the previous overlay text timed out, the timer is restarted and the text +is updated. If this value is zero, the text never disappears. + */ +CV_EXPORTS_W void displayOverlay(const String& winname, const String& text, int delayms = 0); + +/** @brief Displays a text on the window statusbar during the specified period of time. + +The function displayStatusBar displays useful information/tips on top of the window for a certain +amount of time *delayms* . This information is displayed on the window statusbar (the window must be +created with the CV_GUI_EXPANDED flags). + +@param winname Name of the window. +@param text Text to write on the window statusbar. +@param delayms Duration (in milliseconds) to display the text. If this function is called before +the previous text timed out, the timer is restarted and the text is updated. If this value is +zero, the text never disappears. + */ +CV_EXPORTS_W void displayStatusBar(const String& winname, const String& text, int delayms = 0); + +/** @brief Saves parameters of the specified window. + +The function saveWindowParameters saves size, location, flags, trackbars value, zoom and panning +location of the window windowName. + +@param windowName Name of the window. + */ +CV_EXPORTS void saveWindowParameters(const String& windowName); + +/** @brief Loads parameters of the specified window. + +The function loadWindowParameters loads size, location, flags, trackbars value, zoom and panning +location of the window windowName. + +@param windowName Name of the window. + */ +CV_EXPORTS void loadWindowParameters(const String& windowName); + +CV_EXPORTS int startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]); + +CV_EXPORTS void stopLoop(); + +/** @brief Attaches a button to the control panel. + +The function createButton attaches a button to the control panel. Each button is added to a +buttonbar to the right of the last button. A new buttonbar is created if nothing was attached to the +control panel before, or if the last element attached to the control panel was a trackbar or if the +QT_NEW_BUTTONBAR flag is added to the type. + +See below various examples of the cv::createButton function call: : +@code + createButton("",callbackButton);//create a push button "button 0", that will call callbackButton. + createButton("button2",callbackButton,NULL,QT_CHECKBOX,0); + createButton("button3",callbackButton,&value); + createButton("button5",callbackButton1,NULL,QT_RADIOBOX); + createButton("button6",callbackButton2,NULL,QT_PUSH_BUTTON,1); + createButton("button6",callbackButton2,NULL,QT_PUSH_BUTTON|QT_NEW_BUTTONBAR);// create a push button in a new row +@endcode + +@param bar_name Name of the button. +@param on_change Pointer to the function to be called every time the button changes 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. +@param type Optional type of the button. Available types are: (cv::QtButtonTypes) +@param initial_button_state Default state of the button. Use for checkbox and radiobox. Its +value could be 0 or 1. (__Optional__) +*/ +CV_EXPORTS int createButton( const String& bar_name, ButtonCallback on_change, + void* userdata = 0, int type = QT_PUSH_BUTTON, + bool initial_button_state = false); + +//! @} highgui_qt + +//! @} highgui + +} // cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/highgui/highgui.hpp b/Prj-Win/3rd/opencv/include/opencv2/highgui/highgui.hpp new file mode 100755 index 0000000..160c9cf --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/highgui/highgui.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/highgui.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/highgui/highgui_c.h b/Prj-Win/3rd/opencv/include/opencv2/highgui/highgui_c.h new file mode 100755 index 0000000..5d20b95 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/highgui/highgui_c.h @@ -0,0 +1,256 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_HIGHGUI_H +#define OPENCV_HIGHGUI_H + +#include "opencv2/core/core_c.h" +#include "opencv2/imgproc/imgproc_c.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup highgui_c + @{ + */ + +/****************************************************************************************\ +* Basic GUI functions * +\****************************************************************************************/ +//YV +//-----------New for Qt +/* For font */ +enum { CV_FONT_LIGHT = 25,//QFont::Light, + CV_FONT_NORMAL = 50,//QFont::Normal, + CV_FONT_DEMIBOLD = 63,//QFont::DemiBold, + CV_FONT_BOLD = 75,//QFont::Bold, + CV_FONT_BLACK = 87 //QFont::Black +}; + +enum { CV_STYLE_NORMAL = 0,//QFont::StyleNormal, + CV_STYLE_ITALIC = 1,//QFont::StyleItalic, + CV_STYLE_OBLIQUE = 2 //QFont::StyleOblique +}; +/* ---------*/ + +//for color cvScalar(blue_component, green_component, red_component[, alpha_component]) +//and alpha= 0 <-> 0xFF (not transparent <-> transparent) +CVAPI(CvFont) cvFontQt(const char* nameFont, int pointSize CV_DEFAULT(-1), CvScalar color CV_DEFAULT(cvScalarAll(0)), int weight CV_DEFAULT(CV_FONT_NORMAL), int style CV_DEFAULT(CV_STYLE_NORMAL), int spacing CV_DEFAULT(0)); + +CVAPI(void) cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont *arg2); + +CVAPI(void) cvDisplayOverlay(const char* name, const char* text, int delayms CV_DEFAULT(0)); +CVAPI(void) cvDisplayStatusBar(const char* name, const char* text, int delayms CV_DEFAULT(0)); + +CVAPI(void) cvSaveWindowParameters(const char* name); +CVAPI(void) cvLoadWindowParameters(const char* name); +CVAPI(int) cvStartLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]); +CVAPI(void) cvStopLoop( void ); + +typedef void (CV_CDECL *CvButtonCallback)(int state, void* userdata); +enum {CV_PUSH_BUTTON = 0, CV_CHECKBOX = 1, CV_RADIOBOX = 2}; +CVAPI(int) 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)); +//---------------------- + + +/* this function is used to set some external parameters in case of X Window */ +CVAPI(int) cvInitSystem( int argc, char** argv ); + +CVAPI(int) cvStartWindowThread( void ); + +// --------- YV --------- +enum +{ + //These 3 flags are used by cvSet/GetWindowProperty + CV_WND_PROP_FULLSCREEN = 0, //to change/get window's fullscreen property + CV_WND_PROP_AUTOSIZE = 1, //to change/get window's autosize property + CV_WND_PROP_ASPECTRATIO= 2, //to change/get window's aspectratio property + CV_WND_PROP_OPENGL = 3, //to change/get window's opengl support + CV_WND_PROP_VISIBLE = 4, + + //These 2 flags are used by cvNamedWindow and cvSet/GetWindowProperty + CV_WINDOW_NORMAL = 0x00000000, //the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size + CV_WINDOW_AUTOSIZE = 0x00000001, //the user cannot resize the window, the size is constrainted by the image displayed + CV_WINDOW_OPENGL = 0x00001000, //window with opengl support + + //Those flags are only for Qt + CV_GUI_EXPANDED = 0x00000000, //status bar and tool bar + CV_GUI_NORMAL = 0x00000010, //old fashious way + + //These 3 flags are used by cvNamedWindow and cvSet/GetWindowProperty + CV_WINDOW_FULLSCREEN = 1,//change the window to fullscreen + CV_WINDOW_FREERATIO = 0x00000100,//the image expends as much as it can (no ratio constraint) + CV_WINDOW_KEEPRATIO = 0x00000000//the ration image is respected. +}; + +/* create window */ +CVAPI(int) cvNamedWindow( const char* name, int flags CV_DEFAULT(CV_WINDOW_AUTOSIZE) ); + +/* Set and Get Property of the window */ +CVAPI(void) cvSetWindowProperty(const char* name, int prop_id, double prop_value); +CVAPI(double) cvGetWindowProperty(const char* name, int prop_id); + +#ifdef __cplusplus // FIXIT remove in OpenCV 4.0 +/* Get window image rectangle coordinates, width and height */ +CVAPI(cv::Rect)cvGetWindowImageRect(const char* name); +#endif + +/* display image within window (highgui windows remember their content) */ +CVAPI(void) cvShowImage( const char* name, const CvArr* image ); + +/* resize/move window */ +CVAPI(void) cvResizeWindow( const char* name, int width, int height ); +CVAPI(void) cvMoveWindow( const char* name, int x, int y ); + + +/* destroy window and all the trackers associated with it */ +CVAPI(void) cvDestroyWindow( const char* name ); + +CVAPI(void) cvDestroyAllWindows(void); + +/* get native window handle (HWND in case of Win32 and Widget in case of X Window) */ +CVAPI(void*) cvGetWindowHandle( const char* name ); + +/* get name of highgui window given its native handle */ +CVAPI(const char*) cvGetWindowName( void* window_handle ); + + +typedef void (CV_CDECL *CvTrackbarCallback)(int pos); + +/* create trackbar and display it on top of given window, set callback */ +CVAPI(int) cvCreateTrackbar( const char* trackbar_name, const char* window_name, + int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL)); + +typedef void (CV_CDECL *CvTrackbarCallback2)(int pos, void* userdata); + +CVAPI(int) cvCreateTrackbar2( const char* trackbar_name, const char* window_name, + int* value, int count, CvTrackbarCallback2 on_change, + void* userdata CV_DEFAULT(0)); + +/* retrieve or set trackbar position */ +CVAPI(int) cvGetTrackbarPos( const char* trackbar_name, const char* window_name ); +CVAPI(void) cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos ); +CVAPI(void) cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval); +CVAPI(void) cvSetTrackbarMin(const char* trackbar_name, const char* window_name, int minval); + +enum +{ + CV_EVENT_MOUSEMOVE =0, + CV_EVENT_LBUTTONDOWN =1, + CV_EVENT_RBUTTONDOWN =2, + CV_EVENT_MBUTTONDOWN =3, + CV_EVENT_LBUTTONUP =4, + CV_EVENT_RBUTTONUP =5, + CV_EVENT_MBUTTONUP =6, + CV_EVENT_LBUTTONDBLCLK =7, + CV_EVENT_RBUTTONDBLCLK =8, + CV_EVENT_MBUTTONDBLCLK =9, + CV_EVENT_MOUSEWHEEL =10, + CV_EVENT_MOUSEHWHEEL =11 +}; + +enum +{ + CV_EVENT_FLAG_LBUTTON =1, + CV_EVENT_FLAG_RBUTTON =2, + CV_EVENT_FLAG_MBUTTON =4, + CV_EVENT_FLAG_CTRLKEY =8, + CV_EVENT_FLAG_SHIFTKEY =16, + CV_EVENT_FLAG_ALTKEY =32 +}; + + +#define CV_GET_WHEEL_DELTA(flags) ((short)((flags >> 16) & 0xffff)) // upper 16 bits + +typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param); + +/* assign callback for mouse events */ +CVAPI(void) cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, + void* param CV_DEFAULT(NULL)); + +/* wait for key event infinitely (delay<=0) or for "delay" milliseconds */ +CVAPI(int) cvWaitKey(int delay CV_DEFAULT(0)); + +// OpenGL support + +typedef void (CV_CDECL *CvOpenGlDrawCallback)(void* userdata); +CVAPI(void) cvSetOpenGlDrawCallback(const char* window_name, CvOpenGlDrawCallback callback, void* userdata CV_DEFAULT(NULL)); + +CVAPI(void) cvSetOpenGlContext(const char* window_name); +CVAPI(void) cvUpdateWindow(const char* window_name); + + +/****************************************************************************************\ + +* Obsolete functions/synonyms * +\****************************************************************************************/ + +#define cvAddSearchPath(path) +#define cvvInitSystem cvInitSystem +#define cvvNamedWindow cvNamedWindow +#define cvvShowImage cvShowImage +#define cvvResizeWindow cvResizeWindow +#define cvvDestroyWindow cvDestroyWindow +#define cvvCreateTrackbar cvCreateTrackbar +#define cvvAddSearchPath cvAddSearchPath +#define cvvWaitKey(name) cvWaitKey(0) +#define cvvWaitKeyEx(name,delay) cvWaitKey(delay) +#define HG_AUTOSIZE CV_WINDOW_AUTOSIZE +#define set_preprocess_func cvSetPreprocessFuncWin32 +#define set_postprocess_func cvSetPostprocessFuncWin32 + +#if defined _WIN32 + +CVAPI(void) cvSetPreprocessFuncWin32_(const void* callback); +CVAPI(void) cvSetPostprocessFuncWin32_(const void* callback); +#define cvSetPreprocessFuncWin32(callback) cvSetPreprocessFuncWin32_((const void*)(callback)) +#define cvSetPostprocessFuncWin32(callback) cvSetPostprocessFuncWin32_((const void*)(callback)) + +#endif + +/** @} highgui_c */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgcodecs.hpp b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs.hpp new file mode 100755 index 0000000..143926b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs.hpp @@ -0,0 +1,277 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_IMGCODECS_HPP +#define OPENCV_IMGCODECS_HPP + +#include "opencv2/core.hpp" + +/** + @defgroup imgcodecs Image file reading and writing + @{ + @defgroup imgcodecs_c C API + @defgroup imgcodecs_ios iOS glue + @} +*/ + +//////////////////////////////// image codec //////////////////////////////// +namespace cv +{ + +//! @addtogroup imgcodecs +//! @{ + +//! Imread flags +enum ImreadModes { + IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). + IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image (codec internal conversion). + IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image. + IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit. + IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format. + IMREAD_LOAD_GDAL = 8, //!< If set, use the gdal driver for loading the image. + IMREAD_REDUCED_GRAYSCALE_2 = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2. + IMREAD_REDUCED_COLOR_2 = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2. + IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4. + IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4. + IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8. + IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8. + IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag. + }; + +//! Imwrite flags +enum ImwriteFlags { + IMWRITE_JPEG_QUALITY = 1, //!< For JPEG, it can be a quality from 0 to 100 (the higher is the better). Default value is 95. + IMWRITE_JPEG_PROGRESSIVE = 2, //!< Enable JPEG features, 0 or 1, default is False. + IMWRITE_JPEG_OPTIMIZE = 3, //!< Enable JPEG features, 0 or 1, default is False. + IMWRITE_JPEG_RST_INTERVAL = 4, //!< JPEG restart interval, 0 - 65535, default is 0 - no restart. + IMWRITE_JPEG_LUMA_QUALITY = 5, //!< Separate luma quality level, 0 - 100, default is 0 - don't use. + IMWRITE_JPEG_CHROMA_QUALITY = 6, //!< Separate chroma quality level, 0 - 100, default is 0 - don't use. + IMWRITE_PNG_COMPRESSION = 16, //!< For PNG, it can be the compression level from 0 to 9. A higher value means a smaller size and longer compression time. If specified, strategy is changed to IMWRITE_PNG_STRATEGY_DEFAULT (Z_DEFAULT_STRATEGY). Default value is 1 (best speed setting). + IMWRITE_PNG_STRATEGY = 17, //!< One of cv::ImwritePNGFlags, default is IMWRITE_PNG_STRATEGY_RLE. + IMWRITE_PNG_BILEVEL = 18, //!< Binary level PNG, 0 or 1, default is 0. + IMWRITE_PXM_BINARY = 32, //!< For PPM, PGM, or PBM, it can be a binary format flag, 0 or 1. Default value is 1. + IMWRITE_EXR_TYPE = (3 << 4) + 0, /* 48 */ //!< override EXR storage type (FLOAT (FP32) is default) + IMWRITE_WEBP_QUALITY = 64, //!< For WEBP, it can be a quality from 1 to 100 (the higher is the better). By default (without any parameter) and for quality above 100 the lossless compression is used. + IMWRITE_PAM_TUPLETYPE = 128,//!< For PAM, sets the TUPLETYPE field to the corresponding string value that is defined for the format + IMWRITE_TIFF_RESUNIT = 256,//!< For TIFF, use to specify which DPI resolution unit to set; see libtiff documentation for valid values + IMWRITE_TIFF_XDPI = 257,//!< For TIFF, use to specify the X direction DPI + IMWRITE_TIFF_YDPI = 258, //!< For TIFF, use to specify the Y direction DPI + IMWRITE_TIFF_COMPRESSION = 259, //!< For TIFF, use to specify the image compression scheme. See libtiff for integer constants corresponding to compression formats. Note, for images whose depth is CV_32F, only libtiff's SGILOG compression scheme is used. For other supported depths, the compression scheme can be specified by this flag; LZW compression is the default. + IMWRITE_JPEG2000_COMPRESSION_X1000 = 272 //!< For JPEG2000, use to specify the target compression rate (multiplied by 1000). The value can be from 0 to 1000. Default is 1000. + }; + +enum ImwriteEXRTypeFlags { + /*IMWRITE_EXR_TYPE_UNIT = 0, //!< not supported */ + IMWRITE_EXR_TYPE_HALF = 1, //!< store as HALF (FP16) + IMWRITE_EXR_TYPE_FLOAT = 2 //!< store as FP32 (default) + }; + +//! Imwrite PNG specific flags used to tune the compression algorithm. +/** These flags will be modify the way of PNG image compression and will be passed to the underlying zlib processing stage. + +- The effect of IMWRITE_PNG_STRATEGY_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between IMWRITE_PNG_STRATEGY_DEFAULT and IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY. +- IMWRITE_PNG_STRATEGY_RLE is designed to be almost as fast as IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY, but give better compression for PNG image data. +- The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. +- IMWRITE_PNG_STRATEGY_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. +*/ +enum ImwritePNGFlags { + IMWRITE_PNG_STRATEGY_DEFAULT = 0, //!< Use this value for normal data. + IMWRITE_PNG_STRATEGY_FILTERED = 1, //!< Use this value for data produced by a filter (or predictor).Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. + IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY = 2, //!< Use this value to force Huffman encoding only (no string match). + IMWRITE_PNG_STRATEGY_RLE = 3, //!< Use this value to limit match distances to one (run-length encoding). + IMWRITE_PNG_STRATEGY_FIXED = 4 //!< Using this value prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. + }; + +//! Imwrite PAM specific tupletype flags used to define the 'TUPETYPE' field of a PAM file. +enum ImwritePAMFlags { + IMWRITE_PAM_FORMAT_NULL = 0, + IMWRITE_PAM_FORMAT_BLACKANDWHITE = 1, + IMWRITE_PAM_FORMAT_GRAYSCALE = 2, + IMWRITE_PAM_FORMAT_GRAYSCALE_ALPHA = 3, + IMWRITE_PAM_FORMAT_RGB = 4, + IMWRITE_PAM_FORMAT_RGB_ALPHA = 5, + }; + +/** @brief Loads an image from a file. + +@anchor imread + +The function imread loads an image from the specified file and returns it. If the image cannot be +read (because of missing file, improper permissions, unsupported or invalid format), the function +returns an empty matrix ( Mat::data==NULL ). + +Currently, the following file formats are supported: + +- Windows bitmaps - \*.bmp, \*.dib (always supported) +- JPEG files - \*.jpeg, \*.jpg, \*.jpe (see the *Note* section) +- JPEG 2000 files - \*.jp2 (see the *Note* section) +- Portable Network Graphics - \*.png (see the *Note* section) +- WebP - \*.webp (see the *Note* section) +- Portable image format - \*.pbm, \*.pgm, \*.ppm \*.pxm, \*.pnm (always supported) +- PFM files - \*.pfm (see the *Note* section) +- Sun rasters - \*.sr, \*.ras (always supported) +- TIFF files - \*.tiff, \*.tif (see the *Note* section) +- OpenEXR Image files - \*.exr (see the *Note* section) +- Radiance HDR - \*.hdr, \*.pic (always supported) +- Raster and Vector geospatial data supported by GDAL (see the *Note* section) + +@note +- The function determines the type of an image by the content, not by the file extension. +- In the case of color images, the decoded images will have the channels stored in **B G R** order. +- When using IMREAD_GRAYSCALE, the codec's internal grayscale conversion will be used, if available. + Results may differ to the output of cvtColor() +- On Microsoft Windows\* OS and MacOSX\*, the codecs shipped with an OpenCV image (libjpeg, + libpng, libtiff, and libjasper) are used by default. So, OpenCV can always read JPEGs, PNGs, + and TIFFs. On MacOSX, there is also an option to use native MacOSX image readers. But beware + that currently these native image loaders give images with different pixel values because of + the color management embedded into MacOSX. +- On Linux\*, BSD flavors and other Unix-like open-source operating systems, OpenCV looks for + codecs supplied with an OS image. Install the relevant packages (do not forget the development + files, for example, "libjpeg-dev", in Debian\* and Ubuntu\*) to get the codec support or turn + on the OPENCV_BUILD_3RDPARTY_LIBS flag in CMake. +- In the case you set *WITH_GDAL* flag to true in CMake and @ref IMREAD_LOAD_GDAL to load the image, + then the [GDAL](http://www.gdal.org) driver will be used in order to decode the image, supporting + the following formats: [Raster](http://www.gdal.org/formats_list.html), + [Vector](http://www.gdal.org/ogr_formats.html). +- If EXIF information are embedded in the image file, the EXIF orientation will be taken into account + and thus the image will be rotated accordingly except if the flag @ref IMREAD_IGNORE_ORIENTATION is passed. +- Use the IMREAD_UNCHANGED flag to keep the floating point values from PFM image. +- By default number of pixels must be less than 2^30. Limit can be set using system + variable OPENCV_IO_MAX_IMAGE_PIXELS + +@param filename Name of file to be loaded. +@param flags Flag that can take values of cv::ImreadModes +*/ +CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR ); + +/** @brief Loads a multi-page image from a file. + +The function imreadmulti loads a multi-page image from the specified file into a vector of Mat objects. +@param filename Name of file to be loaded. +@param flags Flag that can take values of cv::ImreadModes, default with cv::IMREAD_ANYCOLOR. +@param mats A vector of Mat objects holding each page, if more than one. +@sa cv::imread +*/ +CV_EXPORTS_W bool imreadmulti(const String& filename, CV_OUT std::vector& mats, int flags = IMREAD_ANYCOLOR); + +/** @brief Saves an image to a specified file. + +The function imwrite saves the image to the specified file. The image format is chosen based on the +filename extension (see cv::imread for the list of extensions). In general, only 8-bit +single-channel or 3-channel (with 'BGR' channel order) images +can be saved using this function, with these exceptions: + +- 16-bit unsigned (CV_16U) images can be saved in the case of PNG, JPEG 2000, and TIFF formats +- 32-bit float (CV_32F) images can be saved in PFM, TIFF, OpenEXR, and Radiance HDR formats; + 3-channel (CV_32FC3) TIFF images will be saved using the LogLuv high dynamic range encoding + (4 bytes per pixel) +- PNG images with an alpha channel can be saved using this function. To do this, create +8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels +should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535 (see the code sample below). + +If the format, depth or channel order is different, use +Mat::convertTo and cv::cvtColor to convert it before saving. Or, use the universal FileStorage I/O +functions to save the image to XML or YAML format. + +The sample below shows how to create a BGRA image and save it to a PNG file. It also demonstrates how to set custom +compression parameters: +@include snippets/imgcodecs_imwrite.cpp +@param filename Name of the file. +@param img Image to be saved. +@param params Format-specific parameters encoded as pairs (paramId_1, paramValue_1, paramId_2, paramValue_2, ... .) see cv::ImwriteFlags +*/ +CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, + const std::vector& params = std::vector()); + +/** @brief Reads an image from a buffer in memory. + +The function imdecode reads an image from the specified buffer in the memory. If the buffer is too short or +contains invalid data, the function returns an empty matrix ( Mat::data==NULL ). + +See cv::imread for the list of supported formats and flags description. + +@note In the case of color images, the decoded images will have the channels stored in **B G R** order. +@param buf Input array or vector of bytes. +@param flags The same flags as in cv::imread, see cv::ImreadModes. +*/ +CV_EXPORTS_W Mat imdecode( InputArray buf, int flags ); + +/** @overload +@param buf +@param flags +@param dst The optional output placeholder for the decoded matrix. It can save the image +reallocations when the function is called repeatedly for images of the same size. +*/ +CV_EXPORTS Mat imdecode( InputArray buf, int flags, Mat* dst); + +/** @brief Encodes an image into a memory buffer. + +The function imencode compresses the image and stores it in the memory buffer that is resized to fit the +result. See cv::imwrite for the list of supported formats and flags description. + +@param ext File extension that defines the output format. +@param img Image to be written. +@param buf Output buffer resized to fit the compressed image. +@param params Format-specific parameters. See cv::imwrite and cv::ImwriteFlags. +*/ +CV_EXPORTS_W bool imencode( const String& ext, InputArray img, + CV_OUT std::vector& buf, + const std::vector& params = std::vector()); + +/** @brief Returns true if the specified image can be decoded by OpenCV + +@param filename File name of the image +*/ +CV_EXPORTS_W bool haveImageReader( const String& filename ); + +/** @brief Returns true if an image with the specified filename can be encoded by OpenCV + + @param filename File name of the image + */ +CV_EXPORTS_W bool haveImageWriter( const String& filename ); + + +//! @} imgcodecs + +} // cv + +#endif //OPENCV_IMGCODECS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs.hpp b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs.hpp new file mode 100755 index 0000000..a3cd232 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/imgcodecs.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs_c.h b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs_c.h new file mode 100755 index 0000000..5c13e55 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/imgcodecs_c.h @@ -0,0 +1 @@ +#error "This header with legacy C API declarations has been removed from OpenCV. Legacy contants are available from legacy/constants_c.h file." diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/ios.h b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/ios.h new file mode 100755 index 0000000..a90c6d3 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/ios.h @@ -0,0 +1,57 @@ + +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#import +#import +#import +#import +#include "opencv2/core/core.hpp" + +//! @addtogroup imgcodecs_ios +//! @{ + +CV_EXPORTS UIImage* MatToUIImage(const cv::Mat& image); +CV_EXPORTS void UIImageToMat(const UIImage* image, + cv::Mat& m, bool alphaExist = false); + +//! @} diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/legacy/constants_c.h b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/legacy/constants_c.h new file mode 100755 index 0000000..de7be4f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgcodecs/legacy/constants_c.h @@ -0,0 +1,54 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_IMGCODECS_LEGACY_CONSTANTS_H +#define OPENCV_IMGCODECS_LEGACY_CONSTANTS_H + +/* duplicate of "ImreadModes" enumeration for better compatibility with OpenCV 3.x */ +enum +{ +/* 8bit, color or not */ + CV_LOAD_IMAGE_UNCHANGED =-1, +/* 8bit, gray */ + CV_LOAD_IMAGE_GRAYSCALE =0, +/* ?, color */ + CV_LOAD_IMAGE_COLOR =1, +/* any depth, ? */ + CV_LOAD_IMAGE_ANYDEPTH =2, +/* ?, any color */ + CV_LOAD_IMAGE_ANYCOLOR =4, +/* ?, no rotate */ + CV_LOAD_IMAGE_IGNORE_ORIENTATION =128 +}; + +/* duplicate of "ImwriteFlags" enumeration for better compatibility with OpenCV 3.x */ +enum +{ + CV_IMWRITE_JPEG_QUALITY =1, + CV_IMWRITE_JPEG_PROGRESSIVE =2, + CV_IMWRITE_JPEG_OPTIMIZE =3, + CV_IMWRITE_JPEG_RST_INTERVAL =4, + CV_IMWRITE_JPEG_LUMA_QUALITY =5, + CV_IMWRITE_JPEG_CHROMA_QUALITY =6, + CV_IMWRITE_PNG_COMPRESSION =16, + CV_IMWRITE_PNG_STRATEGY =17, + CV_IMWRITE_PNG_BILEVEL =18, + CV_IMWRITE_PNG_STRATEGY_DEFAULT =0, + CV_IMWRITE_PNG_STRATEGY_FILTERED =1, + CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY =2, + CV_IMWRITE_PNG_STRATEGY_RLE =3, + CV_IMWRITE_PNG_STRATEGY_FIXED =4, + CV_IMWRITE_PXM_BINARY =32, + CV_IMWRITE_EXR_TYPE = 48, + CV_IMWRITE_WEBP_QUALITY =64, + CV_IMWRITE_PAM_TUPLETYPE = 128, + CV_IMWRITE_PAM_FORMAT_NULL = 0, + CV_IMWRITE_PAM_FORMAT_BLACKANDWHITE = 1, + CV_IMWRITE_PAM_FORMAT_GRAYSCALE = 2, + CV_IMWRITE_PAM_FORMAT_GRAYSCALE_ALPHA = 3, + CV_IMWRITE_PAM_FORMAT_RGB = 4, + CV_IMWRITE_PAM_FORMAT_RGB_ALPHA = 5, +}; + +#endif // OPENCV_IMGCODECS_LEGACY_CONSTANTS_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgproc.hpp b/Prj-Win/3rd/opencv/include/opencv2/imgproc.hpp new file mode 100755 index 0000000..b2a7b17 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgproc.hpp @@ -0,0 +1,4758 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_IMGPROC_HPP +#define OPENCV_IMGPROC_HPP + +#include "opencv2/core.hpp" + +/** + @defgroup imgproc Image Processing + +This module includes image-processing functions. + + @{ + @defgroup imgproc_filter Image Filtering + +Functions and classes described in this section are used to perform various linear or non-linear +filtering operations on 2D images (represented as Mat's). It means that for each pixel location +\f$(x,y)\f$ in the source image (normally, rectangular), its 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 values, and so on. The computed response is +stored in the destination image at the same location \f$(x,y)\f$. It means that the output image +will be of the same size as the input image. Normally, the functions support 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 you want to smooth an image using a Gaussian \f$3 \times 3\f$ filter, then, when +processing the left-most pixels in each row, you need pixels to the left of them, that is, outside +of the image. You can let these pixels be the same as the left-most image pixels ("replicated +border" extrapolation method), or assume that all the non-existing pixels are zeros ("constant +border" extrapolation method), and so on. OpenCV enables you to specify the extrapolation method. +For details, see #BorderTypes + +@anchor filter_depths +### Depth combinations +Input depth (src.depth()) | Output depth (ddepth) +--------------------------|---------------------- +CV_8U | -1/CV_16S/CV_32F/CV_64F +CV_16U/CV_16S | -1/CV_32F/CV_64F +CV_32F | -1/CV_32F/CV_64F +CV_64F | -1/CV_64F + +@note when ddepth=-1, the output image will have the same depth as the source. + + @defgroup imgproc_transform Geometric Image Transformations + +The functions in this section perform various geometrical transformations of 2D images. 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 \f$(x, y)\f$ of the destination image, the +functions compute coordinates of the corresponding "donor" pixel in the source image and copy the +pixel value: + +\f[\texttt{dst} (x,y)= \texttt{src} (f_x(x,y), f_y(x,y))\f] + +In case when you specify the forward mapping \f$\left: \texttt{src} \rightarrow +\texttt{dst}\f$, the OpenCV functions first compute the corresponding inverse mapping +\f$\left: \texttt{dst} \rightarrow \texttt{src}\f$ and then use the above formula. + +The actual implementations of the geometrical transformations, from the most generic remap and to +the simplest and the fastest resize, need to solve two main problems with the above formula: + +- Extrapolation of non-existing pixels. Similarly to the filtering functions described in the +previous section, for some \f$(x,y)\f$, either one of \f$f_x(x,y)\f$, or \f$f_y(x,y)\f$, or both +of them may fall outside of the image. In this case, an extrapolation method needs to be used. +OpenCV provides the same selection of extrapolation methods as in the filtering functions. In +addition, it provides the method #BORDER_TRANSPARENT. This means that the corresponding pixels in +the destination image will not be modified at all. + +- Interpolation of pixel values. Usually \f$f_x(x,y)\f$ and \f$f_y(x,y)\f$ are floating-point +numbers. This means that \f$\left\f$ can be either an affine or perspective +transformation, or radial lens distortion correction, and so on. So, a pixel value 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 can be used. This is called a +nearest-neighbor interpolation. However, a better result can be achieved by using more +sophisticated [interpolation methods](http://en.wikipedia.org/wiki/Multivariate_interpolation) , +where a polynomial function is fit into some neighborhood of the computed pixel \f$(f_x(x,y), +f_y(x,y))\f$, and then the value of the polynomial at \f$(f_x(x,y), f_y(x,y))\f$ is taken as the +interpolated pixel value. In OpenCV, you can choose between several interpolation methods. See +resize for details. + +@note The geometrical transformations do not work with `CV_8S` or `CV_32S` images. + + @defgroup imgproc_misc Miscellaneous Image Transformations + @defgroup imgproc_draw Drawing Functions + +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 an RGB value (that may be constructed with the Scalar constructor ) +for color images and brightness for grayscale images. For color images, the channel ordering is +normally *Blue, Green, Red*. This is what imshow, imread, and imwrite expect. So, if you form a +color using the Scalar constructor, it should look like: + +\f[\texttt{Scalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component])\f] + +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 used color space. The whole image can be converted from BGR to RGB or to a different color +space using 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. This means +that 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 +\f$\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})\f$ . This feature is +especially effective when rendering antialiased shapes. + +@note The functions do not support alpha-transparency when the target image is 4-channel. In this +case, 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. + + @defgroup imgproc_color_conversions Color Space Conversions + @defgroup imgproc_colormap ColorMaps in OpenCV + +The human perception isn't built for observing fine changes in grayscale images. Human eyes are more +sensitive to observing changes between colors, so you often need to recolor your grayscale images to +get a clue about them. OpenCV now comes with various colormaps to enhance the visualization in your +computer vision application. + +In OpenCV you only need applyColorMap to apply a colormap on a given image. The following sample +code reads the path to an image from command line, applies a Jet colormap on it and shows the +result: + +@include snippets/imgproc_applyColorMap.cpp + +@see #ColormapTypes + + @defgroup imgproc_subdiv2d Planar Subdivision + +The Subdiv2D class described in this section is used to perform various planar subdivision on +a set of 2D points (represented as vector of Point2f). OpenCV subdivides a plane into triangles +using the Delaunay's algorithm, which corresponds to the dual graph of the Voronoi diagram. +In the figure below, the Delaunay's triangulation is marked with black lines and the Voronoi +diagram with red lines. + +![Delaunay triangulation (black) and Voronoi (red)](pics/delaunay_voronoi.png) + +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. + + @defgroup imgproc_hist Histograms + @defgroup imgproc_shape Structural Analysis and Shape Descriptors + @defgroup imgproc_motion Motion Analysis and Object Tracking + @defgroup imgproc_feature Feature Detection + @defgroup imgproc_object Object Detection + @defgroup imgproc_c C API + @defgroup imgproc_hal Hardware Acceleration Layer + @{ + @defgroup imgproc_hal_functions Functions + @defgroup imgproc_hal_interface Interface + @} + @} +*/ + +namespace cv +{ + +/** @addtogroup imgproc +@{ +*/ + +//! @addtogroup imgproc_filter +//! @{ + +enum SpecialFilter { + FILTER_SCHARR = -1 +}; + +//! type of morphological operation +enum MorphTypes{ + MORPH_ERODE = 0, //!< see #erode + MORPH_DILATE = 1, //!< see #dilate + MORPH_OPEN = 2, //!< an opening operation + //!< \f[\texttt{dst} = \mathrm{open} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \mathrm{erode} ( \texttt{src} , \texttt{element} ))\f] + MORPH_CLOSE = 3, //!< a closing operation + //!< \f[\texttt{dst} = \mathrm{close} ( \texttt{src} , \texttt{element} )= \mathrm{erode} ( \mathrm{dilate} ( \texttt{src} , \texttt{element} ))\f] + MORPH_GRADIENT = 4, //!< a morphological gradient + //!< \f[\texttt{dst} = \mathrm{morph\_grad} ( \texttt{src} , \texttt{element} )= \mathrm{dilate} ( \texttt{src} , \texttt{element} )- \mathrm{erode} ( \texttt{src} , \texttt{element} )\f] + MORPH_TOPHAT = 5, //!< "top hat" + //!< \f[\texttt{dst} = \mathrm{tophat} ( \texttt{src} , \texttt{element} )= \texttt{src} - \mathrm{open} ( \texttt{src} , \texttt{element} )\f] + MORPH_BLACKHAT = 6, //!< "black hat" + //!< \f[\texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src}\f] + MORPH_HITMISS = 7 //!< "hit or miss" + //!< .- Only supported for CV_8UC1 binary images. A tutorial can be found in the documentation +}; + +//! shape of the structuring element +enum MorphShapes { + MORPH_RECT = 0, //!< a rectangular structuring element: \f[E_{ij}=1\f] + MORPH_CROSS = 1, //!< a cross-shaped structuring element: + //!< \f[E_{ij} = \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}\f] + MORPH_ELLIPSE = 2 //!< an elliptic structuring element, that is, a filled ellipse inscribed + //!< into the rectangle Rect(0, 0, esize.width, 0.esize.height) +}; + +//! @} imgproc_filter + +//! @addtogroup imgproc_transform +//! @{ + +//! interpolation algorithm +enum InterpolationFlags{ + /** nearest neighbor interpolation */ + INTER_NEAREST = 0, + /** bilinear interpolation */ + INTER_LINEAR = 1, + /** bicubic interpolation */ + INTER_CUBIC = 2, + /** resampling using pixel area relation. It may be a preferred method for image decimation, as + it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST + method. */ + INTER_AREA = 3, + /** Lanczos interpolation over 8x8 neighborhood */ + INTER_LANCZOS4 = 4, + /** Bit exact bilinear interpolation */ + INTER_LINEAR_EXACT = 5, + /** mask for interpolation codes */ + INTER_MAX = 7, + /** flag, fills all of the destination image pixels. If some of them correspond to outliers in the + source image, they are set to zero */ + WARP_FILL_OUTLIERS = 8, + /** flag, inverse transformation + + For example, #linearPolar or #logPolar transforms: + - flag is __not__ set: \f$dst( \rho , \phi ) = src(x,y)\f$ + - flag is set: \f$dst(x,y) = src( \rho , \phi )\f$ + */ + WARP_INVERSE_MAP = 16 +}; + +/** \brief Specify the polar mapping mode +@sa warpPolar +*/ +enum WarpPolarMode +{ + WARP_POLAR_LINEAR = 0, ///< Remaps an image to/from polar space. + WARP_POLAR_LOG = 256 ///< Remaps an image to/from semilog-polar space. +}; + +enum InterpolationMasks { + INTER_BITS = 5, + INTER_BITS2 = INTER_BITS * 2, + INTER_TAB_SIZE = 1 << INTER_BITS, + INTER_TAB_SIZE2 = INTER_TAB_SIZE * INTER_TAB_SIZE + }; + +//! @} imgproc_transform + +//! @addtogroup imgproc_misc +//! @{ + +//! Distance types for Distance Transform and M-estimators +//! @see distanceTransform, fitLine +enum DistanceTypes { + DIST_USER = -1, //!< User defined distance + DIST_L1 = 1, //!< distance = |x1-x2| + |y1-y2| + DIST_L2 = 2, //!< the simple euclidean distance + DIST_C = 3, //!< distance = max(|x1-x2|,|y1-y2|) + DIST_L12 = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) + DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 + DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 + DIST_HUBER = 7 //!< distance = |x| \texttt{thresh}\)}{0}{otherwise}\f] + THRESH_BINARY_INV = 1, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxval}}{otherwise}\f] + THRESH_TRUNC = 2, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] + THRESH_TOZERO = 3, //!< \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] + THRESH_TOZERO_INV = 4, //!< \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] + THRESH_MASK = 7, + THRESH_OTSU = 8, //!< flag, use Otsu algorithm to choose the optimal threshold value + THRESH_TRIANGLE = 16 //!< flag, use Triangle algorithm to choose the optimal threshold value +}; + +//! adaptive threshold algorithm +//! @see adaptiveThreshold +enum AdaptiveThresholdTypes { + /** the threshold value \f$T(x,y)\f$ is a mean of the \f$\texttt{blockSize} \times + \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ minus C */ + ADAPTIVE_THRESH_MEAN_C = 0, + /** the threshold value \f$T(x, y)\f$ is a weighted sum (cross-correlation with a Gaussian + window) of the \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood of \f$(x, y)\f$ + minus C . The default sigma (standard deviation) is used for the specified blockSize . See + #getGaussianKernel*/ + ADAPTIVE_THRESH_GAUSSIAN_C = 1 +}; + +//! class of the pixel in GrabCut algorithm +enum GrabCutClasses { + GC_BGD = 0, //!< an obvious background pixels + GC_FGD = 1, //!< an obvious foreground (object) pixel + GC_PR_BGD = 2, //!< a possible background pixel + GC_PR_FGD = 3 //!< a possible foreground pixel +}; + +//! GrabCut algorithm flags +enum GrabCutModes { + /** The function initializes the state and the mask using the provided rectangle. After that it + runs iterCount iterations of the algorithm. */ + GC_INIT_WITH_RECT = 0, + /** The function initializes the state using the provided mask. Note that GC_INIT_WITH_RECT + and GC_INIT_WITH_MASK can be combined. Then, all the pixels outside of the ROI are + automatically initialized with GC_BGD .*/ + GC_INIT_WITH_MASK = 1, + /** The value means that the algorithm should just resume. */ + GC_EVAL = 2, + /** The value means that the algorithm should just run the grabCut algorithm (a single iteration) with the fixed model */ + GC_EVAL_FREEZE_MODEL = 3 +}; + +//! distanceTransform algorithm flags +enum DistanceTransformLabelTypes { + /** each connected component of zeros in src (as well as all the non-zero pixels closest to the + connected component) will be assigned the same label */ + DIST_LABEL_CCOMP = 0, + /** each zero pixel (and all the non-zero pixels closest to it) gets its own label. */ + DIST_LABEL_PIXEL = 1 +}; + +//! floodfill algorithm flags +enum FloodFillFlags { + /** If set, the difference between the current pixel and seed pixel is considered. Otherwise, + the difference between neighbor pixels is considered (that is, the range is floating). */ + FLOODFILL_FIXED_RANGE = 1 << 16, + /** If set, the function does not change the image ( newVal is ignored), and only fills the + mask with the value specified in bits 8-16 of flags as described above. This option only make + sense in function variants that have the mask parameter. */ + FLOODFILL_MASK_ONLY = 1 << 17 +}; + +//! @} imgproc_misc + +//! @addtogroup imgproc_shape +//! @{ + +//! connected components algorithm output formats +enum ConnectedComponentsTypes { + CC_STAT_LEFT = 0, //!< The leftmost (x) coordinate which is the inclusive start of the bounding + //!< box in the horizontal direction. + CC_STAT_TOP = 1, //!< The topmost (y) coordinate which is the inclusive start of the bounding + //!< box in the vertical direction. + CC_STAT_WIDTH = 2, //!< The horizontal size of the bounding box + CC_STAT_HEIGHT = 3, //!< The vertical size of the bounding box + CC_STAT_AREA = 4, //!< The total area (in pixels) of the connected component + CC_STAT_MAX = 5 +}; + +//! connected components algorithm +enum ConnectedComponentsAlgorithmsTypes { + CCL_WU = 0, //!< SAUF algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity + CCL_DEFAULT = -1, //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity + CCL_GRANA = 1 //!< BBDT algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity +}; + +//! mode of the contour retrieval algorithm +enum RetrievalModes { + /** retrieves only the extreme outer contours. It sets `hierarchy[i][2]=hierarchy[i][3]=-1` for + all the contours. */ + RETR_EXTERNAL = 0, + /** retrieves all of the contours without establishing any hierarchical relationships. */ + RETR_LIST = 1, + /** retrieves all of the contours and organizes them into a two-level hierarchy. At the top + level, there are external boundaries of the components. At the second level, there are + boundaries of the holes. If there is another contour inside a hole of a connected component, it + is still put at the top level. */ + RETR_CCOMP = 2, + /** retrieves all of the contours and reconstructs a full hierarchy of nested contours.*/ + RETR_TREE = 3, + RETR_FLOODFILL = 4 //!< +}; + +//! the contour approximation algorithm +enum ContourApproximationModes { + /** stores absolutely all the contour points. That is, any 2 subsequent points (x1,y1) and + (x2,y2) of the contour will be either horizontal, vertical or diagonal neighbors, that is, + max(abs(x1-x2),abs(y2-y1))==1. */ + CHAIN_APPROX_NONE = 1, + /** compresses horizontal, vertical, and diagonal segments and leaves only their end points. + For example, an up-right rectangular contour is encoded with 4 points. */ + CHAIN_APPROX_SIMPLE = 2, + /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */ + CHAIN_APPROX_TC89_L1 = 3, + /** applies one of the flavors of the Teh-Chin chain approximation algorithm @cite TehChin89 */ + CHAIN_APPROX_TC89_KCOS = 4 +}; + +/** @brief Shape matching methods + +\f$A\f$ denotes object1,\f$B\f$ denotes object2 + +\f$\begin{array}{l} m^A_i = \mathrm{sign} (h^A_i) \cdot \log{h^A_i} \\ m^B_i = \mathrm{sign} (h^B_i) \cdot \log{h^B_i} \end{array}\f$ + +and \f$h^A_i, h^B_i\f$ are the Hu moments of \f$A\f$ and \f$B\f$ , respectively. +*/ +enum ShapeMatchModes { + CONTOURS_MATCH_I1 =1, //!< \f[I_1(A,B) = \sum _{i=1...7} \left | \frac{1}{m^A_i} - \frac{1}{m^B_i} \right |\f] + CONTOURS_MATCH_I2 =2, //!< \f[I_2(A,B) = \sum _{i=1...7} \left | m^A_i - m^B_i \right |\f] + CONTOURS_MATCH_I3 =3 //!< \f[I_3(A,B) = \max _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| }\f] +}; + +//! @} imgproc_shape + +//! @addtogroup imgproc_feature +//! @{ + +//! Variants of a Hough transform +enum HoughModes { + + /** classical or standard Hough transform. Every line is represented by two floating-point + numbers \f$(\rho, \theta)\f$ , where \f$\rho\f$ is a distance between (0,0) point and the line, + and \f$\theta\f$ 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 */ + HOUGH_STANDARD = 0, + /** probabilistic Hough transform (more efficient in case if the 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 the CV_32SC4 type. */ + HOUGH_PROBABILISTIC = 1, + /** multi-scale variant of the classical Hough transform. The lines are encoded the same way as + HOUGH_STANDARD. */ + HOUGH_MULTI_SCALE = 2, + HOUGH_GRADIENT = 3 //!< basically *21HT*, described in @cite Yuen90 +}; + +//! Variants of Line Segment %Detector +enum LineSegmentDetectorModes { + LSD_REFINE_NONE = 0, //!< No refinement applied + LSD_REFINE_STD = 1, //!< Standard refinement is applied. E.g. breaking arches into smaller straighter line approximations. + LSD_REFINE_ADV = 2 //!< Advanced refinement. Number of false alarms is calculated, lines are + //!< refined through increase of precision, decrement in size, etc. +}; + +//! @} imgproc_feature + +/** Histogram comparison methods + @ingroup imgproc_hist +*/ +enum HistCompMethods { + /** Correlation + \f[d(H_1,H_2) = \frac{\sum_I (H_1(I) - \bar{H_1}) (H_2(I) - \bar{H_2})}{\sqrt{\sum_I(H_1(I) - \bar{H_1})^2 \sum_I(H_2(I) - \bar{H_2})^2}}\f] + where + \f[\bar{H_k} = \frac{1}{N} \sum _J H_k(J)\f] + and \f$N\f$ is a total number of histogram bins. */ + HISTCMP_CORREL = 0, + /** Chi-Square + \f[d(H_1,H_2) = \sum _I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)}\f] */ + HISTCMP_CHISQR = 1, + /** Intersection + \f[d(H_1,H_2) = \sum _I \min (H_1(I), H_2(I))\f] */ + HISTCMP_INTERSECT = 2, + /** Bhattacharyya distance + (In fact, OpenCV computes Hellinger distance, which is related to Bhattacharyya coefficient.) + \f[d(H_1,H_2) = \sqrt{1 - \frac{1}{\sqrt{\bar{H_1} \bar{H_2} N^2}} \sum_I \sqrt{H_1(I) \cdot H_2(I)}}\f] */ + HISTCMP_BHATTACHARYYA = 3, + HISTCMP_HELLINGER = HISTCMP_BHATTACHARYYA, //!< Synonym for HISTCMP_BHATTACHARYYA + /** Alternative Chi-Square + \f[d(H_1,H_2) = 2 * \sum _I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)+H_2(I)}\f] + This alternative formula is regularly used for texture comparison. See e.g. @cite Puzicha1997 */ + HISTCMP_CHISQR_ALT = 4, + /** Kullback-Leibler divergence + \f[d(H_1,H_2) = \sum _I H_1(I) \log \left(\frac{H_1(I)}{H_2(I)}\right)\f] */ + HISTCMP_KL_DIV = 5 +}; + +/** the color conversion codes +@see @ref imgproc_color_conversions +@ingroup imgproc_color_conversions + */ +enum ColorConversionCodes { + COLOR_BGR2BGRA = 0, //!< add alpha channel to RGB or BGR image + COLOR_RGB2RGBA = COLOR_BGR2BGRA, + + COLOR_BGRA2BGR = 1, //!< remove alpha channel from RGB or BGR image + COLOR_RGBA2RGB = COLOR_BGRA2BGR, + + COLOR_BGR2RGBA = 2, //!< convert between RGB and BGR color spaces (with or without alpha channel) + COLOR_RGB2BGRA = COLOR_BGR2RGBA, + + COLOR_RGBA2BGR = 3, + COLOR_BGRA2RGB = COLOR_RGBA2BGR, + + COLOR_BGR2RGB = 4, + COLOR_RGB2BGR = COLOR_BGR2RGB, + + COLOR_BGRA2RGBA = 5, + COLOR_RGBA2BGRA = COLOR_BGRA2RGBA, + + COLOR_BGR2GRAY = 6, //!< convert between RGB/BGR and grayscale, @ref color_convert_rgb_gray "color conversions" + COLOR_RGB2GRAY = 7, + COLOR_GRAY2BGR = 8, + COLOR_GRAY2RGB = COLOR_GRAY2BGR, + COLOR_GRAY2BGRA = 9, + COLOR_GRAY2RGBA = COLOR_GRAY2BGRA, + COLOR_BGRA2GRAY = 10, + COLOR_RGBA2GRAY = 11, + + COLOR_BGR2BGR565 = 12, //!< convert between RGB/BGR and BGR565 (16-bit images) + COLOR_RGB2BGR565 = 13, + COLOR_BGR5652BGR = 14, + COLOR_BGR5652RGB = 15, + COLOR_BGRA2BGR565 = 16, + COLOR_RGBA2BGR565 = 17, + COLOR_BGR5652BGRA = 18, + COLOR_BGR5652RGBA = 19, + + COLOR_GRAY2BGR565 = 20, //!< convert between grayscale to BGR565 (16-bit images) + COLOR_BGR5652GRAY = 21, + + COLOR_BGR2BGR555 = 22, //!< convert between RGB/BGR and BGR555 (16-bit images) + COLOR_RGB2BGR555 = 23, + COLOR_BGR5552BGR = 24, + COLOR_BGR5552RGB = 25, + COLOR_BGRA2BGR555 = 26, + COLOR_RGBA2BGR555 = 27, + COLOR_BGR5552BGRA = 28, + COLOR_BGR5552RGBA = 29, + + COLOR_GRAY2BGR555 = 30, //!< convert between grayscale and BGR555 (16-bit images) + COLOR_BGR5552GRAY = 31, + + COLOR_BGR2XYZ = 32, //!< convert RGB/BGR to CIE XYZ, @ref color_convert_rgb_xyz "color conversions" + COLOR_RGB2XYZ = 33, + COLOR_XYZ2BGR = 34, + COLOR_XYZ2RGB = 35, + + COLOR_BGR2YCrCb = 36, //!< convert RGB/BGR to luma-chroma (aka YCC), @ref color_convert_rgb_ycrcb "color conversions" + COLOR_RGB2YCrCb = 37, + COLOR_YCrCb2BGR = 38, + COLOR_YCrCb2RGB = 39, + + COLOR_BGR2HSV = 40, //!< convert RGB/BGR to HSV (hue saturation value), @ref color_convert_rgb_hsv "color conversions" + COLOR_RGB2HSV = 41, + + COLOR_BGR2Lab = 44, //!< convert RGB/BGR to CIE Lab, @ref color_convert_rgb_lab "color conversions" + COLOR_RGB2Lab = 45, + + COLOR_BGR2Luv = 50, //!< convert RGB/BGR to CIE Luv, @ref color_convert_rgb_luv "color conversions" + COLOR_RGB2Luv = 51, + COLOR_BGR2HLS = 52, //!< convert RGB/BGR to HLS (hue lightness saturation), @ref color_convert_rgb_hls "color conversions" + COLOR_RGB2HLS = 53, + + COLOR_HSV2BGR = 54, //!< backward conversions to RGB/BGR + COLOR_HSV2RGB = 55, + + COLOR_Lab2BGR = 56, + COLOR_Lab2RGB = 57, + COLOR_Luv2BGR = 58, + COLOR_Luv2RGB = 59, + COLOR_HLS2BGR = 60, + COLOR_HLS2RGB = 61, + + COLOR_BGR2HSV_FULL = 66, + COLOR_RGB2HSV_FULL = 67, + COLOR_BGR2HLS_FULL = 68, + COLOR_RGB2HLS_FULL = 69, + + COLOR_HSV2BGR_FULL = 70, + COLOR_HSV2RGB_FULL = 71, + COLOR_HLS2BGR_FULL = 72, + COLOR_HLS2RGB_FULL = 73, + + COLOR_LBGR2Lab = 74, + COLOR_LRGB2Lab = 75, + COLOR_LBGR2Luv = 76, + COLOR_LRGB2Luv = 77, + + COLOR_Lab2LBGR = 78, + COLOR_Lab2LRGB = 79, + COLOR_Luv2LBGR = 80, + COLOR_Luv2LRGB = 81, + + COLOR_BGR2YUV = 82, //!< convert between RGB/BGR and YUV + COLOR_RGB2YUV = 83, + COLOR_YUV2BGR = 84, + COLOR_YUV2RGB = 85, + + //! YUV 4:2:0 family to RGB + COLOR_YUV2RGB_NV12 = 90, + COLOR_YUV2BGR_NV12 = 91, + COLOR_YUV2RGB_NV21 = 92, + COLOR_YUV2BGR_NV21 = 93, + COLOR_YUV420sp2RGB = COLOR_YUV2RGB_NV21, + COLOR_YUV420sp2BGR = COLOR_YUV2BGR_NV21, + + COLOR_YUV2RGBA_NV12 = 94, + COLOR_YUV2BGRA_NV12 = 95, + COLOR_YUV2RGBA_NV21 = 96, + COLOR_YUV2BGRA_NV21 = 97, + COLOR_YUV420sp2RGBA = COLOR_YUV2RGBA_NV21, + COLOR_YUV420sp2BGRA = COLOR_YUV2BGRA_NV21, + + COLOR_YUV2RGB_YV12 = 98, + COLOR_YUV2BGR_YV12 = 99, + COLOR_YUV2RGB_IYUV = 100, + COLOR_YUV2BGR_IYUV = 101, + COLOR_YUV2RGB_I420 = COLOR_YUV2RGB_IYUV, + COLOR_YUV2BGR_I420 = COLOR_YUV2BGR_IYUV, + COLOR_YUV420p2RGB = COLOR_YUV2RGB_YV12, + COLOR_YUV420p2BGR = COLOR_YUV2BGR_YV12, + + COLOR_YUV2RGBA_YV12 = 102, + COLOR_YUV2BGRA_YV12 = 103, + COLOR_YUV2RGBA_IYUV = 104, + COLOR_YUV2BGRA_IYUV = 105, + COLOR_YUV2RGBA_I420 = COLOR_YUV2RGBA_IYUV, + COLOR_YUV2BGRA_I420 = COLOR_YUV2BGRA_IYUV, + COLOR_YUV420p2RGBA = COLOR_YUV2RGBA_YV12, + COLOR_YUV420p2BGRA = COLOR_YUV2BGRA_YV12, + + COLOR_YUV2GRAY_420 = 106, + COLOR_YUV2GRAY_NV21 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_NV12 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_YV12 = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_IYUV = COLOR_YUV2GRAY_420, + COLOR_YUV2GRAY_I420 = COLOR_YUV2GRAY_420, + COLOR_YUV420sp2GRAY = COLOR_YUV2GRAY_420, + COLOR_YUV420p2GRAY = COLOR_YUV2GRAY_420, + + //! YUV 4:2:2 family to RGB + COLOR_YUV2RGB_UYVY = 107, + COLOR_YUV2BGR_UYVY = 108, + //COLOR_YUV2RGB_VYUY = 109, + //COLOR_YUV2BGR_VYUY = 110, + COLOR_YUV2RGB_Y422 = COLOR_YUV2RGB_UYVY, + COLOR_YUV2BGR_Y422 = COLOR_YUV2BGR_UYVY, + COLOR_YUV2RGB_UYNV = COLOR_YUV2RGB_UYVY, + COLOR_YUV2BGR_UYNV = COLOR_YUV2BGR_UYVY, + + COLOR_YUV2RGBA_UYVY = 111, + COLOR_YUV2BGRA_UYVY = 112, + //COLOR_YUV2RGBA_VYUY = 113, + //COLOR_YUV2BGRA_VYUY = 114, + COLOR_YUV2RGBA_Y422 = COLOR_YUV2RGBA_UYVY, + COLOR_YUV2BGRA_Y422 = COLOR_YUV2BGRA_UYVY, + COLOR_YUV2RGBA_UYNV = COLOR_YUV2RGBA_UYVY, + COLOR_YUV2BGRA_UYNV = COLOR_YUV2BGRA_UYVY, + + COLOR_YUV2RGB_YUY2 = 115, + COLOR_YUV2BGR_YUY2 = 116, + COLOR_YUV2RGB_YVYU = 117, + COLOR_YUV2BGR_YVYU = 118, + COLOR_YUV2RGB_YUYV = COLOR_YUV2RGB_YUY2, + COLOR_YUV2BGR_YUYV = COLOR_YUV2BGR_YUY2, + COLOR_YUV2RGB_YUNV = COLOR_YUV2RGB_YUY2, + COLOR_YUV2BGR_YUNV = COLOR_YUV2BGR_YUY2, + + COLOR_YUV2RGBA_YUY2 = 119, + COLOR_YUV2BGRA_YUY2 = 120, + COLOR_YUV2RGBA_YVYU = 121, + COLOR_YUV2BGRA_YVYU = 122, + COLOR_YUV2RGBA_YUYV = COLOR_YUV2RGBA_YUY2, + COLOR_YUV2BGRA_YUYV = COLOR_YUV2BGRA_YUY2, + COLOR_YUV2RGBA_YUNV = COLOR_YUV2RGBA_YUY2, + COLOR_YUV2BGRA_YUNV = COLOR_YUV2BGRA_YUY2, + + COLOR_YUV2GRAY_UYVY = 123, + COLOR_YUV2GRAY_YUY2 = 124, + //CV_YUV2GRAY_VYUY = CV_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_Y422 = COLOR_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_UYNV = COLOR_YUV2GRAY_UYVY, + COLOR_YUV2GRAY_YVYU = COLOR_YUV2GRAY_YUY2, + COLOR_YUV2GRAY_YUYV = COLOR_YUV2GRAY_YUY2, + COLOR_YUV2GRAY_YUNV = COLOR_YUV2GRAY_YUY2, + + //! alpha premultiplication + COLOR_RGBA2mRGBA = 125, + COLOR_mRGBA2RGBA = 126, + + //! RGB to YUV 4:2:0 family + COLOR_RGB2YUV_I420 = 127, + COLOR_BGR2YUV_I420 = 128, + COLOR_RGB2YUV_IYUV = COLOR_RGB2YUV_I420, + COLOR_BGR2YUV_IYUV = COLOR_BGR2YUV_I420, + + COLOR_RGBA2YUV_I420 = 129, + COLOR_BGRA2YUV_I420 = 130, + COLOR_RGBA2YUV_IYUV = COLOR_RGBA2YUV_I420, + COLOR_BGRA2YUV_IYUV = COLOR_BGRA2YUV_I420, + COLOR_RGB2YUV_YV12 = 131, + COLOR_BGR2YUV_YV12 = 132, + COLOR_RGBA2YUV_YV12 = 133, + COLOR_BGRA2YUV_YV12 = 134, + + //! Demosaicing + COLOR_BayerBG2BGR = 46, + COLOR_BayerGB2BGR = 47, + COLOR_BayerRG2BGR = 48, + COLOR_BayerGR2BGR = 49, + + COLOR_BayerBG2RGB = COLOR_BayerRG2BGR, + COLOR_BayerGB2RGB = COLOR_BayerGR2BGR, + COLOR_BayerRG2RGB = COLOR_BayerBG2BGR, + COLOR_BayerGR2RGB = COLOR_BayerGB2BGR, + + COLOR_BayerBG2GRAY = 86, + COLOR_BayerGB2GRAY = 87, + COLOR_BayerRG2GRAY = 88, + COLOR_BayerGR2GRAY = 89, + + //! Demosaicing using Variable Number of Gradients + COLOR_BayerBG2BGR_VNG = 62, + COLOR_BayerGB2BGR_VNG = 63, + COLOR_BayerRG2BGR_VNG = 64, + COLOR_BayerGR2BGR_VNG = 65, + + COLOR_BayerBG2RGB_VNG = COLOR_BayerRG2BGR_VNG, + COLOR_BayerGB2RGB_VNG = COLOR_BayerGR2BGR_VNG, + COLOR_BayerRG2RGB_VNG = COLOR_BayerBG2BGR_VNG, + COLOR_BayerGR2RGB_VNG = COLOR_BayerGB2BGR_VNG, + + //! Edge-Aware Demosaicing + COLOR_BayerBG2BGR_EA = 135, + COLOR_BayerGB2BGR_EA = 136, + COLOR_BayerRG2BGR_EA = 137, + COLOR_BayerGR2BGR_EA = 138, + + COLOR_BayerBG2RGB_EA = COLOR_BayerRG2BGR_EA, + COLOR_BayerGB2RGB_EA = COLOR_BayerGR2BGR_EA, + COLOR_BayerRG2RGB_EA = COLOR_BayerBG2BGR_EA, + COLOR_BayerGR2RGB_EA = COLOR_BayerGB2BGR_EA, + + //! Demosaicing with alpha channel + COLOR_BayerBG2BGRA = 139, + COLOR_BayerGB2BGRA = 140, + COLOR_BayerRG2BGRA = 141, + COLOR_BayerGR2BGRA = 142, + + COLOR_BayerBG2RGBA = COLOR_BayerRG2BGRA, + COLOR_BayerGB2RGBA = COLOR_BayerGR2BGRA, + COLOR_BayerRG2RGBA = COLOR_BayerBG2BGRA, + COLOR_BayerGR2RGBA = COLOR_BayerGB2BGRA, + + COLOR_COLORCVT_MAX = 143 +}; + +//! @addtogroup imgproc_shape +//! @{ + +//! types of intersection between rectangles +enum RectanglesIntersectTypes { + INTERSECT_NONE = 0, //!< No intersection + INTERSECT_PARTIAL = 1, //!< There is a partial intersection + INTERSECT_FULL = 2 //!< One of the rectangle is fully enclosed in the other +}; + +/** types of line +@ingroup imgproc_draw +*/ +enum LineTypes { + FILLED = -1, + LINE_4 = 4, //!< 4-connected line + LINE_8 = 8, //!< 8-connected line + LINE_AA = 16 //!< antialiased line +}; + +/** Only a subset of Hershey fonts are supported +@ingroup imgproc_draw +*/ +enum HersheyFonts { + FONT_HERSHEY_SIMPLEX = 0, //!< normal size sans-serif font + FONT_HERSHEY_PLAIN = 1, //!< small size sans-serif font + FONT_HERSHEY_DUPLEX = 2, //!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX) + FONT_HERSHEY_COMPLEX = 3, //!< normal size serif font + FONT_HERSHEY_TRIPLEX = 4, //!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX) + FONT_HERSHEY_COMPLEX_SMALL = 5, //!< smaller version of FONT_HERSHEY_COMPLEX + FONT_HERSHEY_SCRIPT_SIMPLEX = 6, //!< hand-writing style font + FONT_HERSHEY_SCRIPT_COMPLEX = 7, //!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX + FONT_ITALIC = 16 //!< flag for italic font +}; + +/** Possible set of marker types used for the cv::drawMarker function +@ingroup imgproc_draw +*/ +enum MarkerTypes +{ + MARKER_CROSS = 0, //!< A crosshair marker shape + MARKER_TILTED_CROSS = 1, //!< A 45 degree tilted crosshair marker shape + MARKER_STAR = 2, //!< A star marker shape, combination of cross and tilted cross + MARKER_DIAMOND = 3, //!< A diamond marker shape + MARKER_SQUARE = 4, //!< A square marker shape + MARKER_TRIANGLE_UP = 5, //!< An upwards pointing triangle marker shape + MARKER_TRIANGLE_DOWN = 6 //!< A downwards pointing triangle marker shape +}; + +/** @brief finds arbitrary template in the grayscale image using Generalized Hough Transform +*/ +class CV_EXPORTS_W GeneralizedHough : public Algorithm +{ +public: + //! set template to search + CV_WRAP virtual void setTemplate(InputArray templ, Point templCenter = Point(-1, -1)) = 0; + CV_WRAP virtual void setTemplate(InputArray edges, InputArray dx, InputArray dy, Point templCenter = Point(-1, -1)) = 0; + + //! find template on image + CV_WRAP virtual void detect(InputArray image, OutputArray positions, OutputArray votes = noArray()) = 0; + CV_WRAP virtual void detect(InputArray edges, InputArray dx, InputArray dy, OutputArray positions, OutputArray votes = noArray()) = 0; + + //! Canny low threshold. + CV_WRAP virtual void setCannyLowThresh(int cannyLowThresh) = 0; + CV_WRAP virtual int getCannyLowThresh() const = 0; + + //! Canny high threshold. + CV_WRAP virtual void setCannyHighThresh(int cannyHighThresh) = 0; + CV_WRAP virtual int getCannyHighThresh() const = 0; + + //! Minimum distance between the centers of the detected objects. + CV_WRAP virtual void setMinDist(double minDist) = 0; + CV_WRAP virtual double getMinDist() const = 0; + + //! Inverse ratio of the accumulator resolution to the image resolution. + CV_WRAP virtual void setDp(double dp) = 0; + CV_WRAP virtual double getDp() const = 0; + + //! Maximal size of inner buffers. + CV_WRAP virtual void setMaxBufferSize(int maxBufferSize) = 0; + CV_WRAP virtual int getMaxBufferSize() const = 0; +}; + +/** @brief finds arbitrary template in the grayscale image using Generalized Hough Transform + +Detects position only without translation and rotation @cite Ballard1981 . +*/ +class CV_EXPORTS_W GeneralizedHoughBallard : public GeneralizedHough +{ +public: + //! R-Table levels. + CV_WRAP virtual void setLevels(int levels) = 0; + CV_WRAP virtual int getLevels() const = 0; + + //! The accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected. + CV_WRAP virtual void setVotesThreshold(int votesThreshold) = 0; + CV_WRAP virtual int getVotesThreshold() const = 0; +}; + +/** @brief finds arbitrary template in the grayscale image using Generalized Hough Transform + +Detects position, translation and rotation @cite Guil1999 . +*/ +class CV_EXPORTS_W GeneralizedHoughGuil : public GeneralizedHough +{ +public: + //! Angle difference in degrees between two points in feature. + CV_WRAP virtual void setXi(double xi) = 0; + CV_WRAP virtual double getXi() const = 0; + + //! Feature table levels. + CV_WRAP virtual void setLevels(int levels) = 0; + CV_WRAP virtual int getLevels() const = 0; + + //! Maximal difference between angles that treated as equal. + CV_WRAP virtual void setAngleEpsilon(double angleEpsilon) = 0; + CV_WRAP virtual double getAngleEpsilon() const = 0; + + //! Minimal rotation angle to detect in degrees. + CV_WRAP virtual void setMinAngle(double minAngle) = 0; + CV_WRAP virtual double getMinAngle() const = 0; + + //! Maximal rotation angle to detect in degrees. + CV_WRAP virtual void setMaxAngle(double maxAngle) = 0; + CV_WRAP virtual double getMaxAngle() const = 0; + + //! Angle step in degrees. + CV_WRAP virtual void setAngleStep(double angleStep) = 0; + CV_WRAP virtual double getAngleStep() const = 0; + + //! Angle votes threshold. + CV_WRAP virtual void setAngleThresh(int angleThresh) = 0; + CV_WRAP virtual int getAngleThresh() const = 0; + + //! Minimal scale to detect. + CV_WRAP virtual void setMinScale(double minScale) = 0; + CV_WRAP virtual double getMinScale() const = 0; + + //! Maximal scale to detect. + CV_WRAP virtual void setMaxScale(double maxScale) = 0; + CV_WRAP virtual double getMaxScale() const = 0; + + //! Scale step. + CV_WRAP virtual void setScaleStep(double scaleStep) = 0; + CV_WRAP virtual double getScaleStep() const = 0; + + //! Scale votes threshold. + CV_WRAP virtual void setScaleThresh(int scaleThresh) = 0; + CV_WRAP virtual int getScaleThresh() const = 0; + + //! Position votes threshold. + CV_WRAP virtual void setPosThresh(int posThresh) = 0; + CV_WRAP virtual int getPosThresh() const = 0; +}; + +//! @} imgproc_shape + +//! @addtogroup imgproc_hist +//! @{ + +/** @brief Base class for Contrast Limited Adaptive Histogram Equalization. +*/ +class CV_EXPORTS_W CLAHE : public Algorithm +{ +public: + /** @brief Equalizes the histogram of a grayscale image using Contrast Limited Adaptive Histogram Equalization. + + @param src Source image of type CV_8UC1 or CV_16UC1. + @param dst Destination image. + */ + CV_WRAP virtual void apply(InputArray src, OutputArray dst) = 0; + + /** @brief Sets threshold for contrast limiting. + + @param clipLimit threshold value. + */ + CV_WRAP virtual void setClipLimit(double clipLimit) = 0; + + //! Returns threshold value for contrast limiting. + CV_WRAP virtual double getClipLimit() const = 0; + + /** @brief Sets size of grid for histogram equalization. Input image will be divided into + equally sized rectangular tiles. + + @param tileGridSize defines the number of tiles in row and column. + */ + CV_WRAP virtual void setTilesGridSize(Size tileGridSize) = 0; + + //!@brief Returns Size defines the number of tiles in row and column. + CV_WRAP virtual Size getTilesGridSize() const = 0; + + CV_WRAP virtual void collectGarbage() = 0; +}; + +//! @} imgproc_hist + +//! @addtogroup imgproc_subdiv2d +//! @{ + +class CV_EXPORTS_W Subdiv2D +{ +public: + /** Subdiv2D point location cases */ + enum { PTLOC_ERROR = -2, //!< Point location error + PTLOC_OUTSIDE_RECT = -1, //!< Point outside the subdivision bounding rect + PTLOC_INSIDE = 0, //!< Point inside some facet + PTLOC_VERTEX = 1, //!< Point coincides with one of the subdivision vertices + PTLOC_ON_EDGE = 2 //!< Point on some edge + }; + + /** Subdiv2D edge type navigation (see: getEdge()) */ + enum { NEXT_AROUND_ORG = 0x00, + NEXT_AROUND_DST = 0x22, + PREV_AROUND_ORG = 0x11, + PREV_AROUND_DST = 0x33, + NEXT_AROUND_LEFT = 0x13, + NEXT_AROUND_RIGHT = 0x31, + PREV_AROUND_LEFT = 0x20, + PREV_AROUND_RIGHT = 0x02 + }; + + /** creates an empty Subdiv2D object. + To create a new empty Delaunay subdivision you need to use the #initDelaunay function. + */ + CV_WRAP Subdiv2D(); + + /** @overload + + @param rect Rectangle that includes all of the 2D points that are to be added to the subdivision. + + The function creates an empty Delaunay subdivision where 2D points can be added using the function + insert() . All of the points to be added must be within the specified rectangle, otherwise a runtime + error is raised. + */ + CV_WRAP Subdiv2D(Rect rect); + + /** @brief Creates a new empty Delaunay subdivision + + @param rect Rectangle that includes all of the 2D points that are to be added to the subdivision. + + */ + CV_WRAP void initDelaunay(Rect rect); + + /** @brief Insert a single point into a Delaunay triangulation. + + @param pt Point to insert. + + 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. + @returns the ID of the point. + + @note If the point is outside of the triangulation specified rect a runtime error is raised. + */ + CV_WRAP int insert(Point2f pt); + + /** @brief Insert multiple points into a Delaunay triangulation. + + @param ptvec Points to insert. + + The function inserts a vector of points into a subdivision and modifies the subdivision topology + appropriately. + */ + CV_WRAP void insert(const std::vector& ptvec); + + /** @brief Returns the location of a point within a Delaunay triangulation. + + @param pt Point to locate. + @param edge Output edge that the point belongs to or is located to the right of it. + @param vertex Optional output vertex the input point coincides with. + + The function locates the input point within the subdivision and gives one of the triangle edges + or vertices. + + @returns an integer which specify one of the following five cases for point location: + - The point falls into some facet. The function returns #PTLOC_INSIDE and edge will contain one of + edges of the facet. + - The point falls onto the edge. The function returns #PTLOC_ON_EDGE and edge will contain this edge. + - The point coincides with one of the subdivision vertices. The function returns #PTLOC_VERTEX and + vertex will contain a pointer to the vertex. + - The point is outside the subdivision reference rectangle. The function returns #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, #PTLOC_ERROR is returned. + */ + CV_WRAP int locate(Point2f pt, CV_OUT int& edge, CV_OUT int& vertex); + + /** @brief Finds the subdivision vertex closest to the given point. + + @param pt Input point. + @param nearestPt Output subdivision vertex 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 + of the facet containing the input point, though the facet (located using locate() ) is used as a + starting point. + + @returns vertex ID. + */ + CV_WRAP int findNearest(Point2f pt, CV_OUT Point2f* nearestPt = 0); + + /** @brief Returns a list of all edges. + + @param edgeList Output vector. + + The function gives each edge as a 4 numbers vector, where each two are one of the edge + vertices. i.e. org_x = v[0], org_y = v[1], dst_x = v[2], dst_y = v[3]. + */ + CV_WRAP void getEdgeList(CV_OUT std::vector& edgeList) const; + + /** @brief Returns a list of the leading edge ID connected to each triangle. + + @param leadingEdgeList Output vector. + + The function gives one edge ID for each triangle. + */ + CV_WRAP void getLeadingEdgeList(CV_OUT std::vector& leadingEdgeList) const; + + /** @brief Returns a list of all triangles. + + @param triangleList Output vector. + + The function gives each triangle as a 6 numbers vector, where each two are one of the triangle + vertices. i.e. p1_x = v[0], p1_y = v[1], p2_x = v[2], p2_y = v[3], p3_x = v[4], p3_y = v[5]. + */ + CV_WRAP void getTriangleList(CV_OUT std::vector& triangleList) const; + + /** @brief Returns a list of all Voroni facets. + + @param idx Vector of vertices IDs to consider. For all vertices you can pass empty vector. + @param facetList Output vector of the Voroni facets. + @param facetCenters Output vector of the Voroni facets center points. + + */ + CV_WRAP void getVoronoiFacetList(const std::vector& idx, CV_OUT std::vector >& facetList, + CV_OUT std::vector& facetCenters); + + /** @brief Returns vertex location from vertex ID. + + @param vertex vertex ID. + @param firstEdge Optional. The first edge ID which is connected to the vertex. + @returns vertex (x,y) + + */ + CV_WRAP Point2f getVertex(int vertex, CV_OUT int* firstEdge = 0) const; + + /** @brief Returns one of the edges related to the given edge. + + @param edge Subdivision edge ID. + @param nextEdgeType Parameter specifying which of the related edges to return. + The following values are possible: + - NEXT_AROUND_ORG next around the edge origin ( eOnext on the picture below if e is the input edge) + - NEXT_AROUND_DST next around the edge vertex ( eDnext ) + - PREV_AROUND_ORG previous around the edge origin (reversed eRnext ) + - PREV_AROUND_DST previous around the edge destination (reversed eLnext ) + - NEXT_AROUND_LEFT next around the left facet ( eLnext ) + - NEXT_AROUND_RIGHT next around the right facet ( eRnext ) + - PREV_AROUND_LEFT previous around the left facet (reversed eOnext ) + - PREV_AROUND_RIGHT previous around the right facet (reversed eDnext ) + + ![sample output](pics/quadedge.png) + + @returns edge ID related to the input edge. + */ + CV_WRAP int getEdge( int edge, int nextEdgeType ) const; + + /** @brief Returns next edge around the edge origin. + + @param edge Subdivision edge ID. + + @returns an integer which is next edge ID around the edge origin: eOnext on the + picture above if e is the input edge). + */ + CV_WRAP int nextEdge(int edge) const; + + /** @brief Returns another edge of the same quad-edge. + + @param edge Subdivision edge ID. + @param rotate Parameter specifying which of the edges of the same quad-edge as the input + one to return. The following values are possible: + - 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)) + + @returns one of the edges ID of the same quad-edge as the input edge. + */ + CV_WRAP int rotateEdge(int edge, int rotate) const; + CV_WRAP int symEdge(int edge) const; + + /** @brief Returns the edge origin. + + @param edge Subdivision edge ID. + @param orgpt Output vertex location. + + @returns vertex ID. + */ + CV_WRAP int edgeOrg(int edge, CV_OUT Point2f* orgpt = 0) const; + + /** @brief Returns the edge destination. + + @param edge Subdivision edge ID. + @param dstpt Output vertex location. + + @returns vertex ID. + */ + CV_WRAP int edgeDst(int edge, CV_OUT Point2f* dstpt = 0) const; + +protected: + int newEdge(); + void deleteEdge(int edge); + int newPoint(Point2f pt, bool isvirtual, int firstEdge = 0); + void deletePoint(int vtx); + void setEdgePoints( int edge, int orgPt, int dstPt ); + void splice( int edgeA, int edgeB ); + int connectEdges( int edgeA, int edgeB ); + void swapEdges( int edge ); + int isRightOf(Point2f pt, int edge) const; + void calcVoronoi(); + void clearVoronoi(); + void checkSubdiv() const; + + struct CV_EXPORTS Vertex + { + Vertex(); + Vertex(Point2f pt, bool _isvirtual, int _firstEdge=0); + bool isvirtual() const; + bool isfree() const; + + int firstEdge; + int type; + Point2f pt; + }; + + struct CV_EXPORTS QuadEdge + { + QuadEdge(); + QuadEdge(int edgeidx); + bool isfree() const; + + int next[4]; + int pt[4]; + }; + + //! All of the vertices + std::vector vtx; + //! All of the edges + std::vector qedges; + int freeQEdge; + int freePoint; + bool validGeometry; + + int recentEdge; + //! Top left corner of the bounding rect + Point2f topLeft; + //! Bottom right corner of the bounding rect + Point2f bottomRight; +}; + +//! @} imgproc_subdiv2d + +//! @addtogroup imgproc_feature +//! @{ + +/** @brief Line segment detector class + +following the algorithm described at @cite Rafael12 . + +@note Implementation has been removed due original code license conflict + +*/ +class CV_EXPORTS_W LineSegmentDetector : public Algorithm +{ +public: + + /** @brief Finds lines in the input image. + + This is the output of the default parameters of the algorithm on the above shown image. + + ![image](pics/building_lsd.png) + + @param _image A grayscale (CV_8UC1) input image. If only a roi needs to be selected, use: + `lsd_ptr-\>detect(image(roi), lines, ...); lines += Scalar(roi.x, roi.y, roi.x, roi.y);` + @param _lines A vector of Vec4i or Vec4f elements specifying the beginning and ending point of a line. Where + Vec4i/Vec4f is (x1, y1, x2, y2), point 1 is the start, point 2 - end. Returned lines are strictly + oriented depending on the gradient. + @param width Vector of widths of the regions, where the lines are found. E.g. Width of line. + @param prec Vector of precisions with which the lines are found. + @param nfa Vector containing number of false alarms in the line region, with precision of 10%. The + bigger the value, logarithmically better the detection. + - -1 corresponds to 10 mean false alarms + - 0 corresponds to 1 mean false alarm + - 1 corresponds to 0.1 mean false alarms + This vector will be calculated only when the objects type is #LSD_REFINE_ADV. + */ + CV_WRAP virtual void detect(InputArray _image, OutputArray _lines, + OutputArray width = noArray(), OutputArray prec = noArray(), + OutputArray nfa = noArray()) = 0; + + /** @brief Draws the line segments on a given image. + @param _image The image, where the lines will be drawn. Should be bigger or equal to the image, + where the lines were found. + @param lines A vector of the lines that needed to be drawn. + */ + CV_WRAP virtual void drawSegments(InputOutputArray _image, InputArray lines) = 0; + + /** @brief Draws two groups of lines in blue and red, counting the non overlapping (mismatching) pixels. + + @param size The size of the image, where lines1 and lines2 were found. + @param lines1 The first group of lines that needs to be drawn. It is visualized in blue color. + @param lines2 The second group of lines. They visualized in red color. + @param _image Optional image, where the lines will be drawn. The image should be color(3-channel) + in order for lines1 and lines2 to be drawn in the above mentioned colors. + */ + CV_WRAP virtual int compareSegments(const Size& size, InputArray lines1, InputArray lines2, InputOutputArray _image = noArray()) = 0; + + virtual ~LineSegmentDetector() { } +}; + +/** @brief Creates a smart pointer to a LineSegmentDetector object and initializes it. + +The LineSegmentDetector algorithm is defined using the standard values. Only advanced users may want +to edit those, as to tailor it for their own application. + +@param _refine The way found lines will be refined, see #LineSegmentDetectorModes +@param _scale The scale of the image that will be used to find the lines. Range (0..1]. +@param _sigma_scale Sigma for Gaussian filter. It is computed as sigma = _sigma_scale/_scale. +@param _quant Bound to the quantization error on the gradient norm. +@param _ang_th Gradient angle tolerance in degrees. +@param _log_eps Detection threshold: -log10(NFA) \> log_eps. Used only when advance refinement +is chosen. +@param _density_th Minimal density of aligned region points in the enclosing rectangle. +@param _n_bins Number of bins in pseudo-ordering of gradient modulus. + +@note Implementation has been removed due original code license conflict + */ +CV_EXPORTS_W Ptr createLineSegmentDetector( + int _refine = LSD_REFINE_STD, double _scale = 0.8, + double _sigma_scale = 0.6, double _quant = 2.0, double _ang_th = 22.5, + double _log_eps = 0, double _density_th = 0.7, int _n_bins = 1024); + +//! @} imgproc_feature + +//! @addtogroup imgproc_filter +//! @{ + +/** @brief Returns Gaussian filter coefficients. + +The function computes and returns the \f$\texttt{ksize} \times 1\f$ matrix of Gaussian filter +coefficients: + +\f[G_i= \alpha *e^{-(i-( \texttt{ksize} -1)/2)^2/(2* \texttt{sigma}^2)},\f] + +where \f$i=0..\texttt{ksize}-1\f$ and \f$\alpha\f$ is the scale factor chosen so that \f$\sum_i G_i=1\f$. + +Two of such generated kernels can be passed to sepFilter2D. Those functions automatically recognize +smoothing kernels (a symmetrical kernel with sum of weights equal to 1) and handle them accordingly. +You may also use the higher-level GaussianBlur. +@param ksize Aperture size. It should be odd ( \f$\texttt{ksize} \mod 2 = 1\f$ ) and positive. +@param sigma Gaussian standard deviation. If it is non-positive, it is computed from ksize as +`sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8`. +@param ktype Type of filter coefficients. It can be CV_32F or CV_64F . +@sa sepFilter2D, getDerivKernels, getStructuringElement, GaussianBlur + */ +CV_EXPORTS_W Mat getGaussianKernel( int ksize, double sigma, int ktype = CV_64F ); + +/** @brief Returns filter coefficients for computing spatial image derivatives. + +The function computes and returns the filter coefficients for spatial image derivatives. When +`ksize=FILTER_SCHARR`, the Scharr \f$3 \times 3\f$ kernels are generated (see #Scharr). Otherwise, Sobel +kernels are generated (see #Sobel). The filters are normally passed to #sepFilter2D or to + +@param kx Output matrix of row filter coefficients. It has the type ktype . +@param ky Output matrix of column filter coefficients. It has the type ktype . +@param dx Derivative order in respect of x. +@param dy Derivative order in respect of y. +@param ksize Aperture size. It can be FILTER_SCHARR, 1, 3, 5, or 7. +@param normalize Flag indicating whether to normalize (scale down) the filter coefficients or not. +Theoretically, the coefficients should have the denominator \f$=2^{ksize*2-dx-dy-2}\f$. If you are +going to filter floating-point images, you are likely to use the normalized kernels. But if you +compute derivatives of an 8-bit image, store the results in a 16-bit image, and wish to preserve +all the fractional bits, you may want to set normalize=false . +@param ktype Type of filter coefficients. It can be CV_32f or CV_64F . + */ +CV_EXPORTS_W void getDerivKernels( OutputArray kx, OutputArray ky, + int dx, int dy, int ksize, + bool normalize = false, int ktype = CV_32F ); + +/** @brief Returns Gabor filter coefficients. + +For more details about gabor filter equations and parameters, see: [Gabor +Filter](http://en.wikipedia.org/wiki/Gabor_filter). + +@param ksize Size of the filter returned. +@param sigma Standard deviation of the gaussian envelope. +@param theta Orientation of the normal to the parallel stripes of a Gabor function. +@param lambd Wavelength of the sinusoidal factor. +@param gamma Spatial aspect ratio. +@param psi Phase offset. +@param ktype Type of filter coefficients. It can be CV_32F or CV_64F . + */ +CV_EXPORTS_W Mat getGaborKernel( Size ksize, double sigma, double theta, double lambd, + double gamma, double psi = CV_PI*0.5, int ktype = CV_64F ); + +//! returns "magic" border value for erosion and dilation. It is automatically transformed to Scalar::all(-DBL_MAX) for dilation. +static inline Scalar morphologyDefaultBorderValue() { return Scalar::all(DBL_MAX); } + +/** @brief Returns a structuring element of the specified size and shape for morphological operations. + +The function constructs and returns the structuring element that can be further passed to #erode, +#dilate or #morphologyEx. But you can also construct an arbitrary binary mask yourself and use it as +the structuring element. + +@param shape Element shape that could be one of #MorphShapes +@param ksize Size of the structuring element. +@param anchor Anchor position within the element. The default value \f$(-1, -1)\f$ 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. + */ +CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1)); + +/** @example samples/cpp/tutorial_code/ImgProc/Smoothing/Smoothing.cpp +Sample code for simple filters +![Sample screenshot](Smoothing_Tutorial_Result_Median_Filter.jpg) +Check @ref tutorial_gausian_median_blur_bilateral_filter "the corresponding tutorial" for more details + */ + +/** @brief Blurs an image using the median filter. + +The function smoothes an image using the median filter with the \f$\texttt{ksize} \times +\texttt{ksize}\f$ aperture. Each channel of a multi-channel image is processed independently. +In-place operation is supported. + +@note The median filter uses #BORDER_REPLICATE internally to cope with border pixels, see #BorderTypes + +@param src input 1-, 3-, or 4-channel image; when ksize is 3 or 5, the image depth should be +CV_8U, CV_16U, or CV_32F, for larger aperture sizes, it can only be CV_8U. +@param dst destination array of the same size and type as src. +@param ksize aperture linear size; it must be odd and greater than 1, for example: 3, 5, 7 ... +@sa bilateralFilter, blur, boxFilter, GaussianBlur + */ +CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize ); + +/** @brief Blurs an image using a Gaussian filter. + +The function convolves the source image with the specified Gaussian kernel. In-place filtering is +supported. + +@param src input image; the image can have any number of channels, which are processed +independently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. +@param dst output image of the same size and type as src. +@param ksize Gaussian kernel size. ksize.width and ksize.height can differ but they both must be +positive and odd. Or, they can be zero's and then they are computed from sigma. +@param sigmaX Gaussian kernel standard deviation in X direction. +@param sigmaY Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to be +equal to sigmaX, if both sigmas are zeros, they are computed from ksize.width and ksize.height, +respectively (see #getGaussianKernel for details); to fully control the result regardless of +possible future modifications of all this semantics, it is recommended to specify all of ksize, +sigmaX, and sigmaY. +@param borderType pixel extrapolation method, see #BorderTypes + +@sa sepFilter2D, filter2D, blur, boxFilter, bilateralFilter, medianBlur + */ +CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize, + double sigmaX, double sigmaY = 0, + int borderType = BORDER_DEFAULT ); + +/** @brief Applies the bilateral filter to an image. + +The function applies bilateral filtering to the input image, as described in +http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html +bilateralFilter can reduce unwanted noise very well while keeping edges fairly sharp. However, it is +very slow compared to most filters. + +_Sigma values_: For simplicity, you can set the 2 sigma values to be the same. If they are small (\< +10), the filter will not have much effect, whereas if they are large (\> 150), they will have a very +strong effect, making the image look "cartoonish". + +_Filter size_: Large filters (d \> 5) are very slow, so it is recommended to use d=5 for real-time +applications, and perhaps d=9 for offline applications that need heavy noise filtering. + +This filter does not work inplace. +@param src Source 8-bit or floating-point, 1-channel or 3-channel image. +@param dst Destination image of the same size and type as src . +@param d Diameter of each pixel neighborhood that is used during filtering. If it is non-positive, +it is computed from sigmaSpace. +@param sigmaColor Filter sigma in the color space. A larger value of the parameter means that +farther colors within the pixel neighborhood (see sigmaSpace) will be mixed together, resulting +in larger areas of semi-equal color. +@param sigmaSpace Filter sigma in the coordinate space. A larger value of the parameter means that +farther pixels will influence each other as long as their colors are close enough (see sigmaColor +). When d\>0, it specifies the neighborhood size regardless of sigmaSpace. Otherwise, d is +proportional to sigmaSpace. +@param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes + */ +CV_EXPORTS_W void bilateralFilter( InputArray src, OutputArray dst, int d, + double sigmaColor, double sigmaSpace, + int borderType = BORDER_DEFAULT ); + +/** @brief Blurs an image using the box filter. + +The function smooths an image using the kernel: + +\f[\texttt{K} = \alpha \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \end{bmatrix}\f] + +where + +\f[\alpha = \fork{\frac{1}{\texttt{ksize.width*ksize.height}}}{when \texttt{normalize=true}}{1}{otherwise}\f] + +Unnormalized box filter is useful for computing various integral characteristics over each pixel +neighborhood, such as covariance matrices of image derivatives (used in dense optical flow +algorithms, and so on). If you need to compute pixel sums over variable-size windows, use #integral. + +@param src input image. +@param dst output image of the same size and type as src. +@param ddepth the output image depth (-1 to use src.depth()). +@param ksize blurring kernel size. +@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel +center. +@param normalize flag, specifying whether the kernel is normalized by its area or not. +@param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes +@sa blur, bilateralFilter, GaussianBlur, medianBlur, integral + */ +CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth, + Size ksize, Point anchor = Point(-1,-1), + bool normalize = true, + int borderType = BORDER_DEFAULT ); + +/** @brief Calculates the normalized sum of squares of the pixel values overlapping the filter. + +For every pixel \f$ (x, y) \f$ in the source image, the function calculates the sum of squares of those neighboring +pixel values which overlap the filter placed over the pixel \f$ (x, y) \f$. + +The unnormalized square box filter can be useful in computing local image statistics such as the the local +variance and standard deviation around the neighborhood of a pixel. + +@param src input image +@param dst output image of the same size and type as _src +@param ddepth the output image depth (-1 to use src.depth()) +@param ksize kernel size +@param anchor kernel anchor point. The default value of Point(-1, -1) denotes that the anchor is at the kernel +center. +@param normalize flag, specifying whether the kernel is to be normalized by it's area or not. +@param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes +@sa boxFilter +*/ +CV_EXPORTS_W void sqrBoxFilter( InputArray src, OutputArray dst, int ddepth, + Size ksize, Point anchor = Point(-1, -1), + bool normalize = true, + int borderType = BORDER_DEFAULT ); + +/** @brief Blurs an image using the normalized box filter. + +The function smooths an image using the kernel: + +\f[\texttt{K} = \frac{1}{\texttt{ksize.width*ksize.height}} \begin{bmatrix} 1 & 1 & 1 & \cdots & 1 & 1 \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \hdotsfor{6} \\ 1 & 1 & 1 & \cdots & 1 & 1 \\ \end{bmatrix}\f] + +The call `blur(src, dst, ksize, anchor, borderType)` is equivalent to `boxFilter(src, dst, src.type(), +anchor, true, borderType)`. + +@param src input image; it can have any number of channels, which are processed independently, but +the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. +@param dst output image of the same size and type as src. +@param ksize blurring kernel size. +@param anchor anchor point; default value Point(-1,-1) means that the anchor is at the kernel +center. +@param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes +@sa boxFilter, bilateralFilter, GaussianBlur, medianBlur + */ +CV_EXPORTS_W void blur( InputArray src, OutputArray dst, + Size ksize, Point anchor = Point(-1,-1), + int borderType = BORDER_DEFAULT ); + +/** @brief Convolves an image with the kernel. + +The function applies an arbitrary linear filter to an image. In-place operation is supported. When +the aperture is partially outside the image, the function interpolates outlier pixel values +according to the specified border mode. + +The function does actually compute correlation, not the convolution: + +\f[\texttt{dst} (x,y) = \sum _{ \stackrel{0\leq x' < \texttt{kernel.cols},}{0\leq y' < \texttt{kernel.rows}} } \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} )\f] + +That is, the kernel is not mirrored around the anchor point. If you need a real convolution, flip +the kernel using #flip and set the new anchor to `(kernel.cols - anchor.x - 1, kernel.rows - +anchor.y - 1)`. + +The function uses the DFT-based algorithm in case of sufficiently large kernels (~`11 x 11` or +larger) and the direct algorithm for small kernels. + +@param src input image. +@param dst output image of the same size and the same number of channels as src. +@param ddepth desired depth of the destination image, see @ref filter_depths "combinations" +@param kernel convolution kernel (or rather a correlation 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 split and process them individually. +@param anchor anchor of the kernel that indicates the relative position of a filtered point within +the kernel; the anchor should lie within the kernel; default value (-1,-1) means that the anchor +is at the kernel center. +@param delta optional value added to the filtered pixels before storing them in dst. +@param borderType pixel extrapolation method, see #BorderTypes +@sa sepFilter2D, dft, matchTemplate + */ +CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth, + InputArray kernel, Point anchor = Point(-1,-1), + double delta = 0, int borderType = BORDER_DEFAULT ); + +/** @brief Applies a separable linear filter to an image. + +The function applies a separable linear filter to the image. That is, first, every row of src is +filtered with the 1D kernel kernelX. Then, every column of the result is filtered with the 1D +kernel kernelY. The final result shifted by delta is stored in dst . + +@param src Source image. +@param dst Destination image of the same size and the same number of channels as src . +@param ddepth Destination image depth, see @ref filter_depths "combinations" +@param kernelX Coefficients for filtering each row. +@param kernelY Coefficients for filtering each column. +@param anchor Anchor position within the kernel. The default value \f$(-1,-1)\f$ means that the anchor +is at the kernel center. +@param delta Value added to the filtered results before storing them. +@param borderType Pixel extrapolation method, see #BorderTypes +@sa filter2D, Sobel, GaussianBlur, boxFilter, blur + */ +CV_EXPORTS_W void sepFilter2D( InputArray src, OutputArray dst, int ddepth, + InputArray kernelX, InputArray kernelY, + Point anchor = Point(-1,-1), + double delta = 0, int borderType = BORDER_DEFAULT ); + +/** @example samples/cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp +Sample code using Sobel and/or Scharr OpenCV functions to make a simple Edge Detector +![Sample screenshot](Sobel_Derivatives_Tutorial_Result.jpg) +Check @ref tutorial_sobel_derivatives "the corresponding tutorial" for more details +*/ + +/** @brief Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator. + +In all cases except one, the \f$\texttt{ksize} \times \texttt{ksize}\f$ separable kernel is used to +calculate the derivative. When \f$\texttt{ksize = 1}\f$, the \f$3 \times 1\f$ or \f$1 \times 3\f$ +kernel is used (that is, no Gaussian smoothing is done). `ksize = 1` can only be used for the first +or the second x- or y- derivatives. + +There is also the special value `ksize = #FILTER_SCHARR (-1)` that corresponds to the \f$3\times3\f$ Scharr +filter that may give more accurate results than the \f$3\times3\f$ Sobel. The Scharr aperture is + +\f[\vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3}\f] + +for the x-derivative, or transposed for the y-derivative. + +The function calculates an image derivative by convolving the image with the appropriate kernel: + +\f[\texttt{dst} = \frac{\partial^{xorder+yorder} \texttt{src}}{\partial x^{xorder} \partial y^{yorder}}\f] + +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, ksize = 3) +or ( xorder = 0, yorder = 1, ksize = 3) to calculate the first x- or y- image derivative. The first +case corresponds to a kernel of: + +\f[\vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1}\f] + +The second case corresponds to a kernel of: + +\f[\vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1}\f] + +@param src input image. +@param dst output image of the same size and the same number of channels as src . +@param ddepth output image depth, see @ref filter_depths "combinations"; in the case of + 8-bit input images it will result in truncated derivatives. +@param dx order of the derivative x. +@param dy order of the derivative y. +@param ksize size of the extended Sobel kernel; it must be 1, 3, 5, or 7. +@param scale optional scale factor for the computed derivative values; by default, no scaling is +applied (see #getDerivKernels for details). +@param delta optional delta value that is added to the results prior to storing them in dst. +@param borderType pixel extrapolation method, see #BorderTypes +@sa Scharr, Laplacian, sepFilter2D, filter2D, GaussianBlur, cartToPolar + */ +CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth, + int dx, int dy, int ksize = 3, + double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT ); + +/** @brief Calculates the first order image derivative in both x and y using a Sobel operator + +Equivalent to calling: + +@code +Sobel( src, dx, CV_16SC1, 1, 0, 3 ); +Sobel( src, dy, CV_16SC1, 0, 1, 3 ); +@endcode + +@param src input image. +@param dx output image with first-order derivative in x. +@param dy output image with first-order derivative in y. +@param ksize size of Sobel kernel. It must be 3. +@param borderType pixel extrapolation method, see #BorderTypes + +@sa Sobel + */ + +CV_EXPORTS_W void spatialGradient( InputArray src, OutputArray dx, + OutputArray dy, int ksize = 3, + int borderType = BORDER_DEFAULT ); + +/** @brief Calculates the first x- or y- image derivative using Scharr operator. + +The function computes the first x- or y- spatial image derivative using the Scharr operator. The +call + +\f[\texttt{Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)}\f] + +is equivalent to + +\f[\texttt{Sobel(src, dst, ddepth, dx, dy, FILTER_SCHARR, scale, delta, borderType)} .\f] + +@param src input image. +@param dst output image of the same size and the same number of channels as src. +@param ddepth output image depth, see @ref filter_depths "combinations" +@param dx order of the derivative x. +@param dy order of the derivative y. +@param scale optional scale factor for the computed derivative values; by default, no scaling is +applied (see #getDerivKernels for details). +@param delta optional delta value that is added to the results prior to storing them in dst. +@param borderType pixel extrapolation method, see #BorderTypes +@sa cartToPolar + */ +CV_EXPORTS_W void Scharr( InputArray src, OutputArray dst, int ddepth, + int dx, int dy, double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT ); + +/** @example samples/cpp/laplace.cpp +An example using Laplace transformations for edge detection +*/ + +/** @brief Calculates the Laplacian of an image. + +The function calculates the Laplacian of the source image by adding up the second x and y +derivatives calculated using the Sobel operator: + +\f[\texttt{dst} = \Delta \texttt{src} = \frac{\partial^2 \texttt{src}}{\partial x^2} + \frac{\partial^2 \texttt{src}}{\partial y^2}\f] + +This is done when `ksize > 1`. When `ksize == 1`, the Laplacian is computed by filtering the image +with the following \f$3 \times 3\f$ aperture: + +\f[\vecthreethree {0}{1}{0}{1}{-4}{1}{0}{1}{0}\f] + +@param src Source image. +@param dst Destination image of the same size and the same number of channels as src . +@param ddepth Desired depth of the destination image. +@param ksize Aperture size used to compute the second-derivative filters. See #getDerivKernels for +details. The size must be positive and odd. +@param scale Optional scale factor for the computed Laplacian values. By default, no scaling is +applied. See #getDerivKernels for details. +@param delta Optional delta value that is added to the results prior to storing them in dst . +@param borderType Pixel extrapolation method, see #BorderTypes +@sa Sobel, Scharr + */ +CV_EXPORTS_W void Laplacian( InputArray src, OutputArray dst, int ddepth, + int ksize = 1, double scale = 1, double delta = 0, + int borderType = BORDER_DEFAULT ); + +//! @} imgproc_filter + +//! @addtogroup imgproc_feature +//! @{ + +/** @example samples/cpp/edge.cpp +This program demonstrates usage of the Canny edge detector + +Check @ref tutorial_canny_detector "the corresponding tutorial" for more details +*/ + +/** @brief Finds edges in an image using the Canny algorithm @cite Canny86 . + +The function finds edges in the input image and marks them in the output map edges using the +Canny algorithm. The smallest value between threshold1 and threshold2 is used for edge linking. The +largest value is used to find initial segments of strong edges. See + + +@param image 8-bit input image. +@param edges output edge map; single channels 8-bit image, which has the same size as image . +@param threshold1 first threshold for the hysteresis procedure. +@param threshold2 second threshold for the hysteresis procedure. +@param apertureSize aperture size for the Sobel operator. +@param L2gradient a flag, indicating whether a more accurate \f$L_2\f$ norm +\f$=\sqrt{(dI/dx)^2 + (dI/dy)^2}\f$ should be used to calculate the image gradient magnitude ( +L2gradient=true ), or whether the default \f$L_1\f$ norm \f$=|dI/dx|+|dI/dy|\f$ is enough ( +L2gradient=false ). + */ +CV_EXPORTS_W void Canny( InputArray image, OutputArray edges, + double threshold1, double threshold2, + int apertureSize = 3, bool L2gradient = false ); + +/** \overload + +Finds edges in an image using the Canny algorithm with custom image gradient. + +@param dx 16-bit x derivative of input image (CV_16SC1 or CV_16SC3). +@param dy 16-bit y derivative of input image (same type as dx). +@param edges output edge map; single channels 8-bit image, which has the same size as image . +@param threshold1 first threshold for the hysteresis procedure. +@param threshold2 second threshold for the hysteresis procedure. +@param L2gradient a flag, indicating whether a more accurate \f$L_2\f$ norm +\f$=\sqrt{(dI/dx)^2 + (dI/dy)^2}\f$ should be used to calculate the image gradient magnitude ( +L2gradient=true ), or whether the default \f$L_1\f$ norm \f$=|dI/dx|+|dI/dy|\f$ is enough ( +L2gradient=false ). + */ +CV_EXPORTS_W void Canny( InputArray dx, InputArray dy, + OutputArray edges, + double threshold1, double threshold2, + bool L2gradient = false ); + +/** @brief Calculates the minimal eigenvalue of gradient matrices for corner detection. + +The function is similar to cornerEigenValsAndVecs but it calculates and stores only the minimal +eigenvalue of the covariance matrix of derivatives, that is, \f$\min(\lambda_1, \lambda_2)\f$ in terms +of the formulae in the cornerEigenValsAndVecs description. + +@param src Input single-channel 8-bit or floating-point image. +@param dst Image to store the minimal eigenvalues. It has the type CV_32FC1 and the same size as +src . +@param blockSize Neighborhood size (see the details on #cornerEigenValsAndVecs ). +@param ksize Aperture parameter for the Sobel operator. +@param borderType Pixel extrapolation method. See #BorderTypes. + */ +CV_EXPORTS_W void cornerMinEigenVal( InputArray src, OutputArray dst, + int blockSize, int ksize = 3, + int borderType = BORDER_DEFAULT ); + +/** @brief Harris corner detector. + +The function runs the Harris corner detector on the image. Similarly to cornerMinEigenVal and +cornerEigenValsAndVecs , for each pixel \f$(x, y)\f$ it calculates a \f$2\times2\f$ gradient covariance +matrix \f$M^{(x,y)}\f$ over a \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood. Then, it +computes the following characteristic: + +\f[\texttt{dst} (x,y) = \mathrm{det} M^{(x,y)} - k \cdot \left ( \mathrm{tr} M^{(x,y)} \right )^2\f] + +Corners in the image can be found as the local maxima of this response map. + +@param src Input single-channel 8-bit or floating-point image. +@param dst Image to store the Harris detector responses. It has the type CV_32FC1 and the same +size as src . +@param blockSize Neighborhood size (see the details on #cornerEigenValsAndVecs ). +@param ksize Aperture parameter for the Sobel operator. +@param k Harris detector free parameter. See the formula above. +@param borderType Pixel extrapolation method. See #BorderTypes. + */ +CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize, + int ksize, double k, + int borderType = BORDER_DEFAULT ); + +/** @brief Calculates eigenvalues and eigenvectors of image blocks for corner detection. + +For every pixel \f$p\f$ , the function cornerEigenValsAndVecs considers a blockSize \f$\times\f$ blockSize +neighborhood \f$S(p)\f$ . It calculates the covariation matrix of derivatives over the neighborhood as: + +\f[M = \begin{bmatrix} \sum _{S(p)}(dI/dx)^2 & \sum _{S(p)}dI/dx dI/dy \\ \sum _{S(p)}dI/dx dI/dy & \sum _{S(p)}(dI/dy)^2 \end{bmatrix}\f] + +where the derivatives are computed using the Sobel operator. + +After that, it finds eigenvectors and eigenvalues of \f$M\f$ and stores them in the destination image as +\f$(\lambda_1, \lambda_2, x_1, y_1, x_2, y_2)\f$ where + +- \f$\lambda_1, \lambda_2\f$ are the non-sorted eigenvalues of \f$M\f$ +- \f$x_1, y_1\f$ are the eigenvectors corresponding to \f$\lambda_1\f$ +- \f$x_2, y_2\f$ are the eigenvectors corresponding to \f$\lambda_2\f$ + +The output of the function can be used for robust edge or corner detection. + +@param src Input single-channel 8-bit or floating-point image. +@param dst Image to store the results. It has the same size as src and the type CV_32FC(6) . +@param blockSize Neighborhood size (see details below). +@param ksize Aperture parameter for the Sobel operator. +@param borderType Pixel extrapolation method. See #BorderTypes. + +@sa cornerMinEigenVal, cornerHarris, preCornerDetect + */ +CV_EXPORTS_W void cornerEigenValsAndVecs( InputArray src, OutputArray dst, + int blockSize, int ksize, + int borderType = BORDER_DEFAULT ); + +/** @brief Calculates a feature map for corner detection. + +The function calculates the complex spatial derivative-based function of the source image + +\f[\texttt{dst} = (D_x \texttt{src} )^2 \cdot D_{yy} \texttt{src} + (D_y \texttt{src} )^2 \cdot D_{xx} \texttt{src} - 2 D_x \texttt{src} \cdot D_y \texttt{src} \cdot D_{xy} \texttt{src}\f] + +where \f$D_x\f$,\f$D_y\f$ are the first image derivatives, \f$D_{xx}\f$,\f$D_{yy}\f$ are the second image +derivatives, and \f$D_{xy}\f$ is the mixed derivative. + +The corners can be found as local maximums of the functions, as shown below: +@code + Mat corners, dilated_corners; + preCornerDetect(image, corners, 3); + // dilation with 3x3 rectangular structuring element + dilate(corners, dilated_corners, Mat(), 1); + Mat corner_mask = corners == dilated_corners; +@endcode + +@param src Source single-channel 8-bit of floating-point image. +@param dst Output image that has the type CV_32F and the same size as src . +@param ksize %Aperture size of the Sobel . +@param borderType Pixel extrapolation method. See #BorderTypes. + */ +CV_EXPORTS_W void preCornerDetect( InputArray src, OutputArray dst, int ksize, + int borderType = BORDER_DEFAULT ); + +/** @brief Refines the corner locations. + +The function iterates to find the sub-pixel accurate location of corners or radial saddle points, as +shown on the figure below. + +![image](pics/cornersubpix.png) + +Sub-pixel accurate corner locator is based on the observation that every vector from the center \f$q\f$ +to a point \f$p\f$ located within a neighborhood of \f$q\f$ is orthogonal to the image gradient at \f$p\f$ +subject to image and measurement noise. Consider the expression: + +\f[\epsilon _i = {DI_{p_i}}^T \cdot (q - p_i)\f] + +where \f${DI_{p_i}}\f$ is an image gradient at one of the points \f$p_i\f$ in a neighborhood of \f$q\f$ . The +value of \f$q\f$ is to be found so that \f$\epsilon_i\f$ is minimized. A system of equations may be set up +with \f$\epsilon_i\f$ set to zero: + +\f[\sum _i(DI_{p_i} \cdot {DI_{p_i}}^T) \cdot q - \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i)\f] + +where the gradients are summed within a neighborhood ("search window") of \f$q\f$ . Calling the first +gradient term \f$G\f$ and the second gradient term \f$b\f$ gives: + +\f[q = G^{-1} \cdot b\f] + +The algorithm sets the center of the neighborhood window at this new center \f$q\f$ and then iterates +until the center stays within a set threshold. + +@param image Input single-channel, 8-bit or float image. +@param corners Initial coordinates of the input corners and refined coordinates provided for +output. +@param winSize Half of the side length of the search window. For example, if winSize=Size(5,5) , +then a \f$(5*2+1) \times (5*2+1) = 11 \times 11\f$ search window is used. +@param zeroZone 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 +a size. +@param criteria Criteria for termination of the iterative process of corner refinement. That is, +the process of corner position refinement stops either after criteria.maxCount iterations or when +the corner position moves by less than criteria.epsilon on some iteration. + */ +CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners, + Size winSize, Size zeroZone, + TermCriteria criteria ); + +/** @brief Determines strong corners on an image. + +The function finds the most prominent corners in the image or in the specified image region, as +described in @cite Shi94 + +- Function calculates the corner quality measure at every source image pixel using the + #cornerMinEigenVal or #cornerHarris . +- Function performs a non-maximum suppression (the local maximums in *3 x 3* neighborhood are + retained). +- The corners with the minimal eigenvalue less than + \f$\texttt{qualityLevel} \cdot \max_{x,y} qualityMeasureMap(x,y)\f$ are rejected. +- The remaining corners are sorted by the quality measure in the descending order. +- Function throws away each corner for which there is a stronger corner at a distance less than + maxDistance. + +The function can be used to initialize a point-based tracker of an object. + +@note If the function is called with different values A and B of the parameter qualityLevel , and +A \> B, the vector of returned corners with qualityLevel=A will be the prefix of the output vector +with qualityLevel=B . + +@param image Input 8-bit or floating-point 32-bit, single-channel image. +@param corners Output vector of detected corners. +@param maxCorners Maximum number of corners to return. If there are more corners than are found, +the strongest of them is returned. `maxCorners <= 0` implies that no limit on the maximum is set +and all detected corners are returned. +@param qualityLevel Parameter characterizing the minimal accepted quality of image corners. The +parameter value is multiplied by the best corner quality measure, which is the minimal eigenvalue +(see #cornerMinEigenVal ) or the Harris function response (see #cornerHarris ). The corners with the +quality measure less than the product are rejected. For example, if the best corner has the +quality measure = 1500, and the qualityLevel=0.01 , then all the corners with the quality measure +less than 15 are rejected. +@param minDistance Minimum possible Euclidean distance between the returned corners. +@param mask Optional region of interest. If the image is not empty (it needs to have the type +CV_8UC1 and the same size as image ), it specifies the region in which the corners are detected. +@param blockSize Size of an average block for computing a derivative covariation matrix over each +pixel neighborhood. See cornerEigenValsAndVecs . +@param useHarrisDetector Parameter indicating whether to use a Harris detector (see #cornerHarris) +or #cornerMinEigenVal. +@param k Free parameter of the Harris detector. + +@sa cornerMinEigenVal, cornerHarris, calcOpticalFlowPyrLK, estimateRigidTransform, + */ + +CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners, + int maxCorners, double qualityLevel, double minDistance, + InputArray mask = noArray(), int blockSize = 3, + bool useHarrisDetector = false, double k = 0.04 ); + +CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners, + int maxCorners, double qualityLevel, double minDistance, + InputArray mask, int blockSize, + int gradientSize, bool useHarrisDetector = false, + double k = 0.04 ); +/** @example samples/cpp/tutorial_code/ImgTrans/houghlines.cpp +An example using the Hough line detector +![Sample input image](Hough_Lines_Tutorial_Original_Image.jpg) ![Output image](Hough_Lines_Tutorial_Result.jpg) +*/ + +/** @brief Finds lines in a binary image using the standard Hough transform. + +The function implements the standard or standard multi-scale Hough transform algorithm for line +detection. See for a good explanation of Hough +transform. + +@param image 8-bit, single-channel binary source image. The image may be modified by the function. +@param lines Output vector of lines. Each line is represented by a 2 or 3 element vector +\f$(\rho, \theta)\f$ or \f$(\rho, \theta, \textrm{votes})\f$ . \f$\rho\f$ is the distance from the coordinate origin \f$(0,0)\f$ (top-left corner of +the image). \f$\theta\f$ is the line rotation angle in radians ( +\f$0 \sim \textrm{vertical line}, \pi/2 \sim \textrm{horizontal line}\f$ ). +\f$\textrm{votes}\f$ is the value of accumulator. +@param rho Distance resolution of the accumulator in pixels. +@param theta Angle resolution of the accumulator in radians. +@param threshold Accumulator threshold parameter. Only those lines are returned that get enough +votes ( \f$>\texttt{threshold}\f$ ). +@param srn For the multi-scale Hough transform, it is a divisor for the distance resolution rho . +The coarse accumulator distance resolution is rho and the accurate accumulator resolution is +rho/srn . If both srn=0 and stn=0 , the classical Hough transform is used. Otherwise, both these +parameters should be positive. +@param stn For the multi-scale Hough transform, it is a divisor for the distance resolution theta. +@param min_theta For standard and multi-scale Hough transform, minimum angle to check for lines. +Must fall between 0 and max_theta. +@param max_theta For standard and multi-scale Hough transform, maximum angle to check for lines. +Must fall between min_theta and CV_PI. + */ +CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines, + double rho, double theta, int threshold, + double srn = 0, double stn = 0, + double min_theta = 0, double max_theta = CV_PI ); + +/** @brief Finds line segments in a binary image using the probabilistic Hough transform. + +The function implements the probabilistic Hough transform algorithm for line detection, described +in @cite Matas00 + +See the line detection example below: +@include snippets/imgproc_HoughLinesP.cpp +This is a sample picture the function parameters have been tuned for: + +![image](pics/building.jpg) + +And this is the output of the above program in case of the probabilistic Hough transform: + +![image](pics/houghp.png) + +@param image 8-bit, single-channel binary source image. The image may be modified by the function. +@param lines Output vector of lines. Each line is represented by a 4-element vector +\f$(x_1, y_1, x_2, y_2)\f$ , where \f$(x_1,y_1)\f$ and \f$(x_2, y_2)\f$ are the ending points of each detected +line segment. +@param rho Distance resolution of the accumulator in pixels. +@param theta Angle resolution of the accumulator in radians. +@param threshold Accumulator threshold parameter. Only those lines are returned that get enough +votes ( \f$>\texttt{threshold}\f$ ). +@param minLineLength Minimum line length. Line segments shorter than that are rejected. +@param maxLineGap Maximum allowed gap between points on the same line to link them. + +@sa LineSegmentDetector + */ +CV_EXPORTS_W void HoughLinesP( InputArray image, OutputArray lines, + double rho, double theta, int threshold, + double minLineLength = 0, double maxLineGap = 0 ); + +/** @brief Finds lines in a set of points using the standard Hough transform. + +The function finds lines in a set of points using a modification of the Hough transform. +@include snippets/imgproc_HoughLinesPointSet.cpp +@param _point Input vector of points. Each vector must be encoded as a Point vector \f$(x,y)\f$. Type must be CV_32FC2 or CV_32SC2. +@param _lines Output vector of found lines. Each vector is encoded as a vector \f$(votes, rho, theta)\f$. +The larger the value of 'votes', the higher the reliability of the Hough line. +@param lines_max Max count of hough lines. +@param threshold Accumulator threshold parameter. Only those lines are returned that get enough +votes ( \f$>\texttt{threshold}\f$ ) +@param min_rho Minimum Distance value of the accumulator in pixels. +@param max_rho Maximum Distance value of the accumulator in pixels. +@param rho_step Distance resolution of the accumulator in pixels. +@param min_theta Minimum angle value of the accumulator in radians. +@param max_theta Maximum angle value of the accumulator in radians. +@param theta_step Angle resolution of the accumulator in radians. + */ +CV_EXPORTS_W void HoughLinesPointSet( InputArray _point, OutputArray _lines, int lines_max, int threshold, + double min_rho, double max_rho, double rho_step, + double min_theta, double max_theta, double theta_step ); + +/** @example samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp +An example using the Hough circle detector +*/ + +/** @brief Finds circles in a grayscale image using the Hough transform. + +The function finds circles in a grayscale image using a modification of the Hough transform. + +Example: : +@include snippets/imgproc_HoughLinesCircles.cpp + +@note Usually the function detects the centers of circles well. However, it may fail to find correct +radii. You can assist to the function by specifying the radius range ( minRadius and maxRadius ) if +you know it. Or, you may set maxRadius to a negative number to return centers only without radius +search, and find the correct radius using an additional procedure. + +@param image 8-bit, single-channel, grayscale input image. +@param circles Output vector of found circles. Each vector is encoded as 3 or 4 element +floating-point vector \f$(x, y, radius)\f$ or \f$(x, y, radius, votes)\f$ . +@param method Detection method, see #HoughModes. Currently, the only implemented method is #HOUGH_GRADIENT +@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. +@param minDist Minimum distance between the centers of the detected circles. If the parameter is +too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is +too large, some circles may be missed. +@param param1 First method-specific parameter. In case of #HOUGH_GRADIENT , it is the higher +threshold of the two passed to the Canny edge detector (the lower one is twice smaller). +@param param2 Second method-specific parameter. In case of #HOUGH_GRADIENT , it is the +accumulator threshold for the circle centers at the detection stage. The smaller it is, the more +false circles may be detected. Circles, corresponding to the larger accumulator values, will be +returned first. +@param minRadius Minimum circle radius. +@param maxRadius Maximum circle radius. If <= 0, uses the maximum image dimension. If < 0, returns +centers without finding the radius. + +@sa fitEllipse, minEnclosingCircle + */ +CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles, + int method, double dp, double minDist, + double param1 = 100, double param2 = 100, + int minRadius = 0, int maxRadius = 0 ); + +//! @} imgproc_feature + +//! @addtogroup imgproc_filter +//! @{ + +/** @example samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp +Advanced morphology Transformations sample code +![Sample screenshot](Morphology_2_Tutorial_Result.jpg) +Check @ref tutorial_opening_closing_hats "the corresponding tutorial" for more details +*/ + +/** @brief Erodes an image by using a specific structuring element. + +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: + +\f[\texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f] + +The function supports the in-place mode. Erosion can be applied several ( iterations ) times. In +case of multi-channel images, each channel is processed independently. + +@param src input image; the number of channels can be arbitrary, but the depth should be one of +CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. +@param dst output image of the same size and type as src. +@param kernel structuring element used for erosion; if `element=Mat()`, a `3 x 3` rectangular +structuring element is used. Kernel can be created using #getStructuringElement. +@param anchor position of the anchor within the element; default value (-1, -1) means that the +anchor is at the element center. +@param iterations number of times erosion is applied. +@param borderType pixel extrapolation method, see #BorderTypes +@param borderValue border value in case of a constant border +@sa dilate, morphologyEx, getStructuringElement + */ +CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel, + Point anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue() ); + +/** @example samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp +Erosion and Dilation sample code +![Sample Screenshot-Erosion](Morphology_1_Tutorial_Erosion_Result.jpg)![Sample Screenshot-Dilation](Morphology_1_Tutorial_Dilation_Result.jpg) +Check @ref tutorial_erosion_dilatation "the corresponding tutorial" for more details +*/ + +/** @brief Dilates an image by using a specific structuring element. + +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: +\f[\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f] + +The function supports the in-place mode. Dilation can be applied several ( iterations ) times. In +case of multi-channel images, each channel is processed independently. + +@param src input image; the number of channels can be arbitrary, but the depth should be one of +CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. +@param dst output image of the same size and type as src. +@param kernel structuring element used for dilation; if elemenat=Mat(), a 3 x 3 rectangular +structuring element is used. Kernel can be created using #getStructuringElement +@param anchor position of the anchor within the element; default value (-1, -1) means that the +anchor is at the element center. +@param iterations number of times dilation is applied. +@param borderType pixel extrapolation method, see #BorderTypes +@param borderValue border value in case of a constant border +@sa erode, morphologyEx, getStructuringElement + */ +CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel, + Point anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue() ); + +/** @brief Performs advanced morphological transformations. + +The function cv::morphologyEx can perform advanced morphological transformations using an erosion and dilation as +basic operations. + +Any of the operations can be done in-place. In case of multi-channel images, each channel is +processed independently. + +@param src Source image. The number of channels can be arbitrary. The depth should be one of +CV_8U, CV_16U, CV_16S, CV_32F or CV_64F. +@param dst Destination image of the same size and type as source image. +@param op Type of a morphological operation, see #MorphTypes +@param kernel Structuring element. It can be created using #getStructuringElement. +@param anchor Anchor position with the kernel. Negative values mean that the anchor is at the +kernel center. +@param iterations Number of times erosion and dilation are applied. +@param borderType Pixel extrapolation method, see #BorderTypes +@param borderValue Border value in case of a constant border. The default value has a special +meaning. +@sa dilate, erode, getStructuringElement +@note The number of iterations is the number of times erosion or dilatation operation will be applied. +For instance, an opening operation (#MORPH_OPEN) with two iterations is equivalent to apply +successively: erode -> erode -> dilate -> dilate (and not erode -> dilate -> erode -> dilate). + */ +CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst, + int op, InputArray kernel, + Point anchor = Point(-1,-1), int iterations = 1, + int borderType = BORDER_CONSTANT, + const Scalar& borderValue = morphologyDefaultBorderValue() ); + +//! @} imgproc_filter + +//! @addtogroup imgproc_transform +//! @{ + +/** @brief Resizes an image. + +The function resize resizes the image src down to or up to the specified size. Note that the +initial dst type or size are not taken into account. Instead, the size and type are derived from +the `src`,`dsize`,`fx`, and `fy`. If you want to resize src so that it fits the pre-created dst, +you may call the function as follows: +@code + // explicitly specify dsize=dst.size(); fx and fy will be computed from that. + resize(src, dst, dst.size(), 0, 0, interpolation); +@endcode +If you want to decimate the image by factor of 2 in each direction, you can call the function this +way: +@code + // specify fx and fy and let the function compute the destination image size. + resize(src, dst, Size(), 0.5, 0.5, interpolation); +@endcode +To shrink an image, it will generally look best with #INTER_AREA interpolation, whereas to +enlarge an image, it will generally look best with c#INTER_CUBIC (slow) or #INTER_LINEAR +(faster but still looks OK). + +@param src input image. +@param dst output image; it has the size dsize (when it is non-zero) or the size computed from +src.size(), fx, and fy; the type of dst is the same as of src. +@param dsize output image size; if it equals zero, it is computed as: + \f[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\f] + Either dsize or both fx and fy must be non-zero. +@param fx scale factor along the horizontal axis; when it equals 0, it is computed as +\f[\texttt{(double)dsize.width/src.cols}\f] +@param fy scale factor along the vertical axis; when it equals 0, it is computed as +\f[\texttt{(double)dsize.height/src.rows}\f] +@param interpolation interpolation method, see #InterpolationFlags + +@sa warpAffine, warpPerspective, remap + */ +CV_EXPORTS_W void resize( InputArray src, OutputArray dst, + Size dsize, double fx = 0, double fy = 0, + int interpolation = INTER_LINEAR ); + +/** @brief Applies an affine transformation to an image. + +The function warpAffine transforms the source image using the specified matrix: + +\f[\texttt{dst} (x,y) = \texttt{src} ( \texttt{M} _{11} x + \texttt{M} _{12} y + \texttt{M} _{13}, \texttt{M} _{21} x + \texttt{M} _{22} y + \texttt{M} _{23})\f] + +when the flag #WARP_INVERSE_MAP is set. Otherwise, the transformation is first inverted +with #invertAffineTransform and then put in the formula above instead of M. The function cannot +operate in-place. + +@param src input image. +@param dst output image that has the size dsize and the same type as src . +@param M \f$2\times 3\f$ transformation matrix. +@param dsize size of the output image. +@param flags combination of interpolation methods (see #InterpolationFlags) and the optional +flag #WARP_INVERSE_MAP that means that M is the inverse transformation ( +\f$\texttt{dst}\rightarrow\texttt{src}\f$ ). +@param borderMode pixel extrapolation method (see #BorderTypes); when +borderMode=#BORDER_TRANSPARENT, it means that the pixels in the destination image corresponding to +the "outliers" in the source image are not modified by the function. +@param borderValue value used in case of a constant border; by default, it is 0. + +@sa warpPerspective, resize, remap, getRectSubPix, transform + */ +CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, + InputArray M, Size dsize, + int flags = INTER_LINEAR, + int borderMode = BORDER_CONSTANT, + const Scalar& borderValue = Scalar()); + +/** @example samples/cpp/warpPerspective_demo.cpp +An example program shows using cv::findHomography and cv::warpPerspective for image warping +*/ + +/** @brief Applies a perspective transformation to an image. + +The function warpPerspective transforms the source image using the specified matrix: + +\f[\texttt{dst} (x,y) = \texttt{src} \left ( \frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}} , + \frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}} \right )\f] + +when the flag #WARP_INVERSE_MAP is set. Otherwise, the transformation is first inverted with invert +and then put in the formula above instead of M. The function cannot operate in-place. + +@param src input image. +@param dst output image that has the size dsize and the same type as src . +@param M \f$3\times 3\f$ transformation matrix. +@param dsize size of the output image. +@param flags combination of interpolation methods (#INTER_LINEAR or #INTER_NEAREST) and the +optional flag #WARP_INVERSE_MAP, that sets M as the inverse transformation ( +\f$\texttt{dst}\rightarrow\texttt{src}\f$ ). +@param borderMode pixel extrapolation method (#BORDER_CONSTANT or #BORDER_REPLICATE). +@param borderValue value used in case of a constant border; by default, it equals 0. + +@sa warpAffine, resize, remap, getRectSubPix, perspectiveTransform + */ +CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst, + InputArray M, Size dsize, + int flags = INTER_LINEAR, + int borderMode = BORDER_CONSTANT, + const Scalar& borderValue = Scalar()); + +/** @brief Applies a generic geometrical transformation to an image. + +The function remap transforms the source image using the specified map: + +\f[\texttt{dst} (x,y) = \texttt{src} (map_x(x,y),map_y(x,y))\f] + +where values of pixels with non-integer coordinates are computed using one of available +interpolation methods. \f$map_x\f$ and \f$map_y\f$ can be encoded as separate floating-point maps +in \f$map_1\f$ and \f$map_2\f$ respectively, or interleaved floating-point maps of \f$(x,y)\f$ in +\f$map_1\f$, or fixed-point maps created by using convertMaps. The reason you might want to +convert from floating to fixed-point representations of a map is that they can yield much faster +(\~2x) remapping operations. In the converted case, \f$map_1\f$ contains pairs (cvFloor(x), +cvFloor(y)) and \f$map_2\f$ contains indices in a table of interpolation coefficients. + +This function cannot operate in-place. + +@param src Source image. +@param dst Destination image. It has the same size as map1 and the same type as src . +@param map1 The first map of either (x,y) points or just x values having the type CV_16SC2 , +CV_32FC1, or CV_32FC2. See convertMaps for details on converting a floating point +representation to fixed-point for speed. +@param map2 The second map of y values having the type CV_16UC1, CV_32FC1, or none (empty map +if map1 is (x,y) points), respectively. +@param interpolation Interpolation method (see #InterpolationFlags). The method #INTER_AREA is +not supported by this function. +@param borderMode Pixel extrapolation method (see #BorderTypes). When +borderMode=#BORDER_TRANSPARENT, it means that the pixels in the destination image that +corresponds to the "outliers" in the source image are not modified by the function. +@param borderValue Value used in case of a constant border. By default, it is 0. +@note +Due to current implementation limitations the size of an input and output images should be less than 32767x32767. + */ +CV_EXPORTS_W void remap( InputArray src, OutputArray dst, + InputArray map1, InputArray map2, + int interpolation, int borderMode = BORDER_CONSTANT, + const Scalar& borderValue = Scalar()); + +/** @brief Converts image transformation maps from one representation to another. + +The function converts a pair of maps for remap from one representation to another. The following +options ( (map1.type(), map2.type()) \f$\rightarrow\f$ (dstmap1.type(), dstmap2.type()) ) are +supported: + +- \f$\texttt{(CV_32FC1, CV_32FC1)} \rightarrow \texttt{(CV_16SC2, CV_16UC1)}\f$. This is the +most frequently used conversion operation, in which the original floating-point maps (see remap ) +are converted to a more compact and much faster fixed-point representation. The first output array +contains the rounded coordinates and the second array (created only when nninterpolation=false ) +contains indices in the interpolation tables. + +- \f$\texttt{(CV_32FC2)} \rightarrow \texttt{(CV_16SC2, CV_16UC1)}\f$. The same as above but +the original maps are stored in one 2-channel matrix. + +- Reverse conversion. Obviously, the reconstructed floating-point maps will not be exactly the same +as the originals. + +@param map1 The first input map of type CV_16SC2, CV_32FC1, or CV_32FC2 . +@param map2 The second input map of type CV_16UC1, CV_32FC1, or none (empty matrix), +respectively. +@param dstmap1 The first output map that has the type dstmap1type and the same size as src . +@param dstmap2 The second output map. +@param dstmap1type Type of the first output map that should be CV_16SC2, CV_32FC1, or +CV_32FC2 . +@param nninterpolation Flag indicating whether the fixed-point maps are used for the +nearest-neighbor or for a more complex interpolation. + +@sa remap, undistort, initUndistortRectifyMap + */ +CV_EXPORTS_W void convertMaps( InputArray map1, InputArray map2, + OutputArray dstmap1, OutputArray dstmap2, + int dstmap1type, bool nninterpolation = false ); + +/** @brief Calculates an affine matrix of 2D rotation. + +The function calculates the following matrix: + +\f[\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}\f] + +where + +\f[\begin{array}{l} \alpha = \texttt{scale} \cdot \cos \texttt{angle} , \\ \beta = \texttt{scale} \cdot \sin \texttt{angle} \end{array}\f] + +The transformation maps the rotation center to itself. If this is not the target, adjust the shift. + +@param center Center of the rotation in the source image. +@param angle 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. + +@sa getAffineTransform, warpAffine, transform + */ +CV_EXPORTS_W Mat getRotationMatrix2D( Point2f center, double angle, double scale ); + +/** @brief Calculates an affine transform from three pairs of the corresponding points. + +The function calculates the \f$2 \times 3\f$ matrix of an affine transform so that: + +\f[\begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f] + +where + +\f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2\f] + +@param src Coordinates of triangle vertices in the source image. +@param dst Coordinates of the corresponding triangle vertices in the destination image. + +@sa warpAffine, transform + */ +CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] ); + +/** @brief Inverts an affine transformation. + +The function computes an inverse affine transformation represented by \f$2 \times 3\f$ matrix M: + +\f[\begin{bmatrix} a_{11} & a_{12} & b_1 \\ a_{21} & a_{22} & b_2 \end{bmatrix}\f] + +The result is also a \f$2 \times 3\f$ matrix of the same type as M. + +@param M Original affine transformation. +@param iM Output reverse affine transformation. + */ +CV_EXPORTS_W void invertAffineTransform( InputArray M, OutputArray iM ); + +/** @brief Calculates a perspective transform from four pairs of the corresponding points. + +The function calculates the \f$3 \times 3\f$ matrix of a perspective transform so that: + +\f[\begin{bmatrix} t_i x'_i \\ t_i y'_i \\ t_i \end{bmatrix} = \texttt{map_matrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix}\f] + +where + +\f[dst(i)=(x'_i,y'_i), src(i)=(x_i, y_i), i=0,1,2,3\f] + +@param src Coordinates of quadrangle vertices in the source image. +@param dst Coordinates of the corresponding quadrangle vertices in the destination image. +@param solveMethod method passed to cv::solve (#DecompTypes) + +@sa findHomography, warpPerspective, perspectiveTransform + */ +CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU); + +/** @overload */ +CV_EXPORTS Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU); + + +CV_EXPORTS_W Mat getAffineTransform( InputArray src, InputArray dst ); + +/** @brief Retrieves a pixel rectangle from an image with sub-pixel accuracy. + +The function getRectSubPix extracts pixels from src: + +\f[patch(x, y) = src(x + \texttt{center.x} - ( \texttt{dst.cols} -1)*0.5, y + \texttt{center.y} - ( \texttt{dst.rows} -1)*0.5)\f] + +where the values of the pixels at non-integer coordinates are retrieved using bilinear +interpolation. Every channel of multi-channel images is processed independently. Also +the image should be a single channel or three channel image. While the center of the +rectangle must be inside the image, parts of the rectangle may be outside. + +@param image Source image. +@param patchSize Size of the extracted patch. +@param center Floating point coordinates of the center of the extracted rectangle within the +source image. The center must be inside the image. +@param patch Extracted patch that has the size patchSize and the same number of channels as src . +@param patchType Depth of the extracted pixels. By default, they have the same depth as src . + +@sa warpAffine, warpPerspective + */ +CV_EXPORTS_W void getRectSubPix( InputArray image, Size patchSize, + Point2f center, OutputArray patch, int patchType = -1 ); + +/** @example samples/cpp/polar_transforms.cpp +An example using the cv::linearPolar and cv::logPolar operations +*/ + +/** @brief Remaps an image to semilog-polar coordinates space. + +@deprecated This function produces same result as cv::warpPolar(src, dst, src.size(), center, maxRadius, flags+WARP_POLAR_LOG); + +@internal +Transform the source image using the following transformation (See @ref polar_remaps_reference_image "Polar remaps reference image d)"): +\f[\begin{array}{l} + dst( \rho , \phi ) = src(x,y) \\ + dst.size() \leftarrow src.size() +\end{array}\f] + +where +\f[\begin{array}{l} + I = (dx,dy) = (x - center.x,y - center.y) \\ + \rho = M \cdot log_e(\texttt{magnitude} (I)) ,\\ + \phi = Kangle \cdot \texttt{angle} (I) \\ +\end{array}\f] + +and +\f[\begin{array}{l} + M = src.cols / log_e(maxRadius) \\ + Kangle = src.rows / 2\Pi \\ +\end{array}\f] + +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. +@param src Source image +@param dst Destination image. It will have same size and type as src. +@param center The transformation center; where the output precision is maximal +@param M Magnitude scale parameter. It determines the radius of the bounding circle to transform too. +@param flags A combination of interpolation methods, see #InterpolationFlags + +@note +- The function can not operate in-place. +- To calculate magnitude and angle in degrees #cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees. + +@sa cv::linearPolar +@endinternal +*/ +CV_EXPORTS_W void logPolar( InputArray src, OutputArray dst, + Point2f center, double M, int flags ); + +/** @brief Remaps an image to polar coordinates space. + +@deprecated This function produces same result as cv::warpPolar(src, dst, src.size(), center, maxRadius, flags) + +@internal +Transform the source image using the following transformation (See @ref polar_remaps_reference_image "Polar remaps reference image c)"): +\f[\begin{array}{l} + dst( \rho , \phi ) = src(x,y) \\ + dst.size() \leftarrow src.size() +\end{array}\f] + +where +\f[\begin{array}{l} + I = (dx,dy) = (x - center.x,y - center.y) \\ + \rho = Kmag \cdot \texttt{magnitude} (I) ,\\ + \phi = angle \cdot \texttt{angle} (I) +\end{array}\f] + +and +\f[\begin{array}{l} + Kx = src.cols / maxRadius \\ + Ky = src.rows / 2\Pi +\end{array}\f] + + +@param src Source image +@param dst Destination image. It will have same size and type as src. +@param center The transformation center; +@param maxRadius The radius of the bounding circle to transform. It determines the inverse magnitude scale parameter too. +@param flags A combination of interpolation methods, see #InterpolationFlags + +@note +- The function can not operate in-place. +- To calculate magnitude and angle in degrees #cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees. + +@sa cv::logPolar +@endinternal +*/ +CV_EXPORTS_W void linearPolar( InputArray src, OutputArray dst, + Point2f center, double maxRadius, int flags ); + + +/** \brief Remaps an image to polar or semilog-polar coordinates space + +@anchor polar_remaps_reference_image +![Polar remaps reference](pics/polar_remap_doc.png) + +Transform the source image using the following transformation: +\f[ +dst(\rho , \phi ) = src(x,y) +\f] + +where +\f[ +\begin{array}{l} +\vec{I} = (x - center.x, \;y - center.y) \\ +\phi = Kangle \cdot \texttt{angle} (\vec{I}) \\ +\rho = \left\{\begin{matrix} +Klin \cdot \texttt{magnitude} (\vec{I}) & default \\ +Klog \cdot log_e(\texttt{magnitude} (\vec{I})) & if \; semilog \\ +\end{matrix}\right. +\end{array} +\f] + +and +\f[ +\begin{array}{l} +Kangle = dsize.height / 2\Pi \\ +Klin = dsize.width / maxRadius \\ +Klog = dsize.width / log_e(maxRadius) \\ +\end{array} +\f] + + +\par Linear vs semilog mapping + +Polar mapping can be linear or semi-log. Add one of #WarpPolarMode to `flags` to specify the polar mapping mode. + +Linear is the default mode. + +The semilog mapping emulates the human "foveal" vision that permit very high acuity on the line of sight (central vision) +in contrast to peripheral vision where acuity is minor. + +\par Option on `dsize`: + +- if both values in `dsize <=0 ` (default), +the destination image will have (almost) same area of source bounding circle: +\f[\begin{array}{l} +dsize.area \leftarrow (maxRadius^2 \cdot \Pi) \\ +dsize.width = \texttt{cvRound}(maxRadius) \\ +dsize.height = \texttt{cvRound}(maxRadius \cdot \Pi) \\ +\end{array}\f] + + +- if only `dsize.height <= 0`, +the destination image area will be proportional to the bounding circle area but scaled by `Kx * Kx`: +\f[\begin{array}{l} +dsize.height = \texttt{cvRound}(dsize.width \cdot \Pi) \\ +\end{array} +\f] + +- if both values in `dsize > 0 `, +the destination image will have the given size therefore the area of the bounding circle will be scaled to `dsize`. + + +\par Reverse mapping + +You can get reverse mapping adding #WARP_INVERSE_MAP to `flags` +\snippet polar_transforms.cpp InverseMap + +In addiction, to calculate the original coordinate from a polar mapped coordinate \f$(rho, phi)->(x, y)\f$: +\snippet polar_transforms.cpp InverseCoordinate + +@param src Source image. +@param dst Destination image. It will have same type as src. +@param dsize The destination image size (see description for valid options). +@param center The transformation center. +@param maxRadius The radius of the bounding circle to transform. It determines the inverse magnitude scale parameter too. +@param flags A combination of interpolation methods, #InterpolationFlags + #WarpPolarMode. + - Add #WARP_POLAR_LINEAR to select linear polar mapping (default) + - Add #WARP_POLAR_LOG to select semilog polar mapping + - Add #WARP_INVERSE_MAP for reverse mapping. +@note +- The function can not operate in-place. +- To calculate magnitude and angle in degrees #cartToPolar is used internally thus angles are measured from 0 to 360 with accuracy about 0.3 degrees. +- This function uses #remap. Due to current implementation limitations the size of an input and output images should be less than 32767x32767. + +@sa cv::remap +*/ +CV_EXPORTS_W void warpPolar(InputArray src, OutputArray dst, Size dsize, + Point2f center, double maxRadius, int flags); + + +//! @} imgproc_transform + +//! @addtogroup imgproc_misc +//! @{ + +/** @overload */ +CV_EXPORTS_W void integral( InputArray src, OutputArray sum, int sdepth = -1 ); + +/** @overload */ +CV_EXPORTS_AS(integral2) void integral( InputArray src, OutputArray sum, + OutputArray sqsum, int sdepth = -1, int sqdepth = -1 ); + +/** @brief Calculates the integral of an image. + +The function calculates one or more integral images for the source image as follows: + +\f[\texttt{sum} (X,Y) = \sum _{x + +Calculates the cross-power spectrum of two supplied source arrays. The arrays are padded if needed +with getOptimalDFTSize. + +The function performs the following equations: +- First it applies a Hanning window (see ) to each +image to remove possible edge effects. This window is cached until the array size changes to speed +up processing time. +- Next it computes the forward DFTs of each source array: +\f[\mathbf{G}_a = \mathcal{F}\{src_1\}, \; \mathbf{G}_b = \mathcal{F}\{src_2\}\f] +where \f$\mathcal{F}\f$ is the forward DFT. +- It then computes the cross-power spectrum of each frequency domain array: +\f[R = \frac{ \mathbf{G}_a \mathbf{G}_b^*}{|\mathbf{G}_a \mathbf{G}_b^*|}\f] +- Next the cross-correlation is converted back into the time domain via the inverse DFT: +\f[r = \mathcal{F}^{-1}\{R\}\f] +- Finally, it computes the peak location and computes a 5x5 weighted centroid around the peak to +achieve sub-pixel accuracy. +\f[(\Delta x, \Delta y) = \texttt{weightedCentroid} \{\arg \max_{(x, y)}\{r\}\}\f] +- If non-zero, the response parameter is computed as the sum of the elements of r within the 5x5 +centroid around the peak location. It is normalized to a maximum of 1 (meaning there is a single +peak) and will be smaller when there are multiple peaks. + +@param src1 Source floating point array (CV_32FC1 or CV_64FC1) +@param src2 Source floating point array (CV_32FC1 or CV_64FC1) +@param window Floating point array with windowing coefficients to reduce edge effects (optional). +@param response Signal power within the 5x5 centroid around the peak, between 0 and 1 (optional). +@returns detected phase shift (sub-pixel) between the two arrays. + +@sa dft, getOptimalDFTSize, idft, mulSpectrums createHanningWindow + */ +CV_EXPORTS_W Point2d phaseCorrelate(InputArray src1, InputArray src2, + InputArray window = noArray(), CV_OUT double* response = 0); + +/** @brief This function computes a Hanning window coefficients in two dimensions. + +See (http://en.wikipedia.org/wiki/Hann_function) and (http://en.wikipedia.org/wiki/Window_function) +for more information. + +An example is shown below: +@code + // create hanning window of size 100x100 and type CV_32F + Mat hann; + createHanningWindow(hann, Size(100, 100), CV_32F); +@endcode +@param dst Destination array to place Hann coefficients in +@param winSize The window size specifications (both width and height must be > 1) +@param type Created array type + */ +CV_EXPORTS_W void createHanningWindow(OutputArray dst, Size winSize, int type); + +//! @} imgproc_motion + +//! @addtogroup imgproc_misc +//! @{ + +/** @brief Applies a fixed-level threshold to each array element. + +The function applies fixed-level thresholding to a multiple-channel array. The function is typically +used to get a bi-level (binary) image out of a grayscale image ( #compare could be also used for +this purpose) or for removing a noise, that is, filtering out pixels with too small or too large +values. There are several types of thresholding supported by the function. They are determined by +type parameter. + +Also, the special values #THRESH_OTSU or #THRESH_TRIANGLE may be combined with one of the +above values. In these cases, the function determines the optimal threshold value using the Otsu's +or Triangle algorithm and uses it instead of the specified thresh. + +@note Currently, the Otsu's and Triangle methods are implemented only for 8-bit single-channel images. + +@param src input array (multiple-channel, 8-bit or 32-bit floating point). +@param dst output array of the same size and type and the same number of channels as src. +@param thresh threshold value. +@param maxval maximum value to use with the #THRESH_BINARY and #THRESH_BINARY_INV thresholding +types. +@param type thresholding type (see #ThresholdTypes). +@return the computed threshold value if Otsu's or Triangle methods used. + +@sa adaptiveThreshold, findContours, compare, min, max + */ +CV_EXPORTS_W double threshold( InputArray src, OutputArray dst, + double thresh, double maxval, int type ); + + +/** @brief Applies an adaptive threshold to an array. + +The function transforms a grayscale image to a binary image according to the formulae: +- **THRESH_BINARY** + \f[dst(x,y) = \fork{\texttt{maxValue}}{if \(src(x,y) > T(x,y)\)}{0}{otherwise}\f] +- **THRESH_BINARY_INV** + \f[dst(x,y) = \fork{0}{if \(src(x,y) > T(x,y)\)}{\texttt{maxValue}}{otherwise}\f] +where \f$T(x,y)\f$ is a threshold calculated individually for each pixel (see adaptiveMethod parameter). + +The function can process the image in-place. + +@param src Source 8-bit single-channel image. +@param dst Destination image of the same size and the same type as src. +@param maxValue Non-zero value assigned to the pixels for which the condition is satisfied +@param adaptiveMethod Adaptive thresholding algorithm to use, see #AdaptiveThresholdTypes. +The #BORDER_REPLICATE | #BORDER_ISOLATED is used to process boundaries. +@param thresholdType Thresholding type that must be either #THRESH_BINARY or #THRESH_BINARY_INV, +see #ThresholdTypes. +@param blockSize Size of a pixel neighborhood that is used to calculate a threshold value for the +pixel: 3, 5, 7, and so on. +@param C Constant subtracted from the mean or weighted mean (see the details below). Normally, it +is positive but may be zero or negative as well. + +@sa threshold, blur, GaussianBlur + */ +CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst, + double maxValue, int adaptiveMethod, + int thresholdType, int blockSize, double C ); + +//! @} imgproc_misc + +//! @addtogroup imgproc_filter +//! @{ + +/** @example samples/cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp +An example using pyrDown and pyrUp functions +*/ + +/** @brief Blurs an image and downsamples it. + +By default, size of the output image is computed as `Size((src.cols+1)/2, (src.rows+1)/2)`, but in +any case, the following conditions should be satisfied: + +\f[\begin{array}{l} | \texttt{dstsize.width} *2-src.cols| \leq 2 \\ | \texttt{dstsize.height} *2-src.rows| \leq 2 \end{array}\f] + +The function performs the downsampling step of the Gaussian pyramid construction. First, it +convolves the source image with the kernel: + +\f[\frac{1}{256} \begin{bmatrix} 1 & 4 & 6 & 4 & 1 \\ 4 & 16 & 24 & 16 & 4 \\ 6 & 24 & 36 & 24 & 6 \\ 4 & 16 & 24 & 16 & 4 \\ 1 & 4 & 6 & 4 & 1 \end{bmatrix}\f] + +Then, it downsamples the image by rejecting even rows and columns. + +@param src input image. +@param dst output image; it has the specified size and the same type as src. +@param dstsize size of the output image. +@param borderType Pixel extrapolation method, see #BorderTypes (#BORDER_CONSTANT isn't supported) + */ +CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst, + const Size& dstsize = Size(), int borderType = BORDER_DEFAULT ); + +/** @brief Upsamples an image and then blurs it. + +By default, size of the output image is computed as `Size(src.cols\*2, (src.rows\*2)`, but in any +case, the following conditions should be satisfied: + +\f[\begin{array}{l} | \texttt{dstsize.width} -src.cols*2| \leq ( \texttt{dstsize.width} \mod 2) \\ | \texttt{dstsize.height} -src.rows*2| \leq ( \texttt{dstsize.height} \mod 2) \end{array}\f] + +The function performs the upsampling step of the Gaussian pyramid construction, though it can +actually be used to construct the Laplacian pyramid. First, it upsamples the source image by +injecting even zero rows and columns and then convolves the result with the same kernel as in +pyrDown multiplied by 4. + +@param src input image. +@param dst output image. It has the specified size and the same type as src . +@param dstsize size of the output image. +@param borderType Pixel extrapolation method, see #BorderTypes (only #BORDER_DEFAULT is supported) + */ +CV_EXPORTS_W void pyrUp( InputArray src, OutputArray dst, + const Size& dstsize = Size(), int borderType = BORDER_DEFAULT ); + +/** @brief Constructs the Gaussian pyramid for an image. + +The function constructs a vector of images and builds the Gaussian pyramid by recursively applying +pyrDown to the previously built pyramid layers, starting from `dst[0]==src`. + +@param src Source image. Check pyrDown for the list of supported types. +@param dst Destination vector of maxlevel+1 images of the same type as src. dst[0] will be the +same as src. dst[1] is the next pyramid layer, a smoothed and down-sized src, and so on. +@param maxlevel 0-based index of the last (the smallest) pyramid layer. It must be non-negative. +@param borderType Pixel extrapolation method, see #BorderTypes (#BORDER_CONSTANT isn't supported) + */ +CV_EXPORTS void buildPyramid( InputArray src, OutputArrayOfArrays dst, + int maxlevel, int borderType = BORDER_DEFAULT ); + +//! @} imgproc_filter + +//! @addtogroup imgproc_hist +//! @{ + +/** @example samples/cpp/demhist.cpp +An example for creating histograms of an image +*/ + +/** @brief Calculates a histogram of a set of arrays. + +The function cv::calcHist calculates the histogram of one or more arrays. The elements of a tuple used +to increment a histogram bin are taken from the corresponding input arrays at the same location. The +sample below shows how to compute a 2D Hue-Saturation histogram for a color image. : +@include snippets/imgproc_calcHist.cpp + +@param images Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same +size. Each of them can have an arbitrary number of channels. +@param nimages Number of source images. +@param channels List of the dims channels used to compute the histogram. The first array channels +are numerated from 0 to images[0].channels()-1 , the second array channels are counted from +images[0].channels() to images[0].channels() + images[1].channels()-1, and so on. +@param mask Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size +as images[i] . The non-zero mask elements mark the array elements counted in the histogram. +@param hist Output histogram, which is a dense or sparse dims -dimensional array. +@param dims Histogram dimensionality that must be positive and not greater than CV_MAX_DIMS +(equal to 32 in the current OpenCV version). +@param histSize Array of histogram sizes in each dimension. +@param ranges Array of the dims arrays of the histogram bin boundaries in each dimension. When the +histogram is uniform ( uniform =true), then for each dimension i it is enough to specify the lower +(inclusive) boundary \f$L_0\f$ of the 0-th histogram bin and the upper (exclusive) boundary +\f$U_{\texttt{histSize}[i]-1}\f$ for the last histogram bin histSize[i]-1 . That is, in case of a +uniform histogram each of ranges[i] is an array of 2 elements. When the histogram is not uniform ( +uniform=false ), then each of ranges[i] contains histSize[i]+1 elements: +\f$L_0, U_0=L_1, U_1=L_2, ..., U_{\texttt{histSize[i]}-2}=L_{\texttt{histSize[i]}-1}, U_{\texttt{histSize[i]}-1}\f$ +. The array elements, that are not between \f$L_0\f$ and \f$U_{\texttt{histSize[i]}-1}\f$ , are not +counted in the histogram. +@param uniform Flag indicating whether the histogram is uniform or not (see above). +@param accumulate Accumulation flag. If it is set, the histogram is not cleared in the beginning +when it is allocated. This feature enables you to compute a single histogram from several sets of +arrays, or to update the histogram in time. +*/ +CV_EXPORTS void calcHist( const Mat* images, int nimages, + const int* channels, InputArray mask, + OutputArray hist, int dims, const int* histSize, + const float** ranges, bool uniform = true, bool accumulate = false ); + +/** @overload + +this variant uses %SparseMat for output +*/ +CV_EXPORTS void calcHist( const Mat* images, int nimages, + const int* channels, InputArray mask, + SparseMat& hist, int dims, + const int* histSize, const float** ranges, + bool uniform = true, bool accumulate = false ); + +/** @overload */ +CV_EXPORTS_W void calcHist( InputArrayOfArrays images, + const std::vector& channels, + InputArray mask, OutputArray hist, + const std::vector& histSize, + const std::vector& ranges, + bool accumulate = false ); + +/** @brief Calculates the back projection of a histogram. + +The function cv::calcBackProject calculates the back project of the histogram. That is, similarly to +#calcHist , at each location (x, y) the function collects the values from the selected channels +in the input images and finds the corresponding histogram bin. But instead of incrementing it, the +function reads the bin value, scales it by scale , and stores in backProject(x,y) . In terms of +statistics, the function computes probability of each element value in respect with the empirical +probability distribution represented by the histogram. See how, for example, you can find and track +a bright-colored object in a scene: + +- Before tracking, show the object to the camera so that it covers almost the whole frame. +Calculate a hue histogram. The histogram may have strong maximums, corresponding to the dominant +colors in the object. + +- When tracking, calculate a back projection of a hue plane of each input video frame using that +pre-computed histogram. Threshold the back projection to suppress weak colors. It may also make +sense to suppress pixels with non-sufficient color saturation and too dark or too bright pixels. + +- Find connected components in the resulting picture and choose, for example, the largest +component. + +This is an approximate algorithm of the CamShift color object tracker. + +@param images Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same +size. Each of them can have an arbitrary number of channels. +@param nimages Number of source images. +@param channels The list of channels used to compute the back projection. The number of channels +must match the histogram dimensionality. The first array channels are numerated from 0 to +images[0].channels()-1 , the second array channels are counted from images[0].channels() to +images[0].channels() + images[1].channels()-1, and so on. +@param hist Input histogram that can be dense or sparse. +@param backProject Destination back projection array that is a single-channel array of the same +size and depth as images[0] . +@param ranges Array of arrays of the histogram bin boundaries in each dimension. See #calcHist . +@param scale Optional scale factor for the output back projection. +@param uniform Flag indicating whether the histogram is uniform or not (see above). + +@sa calcHist, compareHist + */ +CV_EXPORTS void calcBackProject( const Mat* images, int nimages, + const int* channels, InputArray hist, + OutputArray backProject, const float** ranges, + double scale = 1, bool uniform = true ); + +/** @overload */ +CV_EXPORTS void calcBackProject( const Mat* images, int nimages, + const int* channels, const SparseMat& hist, + OutputArray backProject, const float** ranges, + double scale = 1, bool uniform = true ); + +/** @overload */ +CV_EXPORTS_W void calcBackProject( InputArrayOfArrays images, const std::vector& channels, + InputArray hist, OutputArray dst, + const std::vector& ranges, + double scale ); + +/** @brief Compares two histograms. + +The function cv::compareHist compares two dense or two sparse histograms using the specified method. + +The function returns \f$d(H_1, H_2)\f$ . + +While the function works well with 1-, 2-, 3-dimensional dense histograms, it may not be suitable +for high-dimensional sparse histograms. In such histograms, because of aliasing and sampling +problems, the coordinates of non-zero histogram bins can slightly shift. To compare such histograms +or more general sparse configurations of weighted points, consider using the #EMD function. + +@param H1 First compared histogram. +@param H2 Second compared histogram of the same size as H1 . +@param method Comparison method, see #HistCompMethods + */ +CV_EXPORTS_W double compareHist( InputArray H1, InputArray H2, int method ); + +/** @overload */ +CV_EXPORTS double compareHist( const SparseMat& H1, const SparseMat& H2, int method ); + +/** @brief Equalizes the histogram of a grayscale image. + +The function equalizes the histogram of the input image using the following algorithm: + +- Calculate the histogram \f$H\f$ for src . +- Normalize the histogram so that the sum of histogram bins is 255. +- Compute the integral of the histogram: +\f[H'_i = \sum _{0 \le j < i} H(j)\f] +- Transform the image using \f$H'\f$ as a look-up table: \f$\texttt{dst}(x,y) = H'(\texttt{src}(x,y))\f$ + +The algorithm normalizes the brightness and increases the contrast of the image. + +@param src Source 8-bit single channel image. +@param dst Destination image of the same size and type as src . + */ +CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst ); + +/** @brief Creates a smart pointer to a cv::CLAHE class and initializes it. + +@param clipLimit Threshold for contrast limiting. +@param tileGridSize Size of grid for histogram equalization. Input image will be divided into +equally sized rectangular tiles. tileGridSize defines the number of tiles in row and column. + */ +CV_EXPORTS_W Ptr createCLAHE(double clipLimit = 40.0, Size tileGridSize = Size(8, 8)); + +/** @brief Computes the "minimal work" distance between two weighted point configurations. + +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 @cite RubnerSept98, +@cite Rubner2000 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. + +@param signature1 First signature, a \f$\texttt{size1}\times \texttt{dims}+1\f$ 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. The weights must be +non-negative and have at least one non-zero value. +@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. The weights must be non-negative and have at least one non-zero +value. +@param distType Used metric. See #DistanceTypes. +@param cost User-defined \f$\texttt{size1}\times \texttt{size2}\f$ cost matrix. Also, if a cost matrix +is used, lower boundary lowerBound cannot be calculated because it needs a metric function. +@param lowerBound Optional input/output parameter: lower boundary of a 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 (the signature matrices have a single column). You +**must** initialize \*lowerBound . If the calculated distance between mass centers is greater or +equal to \*lowerBound (it means that the signatures are far enough), the function does not +calculate EMD. In any case \*lowerBound is set to the calculated distance between mass centers on +return. Thus, if you want to calculate both distance between mass centers and EMD, \*lowerBound +should be set to 0. +@param flow Resultant \f$\texttt{size1} \times \texttt{size2}\f$ flow matrix: \f$\texttt{flow}_{i,j}\f$ is +a flow from \f$i\f$ -th point of signature1 to \f$j\f$ -th point of signature2 . + */ +CV_EXPORTS float EMD( InputArray signature1, InputArray signature2, + int distType, InputArray cost=noArray(), + float* lowerBound = 0, OutputArray flow = noArray() ); + +CV_EXPORTS_AS(EMD) float wrapperEMD( InputArray signature1, InputArray signature2, + int distType, InputArray cost=noArray(), + CV_IN_OUT Ptr lowerBound = Ptr(), OutputArray flow = noArray() ); + +//! @} imgproc_hist + +/** @example samples/cpp/watershed.cpp +An example using the watershed algorithm +*/ + +/** @brief Performs a marker-based image segmentation using the watershed algorithm. + +The function implements one of the variants of watershed, non-parametric marker-based segmentation +algorithm, described in @cite Meyer92 . + +Before passing the image to the function, you have to roughly outline the desired regions in the +image markers with positive (\>0) indices. So, every region is represented as one or more connected +components with the pixel values 1, 2, 3, and so on. Such markers can be retrieved from a binary +mask using #findContours and #drawContours (see the watershed.cpp demo). The markers are "seeds" of +the future image regions. All the other pixels in markers , whose relation to the outlined regions +is not known and should be defined by the algorithm, should be set to 0's. In the function output, +each pixel in markers is set to a value of the "seed" components or to -1 at boundaries between the +regions. + +@note Any two neighbor connected components are not necessarily separated by a watershed boundary +(-1's pixels); for example, they can touch each other in the initial marker image passed to the +function. + +@param image Input 8-bit 3-channel image. +@param markers Input/output 32-bit single-channel image (map) of markers. It should have the same +size as image . + +@sa findContours + +@ingroup imgproc_misc + */ +CV_EXPORTS_W void watershed( InputArray image, InputOutputArray markers ); + +//! @addtogroup imgproc_filter +//! @{ + +/** @brief Performs initial step of meanshift segmentation of an image. + +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: + +\f[(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}\f] + +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: + +\f[(X,Y)~(X',Y'), (R,G,B)~(R',G',B').\f] + +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): + +\f[I(X,Y) <- (R*,G*,B*)\f] + +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). + +@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. + */ +CV_EXPORTS_W void pyrMeanShiftFiltering( InputArray src, OutputArray dst, + double sp, double sr, int maxLevel = 1, + TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) ); + +//! @} + +//! @addtogroup imgproc_misc +//! @{ + +/** @example samples/cpp/grabcut.cpp +An example using the GrabCut algorithm +![Sample Screenshot](grabcut_output1.jpg) +*/ + +/** @brief Runs the GrabCut algorithm. + +The function implements the [GrabCut image segmentation algorithm](http://en.wikipedia.org/wiki/GrabCut). + +@param img Input 8-bit 3-channel image. +@param mask Input/output 8-bit single-channel mask. The mask is initialized by the function when +mode is set to #GC_INIT_WITH_RECT. Its elements may have one of the #GrabCutClasses. +@param rect ROI containing a segmented object. The pixels outside of the ROI are marked as +"obvious background". The parameter is only used when mode==#GC_INIT_WITH_RECT . +@param bgdModel Temporary array for the background model. Do not modify it while you are +processing the same image. +@param fgdModel Temporary arrays for the foreground model. Do not modify it while you are +processing the same image. +@param iterCount Number of iterations the algorithm should make before returning the result. Note +that the result can be refined with further calls with mode==#GC_INIT_WITH_MASK or +mode==GC_EVAL . +@param mode Operation mode that could be one of the #GrabCutModes + */ +CV_EXPORTS_W void grabCut( InputArray img, InputOutputArray mask, Rect rect, + InputOutputArray bgdModel, InputOutputArray fgdModel, + int iterCount, int mode = GC_EVAL ); + +/** @example samples/cpp/distrans.cpp +An example on using the distance transform +*/ + +/** @brief Calculates the distance to the closest zero pixel for each pixel of the source image. + +The function cv::distanceTransform calculates 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 == #DIST_MASK_PRECISE and distanceType == #DIST_L2 , the function runs the +algorithm described in @cite Felzenszwalb04 . This algorithm is parallelized with the TBB library. + +In other cases, the algorithm @cite 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, vertical, +diagonal, or knight's move (the latest is available for a \f$5\times 5\f$ mask). The overall +distance is calculated as a sum of these basic distances. Since the distance function should be +symmetric, all of the horizontal and vertical shifts must have the same cost (denoted as a ), all +the diagonal shifts must have the same cost (denoted as `b`), and all knight's moves must have the +same cost (denoted as `c`). For the #DIST_C and #DIST_L1 types, the distance is calculated +precisely, whereas for #DIST_L2 (Euclidean distance) the distance can be calculated only with a +relative error (a \f$5\times 5\f$ mask gives more accurate results). For `a`,`b`, and `c`, OpenCV +uses the values suggested in the original paper: +- DIST_L1: `a = 1, b = 2` +- DIST_L2: + - `3 x 3`: `a=0.955, b=1.3693` + - `5 x 5`: `a=1, b=1.4, c=2.1969` +- DIST_C: `a = 1, b = 1` + +Typically, for a fast, coarse distance estimation #DIST_L2, a \f$3\times 3\f$ mask is used. For a +more accurate distance estimation #DIST_L2, a \f$5\times 5\f$ mask or the precise algorithm is used. +Note that both the precise and the approximate algorithms are linear on the number of pixels. + +This variant of the function does not only compute the minimum distance for each pixel \f$(x, y)\f$ +but also identifies the nearest connected component consisting of zero pixels +(labelType==#DIST_LABEL_CCOMP) or the nearest zero pixel (labelType==#DIST_LABEL_PIXEL). Index of the +component/pixel is stored in `labels(x, y)`. When labelType==#DIST_LABEL_CCOMP, the function +automatically finds connected components of zero pixels in the input image and marks them with +distinct labels. When labelType==#DIST_LABEL_CCOMP, the function scans through the input image and +marks all the zero pixels with distinct labels. + +In this mode, the complexity is still linear. That is, the function provides a very fast way to +compute the Voronoi diagram for a binary image. Currently, the second variant can use only the +approximate distance transform algorithm, i.e. maskSize=#DIST_MASK_PRECISE is not supported +yet. + +@param src 8-bit, single-channel (binary) source image. +@param dst Output image with calculated distances. It is a 8-bit or 32-bit floating-point, +single-channel image of the same size as src. +@param labels Output 2D array of labels (the discrete Voronoi diagram). It has the type +CV_32SC1 and the same size as src. +@param distanceType Type of distance, see #DistanceTypes +@param maskSize Size of the distance transform mask, see #DistanceTransformMasks. +#DIST_MASK_PRECISE is not supported by this variant. In case of the #DIST_L1 or #DIST_C distance type, +the parameter is forced to 3 because a \f$3\times 3\f$ mask gives the same result as \f$5\times +5\f$ or any larger aperture. +@param labelType Type of the label array to build, see #DistanceTransformLabelTypes. + */ +CV_EXPORTS_AS(distanceTransformWithLabels) void distanceTransform( InputArray src, OutputArray dst, + OutputArray labels, int distanceType, int maskSize, + int labelType = DIST_LABEL_CCOMP ); + +/** @overload +@param src 8-bit, single-channel (binary) source image. +@param dst Output image with calculated distances. It is a 8-bit or 32-bit floating-point, +single-channel image of the same size as src . +@param distanceType Type of distance, see #DistanceTypes +@param maskSize Size of the distance transform mask, see #DistanceTransformMasks. In case of the +#DIST_L1 or #DIST_C distance type, the parameter is forced to 3 because a \f$3\times 3\f$ mask gives +the same result as \f$5\times 5\f$ or any larger aperture. +@param dstType Type of output image. It can be CV_8U or CV_32F. Type CV_8U can be used only for +the first variant of the function and distanceType == #DIST_L1. +*/ +CV_EXPORTS_W void distanceTransform( InputArray src, OutputArray dst, + int distanceType, int maskSize, int dstType=CV_32F); + +/** @example samples/cpp/ffilldemo.cpp +An example using the FloodFill technique +*/ + +/** @overload + +variant without `mask` parameter +*/ +CV_EXPORTS int floodFill( InputOutputArray image, + Point seedPoint, Scalar newVal, CV_OUT Rect* rect = 0, + Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), + int flags = 4 ); + +/** @brief Fills a connected component with the given color. + +The function cv::floodFill fills a connected component starting from the seed point with the specified +color. The connectivity is determined by the color/brightness closeness of the neighbor pixels. The +pixel at \f$(x,y)\f$ is considered to belong to the repainted domain if: + +- in case of a grayscale image and floating range +\f[\texttt{src} (x',y')- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} (x',y')+ \texttt{upDiff}\f] + + +- in case of a grayscale image and fixed range +\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)+ \texttt{upDiff}\f] + + +- in case of a color image and floating range +\f[\texttt{src} (x',y')_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} (x',y')_r+ \texttt{upDiff} _r,\f] +\f[\texttt{src} (x',y')_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} (x',y')_g+ \texttt{upDiff} _g\f] +and +\f[\texttt{src} (x',y')_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} (x',y')_b+ \texttt{upDiff} _b\f] + + +- in case of a color image and fixed range +\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_r+ \texttt{upDiff} _r,\f] +\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_g+ \texttt{upDiff} _g\f] +and +\f[\texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} ( \texttt{seedPoint} .x, \texttt{seedPoint} .y)_b+ \texttt{upDiff} _b\f] + + +where \f$src(x',y')\f$ is the value of one of pixel neighbors that is already known to belong to the +component. That is, to be added to the connected component, a color/brightness of the pixel should +be close enough to: +- Color/brightness of one of its neighbors that already belong to the connected component in case +of a floating range. +- Color/brightness of the seed point in case of a fixed range. + +Use these functions to either mark a connected component with the specified color in-place, or build +a mask and then extract the contour, or copy the region to another image, and so on. + +@param image Input/output 1- or 3-channel, 8-bit, or floating-point image. It is modified by the +function unless the #FLOODFILL_MASK_ONLY flag is set in the second variant of the function. See +the details below. +@param mask Operation mask that should be a single-channel 8-bit image, 2 pixels wider and 2 pixels +taller than image. Since this is both an input and output parameter, you must take responsibility +of initializing it. Flood-filling cannot go across non-zero pixels in the input mask. For example, +an edge detector output can be used as a mask to stop filling at edges. On output, pixels in the +mask corresponding to filled pixels in the image are set to 1 or to the a value specified in flags +as described below. Additionally, the function fills the border of the mask with ones to simplify +internal processing. It is therefore possible to use the same mask in multiple calls to the function +to make sure the filled areas do not overlap. +@param seedPoint Starting point. +@param newVal New value of the repainted domain pixels. +@param loDiff 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. +@param upDiff 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. +@param rect Optional output parameter set by the function to the minimum bounding rectangle of the +repainted domain. +@param flags Operation flags. The first 8 bits contain a connectivity value. The default value of +4 means that only the four nearest neighbor pixels (those that share an edge) are considered. A +connectivity value of 8 means that the eight nearest neighbor pixels (those that share a corner) +will be considered. The next 8 bits (8-16) contain a value between 1 and 255 with which to fill +the mask (the default value is 1). For example, 4 | ( 255 \<\< 8 ) will consider 4 nearest +neighbours and fill the mask with a value of 255. The following additional options occupy higher +bits and therefore may be further combined with the connectivity and mask fill values using +bit-wise or (|), see #FloodFillFlags. + +@note Since the mask is larger than the filled image, a pixel \f$(x, y)\f$ in image corresponds to the +pixel \f$(x+1, y+1)\f$ in the mask . + +@sa findContours + */ +CV_EXPORTS_W int floodFill( InputOutputArray image, InputOutputArray mask, + Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0, + Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), + int flags = 4 ); + +//! Performs linear blending of two images: +//! \f[ \texttt{dst}(i,j) = \texttt{weights1}(i,j)*\texttt{src1}(i,j) + \texttt{weights2}(i,j)*\texttt{src2}(i,j) \f] +//! @param src1 It has a type of CV_8UC(n) or CV_32FC(n), where n is a positive integer. +//! @param src2 It has the same type and size as src1. +//! @param weights1 It has a type of CV_32FC1 and the same size with src1. +//! @param weights2 It has a type of CV_32FC1 and the same size with src1. +//! @param dst It is created if it does not have the same size and type with src1. +CV_EXPORTS void blendLinear(InputArray src1, InputArray src2, InputArray weights1, InputArray weights2, OutputArray dst); + +//! @} imgproc_misc + +//! @addtogroup imgproc_color_conversions +//! @{ + +/** @brief Converts an image from one color space to another. + +The function converts an input image from one color space to another. In case of a transformation +to-from RGB color space, the order of the channels should be specified explicitly (RGB or BGR). Note +that the default color format in OpenCV is often referred to as RGB but it is actually BGR (the +bytes are reversed). So the first byte in a standard (24-bit) color image will be an 8-bit Blue +component, the second byte will be Green, and the third byte will be Red. The fourth, fifth, and +sixth bytes would then be the second pixel (Blue, then Green, then Red), and so on. + +The conventional ranges for R, G, and B channel values are: +- 0 to 255 for CV_8U images +- 0 to 65535 for CV_16U images +- 0 to 1 for CV_32F images + +In case of linear transformations, the range does not matter. But in case of a non-linear +transformation, an input RGB image should be normalized to the proper value range to get the correct +results, for example, for RGB \f$\rightarrow\f$ L\*u\*v\* transformation. For example, if you have a +32-bit floating-point image directly converted from an 8-bit image without any scaling, then it will +have the 0..255 value range instead of 0..1 assumed by the function. So, before calling #cvtColor , +you need first to scale the image down: +@code + img *= 1./255; + cvtColor(img, img, COLOR_BGR2Luv); +@endcode +If you use #cvtColor with 8-bit images, the conversion will have some information lost. For many +applications, this will not be noticeable but it is recommended to use 32-bit images in applications +that need the full range of colors or that convert an image before an operation and then convert +back. + +If conversion adds the alpha channel, its value will set to the maximum of corresponding channel +range: 255 for CV_8U, 65535 for CV_16U, 1 for CV_32F. + +@param src input image: 8-bit unsigned, 16-bit unsigned ( CV_16UC... ), or single-precision +floating-point. +@param dst output image of the same size and depth as src. +@param code color space conversion code (see #ColorConversionCodes). +@param dstCn number of channels in the destination image; if the parameter is 0, the number of the +channels is derived automatically from src and code. + +@see @ref imgproc_color_conversions + */ +CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 ); + +/** @brief Converts an image from one color space to another where the source image is +stored in two planes. + +This function only supports YUV420 to RGB conversion as of now. + +@param src1: 8-bit image (#CV_8U) of the Y plane. +@param src2: image containing interleaved U/V plane. +@param dst: output image. +@param code: Specifies the type of conversion. It can take any of the following values: +- #COLOR_YUV2BGR_NV12 +- #COLOR_YUV2RGB_NV12 +- #COLOR_YUV2BGRA_NV12 +- #COLOR_YUV2RGBA_NV12 +- #COLOR_YUV2BGR_NV21 +- #COLOR_YUV2RGB_NV21 +- #COLOR_YUV2BGRA_NV21 +- #COLOR_YUV2RGBA_NV21 +*/ +CV_EXPORTS_W void cvtColorTwoPlane( InputArray src1, InputArray src2, OutputArray dst, int code ); + +/** @brief main function for all demosaicing processes + +@param src input image: 8-bit unsigned or 16-bit unsigned. +@param dst output image of the same size and depth as src. +@param code Color space conversion code (see the description below). +@param dstCn number of channels in the destination image; if the parameter is 0, the number of the +channels is derived automatically from src and code. + +The function can do the following transformations: + +- Demosaicing using bilinear interpolation + + #COLOR_BayerBG2BGR , #COLOR_BayerGB2BGR , #COLOR_BayerRG2BGR , #COLOR_BayerGR2BGR + + #COLOR_BayerBG2GRAY , #COLOR_BayerGB2GRAY , #COLOR_BayerRG2GRAY , #COLOR_BayerGR2GRAY + +- Demosaicing using Variable Number of Gradients. + + #COLOR_BayerBG2BGR_VNG , #COLOR_BayerGB2BGR_VNG , #COLOR_BayerRG2BGR_VNG , #COLOR_BayerGR2BGR_VNG + +- Edge-Aware Demosaicing. + + #COLOR_BayerBG2BGR_EA , #COLOR_BayerGB2BGR_EA , #COLOR_BayerRG2BGR_EA , #COLOR_BayerGR2BGR_EA + +- Demosaicing with alpha channel + + #COLOR_BayerBG2BGRA , #COLOR_BayerGB2BGRA , #COLOR_BayerRG2BGRA , #COLOR_BayerGR2BGRA + +@sa cvtColor +*/ +CV_EXPORTS_W void demosaicing(InputArray src, OutputArray dst, int code, int dstCn = 0); + +//! @} imgproc_color_conversions + +//! @addtogroup imgproc_shape +//! @{ + +/** @brief Calculates all of the moments up to the third order of a polygon or rasterized shape. + +The function computes moments, up to the 3rd order, of a vector shape or a rasterized shape. The +results are returned in the structure cv::Moments. + +@param array Raster image (single-channel, 8-bit or floating-point 2D array) or an array ( +\f$1 \times N\f$ or \f$N \times 1\f$ ) of 2D points (Point or Point2f ). +@param binaryImage If it is true, all non-zero image pixels are treated as 1's. The parameter is +used for images only. +@returns moments. + +@note Only applicable to contour moments calculations from Python bindings: Note that the numpy +type for the input array should be either np.int32 or np.float32. + +@sa contourArea, arcLength + */ +CV_EXPORTS_W Moments moments( InputArray array, bool binaryImage = false ); + +/** @brief Calculates seven Hu invariants. + +The function calculates seven Hu invariants (introduced in @cite Hu62; see also +) defined as: + +\f[\begin{array}{l} hu[0]= \eta _{20}+ \eta _{02} \\ hu[1]=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu[2]=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu[3]=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu[4]=( \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[5]=( \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[6]=(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}\f] + +where \f$\eta_{ji}\f$ stands for \f$\texttt{Moments::nu}_{ji}\f$ . + +These values are proved to be invariants to the image scale, rotation, and reflection except the +seventh one, whose sign is changed by reflection. This invariance is proved with the assumption of +infinite image resolution. In case of raster images, the computed Hu invariants for the original and +transformed images are a bit different. + +@param moments Input moments computed with moments . +@param hu Output Hu invariants. + +@sa matchShapes + */ +CV_EXPORTS void HuMoments( const Moments& moments, double hu[7] ); + +/** @overload */ +CV_EXPORTS_W void HuMoments( const Moments& m, OutputArray hu ); + +//! @} imgproc_shape + +//! @addtogroup imgproc_object +//! @{ + +//! type of the template matching operation +enum TemplateMatchModes { + TM_SQDIFF = 0, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f] + TM_SQDIFF_NORMED = 1, //!< \f[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}}\f] + TM_CCORR = 2, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y'))\f] + TM_CCORR_NORMED = 3, //!< \f[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}}\f] + TM_CCOEFF = 4, //!< \f[R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y'))\f] + //!< where + //!< \f[\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}\f] + TM_CCOEFF_NORMED = 5 //!< \f[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} }\f] +}; + +/** @example samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp +An example using Template Matching algorithm +*/ + +/** @brief Compares a template against overlapped image regions. + +The function slides through image , compares the overlapped patches of size \f$w \times h\f$ against +templ using the specified method and stores the comparison results in result . Here are the formulae +for the available comparison methods ( \f$I\f$ denotes image, \f$T\f$ template, \f$R\f$ result ). The summation +is done over template and/or the image patch: \f$x' = 0...w-1, y' = 0...h-1\f$ + +After the function finishes the comparison, the best matches can be found as global minimums (when +#TM_SQDIFF was used) or maximums (when #TM_CCORR or #TM_CCOEFF was used) using the +#minMaxLoc function. In 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. +That is, the function can take a color template and a color image. The result will still be a +single-channel image, which is easier to analyze. + +@param image Image where the search is running. It must be 8-bit or 32-bit floating-point. +@param templ Searched template. It must be not greater than the source image and have the same +data type. +@param result Map of comparison results. It must be single-channel 32-bit floating-point. If image +is \f$W \times H\f$ and templ is \f$w \times h\f$ , then result is \f$(W-w+1) \times (H-h+1)\f$ . +@param method Parameter specifying the comparison method, see #TemplateMatchModes +@param mask Mask of searched template. It must have the same datatype and size with templ. It is +not set by default. Currently, only the #TM_SQDIFF and #TM_CCORR_NORMED methods are supported. + */ +CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ, + OutputArray result, int method, InputArray mask = noArray() ); + +//! @} + +//! @addtogroup imgproc_shape +//! @{ + +/** @example samples/cpp/connected_components.cpp +This program demonstrates connected components and use of the trackbar +*/ + +/** @brief computes the connected components labeled image of boolean image + +image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0 +represents the background label. ltype specifies the output label image type, an important +consideration based on the total number of labels or alternatively the total number of pixels in +the source image. ccltype specifies the connected components labeling algorithm to use, currently +Grana (BBDT) and Wu's (SAUF) algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes +for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not. +This function uses parallel version of both Grana and Wu's algorithms if at least one allowed +parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs. + +@param image the 8-bit single-channel image to be labeled +@param labels destination labeled image +@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively +@param ltype output image label type. Currently CV_32S and CV_16U are supported. +@param ccltype connected components algorithm type (see the #ConnectedComponentsAlgorithmsTypes). +*/ +CV_EXPORTS_AS(connectedComponentsWithAlgorithm) int connectedComponents(InputArray image, OutputArray labels, + int connectivity, int ltype, int ccltype); + + +/** @overload + +@param image the 8-bit single-channel image to be labeled +@param labels destination labeled image +@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively +@param ltype output image label type. Currently CV_32S and CV_16U are supported. +*/ +CV_EXPORTS_W int connectedComponents(InputArray image, OutputArray labels, + int connectivity = 8, int ltype = CV_32S); + + +/** @brief computes the connected components labeled image of boolean image and also produces a statistics output for each label + +image with 4 or 8 way connectivity - returns N, the total number of labels [0, N-1] where 0 +represents the background label. ltype specifies the output label image type, an important +consideration based on the total number of labels or alternatively the total number of pixels in +the source image. ccltype specifies the connected components labeling algorithm to use, currently +Grana's (BBDT) and Wu's (SAUF) algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes +for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not. +This function uses parallel version of both Grana and Wu's algorithms (statistics included) if at least one allowed +parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs. + +@param image the 8-bit single-channel image to be labeled +@param labels destination labeled image +@param stats statistics output for each label, including the background label, see below for +available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of +#ConnectedComponentsTypes. The data type is CV_32S. +@param centroids centroid output for each label, including the background label. Centroids are +accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F. +@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively +@param ltype output image label type. Currently CV_32S and CV_16U are supported. +@param ccltype connected components algorithm type (see #ConnectedComponentsAlgorithmsTypes). +*/ +CV_EXPORTS_AS(connectedComponentsWithStatsWithAlgorithm) int connectedComponentsWithStats(InputArray image, OutputArray labels, + OutputArray stats, OutputArray centroids, + int connectivity, int ltype, int ccltype); + +/** @overload +@param image the 8-bit single-channel image to be labeled +@param labels destination labeled image +@param stats statistics output for each label, including the background label, see below for +available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of +#ConnectedComponentsTypes. The data type is CV_32S. +@param centroids centroid output for each label, including the background label. Centroids are +accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F. +@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively +@param ltype output image label type. Currently CV_32S and CV_16U are supported. +*/ +CV_EXPORTS_W int connectedComponentsWithStats(InputArray image, OutputArray labels, + OutputArray stats, OutputArray centroids, + int connectivity = 8, int ltype = CV_32S); + + +/** @brief Finds contours in a binary image. + +The function retrieves contours from the binary image using the algorithm @cite Suzuki85 . The contours +are a useful tool for shape analysis and object detection and recognition. See squares.cpp in the +OpenCV sample directory. +@note Since opencv 3.2 source image is not modified by this function. + +@param image Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero +pixels remain 0's, so the image is treated as binary . You can use #compare, #inRange, #threshold , +#adaptiveThreshold, #Canny, and others to create a binary image out of a grayscale or color one. +If mode equals to #RETR_CCOMP or #RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1). +@param contours Detected contours. Each contour is stored as a vector of points (e.g. +std::vector >). +@param hierarchy Optional output vector (e.g. std::vector), containing information about the image topology. It has +as many elements as the number of contours. For each i-th contour contours[i], the elements +hierarchy[i][0] , hierarchy[i][1] , hierarchy[i][2] , and hierarchy[i][3] are set to 0-based indices +in contours of the next and previous contours at the same hierarchical level, the first child +contour and the parent contour, respectively. If for the contour i there are no next, previous, +parent, or nested contours, the corresponding elements of hierarchy[i] will be negative. +@param mode Contour retrieval mode, see #RetrievalModes +@param method Contour approximation method, see #ContourApproximationModes +@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. + */ +CV_EXPORTS_W void findContours( InputArray image, OutputArrayOfArrays contours, + OutputArray hierarchy, int mode, + int method, Point offset = Point()); + +/** @overload */ +CV_EXPORTS void findContours( InputArray image, OutputArrayOfArrays contours, + int mode, int method, Point offset = Point()); + +/** @example samples/cpp/squares.cpp +A program using pyramid scaling, Canny, contours and contour simplification to find +squares in a list of images (pic1-6.png). Returns sequence of squares detected on the image. +*/ + +/** @example samples/tapi/squares.cpp +A program using pyramid scaling, Canny, contours and contour simplification to find +squares in the input image. +*/ + +/** @brief Approximates a polygonal curve(s) with the specified precision. + +The function cv::approxPolyDP approximates a curve or a polygon with another curve/polygon with less +vertices so that the distance between them is less or equal to the specified precision. It uses the +Douglas-Peucker algorithm + +@param curve Input vector of a 2D point stored in std::vector or Mat +@param approxCurve Result of the approximation. The type should match the type of the input curve. +@param epsilon Parameter specifying the approximation accuracy. This is the maximum distance +between the original curve and its approximation. +@param closed If true, the approximated curve is closed (its first and last vertices are +connected). Otherwise, it is not closed. + */ +CV_EXPORTS_W void approxPolyDP( InputArray curve, + OutputArray approxCurve, + double epsilon, bool closed ); + +/** @brief Calculates a contour perimeter or a curve length. + +The function computes a curve length or a closed contour perimeter. + +@param curve Input vector of 2D points, stored in std::vector or Mat. +@param closed Flag indicating whether the curve is closed or not. + */ +CV_EXPORTS_W double arcLength( InputArray curve, bool closed ); + +/** @brief Calculates the up-right bounding rectangle of a point set or non-zero pixels of gray-scale image. + +The function calculates and returns the minimal up-right bounding rectangle for the specified point set or +non-zero pixels of gray-scale image. + +@param array Input gray-scale image or 2D point set, stored in std::vector or Mat. + */ +CV_EXPORTS_W Rect boundingRect( InputArray array ); + +/** @brief Calculates a contour area. + +The function computes a contour area. Similarly to moments , the area is computed using the Green +formula. Thus, the returned area and the number of non-zero pixels, if you draw the contour using +#drawContours or #fillPoly , can be different. Also, the function will most certainly give a wrong +results for contours with self-intersections. + +Example: +@code + vector contour; + contour.push_back(Point2f(0, 0)); + contour.push_back(Point2f(10, 0)); + contour.push_back(Point2f(10, 10)); + contour.push_back(Point2f(5, 4)); + + double area0 = contourArea(contour); + vector approx; + approxPolyDP(contour, approx, 5, true); + double area1 = contourArea(approx); + + cout << "area0 =" << area0 << endl << + "area1 =" << area1 << endl << + "approx poly vertices" << approx.size() << endl; +@endcode +@param contour Input vector of 2D points (contour vertices), stored in std::vector or Mat. +@param oriented Oriented area flag. If it is true, the function returns a signed area value, +depending on the contour orientation (clockwise or counter-clockwise). Using this feature you can +determine orientation of a contour by taking the sign of an area. By default, the parameter is +false, which means that the absolute value is returned. + */ +CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false ); + +/** @brief Finds a rotated rectangle of the minimum area enclosing the input 2D point set. + +The function calculates and returns the minimum-area bounding rectangle (possibly rotated) for a +specified point set. Developer should keep in mind that the returned RotatedRect can contain negative +indices when data is close to the containing Mat element boundary. + +@param points Input vector of 2D points, stored in std::vector\<\> or Mat + */ +CV_EXPORTS_W RotatedRect minAreaRect( InputArray points ); + +/** @brief Finds the four vertices of a rotated rect. Useful to draw the rotated rectangle. + +The function finds the four vertices of a rotated rectangle. This function is useful to draw the +rectangle. In C++, instead of using this function, you can directly use RotatedRect::points method. Please +visit the @ref tutorial_bounding_rotated_ellipses "tutorial on Creating Bounding rotated boxes and ellipses for contours" for more information. + +@param box The input rotated rectangle. It may be the output of +@param points The output array of four vertices of rectangles. + */ +CV_EXPORTS_W void boxPoints(RotatedRect box, OutputArray points); + +/** @brief Finds a circle of the minimum area enclosing a 2D point set. + +The function finds the minimal enclosing circle of a 2D point set using an iterative algorithm. + +@param points Input vector of 2D points, stored in std::vector\<\> or Mat +@param center Output center of the circle. +@param radius Output radius of the circle. + */ +CV_EXPORTS_W void minEnclosingCircle( InputArray points, + CV_OUT Point2f& center, CV_OUT float& radius ); + +/** @example samples/cpp/minarea.cpp +*/ + +/** @brief Finds a triangle of minimum area enclosing a 2D point set and returns its area. + +The function finds a triangle of minimum area enclosing the given set of 2D points and returns its +area. The output for a given 2D point set is shown in the image below. 2D points are depicted in +*red* and the enclosing triangle in *yellow*. + +![Sample output of the minimum enclosing triangle function](pics/minenclosingtriangle.png) + +The implementation of the algorithm is based on O'Rourke's @cite ORourke86 and Klee and Laskowski's +@cite KleeLaskowski85 papers. O'Rourke provides a \f$\theta(n)\f$ algorithm for finding the minimal +enclosing triangle of a 2D convex polygon with n vertices. Since the #minEnclosingTriangle function +takes a 2D point set as input an additional preprocessing step of computing the convex hull of the +2D point set is required. The complexity of the #convexHull function is \f$O(n log(n))\f$ which is higher +than \f$\theta(n)\f$. Thus the overall complexity of the function is \f$O(n log(n))\f$. + +@param points Input vector of 2D points with depth CV_32S or CV_32F, stored in std::vector\<\> or Mat +@param triangle Output vector of three 2D points defining the vertices of the triangle. The depth +of the OutputArray must be CV_32F. + */ +CV_EXPORTS_W double minEnclosingTriangle( InputArray points, CV_OUT OutputArray triangle ); + +/** @brief Compares two shapes. + +The function compares two shapes. All three implemented methods use the Hu invariants (see #HuMoments) + +@param contour1 First contour or grayscale image. +@param contour2 Second contour or grayscale image. +@param method Comparison method, see #ShapeMatchModes +@param parameter Method-specific parameter (not supported now). + */ +CV_EXPORTS_W double matchShapes( InputArray contour1, InputArray contour2, + int method, double parameter ); + +/** @example samples/cpp/convexhull.cpp +An example using the convexHull functionality +*/ + +/** @brief Finds the convex hull of a point set. + +The function cv::convexHull finds the convex hull of a 2D point set using the Sklansky's algorithm @cite Sklansky82 +that has *O(N logN)* complexity in the current implementation. + +@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 are the convex hull points themselves. +@param clockwise Orientation flag. If it is true, the output convex hull is oriented clockwise. +Otherwise, it is oriented counter-clockwise. The assumed coordinate system has its X axis pointing +to the right, and its Y axis pointing upwards. +@param returnPoints Operation flag. In case of a matrix, when the flag is true, the function +returns convex hull points. Otherwise, it returns 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=false, std::vector\ implies +returnPoints=true. + +@note `points` and `hull` should be different arrays, inplace processing isn't supported. + +Check @ref tutorial_hull "the corresponding tutorial" for more details. + +useful links: + +https://www.learnopencv.com/convex-hull-using-opencv-in-python-and-c/ + */ +CV_EXPORTS_W void convexHull( InputArray points, OutputArray hull, + bool clockwise = false, bool returnPoints = true ); + +/** @brief Finds the convexity defects of a contour. + +The figure below displays convexity defects of a hand contour: + +![image](pics/defects.png) + +@param contour Input contour. +@param convexhull Convex hull obtained using convexHull that should contain indices of the contour +points that make the hull. +@param convexityDefects The output vector of convexity defects. In C++ and the new Python/Java +interface each convexity defect is represented as 4-element integer vector (a.k.a. #Vec4i): +(start_index, end_index, farthest_pt_index, fixpt_depth), where indices are 0-based indices +in the original contour of the convexity defect beginning, end and the farthest point, and +fixpt_depth is fixed-point approximation (with 8 fractional bits) of the distance between the +farthest contour point and the hull. That is, to get the floating-point value of the depth will be +fixpt_depth/256.0. + */ +CV_EXPORTS_W void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects ); + +/** @brief Tests a contour convexity. + +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. + +@param contour Input vector of 2D points, stored in std::vector\<\> or Mat + */ +CV_EXPORTS_W bool isContourConvex( InputArray contour ); + +//! finds intersection of two convex polygons +CV_EXPORTS_W float intersectConvexConvex( InputArray _p1, InputArray _p2, + OutputArray _p12, bool handleNested = true ); + +/** @example samples/cpp/fitellipse.cpp +An example using the fitEllipse technique +*/ + +/** @brief Fits an ellipse around a set of 2D points. + +The function calculates the ellipse that fits (in a least-squares sense) a set of 2D points best of +all. It returns the rotated rectangle in which the ellipse is inscribed. The first algorithm described by @cite Fitzgibbon95 +is used. Developer should keep in mind that it is possible that the returned +ellipse/rotatedRect data contains negative indices, due to the data points being close to the +border of the containing Mat element. + +@param points Input 2D point set, stored in std::vector\<\> or Mat + */ +CV_EXPORTS_W RotatedRect fitEllipse( InputArray points ); + +/** @brief Fits an ellipse around a set of 2D points. + + The function calculates the ellipse that fits a set of 2D points. + It returns the rotated rectangle in which the ellipse is inscribed. + The Approximate Mean Square (AMS) proposed by @cite Taubin1991 is used. + + For an ellipse, this basis set is \f$ \chi= \left(x^2, x y, y^2, x, y, 1\right) \f$, + which is a set of six free coefficients \f$ A^T=\left\{A_{\text{xx}},A_{\text{xy}},A_{\text{yy}},A_x,A_y,A_0\right\} \f$. + However, to specify an ellipse, all that is needed is five numbers; the major and minor axes lengths \f$ (a,b) \f$, + the position \f$ (x_0,y_0) \f$, and the orientation \f$ \theta \f$. This is because the basis set includes lines, + quadratics, parabolic and hyperbolic functions as well as elliptical functions as possible fits. + If the fit is found to be a parabolic or hyperbolic function then the standard #fitEllipse method is used. + The AMS method restricts the fit to parabolic, hyperbolic and elliptical curves + by imposing the condition that \f$ A^T ( D_x^T D_x + D_y^T D_y) A = 1 \f$ where + the matrices \f$ Dx \f$ and \f$ Dy \f$ are the partial derivatives of the design matrix \f$ D \f$ with + respect to x and y. The matrices are formed row by row applying the following to + each of the points in the set: + \f{align*}{ + D(i,:)&=\left\{x_i^2, x_i y_i, y_i^2, x_i, y_i, 1\right\} & + D_x(i,:)&=\left\{2 x_i,y_i,0,1,0,0\right\} & + D_y(i,:)&=\left\{0,x_i,2 y_i,0,1,0\right\} + \f} + The AMS method minimizes the cost function + \f{equation*}{ + \epsilon ^2=\frac{ A^T D^T D A }{ A^T (D_x^T D_x + D_y^T D_y) A^T } + \f} + + The minimum cost is found by solving the generalized eigenvalue problem. + + \f{equation*}{ + D^T D A = \lambda \left( D_x^T D_x + D_y^T D_y\right) A + \f} + + @param points Input 2D point set, stored in std::vector\<\> or Mat + */ +CV_EXPORTS_W RotatedRect fitEllipseAMS( InputArray points ); + + +/** @brief Fits an ellipse around a set of 2D points. + + The function calculates the ellipse that fits a set of 2D points. + It returns the rotated rectangle in which the ellipse is inscribed. + The Direct least square (Direct) method by @cite Fitzgibbon1999 is used. + + For an ellipse, this basis set is \f$ \chi= \left(x^2, x y, y^2, x, y, 1\right) \f$, + which is a set of six free coefficients \f$ A^T=\left\{A_{\text{xx}},A_{\text{xy}},A_{\text{yy}},A_x,A_y,A_0\right\} \f$. + However, to specify an ellipse, all that is needed is five numbers; the major and minor axes lengths \f$ (a,b) \f$, + the position \f$ (x_0,y_0) \f$, and the orientation \f$ \theta \f$. This is because the basis set includes lines, + quadratics, parabolic and hyperbolic functions as well as elliptical functions as possible fits. + The Direct method confines the fit to ellipses by ensuring that \f$ 4 A_{xx} A_{yy}- A_{xy}^2 > 0 \f$. + The condition imposed is that \f$ 4 A_{xx} A_{yy}- A_{xy}^2=1 \f$ which satisfies the inequality + and as the coefficients can be arbitrarily scaled is not overly restrictive. + + \f{equation*}{ + \epsilon ^2= A^T D^T D A \quad \text{with} \quad A^T C A =1 \quad \text{and} \quad C=\left(\begin{matrix} + 0 & 0 & 2 & 0 & 0 & 0 \\ + 0 & -1 & 0 & 0 & 0 & 0 \\ + 2 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 & 0 + \end{matrix} \right) + \f} + + The minimum cost is found by solving the generalized eigenvalue problem. + + \f{equation*}{ + D^T D A = \lambda \left( C\right) A + \f} + + The system produces only one positive eigenvalue \f$ \lambda\f$ which is chosen as the solution + with its eigenvector \f$\mathbf{u}\f$. These are used to find the coefficients + + \f{equation*}{ + A = \sqrt{\frac{1}{\mathbf{u}^T C \mathbf{u}}} \mathbf{u} + \f} + The scaling factor guarantees that \f$A^T C A =1\f$. + + @param points Input 2D point set, stored in std::vector\<\> or Mat + */ +CV_EXPORTS_W RotatedRect fitEllipseDirect( InputArray points ); + +/** @brief Fits a line to a 2D or 3D point set. + +The function fitLine fits a line to a 2D or 3D point set by minimizing \f$\sum_i \rho(r_i)\f$ where +\f$r_i\f$ is a distance between the \f$i^{th}\f$ point, the line and \f$\rho(r)\f$ is a distance function, one +of the following: +- DIST_L2 +\f[\rho (r) = r^2/2 \quad \text{(the simplest and the fastest least-squares method)}\f] +- DIST_L1 +\f[\rho (r) = r\f] +- DIST_L12 +\f[\rho (r) = 2 \cdot ( \sqrt{1 + \frac{r^2}{2}} - 1)\f] +- DIST_FAIR +\f[\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\f] +- DIST_WELSCH +\f[\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\f] +- DIST_HUBER +\f[\rho (r) = \fork{r^2/2}{if \(r < C\)}{C \cdot (r-C/2)}{otherwise} \quad \text{where} \quad C=1.345\f] + +The algorithm is based on the M-estimator ( ) technique +that iteratively fits the line using the weighted least-squares algorithm. After each iteration the +weights \f$w_i\f$ are adjusted to be inversely proportional to \f$\rho(r_i)\f$ . + +@param points Input vector of 2D or 3D points, stored in std::vector\<\> or Mat. +@param line Output line parameters. In case of 2D fitting, it should be a vector of 4 elements +(like Vec4f) - (vx, vy, x0, y0), where (vx, vy) is a normalized vector collinear to the line and +(x0, y0) is a point on the line. In case of 3D fitting, it should be a vector of 6 elements (like +Vec6f) - (vx, vy, vz, x0, y0, z0), where (vx, vy, vz) is a normalized vector collinear to the line +and (x0, y0, z0) is a point on the line. +@param distType Distance used by the M-estimator, see #DistanceTypes +@param param Numerical parameter ( C ) for some types of distances. If it is 0, an optimal value +is chosen. +@param reps Sufficient accuracy for the radius (distance between the coordinate origin and the line). +@param aeps Sufficient accuracy for the angle. 0.01 would be a good default value for reps and aeps. + */ +CV_EXPORTS_W void fitLine( InputArray points, OutputArray line, int distType, + double param, double reps, double aeps ); + +/** @brief Performs a point-in-contour test. + +The function determines whether the point is inside a contour, outside, or lies on an edge (or +coincides with a vertex). It returns positive (inside), negative (outside), or zero (on an edge) +value, correspondingly. When measureDist=false , the return value is +1, -1, and 0, respectively. +Otherwise, the return value is a signed distance between the point and the nearest contour edge. + +See below a sample output of the function where each image pixel is tested against the contour: + +![sample output](pics/pointpolygon.png) + +@param contour Input contour. +@param pt Point tested against the contour. +@param measureDist If true, the function estimates the signed distance from the point to the +nearest contour edge. Otherwise, the function only checks if the point is inside a contour or not. + */ +CV_EXPORTS_W double pointPolygonTest( InputArray contour, Point2f pt, bool measureDist ); + +/** @brief Finds out if there is any intersection between two rotated rectangles. + +If there is then the vertices of the intersecting region are returned as well. + +Below are some examples of intersection configurations. The hatched pattern indicates the +intersecting region and the red vertices are returned by the function. + +![intersection examples](pics/intersection.png) + +@param rect1 First rectangle +@param rect2 Second rectangle +@param intersectingRegion The output array of the vertices of the intersecting region. It returns +at most 8 vertices. Stored as std::vector\ or cv::Mat as Mx1 of type CV_32FC2. +@returns One of #RectanglesIntersectTypes + */ +CV_EXPORTS_W int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion ); + +/** @brief Creates a smart pointer to a cv::GeneralizedHoughBallard class and initializes it. +*/ +CV_EXPORTS_W Ptr createGeneralizedHoughBallard(); + +/** @brief Creates a smart pointer to a cv::GeneralizedHoughGuil class and initializes it. +*/ +CV_EXPORTS_W Ptr createGeneralizedHoughGuil(); + +//! @} imgproc_shape + +//! @addtogroup imgproc_colormap +//! @{ + +//! GNU Octave/MATLAB equivalent colormaps +enum ColormapTypes +{ + COLORMAP_AUTUMN = 0, //!< ![autumn](pics/colormaps/colorscale_autumn.jpg) + COLORMAP_BONE = 1, //!< ![bone](pics/colormaps/colorscale_bone.jpg) + COLORMAP_JET = 2, //!< ![jet](pics/colormaps/colorscale_jet.jpg) + COLORMAP_WINTER = 3, //!< ![winter](pics/colormaps/colorscale_winter.jpg) + COLORMAP_RAINBOW = 4, //!< ![rainbow](pics/colormaps/colorscale_rainbow.jpg) + COLORMAP_OCEAN = 5, //!< ![ocean](pics/colormaps/colorscale_ocean.jpg) + COLORMAP_SUMMER = 6, //!< ![summer](pics/colormaps/colorscale_summer.jpg) + COLORMAP_SPRING = 7, //!< ![spring](pics/colormaps/colorscale_spring.jpg) + COLORMAP_COOL = 8, //!< ![cool](pics/colormaps/colorscale_cool.jpg) + COLORMAP_HSV = 9, //!< ![HSV](pics/colormaps/colorscale_hsv.jpg) + COLORMAP_PINK = 10, //!< ![pink](pics/colormaps/colorscale_pink.jpg) + COLORMAP_HOT = 11, //!< ![hot](pics/colormaps/colorscale_hot.jpg) + COLORMAP_PARULA = 12, //!< ![parula](pics/colormaps/colorscale_parula.jpg) + COLORMAP_MAGMA = 13, //!< ![magma](pics/colormaps/colorscale_magma.jpg) + COLORMAP_INFERNO = 14, //!< ![inferno](pics/colormaps/colorscale_inferno.jpg) + COLORMAP_PLASMA = 15, //!< ![plasma](pics/colormaps/colorscale_plasma.jpg) + COLORMAP_VIRIDIS = 16, //!< ![viridis](pics/colormaps/colorscale_viridis.jpg) + COLORMAP_CIVIDIS = 17, //!< ![cividis](pics/colormaps/colorscale_cividis.jpg) + COLORMAP_TWILIGHT = 18, //!< ![twilight](pics/colormaps/colorscale_twilight.jpg) + COLORMAP_TWILIGHT_SHIFTED = 19 //!< ![twilight shifted](pics/colormaps/colorscale_twilight_shifted.jpg) +}; + +/** @example samples/cpp/falsecolor.cpp +An example using applyColorMap function +*/ + +/** @brief Applies a GNU Octave/MATLAB equivalent colormap on a given image. + +@param src The source image, grayscale or colored of type CV_8UC1 or CV_8UC3. +@param dst The result is the colormapped source image. Note: Mat::create is called on dst. +@param colormap The colormap to apply, see #ColormapTypes +*/ +CV_EXPORTS_W void applyColorMap(InputArray src, OutputArray dst, int colormap); + +/** @brief Applies a user colormap on a given image. + +@param src The source image, grayscale or colored of type CV_8UC1 or CV_8UC3. +@param dst The result is the colormapped source image. Note: Mat::create is called on dst. +@param userColor The colormap to apply of type CV_8UC1 or CV_8UC3 and size 256 +*/ +CV_EXPORTS_W void applyColorMap(InputArray src, OutputArray dst, InputArray userColor); + +//! @} imgproc_colormap + +//! @addtogroup imgproc_draw +//! @{ + + +/** OpenCV color channel order is BGR[A] */ +#define CV_RGB(r, g, b) cv::Scalar((b), (g), (r), 0) + +/** @brief Draws a line segment connecting two points. + +The function line draws the line segment between pt1 and pt2 points in the image. The line is +clipped by the image boundaries. 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. + +@param img 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. See #LineTypes. +@param shift Number of fractional bits in the point coordinates. + */ +CV_EXPORTS_W void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, + int thickness = 1, int lineType = LINE_8, int shift = 0); + +/** @brief Draws a arrow segment pointing from the first point to the second one. + +The function cv::arrowedLine draws an arrow between pt1 and pt2 points in the image. See also #line. + +@param img Image. +@param pt1 The point the arrow starts from. +@param pt2 The point the arrow points to. +@param color Line color. +@param thickness Line thickness. +@param line_type Type of the line. See #LineTypes +@param shift Number of fractional bits in the point coordinates. +@param tipLength The length of the arrow tip in relation to the arrow length + */ +CV_EXPORTS_W void arrowedLine(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, + int thickness=1, int line_type=8, int shift=0, double tipLength=0.1); + +/** @brief Draws a simple, thick, or filled up-right rectangle. + +The function cv::rectangle draws a rectangle outline or a filled rectangle whose two opposite corners +are pt1 and pt2. + +@param img Image. +@param pt1 Vertex of the rectangle. +@param pt2 Vertex of the rectangle opposite to pt1 . +@param color Rectangle color or brightness (grayscale image). +@param thickness Thickness of lines that make up the rectangle. Negative values, like #FILLED, +mean that the function has to draw a filled rectangle. +@param lineType Type of the line. See #LineTypes +@param shift Number of fractional bits in the point coordinates. + */ +CV_EXPORTS_W void rectangle(InputOutputArray img, Point pt1, Point pt2, + const Scalar& color, int thickness = 1, + int lineType = LINE_8, int shift = 0); + +/** @overload + +use `rec` parameter as alternative specification of the drawn rectangle: `r.tl() and +r.br()-Point(1,1)` are opposite corners +*/ +CV_EXPORTS_W void rectangle(InputOutputArray img, Rect rec, + const Scalar& color, int thickness = 1, + int lineType = LINE_8, int shift = 0); + +/** @example samples/cpp/tutorial_code/ImgProc/basic_drawing/Drawing_2.cpp +An example using drawing functions +*/ + +/** @brief Draws a circle. + +The function cv::circle draws a simple or filled circle with a given center and radius. +@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. Negative values, like #FILLED, +mean that a filled circle is to be drawn. +@param lineType Type of the circle boundary. See #LineTypes +@param shift Number of fractional bits in the coordinates of the center and in the radius value. + */ +CV_EXPORTS_W void circle(InputOutputArray img, Point center, int radius, + const Scalar& color, int thickness = 1, + int lineType = LINE_8, int shift = 0); + +/** @brief Draws a simple or thick elliptic arc or fills an ellipse sector. + +The function cv::ellipse with more parameters draws an ellipse outline, a filled ellipse, an elliptic +arc, or a filled ellipse sector. The drawing code uses general parametric form. +A piecewise-linear curve is used to approximate the elliptic arc +boundary. If you need more control of the ellipse rendering, you can retrieve the curve using +#ellipse2Poly and then render it with #polylines or fill it with #fillPoly. If you use the first +variant of the function and want to draw the whole ellipse, not an arc, pass `startAngle=0` and +`endAngle=360`. If `startAngle` is greater than `endAngle`, they are swapped. The figure below explains +the meaning of the parameters to draw the blue arc. + +![Parameters of Elliptic Arc](pics/ellipse.svg) + +@param img Image. +@param center Center of the ellipse. +@param axes Half of the size of the ellipse main axes. +@param angle Ellipse rotation angle in degrees. +@param startAngle Starting angle of the elliptic arc in degrees. +@param endAngle Ending angle of the elliptic arc in degrees. +@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 #LineTypes +@param shift Number of fractional bits in the coordinates of the center and values of axes. + */ +CV_EXPORTS_W void ellipse(InputOutputArray img, Point center, Size axes, + double angle, double startAngle, double endAngle, + const Scalar& color, int thickness = 1, + int lineType = LINE_8, int shift = 0); + +/** @overload +@param img Image. +@param box Alternative ellipse representation via RotatedRect. This means that the function draws +an ellipse inscribed in the rotated rectangle. +@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 #LineTypes +*/ +CV_EXPORTS_W void ellipse(InputOutputArray img, const RotatedRect& box, const Scalar& color, + int thickness = 1, int lineType = LINE_8); + +/* ----------------------------------------------------------------------------------------- */ +/* ADDING A SET OF PREDEFINED MARKERS WHICH COULD BE USED TO HIGHLIGHT POSITIONS IN AN IMAGE */ +/* ----------------------------------------------------------------------------------------- */ + +/** @brief Draws a marker on a predefined position in an image. + +The function cv::drawMarker draws a marker on a given position in the image. For the moment several +marker types are supported, see #MarkerTypes for more information. + +@param img Image. +@param position The point where the crosshair is positioned. +@param color Line color. +@param markerType The specific type of marker you want to use, see #MarkerTypes +@param thickness Line thickness. +@param line_type Type of the line, See #LineTypes +@param markerSize The length of the marker axis [default = 20 pixels] + */ +CV_EXPORTS_W void drawMarker(InputOutputArray img, Point position, const Scalar& color, + int markerType = MARKER_CROSS, int markerSize=20, int thickness=1, + int line_type=8); + +/* ----------------------------------------------------------------------------------------- */ +/* END OF MARKER SECTION */ +/* ----------------------------------------------------------------------------------------- */ + +/** @overload */ +CV_EXPORTS void fillConvexPoly(InputOutputArray img, const Point* pts, int npts, + const Scalar& color, int lineType = LINE_8, + int shift = 0); + +/** @brief Fills a convex polygon. + +The function cv::fillConvexPoly draws a filled convex polygon. This function is much faster than the +function #fillPoly . It can fill not only convex polygons but any monotonic polygon without +self-intersections, that is, a polygon whose contour intersects every horizontal line (scan line) +twice at the most (though, its top-most and/or the bottom edge could be horizontal). + +@param img Image. +@param points Polygon vertices. +@param color Polygon color. +@param lineType Type of the polygon boundaries. See #LineTypes +@param shift Number of fractional bits in the vertex coordinates. + */ +CV_EXPORTS_W void fillConvexPoly(InputOutputArray img, InputArray points, + const Scalar& color, int lineType = LINE_8, + int shift = 0); + +/** @overload */ +CV_EXPORTS void fillPoly(InputOutputArray img, const Point** pts, + const int* npts, int ncontours, + const Scalar& color, int lineType = LINE_8, int shift = 0, + Point offset = Point() ); + +/** @example samples/cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp +An example using drawing functions +Check @ref tutorial_random_generator_and_text "the corresponding tutorial" for more details +*/ + +/** @brief Fills the area bounded by one or more polygons. + +The function cv::fillPoly fills an area bounded by several polygonal contours. The function can fill +complex areas, for example, areas with holes, contours with self-intersections (some of their +parts), and so forth. + +@param img Image. +@param pts Array of polygons where each polygon is represented as an array of points. +@param color Polygon color. +@param lineType Type of the polygon boundaries. See #LineTypes +@param shift Number of fractional bits in the vertex coordinates. +@param offset Optional offset of all points of the contours. + */ +CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts, + const Scalar& color, int lineType = LINE_8, int shift = 0, + Point offset = Point() ); + +/** @overload */ +CV_EXPORTS void polylines(InputOutputArray img, const Point* const* pts, const int* npts, + int ncontours, bool isClosed, const Scalar& color, + int thickness = 1, int lineType = LINE_8, int shift = 0 ); + +/** @brief Draws several polygonal curves. + +@param img Image. +@param pts Array of polygonal curves. +@param isClosed Flag indicating whether the drawn polylines are closed or not. If they are closed, +the function draws a line from the last vertex of each curve to its first vertex. +@param color Polyline color. +@param thickness Thickness of the polyline edges. +@param lineType Type of the line segments. See #LineTypes +@param shift Number of fractional bits in the vertex coordinates. + +The function cv::polylines draws one or more polygonal curves. + */ +CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts, + bool isClosed, const Scalar& color, + int thickness = 1, int lineType = LINE_8, int shift = 0 ); + +/** @example samples/cpp/contours2.cpp +An example program illustrates the use of cv::findContours and cv::drawContours +\image html WindowsQtContoursOutput.png "Screenshot of the program" +*/ + +/** @example samples/cpp/segment_objects.cpp +An example using drawContours to clean up a background segmentation result +*/ + +/** @brief Draws contours outlines or filled contours. + +The function draws contour outlines in the image if \f$\texttt{thickness} \ge 0\f$ or fills the area +bounded by the contours if \f$\texttt{thickness}<0\f$ . The example below shows how to retrieve +connected components from the binary image and label them: : +@include snippets/imgproc_drawContours.cpp + +@param image Destination image. +@param contours All the input contours. Each contour is stored as a point vector. +@param contourIdx Parameter indicating a contour to draw. If it is negative, all the contours are drawn. +@param color Color of the contours. +@param thickness Thickness of lines the contours are drawn with. If it is negative (for example, +thickness=#FILLED ), the contour interiors are drawn. +@param lineType Line connectivity. See #LineTypes +@param hierarchy Optional information about hierarchy. It is only needed if you want to draw only +some of the contours (see maxLevel ). +@param maxLevel Maximal level for drawn contours. If it is 0, only the specified contour is drawn. +If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function +draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This +parameter is only taken into account when there is hierarchy available. +@param offset Optional contour shift parameter. Shift all the drawn contours by the specified +\f$\texttt{offset}=(dx,dy)\f$ . +@note When thickness=#FILLED, the function is designed to handle connected components with holes correctly +even when no hierarchy date is provided. This is done by analyzing all the outlines together +using even-odd rule. This may give incorrect results if you have a joint collection of separately retrieved +contours. In order to solve this problem, you need to call #drawContours separately for each sub-group +of contours, or iterate over the collection using contourIdx parameter. + */ +CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours, + int contourIdx, const Scalar& color, + int thickness = 1, int lineType = LINE_8, + InputArray hierarchy = noArray(), + int maxLevel = INT_MAX, Point offset = Point() ); + +/** @brief Clips the line against the image rectangle. + +The function cv::clipLine calculates a part of the line segment that is entirely within the specified +rectangle. it returns false if the line segment is completely outside the rectangle. Otherwise, +it returns true . +@param imgSize Image size. The image rectangle is Rect(0, 0, imgSize.width, imgSize.height) . +@param pt1 First line point. +@param pt2 Second line point. + */ +CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2); + +/** @overload +@param imgSize Image size. The image rectangle is Rect(0, 0, imgSize.width, imgSize.height) . +@param pt1 First line point. +@param pt2 Second line point. +*/ +CV_EXPORTS bool clipLine(Size2l imgSize, CV_IN_OUT Point2l& pt1, CV_IN_OUT Point2l& pt2); + +/** @overload +@param imgRect Image rectangle. +@param pt1 First line point. +@param pt2 Second line point. +*/ +CV_EXPORTS_W bool clipLine(Rect imgRect, CV_OUT CV_IN_OUT Point& pt1, CV_OUT CV_IN_OUT Point& pt2); + +/** @brief Approximates an elliptic arc with a polyline. + +The function ellipse2Poly computes the vertices of a polyline that approximates the specified +elliptic arc. It is used by #ellipse. If `arcStart` is greater than `arcEnd`, they are swapped. + +@param center Center of the arc. +@param axes Half of the size of the ellipse main axes. See #ellipse for details. +@param angle Rotation angle of the ellipse in degrees. See #ellipse for details. +@param arcStart Starting angle of the elliptic arc in degrees. +@param arcEnd Ending angle of the elliptic arc in degrees. +@param delta Angle between the subsequent polyline vertices. It defines the approximation +accuracy. +@param pts Output vector of polyline vertices. + */ +CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle, + int arcStart, int arcEnd, int delta, + CV_OUT std::vector& pts ); + +/** @overload +@param center Center of the arc. +@param axes Half of the size of the ellipse main axes. See #ellipse for details. +@param angle Rotation angle of the ellipse in degrees. See #ellipse for details. +@param arcStart Starting angle of the elliptic arc in degrees. +@param arcEnd Ending angle of the elliptic arc in degrees. +@param delta Angle between the subsequent polyline vertices. It defines the approximation accuracy. +@param pts Output vector of polyline vertices. +*/ +CV_EXPORTS void ellipse2Poly(Point2d center, Size2d axes, int angle, + int arcStart, int arcEnd, int delta, + CV_OUT std::vector& pts); + +/** @brief Draws a text string. + +The function cv::putText renders the specified text string in the image. Symbols that cannot be rendered +using the specified font are replaced by question marks. See #getTextSize for a text rendering code +example. + +@param img Image. +@param text Text string to be drawn. +@param org Bottom-left corner of the text string in the image. +@param fontFace Font type, see #HersheyFonts. +@param fontScale Font scale factor that is multiplied by the font-specific base size. +@param color Text color. +@param thickness Thickness of the lines used to draw a text. +@param lineType Line type. See #LineTypes +@param bottomLeftOrigin When true, the image data origin is at the bottom-left corner. Otherwise, +it is at the top-left corner. + */ +CV_EXPORTS_W void putText( InputOutputArray img, const String& text, Point org, + int fontFace, double fontScale, Scalar color, + int thickness = 1, int lineType = LINE_8, + bool bottomLeftOrigin = false ); + +/** @brief Calculates the width and height of a text string. + +The function cv::getTextSize calculates and returns the size of a box that contains the specified text. +That is, the following code renders some text, the tight box surrounding it, and the baseline: : +@code + String text = "Funny text inside the box"; + int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX; + double fontScale = 2; + int thickness = 3; + + Mat img(600, 800, CV_8UC3, Scalar::all(0)); + + int baseline=0; + Size textSize = getTextSize(text, fontFace, + fontScale, thickness, &baseline); + baseline += thickness; + + // center the text + Point textOrg((img.cols - textSize.width)/2, + (img.rows + textSize.height)/2); + + // draw the box + rectangle(img, textOrg + Point(0, baseline), + textOrg + Point(textSize.width, -textSize.height), + Scalar(0,0,255)); + // ... and the baseline first + line(img, textOrg + Point(0, thickness), + textOrg + Point(textSize.width, thickness), + Scalar(0, 0, 255)); + + // then put the text itself + putText(img, text, textOrg, fontFace, fontScale, + Scalar::all(255), thickness, 8); +@endcode + +@param text Input text string. +@param fontFace Font to use, see #HersheyFonts. +@param fontScale Font scale factor that is multiplied by the font-specific base size. +@param thickness Thickness of lines used to render the text. See #putText for details. +@param[out] baseLine y-coordinate of the baseline relative to the bottom-most text +point. +@return The size of a box that contains the specified text. + +@see putText + */ +CV_EXPORTS_W Size getTextSize(const String& text, int fontFace, + double fontScale, int thickness, + CV_OUT int* baseLine); + + +/** @brief Calculates the font-specific size to use to achieve a given height in pixels. + +@param fontFace Font to use, see cv::HersheyFonts. +@param pixelHeight Pixel height to compute the fontScale for +@param thickness Thickness of lines used to render the text.See putText for details. +@return The fontSize to use for cv::putText + +@see cv::putText +*/ +CV_EXPORTS_W double getFontScaleFromHeight(const int fontFace, + const int pixelHeight, + const int thickness = 1); + +/** @brief Line iterator + +The class is used to iterate over all the pixels on the raster line +segment connecting two specified points. + +The class LineIterator is used to get each pixel of a raster line. It +can be treated as versatile implementation of the Bresenham algorithm +where you can stop at each pixel and do some extra processing, for +example, grab pixel values along the line or draw a line with an effect +(for example, with XOR operation). + +The number of pixels along the line is stored in LineIterator::count. +The method LineIterator::pos returns the current position in the image: + +@code{.cpp} +// grabs pixels along the line (pt1, pt2) +// from 8-bit 3-channel image to the buffer +LineIterator it(img, pt1, pt2, 8); +LineIterator it2 = it; +vector buf(it.count); + +for(int i = 0; i < it.count; i++, ++it) + buf[i] = *(const Vec3b*)*it; + +// alternative way of iterating through the line +for(int i = 0; i < it2.count; i++, ++it2) +{ + Vec3b val = img.at(it2.pos()); + CV_Assert(buf[i] == val); +} +@endcode +*/ +class CV_EXPORTS LineIterator +{ +public: + /** @brief initializes the iterator + + creates iterators for the line connecting pt1 and pt2 + the line will be clipped on the image boundaries + the line is 8-connected or 4-connected + If leftToRight=true, then the iteration is always done + from the left-most point to the right most, + not to depend on the ordering of pt1 and pt2 parameters + */ + LineIterator( const Mat& img, Point pt1, Point pt2, + int connectivity = 8, bool leftToRight = false ); + /** @brief returns pointer to the current pixel + */ + uchar* operator *(); + /** @brief prefix increment operator (++it). shifts iterator to the next pixel + */ + LineIterator& operator ++(); + /** @brief postfix increment operator (it++). shifts iterator to the next pixel + */ + LineIterator operator ++(int); + /** @brief returns coordinates of the current pixel + */ + Point pos() const; + + uchar* ptr; + const uchar* ptr0; + int step, elemSize; + int err, count; + int minusDelta, plusDelta; + int minusStep, plusStep; +}; + +//! @cond IGNORED + +// === LineIterator implementation === + +inline +uchar* LineIterator::operator *() +{ + return ptr; +} + +inline +LineIterator& LineIterator::operator ++() +{ + int mask = err < 0 ? -1 : 0; + err += minusDelta + (plusDelta & mask); + ptr += minusStep + (plusStep & mask); + return *this; +} + +inline +LineIterator LineIterator::operator ++(int) +{ + LineIterator it = *this; + ++(*this); + return it; +} + +inline +Point LineIterator::pos() const +{ + Point p; + p.y = (int)((ptr - ptr0)/step); + p.x = (int)(((ptr - ptr0) - p.y*step)/elemSize); + return p; +} + +//! @endcond + +//! @} imgproc_draw + +//! @} imgproc + +} // cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgproc/detail/gcgraph.hpp b/Prj-Win/3rd/opencv/include/opencv2/imgproc/detail/gcgraph.hpp new file mode 100755 index 0000000..db2ea0f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgproc/detail/gcgraph.hpp @@ -0,0 +1,393 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_IMGPROC_DETAIL_GCGRAPH_HPP +#define OPENCV_IMGPROC_DETAIL_GCGRAPH_HPP + +//! @cond IGNORED + +namespace cv { namespace detail { +template class GCGraph +{ +public: + GCGraph(); + GCGraph( unsigned int vtxCount, unsigned int edgeCount ); + ~GCGraph(); + void create( unsigned int vtxCount, unsigned int edgeCount ); + int addVtx(); + void addEdges( int i, int j, TWeight w, TWeight revw ); + void addTermWeights( int i, TWeight sourceW, TWeight sinkW ); + TWeight maxFlow(); + bool inSourceSegment( int i ); +private: + class Vtx + { + public: + Vtx *next; // initialized and used in maxFlow() only + int parent; + int first; + int ts; + int dist; + TWeight weight; + uchar t; + }; + class Edge + { + public: + int dst; + int next; + TWeight weight; + }; + + std::vector vtcs; + std::vector edges; + TWeight flow; +}; + +template +GCGraph::GCGraph() +{ + flow = 0; +} +template +GCGraph::GCGraph( unsigned int vtxCount, unsigned int edgeCount ) +{ + create( vtxCount, edgeCount ); +} +template +GCGraph::~GCGraph() +{ +} +template +void GCGraph::create( unsigned int vtxCount, unsigned int edgeCount ) +{ + vtcs.reserve( vtxCount ); + edges.reserve( edgeCount + 2 ); + flow = 0; +} + +template +int GCGraph::addVtx() +{ + Vtx v; + memset( &v, 0, sizeof(Vtx)); + vtcs.push_back(v); + return (int)vtcs.size() - 1; +} + +template +void GCGraph::addEdges( int i, int j, TWeight w, TWeight revw ) +{ + CV_Assert( i>=0 && i<(int)vtcs.size() ); + CV_Assert( j>=0 && j<(int)vtcs.size() ); + CV_Assert( w>=0 && revw>=0 ); + CV_Assert( i != j ); + + if( !edges.size() ) + edges.resize( 2 ); + + Edge fromI, toI; + fromI.dst = j; + fromI.next = vtcs[i].first; + fromI.weight = w; + vtcs[i].first = (int)edges.size(); + edges.push_back( fromI ); + + toI.dst = i; + toI.next = vtcs[j].first; + toI.weight = revw; + vtcs[j].first = (int)edges.size(); + edges.push_back( toI ); +} + +template +void GCGraph::addTermWeights( int i, TWeight sourceW, TWeight sinkW ) +{ + CV_Assert( i>=0 && i<(int)vtcs.size() ); + + TWeight dw = vtcs[i].weight; + if( dw > 0 ) + sourceW += dw; + else + sinkW -= dw; + flow += (sourceW < sinkW) ? sourceW : sinkW; + vtcs[i].weight = sourceW - sinkW; +} + +template +TWeight GCGraph::maxFlow() +{ + const int TERMINAL = -1, ORPHAN = -2; + Vtx stub, *nilNode = &stub, *first = nilNode, *last = nilNode; + int curr_ts = 0; + stub.next = nilNode; + Vtx *vtxPtr = &vtcs[0]; + Edge *edgePtr = &edges[0]; + + std::vector orphans; + + // initialize the active queue and the graph vertices + for( int i = 0; i < (int)vtcs.size(); i++ ) + { + Vtx* v = vtxPtr + i; + v->ts = 0; + if( v->weight != 0 ) + { + last = last->next = v; + v->dist = 1; + v->parent = TERMINAL; + v->t = v->weight < 0; + } + else + v->parent = 0; + } + first = first->next; + last->next = nilNode; + nilNode->next = 0; + + // run the search-path -> augment-graph -> restore-trees loop + for(;;) + { + Vtx* v, *u; + int e0 = -1, ei = 0, ej = 0; + TWeight minWeight, weight; + uchar vt; + + // grow S & T search trees, find an edge connecting them + while( first != nilNode ) + { + v = first; + if( v->parent ) + { + vt = v->t; + for( ei = v->first; ei != 0; ei = edgePtr[ei].next ) + { + if( edgePtr[ei^vt].weight == 0 ) + continue; + u = vtxPtr+edgePtr[ei].dst; + if( !u->parent ) + { + u->t = vt; + u->parent = ei ^ 1; + u->ts = v->ts; + u->dist = v->dist + 1; + if( !u->next ) + { + u->next = nilNode; + last = last->next = u; + } + continue; + } + + if( u->t != vt ) + { + e0 = ei ^ vt; + break; + } + + if( u->dist > v->dist+1 && u->ts <= v->ts ) + { + // reassign the parent + u->parent = ei ^ 1; + u->ts = v->ts; + u->dist = v->dist + 1; + } + } + if( e0 > 0 ) + break; + } + // exclude the vertex from the active list + first = first->next; + v->next = 0; + } + + if( e0 <= 0 ) + break; + + // find the minimum edge weight along the path + minWeight = edgePtr[e0].weight; + CV_Assert( minWeight > 0 ); + // k = 1: source tree, k = 0: destination tree + for( int k = 1; k >= 0; k-- ) + { + for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst ) + { + if( (ei = v->parent) < 0 ) + break; + weight = edgePtr[ei^k].weight; + minWeight = MIN(minWeight, weight); + CV_Assert( minWeight > 0 ); + } + weight = fabs(v->weight); + minWeight = MIN(minWeight, weight); + CV_Assert( minWeight > 0 ); + } + + // modify weights of the edges along the path and collect orphans + edgePtr[e0].weight -= minWeight; + edgePtr[e0^1].weight += minWeight; + flow += minWeight; + + // k = 1: source tree, k = 0: destination tree + for( int k = 1; k >= 0; k-- ) + { + for( v = vtxPtr+edgePtr[e0^k].dst;; v = vtxPtr+edgePtr[ei].dst ) + { + if( (ei = v->parent) < 0 ) + break; + edgePtr[ei^(k^1)].weight += minWeight; + if( (edgePtr[ei^k].weight -= minWeight) == 0 ) + { + orphans.push_back(v); + v->parent = ORPHAN; + } + } + + v->weight = v->weight + minWeight*(1-k*2); + if( v->weight == 0 ) + { + orphans.push_back(v); + v->parent = ORPHAN; + } + } + + // restore the search trees by finding new parents for the orphans + curr_ts++; + while( !orphans.empty() ) + { + Vtx* v2 = orphans.back(); + orphans.pop_back(); + + int d, minDist = INT_MAX; + e0 = 0; + vt = v2->t; + + for( ei = v2->first; ei != 0; ei = edgePtr[ei].next ) + { + if( edgePtr[ei^(vt^1)].weight == 0 ) + continue; + u = vtxPtr+edgePtr[ei].dst; + if( u->t != vt || u->parent == 0 ) + continue; + // compute the distance to the tree root + for( d = 0;; ) + { + if( u->ts == curr_ts ) + { + d += u->dist; + break; + } + ej = u->parent; + d++; + if( ej < 0 ) + { + if( ej == ORPHAN ) + d = INT_MAX-1; + else + { + u->ts = curr_ts; + u->dist = 1; + } + break; + } + u = vtxPtr+edgePtr[ej].dst; + } + + // update the distance + if( ++d < INT_MAX ) + { + if( d < minDist ) + { + minDist = d; + e0 = ei; + } + for( u = vtxPtr+edgePtr[ei].dst; u->ts != curr_ts; u = vtxPtr+edgePtr[u->parent].dst ) + { + u->ts = curr_ts; + u->dist = --d; + } + } + } + + if( (v2->parent = e0) > 0 ) + { + v2->ts = curr_ts; + v2->dist = minDist; + continue; + } + + /* no parent is found */ + v2->ts = 0; + for( ei = v2->first; ei != 0; ei = edgePtr[ei].next ) + { + u = vtxPtr+edgePtr[ei].dst; + ej = u->parent; + if( u->t != vt || !ej ) + continue; + if( edgePtr[ei^(vt^1)].weight && !u->next ) + { + u->next = nilNode; + last = last->next = u; + } + if( ej > 0 && vtxPtr+edgePtr[ej].dst == v2 ) + { + orphans.push_back(u); + u->parent = ORPHAN; + } + } + } + } + return flow; +} + +template +bool GCGraph::inSourceSegment( int i ) +{ + CV_Assert( i>=0 && i<(int)vtcs.size() ); + return vtcs[i].t == 0; +} + +}} // namespace detail, cv + + +//! @endcond + +#endif // OPENCV_IMGPROC_DETAIL_GCGRAPH_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/hal.hpp b/Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/hal.hpp new file mode 100755 index 0000000..ac20725 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/hal.hpp @@ -0,0 +1,241 @@ +#ifndef CV_IMGPROC_HAL_HPP +#define CV_IMGPROC_HAL_HPP + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/cvstd.hpp" +#include "opencv2/core/hal/interface.h" + +namespace cv { namespace hal { + +//! @addtogroup imgproc_hal_functions +//! @{ + +//--------------------------- +//! @cond IGNORED + +struct CV_EXPORTS Filter2D +{ + CV_DEPRECATED static Ptr create(uchar * , size_t , int , + int , int , + int , int , + int , int , + int , double , + int , int , + bool , bool ); + virtual void apply(uchar * , size_t , + uchar * , size_t , + int , int , + int , int , + int , int ) = 0; + virtual ~Filter2D() {} +}; + +struct CV_EXPORTS SepFilter2D +{ + CV_DEPRECATED static Ptr create(int , int , int , + uchar * , int , + uchar * , int , + int , int , + double , int ); + virtual void apply(uchar * , size_t , + uchar * , size_t , + int , int , + int , int , + int , int ) = 0; + virtual ~SepFilter2D() {} +}; + + +struct CV_EXPORTS Morph +{ + CV_DEPRECATED static Ptr create(int , int , int , int , int , + int , uchar * , size_t , + int , int , + int , int , + int , const double *, + int , bool , bool ); + virtual void apply(uchar * , size_t , uchar * , size_t , int , int , + int , int , int , int , + int , int , int , int ) = 0; + virtual ~Morph() {} +}; + +//! @endcond +//--------------------------- + +CV_EXPORTS void filter2D(int stype, int dtype, int kernel_type, + uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int full_width, int full_height, + int offset_x, int offset_y, + uchar * kernel_data, size_t kernel_step, + int kernel_width, int kernel_height, + int anchor_x, int anchor_y, + double delta, int borderType, + bool isSubmatrix); + +CV_EXPORTS void sepFilter2D(int stype, int dtype, int ktype, + uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int full_width, int full_height, + int offset_x, int offset_y, + uchar * kernelx_data, int kernelx_len, + uchar * kernely_data, int kernely_len, + int anchor_x, int anchor_y, + double delta, int borderType); + +CV_EXPORTS void morph(int op, int src_type, int dst_type, + uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int roi_width, int roi_height, int roi_x, int roi_y, + int roi_width2, int roi_height2, int roi_x2, int roi_y2, + int kernel_type, uchar * kernel_data, size_t kernel_step, + int kernel_width, int kernel_height, int anchor_x, int anchor_y, + int borderType, const double borderValue[4], + int iterations, bool isSubmatrix); + + +CV_EXPORTS void resize(int src_type, + const uchar * src_data, size_t src_step, int src_width, int src_height, + uchar * dst_data, size_t dst_step, int dst_width, int dst_height, + double inv_scale_x, double inv_scale_y, int interpolation); + +CV_EXPORTS void warpAffine(int src_type, + const uchar * src_data, size_t src_step, int src_width, int src_height, + uchar * dst_data, size_t dst_step, int dst_width, int dst_height, + const double M[6], int interpolation, int borderType, const double borderValue[4]); + +CV_EXPORTS void warpPerspective(int src_type, + const uchar * src_data, size_t src_step, int src_width, int src_height, + uchar * dst_data, size_t dst_step, int dst_width, int dst_height, + const double M[9], int interpolation, int borderType, const double borderValue[4]); + +CV_EXPORTS void cvtBGRtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, int dcn, bool swapBlue); + +CV_EXPORTS void cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int scn, bool swapBlue, int greenBits); + +CV_EXPORTS void cvtBGR5x5toBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int dcn, bool swapBlue, int greenBits); + +CV_EXPORTS void cvtBGRtoGray(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue); + +CV_EXPORTS void cvtGraytoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn); + +CV_EXPORTS void cvtBGR5x5toGray(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int greenBits); + +CV_EXPORTS void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int greenBits); +CV_EXPORTS void cvtBGRtoYUV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isCbCr); + +CV_EXPORTS void cvtYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isCbCr); + +CV_EXPORTS void cvtBGRtoXYZ(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue); + +CV_EXPORTS void cvtXYZtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue); + +CV_EXPORTS void cvtBGRtoHSV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isFullRange, bool isHSV); + +CV_EXPORTS void cvtHSVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV); + +CV_EXPORTS void cvtBGRtoLab(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int scn, bool swapBlue, bool isLab, bool srgb); + +CV_EXPORTS void cvtLabtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int depth, int dcn, bool swapBlue, bool isLab, bool srgb); + +CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int dst_width, int dst_height, + int dcn, bool swapBlue, int uIdx); + +//! Separate Y and UV planes +CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int dst_width, int dst_height, + int dcn, bool swapBlue, int uIdx); + +CV_EXPORTS void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int dst_width, int dst_height, + int dcn, bool swapBlue, int uIdx); + +CV_EXPORTS void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int scn, bool swapBlue, int uIdx); + +//! Separate Y and UV planes +CV_EXPORTS void cvtBGRtoTwoPlaneYUV(const uchar * src_data, size_t src_step, + uchar * y_data, uchar * uv_data, size_t dst_step, + int width, int height, + int scn, bool swapBlue, int uIdx); + +CV_EXPORTS void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height, + int dcn, bool swapBlue, int uIdx, int ycn); + +CV_EXPORTS void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height); + +CV_EXPORTS void cvtMultipliedRGBAtoRGBA(const uchar * src_data, size_t src_step, + uchar * dst_data, size_t dst_step, + int width, int height); + +CV_EXPORTS void integral(int depth, int sdepth, int sqdepth, + const uchar* src, size_t srcstep, + uchar* sum, size_t sumstep, + uchar* sqsum, size_t sqsumstep, + uchar* tilted, size_t tstep, + int width, int height, int cn); + +//! @} + +}} + +#endif // CV_IMGPROC_HAL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/interface.h b/Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/interface.h new file mode 100755 index 0000000..f8dbcfe --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgproc/hal/interface.h @@ -0,0 +1,46 @@ +#ifndef OPENCV_IMGPROC_HAL_INTERFACE_H +#define OPENCV_IMGPROC_HAL_INTERFACE_H + +//! @addtogroup imgproc_hal_interface +//! @{ + +//! @name Interpolation modes +//! @sa cv::InterpolationFlags +//! @{ +#define CV_HAL_INTER_NEAREST 0 +#define CV_HAL_INTER_LINEAR 1 +#define CV_HAL_INTER_CUBIC 2 +#define CV_HAL_INTER_AREA 3 +#define CV_HAL_INTER_LANCZOS4 4 +//! @} + +//! @name Morphology operations +//! @sa cv::MorphTypes +//! @{ +#define CV_HAL_MORPH_ERODE 0 +#define CV_HAL_MORPH_DILATE 1 +//! @} + +//! @name Threshold types +//! @sa cv::ThresholdTypes +//! @{ +#define CV_HAL_THRESH_BINARY 0 +#define CV_HAL_THRESH_BINARY_INV 1 +#define CV_HAL_THRESH_TRUNC 2 +#define CV_HAL_THRESH_TOZERO 3 +#define CV_HAL_THRESH_TOZERO_INV 4 +#define CV_HAL_THRESH_MASK 7 +#define CV_HAL_THRESH_OTSU 8 +#define CV_HAL_THRESH_TRIANGLE 16 +//! @} + +//! @name Adaptive threshold algorithm +//! @sa cv::AdaptiveThresholdTypes +//! @{ +#define CV_HAL_ADAPTIVE_THRESH_MEAN_C 0 +#define CV_HAL_ADAPTIVE_THRESH_GAUSSIAN_C 1 +//! @} + +//! @} + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc.hpp b/Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc.hpp new file mode 100755 index 0000000..4175bd0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/imgproc.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc_c.h b/Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc_c.h new file mode 100755 index 0000000..9f7131f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgproc/imgproc_c.h @@ -0,0 +1,1177 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_IMGPROC_IMGPROC_C_H +#define OPENCV_IMGPROC_IMGPROC_C_H + +#include "opencv2/imgproc/types_c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup imgproc_c +@{ +*/ + +/*********************** Background statistics accumulation *****************************/ + +/** @brief Adds image to accumulator +@see cv::accumulate +*/ +CVAPI(void) cvAcc( const CvArr* image, CvArr* sum, + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @brief Adds squared image to accumulator +@see cv::accumulateSquare +*/ +CVAPI(void) cvSquareAcc( const CvArr* image, CvArr* sqsum, + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @brief Adds a product of two images to accumulator +@see cv::accumulateProduct +*/ +CVAPI(void) cvMultiplyAcc( const CvArr* image1, const CvArr* image2, CvArr* acc, + const CvArr* mask CV_DEFAULT(NULL) ); + +/** @brief Adds image to accumulator with weights: acc = acc*(1-alpha) + image*alpha +@see cv::accumulateWeighted +*/ +CVAPI(void) cvRunningAvg( const CvArr* image, CvArr* acc, double alpha, + const CvArr* mask CV_DEFAULT(NULL) ); + +/****************************************************************************************\ +* Image Processing * +\****************************************************************************************/ + +/** Copies source 2D array inside of the larger destination array and + makes a border of the specified type (IPL_BORDER_*) around the copied area. */ +CVAPI(void) cvCopyMakeBorder( const CvArr* src, CvArr* dst, CvPoint offset, + int bordertype, CvScalar value CV_DEFAULT(cvScalarAll(0))); + +/** @brief Smooths the image in one of several ways. + +@param src The source image +@param dst The destination image +@param smoothtype Type of the smoothing, see SmoothMethod_c +@param size1 The first parameter of the smoothing operation, the aperture width. Must be a +positive odd number (1, 3, 5, ...) +@param size2 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 +size2 is zero, it is set to size1. Otherwise it must be a positive odd number. +@param sigma1 In the case of a Gaussian parameter this parameter may specify Gaussian \f$\sigma\f$ +(standard deviation). If it is zero, it is calculated from the kernel size: +\f[\sigma = 0.3 (n/2 - 1) + 0.8 \quad \text{where} \quad n= \begin{array}{l l} \mbox{\texttt{size1} for horizontal kernel} \\ \mbox{\texttt{size2} for vertical kernel} \end{array}\f] +Using standard sigma for small kernels ( \f$3\times 3\f$ to \f$7\times 7\f$ ) gives better speed. If +sigma1 is not zero, while size1 and size2 are zeros, the kernel size is calculated from the +sigma (to provide accurate enough operation). +@param sigma2 additional parameter for bilateral filtering + +@see cv::GaussianBlur, cv::blur, cv::medianBlur, cv::bilateralFilter. + */ +CVAPI(void) cvSmooth( const CvArr* src, CvArr* dst, + int smoothtype CV_DEFAULT(CV_GAUSSIAN), + int size1 CV_DEFAULT(3), + int size2 CV_DEFAULT(0), + double sigma1 CV_DEFAULT(0), + double sigma2 CV_DEFAULT(0)); + +/** @brief Convolves an image with the kernel. + +@param src input image. +@param dst output image of the same size and the same number of channels as src. +@param kernel convolution kernel (or rather a correlation 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 split and process them individually. +@param anchor anchor of the kernel that indicates the relative position of a filtered point within +the kernel; the anchor should lie within the kernel; default value (-1,-1) means that the anchor +is at the kernel center. + +@see cv::filter2D + */ +CVAPI(void) cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel, + CvPoint anchor CV_DEFAULT(cvPoint(-1,-1))); + +/** @brief Finds integral image: SUM(X,Y) = sum(x \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)\)}\f] + +@param hist1 First histogram (the divisor). +@param hist2 Second histogram. +@param dst_hist Destination histogram. +@param scale Scale factor for the destination histogram. + */ +CVAPI(void) cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, + CvHistogram* dst_hist, double scale CV_DEFAULT(255) ); + +/** @brief equalizes histogram of 8-bit single-channel image +@see cv::equalizeHist +*/ +CVAPI(void) cvEqualizeHist( const CvArr* src, CvArr* dst ); + + +/** @brief Applies distance transform to binary image +@see cv::distanceTransform +*/ +CVAPI(void) cvDistTransform( const CvArr* src, CvArr* dst, + int distance_type CV_DEFAULT(CV_DIST_L2), + int mask_size CV_DEFAULT(3), + const float* mask CV_DEFAULT(NULL), + CvArr* labels CV_DEFAULT(NULL), + int labelType CV_DEFAULT(CV_DIST_LABEL_CCOMP)); + + +/** @brief Applies fixed-level threshold to grayscale image. + + This is a basic operation applied before retrieving contours +@see cv::threshold +*/ +CVAPI(double) cvThreshold( const CvArr* src, CvArr* dst, + double threshold, double max_value, + int threshold_type ); + +/** @brief Applies adaptive threshold to grayscale image. + + The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and + CV_ADAPTIVE_THRESH_GAUSSIAN_C are: + neighborhood size (3, 5, 7 etc.), + and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...) +@see cv::adaptiveThreshold +*/ +CVAPI(void) cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value, + int adaptive_method CV_DEFAULT(CV_ADAPTIVE_THRESH_MEAN_C), + int threshold_type CV_DEFAULT(CV_THRESH_BINARY), + int block_size CV_DEFAULT(3), + double param1 CV_DEFAULT(5)); + +/** @brief Fills the connected component until the color difference gets large enough +@see cv::floodFill +*/ +CVAPI(void) cvFloodFill( CvArr* image, CvPoint seed_point, + CvScalar new_val, CvScalar lo_diff CV_DEFAULT(cvScalarAll(0)), + CvScalar up_diff CV_DEFAULT(cvScalarAll(0)), + CvConnectedComp* comp CV_DEFAULT(NULL), + int flags CV_DEFAULT(4), + CvArr* mask CV_DEFAULT(NULL)); + +/****************************************************************************************\ +* Feature detection * +\****************************************************************************************/ + +/** @brief Runs canny edge detector +@see cv::Canny +*/ +CVAPI(void) cvCanny( const CvArr* image, CvArr* edges, double threshold1, + double threshold2, int aperture_size CV_DEFAULT(3) ); + +/** @brief Calculates constraint image for corner detection + + Dx^2 * Dyy + Dxx * Dy^2 - 2 * Dx * Dy * Dxy. + Applying threshold to the result gives coordinates of corners +@see cv::preCornerDetect +*/ +CVAPI(void) cvPreCornerDetect( const CvArr* image, CvArr* corners, + int aperture_size CV_DEFAULT(3) ); + +/** @brief Calculates eigen values and vectors of 2x2 + gradient covariation matrix at every image pixel +@see cv::cornerEigenValsAndVecs +*/ +CVAPI(void) cvCornerEigenValsAndVecs( const CvArr* image, CvArr* eigenvv, + int block_size, int aperture_size CV_DEFAULT(3) ); + +/** @brief Calculates minimal eigenvalue for 2x2 gradient covariation matrix at + every image pixel +@see cv::cornerMinEigenVal +*/ +CVAPI(void) cvCornerMinEigenVal( const CvArr* image, CvArr* eigenval, + int block_size, int aperture_size CV_DEFAULT(3) ); + +/** @brief Harris corner detector: + + Calculates det(M) - k*(trace(M)^2), where M is 2x2 gradient covariation matrix for each pixel +@see cv::cornerHarris +*/ +CVAPI(void) cvCornerHarris( const CvArr* image, CvArr* harris_response, + int block_size, int aperture_size CV_DEFAULT(3), + double k CV_DEFAULT(0.04) ); + +/** @brief Adjust corner position using some sort of gradient search +@see cv::cornerSubPix +*/ +CVAPI(void) cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners, + int count, CvSize win, CvSize zero_zone, + CvTermCriteria criteria ); + +/** @brief Finds a sparse set of points within the selected region + that seem to be easy to track +@see cv::goodFeaturesToTrack +*/ +CVAPI(void) cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, + CvArr* temp_image, CvPoint2D32f* corners, + int* corner_count, double quality_level, + double min_distance, + const CvArr* mask CV_DEFAULT(NULL), + int block_size CV_DEFAULT(3), + int use_harris CV_DEFAULT(0), + double k CV_DEFAULT(0.04) ); + +/** @brief Finds lines on binary image using one of several methods. + + line_storage is either memory storage or 1 x _max number of lines_ CvMat, its + number of columns is changed by the function. + method is one of CV_HOUGH_*; + rho, theta and threshold are used for each of those methods; + param1 ~ line length, param2 ~ line gap - for probabilistic, + param1 ~ srn, param2 ~ stn - for multi-scale +@see cv::HoughLines +*/ +CVAPI(CvSeq*) cvHoughLines2( CvArr* image, void* line_storage, int method, + double rho, double theta, int threshold, + double param1 CV_DEFAULT(0), double param2 CV_DEFAULT(0), + double min_theta CV_DEFAULT(0), double max_theta CV_DEFAULT(CV_PI)); + +/** @brief Finds circles in the image +@see cv::HoughCircles +*/ +CVAPI(CvSeq*) cvHoughCircles( CvArr* image, void* circle_storage, + int method, double dp, double min_dist, + double param1 CV_DEFAULT(100), + double param2 CV_DEFAULT(100), + int min_radius CV_DEFAULT(0), + int max_radius CV_DEFAULT(0)); + +/** @brief Fits a line into set of 2d or 3d points in a robust way (M-estimator technique) +@see cv::fitLine +*/ +CVAPI(void) cvFitLine( const CvArr* points, int dist_type, double param, + double reps, double aeps, float* line ); + +/****************************************************************************************\ +* Drawing * +\****************************************************************************************/ + +/****************************************************************************************\ +* Drawing functions work with images/matrices of arbitrary type. * +* For color images the channel order is BGR[A] * +* Antialiasing is supported only for 8-bit image now. * +* All the functions include parameter color that means rgb value (that may be * +* constructed with CV_RGB macro) for color images and brightness * +* for grayscale images. * +* If a drawn figure is partially or completely outside of the image, it is clipped.* +\****************************************************************************************/ + +#define CV_FILLED -1 + +#define CV_AA 16 + +/** @brief Draws 4-connected, 8-connected or antialiased line segment connecting two points +@see cv::line +*/ +CVAPI(void) cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ); + +/** @brief Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2) + + if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn +@see cv::rectangle +*/ +CVAPI(void) cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), + int shift CV_DEFAULT(0)); + +/** @brief Draws a rectangle specified by a CvRect structure +@see cv::rectangle +*/ +CVAPI(void) cvRectangleR( CvArr* img, CvRect r, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), + int shift CV_DEFAULT(0)); + + +/** @brief Draws a circle with specified center and radius. + + Thickness works in the same way as with cvRectangle +@see cv::circle +*/ +CVAPI(void) cvCircle( CvArr* img, CvPoint center, int radius, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0)); + +/** @brief Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector + + depending on _thickness_, _start_angle_ and _end_angle_ parameters. The resultant figure + is rotated by _angle_. All the angles are in degrees +@see cv::ellipse +*/ +CVAPI(void) cvEllipse( CvArr* img, CvPoint center, CvSize axes, + double angle, double start_angle, double end_angle, + CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0)); + +CV_INLINE void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color, + int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ) +{ + CvSize axes = cvSize( + cvRound(box.size.width*0.5), + cvRound(box.size.height*0.5) + ); + + cvEllipse( img, cvPointFrom32f( box.center ), axes, box.angle, + 0, 360, color, thickness, line_type, shift ); +} + +/** @brief Fills convex or monotonous polygon. +@see cv::fillConvexPoly +*/ +CVAPI(void) cvFillConvexPoly( CvArr* img, const CvPoint* pts, int npts, CvScalar color, + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0)); + +/** @brief Fills an area bounded by one or more arbitrary polygons +@see cv::fillPoly +*/ +CVAPI(void) cvFillPoly( CvArr* img, CvPoint** pts, const int* npts, + int contours, CvScalar color, + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ); + +/** @brief Draws one or more polygonal curves +@see cv::polylines +*/ +CVAPI(void) cvPolyLine( CvArr* img, CvPoint** pts, const int* npts, int contours, + int is_closed, CvScalar color, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) ); + +#define cvDrawRect cvRectangle +#define cvDrawLine cvLine +#define cvDrawCircle cvCircle +#define cvDrawEllipse cvEllipse +#define cvDrawPolyLine cvPolyLine + +/** @brief Clips the line segment connecting *pt1 and *pt2 + by the rectangular window + + (0<=xptr will point to pt1 (or pt2, see left_to_right description) location in +the image. Returns the number of pixels on the line between the ending points. +@see cv::LineIterator +*/ +CVAPI(int) cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2, + CvLineIterator* line_iterator, + int connectivity CV_DEFAULT(8), + int left_to_right CV_DEFAULT(0)); + +#define CV_NEXT_LINE_POINT( line_iterator ) \ +{ \ + int _line_iterator_mask = (line_iterator).err < 0 ? -1 : 0; \ + (line_iterator).err += (line_iterator).minus_delta + \ + ((line_iterator).plus_delta & _line_iterator_mask); \ + (line_iterator).ptr += (line_iterator).minus_step + \ + ((line_iterator).plus_step & _line_iterator_mask); \ +} + + +#define CV_FONT_HERSHEY_SIMPLEX 0 +#define CV_FONT_HERSHEY_PLAIN 1 +#define CV_FONT_HERSHEY_DUPLEX 2 +#define CV_FONT_HERSHEY_COMPLEX 3 +#define CV_FONT_HERSHEY_TRIPLEX 4 +#define CV_FONT_HERSHEY_COMPLEX_SMALL 5 +#define CV_FONT_HERSHEY_SCRIPT_SIMPLEX 6 +#define CV_FONT_HERSHEY_SCRIPT_COMPLEX 7 + +#define CV_FONT_ITALIC 16 + +#define CV_FONT_VECTOR0 CV_FONT_HERSHEY_SIMPLEX + + +/** Font structure */ +typedef struct CvFont +{ + const char* nameFont; //Qt:nameFont + CvScalar color; //Qt:ColorFont -> cvScalar(blue_component, green_component, red_component[, alpha_component]) + int font_face; //Qt: bool italic /** =CV_FONT_* */ + const int* ascii; //!< font data and metrics + const int* greek; + const int* cyrillic; + float hscale, vscale; + float shear; //!< slope coefficient: 0 - normal, >0 - italic + int thickness; //!< Qt: weight /** letters thickness */ + float dx; //!< horizontal interval between letters + int line_type; //!< Qt: PointSize +} +CvFont; + +/** @brief Initializes font structure (OpenCV 1.x API). + +The function initializes the font structure that can be passed to text rendering functions. + +@param font Pointer to the font structure initialized by the function +@param font_face Font name identifier. See cv::HersheyFonts and corresponding old CV_* identifiers. +@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 line_type Type of the strokes, see line description + +@sa cvPutText + */ +CVAPI(void) cvInitFont( CvFont* font, int font_face, + double hscale, double vscale, + double shear CV_DEFAULT(0), + int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8)); + +CV_INLINE CvFont cvFont( double scale, int thickness CV_DEFAULT(1) ) +{ + CvFont font; + cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, scale, scale, 0, thickness, CV_AA ); + return font; +} + +/** @brief Renders text stroke with specified font and color at specified location. + CvFont should be initialized with cvInitFont +@see cvInitFont, cvGetTextSize, cvFont, cv::putText +*/ +CVAPI(void) cvPutText( CvArr* img, const char* text, CvPoint org, + const CvFont* font, CvScalar color ); + +/** @brief Calculates bounding box of text stroke (useful for alignment) +@see cv::getTextSize +*/ +CVAPI(void) cvGetTextSize( const char* text_string, const CvFont* font, + CvSize* text_size, int* baseline ); + +/** @brief Unpacks color value + +if arrtype is CV_8UC?, _color_ is treated as packed color value, otherwise the first channels +(depending on arrtype) of destination scalar are set to the same value = _color_ +*/ +CVAPI(CvScalar) cvColorToScalar( double packed_color, int arrtype ); + +/** @brief Returns the polygon points which make up the given ellipse. + +The ellipse is define by the box of size 'axes' rotated 'angle' around the 'center'. A partial +sweep of the ellipse arc can be done by spcifying arc_start and arc_end to be something other than +0 and 360, respectively. The input array 'pts' must be large enough to hold the result. The total +number of points stored into 'pts' is returned by this function. +@see cv::ellipse2Poly +*/ +CVAPI(int) cvEllipse2Poly( CvPoint center, CvSize axes, + int angle, int arc_start, int arc_end, CvPoint * pts, int delta ); + +/** @brief Draws contour outlines or filled interiors on the image +@see cv::drawContours +*/ +CVAPI(void) cvDrawContours( CvArr *img, CvSeq* contour, + CvScalar external_color, CvScalar hole_color, + int max_level, int thickness CV_DEFAULT(1), + int line_type CV_DEFAULT(8), + CvPoint offset CV_DEFAULT(cvPoint(0,0))); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/imgproc/types_c.h b/Prj-Win/3rd/opencv/include/opencv2/imgproc/types_c.h new file mode 100755 index 0000000..d3e55f5 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/imgproc/types_c.h @@ -0,0 +1,659 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_IMGPROC_TYPES_C_H +#define OPENCV_IMGPROC_TYPES_C_H + +#include "opencv2/core/core_c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup imgproc_c + @{ +*/ + +/** Connected component structure */ +typedef struct CvConnectedComp +{ + double area; /** DBL_EPSILON ? 1./std::sqrt(am00) : 0; + } + operator cv::Moments() const + { + return cv::Moments(m00, m10, m01, m20, m11, m02, m30, m21, m12, m03); + } +#endif +} +CvMoments; + +#ifdef __cplusplus +} // extern "C" + +CV_INLINE CvMoments cvMoments() +{ +#if !defined(CV__ENABLE_C_API_CTORS) + CvMoments self = CV_STRUCT_INITIALIZER; return self; +#else + return CvMoments(); +#endif +} + +CV_INLINE CvMoments cvMoments(const cv::Moments& m) +{ +#if !defined(CV__ENABLE_C_API_CTORS) + double am00 = std::abs(m.m00); + CvMoments self = { + m.m00, m.m10, m.m01, m.m20, m.m11, m.m02, m.m30, m.m21, m.m12, m.m03, + m.mu20, m.mu11, m.mu02, m.mu30, m.mu21, m.mu12, m.mu03, + am00 > DBL_EPSILON ? 1./std::sqrt(am00) : 0 + }; + return self; +#else + return CvMoments(m); +#endif +} + +extern "C" { +#endif // __cplusplus + +/** Hu invariants */ +typedef struct CvHuMoments +{ + double hu1, hu2, hu3, hu4, hu5, hu6, hu7; /**< Hu invariants */ +} +CvHuMoments; + +/** Template matching methods */ +enum +{ + CV_TM_SQDIFF =0, + CV_TM_SQDIFF_NORMED =1, + CV_TM_CCORR =2, + CV_TM_CCORR_NORMED =3, + CV_TM_CCOEFF =4, + CV_TM_CCOEFF_NORMED =5 +}; + +typedef float (CV_CDECL * CvDistanceFunction)( const float* a, const float* b, void* user_param ); + +/** Contour retrieval modes */ +enum +{ + CV_RETR_EXTERNAL=0, + CV_RETR_LIST=1, + CV_RETR_CCOMP=2, + CV_RETR_TREE=3, + CV_RETR_FLOODFILL=4 +}; + +/** Contour approximation methods */ +enum +{ + CV_CHAIN_CODE=0, + CV_CHAIN_APPROX_NONE=1, + CV_CHAIN_APPROX_SIMPLE=2, + CV_CHAIN_APPROX_TC89_L1=3, + CV_CHAIN_APPROX_TC89_KCOS=4, + CV_LINK_RUNS=5 +}; + +/* +Internal structure that is used for sequential retrieving contours from the image. +It supports both hierarchical and plane variants of Suzuki algorithm. +*/ +typedef struct _CvContourScanner* CvContourScanner; + +/** Freeman chain reader state */ +typedef struct CvChainPtReader +{ + CV_SEQ_READER_FIELDS() + char code; + CvPoint pt; + schar deltas[8][2]; +} +CvChainPtReader; + +/** initializes 8-element array for fast access to 3x3 neighborhood of a pixel */ +#define CV_INIT_3X3_DELTAS( deltas, step, nch ) \ + ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \ + (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \ + (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \ + (deltas)[6] = (step), (deltas)[7] = (step) + (nch)) + + +/** Contour approximation algorithms */ +enum +{ + CV_POLY_APPROX_DP = 0 +}; + +/** Shape matching methods */ +enum +{ + CV_CONTOURS_MATCH_I1 =1, //!< \f[I_1(A,B) = \sum _{i=1...7} \left | \frac{1}{m^A_i} - \frac{1}{m^B_i} \right |\f] + CV_CONTOURS_MATCH_I2 =2, //!< \f[I_2(A,B) = \sum _{i=1...7} \left | m^A_i - m^B_i \right |\f] + CV_CONTOURS_MATCH_I3 =3 //!< \f[I_3(A,B) = \max _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| }\f] +}; + +/** Shape orientation */ +enum +{ + CV_CLOCKWISE =1, + CV_COUNTER_CLOCKWISE =2 +}; + + +/** 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; + + +/** Histogram comparison methods */ +enum +{ + CV_COMP_CORREL =0, + CV_COMP_CHISQR =1, + CV_COMP_INTERSECT =2, + CV_COMP_BHATTACHARYYA =3, + CV_COMP_HELLINGER =CV_COMP_BHATTACHARYYA, + CV_COMP_CHISQR_ALT =4, + CV_COMP_KL_DIV =5 +}; + +/** Mask size for distance transform */ +enum +{ + CV_DIST_MASK_3 =3, + CV_DIST_MASK_5 =5, + CV_DIST_MASK_PRECISE =0 +}; + +/** Content of output label array: connected components or pixels */ +enum +{ + CV_DIST_LABEL_CCOMP = 0, + CV_DIST_LABEL_PIXEL = 1 +}; + +/** Distance types for Distance Transform and M-estimators */ +enum +{ + CV_DIST_USER =-1, /**< User defined distance */ + CV_DIST_L1 =1, /**< distance = |x1-x2| + |y1-y2| */ + CV_DIST_L2 =2, /**< the simple euclidean distance */ + CV_DIST_C =3, /**< distance = max(|x1-x2|,|y1-y2|) */ + CV_DIST_L12 =4, /**< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1)) */ + CV_DIST_FAIR =5, /**< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998 */ + CV_DIST_WELSCH =6, /**< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846 */ + CV_DIST_HUBER =7 /**< distance = |x| threshold ? max_value : 0 */ + CV_THRESH_BINARY_INV =1, /**< value = value > threshold ? 0 : max_value */ + CV_THRESH_TRUNC =2, /**< value = value > threshold ? threshold : value */ + CV_THRESH_TOZERO =3, /**< value = value > threshold ? value : 0 */ + CV_THRESH_TOZERO_INV =4, /**< value = value > threshold ? 0 : value */ + CV_THRESH_MASK =7, + CV_THRESH_OTSU =8, /**< use Otsu algorithm to choose the optimal threshold value; + combine the flag with one of the above CV_THRESH_* values */ + CV_THRESH_TRIANGLE =16 /**< use Triangle algorithm to choose the optimal threshold value; + combine the flag with one of the above CV_THRESH_* values, but not + with CV_THRESH_OTSU */ +}; + +/** Adaptive threshold methods */ +enum +{ + CV_ADAPTIVE_THRESH_MEAN_C =0, + CV_ADAPTIVE_THRESH_GAUSSIAN_C =1 +}; + +/** FloodFill flags */ +enum +{ + CV_FLOODFILL_FIXED_RANGE =(1 << 16), + CV_FLOODFILL_MASK_ONLY =(1 << 17) +}; + + +/** Canny edge detector flags */ +enum +{ + CV_CANNY_L2_GRADIENT =(1 << 31) +}; + +/** Variants of a Hough transform */ +enum +{ + CV_HOUGH_STANDARD =0, + CV_HOUGH_PROBABILISTIC =1, + CV_HOUGH_MULTI_SCALE =2, + CV_HOUGH_GRADIENT =3 +}; + + +/* Fast search data structures */ +struct CvFeatureTree; +struct CvLSH; +struct CvLSHOperations; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/ml.hpp b/Prj-Win/3rd/opencv/include/opencv2/ml.hpp new file mode 100755 index 0000000..68757f3 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/ml.hpp @@ -0,0 +1,1947 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Copyright (C) 2014, Itseez Inc, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_ML_HPP +#define OPENCV_ML_HPP + +#ifdef __cplusplus +# include "opencv2/core.hpp" +#endif + +#ifdef __cplusplus + +#include +#include +#include + +/** + @defgroup ml Machine Learning + + The Machine Learning Library (MLL) is a set of classes and functions for statistical + classification, regression, and clustering of data. + + Most of the classification and regression algorithms are implemented as C++ classes. As the + algorithms have different sets of features (like an ability to handle missing measurements or + categorical input variables), there is a little common ground between the classes. This common + ground is defined by the class cv::ml::StatModel that all the other ML classes are derived from. + + See detailed overview here: @ref ml_intro. + */ + +namespace cv +{ + +namespace ml +{ + +//! @addtogroup ml +//! @{ + +/** @brief Variable types */ +enum VariableTypes +{ + VAR_NUMERICAL =0, //!< same as VAR_ORDERED + VAR_ORDERED =0, //!< ordered variables + VAR_CATEGORICAL =1 //!< categorical variables +}; + +/** @brief %Error types */ +enum ErrorTypes +{ + TEST_ERROR = 0, + TRAIN_ERROR = 1 +}; + +/** @brief Sample types */ +enum SampleTypes +{ + ROW_SAMPLE = 0, //!< each training sample is a row of samples + COL_SAMPLE = 1 //!< each training sample occupies a column of samples +}; + +/** @brief The structure represents the logarithmic grid range of statmodel parameters. + +It is used for optimizing statmodel accuracy by varying model parameters, the accuracy estimate +being computed by cross-validation. + */ +class CV_EXPORTS_W ParamGrid +{ +public: + /** @brief Default constructor */ + ParamGrid(); + /** @brief Constructor with parameters */ + ParamGrid(double _minVal, double _maxVal, double _logStep); + + CV_PROP_RW double minVal; //!< Minimum value of the statmodel parameter. Default value is 0. + CV_PROP_RW double maxVal; //!< Maximum value of the statmodel parameter. Default value is 0. + /** @brief Logarithmic step for iterating the statmodel parameter. + + The grid determines the following iteration sequence of the statmodel parameter values: + \f[(minVal, minVal*step, minVal*{step}^2, \dots, minVal*{logStep}^n),\f] + where \f$n\f$ is the maximal index satisfying + \f[\texttt{minVal} * \texttt{logStep} ^n < \texttt{maxVal}\f] + The grid is logarithmic, so logStep must always be greater than 1. Default value is 1. + */ + CV_PROP_RW double logStep; + + /** @brief Creates a ParamGrid Ptr that can be given to the %SVM::trainAuto method + + @param minVal minimum value of the parameter grid + @param maxVal maximum value of the parameter grid + @param logstep Logarithmic step for iterating the statmodel parameter + */ + CV_WRAP static Ptr create(double minVal=0., double maxVal=0., double logstep=1.); +}; + +/** @brief Class encapsulating training data. + +Please note that the class only specifies the interface of training data, but not implementation. +All the statistical model classes in _ml_ module accepts Ptr\ as parameter. In other +words, you can create your own class derived from TrainData and pass smart pointer to the instance +of this class into StatModel::train. + +@sa @ref ml_intro_data + */ +class CV_EXPORTS_W TrainData +{ +public: + static inline float missingValue() { return FLT_MAX; } + virtual ~TrainData(); + + CV_WRAP virtual int getLayout() const = 0; + CV_WRAP virtual int getNTrainSamples() const = 0; + CV_WRAP virtual int getNTestSamples() const = 0; + CV_WRAP virtual int getNSamples() const = 0; + CV_WRAP virtual int getNVars() const = 0; + CV_WRAP virtual int getNAllVars() const = 0; + + CV_WRAP virtual void getSample(InputArray varIdx, int sidx, float* buf) const = 0; + CV_WRAP virtual Mat getSamples() const = 0; + CV_WRAP virtual Mat getMissing() const = 0; + + /** @brief Returns matrix of train samples + + @param layout The requested layout. If it's different from the initial one, the matrix is + transposed. See ml::SampleTypes. + @param compressSamples if true, the function returns only the training samples (specified by + sampleIdx) + @param compressVars if true, the function returns the shorter training samples, containing only + the active variables. + + In current implementation the function tries to avoid physical data copying and returns the + matrix stored inside TrainData (unless the transposition or compression is needed). + */ + CV_WRAP virtual Mat getTrainSamples(int layout=ROW_SAMPLE, + bool compressSamples=true, + bool compressVars=true) const = 0; + + /** @brief Returns the vector of responses + + The function returns ordered or the original categorical responses. Usually it's used in + regression algorithms. + */ + CV_WRAP virtual Mat getTrainResponses() const = 0; + + /** @brief Returns the vector of normalized categorical responses + + The function returns vector of responses. Each response is integer from `0` to `-1`. The actual label value can be retrieved then from the class label vector, see + TrainData::getClassLabels. + */ + CV_WRAP virtual Mat getTrainNormCatResponses() const = 0; + CV_WRAP virtual Mat getTestResponses() const = 0; + CV_WRAP virtual Mat getTestNormCatResponses() const = 0; + CV_WRAP virtual Mat getResponses() const = 0; + CV_WRAP virtual Mat getNormCatResponses() const = 0; + CV_WRAP virtual Mat getSampleWeights() const = 0; + CV_WRAP virtual Mat getTrainSampleWeights() const = 0; + CV_WRAP virtual Mat getTestSampleWeights() const = 0; + CV_WRAP virtual Mat getVarIdx() const = 0; + CV_WRAP virtual Mat getVarType() const = 0; + CV_WRAP virtual Mat getVarSymbolFlags() const = 0; + CV_WRAP virtual int getResponseType() const = 0; + CV_WRAP virtual Mat getTrainSampleIdx() const = 0; + CV_WRAP virtual Mat getTestSampleIdx() const = 0; + CV_WRAP virtual void getValues(int vi, InputArray sidx, float* values) const = 0; + virtual void getNormCatValues(int vi, InputArray sidx, int* values) const = 0; + CV_WRAP virtual Mat getDefaultSubstValues() const = 0; + + CV_WRAP virtual int getCatCount(int vi) const = 0; + + /** @brief Returns the vector of class labels + + The function returns vector of unique labels occurred in the responses. + */ + CV_WRAP virtual Mat getClassLabels() const = 0; + + CV_WRAP virtual Mat getCatOfs() const = 0; + CV_WRAP virtual Mat getCatMap() const = 0; + + /** @brief Splits the training data into the training and test parts + @sa TrainData::setTrainTestSplitRatio + */ + CV_WRAP virtual void setTrainTestSplit(int count, bool shuffle=true) = 0; + + /** @brief Splits the training data into the training and test parts + + The function selects a subset of specified relative size and then returns it as the training + set. If the function is not called, all the data is used for training. Please, note that for + each of TrainData::getTrain\* there is corresponding TrainData::getTest\*, so that the test + subset can be retrieved and processed as well. + @sa TrainData::setTrainTestSplit + */ + CV_WRAP virtual void setTrainTestSplitRatio(double ratio, bool shuffle=true) = 0; + CV_WRAP virtual void shuffleTrainTest() = 0; + + /** @brief Returns matrix of test samples */ + CV_WRAP virtual Mat getTestSamples() const = 0; + + /** @brief Returns vector of symbolic names captured in loadFromCSV() */ + CV_WRAP virtual void getNames(std::vector& names) const = 0; + + /** @brief Extract from 1D vector elements specified by passed indexes. + @param vec input vector (supported types: CV_32S, CV_32F, CV_64F) + @param idx 1D index vector + */ + static CV_WRAP Mat getSubVector(const Mat& vec, const Mat& idx); + + /** @brief Extract from matrix rows/cols specified by passed indexes. + @param matrix input matrix (supported types: CV_32S, CV_32F, CV_64F) + @param idx 1D index vector + @param layout specifies to extract rows (cv::ml::ROW_SAMPLES) or to extract columns (cv::ml::COL_SAMPLES) + */ + static CV_WRAP Mat getSubMatrix(const Mat& matrix, const Mat& idx, int layout); + + /** @brief Reads the dataset from a .csv file and returns the ready-to-use training data. + + @param filename The input file name + @param headerLineCount The number of lines in the beginning to skip; besides the header, the + function also skips empty lines and lines staring with `#` + @param responseStartIdx Index of the first output variable. If -1, the function considers the + last variable as the response + @param responseEndIdx Index of the last output variable + 1. If -1, then there is single + response variable at responseStartIdx. + @param varTypeSpec The optional text string that specifies the variables' types. It has the + format `ord[n1-n2,n3,n4-n5,...]cat[n6,n7-n8,...]`. That is, variables from `n1 to n2` + (inclusive range), `n3`, `n4 to n5` ... are considered ordered and `n6`, `n7 to n8` ... are + considered as categorical. The range `[n1..n2] + [n3] + [n4..n5] + ... + [n6] + [n7..n8]` + should cover all the variables. If varTypeSpec is not specified, then algorithm uses the + following rules: + - all input variables are considered ordered by default. If some column contains has non- + numerical values, e.g. 'apple', 'pear', 'apple', 'apple', 'mango', the corresponding + variable is considered categorical. + - if there are several output variables, they are all considered as ordered. Error is + reported when non-numerical values are used. + - if there is a single output variable, then if its values are non-numerical or are all + integers, then it's considered categorical. Otherwise, it's considered ordered. + @param delimiter The character used to separate values in each line. + @param missch The character used to specify missing measurements. It should not be a digit. + Although it's a non-numerical value, it surely does not affect the decision of whether the + variable ordered or categorical. + @note If the dataset only contains input variables and no responses, use responseStartIdx = -2 + and responseEndIdx = 0. The output variables vector will just contain zeros. + */ + static Ptr loadFromCSV(const String& filename, + int headerLineCount, + int responseStartIdx=-1, + int responseEndIdx=-1, + const String& varTypeSpec=String(), + char delimiter=',', + char missch='?'); + + /** @brief Creates training data from in-memory arrays. + + @param samples matrix of samples. It should have CV_32F type. + @param layout see ml::SampleTypes. + @param responses matrix of responses. If the responses are scalar, they should be stored as a + single row or as a single column. The matrix should have type CV_32F or CV_32S (in the + former case the responses are considered as ordered by default; in the latter case - as + categorical) + @param varIdx vector specifying which variables to use for training. It can be an integer vector + (CV_32S) containing 0-based variable indices or byte vector (CV_8U) containing a mask of + active variables. + @param sampleIdx vector specifying which samples to use for training. It can be an integer + vector (CV_32S) containing 0-based sample indices or byte vector (CV_8U) containing a mask + of training samples. + @param sampleWeights optional vector with weights for each sample. It should have CV_32F type. + @param varType optional vector of type CV_8U and size ` + + `, containing types of each input and output variable. See + ml::VariableTypes. + */ + CV_WRAP static Ptr create(InputArray samples, int layout, InputArray responses, + InputArray varIdx=noArray(), InputArray sampleIdx=noArray(), + InputArray sampleWeights=noArray(), InputArray varType=noArray()); +}; + +/** @brief Base class for statistical models in OpenCV ML. + */ +class CV_EXPORTS_W StatModel : public Algorithm +{ +public: + /** Predict options */ + enum Flags { + UPDATE_MODEL = 1, + RAW_OUTPUT=1, //!< makes the method return the raw results (the sum), not the class label + COMPRESSED_INPUT=2, + PREPROCESSED_INPUT=4 + }; + + /** @brief Returns the number of variables in training samples */ + CV_WRAP virtual int getVarCount() const = 0; + + CV_WRAP virtual bool empty() const CV_OVERRIDE; + + /** @brief Returns true if the model is trained */ + CV_WRAP virtual bool isTrained() const = 0; + /** @brief Returns true if the model is classifier */ + CV_WRAP virtual bool isClassifier() const = 0; + + /** @brief Trains the statistical model + + @param trainData training data that can be loaded from file using TrainData::loadFromCSV or + created with TrainData::create. + @param flags optional flags, depending on the model. Some of the models can be updated with the + new training samples, not completely overwritten (such as NormalBayesClassifier or ANN_MLP). + */ + CV_WRAP virtual bool train( const Ptr& trainData, int flags=0 ); + + /** @brief Trains the statistical model + + @param samples training samples + @param layout See ml::SampleTypes. + @param responses vector of responses associated with the training samples. + */ + CV_WRAP virtual bool train( InputArray samples, int layout, InputArray responses ); + + /** @brief Computes error on the training or test dataset + + @param data the training data + @param test if true, the error is computed over the test subset of the data, otherwise it's + computed over the training subset of the data. Please note that if you loaded a completely + different dataset to evaluate already trained classifier, you will probably want not to set + the test subset at all with TrainData::setTrainTestSplitRatio and specify test=false, so + that the error is computed for the whole new set. Yes, this sounds a bit confusing. + @param resp the optional output responses. + + The method uses StatModel::predict to compute the error. For regression models the error is + computed as RMS, for classifiers - as a percent of missclassified samples (0%-100%). + */ + CV_WRAP virtual float calcError( const Ptr& data, bool test, OutputArray resp ) const; + + /** @brief Predicts response(s) for the provided sample(s) + + @param samples The input samples, floating-point matrix + @param results The optional output matrix of results. + @param flags The optional flags, model-dependent. See cv::ml::StatModel::Flags. + */ + CV_WRAP virtual float predict( InputArray samples, OutputArray results=noArray(), int flags=0 ) const = 0; + + /** @brief Create and train model with default parameters + + The class must implement static `create()` method with no parameters or with all default parameter values + */ + template static Ptr<_Tp> train(const Ptr& data, int flags=0) + { + Ptr<_Tp> model = _Tp::create(); + return !model.empty() && model->train(data, flags) ? model : Ptr<_Tp>(); + } +}; + +/****************************************************************************************\ +* Normal Bayes Classifier * +\****************************************************************************************/ + +/** @brief Bayes classifier for normally distributed data. + +@sa @ref ml_intro_bayes + */ +class CV_EXPORTS_W NormalBayesClassifier : public StatModel +{ +public: + /** @brief Predicts the response for sample(s). + + The method estimates the most probable classes for input vectors. Input vectors (one or more) + are stored as rows of the matrix inputs. In case of multiple input vectors, there should be one + output vector outputs. The predicted class for a single input vector is returned by the method. + The vector outputProbs contains the output probabilities corresponding to each element of + result. + */ + CV_WRAP virtual float predictProb( InputArray inputs, OutputArray outputs, + OutputArray outputProbs, int flags=0 ) const = 0; + + /** Creates empty model + Use StatModel::train to train the model after creation. */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized NormalBayesClassifier from a file + * + * Use NormalBayesClassifier::save to serialize and store an NormalBayesClassifier to disk. + * Load the NormalBayesClassifier from this file again, by calling this function with the path to the file. + * Optionally specify the node for the file containing the classifier + * + * @param filepath path to serialized NormalBayesClassifier + * @param nodeName name of node containing the classifier + */ + CV_WRAP static Ptr load(const String& filepath , const String& nodeName = String()); +}; + +/****************************************************************************************\ +* K-Nearest Neighbour Classifier * +\****************************************************************************************/ + +/** @brief The class implements K-Nearest Neighbors model + +@sa @ref ml_intro_knn + */ +class CV_EXPORTS_W KNearest : public StatModel +{ +public: + + /** Default number of neighbors to use in predict method. */ + /** @see setDefaultK */ + CV_WRAP virtual int getDefaultK() const = 0; + /** @copybrief getDefaultK @see getDefaultK */ + CV_WRAP virtual void setDefaultK(int val) = 0; + + /** Whether classification or regression model should be trained. */ + /** @see setIsClassifier */ + CV_WRAP virtual bool getIsClassifier() const = 0; + /** @copybrief getIsClassifier @see getIsClassifier */ + CV_WRAP virtual void setIsClassifier(bool val) = 0; + + /** Parameter for KDTree implementation. */ + /** @see setEmax */ + CV_WRAP virtual int getEmax() const = 0; + /** @copybrief getEmax @see getEmax */ + CV_WRAP virtual void setEmax(int val) = 0; + + /** %Algorithm type, one of KNearest::Types. */ + /** @see setAlgorithmType */ + CV_WRAP virtual int getAlgorithmType() const = 0; + /** @copybrief getAlgorithmType @see getAlgorithmType */ + CV_WRAP virtual void setAlgorithmType(int val) = 0; + + /** @brief Finds the neighbors and predicts responses for input vectors. + + @param samples Input samples stored by rows. It is a single-precision floating-point matrix of + ` * k` size. + @param k Number of used nearest neighbors. Should be greater than 1. + @param results Vector with results of prediction (regression or classification) for each input + sample. It is a single-precision floating-point vector with `` elements. + @param neighborResponses Optional output values for corresponding neighbors. It is a single- + precision floating-point matrix of ` * k` size. + @param dist Optional output distances from the input vectors to the corresponding neighbors. It + is a single-precision floating-point matrix of ` * k` size. + + For each input vector (a row of the matrix samples), the method finds the k nearest neighbors. + In case of regression, the predicted result is a mean value of the particular vector's neighbor + responses. In case of classification, the class is determined by voting. + + For each input vector, the neighbors are sorted by their distances to the vector. + + In case of C++ interface you can use output pointers to empty matrices and the function will + allocate memory itself. + + If only a single input vector is passed, all output matrices are optional and the predicted + value is returned by the method. + + The function is parallelized with the TBB library. + */ + CV_WRAP virtual float findNearest( InputArray samples, int k, + OutputArray results, + OutputArray neighborResponses=noArray(), + OutputArray dist=noArray() ) const = 0; + + /** @brief Implementations of KNearest algorithm + */ + enum Types + { + BRUTE_FORCE=1, + KDTREE=2 + }; + + /** @brief Creates the empty model + + The static method creates empty %KNearest classifier. It should be then trained using StatModel::train method. + */ + CV_WRAP static Ptr create(); + /** @brief Loads and creates a serialized knearest from a file + * + * Use KNearest::save to serialize and store an KNearest to disk. + * Load the KNearest from this file again, by calling this function with the path to the file. + * + * @param filepath path to serialized KNearest + */ + CV_WRAP static Ptr load(const String& filepath); +}; + +/****************************************************************************************\ +* Support Vector Machines * +\****************************************************************************************/ + +/** @brief Support Vector Machines. + +@sa @ref ml_intro_svm + */ +class CV_EXPORTS_W SVM : public StatModel +{ +public: + + class CV_EXPORTS Kernel : public Algorithm + { + public: + virtual int getType() const = 0; + virtual void calc( int vcount, int n, const float* vecs, const float* another, float* results ) = 0; + }; + + /** Type of a %SVM formulation. + See SVM::Types. Default value is SVM::C_SVC. */ + /** @see setType */ + CV_WRAP virtual int getType() const = 0; + /** @copybrief getType @see getType */ + CV_WRAP virtual void setType(int val) = 0; + + /** Parameter \f$\gamma\f$ of a kernel function. + For SVM::POLY, SVM::RBF, SVM::SIGMOID or SVM::CHI2. Default value is 1. */ + /** @see setGamma */ + CV_WRAP virtual double getGamma() const = 0; + /** @copybrief getGamma @see getGamma */ + CV_WRAP virtual void setGamma(double val) = 0; + + /** Parameter _coef0_ of a kernel function. + For SVM::POLY or SVM::SIGMOID. Default value is 0.*/ + /** @see setCoef0 */ + CV_WRAP virtual double getCoef0() const = 0; + /** @copybrief getCoef0 @see getCoef0 */ + CV_WRAP virtual void setCoef0(double val) = 0; + + /** Parameter _degree_ of a kernel function. + For SVM::POLY. Default value is 0. */ + /** @see setDegree */ + CV_WRAP virtual double getDegree() const = 0; + /** @copybrief getDegree @see getDegree */ + CV_WRAP virtual void setDegree(double val) = 0; + + /** Parameter _C_ of a %SVM optimization problem. + For SVM::C_SVC, SVM::EPS_SVR or SVM::NU_SVR. Default value is 0. */ + /** @see setC */ + CV_WRAP virtual double getC() const = 0; + /** @copybrief getC @see getC */ + CV_WRAP virtual void setC(double val) = 0; + + /** Parameter \f$\nu\f$ of a %SVM optimization problem. + For SVM::NU_SVC, SVM::ONE_CLASS or SVM::NU_SVR. Default value is 0. */ + /** @see setNu */ + CV_WRAP virtual double getNu() const = 0; + /** @copybrief getNu @see getNu */ + CV_WRAP virtual void setNu(double val) = 0; + + /** Parameter \f$\epsilon\f$ of a %SVM optimization problem. + For SVM::EPS_SVR. Default value is 0. */ + /** @see setP */ + CV_WRAP virtual double getP() const = 0; + /** @copybrief getP @see getP */ + CV_WRAP virtual void setP(double val) = 0; + + /** Optional weights in the SVM::C_SVC problem, assigned to particular classes. + They are multiplied by _C_ so the parameter _C_ of class _i_ becomes `classWeights(i) * C`. Thus + these weights affect the misclassification penalty for different classes. The larger weight, + the larger penalty on misclassification of data from the corresponding class. Default value is + empty Mat. */ + /** @see setClassWeights */ + CV_WRAP virtual cv::Mat getClassWeights() const = 0; + /** @copybrief getClassWeights @see getClassWeights */ + CV_WRAP virtual void setClassWeights(const cv::Mat &val) = 0; + + /** Termination criteria of the iterative %SVM training procedure which solves a partial + case of constrained quadratic optimization problem. + You can specify tolerance and/or the maximum number of iterations. Default value is + `TermCriteria( TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, FLT_EPSILON )`; */ + /** @see setTermCriteria */ + CV_WRAP virtual cv::TermCriteria getTermCriteria() const = 0; + /** @copybrief getTermCriteria @see getTermCriteria */ + CV_WRAP virtual void setTermCriteria(const cv::TermCriteria &val) = 0; + + /** Type of a %SVM kernel. + See SVM::KernelTypes. Default value is SVM::RBF. */ + CV_WRAP virtual int getKernelType() const = 0; + + /** Initialize with one of predefined kernels. + See SVM::KernelTypes. */ + CV_WRAP virtual void setKernel(int kernelType) = 0; + + /** Initialize with custom kernel. + See SVM::Kernel class for implementation details */ + virtual void setCustomKernel(const Ptr &_kernel) = 0; + + //! %SVM type + enum Types { + /** C-Support Vector Classification. n-class classification (n \f$\geq\f$ 2), allows + imperfect separation of classes with penalty multiplier C for outliers. */ + C_SVC=100, + /** \f$\nu\f$-Support Vector Classification. n-class classification with possible + imperfect separation. Parameter \f$\nu\f$ (in the range 0..1, the larger the value, the smoother + the decision boundary) is used instead of C. */ + NU_SVC=101, + /** Distribution Estimation (One-class %SVM). All the training data are from + the same class, %SVM builds a boundary that separates the class from the rest of the feature + space. */ + ONE_CLASS=102, + /** \f$\epsilon\f$-Support Vector Regression. The distance between feature vectors + from the training set and the fitting hyper-plane must be less than p. For outliers the + penalty multiplier C is used. */ + EPS_SVR=103, + /** \f$\nu\f$-Support Vector Regression. \f$\nu\f$ is used instead of p. + See @cite LibSVM for details. */ + NU_SVR=104 + }; + + /** @brief %SVM kernel type + + A comparison of different kernels on the following 2D test case with four classes. Four + SVM::C_SVC SVMs have been trained (one against rest) with auto_train. Evaluation on three + different kernels (SVM::CHI2, SVM::INTER, SVM::RBF). The color depicts the class with max score. + Bright means max-score \> 0, dark means max-score \< 0. + ![image](pics/SVM_Comparison.png) + */ + enum KernelTypes { + /** Returned by SVM::getKernelType in case when custom kernel has been set */ + CUSTOM=-1, + /** Linear kernel. No mapping is done, linear discrimination (or regression) is + done in the original feature space. It is the fastest option. \f$K(x_i, x_j) = x_i^T x_j\f$. */ + LINEAR=0, + /** Polynomial kernel: + \f$K(x_i, x_j) = (\gamma x_i^T x_j + coef0)^{degree}, \gamma > 0\f$. */ + POLY=1, + /** Radial basis function (RBF), a good choice in most cases. + \f$K(x_i, x_j) = e^{-\gamma ||x_i - x_j||^2}, \gamma > 0\f$. */ + RBF=2, + /** Sigmoid kernel: \f$K(x_i, x_j) = \tanh(\gamma x_i^T x_j + coef0)\f$. */ + SIGMOID=3, + /** Exponential Chi2 kernel, similar to the RBF kernel: + \f$K(x_i, x_j) = e^{-\gamma \chi^2(x_i,x_j)}, \chi^2(x_i,x_j) = (x_i-x_j)^2/(x_i+x_j), \gamma > 0\f$. */ + CHI2=4, + /** Histogram intersection kernel. A fast kernel. \f$K(x_i, x_j) = min(x_i,x_j)\f$. */ + INTER=5 + }; + + //! %SVM params type + enum ParamTypes { + C=0, + GAMMA=1, + P=2, + NU=3, + COEF=4, + DEGREE=5 + }; + + /** @brief Trains an %SVM with optimal parameters. + + @param data the training data that can be constructed using TrainData::create or + TrainData::loadFromCSV. + @param kFold Cross-validation parameter. The training set is divided into kFold subsets. One + subset is used to test the model, the others form the train set. So, the %SVM algorithm is + executed kFold times. + @param Cgrid grid for C + @param gammaGrid grid for gamma + @param pGrid grid for p + @param nuGrid grid for nu + @param coeffGrid grid for coeff + @param degreeGrid grid for degree + @param balanced If true and the problem is 2-class classification then the method creates more + balanced cross-validation subsets that is proportions between classes in subsets are close + to such proportion in the whole train dataset. + + The method trains the %SVM model automatically by choosing the optimal parameters C, gamma, p, + nu, coef0, degree. Parameters are considered optimal when the cross-validation + estimate of the test set error is minimal. + + If there is no need to optimize a parameter, the corresponding grid step should be set to any + value less than or equal to 1. For example, to avoid optimization in gamma, set `gammaGrid.step + = 0`, `gammaGrid.minVal`, `gamma_grid.maxVal` as arbitrary numbers. In this case, the value + `Gamma` is taken for gamma. + + And, finally, if the optimization in a parameter is required but the corresponding grid is + unknown, you may call the function SVM::getDefaultGrid. To generate a grid, for example, for + gamma, call `SVM::getDefaultGrid(SVM::GAMMA)`. + + This function works for the classification (SVM::C_SVC or SVM::NU_SVC) as well as for the + regression (SVM::EPS_SVR or SVM::NU_SVR). If it is SVM::ONE_CLASS, no optimization is made and + the usual %SVM with parameters specified in params is executed. + */ + virtual bool trainAuto( const Ptr& data, int kFold = 10, + ParamGrid Cgrid = getDefaultGrid(C), + ParamGrid gammaGrid = getDefaultGrid(GAMMA), + ParamGrid pGrid = getDefaultGrid(P), + ParamGrid nuGrid = getDefaultGrid(NU), + ParamGrid coeffGrid = getDefaultGrid(COEF), + ParamGrid degreeGrid = getDefaultGrid(DEGREE), + bool balanced=false) = 0; + + /** @brief Trains an %SVM with optimal parameters + + @param samples training samples + @param layout See ml::SampleTypes. + @param responses vector of responses associated with the training samples. + @param kFold Cross-validation parameter. The training set is divided into kFold subsets. One + subset is used to test the model, the others form the train set. So, the %SVM algorithm is + @param Cgrid grid for C + @param gammaGrid grid for gamma + @param pGrid grid for p + @param nuGrid grid for nu + @param coeffGrid grid for coeff + @param degreeGrid grid for degree + @param balanced If true and the problem is 2-class classification then the method creates more + balanced cross-validation subsets that is proportions between classes in subsets are close + to such proportion in the whole train dataset. + + The method trains the %SVM model automatically by choosing the optimal parameters C, gamma, p, + nu, coef0, degree. Parameters are considered optimal when the cross-validation + estimate of the test set error is minimal. + + This function only makes use of SVM::getDefaultGrid for parameter optimization and thus only + offers rudimentary parameter options. + + This function works for the classification (SVM::C_SVC or SVM::NU_SVC) as well as for the + regression (SVM::EPS_SVR or SVM::NU_SVR). If it is SVM::ONE_CLASS, no optimization is made and + the usual %SVM with parameters specified in params is executed. + */ + CV_WRAP virtual bool trainAuto(InputArray samples, + int layout, + InputArray responses, + int kFold = 10, + Ptr Cgrid = SVM::getDefaultGridPtr(SVM::C), + Ptr gammaGrid = SVM::getDefaultGridPtr(SVM::GAMMA), + Ptr pGrid = SVM::getDefaultGridPtr(SVM::P), + Ptr nuGrid = SVM::getDefaultGridPtr(SVM::NU), + Ptr coeffGrid = SVM::getDefaultGridPtr(SVM::COEF), + Ptr degreeGrid = SVM::getDefaultGridPtr(SVM::DEGREE), + bool balanced=false) = 0; + + /** @brief Retrieves all the support vectors + + The method returns all the support vectors as a floating-point matrix, where support vectors are + stored as matrix rows. + */ + CV_WRAP virtual Mat getSupportVectors() const = 0; + + /** @brief Retrieves all the uncompressed support vectors of a linear %SVM + + The method returns all the uncompressed support vectors of a linear %SVM that the compressed + support vector, used for prediction, was derived from. They are returned in a floating-point + matrix, where the support vectors are stored as matrix rows. + */ + CV_WRAP virtual Mat getUncompressedSupportVectors() const = 0; + + /** @brief Retrieves the decision function + + @param i the index of the decision function. If the problem solved is regression, 1-class or + 2-class classification, then there will be just one decision function and the index should + always be 0. Otherwise, in the case of N-class classification, there will be \f$N(N-1)/2\f$ + decision functions. + @param alpha the optional output vector for weights, corresponding to different support vectors. + In the case of linear %SVM all the alpha's will be 1's. + @param svidx the optional output vector of indices of support vectors within the matrix of + support vectors (which can be retrieved by SVM::getSupportVectors). In the case of linear + %SVM each decision function consists of a single "compressed" support vector. + + The method returns rho parameter of the decision function, a scalar subtracted from the weighted + sum of kernel responses. + */ + CV_WRAP virtual double getDecisionFunction(int i, OutputArray alpha, OutputArray svidx) const = 0; + + /** @brief Generates a grid for %SVM parameters. + + @param param_id %SVM parameters IDs that must be one of the SVM::ParamTypes. The grid is + generated for the parameter with this ID. + + The function generates a grid for the specified parameter of the %SVM algorithm. The grid may be + passed to the function SVM::trainAuto. + */ + static ParamGrid getDefaultGrid( int param_id ); + + /** @brief Generates a grid for %SVM parameters. + + @param param_id %SVM parameters IDs that must be one of the SVM::ParamTypes. The grid is + generated for the parameter with this ID. + + The function generates a grid pointer for the specified parameter of the %SVM algorithm. + The grid may be passed to the function SVM::trainAuto. + */ + CV_WRAP static Ptr getDefaultGridPtr( int param_id ); + + /** Creates empty model. + Use StatModel::train to train the model. Since %SVM has several parameters, you may want to + find the best parameters for your problem, it can be done with SVM::trainAuto. */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized svm from a file + * + * Use SVM::save to serialize and store an SVM to disk. + * Load the SVM from this file again, by calling this function with the path to the file. + * + * @param filepath path to serialized svm + */ + CV_WRAP static Ptr load(const String& filepath); +}; + +/****************************************************************************************\ +* Expectation - Maximization * +\****************************************************************************************/ + +/** @brief The class implements the Expectation Maximization algorithm. + +@sa @ref ml_intro_em + */ +class CV_EXPORTS_W EM : public StatModel +{ +public: + //! Type of covariation matrices + enum Types { + /** A scaled identity matrix \f$\mu_k * I\f$. There is the only + parameter \f$\mu_k\f$ to be estimated for each matrix. The option may be used in special cases, + when the constraint is relevant, or as a first step in the optimization (for example in case + when the data is preprocessed with PCA). The results of such preliminary estimation may be + passed again to the optimization procedure, this time with + covMatType=EM::COV_MAT_DIAGONAL. */ + COV_MAT_SPHERICAL=0, + /** A diagonal matrix with positive diagonal elements. The number of + free parameters is d for each matrix. This is most commonly used option yielding good + estimation results. */ + COV_MAT_DIAGONAL=1, + /** A symmetric positively defined matrix. The number of free + parameters in each matrix is about \f$d^2/2\f$. It is not recommended to use this option, unless + there is pretty accurate initial estimation of the parameters and/or a huge number of + training samples. */ + COV_MAT_GENERIC=2, + COV_MAT_DEFAULT=COV_MAT_DIAGONAL + }; + + //! Default parameters + enum {DEFAULT_NCLUSTERS=5, DEFAULT_MAX_ITERS=100}; + + //! The initial step + enum {START_E_STEP=1, START_M_STEP=2, START_AUTO_STEP=0}; + + /** The number of mixture components in the Gaussian mixture model. + Default value of the parameter is EM::DEFAULT_NCLUSTERS=5. Some of %EM implementation could + determine the optimal number of mixtures within a specified value range, but that is not the + case in ML yet. */ + /** @see setClustersNumber */ + CV_WRAP virtual int getClustersNumber() const = 0; + /** @copybrief getClustersNumber @see getClustersNumber */ + CV_WRAP virtual void setClustersNumber(int val) = 0; + + /** Constraint on covariance matrices which defines type of matrices. + See EM::Types. */ + /** @see setCovarianceMatrixType */ + CV_WRAP virtual int getCovarianceMatrixType() const = 0; + /** @copybrief getCovarianceMatrixType @see getCovarianceMatrixType */ + CV_WRAP virtual void setCovarianceMatrixType(int val) = 0; + + /** The termination criteria of the %EM algorithm. + The %EM algorithm can be terminated by the number of iterations termCrit.maxCount (number of + M-steps) or when relative change of likelihood logarithm is less than termCrit.epsilon. Default + maximum number of iterations is EM::DEFAULT_MAX_ITERS=100. */ + /** @see setTermCriteria */ + CV_WRAP virtual TermCriteria getTermCriteria() const = 0; + /** @copybrief getTermCriteria @see getTermCriteria */ + CV_WRAP virtual void setTermCriteria(const TermCriteria &val) = 0; + + /** @brief Returns weights of the mixtures + + Returns vector with the number of elements equal to the number of mixtures. + */ + CV_WRAP virtual Mat getWeights() const = 0; + /** @brief Returns the cluster centers (means of the Gaussian mixture) + + Returns matrix with the number of rows equal to the number of mixtures and number of columns + equal to the space dimensionality. + */ + CV_WRAP virtual Mat getMeans() const = 0; + /** @brief Returns covariation matrices + + Returns vector of covariation matrices. Number of matrices is the number of gaussian mixtures, + each matrix is a square floating-point matrix NxN, where N is the space dimensionality. + */ + CV_WRAP virtual void getCovs(CV_OUT std::vector& covs) const = 0; + + /** @brief Returns posterior probabilities for the provided samples + + @param samples The input samples, floating-point matrix + @param results The optional output \f$ nSamples \times nClusters\f$ matrix of results. It contains + posterior probabilities for each sample from the input + @param flags This parameter will be ignored + */ + CV_WRAP virtual float predict( InputArray samples, OutputArray results=noArray(), int flags=0 ) const CV_OVERRIDE = 0; + + /** @brief Returns a likelihood logarithm value and an index of the most probable mixture component + for the given sample. + + @param sample A sample for classification. It should be a one-channel matrix of + \f$1 \times dims\f$ or \f$dims \times 1\f$ size. + @param probs Optional output matrix that contains posterior probabilities of each component + given the sample. It has \f$1 \times nclusters\f$ size and CV_64FC1 type. + + The method returns a two-element double vector. Zero element is a likelihood logarithm value for + the sample. First element is an index of the most probable mixture component for the given + sample. + */ + CV_WRAP virtual Vec2d predict2(InputArray sample, OutputArray probs) const = 0; + + /** @brief Estimate the Gaussian mixture parameters from a samples set. + + This variation starts with Expectation step. Initial values of the model parameters will be + estimated by the k-means algorithm. + + Unlike many of the ML models, %EM is an unsupervised learning algorithm and it does not take + responses (class labels or function values) as input. Instead, it computes the *Maximum + Likelihood Estimate* of the Gaussian mixture parameters from an input sample set, stores all the + parameters inside the structure: \f$p_{i,k}\f$ in probs, \f$a_k\f$ in means , \f$S_k\f$ in + covs[k], \f$\pi_k\f$ in weights , and optionally computes the output "class label" for each + sample: \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most + probable mixture component for each sample). + + The trained model can be used further for prediction, just like any other classifier. The + trained model is similar to the NormalBayesClassifier. + + @param samples Samples from which the Gaussian mixture model will be estimated. It should be a + one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type + it will be converted to the inner matrix of such type for the further computing. + @param logLikelihoods The optional output matrix that contains a likelihood logarithm value for + each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type. + @param labels The optional output "class label" for each sample: + \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most probable + mixture component for each sample). It has \f$nsamples \times 1\f$ size and CV_32SC1 type. + @param probs The optional output matrix that contains posterior probabilities of each Gaussian + mixture component given the each sample. It has \f$nsamples \times nclusters\f$ size and + CV_64FC1 type. + */ + CV_WRAP virtual bool trainEM(InputArray samples, + OutputArray logLikelihoods=noArray(), + OutputArray labels=noArray(), + OutputArray probs=noArray()) = 0; + + /** @brief Estimate the Gaussian mixture parameters from a samples set. + + This variation starts with Expectation step. You need to provide initial means \f$a_k\f$ of + mixture components. Optionally you can pass initial weights \f$\pi_k\f$ and covariance matrices + \f$S_k\f$ of mixture components. + + @param samples Samples from which the Gaussian mixture model will be estimated. It should be a + one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type + it will be converted to the inner matrix of such type for the further computing. + @param means0 Initial means \f$a_k\f$ of mixture components. It is a one-channel matrix of + \f$nclusters \times dims\f$ size. If the matrix does not have CV_64F type it will be + converted to the inner matrix of such type for the further computing. + @param covs0 The vector of initial covariance matrices \f$S_k\f$ of mixture components. Each of + covariance matrices is a one-channel matrix of \f$dims \times dims\f$ size. If the matrices + do not have CV_64F type they will be converted to the inner matrices of such type for the + further computing. + @param weights0 Initial weights \f$\pi_k\f$ of mixture components. It should be a one-channel + floating-point matrix with \f$1 \times nclusters\f$ or \f$nclusters \times 1\f$ size. + @param logLikelihoods The optional output matrix that contains a likelihood logarithm value for + each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type. + @param labels The optional output "class label" for each sample: + \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most probable + mixture component for each sample). It has \f$nsamples \times 1\f$ size and CV_32SC1 type. + @param probs The optional output matrix that contains posterior probabilities of each Gaussian + mixture component given the each sample. It has \f$nsamples \times nclusters\f$ size and + CV_64FC1 type. + */ + CV_WRAP virtual bool trainE(InputArray samples, InputArray means0, + InputArray covs0=noArray(), + InputArray weights0=noArray(), + OutputArray logLikelihoods=noArray(), + OutputArray labels=noArray(), + OutputArray probs=noArray()) = 0; + + /** @brief Estimate the Gaussian mixture parameters from a samples set. + + This variation starts with Maximization step. You need to provide initial probabilities + \f$p_{i,k}\f$ to use this option. + + @param samples Samples from which the Gaussian mixture model will be estimated. It should be a + one-channel matrix, each row of which is a sample. If the matrix does not have CV_64F type + it will be converted to the inner matrix of such type for the further computing. + @param probs0 the probabilities + @param logLikelihoods The optional output matrix that contains a likelihood logarithm value for + each sample. It has \f$nsamples \times 1\f$ size and CV_64FC1 type. + @param labels The optional output "class label" for each sample: + \f$\texttt{labels}_i=\texttt{arg max}_k(p_{i,k}), i=1..N\f$ (indices of the most probable + mixture component for each sample). It has \f$nsamples \times 1\f$ size and CV_32SC1 type. + @param probs The optional output matrix that contains posterior probabilities of each Gaussian + mixture component given the each sample. It has \f$nsamples \times nclusters\f$ size and + CV_64FC1 type. + */ + CV_WRAP virtual bool trainM(InputArray samples, InputArray probs0, + OutputArray logLikelihoods=noArray(), + OutputArray labels=noArray(), + OutputArray probs=noArray()) = 0; + + /** Creates empty %EM model. + The model should be trained then using StatModel::train(traindata, flags) method. Alternatively, you + can use one of the EM::train\* methods or load it from file using Algorithm::load\(filename). + */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized EM from a file + * + * Use EM::save to serialize and store an EM to disk. + * Load the EM from this file again, by calling this function with the path to the file. + * Optionally specify the node for the file containing the classifier + * + * @param filepath path to serialized EM + * @param nodeName name of node containing the classifier + */ + CV_WRAP static Ptr load(const String& filepath , const String& nodeName = String()); +}; + +/****************************************************************************************\ +* Decision Tree * +\****************************************************************************************/ + +/** @brief The class represents a single decision tree or a collection of decision trees. + +The current public interface of the class allows user to train only a single decision tree, however +the class is capable of storing multiple decision trees and using them for prediction (by summing +responses or using a voting schemes), and the derived from DTrees classes (such as RTrees and Boost) +use this capability to implement decision tree ensembles. + +@sa @ref ml_intro_trees +*/ +class CV_EXPORTS_W DTrees : public StatModel +{ +public: + /** Predict options */ + enum Flags { PREDICT_AUTO=0, PREDICT_SUM=(1<<8), PREDICT_MAX_VOTE=(2<<8), PREDICT_MASK=(3<<8) }; + + /** Cluster possible values of a categorical variable into K\<=maxCategories clusters to + find a suboptimal split. + If a discrete variable, on which the training procedure tries to make a split, takes more than + maxCategories values, the precise best subset estimation may take a very long time because the + algorithm is exponential. Instead, many decision trees engines (including our implementation) + try to find sub-optimal split in this case by clustering all the samples into maxCategories + clusters that is some categories are merged together. The clustering is applied only in n \> + 2-class classification problems for categorical variables with N \> max_categories possible + values. In case of regression and 2-class classification the optimal split can be found + efficiently without employing clustering, thus the parameter is not used in these cases. + Default value is 10.*/ + /** @see setMaxCategories */ + CV_WRAP virtual int getMaxCategories() const = 0; + /** @copybrief getMaxCategories @see getMaxCategories */ + CV_WRAP virtual void setMaxCategories(int val) = 0; + + /** The maximum possible depth of the tree. + That is the training algorithms attempts to split a node while its depth is less than maxDepth. + The root node has zero depth. The actual depth may be smaller if the other termination criteria + are met (see the outline of the training procedure @ref ml_intro_trees "here"), and/or if the + tree is pruned. Default value is INT_MAX.*/ + /** @see setMaxDepth */ + CV_WRAP virtual int getMaxDepth() const = 0; + /** @copybrief getMaxDepth @see getMaxDepth */ + CV_WRAP virtual void setMaxDepth(int val) = 0; + + /** If the number of samples in a node is less than this parameter then the node will not be split. + + Default value is 10.*/ + /** @see setMinSampleCount */ + CV_WRAP virtual int getMinSampleCount() const = 0; + /** @copybrief getMinSampleCount @see getMinSampleCount */ + CV_WRAP virtual void setMinSampleCount(int val) = 0; + + /** If CVFolds \> 1 then algorithms prunes the built decision tree using K-fold + cross-validation procedure where K is equal to CVFolds. + Default value is 10.*/ + /** @see setCVFolds */ + CV_WRAP virtual int getCVFolds() const = 0; + /** @copybrief getCVFolds @see getCVFolds */ + CV_WRAP virtual void setCVFolds(int val) = 0; + + /** If true then surrogate splits will be built. + These splits allow to work with missing data and compute variable importance correctly. + Default value is false. + @note currently it's not implemented.*/ + /** @see setUseSurrogates */ + CV_WRAP virtual bool getUseSurrogates() const = 0; + /** @copybrief getUseSurrogates @see getUseSurrogates */ + CV_WRAP virtual void setUseSurrogates(bool val) = 0; + + /** If true then a pruning will be harsher. + This will make a tree more compact and more resistant to the training data noise but a bit less + accurate. Default value is true.*/ + /** @see setUse1SERule */ + CV_WRAP virtual bool getUse1SERule() const = 0; + /** @copybrief getUse1SERule @see getUse1SERule */ + CV_WRAP virtual void setUse1SERule(bool val) = 0; + + /** If true then pruned branches are physically removed from the tree. + Otherwise they are retained and it is possible to get results from the original unpruned (or + pruned less aggressively) tree. Default value is true.*/ + /** @see setTruncatePrunedTree */ + CV_WRAP virtual bool getTruncatePrunedTree() const = 0; + /** @copybrief getTruncatePrunedTree @see getTruncatePrunedTree */ + CV_WRAP virtual void setTruncatePrunedTree(bool val) = 0; + + /** Termination criteria for regression trees. + If all absolute differences between an estimated value in a node and values of train samples + in this node are less than this parameter then the node will not be split further. Default + value is 0.01f*/ + /** @see setRegressionAccuracy */ + CV_WRAP virtual float getRegressionAccuracy() const = 0; + /** @copybrief getRegressionAccuracy @see getRegressionAccuracy */ + CV_WRAP virtual void setRegressionAccuracy(float val) = 0; + + /** @brief The array of a priori class probabilities, sorted by the class label value. + + The parameter can be used to tune the decision tree preferences toward a certain class. For + example, if you want to detect some rare anomaly occurrence, the training base will likely + contain much more normal cases than anomalies, so a very good classification performance + will be achieved just by considering every case as normal. To avoid this, the priors can be + specified, where the anomaly probability is artificially increased (up to 0.5 or even + greater), so the weight of the misclassified anomalies becomes much bigger, and the tree is + adjusted properly. + + You can also think about this parameter as weights of prediction categories which determine + relative weights that you give to misclassification. That is, if the weight of the first + category is 1 and the weight of the second category is 10, then each mistake in predicting + the second category is equivalent to making 10 mistakes in predicting the first category. + Default value is empty Mat.*/ + /** @see setPriors */ + CV_WRAP virtual cv::Mat getPriors() const = 0; + /** @copybrief getPriors @see getPriors */ + CV_WRAP virtual void setPriors(const cv::Mat &val) = 0; + + /** @brief The class represents a decision tree node. + */ + class CV_EXPORTS Node + { + public: + Node(); + double value; //!< Value at the node: a class label in case of classification or estimated + //!< function value in case of regression. + int classIdx; //!< Class index normalized to 0..class_count-1 range and assigned to the + //!< node. It is used internally in classification trees and tree ensembles. + int parent; //!< Index of the parent node + int left; //!< Index of the left child node + int right; //!< Index of right child node + int defaultDir; //!< Default direction where to go (-1: left or +1: right). It helps in the + //!< case of missing values. + int split; //!< Index of the first split + }; + + /** @brief The class represents split in a decision tree. + */ + class CV_EXPORTS Split + { + public: + Split(); + int varIdx; //!< Index of variable on which the split is created. + bool inversed; //!< If true, then the inverse split rule is used (i.e. left and right + //!< branches are exchanged in the rule expressions below). + float quality; //!< The split quality, a positive number. It is used to choose the best split. + int next; //!< Index of the next split in the list of splits for the node + float c; /**< The threshold value in case of split on an ordered variable. + The rule is: + @code{.none} + if var_value < c + then next_node <- left + else next_node <- right + @endcode */ + int subsetOfs; /**< Offset of the bitset used by the split on a categorical variable. + The rule is: + @code{.none} + if bitset[var_value] == 1 + then next_node <- left + else next_node <- right + @endcode */ + }; + + /** @brief Returns indices of root nodes + */ + virtual const std::vector& getRoots() const = 0; + /** @brief Returns all the nodes + + all the node indices are indices in the returned vector + */ + virtual const std::vector& getNodes() const = 0; + /** @brief Returns all the splits + + all the split indices are indices in the returned vector + */ + virtual const std::vector& getSplits() const = 0; + /** @brief Returns all the bitsets for categorical splits + + Split::subsetOfs is an offset in the returned vector + */ + virtual const std::vector& getSubsets() const = 0; + + /** @brief Creates the empty model + + The static method creates empty decision tree with the specified parameters. It should be then + trained using train method (see StatModel::train). Alternatively, you can load the model from + file using Algorithm::load\(filename). + */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized DTrees from a file + * + * Use DTree::save to serialize and store an DTree to disk. + * Load the DTree from this file again, by calling this function with the path to the file. + * Optionally specify the node for the file containing the classifier + * + * @param filepath path to serialized DTree + * @param nodeName name of node containing the classifier + */ + CV_WRAP static Ptr load(const String& filepath , const String& nodeName = String()); +}; + +/****************************************************************************************\ +* Random Trees Classifier * +\****************************************************************************************/ + +/** @brief The class implements the random forest predictor. + +@sa @ref ml_intro_rtrees + */ +class CV_EXPORTS_W RTrees : public DTrees +{ +public: + + /** If true then variable importance will be calculated and then it can be retrieved by RTrees::getVarImportance. + Default value is false.*/ + /** @see setCalculateVarImportance */ + CV_WRAP virtual bool getCalculateVarImportance() const = 0; + /** @copybrief getCalculateVarImportance @see getCalculateVarImportance */ + CV_WRAP virtual void setCalculateVarImportance(bool val) = 0; + + /** The size of the randomly selected subset of features at each tree node and that are used + to find the best split(s). + If you set it to 0 then the size will be set to the square root of the total number of + features. Default value is 0.*/ + /** @see setActiveVarCount */ + CV_WRAP virtual int getActiveVarCount() const = 0; + /** @copybrief getActiveVarCount @see getActiveVarCount */ + CV_WRAP virtual void setActiveVarCount(int val) = 0; + + /** The termination criteria that specifies when the training algorithm stops. + Either when the specified number of trees is trained and added to the ensemble or when + sufficient accuracy (measured as OOB error) is achieved. Typically the more trees you have the + better the accuracy. However, the improvement in accuracy generally diminishes and asymptotes + pass a certain number of trees. Also to keep in mind, the number of tree increases the + prediction time linearly. Default value is TermCriteria(TermCriteria::MAX_ITERS + + TermCriteria::EPS, 50, 0.1)*/ + /** @see setTermCriteria */ + CV_WRAP virtual TermCriteria getTermCriteria() const = 0; + /** @copybrief getTermCriteria @see getTermCriteria */ + CV_WRAP virtual void setTermCriteria(const TermCriteria &val) = 0; + + /** Returns the variable importance array. + The method returns the variable importance vector, computed at the training stage when + CalculateVarImportance is set to true. If this flag was set to false, the empty matrix is + returned. + */ + CV_WRAP virtual Mat getVarImportance() const = 0; + + /** Returns the result of each individual tree in the forest. + In case the model is a regression problem, the method will return each of the trees' + results for each of the sample cases. If the model is a classifier, it will return + a Mat with samples + 1 rows, where the first row gives the class number and the + following rows return the votes each class had for each sample. + @param samples Array containing the samples for which votes will be calculated. + @param results Array where the result of the calculation will be written. + @param flags Flags for defining the type of RTrees. + */ + CV_WRAP virtual void getVotes(InputArray samples, OutputArray results, int flags) const = 0; + + /** Creates the empty model. + Use StatModel::train to train the model, StatModel::train to create and train the model, + Algorithm::load to load the pre-trained model. + */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized RTree from a file + * + * Use RTree::save to serialize and store an RTree to disk. + * Load the RTree from this file again, by calling this function with the path to the file. + * Optionally specify the node for the file containing the classifier + * + * @param filepath path to serialized RTree + * @param nodeName name of node containing the classifier + */ + CV_WRAP static Ptr load(const String& filepath , const String& nodeName = String()); +}; + +/****************************************************************************************\ +* Boosted tree classifier * +\****************************************************************************************/ + +/** @brief Boosted tree classifier derived from DTrees + +@sa @ref ml_intro_boost + */ +class CV_EXPORTS_W Boost : public DTrees +{ +public: + /** Type of the boosting algorithm. + See Boost::Types. Default value is Boost::REAL. */ + /** @see setBoostType */ + CV_WRAP virtual int getBoostType() const = 0; + /** @copybrief getBoostType @see getBoostType */ + CV_WRAP virtual void setBoostType(int val) = 0; + + /** The number of weak classifiers. + Default value is 100. */ + /** @see setWeakCount */ + CV_WRAP virtual int getWeakCount() const = 0; + /** @copybrief getWeakCount @see getWeakCount */ + CV_WRAP virtual void setWeakCount(int val) = 0; + + /** A threshold between 0 and 1 used to save computational time. + Samples with summary weight \f$\leq 1 - weight_trim_rate\f$ do not participate in the *next* + iteration of training. Set this parameter to 0 to turn off this functionality. Default value is 0.95.*/ + /** @see setWeightTrimRate */ + CV_WRAP virtual double getWeightTrimRate() const = 0; + /** @copybrief getWeightTrimRate @see getWeightTrimRate */ + CV_WRAP virtual void setWeightTrimRate(double val) = 0; + + /** Boosting type. + Gentle AdaBoost and Real AdaBoost are often the preferable choices. */ + enum Types { + DISCRETE=0, //!< Discrete AdaBoost. + REAL=1, //!< Real AdaBoost. It is a technique that utilizes confidence-rated predictions + //!< and works well with categorical data. + LOGIT=2, //!< LogitBoost. It can produce good regression fits. + GENTLE=3 //!< Gentle AdaBoost. It puts less weight on outlier data points and for that + //!(filename) to load the pre-trained model. */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized Boost from a file + * + * Use Boost::save to serialize and store an RTree to disk. + * Load the Boost from this file again, by calling this function with the path to the file. + * Optionally specify the node for the file containing the classifier + * + * @param filepath path to serialized Boost + * @param nodeName name of node containing the classifier + */ + CV_WRAP static Ptr load(const String& filepath , const String& nodeName = String()); +}; + +/****************************************************************************************\ +* Gradient Boosted Trees * +\****************************************************************************************/ + +/*class CV_EXPORTS_W GBTrees : public DTrees +{ +public: + struct CV_EXPORTS_W_MAP Params : public DTrees::Params + { + CV_PROP_RW int weakCount; + CV_PROP_RW int lossFunctionType; + CV_PROP_RW float subsamplePortion; + CV_PROP_RW float shrinkage; + + Params(); + Params( int lossFunctionType, int weakCount, float shrinkage, + float subsamplePortion, int maxDepth, bool useSurrogates ); + }; + + enum {SQUARED_LOSS=0, ABSOLUTE_LOSS, HUBER_LOSS=3, DEVIANCE_LOSS}; + + virtual void setK(int k) = 0; + + virtual float predictSerial( InputArray samples, + OutputArray weakResponses, int flags) const = 0; + + static Ptr create(const Params& p); +};*/ + +/****************************************************************************************\ +* Artificial Neural Networks (ANN) * +\****************************************************************************************/ + +/////////////////////////////////// Multi-Layer Perceptrons ////////////////////////////// + +/** @brief Artificial Neural Networks - Multi-Layer Perceptrons. + +Unlike many other models in ML that are constructed and trained at once, in the MLP model these +steps are separated. First, a network with the specified topology is created using the non-default +constructor or the method ANN_MLP::create. All the weights are set to zeros. Then, the network is +trained using a set of input and output vectors. The training procedure can be repeated more than +once, that is, the weights can be adjusted based on the new training data. + +Additional flags for StatModel::train are available: ANN_MLP::TrainFlags. + +@sa @ref ml_intro_ann + */ +class CV_EXPORTS_W ANN_MLP : public StatModel +{ +public: + /** Available training methods */ + enum TrainingMethods { + BACKPROP=0, //!< The back-propagation algorithm. + RPROP = 1, //!< The RPROP algorithm. See @cite RPROP93 for details. + ANNEAL = 2 //!< The simulated annealing algorithm. See @cite Kirkpatrick83 for details. + }; + + /** Sets training method and common parameters. + @param method Default value is ANN_MLP::RPROP. See ANN_MLP::TrainingMethods. + @param param1 passed to setRpropDW0 for ANN_MLP::RPROP and to setBackpropWeightScale for ANN_MLP::BACKPROP and to initialT for ANN_MLP::ANNEAL. + @param param2 passed to setRpropDWMin for ANN_MLP::RPROP and to setBackpropMomentumScale for ANN_MLP::BACKPROP and to finalT for ANN_MLP::ANNEAL. + */ + CV_WRAP virtual void setTrainMethod(int method, double param1 = 0, double param2 = 0) = 0; + + /** Returns current training method */ + CV_WRAP virtual int getTrainMethod() const = 0; + + /** Initialize the activation function for each neuron. + Currently the default and the only fully supported activation function is ANN_MLP::SIGMOID_SYM. + @param type The type of activation function. See ANN_MLP::ActivationFunctions. + @param param1 The first parameter of the activation function, \f$\alpha\f$. Default value is 0. + @param param2 The second parameter of the activation function, \f$\beta\f$. Default value is 0. + */ + CV_WRAP virtual void setActivationFunction(int type, double param1 = 0, double param2 = 0) = 0; + + /** Integer vector specifying the number of neurons in each layer including the input and output layers. + The very first element specifies the number of elements in the input layer. + The last element - number of elements in the output layer. Default value is empty Mat. + @sa getLayerSizes */ + CV_WRAP virtual void setLayerSizes(InputArray _layer_sizes) = 0; + + /** Integer vector specifying the number of neurons in each layer including the input and output layers. + The very first element specifies the number of elements in the input layer. + The last element - number of elements in the output layer. + @sa setLayerSizes */ + CV_WRAP virtual cv::Mat getLayerSizes() const = 0; + + /** Termination criteria of the training algorithm. + You can specify the maximum number of iterations (maxCount) and/or how much the error could + change between the iterations to make the algorithm continue (epsilon). Default value is + TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 0.01).*/ + /** @see setTermCriteria */ + CV_WRAP virtual TermCriteria getTermCriteria() const = 0; + /** @copybrief getTermCriteria @see getTermCriteria */ + CV_WRAP virtual void setTermCriteria(TermCriteria val) = 0; + + /** BPROP: Strength of the weight gradient term. + The recommended value is about 0.1. Default value is 0.1.*/ + /** @see setBackpropWeightScale */ + CV_WRAP virtual double getBackpropWeightScale() const = 0; + /** @copybrief getBackpropWeightScale @see getBackpropWeightScale */ + CV_WRAP virtual void setBackpropWeightScale(double val) = 0; + + /** BPROP: 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. + Default value is 0.1.*/ + /** @see setBackpropMomentumScale */ + CV_WRAP virtual double getBackpropMomentumScale() const = 0; + /** @copybrief getBackpropMomentumScale @see getBackpropMomentumScale */ + CV_WRAP virtual void setBackpropMomentumScale(double val) = 0; + + /** RPROP: Initial value \f$\Delta_0\f$ of update-values \f$\Delta_{ij}\f$. + Default value is 0.1.*/ + /** @see setRpropDW0 */ + CV_WRAP virtual double getRpropDW0() const = 0; + /** @copybrief getRpropDW0 @see getRpropDW0 */ + CV_WRAP virtual void setRpropDW0(double val) = 0; + + /** RPROP: Increase factor \f$\eta^+\f$. + It must be \>1. Default value is 1.2.*/ + /** @see setRpropDWPlus */ + CV_WRAP virtual double getRpropDWPlus() const = 0; + /** @copybrief getRpropDWPlus @see getRpropDWPlus */ + CV_WRAP virtual void setRpropDWPlus(double val) = 0; + + /** RPROP: Decrease factor \f$\eta^-\f$. + It must be \<1. Default value is 0.5.*/ + /** @see setRpropDWMinus */ + CV_WRAP virtual double getRpropDWMinus() const = 0; + /** @copybrief getRpropDWMinus @see getRpropDWMinus */ + CV_WRAP virtual void setRpropDWMinus(double val) = 0; + + /** RPROP: Update-values lower limit \f$\Delta_{min}\f$. + It must be positive. Default value is FLT_EPSILON.*/ + /** @see setRpropDWMin */ + CV_WRAP virtual double getRpropDWMin() const = 0; + /** @copybrief getRpropDWMin @see getRpropDWMin */ + CV_WRAP virtual void setRpropDWMin(double val) = 0; + + /** RPROP: Update-values upper limit \f$\Delta_{max}\f$. + It must be \>1. Default value is 50.*/ + /** @see setRpropDWMax */ + CV_WRAP virtual double getRpropDWMax() const = 0; + /** @copybrief getRpropDWMax @see getRpropDWMax */ + CV_WRAP virtual void setRpropDWMax(double val) = 0; + + /** ANNEAL: Update initial temperature. + It must be \>=0. Default value is 10.*/ + /** @see setAnnealInitialT */ + CV_WRAP virtual double getAnnealInitialT() const = 0; + /** @copybrief getAnnealInitialT @see getAnnealInitialT */ + CV_WRAP virtual void setAnnealInitialT(double val) = 0; + + /** ANNEAL: Update final temperature. + It must be \>=0 and less than initialT. Default value is 0.1.*/ + /** @see setAnnealFinalT */ + CV_WRAP virtual double getAnnealFinalT() const = 0; + /** @copybrief getAnnealFinalT @see getAnnealFinalT */ + CV_WRAP virtual void setAnnealFinalT(double val) = 0; + + /** ANNEAL: Update cooling ratio. + It must be \>0 and less than 1. Default value is 0.95.*/ + /** @see setAnnealCoolingRatio */ + CV_WRAP virtual double getAnnealCoolingRatio() const = 0; + /** @copybrief getAnnealCoolingRatio @see getAnnealCoolingRatio */ + CV_WRAP virtual void setAnnealCoolingRatio(double val) = 0; + + /** ANNEAL: Update iteration per step. + It must be \>0 . Default value is 10.*/ + /** @see setAnnealItePerStep */ + CV_WRAP virtual int getAnnealItePerStep() const = 0; + /** @copybrief getAnnealItePerStep @see getAnnealItePerStep */ + CV_WRAP virtual void setAnnealItePerStep(int val) = 0; + + /** @brief Set/initialize anneal RNG */ + virtual void setAnnealEnergyRNG(const RNG& rng) = 0; + + /** possible activation functions */ + enum ActivationFunctions { + /** Identity function: \f$f(x)=x\f$ */ + IDENTITY = 0, + /** Symmetrical sigmoid: \f$f(x)=\beta*(1-e^{-\alpha x})/(1+e^{-\alpha x})\f$ + @note + If you are using the default sigmoid activation function with the default parameter values + fparam1=0 and fparam2=0 then the function used is y = 1.7159\*tanh(2/3 \* x), so the output + will range from [-1.7159, 1.7159], instead of [0,1].*/ + SIGMOID_SYM = 1, + /** Gaussian function: \f$f(x)=\beta e^{-\alpha x*x}\f$ */ + GAUSSIAN = 2, + /** ReLU function: \f$f(x)=max(0,x)\f$ */ + RELU = 3, + /** Leaky ReLU function: for x>0 \f$f(x)=x \f$ and x<=0 \f$f(x)=\alpha x \f$*/ + LEAKYRELU= 4 + }; + + /** Train options */ + enum TrainFlags { + /** Update the network weights, rather than compute them from scratch. In the latter case + the weights are initialized using the Nguyen-Widrow algorithm. */ + UPDATE_WEIGHTS = 1, + /** Do not normalize the input vectors. If this flag is not set, the training algorithm + normalizes each input feature independently, shifting its mean value to 0 and making the + standard deviation equal to 1. If the network is assumed to be updated frequently, the new + training data could be much different from original one. In this case, you should take care + of proper normalization. */ + NO_INPUT_SCALE = 2, + /** Do not normalize the output vectors. If the flag is not set, the training algorithm + normalizes each output feature independently, by transforming it to the certain range + depending on the used activation function. */ + NO_OUTPUT_SCALE = 4 + }; + + CV_WRAP virtual Mat getWeights(int layerIdx) const = 0; + + /** @brief Creates empty model + + Use StatModel::train to train the model, Algorithm::load\(filename) to load the pre-trained model. + Note that the train method has optional flags: ANN_MLP::TrainFlags. + */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized ANN from a file + * + * Use ANN::save to serialize and store an ANN to disk. + * Load the ANN from this file again, by calling this function with the path to the file. + * + * @param filepath path to serialized ANN + */ + CV_WRAP static Ptr load(const String& filepath); + +}; + +#ifndef DISABLE_OPENCV_3_COMPATIBILITY +typedef ANN_MLP ANN_MLP_ANNEAL; +#endif + +/****************************************************************************************\ +* Logistic Regression * +\****************************************************************************************/ + +/** @brief Implements Logistic Regression classifier. + +@sa @ref ml_intro_lr + */ +class CV_EXPORTS_W LogisticRegression : public StatModel +{ +public: + + /** Learning rate. */ + /** @see setLearningRate */ + CV_WRAP virtual double getLearningRate() const = 0; + /** @copybrief getLearningRate @see getLearningRate */ + CV_WRAP virtual void setLearningRate(double val) = 0; + + /** Number of iterations. */ + /** @see setIterations */ + CV_WRAP virtual int getIterations() const = 0; + /** @copybrief getIterations @see getIterations */ + CV_WRAP virtual void setIterations(int val) = 0; + + /** Kind of regularization to be applied. See LogisticRegression::RegKinds. */ + /** @see setRegularization */ + CV_WRAP virtual int getRegularization() const = 0; + /** @copybrief getRegularization @see getRegularization */ + CV_WRAP virtual void setRegularization(int val) = 0; + + /** Kind of training method used. See LogisticRegression::Methods. */ + /** @see setTrainMethod */ + CV_WRAP virtual int getTrainMethod() const = 0; + /** @copybrief getTrainMethod @see getTrainMethod */ + CV_WRAP virtual void setTrainMethod(int val) = 0; + + /** Specifies the number of training samples taken in each step of Mini-Batch Gradient + Descent. Will only be used if using LogisticRegression::MINI_BATCH training algorithm. It + has to take values less than the total number of training samples. */ + /** @see setMiniBatchSize */ + CV_WRAP virtual int getMiniBatchSize() const = 0; + /** @copybrief getMiniBatchSize @see getMiniBatchSize */ + CV_WRAP virtual void setMiniBatchSize(int val) = 0; + + /** Termination criteria of the algorithm. */ + /** @see setTermCriteria */ + CV_WRAP virtual TermCriteria getTermCriteria() const = 0; + /** @copybrief getTermCriteria @see getTermCriteria */ + CV_WRAP virtual void setTermCriteria(TermCriteria val) = 0; + + //! Regularization kinds + enum RegKinds { + REG_DISABLE = -1, //!< Regularization disabled + REG_L1 = 0, //!< %L1 norm + REG_L2 = 1 //!< %L2 norm + }; + + //! Training methods + enum Methods { + BATCH = 0, + MINI_BATCH = 1 //!< Set MiniBatchSize to a positive integer when using this method. + }; + + /** @brief Predicts responses for input samples and returns a float type. + + @param samples The input data for the prediction algorithm. Matrix [m x n], where each row + contains variables (features) of one object being classified. Should have data type CV_32F. + @param results Predicted labels as a column matrix of type CV_32S. + @param flags Not used. + */ + CV_WRAP virtual float predict( InputArray samples, OutputArray results=noArray(), int flags=0 ) const CV_OVERRIDE = 0; + + /** @brief This function returns the trained parameters arranged across rows. + + For a two class classifcation problem, it returns a row matrix. It returns learnt parameters of + the Logistic Regression as a matrix of type CV_32F. + */ + CV_WRAP virtual Mat get_learnt_thetas() const = 0; + + /** @brief Creates empty model. + + Creates Logistic Regression model with parameters given. + */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized LogisticRegression from a file + * + * Use LogisticRegression::save to serialize and store an LogisticRegression to disk. + * Load the LogisticRegression from this file again, by calling this function with the path to the file. + * Optionally specify the node for the file containing the classifier + * + * @param filepath path to serialized LogisticRegression + * @param nodeName name of node containing the classifier + */ + CV_WRAP static Ptr load(const String& filepath , const String& nodeName = String()); +}; + + +/****************************************************************************************\ +* Stochastic Gradient Descent SVM Classifier * +\****************************************************************************************/ + +/*! +@brief Stochastic Gradient Descent SVM classifier + +SVMSGD provides a fast and easy-to-use implementation of the SVM classifier using the Stochastic Gradient Descent approach, +as presented in @cite bottou2010large. + +The classifier has following parameters: +- model type, +- margin type, +- margin regularization (\f$\lambda\f$), +- initial step size (\f$\gamma_0\f$), +- step decreasing power (\f$c\f$), +- and termination criteria. + +The model type may have one of the following values: \ref SGD and \ref ASGD. + +- \ref SGD is the classic version of SVMSGD classifier: every next step is calculated by the formula + \f[w_{t+1} = w_t - \gamma(t) \frac{dQ_i}{dw} |_{w = w_t}\f] + where + - \f$w_t\f$ is the weights vector for decision function at step \f$t\f$, + - \f$\gamma(t)\f$ is the step size of model parameters at the iteration \f$t\f$, it is decreased on each step by the formula + \f$\gamma(t) = \gamma_0 (1 + \lambda \gamma_0 t) ^ {-c}\f$ + - \f$Q_i\f$ is the target functional from SVM task for sample with number \f$i\f$, this sample is chosen stochastically on each step of the algorithm. + +- \ref ASGD is Average Stochastic Gradient Descent SVM Classifier. ASGD classifier averages weights vector on each step of algorithm by the formula +\f$\widehat{w}_{t+1} = \frac{t}{1+t}\widehat{w}_{t} + \frac{1}{1+t}w_{t+1}\f$ + +The recommended model type is ASGD (following @cite bottou2010large). + +The margin type may have one of the following values: \ref SOFT_MARGIN or \ref HARD_MARGIN. + +- You should use \ref HARD_MARGIN type, if you have linearly separable sets. +- You should use \ref SOFT_MARGIN type, if you have non-linearly separable sets or sets with outliers. +- In the general case (if you know nothing about linear separability of your sets), use SOFT_MARGIN. + +The other parameters may be described as follows: +- Margin regularization parameter is responsible for weights decreasing at each step and for the strength of restrictions on outliers + (the less the parameter, the less probability that an outlier will be ignored). + Recommended value for SGD model is 0.0001, for ASGD model is 0.00001. + +- Initial step size parameter is the initial value for the step size \f$\gamma(t)\f$. + You will have to find the best initial step for your problem. + +- Step decreasing power is the power parameter for \f$\gamma(t)\f$ decreasing by the formula, mentioned above. + Recommended value for SGD model is 1, for ASGD model is 0.75. + +- Termination criteria can be TermCriteria::COUNT, TermCriteria::EPS or TermCriteria::COUNT + TermCriteria::EPS. + You will have to find the best termination criteria for your problem. + +Note that the parameters margin regularization, initial step size, and step decreasing power should be positive. + +To use SVMSGD algorithm do as follows: + +- first, create the SVMSGD object. The algoorithm will set optimal parameters by default, but you can set your own parameters via functions setSvmsgdType(), + setMarginType(), setMarginRegularization(), setInitialStepSize(), and setStepDecreasingPower(). + +- then the SVM model can be trained using the train features and the correspondent labels by the method train(). + +- after that, the label of a new feature vector can be predicted using the method predict(). + +@code +// Create empty object +cv::Ptr svmsgd = SVMSGD::create(); + +// Train the Stochastic Gradient Descent SVM +svmsgd->train(trainData); + +// Predict labels for the new samples +svmsgd->predict(samples, responses); +@endcode + +*/ + +class CV_EXPORTS_W SVMSGD : public cv::ml::StatModel +{ +public: + + /** SVMSGD type. + ASGD is often the preferable choice. */ + enum SvmsgdType + { + SGD, //!< Stochastic Gradient Descent + ASGD //!< Average Stochastic Gradient Descent + }; + + /** Margin type.*/ + enum MarginType + { + SOFT_MARGIN, //!< General case, suits to the case of non-linearly separable sets, allows outliers. + HARD_MARGIN //!< More accurate for the case of linearly separable sets. + }; + + /** + * @return the weights of the trained model (decision function f(x) = weights * x + shift). + */ + CV_WRAP virtual Mat getWeights() = 0; + + /** + * @return the shift of the trained model (decision function f(x) = weights * x + shift). + */ + CV_WRAP virtual float getShift() = 0; + + /** @brief Creates empty model. + * Use StatModel::train to train the model. Since %SVMSGD has several parameters, you may want to + * find the best parameters for your problem or use setOptimalParameters() to set some default parameters. + */ + CV_WRAP static Ptr create(); + + /** @brief Loads and creates a serialized SVMSGD from a file + * + * Use SVMSGD::save to serialize and store an SVMSGD to disk. + * Load the SVMSGD from this file again, by calling this function with the path to the file. + * Optionally specify the node for the file containing the classifier + * + * @param filepath path to serialized SVMSGD + * @param nodeName name of node containing the classifier + */ + CV_WRAP static Ptr load(const String& filepath , const String& nodeName = String()); + + /** @brief Function sets optimal parameters values for chosen SVM SGD model. + * @param svmsgdType is the type of SVMSGD classifier. + * @param marginType is the type of margin constraint. + */ + CV_WRAP virtual void setOptimalParameters(int svmsgdType = SVMSGD::ASGD, int marginType = SVMSGD::SOFT_MARGIN) = 0; + + /** @brief %Algorithm type, one of SVMSGD::SvmsgdType. */ + /** @see setSvmsgdType */ + CV_WRAP virtual int getSvmsgdType() const = 0; + /** @copybrief getSvmsgdType @see getSvmsgdType */ + CV_WRAP virtual void setSvmsgdType(int svmsgdType) = 0; + + /** @brief %Margin type, one of SVMSGD::MarginType. */ + /** @see setMarginType */ + CV_WRAP virtual int getMarginType() const = 0; + /** @copybrief getMarginType @see getMarginType */ + CV_WRAP virtual void setMarginType(int marginType) = 0; + + /** @brief Parameter marginRegularization of a %SVMSGD optimization problem. */ + /** @see setMarginRegularization */ + CV_WRAP virtual float getMarginRegularization() const = 0; + /** @copybrief getMarginRegularization @see getMarginRegularization */ + CV_WRAP virtual void setMarginRegularization(float marginRegularization) = 0; + + /** @brief Parameter initialStepSize of a %SVMSGD optimization problem. */ + /** @see setInitialStepSize */ + CV_WRAP virtual float getInitialStepSize() const = 0; + /** @copybrief getInitialStepSize @see getInitialStepSize */ + CV_WRAP virtual void setInitialStepSize(float InitialStepSize) = 0; + + /** @brief Parameter stepDecreasingPower of a %SVMSGD optimization problem. */ + /** @see setStepDecreasingPower */ + CV_WRAP virtual float getStepDecreasingPower() const = 0; + /** @copybrief getStepDecreasingPower @see getStepDecreasingPower */ + CV_WRAP virtual void setStepDecreasingPower(float stepDecreasingPower) = 0; + + /** @brief Termination criteria of the training algorithm. + You can specify the maximum number of iterations (maxCount) and/or how much the error could + change between the iterations to make the algorithm continue (epsilon).*/ + /** @see setTermCriteria */ + CV_WRAP virtual TermCriteria getTermCriteria() const = 0; + /** @copybrief getTermCriteria @see getTermCriteria */ + CV_WRAP virtual void setTermCriteria(const cv::TermCriteria &val) = 0; +}; + + +/****************************************************************************************\ +* Auxiliary functions declarations * +\****************************************************************************************/ + +/** @brief Generates _sample_ from multivariate normal distribution + +@param mean an average row vector +@param cov symmetric covariation matrix +@param nsamples returned samples count +@param samples returned samples array +*/ +CV_EXPORTS void randMVNormal( InputArray mean, InputArray cov, int nsamples, OutputArray samples); + +/** @brief Creates test set */ +CV_EXPORTS void createConcentricSpheresTestSet( int nsamples, int nfeatures, int nclasses, + OutputArray samples, OutputArray responses); + + +/****************************************************************************************\ +* Simulated annealing solver * +\****************************************************************************************/ + +#ifdef CV_DOXYGEN +/** @brief This class declares example interface for system state used in simulated annealing optimization algorithm. + +@note This class is not defined in C++ code and can't be use directly - you need your own implementation with the same methods. +*/ +struct SimulatedAnnealingSolverSystem +{ + /** Give energy value for a state of system.*/ + double energy() const; + /** Function which change the state of system (random perturbation).*/ + void changeState(); + /** Function to reverse to the previous state. Can be called once only after changeState(). */ + void reverseState(); +}; +#endif // CV_DOXYGEN + +/** @brief The class implements simulated annealing for optimization. + +@cite Kirkpatrick83 for details + +@param solverSystem optimization system (see SimulatedAnnealingSolverSystem) +@param initialTemperature initial temperature +@param finalTemperature final temperature +@param coolingRatio temperature step multiplies +@param iterationsPerStep number of iterations per temperature changing step +@param lastTemperature optional output for last used temperature +@param rngEnergy specify custom random numbers generator (cv::theRNG() by default) +*/ +template +int simulatedAnnealingSolver(SimulatedAnnealingSolverSystem& solverSystem, + double initialTemperature, double finalTemperature, double coolingRatio, + size_t iterationsPerStep, + CV_OUT double* lastTemperature = NULL, + cv::RNG& rngEnergy = cv::theRNG() +); + +//! @} ml + +} +} + +#include + +#endif // __cplusplus +#endif // OPENCV_ML_HPP + +/* End of file. */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/ml/ml.hpp b/Prj-Win/3rd/opencv/include/opencv2/ml/ml.hpp new file mode 100755 index 0000000..f6f9cd8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/ml/ml.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/ml.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/ml/ml.inl.hpp b/Prj-Win/3rd/opencv/include/opencv2/ml/ml.inl.hpp new file mode 100755 index 0000000..dc9c783 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/ml/ml.inl.hpp @@ -0,0 +1,60 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_ML_INL_HPP +#define OPENCV_ML_INL_HPP + +namespace cv { namespace ml { + +// declared in ml.hpp +template +int simulatedAnnealingSolver(SimulatedAnnealingSolverSystem& solverSystem, + double initialTemperature, double finalTemperature, double coolingRatio, + size_t iterationsPerStep, + CV_OUT double* lastTemperature, + cv::RNG& rngEnergy +) +{ + CV_Assert(finalTemperature > 0); + CV_Assert(initialTemperature > finalTemperature); + CV_Assert(iterationsPerStep > 0); + CV_Assert(coolingRatio < 1.0f); + double Ti = initialTemperature; + double previousEnergy = solverSystem.energy(); + int exchange = 0; + while (Ti > finalTemperature) + { + for (size_t i = 0; i < iterationsPerStep; i++) + { + solverSystem.changeState(); + double newEnergy = solverSystem.energy(); + if (newEnergy < previousEnergy) + { + previousEnergy = newEnergy; + exchange++; + } + else + { + double r = rngEnergy.uniform(0.0, 1.0); + if (r < std::exp(-(newEnergy - previousEnergy) / Ti)) + { + previousEnergy = newEnergy; + exchange++; + } + else + { + solverSystem.reverseState(); + } + } + } + Ti *= coolingRatio; + } + if (lastTemperature) + *lastTemperature = Ti; + return exchange; +} + +}} //namespace + +#endif // OPENCV_ML_INL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/objdetect.hpp b/Prj-Win/3rd/opencv/include/opencv2/objdetect.hpp new file mode 100755 index 0000000..1cbbf84 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/objdetect.hpp @@ -0,0 +1,720 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_OBJDETECT_HPP +#define OPENCV_OBJDETECT_HPP + +#include "opencv2/core.hpp" + +/** +@defgroup objdetect Object Detection + +Haar Feature-based Cascade Classifier for Object Detection +---------------------------------------------------------- + +The object detector described below has been initially proposed by Paul Viola @cite Viola01 and +improved by Rainer Lienhart @cite 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 +classifiers, 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 integral description). + +To see the object detector at work, have a look at the facedetect demo: + + +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 + + +@{ + @defgroup objdetect_c C API +@} + */ + +typedef struct CvHaarClassifierCascade CvHaarClassifierCascade; + +namespace cv +{ + +//! @addtogroup objdetect +//! @{ + +///////////////////////////// Object Detection //////////////////////////// + +//! class for grouping object candidates, detected by Cascade Classifier, HOG etc. +//! instance of the class is to be passed to cv::partition (see cxoperations.hpp) +class CV_EXPORTS SimilarRects +{ +public: + SimilarRects(double _eps) : eps(_eps) {} + inline bool operator()(const Rect& r1, const Rect& r2) const + { + double delta = eps * ((std::min)(r1.width, r2.width) + (std::min)(r1.height, r2.height)) * 0.5; + return std::abs(r1.x - r2.x) <= delta && + std::abs(r1.y - r2.y) <= delta && + std::abs(r1.x + r1.width - r2.x - r2.width) <= delta && + std::abs(r1.y + r1.height - r2.y - r2.height) <= delta; + } + double eps; +}; + +/** @brief Groups the object candidate rectangles. + +@param rectList Input/output vector of rectangles. Output vector includes retained and grouped +rectangles. (The Python list is not modified in place.) +@param groupThreshold Minimum possible number of rectangles minus 1. The threshold is used in a +group of rectangles to retain it. +@param eps Relative difference between sides of the rectangles to merge them into a group. + +The function is a wrapper for the generic function partition . It clusters all the input rectangles +using the rectangle equivalence criteria that combines rectangles with similar sizes and similar +locations. The similarity is defined by eps. When eps=0 , no clustering is done at all. If +\f$\texttt{eps}\rightarrow +\inf\f$ , all the rectangles are put in one cluster. Then, the small +clusters containing less than or equal to groupThreshold rectangles are rejected. In each other +cluster, the average rectangle is computed and put into the output rectangle list. + */ +CV_EXPORTS void groupRectangles(std::vector& rectList, int groupThreshold, double eps = 0.2); +/** @overload */ +CV_EXPORTS_W void groupRectangles(CV_IN_OUT std::vector& rectList, CV_OUT std::vector& weights, + int groupThreshold, double eps = 0.2); +/** @overload */ +CV_EXPORTS void groupRectangles(std::vector& rectList, int groupThreshold, + double eps, std::vector* weights, std::vector* levelWeights ); +/** @overload */ +CV_EXPORTS void groupRectangles(std::vector& rectList, std::vector& rejectLevels, + std::vector& levelWeights, int groupThreshold, double eps = 0.2); +/** @overload */ +CV_EXPORTS void groupRectangles_meanshift(std::vector& rectList, std::vector& foundWeights, + std::vector& foundScales, + double detectThreshold = 0.0, Size winDetSize = Size(64, 128)); + +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(CvHaarClassifierCascade* obj) const; }; + +enum { CASCADE_DO_CANNY_PRUNING = 1, + CASCADE_SCALE_IMAGE = 2, + CASCADE_FIND_BIGGEST_OBJECT = 4, + CASCADE_DO_ROUGH_SEARCH = 8 + }; + +class CV_EXPORTS_W BaseCascadeClassifier : public Algorithm +{ +public: + virtual ~BaseCascadeClassifier(); + virtual bool empty() const CV_OVERRIDE = 0; + virtual bool load( const String& filename ) = 0; + virtual void detectMultiScale( InputArray image, + CV_OUT std::vector& objects, + double scaleFactor, + int minNeighbors, int flags, + Size minSize, Size maxSize ) = 0; + + virtual void detectMultiScale( InputArray image, + CV_OUT std::vector& objects, + CV_OUT std::vector& numDetections, + double scaleFactor, + int minNeighbors, int flags, + Size minSize, Size maxSize ) = 0; + + virtual void detectMultiScale( InputArray image, + CV_OUT std::vector& objects, + CV_OUT std::vector& rejectLevels, + CV_OUT std::vector& levelWeights, + double scaleFactor, + int minNeighbors, int flags, + Size minSize, Size maxSize, + bool outputRejectLevels ) = 0; + + virtual bool isOldFormatCascade() const = 0; + virtual Size getOriginalWindowSize() const = 0; + virtual int getFeatureType() const = 0; + virtual void* getOldCascade() = 0; + + class CV_EXPORTS MaskGenerator + { + public: + virtual ~MaskGenerator() {} + virtual Mat generateMask(const Mat& src)=0; + virtual void initializeMask(const Mat& /*src*/) { } + }; + virtual void setMaskGenerator(const Ptr& maskGenerator) = 0; + virtual Ptr getMaskGenerator() = 0; +}; + +/** @example samples/cpp/facedetect.cpp +This program demonstrates usage of the Cascade classifier class +\image html Cascade_Classifier_Tutorial_Result_Haar.jpg "Sample screenshot" width=321 height=254 +*/ +/** @brief Cascade classifier class for object detection. + */ +class CV_EXPORTS_W CascadeClassifier +{ +public: + CV_WRAP CascadeClassifier(); + /** @brief Loads a classifier from a file. + + @param filename Name of the file from which the classifier is loaded. + */ + CV_WRAP CascadeClassifier(const String& filename); + ~CascadeClassifier(); + /** @brief Checks whether the classifier has been loaded. + */ + CV_WRAP bool empty() const; + /** @brief Loads a classifier from a file. + + @param filename Name of the file from which the classifier is loaded. The file may contain an old + HAAR classifier trained by the haartraining application or a new cascade classifier trained by the + traincascade application. + */ + CV_WRAP bool load( const String& filename ); + /** @brief Reads a classifier from a FileStorage node. + + @note The file may contain a new cascade classifier (trained traincascade application) only. + */ + CV_WRAP bool read( const FileNode& node ); + + /** @brief Detects objects of different sizes in the input image. The detected objects are returned as a list + of rectangles. + + @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, the + rectangles may be partially outside the original image. + @param scaleFactor Parameter specifying how much the image size is reduced at each image scale. + @param minNeighbors Parameter specifying how many neighbors each candidate rectangle should have + to retain it. + @param flags Parameter with the same meaning for an old cascade as in the function + cvHaarDetectObjects. It is not used for a new cascade. + @param minSize Minimum possible object size. Objects smaller than that are ignored. + @param maxSize Maximum possible object size. Objects larger than that are ignored. If `maxSize == minSize` model is evaluated on single scale. + + The function is parallelized with the TBB library. + + @note + - (Python) A face detection example using cascade classifiers can be found at + opencv_source_code/samples/python/facedetect.py + */ + CV_WRAP void detectMultiScale( InputArray image, + CV_OUT std::vector& objects, + double scaleFactor = 1.1, + int minNeighbors = 3, int flags = 0, + Size minSize = Size(), + Size maxSize = Size() ); + + /** @overload + @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, the + rectangles may be partially outside the original image. + @param numDetections Vector of detection numbers for the corresponding objects. An object's number + of detections is the number of neighboring positively classified rectangles that were joined + together to form the object. + @param scaleFactor Parameter specifying how much the image size is reduced at each image scale. + @param minNeighbors Parameter specifying how many neighbors each candidate rectangle should have + to retain it. + @param flags Parameter with the same meaning for an old cascade as in the function + cvHaarDetectObjects. It is not used for a new cascade. + @param minSize Minimum possible object size. Objects smaller than that are ignored. + @param maxSize Maximum possible object size. Objects larger than that are ignored. If `maxSize == minSize` model is evaluated on single scale. + */ + CV_WRAP_AS(detectMultiScale2) void detectMultiScale( InputArray image, + CV_OUT std::vector& objects, + CV_OUT std::vector& numDetections, + double scaleFactor=1.1, + int minNeighbors=3, int flags=0, + Size minSize=Size(), + Size maxSize=Size() ); + + /** @overload + This function allows you to retrieve the final stage decision certainty of classification. + For this, one needs to set `outputRejectLevels` on true and provide the `rejectLevels` and `levelWeights` parameter. + For each resulting detection, `levelWeights` will then contain the certainty of classification at the final stage. + This value can then be used to separate strong from weaker classifications. + + A code sample on how to use it efficiently can be found below: + @code + Mat img; + vector weights; + vector levels; + vector detections; + CascadeClassifier model("/path/to/your/model.xml"); + model.detectMultiScale(img, detections, levels, weights, 1.1, 3, 0, Size(), Size(), true); + cerr << "Detection " << detections[0] << " with weight " << weights[0] << endl; + @endcode + */ + CV_WRAP_AS(detectMultiScale3) void detectMultiScale( InputArray image, + CV_OUT std::vector& objects, + CV_OUT std::vector& rejectLevels, + CV_OUT std::vector& levelWeights, + double scaleFactor = 1.1, + int minNeighbors = 3, int flags = 0, + Size minSize = Size(), + Size maxSize = Size(), + bool outputRejectLevels = false ); + + CV_WRAP bool isOldFormatCascade() const; + CV_WRAP Size getOriginalWindowSize() const; + CV_WRAP int getFeatureType() const; + void* getOldCascade(); + + CV_WRAP static bool convert(const String& oldcascade, const String& newcascade); + + void setMaskGenerator(const Ptr& maskGenerator); + Ptr getMaskGenerator(); + + Ptr cc; +}; + +CV_EXPORTS Ptr createFaceDetectionMaskGenerator(); + +//////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector ////////////// + +//! struct for detection region of interest (ROI) +struct DetectionROI +{ + //! scale(size) of the bounding box + double scale; + //! set of requested locations to be evaluated + std::vector locations; + //! vector that will contain confidence values for each location + std::vector confidences; +}; + +/**@brief Implementation of HOG (Histogram of Oriented Gradients) descriptor and object detector. + +the HOG descriptor algorithm introduced by Navneet Dalal and Bill Triggs @cite Dalal2005 . + +useful links: + +https://hal.inria.fr/inria-00548512/document/ + +https://en.wikipedia.org/wiki/Histogram_of_oriented_gradients + +https://software.intel.com/en-us/ipp-dev-reference-histogram-of-oriented-gradients-hog-descriptor + +http://www.learnopencv.com/histogram-of-oriented-gradients + +http://www.learnopencv.com/handwritten-digits-classification-an-opencv-c-python-tutorial + + */ +struct CV_EXPORTS_W HOGDescriptor +{ +public: + enum HistogramNormType { L2Hys = 0 //!< Default histogramNormType + }; + enum { DEFAULT_NLEVELS = 64 //!< Default nlevels value. + }; + enum DescriptorStorageFormat { DESCR_FORMAT_COL_BY_COL, DESCR_FORMAT_ROW_BY_ROW }; + + /**@brief Creates the HOG descriptor and detector with default params. + + aqual to HOGDescriptor(Size(64,128), Size(16,16), Size(8,8), Size(8,8), 9 ) + */ + CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8), + cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1), + histogramNormType(HOGDescriptor::L2Hys), L2HysThreshold(0.2), gammaCorrection(true), + free_coef(-1.f), nlevels(HOGDescriptor::DEFAULT_NLEVELS), signedGradient(false) + {} + + /** @overload + @param _winSize sets winSize with given value. + @param _blockSize sets blockSize with given value. + @param _blockStride sets blockStride with given value. + @param _cellSize sets cellSize with given value. + @param _nbins sets nbins with given value. + @param _derivAperture sets derivAperture with given value. + @param _winSigma sets winSigma with given value. + @param _histogramNormType sets histogramNormType with given value. + @param _L2HysThreshold sets L2HysThreshold with given value. + @param _gammaCorrection sets gammaCorrection with given value. + @param _nlevels sets nlevels with given value. + @param _signedGradient sets signedGradient with given value. + */ + CV_WRAP HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride, + Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1, + HOGDescriptor::HistogramNormType _histogramNormType=HOGDescriptor::L2Hys, + double _L2HysThreshold=0.2, bool _gammaCorrection=false, + int _nlevels=HOGDescriptor::DEFAULT_NLEVELS, bool _signedGradient=false) + : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize), + nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma), + histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold), + gammaCorrection(_gammaCorrection), free_coef(-1.f), nlevels(_nlevels), signedGradient(_signedGradient) + {} + + /** @overload + @param filename The file name containing HOGDescriptor properties and coefficients for the linear SVM classifier. + */ + CV_WRAP HOGDescriptor(const String& filename) + { + load(filename); + } + + /** @overload + @param d the HOGDescriptor which cloned to create a new one. + */ + HOGDescriptor(const HOGDescriptor& d) + { + d.copyTo(*this); + } + + /**@brief Default destructor. + */ + virtual ~HOGDescriptor() {} + + /**@brief Returns the number of coefficients required for the classification. + */ + CV_WRAP size_t getDescriptorSize() const; + + /** @brief Checks if detector size equal to descriptor size. + */ + CV_WRAP bool checkDetectorSize() const; + + /** @brief Returns winSigma value + */ + CV_WRAP double getWinSigma() const; + + /**@example samples/cpp/peopledetect.cpp + */ + /**@brief Sets coefficients for the linear SVM classifier. + @param svmdetector coefficients for the linear SVM classifier. + */ + CV_WRAP virtual void setSVMDetector(InputArray svmdetector); + + /** @brief Reads HOGDescriptor parameters from a cv::FileNode. + @param fn File node + */ + virtual bool read(FileNode& fn); + + /** @brief Stores HOGDescriptor parameters in a cv::FileStorage. + @param fs File storage + @param objname Object name + */ + virtual void write(FileStorage& fs, const String& objname) const; + + /** @brief loads HOGDescriptor parameters and coefficients for the linear SVM classifier from a file. + @param filename Path of the file to read. + @param objname The optional name of the node to read (if empty, the first top-level node will be used). + */ + CV_WRAP virtual bool load(const String& filename, const String& objname = String()); + + /** @brief saves HOGDescriptor parameters and coefficients for the linear SVM classifier to a file + @param filename File name + @param objname Object name + */ + CV_WRAP virtual void save(const String& filename, const String& objname = String()) const; + + /** @brief clones the HOGDescriptor + @param c cloned HOGDescriptor + */ + virtual void copyTo(HOGDescriptor& c) const; + + /**@example samples/cpp/train_HOG.cpp + */ + /** @brief Computes HOG descriptors of given image. + @param img Matrix of the type CV_8U containing an image where HOG features will be calculated. + @param descriptors Matrix of the type CV_32F + @param winStride Window stride. It must be a multiple of block stride. + @param padding Padding + @param locations Vector of Point + */ + CV_WRAP virtual void compute(InputArray img, + CV_OUT std::vector& descriptors, + Size winStride = Size(), Size padding = Size(), + const std::vector& locations = std::vector()) const; + + /** @brief Performs object detection without a multi-scale window. + @param img Matrix of the type CV_8U or CV_8UC3 containing an image where objects are detected. + @param foundLocations Vector of point where each point contains left-top corner point of detected object boundaries. + @param weights Vector that will contain confidence values for each detected object. + @param hitThreshold Threshold for the distance between features and SVM classifying plane. + Usually it is 0 and should be specified in the detector coefficients (as the last free coefficient). + But if the free coefficient is omitted (which is allowed), you can specify it manually here. + @param winStride Window stride. It must be a multiple of block stride. + @param padding Padding + @param searchLocations Vector of Point includes set of requested locations to be evaluated. + */ + CV_WRAP virtual void detect(InputArray img, CV_OUT std::vector& foundLocations, + CV_OUT std::vector& weights, + double hitThreshold = 0, Size winStride = Size(), + Size padding = Size(), + const std::vector& searchLocations = std::vector()) const; + + /** @brief Performs object detection without a multi-scale window. + @param img Matrix of the type CV_8U or CV_8UC3 containing an image where objects are detected. + @param foundLocations Vector of point where each point contains left-top corner point of detected object boundaries. + @param hitThreshold Threshold for the distance between features and SVM classifying plane. + Usually it is 0 and should be specified in the detector coefficients (as the last free coefficient). + But if the free coefficient is omitted (which is allowed), you can specify it manually here. + @param winStride Window stride. It must be a multiple of block stride. + @param padding Padding + @param searchLocations Vector of Point includes locations to search. + */ + virtual void detect(InputArray img, CV_OUT std::vector& foundLocations, + double hitThreshold = 0, Size winStride = Size(), + Size padding = Size(), + const std::vector& searchLocations=std::vector()) const; + + /** @brief Detects objects of different sizes in the input image. The detected objects are returned as a list + of rectangles. + @param img Matrix of the type CV_8U or CV_8UC3 containing an image where objects are detected. + @param foundLocations Vector of rectangles where each rectangle contains the detected object. + @param foundWeights Vector that will contain confidence values for each detected object. + @param hitThreshold Threshold for the distance between features and SVM classifying plane. + Usually it is 0 and should be specified in the detector coefficients (as the last free coefficient). + But if the free coefficient is omitted (which is allowed), you can specify it manually here. + @param winStride Window stride. It must be a multiple of block stride. + @param padding Padding + @param scale Coefficient of the detection window increase. + @param finalThreshold Final threshold + @param useMeanshiftGrouping indicates grouping algorithm + */ + CV_WRAP virtual void detectMultiScale(InputArray img, CV_OUT std::vector& foundLocations, + CV_OUT std::vector& foundWeights, double hitThreshold = 0, + Size winStride = Size(), Size padding = Size(), double scale = 1.05, + double finalThreshold = 2.0,bool useMeanshiftGrouping = false) const; + + /** @brief Detects objects of different sizes in the input image. The detected objects are returned as a list + of rectangles. + @param img Matrix of the type CV_8U or CV_8UC3 containing an image where objects are detected. + @param foundLocations Vector of rectangles where each rectangle contains the detected object. + @param hitThreshold Threshold for the distance between features and SVM classifying plane. + Usually it is 0 and should be specified in the detector coefficients (as the last free coefficient). + But if the free coefficient is omitted (which is allowed), you can specify it manually here. + @param winStride Window stride. It must be a multiple of block stride. + @param padding Padding + @param scale Coefficient of the detection window increase. + @param finalThreshold Final threshold + @param useMeanshiftGrouping indicates grouping algorithm + */ + virtual void detectMultiScale(InputArray img, CV_OUT std::vector& foundLocations, + double hitThreshold = 0, Size winStride = Size(), + Size padding = Size(), double scale = 1.05, + double finalThreshold = 2.0, bool useMeanshiftGrouping = false) const; + + /** @brief Computes gradients and quantized gradient orientations. + @param img Matrix contains the image to be computed + @param grad Matrix of type CV_32FC2 contains computed gradients + @param angleOfs Matrix of type CV_8UC2 contains quantized gradient orientations + @param paddingTL Padding from top-left + @param paddingBR Padding from bottom-right + */ + CV_WRAP virtual void computeGradient(InputArray img, InputOutputArray grad, InputOutputArray angleOfs, + Size paddingTL = Size(), Size paddingBR = Size()) const; + + /** @brief Returns coefficients of the classifier trained for people detection (for 64x128 windows). + */ + CV_WRAP static std::vector getDefaultPeopleDetector(); + + /**@example samples/tapi/hog.cpp + */ + /** @brief Returns coefficients of the classifier trained for people detection (for 48x96 windows). + */ + CV_WRAP static std::vector getDaimlerPeopleDetector(); + + //! Detection window size. Align to block size and block stride. Default value is Size(64,128). + CV_PROP Size winSize; + + //! Block size in pixels. Align to cell size. Default value is Size(16,16). + CV_PROP Size blockSize; + + //! Block stride. It must be a multiple of cell size. Default value is Size(8,8). + CV_PROP Size blockStride; + + //! Cell size. Default value is Size(8,8). + CV_PROP Size cellSize; + + //! Number of bins used in the calculation of histogram of gradients. Default value is 9. + CV_PROP int nbins; + + //! not documented + CV_PROP int derivAperture; + + //! Gaussian smoothing window parameter. + CV_PROP double winSigma; + + //! histogramNormType + CV_PROP HOGDescriptor::HistogramNormType histogramNormType; + + //! L2-Hys normalization method shrinkage. + CV_PROP double L2HysThreshold; + + //! Flag to specify whether the gamma correction preprocessing is required or not. + CV_PROP bool gammaCorrection; + + //! coefficients for the linear SVM classifier. + CV_PROP std::vector svmDetector; + + //! coefficients for the linear SVM classifier used when OpenCL is enabled + UMat oclSvmDetector; + + //! not documented + float free_coef; + + //! Maximum number of detection window increases. Default value is 64 + CV_PROP int nlevels; + + //! Indicates signed gradient will be used or not + CV_PROP bool signedGradient; + + /** @brief evaluate specified ROI and return confidence value for each location + @param img Matrix of the type CV_8U or CV_8UC3 containing an image where objects are detected. + @param locations Vector of Point + @param foundLocations Vector of Point where each Point is detected object's top-left point. + @param confidences confidences + @param hitThreshold Threshold for the distance between features and SVM classifying plane. Usually + it is 0 and should be specified in the detector coefficients (as the last free coefficient). But if + the free coefficient is omitted (which is allowed), you can specify it manually here + @param winStride winStride + @param padding padding + */ + virtual void detectROI(InputArray img, const std::vector &locations, + CV_OUT std::vector& foundLocations, CV_OUT std::vector& confidences, + double hitThreshold = 0, cv::Size winStride = Size(), + cv::Size padding = Size()) const; + + /** @brief evaluate specified ROI and return confidence value for each location in multiple scales + @param img Matrix of the type CV_8U or CV_8UC3 containing an image where objects are detected. + @param foundLocations Vector of rectangles where each rectangle contains the detected object. + @param locations Vector of DetectionROI + @param hitThreshold Threshold for the distance between features and SVM classifying plane. Usually it is 0 and should be specified + in the detector coefficients (as the last free coefficient). But if the free coefficient is omitted (which is allowed), you can specify it manually here. + @param groupThreshold Minimum possible number of rectangles minus 1. The threshold is used in a group of rectangles to retain it. + */ + virtual void detectMultiScaleROI(InputArray img, + CV_OUT std::vector& foundLocations, + std::vector& locations, + double hitThreshold = 0, + int groupThreshold = 0) const; + + /** @brief Groups the object candidate rectangles. + @param rectList Input/output vector of rectangles. Output vector includes retained and grouped rectangles. (The Python list is not modified in place.) + @param weights Input/output vector of weights of rectangles. Output vector includes weights of retained and grouped rectangles. (The Python list is not modified in place.) + @param groupThreshold Minimum possible number of rectangles minus 1. The threshold is used in a group of rectangles to retain it. + @param eps Relative difference between sides of the rectangles to merge them into a group. + */ + void groupRectangles(std::vector& rectList, std::vector& weights, int groupThreshold, double eps) const; +}; + +class CV_EXPORTS_W QRCodeDetector +{ +public: + CV_WRAP QRCodeDetector(); + ~QRCodeDetector(); + + /** @brief sets the epsilon used during the horizontal scan of QR code stop marker detection. + @param epsX Epsilon neighborhood, which allows you to determine the horizontal pattern + of the scheme 1:1:3:1:1 according to QR code standard. + */ + CV_WRAP void setEpsX(double epsX); + /** @brief sets the epsilon used during the vertical scan of QR code stop marker detection. + @param epsY Epsilon neighborhood, which allows you to determine the vertical pattern + of the scheme 1:1:3:1:1 according to QR code standard. + */ + CV_WRAP void setEpsY(double epsY); + + /** @brief Detects QR code in image and returns the quadrangle containing the code. + @param img grayscale or color (BGR) image containing (or not) QR code. + @param points Output vector of vertices of the minimum-area quadrangle containing the code. + */ + CV_WRAP bool detect(InputArray img, OutputArray points) const; + + /** @brief Decodes QR code in image once it's found by the detect() method. + Returns UTF8-encoded output string or empty string if the code cannot be decoded. + + @param img grayscale or color (BGR) image containing QR code. + @param points Quadrangle vertices found by detect() method (or some other algorithm). + @param straight_qrcode The optional output image containing rectified and binarized QR code + */ + CV_WRAP std::string decode(InputArray img, InputArray points, OutputArray straight_qrcode = noArray()); + + /** @brief Both detects and decodes QR code + + @param img grayscale or color (BGR) image containing QR code. + @param points opiotnal output array of vertices of the found QR code quadrangle. Will be empty if not found. + @param straight_qrcode The optional output image containing rectified and binarized QR code + */ + CV_WRAP std::string detectAndDecode(InputArray img, OutputArray points=noArray(), + OutputArray straight_qrcode = noArray()); +protected: + struct Impl; + Ptr p; +}; + +//! @} objdetect +} + +#include "opencv2/objdetect/detection_based_tracker.hpp" + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/objdetect/detection_based_tracker.hpp b/Prj-Win/3rd/opencv/include/opencv2/objdetect/detection_based_tracker.hpp new file mode 100755 index 0000000..18cde13 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/objdetect/detection_based_tracker.hpp @@ -0,0 +1,222 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_OBJDETECT_DBT_HPP +#define OPENCV_OBJDETECT_DBT_HPP + +#include + +#include + +namespace cv +{ + +//! @addtogroup objdetect +//! @{ + +class CV_EXPORTS DetectionBasedTracker +{ + public: + struct CV_EXPORTS Parameters + { + int maxTrackLifetime; + int minDetectionPeriod; //the minimal time between run of the big object detector (on the whole frame) in ms (1000 mean 1 sec), default=0 + + Parameters(); + }; + + class IDetector + { + public: + IDetector(): + minObjSize(96, 96), + maxObjSize(INT_MAX, INT_MAX), + minNeighbours(2), + scaleFactor(1.1f) + {} + + virtual void detect(const cv::Mat& image, std::vector& objects) = 0; + + void setMinObjectSize(const cv::Size& min) + { + minObjSize = min; + } + void setMaxObjectSize(const cv::Size& max) + { + maxObjSize = max; + } + cv::Size getMinObjectSize() const + { + return minObjSize; + } + cv::Size getMaxObjectSize() const + { + return maxObjSize; + } + float getScaleFactor() + { + return scaleFactor; + } + void setScaleFactor(float value) + { + scaleFactor = value; + } + int getMinNeighbours() + { + return minNeighbours; + } + void setMinNeighbours(int value) + { + minNeighbours = value; + } + virtual ~IDetector() {} + + protected: + cv::Size minObjSize; + cv::Size maxObjSize; + int minNeighbours; + float scaleFactor; + }; + + DetectionBasedTracker(cv::Ptr mainDetector, cv::Ptr trackingDetector, const Parameters& params); + virtual ~DetectionBasedTracker(); + + virtual bool run(); + virtual void stop(); + virtual void resetTracking(); + + virtual void process(const cv::Mat& imageGray); + + bool setParameters(const Parameters& params); + const Parameters& getParameters() const; + + + typedef std::pair Object; + virtual void getObjects(std::vector& result) const; + virtual void getObjects(std::vector& result) const; + + enum ObjectStatus + { + DETECTED_NOT_SHOWN_YET, + DETECTED, + DETECTED_TEMPORARY_LOST, + WRONG_OBJECT + }; + struct ExtObject + { + int id; + cv::Rect location; + ObjectStatus status; + ExtObject(int _id, cv::Rect _location, ObjectStatus _status) + :id(_id), location(_location), status(_status) + { + } + }; + virtual void getObjects(std::vector& result) const; + + + virtual int addObject(const cv::Rect& location); //returns id of the new object + + protected: + class SeparateDetectionWork; + cv::Ptr separateDetectionWork; + friend void* workcycleObjectDetectorFunction(void* p); + + struct InnerParameters + { + int numLastPositionsToTrack; + int numStepsToWaitBeforeFirstShow; + int numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown; + int numStepsToShowWithoutDetecting; + + float coeffTrackingWindowSize; + float coeffObjectSizeToTrack; + float coeffObjectSpeedUsingInPrediction; + + InnerParameters(); + }; + Parameters parameters; + InnerParameters innerParameters; + + struct TrackedObject + { + typedef std::vector PositionsVector; + + PositionsVector lastPositions; + + int numDetectedFrames; + int numFramesNotDetected; + int id; + + TrackedObject(const cv::Rect& rect):numDetectedFrames(1), numFramesNotDetected(0) + { + lastPositions.push_back(rect); + id=getNextId(); + }; + + static int getNextId() + { + static int _id=0; + return _id++; + } + }; + + int numTrackedSteps; + std::vector trackedObjects; + + std::vector weightsPositionsSmoothing; + std::vector weightsSizesSmoothing; + + cv::Ptr cascadeForTracking; + + void updateTrackedObjects(const std::vector& detectedObjects); + cv::Rect calcTrackedObjectPositionToShow(int i) const; + cv::Rect calcTrackedObjectPositionToShow(int i, ObjectStatus& status) const; + void detectInRegion(const cv::Mat& img, const cv::Rect& r, std::vector& detectedObjectsInRegions); +}; + +//! @} objdetect + +} //end of cv namespace + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/objdetect/objdetect.hpp b/Prj-Win/3rd/opencv/include/opencv2/objdetect/objdetect.hpp new file mode 100755 index 0000000..3ee284f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/objdetect/objdetect.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/objdetect.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/opencv.hpp b/Prj-Win/3rd/opencv/include/opencv2/opencv.hpp new file mode 100755 index 0000000..4048158 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/opencv.hpp @@ -0,0 +1,139 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_ALL_HPP +#define OPENCV_ALL_HPP + +// File that defines what modules where included during the build of OpenCV +// These are purely the defines of the correct HAVE_OPENCV_modulename values +#include "opencv2/opencv_modules.hpp" + +// Then the list of defines is checked to include the correct headers +// Core library is always included --> without no OpenCV functionality available +#include "opencv2/core.hpp" + +// Then the optional modules are checked +#ifdef HAVE_OPENCV_CALIB3D +#include "opencv2/calib3d.hpp" +#endif +#ifdef HAVE_OPENCV_FEATURES2D +#include "opencv2/features2d.hpp" +#endif +#ifdef HAVE_OPENCV_DNN +#include "opencv2/dnn.hpp" +#endif +#ifdef HAVE_OPENCV_FLANN +#include "opencv2/flann.hpp" +#endif +#ifdef HAVE_OPENCV_HIGHGUI +#include "opencv2/highgui.hpp" +#endif +#ifdef HAVE_OPENCV_IMGCODECS +#include "opencv2/imgcodecs.hpp" +#endif +#ifdef HAVE_OPENCV_IMGPROC +#include "opencv2/imgproc.hpp" +#endif +#ifdef HAVE_OPENCV_ML +#include "opencv2/ml.hpp" +#endif +#ifdef HAVE_OPENCV_OBJDETECT +#include "opencv2/objdetect.hpp" +#endif +#ifdef HAVE_OPENCV_PHOTO +#include "opencv2/photo.hpp" +#endif +#ifdef HAVE_OPENCV_SHAPE +#include "opencv2/shape.hpp" +#endif +#ifdef HAVE_OPENCV_STITCHING +#include "opencv2/stitching.hpp" +#endif +#ifdef HAVE_OPENCV_SUPERRES +#include "opencv2/superres.hpp" +#endif +#ifdef HAVE_OPENCV_VIDEO +#include "opencv2/video.hpp" +#endif +#ifdef HAVE_OPENCV_VIDEOIO +#include "opencv2/videoio.hpp" +#endif +#ifdef HAVE_OPENCV_VIDEOSTAB +#include "opencv2/videostab.hpp" +#endif +#ifdef HAVE_OPENCV_VIZ +#include "opencv2/viz.hpp" +#endif + +// Finally CUDA specific entries are checked and added +#ifdef HAVE_OPENCV_CUDAARITHM +#include "opencv2/cudaarithm.hpp" +#endif +#ifdef HAVE_OPENCV_CUDABGSEGM +#include "opencv2/cudabgsegm.hpp" +#endif +#ifdef HAVE_OPENCV_CUDACODEC +#include "opencv2/cudacodec.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAFEATURES2D +#include "opencv2/cudafeatures2d.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAFILTERS +#include "opencv2/cudafilters.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAIMGPROC +#include "opencv2/cudaimgproc.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAOBJDETECT +#include "opencv2/cudaobjdetect.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAOPTFLOW +#include "opencv2/cudaoptflow.hpp" +#endif +#ifdef HAVE_OPENCV_CUDASTEREO +#include "opencv2/cudastereo.hpp" +#endif +#ifdef HAVE_OPENCV_CUDAWARPING +#include "opencv2/cudawarping.hpp" +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/opencv_modules.hpp b/Prj-Win/3rd/opencv/include/opencv2/opencv_modules.hpp new file mode 100755 index 0000000..c9e24d8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/opencv_modules.hpp @@ -0,0 +1,30 @@ +/* + * ** File generated automatically, do not modify ** + * + * This file defines the list of modules available in current build configuration + * + * +*/ + +// This definition means that OpenCV is built with enabled non-free code. +// For example, patented algorithms for non-profit/non-commercial use only. +/* #undef OPENCV_ENABLE_NONFREE */ + +#define HAVE_OPENCV_CALIB3D +#define HAVE_OPENCV_CORE +#define HAVE_OPENCV_DNN +#define HAVE_OPENCV_FEATURES2D +#define HAVE_OPENCV_FLANN +#define HAVE_OPENCV_GAPI +#define HAVE_OPENCV_HIGHGUI +#define HAVE_OPENCV_IMGCODECS +#define HAVE_OPENCV_IMGPROC +#define HAVE_OPENCV_ML +#define HAVE_OPENCV_OBJDETECT +#define HAVE_OPENCV_PHOTO +#define HAVE_OPENCV_STITCHING +#define HAVE_OPENCV_VIDEO +#define HAVE_OPENCV_VIDEOIO +#define HAVE_OPENCV_WORLD + + diff --git a/Prj-Win/3rd/opencv/include/opencv2/photo.hpp b/Prj-Win/3rd/opencv/include/opencv2/photo.hpp new file mode 100755 index 0000000..9ef1c0f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/photo.hpp @@ -0,0 +1,856 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_PHOTO_HPP +#define OPENCV_PHOTO_HPP + +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" + +/** +@defgroup photo Computational Photography + +This module includes photo processing algorithms +@{ + @defgroup photo_inpaint Inpainting + @defgroup photo_denoise Denoising + @defgroup photo_hdr HDR imaging + +This section describes high dynamic range imaging algorithms namely tonemapping, exposure alignment, +camera calibration with multiple exposures and exposure fusion. + + @defgroup photo_decolor Contrast Preserving Decolorization + +Useful links: + +http://www.cse.cuhk.edu.hk/leojia/projects/color2gray/index.html + + @defgroup photo_clone Seamless Cloning + +Useful links: + +https://www.learnopencv.com/seamless-cloning-using-opencv-python-cpp + + @defgroup photo_render Non-Photorealistic Rendering + +Useful links: + +http://www.inf.ufrgs.br/~eslgastal/DomainTransform + +https://www.learnopencv.com/non-photorealistic-rendering-using-opencv-python-c/ +@} + */ + +namespace cv +{ + +//! @addtogroup photo +//! @{ + +//! @addtogroup photo_inpaint +//! @{ +//! the inpainting algorithm +enum +{ + INPAINT_NS = 0, //!< Use Navier-Stokes based method + INPAINT_TELEA = 1 //!< Use the algorithm proposed by Alexandru Telea @cite Telea04 +}; + +/** @brief Restores the selected region in an image using the region neighborhood. + +@param src Input 8-bit, 16-bit unsigned or 32-bit float 1-channel or 8-bit 3-channel image. +@param inpaintMask Inpainting mask, 8-bit 1-channel image. Non-zero pixels indicate the area that +needs to be inpainted. +@param dst Output image with the same size and type as src . +@param inpaintRadius Radius of a circular neighborhood of each point inpainted that is considered +by the algorithm. +@param flags Inpainting method that could be cv::INPAINT_NS or cv::INPAINT_TELEA + +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 for more details. + +@note + - An example using the inpainting technique can be found at + opencv_source_code/samples/cpp/inpaint.cpp + - (Python) An example using the inpainting technique can be found at + opencv_source_code/samples/python/inpaint.py + */ +CV_EXPORTS_W void inpaint( InputArray src, InputArray inpaintMask, + OutputArray dst, double inpaintRadius, int flags ); + +//! @} photo_inpaint + +//! @addtogroup photo_denoise +//! @{ + +/** @brief Perform image denoising using Non-local Means Denoising algorithm + with several computational +optimizations. Noise expected to be a gaussian white noise + +@param src Input 8-bit 1-channel, 2-channel, 3-channel or 4-channel image. +@param dst Output image with the same size and type as src . +@param templateWindowSize Size in pixels of the template patch that is used to compute weights. +Should be odd. Recommended value 7 pixels +@param searchWindowSize Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater +denoising time. Recommended value 21 pixels +@param h Parameter regulating filter strength. Big h value perfectly removes noise but also +removes image details, smaller h value preserves details but also preserves some noise + +This function expected to be applied to grayscale images. For colored images look at +fastNlMeansDenoisingColored. Advanced usage of this functions can be manual denoising of colored +image in different colorspaces. Such approach is used in fastNlMeansDenoisingColored by converting +image to CIELAB colorspace and then separately denoise L and AB components with different h +parameter. + */ +CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, float h = 3, + int templateWindowSize = 7, int searchWindowSize = 21); + +/** @brief Perform image denoising using Non-local Means Denoising algorithm + with several computational +optimizations. Noise expected to be a gaussian white noise + +@param src Input 8-bit or 16-bit (only with NORM_L1) 1-channel, +2-channel, 3-channel or 4-channel image. +@param dst Output image with the same size and type as src . +@param templateWindowSize Size in pixels of the template patch that is used to compute weights. +Should be odd. Recommended value 7 pixels +@param searchWindowSize Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater +denoising time. Recommended value 21 pixels +@param h Array of parameters regulating filter strength, either one +parameter applied to all channels or one per channel in dst. Big h value +perfectly removes noise but also removes image details, smaller h +value preserves details but also preserves some noise +@param normType Type of norm used for weight calculation. Can be either NORM_L2 or NORM_L1 + +This function expected to be applied to grayscale images. For colored images look at +fastNlMeansDenoisingColored. Advanced usage of this functions can be manual denoising of colored +image in different colorspaces. Such approach is used in fastNlMeansDenoisingColored by converting +image to CIELAB colorspace and then separately denoise L and AB components with different h +parameter. + */ +CV_EXPORTS_W void fastNlMeansDenoising( InputArray src, OutputArray dst, + const std::vector& h, + int templateWindowSize = 7, int searchWindowSize = 21, + int normType = NORM_L2); + +/** @brief Modification of fastNlMeansDenoising function for colored images + +@param src Input 8-bit 3-channel image. +@param dst Output image with the same size and type as src . +@param templateWindowSize Size in pixels of the template patch that is used to compute weights. +Should be odd. Recommended value 7 pixels +@param searchWindowSize Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater +denoising time. Recommended value 21 pixels +@param h Parameter regulating filter strength for luminance component. Bigger h value perfectly +removes noise but also removes image details, smaller h value preserves details but also preserves +some noise +@param hColor The same as h but for color components. For most images value equals 10 +will be enough to remove colored noise and do not distort colors + +The function converts image to CIELAB colorspace and then separately denoise L and AB components +with given h parameters using fastNlMeansDenoising function. + */ +CV_EXPORTS_W void fastNlMeansDenoisingColored( InputArray src, OutputArray dst, + float h = 3, float hColor = 3, + int templateWindowSize = 7, int searchWindowSize = 21); + +/** @brief Modification of fastNlMeansDenoising function for images sequence where consecutive images have been +captured in small period of time. For example video. This version of the function is for grayscale +images or for manual manipulation with colorspaces. For more details see + + +@param srcImgs Input 8-bit 1-channel, 2-channel, 3-channel or +4-channel images sequence. All images should have the same type and +size. +@param imgToDenoiseIndex Target image to denoise index in srcImgs sequence +@param temporalWindowSize Number of surrounding images to use for target image denoising. Should +be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to +imgToDenoiseIndex - temporalWindowSize / 2 from srcImgs will be used to denoise +srcImgs[imgToDenoiseIndex] image. +@param dst Output image with the same size and type as srcImgs images. +@param templateWindowSize Size in pixels of the template patch that is used to compute weights. +Should be odd. Recommended value 7 pixels +@param searchWindowSize Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater +denoising time. Recommended value 21 pixels +@param h Parameter regulating filter strength. Bigger h value +perfectly removes noise but also removes image details, smaller h +value preserves details but also preserves some noise + */ +CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst, + int imgToDenoiseIndex, int temporalWindowSize, + float h = 3, int templateWindowSize = 7, int searchWindowSize = 21); + +/** @brief Modification of fastNlMeansDenoising function for images sequence where consecutive images have been +captured in small period of time. For example video. This version of the function is for grayscale +images or for manual manipulation with colorspaces. For more details see + + +@param srcImgs Input 8-bit or 16-bit (only with NORM_L1) 1-channel, +2-channel, 3-channel or 4-channel images sequence. All images should +have the same type and size. +@param imgToDenoiseIndex Target image to denoise index in srcImgs sequence +@param temporalWindowSize Number of surrounding images to use for target image denoising. Should +be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to +imgToDenoiseIndex - temporalWindowSize / 2 from srcImgs will be used to denoise +srcImgs[imgToDenoiseIndex] image. +@param dst Output image with the same size and type as srcImgs images. +@param templateWindowSize Size in pixels of the template patch that is used to compute weights. +Should be odd. Recommended value 7 pixels +@param searchWindowSize Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater +denoising time. Recommended value 21 pixels +@param h Array of parameters regulating filter strength, either one +parameter applied to all channels or one per channel in dst. Big h value +perfectly removes noise but also removes image details, smaller h +value preserves details but also preserves some noise +@param normType Type of norm used for weight calculation. Can be either NORM_L2 or NORM_L1 + */ +CV_EXPORTS_W void fastNlMeansDenoisingMulti( InputArrayOfArrays srcImgs, OutputArray dst, + int imgToDenoiseIndex, int temporalWindowSize, + const std::vector& h, + int templateWindowSize = 7, int searchWindowSize = 21, + int normType = NORM_L2); + +/** @brief Modification of fastNlMeansDenoisingMulti function for colored images sequences + +@param srcImgs Input 8-bit 3-channel images sequence. All images should have the same type and +size. +@param imgToDenoiseIndex Target image to denoise index in srcImgs sequence +@param temporalWindowSize Number of surrounding images to use for target image denoising. Should +be odd. Images from imgToDenoiseIndex - temporalWindowSize / 2 to +imgToDenoiseIndex - temporalWindowSize / 2 from srcImgs will be used to denoise +srcImgs[imgToDenoiseIndex] image. +@param dst Output image with the same size and type as srcImgs images. +@param templateWindowSize Size in pixels of the template patch that is used to compute weights. +Should be odd. Recommended value 7 pixels +@param searchWindowSize Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater searchWindowsSize - greater +denoising time. Recommended value 21 pixels +@param h Parameter regulating filter strength for luminance component. Bigger h value perfectly +removes noise but also removes image details, smaller h value preserves details but also preserves +some noise. +@param hColor The same as h but for color components. + +The function converts images to CIELAB colorspace and then separately denoise L and AB components +with given h parameters using fastNlMeansDenoisingMulti function. + */ +CV_EXPORTS_W void fastNlMeansDenoisingColoredMulti( InputArrayOfArrays srcImgs, OutputArray dst, + int imgToDenoiseIndex, int temporalWindowSize, + float h = 3, float hColor = 3, + int templateWindowSize = 7, int searchWindowSize = 21); + +/** @brief Primal-dual algorithm is an algorithm for solving special types of variational problems (that is, +finding a function to minimize some functional). As the image denoising, in particular, may be seen +as the variational problem, primal-dual algorithm then can be used to perform denoising and this is +exactly what is implemented. + +It should be noted, that this implementation was taken from the July 2013 blog entry +@cite MA13 , which also contained (slightly more general) ready-to-use source code on Python. +Subsequently, that code was rewritten on C++ with the usage of openCV by Vadim Pisarevsky at the end +of July 2013 and finally it was slightly adapted by later authors. + +Although the thorough discussion and justification of the algorithm involved may be found in +@cite ChambolleEtAl, it might make sense to skim over it here, following @cite MA13 . To begin +with, we consider the 1-byte gray-level images as the functions from the rectangular domain of +pixels (it may be seen as set +\f$\left\{(x,y)\in\mathbb{N}\times\mathbb{N}\mid 1\leq x\leq n,\;1\leq y\leq m\right\}\f$ for some +\f$m,\;n\in\mathbb{N}\f$) into \f$\{0,1,\dots,255\}\f$. We shall denote the noised images as \f$f_i\f$ and with +this view, given some image \f$x\f$ of the same size, we may measure how bad it is by the formula + +\f[\left\|\left\|\nabla x\right\|\right\| + \lambda\sum_i\left\|\left\|x-f_i\right\|\right\|\f] + +\f$\|\|\cdot\|\|\f$ here denotes \f$L_2\f$-norm and as you see, the first addend states that we want our +image to be smooth (ideally, having zero gradient, thus being constant) and the second states that +we want our result to be close to the observations we've got. If we treat \f$x\f$ as a function, this is +exactly the functional what we seek to minimize and here the Primal-Dual algorithm comes into play. + +@param observations This array should contain one or more noised versions of the image that is to +be restored. +@param result Here the denoised image will be stored. There is no need to do pre-allocation of +storage space, as it will be automatically allocated, if necessary. +@param lambda Corresponds to \f$\lambda\f$ in the formulas above. As it is enlarged, the smooth +(blurred) images are treated more favorably than detailed (but maybe more noised) ones. Roughly +speaking, as it becomes smaller, the result will be more blur but more sever outliers will be +removed. +@param niters Number of iterations that the algorithm will run. Of course, as more iterations as +better, but it is hard to quantitatively refine this statement, so just use the default and +increase it if the results are poor. + */ +CV_EXPORTS_W void denoise_TVL1(const std::vector& observations,Mat& result, double lambda=1.0, int niters=30); + +//! @} photo_denoise + +//! @addtogroup photo_hdr +//! @{ + +enum { LDR_SIZE = 256 }; + +/** @brief Base class for tonemapping algorithms - tools that are used to map HDR image to 8-bit range. + */ +class CV_EXPORTS_W Tonemap : public Algorithm +{ +public: + /** @brief Tonemaps image + + @param src source image - CV_32FC3 Mat (float 32 bits 3 channels) + @param dst destination image - CV_32FC3 Mat with values in [0, 1] range + */ + CV_WRAP virtual void process(InputArray src, OutputArray dst) = 0; + + CV_WRAP virtual float getGamma() const = 0; + CV_WRAP virtual void setGamma(float gamma) = 0; +}; + +/** @brief Creates simple linear mapper with gamma correction + +@param gamma positive value for gamma correction. Gamma value of 1.0 implies no correction, gamma +equal to 2.2f is suitable for most displays. +Generally gamma \> 1 brightens the image and gamma \< 1 darkens it. + */ +CV_EXPORTS_W Ptr createTonemap(float gamma = 1.0f); + +/** @brief Adaptive logarithmic mapping is a fast global tonemapping algorithm that scales the image in +logarithmic domain. + +Since it's a global operator the same function is applied to all the pixels, it is controlled by the +bias parameter. + +Optional saturation enhancement is possible as described in @cite FL02 . + +For more information see @cite DM03 . + */ +class CV_EXPORTS_W TonemapDrago : public Tonemap +{ +public: + + CV_WRAP virtual float getSaturation() const = 0; + CV_WRAP virtual void setSaturation(float saturation) = 0; + + CV_WRAP virtual float getBias() const = 0; + CV_WRAP virtual void setBias(float bias) = 0; +}; + +/** @brief Creates TonemapDrago object + +@param gamma gamma value for gamma correction. See createTonemap +@param saturation positive saturation enhancement value. 1.0 preserves saturation, values greater +than 1 increase saturation and values less than 1 decrease it. +@param bias value for bias function in [0, 1] range. Values from 0.7 to 0.9 usually give best +results, default value is 0.85. + */ +CV_EXPORTS_W Ptr createTonemapDrago(float gamma = 1.0f, float saturation = 1.0f, float bias = 0.85f); + + +/** @brief This is a global tonemapping operator that models human visual system. + +Mapping function is controlled by adaptation parameter, that is computed using light adaptation and +color adaptation. + +For more information see @cite RD05 . + */ +class CV_EXPORTS_W TonemapReinhard : public Tonemap +{ +public: + CV_WRAP virtual float getIntensity() const = 0; + CV_WRAP virtual void setIntensity(float intensity) = 0; + + CV_WRAP virtual float getLightAdaptation() const = 0; + CV_WRAP virtual void setLightAdaptation(float light_adapt) = 0; + + CV_WRAP virtual float getColorAdaptation() const = 0; + CV_WRAP virtual void setColorAdaptation(float color_adapt) = 0; +}; + +/** @brief Creates TonemapReinhard object + +@param gamma gamma value for gamma correction. See createTonemap +@param intensity result intensity in [-8, 8] range. Greater intensity produces brighter results. +@param light_adapt light adaptation in [0, 1] range. If 1 adaptation is based only on pixel +value, if 0 it's global, otherwise it's a weighted mean of this two cases. +@param color_adapt chromatic adaptation in [0, 1] range. If 1 channels are treated independently, +if 0 adaptation level is the same for each channel. + */ +CV_EXPORTS_W Ptr +createTonemapReinhard(float gamma = 1.0f, float intensity = 0.0f, float light_adapt = 1.0f, float color_adapt = 0.0f); + +/** @brief This algorithm transforms image to contrast using gradients on all levels of gaussian pyramid, +transforms contrast values to HVS response and scales the response. After this the image is +reconstructed from new contrast values. + +For more information see @cite MM06 . + */ +class CV_EXPORTS_W TonemapMantiuk : public Tonemap +{ +public: + CV_WRAP virtual float getScale() const = 0; + CV_WRAP virtual void setScale(float scale) = 0; + + CV_WRAP virtual float getSaturation() const = 0; + CV_WRAP virtual void setSaturation(float saturation) = 0; +}; + +/** @brief Creates TonemapMantiuk object + +@param gamma gamma value for gamma correction. See createTonemap +@param scale contrast scale factor. HVS response is multiplied by this parameter, thus compressing +dynamic range. Values from 0.6 to 0.9 produce best results. +@param saturation saturation enhancement value. See createTonemapDrago + */ +CV_EXPORTS_W Ptr +createTonemapMantiuk(float gamma = 1.0f, float scale = 0.7f, float saturation = 1.0f); + +/** @brief The base class for algorithms that align images of the same scene with different exposures + */ +class CV_EXPORTS_W AlignExposures : public Algorithm +{ +public: + /** @brief Aligns images + + @param src vector of input images + @param dst vector of aligned images + @param times vector of exposure time values for each image + @param response 256x1 matrix with inverse camera response function for each pixel value, it should + have the same number of channels as images. + */ + CV_WRAP virtual void process(InputArrayOfArrays src, std::vector& dst, + InputArray times, InputArray response) = 0; +}; + +/** @brief This algorithm converts images to median threshold bitmaps (1 for pixels brighter than median +luminance and 0 otherwise) and than aligns the resulting bitmaps using bit operations. + +It is invariant to exposure, so exposure values and camera response are not necessary. + +In this implementation new image regions are filled with zeros. + +For more information see @cite GW03 . + */ +class CV_EXPORTS_W AlignMTB : public AlignExposures +{ +public: + CV_WRAP virtual void process(InputArrayOfArrays src, std::vector& dst, + InputArray times, InputArray response) CV_OVERRIDE = 0; + + /** @brief Short version of process, that doesn't take extra arguments. + + @param src vector of input images + @param dst vector of aligned images + */ + CV_WRAP virtual void process(InputArrayOfArrays src, std::vector& dst) = 0; + + /** @brief Calculates shift between two images, i. e. how to shift the second image to correspond it with the + first. + + @param img0 first image + @param img1 second image + */ + CV_WRAP virtual Point calculateShift(InputArray img0, InputArray img1) = 0; + /** @brief Helper function, that shift Mat filling new regions with zeros. + + @param src input image + @param dst result image + @param shift shift value + */ + CV_WRAP virtual void shiftMat(InputArray src, OutputArray dst, const Point shift) = 0; + /** @brief Computes median threshold and exclude bitmaps of given image. + + @param img input image + @param tb median threshold bitmap + @param eb exclude bitmap + */ + CV_WRAP virtual void computeBitmaps(InputArray img, OutputArray tb, OutputArray eb) = 0; + + CV_WRAP virtual int getMaxBits() const = 0; + CV_WRAP virtual void setMaxBits(int max_bits) = 0; + + CV_WRAP virtual int getExcludeRange() const = 0; + CV_WRAP virtual void setExcludeRange(int exclude_range) = 0; + + CV_WRAP virtual bool getCut() const = 0; + CV_WRAP virtual void setCut(bool value) = 0; +}; + +/** @brief Creates AlignMTB object + +@param max_bits logarithm to the base 2 of maximal shift in each dimension. Values of 5 and 6 are +usually good enough (31 and 63 pixels shift respectively). +@param exclude_range range for exclusion bitmap that is constructed to suppress noise around the +median value. +@param cut if true cuts images, otherwise fills the new regions with zeros. + */ +CV_EXPORTS_W Ptr createAlignMTB(int max_bits = 6, int exclude_range = 4, bool cut = true); + +/** @brief The base class for camera response calibration algorithms. + */ +class CV_EXPORTS_W CalibrateCRF : public Algorithm +{ +public: + /** @brief Recovers inverse camera response. + + @param src vector of input images + @param dst 256x1 matrix with inverse camera response function + @param times vector of exposure time values for each image + */ + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0; +}; + +/** @brief Inverse camera response function is extracted for each brightness value by minimizing an objective +function as linear system. Objective function is constructed using pixel values on the same position +in all images, extra term is added to make the result smoother. + +For more information see @cite DM97 . + */ +class CV_EXPORTS_W CalibrateDebevec : public CalibrateCRF +{ +public: + CV_WRAP virtual float getLambda() const = 0; + CV_WRAP virtual void setLambda(float lambda) = 0; + + CV_WRAP virtual int getSamples() const = 0; + CV_WRAP virtual void setSamples(int samples) = 0; + + CV_WRAP virtual bool getRandom() const = 0; + CV_WRAP virtual void setRandom(bool random) = 0; +}; + +/** @brief Creates CalibrateDebevec object + +@param samples number of pixel locations to use +@param lambda smoothness term weight. Greater values produce smoother results, but can alter the +response. +@param random if true sample pixel locations are chosen at random, otherwise they form a +rectangular grid. + */ +CV_EXPORTS_W Ptr createCalibrateDebevec(int samples = 70, float lambda = 10.0f, bool random = false); + +/** @brief Inverse camera response function is extracted for each brightness value by minimizing an objective +function as linear system. This algorithm uses all image pixels. + +For more information see @cite RB99 . + */ +class CV_EXPORTS_W CalibrateRobertson : public CalibrateCRF +{ +public: + CV_WRAP virtual int getMaxIter() const = 0; + CV_WRAP virtual void setMaxIter(int max_iter) = 0; + + CV_WRAP virtual float getThreshold() const = 0; + CV_WRAP virtual void setThreshold(float threshold) = 0; + + CV_WRAP virtual Mat getRadiance() const = 0; +}; + +/** @brief Creates CalibrateRobertson object + +@param max_iter maximal number of Gauss-Seidel solver iterations. +@param threshold target difference between results of two successive steps of the minimization. + */ +CV_EXPORTS_W Ptr createCalibrateRobertson(int max_iter = 30, float threshold = 0.01f); + +/** @brief The base class algorithms that can merge exposure sequence to a single image. + */ +class CV_EXPORTS_W MergeExposures : public Algorithm +{ +public: + /** @brief Merges images. + + @param src vector of input images + @param dst result image + @param times vector of exposure time values for each image + @param response 256x1 matrix with inverse camera response function for each pixel value, it should + have the same number of channels as images. + */ + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, + InputArray times, InputArray response) = 0; +}; + +/** @brief The resulting HDR image is calculated as weighted average of the exposures considering exposure +values and camera response. + +For more information see @cite DM97 . + */ +class CV_EXPORTS_W MergeDebevec : public MergeExposures +{ +public: + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, + InputArray times, InputArray response) CV_OVERRIDE = 0; + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0; +}; + +/** @brief Creates MergeDebevec object + */ +CV_EXPORTS_W Ptr createMergeDebevec(); + +/** @brief Pixels are weighted using contrast, saturation and well-exposedness measures, than images are +combined using laplacian pyramids. + +The resulting image weight is constructed as weighted average of contrast, saturation and +well-exposedness measures. + +The resulting image doesn't require tonemapping and can be converted to 8-bit image by multiplying +by 255, but it's recommended to apply gamma correction and/or linear tonemapping. + +For more information see @cite MK07 . + */ +class CV_EXPORTS_W MergeMertens : public MergeExposures +{ +public: + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, + InputArray times, InputArray response) CV_OVERRIDE = 0; + /** @brief Short version of process, that doesn't take extra arguments. + + @param src vector of input images + @param dst result image + */ + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst) = 0; + + CV_WRAP virtual float getContrastWeight() const = 0; + CV_WRAP virtual void setContrastWeight(float contrast_weiht) = 0; + + CV_WRAP virtual float getSaturationWeight() const = 0; + CV_WRAP virtual void setSaturationWeight(float saturation_weight) = 0; + + CV_WRAP virtual float getExposureWeight() const = 0; + CV_WRAP virtual void setExposureWeight(float exposure_weight) = 0; +}; + +/** @brief Creates MergeMertens object + +@param contrast_weight contrast measure weight. See MergeMertens. +@param saturation_weight saturation measure weight +@param exposure_weight well-exposedness measure weight + */ +CV_EXPORTS_W Ptr +createMergeMertens(float contrast_weight = 1.0f, float saturation_weight = 1.0f, float exposure_weight = 0.0f); + +/** @brief The resulting HDR image is calculated as weighted average of the exposures considering exposure +values and camera response. + +For more information see @cite RB99 . + */ +class CV_EXPORTS_W MergeRobertson : public MergeExposures +{ +public: + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, + InputArray times, InputArray response) CV_OVERRIDE = 0; + CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0; +}; + +/** @brief Creates MergeRobertson object + */ +CV_EXPORTS_W Ptr createMergeRobertson(); + +//! @} photo_hdr + +//! @addtogroup photo_decolor +//! @{ + +/** @brief Transforms a color image to a grayscale image. It is a basic tool in digital printing, stylized +black-and-white photograph rendering, and in many single channel image processing applications +@cite CL12 . + +@param src Input 8-bit 3-channel image. +@param grayscale Output 8-bit 1-channel image. +@param color_boost Output 8-bit 3-channel image. + +This function is to be applied on color images. + */ +CV_EXPORTS_W void decolor( InputArray src, OutputArray grayscale, OutputArray color_boost); + +//! @} photo_decolor + +//! @addtogroup photo_clone +//! @{ + + +//! seamlessClone algorithm flags +enum +{ + /** The power of the method is fully expressed when inserting objects with complex outlines into a new background*/ + NORMAL_CLONE = 1, + /** The classic method, color-based selection and alpha masking might be time consuming and often leaves an undesirable + halo. Seamless cloning, even averaged with the original image, is not effective. Mixed seamless cloning based on a loose selection proves effective.*/ + MIXED_CLONE = 2, + /** Monochrome transfer allows the user to easily replace certain features of one object by alternative features.*/ + MONOCHROME_TRANSFER = 3}; + + +/** @example samples/cpp/tutorial_code/photo/seamless_cloning/cloning_demo.cpp +An example using seamlessClone function +*/ +/** @brief Image editing tasks concern either global changes (color/intensity corrections, filters, +deformations) or local changes concerned to a selection. Here we are interested in achieving local +changes, ones that are restricted to a region manually selected (ROI), in a seamless and effortless +manner. The extent of the changes ranges from slight distortions to complete replacement by novel +content @cite PM03 . + +@param src Input 8-bit 3-channel image. +@param dst Input 8-bit 3-channel image. +@param mask Input 8-bit 1 or 3-channel image. +@param p Point in dst image where object is placed. +@param blend Output image with the same size and type as dst. +@param flags Cloning method that could be cv::NORMAL_CLONE, cv::MIXED_CLONE or cv::MONOCHROME_TRANSFER + */ +CV_EXPORTS_W void seamlessClone( InputArray src, InputArray dst, InputArray mask, Point p, + OutputArray blend, int flags); + +/** @brief Given an original color image, two differently colored versions of this image can be mixed +seamlessly. + +@param src Input 8-bit 3-channel image. +@param mask Input 8-bit 1 or 3-channel image. +@param dst Output image with the same size and type as src . +@param red_mul R-channel multiply factor. +@param green_mul G-channel multiply factor. +@param blue_mul B-channel multiply factor. + +Multiplication factor is between .5 to 2.5. + */ +CV_EXPORTS_W void colorChange(InputArray src, InputArray mask, OutputArray dst, float red_mul = 1.0f, + float green_mul = 1.0f, float blue_mul = 1.0f); + +/** @brief Applying an appropriate non-linear transformation to the gradient field inside the selection and +then integrating back with a Poisson solver, modifies locally the apparent illumination of an image. + +@param src Input 8-bit 3-channel image. +@param mask Input 8-bit 1 or 3-channel image. +@param dst Output image with the same size and type as src. +@param alpha Value ranges between 0-2. +@param beta Value ranges between 0-2. + +This is useful to highlight under-exposed foreground objects or to reduce specular reflections. + */ +CV_EXPORTS_W void illuminationChange(InputArray src, InputArray mask, OutputArray dst, + float alpha = 0.2f, float beta = 0.4f); + +/** @brief By retaining only the gradients at edge locations, before integrating with the Poisson solver, one +washes out the texture of the selected region, giving its contents a flat aspect. Here Canny Edge %Detector is used. + +@param src Input 8-bit 3-channel image. +@param mask Input 8-bit 1 or 3-channel image. +@param dst Output image with the same size and type as src. +@param low_threshold %Range from 0 to 100. +@param high_threshold Value \> 100. +@param kernel_size The size of the Sobel kernel to be used. + +@note +The algorithm assumes that the color of the source image is close to that of the destination. This +assumption means that when the colors don't match, the source image color gets tinted toward the +color of the destination image. + */ +CV_EXPORTS_W void textureFlattening(InputArray src, InputArray mask, OutputArray dst, + float low_threshold = 30, float high_threshold = 45, + int kernel_size = 3); + +//! @} photo_clone + +//! @addtogroup photo_render +//! @{ + +//! Edge preserving filters +enum +{ + RECURS_FILTER = 1, //!< Recursive Filtering + NORMCONV_FILTER = 2 //!< Normalized Convolution Filtering +}; + +/** @brief Filtering is the fundamental operation in image and video processing. Edge-preserving smoothing +filters are used in many different applications @cite EM11 . + +@param src Input 8-bit 3-channel image. +@param dst Output 8-bit 3-channel image. +@param flags Edge preserving filters: cv::RECURS_FILTER or cv::NORMCONV_FILTER +@param sigma_s %Range between 0 to 200. +@param sigma_r %Range between 0 to 1. + */ +CV_EXPORTS_W void edgePreservingFilter(InputArray src, OutputArray dst, int flags = 1, + float sigma_s = 60, float sigma_r = 0.4f); + +/** @brief This filter enhances the details of a particular image. + +@param src Input 8-bit 3-channel image. +@param dst Output image with the same size and type as src. +@param sigma_s %Range between 0 to 200. +@param sigma_r %Range between 0 to 1. + */ +CV_EXPORTS_W void detailEnhance(InputArray src, OutputArray dst, float sigma_s = 10, + float sigma_r = 0.15f); + +/** @example samples/cpp/tutorial_code/photo/non_photorealistic_rendering/npr_demo.cpp +An example using non-photorealistic line drawing functions +*/ +/** @brief Pencil-like non-photorealistic line drawing + +@param src Input 8-bit 3-channel image. +@param dst1 Output 8-bit 1-channel image. +@param dst2 Output image with the same size and type as src. +@param sigma_s %Range between 0 to 200. +@param sigma_r %Range between 0 to 1. +@param shade_factor %Range between 0 to 0.1. + */ +CV_EXPORTS_W void pencilSketch(InputArray src, OutputArray dst1, OutputArray dst2, + float sigma_s = 60, float sigma_r = 0.07f, float shade_factor = 0.02f); + +/** @brief Stylization aims to produce digital imagery with a wide variety of effects not focused on +photorealism. Edge-aware filters are ideal for stylization, as they can abstract regions of low +contrast while preserving, or enhancing, high-contrast features. + +@param src Input 8-bit 3-channel image. +@param dst Output image with the same size and type as src. +@param sigma_s %Range between 0 to 200. +@param sigma_r %Range between 0 to 1. + */ +CV_EXPORTS_W void stylization(InputArray src, OutputArray dst, float sigma_s = 60, + float sigma_r = 0.45f); + +//! @} photo_render + +//! @} photo + +} // cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/photo/cuda.hpp b/Prj-Win/3rd/opencv/include/opencv2/photo/cuda.hpp new file mode 100755 index 0000000..a2f3816 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/photo/cuda.hpp @@ -0,0 +1,132 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_PHOTO_CUDA_HPP +#define OPENCV_PHOTO_CUDA_HPP + +#include "opencv2/core/cuda.hpp" + +namespace cv { namespace cuda { + +//! @addtogroup photo_denoise +//! @{ + +/** @brief Performs pure non local means denoising without any simplification, and thus it is not fast. + +@param src Source image. Supports only CV_8UC1, CV_8UC2 and CV_8UC3. +@param dst Destination image. +@param h Filter sigma regulating filter strength for color. +@param search_window Size of search window. +@param block_size Size of block used for computing weights. +@param borderMode Border type. See borderInterpolate for details. BORDER_REFLECT101 , +BORDER_REPLICATE , BORDER_CONSTANT , BORDER_REFLECT and BORDER_WRAP are supported for now. +@param stream Stream for the asynchronous version. + +@sa + fastNlMeansDenoising + */ +CV_EXPORTS void nonLocalMeans(InputArray src, OutputArray dst, + float h, + int search_window = 21, + int block_size = 7, + int borderMode = BORDER_DEFAULT, + Stream& stream = Stream::Null()); + +/** @brief Perform image denoising using Non-local Means Denoising algorithm + with several computational +optimizations. Noise expected to be a gaussian white noise + +@param src Input 8-bit 1-channel, 2-channel or 3-channel image. +@param dst Output image with the same size and type as src . +@param h Parameter regulating filter strength. Big h value perfectly removes noise but also +removes image details, smaller h value preserves details but also preserves some noise +@param search_window Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater search_window - greater +denoising time. Recommended value 21 pixels +@param block_size Size in pixels of the template patch that is used to compute weights. Should be +odd. Recommended value 7 pixels +@param stream Stream for the asynchronous invocations. + +This function expected to be applied to grayscale images. For colored images look at +FastNonLocalMeansDenoising::labMethod. + +@sa + fastNlMeansDenoising + */ +CV_EXPORTS void fastNlMeansDenoising(InputArray src, OutputArray dst, + float h, + int search_window = 21, + int block_size = 7, + Stream& stream = Stream::Null()); + +/** @brief Modification of fastNlMeansDenoising function for colored images + +@param src Input 8-bit 3-channel image. +@param dst Output image with the same size and type as src . +@param h_luminance Parameter regulating filter strength. Big h value perfectly removes noise but +also removes image details, smaller h value preserves details but also preserves some noise +@param photo_render float The same as h but for color components. For most images value equals 10 will be +enough to remove colored noise and do not distort colors +@param search_window Size in pixels of the window that is used to compute weighted average for +given pixel. Should be odd. Affect performance linearly: greater search_window - greater +denoising time. Recommended value 21 pixels +@param block_size Size in pixels of the template patch that is used to compute weights. Should be +odd. Recommended value 7 pixels +@param stream Stream for the asynchronous invocations. + +The function converts image to CIELAB colorspace and then separately denoise L and AB components +with given h parameters using FastNonLocalMeansDenoising::simpleMethod function. + +@sa + fastNlMeansDenoisingColored + */ +CV_EXPORTS void fastNlMeansDenoisingColored(InputArray src, OutputArray dst, + float h_luminance, float photo_render, + int search_window = 21, + int block_size = 7, + Stream& stream = Stream::Null()); + +//! @} photo + +}} // namespace cv { namespace cuda { + +#endif /* OPENCV_PHOTO_CUDA_HPP */ diff --git a/Prj-Win/3rd/opencv/include/opencv2/photo/legacy/constants_c.h b/Prj-Win/3rd/opencv/include/opencv2/photo/legacy/constants_c.h new file mode 100755 index 0000000..ec1d440 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/photo/legacy/constants_c.h @@ -0,0 +1,14 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_PHOTO_LEGACY_CONSTANTS_H +#define OPENCV_PHOTO_LEGACY_CONSTANTS_H + +enum InpaintingModes +{ + CV_INPAINT_NS =0, + CV_INPAINT_TELEA =1 +}; + +#endif // OPENCV_PHOTO_LEGACY_CONSTANTS_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/photo/photo.hpp b/Prj-Win/3rd/opencv/include/opencv2/photo/photo.hpp new file mode 100755 index 0000000..8af5e9f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/photo/photo.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/photo.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching.hpp new file mode 100755 index 0000000..016e7d8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching.hpp @@ -0,0 +1,343 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_STITCHER_HPP +#define OPENCV_STITCHING_STITCHER_HPP + +#include "opencv2/core.hpp" +#include "opencv2/features2d.hpp" +#include "opencv2/stitching/warpers.hpp" +#include "opencv2/stitching/detail/matchers.hpp" +#include "opencv2/stitching/detail/motion_estimators.hpp" +#include "opencv2/stitching/detail/exposure_compensate.hpp" +#include "opencv2/stitching/detail/seam_finders.hpp" +#include "opencv2/stitching/detail/blenders.hpp" +#include "opencv2/stitching/detail/camera.hpp" + + +#if defined(Status) +# warning Detected X11 'Status' macro definition, it can cause build conflicts. Please, include this header before any X11 headers. +#endif + + +/** +@defgroup stitching Images stitching + +This figure illustrates the stitching module pipeline implemented in the Stitcher class. Using that +class it's possible to configure/remove some steps, i.e. adjust the stitching pipeline according to +the particular needs. All building blocks from the pipeline are available in the detail namespace, +one can combine and use them separately. + +The implemented stitching pipeline is very similar to the one proposed in @cite BL07 . + +![stitching pipeline](StitchingPipeline.jpg) + +Camera models +------------- + +There are currently 2 camera models implemented in stitching pipeline. + +- _Homography model_ expecting perspective transformations between images + implemented in @ref cv::detail::BestOf2NearestMatcher cv::detail::HomographyBasedEstimator + cv::detail::BundleAdjusterReproj cv::detail::BundleAdjusterRay +- _Affine model_ expecting affine transformation with 6 DOF or 4 DOF implemented in + @ref cv::detail::AffineBestOf2NearestMatcher cv::detail::AffineBasedEstimator + cv::detail::BundleAdjusterAffine cv::detail::BundleAdjusterAffinePartial cv::AffineWarper + +Homography model is useful for creating photo panoramas captured by camera, +while affine-based model can be used to stitch scans and object captured by +specialized devices. Use @ref cv::Stitcher::create to get preconfigured pipeline for one +of those models. + +@note +Certain detailed settings of @ref cv::Stitcher might not make sense. Especially +you should not mix classes implementing affine model and classes implementing +Homography model, as they work with different transformations. + +@{ + @defgroup stitching_match Features Finding and Images Matching + @defgroup stitching_rotation Rotation Estimation + @defgroup stitching_autocalib Autocalibration + @defgroup stitching_warp Images Warping + @defgroup stitching_seam Seam Estimation + @defgroup stitching_exposure Exposure Compensation + @defgroup stitching_blend Image Blenders +@} + */ + +namespace cv { + +//! @addtogroup stitching +//! @{ + +/** @example samples/cpp/stitching.cpp +A basic example on image stitching +*/ + +/** @example samples/python/stitching.py +A basic example on image stitching in Python. +*/ + +/** @example samples/cpp/stitching_detailed.cpp +A detailed example on image stitching +*/ + +/** @brief High level image stitcher. + +It's possible to use this class without being aware of the entire stitching pipeline. However, to +be able to achieve higher stitching stability and quality of the final images at least being +familiar with the theory is recommended. + +@note +- A basic example on image stitching can be found at + opencv_source_code/samples/cpp/stitching.cpp +- A basic example on image stitching in Python can be found at + opencv_source_code/samples/python/stitching.py +- A detailed example on image stitching can be found at + opencv_source_code/samples/cpp/stitching_detailed.cpp + */ +class CV_EXPORTS_W Stitcher +{ +public: + /** + * When setting a resolution for stitching, this values is a placeholder + * for preserving the original resolution. + */ +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/) + static constexpr double ORIG_RESOL = -1.0; +#else + // support MSVS 2013 + static const double ORIG_RESOL; // Initialized in stitcher.cpp +#endif + + enum Status + { + OK = 0, + ERR_NEED_MORE_IMGS = 1, + ERR_HOMOGRAPHY_EST_FAIL = 2, + ERR_CAMERA_PARAMS_ADJUST_FAIL = 3 + }; + + enum Mode + { + /** Mode for creating photo panoramas. Expects images under perspective + transformation and projects resulting pano to sphere. + + @sa detail::BestOf2NearestMatcher SphericalWarper + */ + PANORAMA = 0, + /** Mode for composing scans. Expects images under affine transformation does + not compensate exposure by default. + + @sa detail::AffineBestOf2NearestMatcher AffineWarper + */ + SCANS = 1, + + }; + + /** @brief Creates a Stitcher configured in one of the stitching modes. + + @param mode Scenario for stitcher operation. This is usually determined by source of images + to stitch and their transformation. Default parameters will be chosen for operation in given + scenario. + @return Stitcher class instance. + */ + CV_WRAP static Ptr create(Mode mode = Stitcher::PANORAMA); + + CV_WRAP double registrationResol() const { return registr_resol_; } + CV_WRAP void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; } + + CV_WRAP double seamEstimationResol() const { return seam_est_resol_; } + CV_WRAP void setSeamEstimationResol(double resol_mpx) { seam_est_resol_ = resol_mpx; } + + CV_WRAP double compositingResol() const { return compose_resol_; } + CV_WRAP void setCompositingResol(double resol_mpx) { compose_resol_ = resol_mpx; } + + CV_WRAP double panoConfidenceThresh() const { return conf_thresh_; } + CV_WRAP void setPanoConfidenceThresh(double conf_thresh) { conf_thresh_ = conf_thresh; } + + CV_WRAP bool waveCorrection() const { return do_wave_correct_; } + CV_WRAP void setWaveCorrection(bool flag) { do_wave_correct_ = flag; } + + CV_WRAP InterpolationFlags interpolationFlags() const { return interp_flags_; } + CV_WRAP void setInterpolationFlags(InterpolationFlags interp_flags) { interp_flags_ = interp_flags; } + + detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; } + void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; } + + Ptr featuresFinder() { return features_finder_; } + const Ptr featuresFinder() const { return features_finder_; } + void setFeaturesFinder(Ptr features_finder) + { features_finder_ = features_finder; } + + Ptr featuresMatcher() { return features_matcher_; } + const Ptr featuresMatcher() const { return features_matcher_; } + void setFeaturesMatcher(Ptr features_matcher) + { features_matcher_ = features_matcher; } + + const cv::UMat& matchingMask() const { return matching_mask_; } + void setMatchingMask(const cv::UMat &mask) + { + CV_Assert(mask.type() == CV_8U && mask.cols == mask.rows); + matching_mask_ = mask.clone(); + } + + Ptr bundleAdjuster() { return bundle_adjuster_; } + const Ptr bundleAdjuster() const { return bundle_adjuster_; } + void setBundleAdjuster(Ptr bundle_adjuster) + { bundle_adjuster_ = bundle_adjuster; } + + Ptr estimator() { return estimator_; } + const Ptr estimator() const { return estimator_; } + void setEstimator(Ptr estimator) + { estimator_ = estimator; } + + Ptr warper() { return warper_; } + const Ptr warper() const { return warper_; } + void setWarper(Ptr creator) { warper_ = creator; } + + Ptr exposureCompensator() { return exposure_comp_; } + const Ptr exposureCompensator() const { return exposure_comp_; } + void setExposureCompensator(Ptr exposure_comp) + { exposure_comp_ = exposure_comp; } + + Ptr seamFinder() { return seam_finder_; } + const Ptr seamFinder() const { return seam_finder_; } + void setSeamFinder(Ptr seam_finder) { seam_finder_ = seam_finder; } + + Ptr blender() { return blender_; } + const Ptr blender() const { return blender_; } + void setBlender(Ptr b) { blender_ = b; } + + /** @brief These functions try to match the given images and to estimate rotations of each camera. + + @note Use the functions only if you're aware of the stitching pipeline, otherwise use + Stitcher::stitch. + + @param images Input images. + @param masks Masks for each input image specifying where to look for keypoints (optional). + @return Status code. + */ + CV_WRAP Status estimateTransform(InputArrayOfArrays images, InputArrayOfArrays masks = noArray()); + + /** @overload */ + CV_WRAP Status composePanorama(OutputArray pano); + /** @brief These functions try to compose the given images (or images stored internally from the other function + calls) into the final pano under the assumption that the image transformations were estimated + before. + + @note Use the functions only if you're aware of the stitching pipeline, otherwise use + Stitcher::stitch. + + @param images Input images. + @param pano Final pano. + @return Status code. + */ + Status composePanorama(InputArrayOfArrays images, OutputArray pano); + + /** @overload */ + CV_WRAP Status stitch(InputArrayOfArrays images, OutputArray pano); + /** @brief These functions try to stitch the given images. + + @param images Input images. + @param masks Masks for each input image specifying where to look for keypoints (optional). + @param pano Final pano. + @return Status code. + */ + CV_WRAP Status stitch(InputArrayOfArrays images, InputArrayOfArrays masks, OutputArray pano); + + std::vector component() const { return indices_; } + std::vector cameras() const { return cameras_; } + CV_WRAP double workScale() const { return work_scale_; } + UMat resultMask() const { return result_mask_; } + +private: + Status matchImages(); + Status estimateCameraParams(); + + double registr_resol_; + double seam_est_resol_; + double compose_resol_; + double conf_thresh_; + InterpolationFlags interp_flags_; + Ptr features_finder_; + Ptr features_matcher_; + cv::UMat matching_mask_; + Ptr bundle_adjuster_; + Ptr estimator_; + bool do_wave_correct_; + detail::WaveCorrectKind wave_correct_kind_; + Ptr warper_; + Ptr exposure_comp_; + Ptr seam_finder_; + Ptr blender_; + + std::vector imgs_; + std::vector masks_; + std::vector full_img_sizes_; + std::vector features_; + std::vector pairwise_matches_; + std::vector seam_est_imgs_; + std::vector indices_; + std::vector cameras_; + UMat result_mask_; + double work_scale_; + double seam_scale_; + double seam_work_aspect_; + double warped_image_scale_; +}; + +/** + * @deprecated use Stitcher::create + */ +CV_DEPRECATED Ptr createStitcher(bool try_use_gpu = false); + +/** + * @deprecated use Stitcher::create + */ +CV_DEPRECATED Ptr createStitcherScans(bool try_use_gpu = false); + +//! @} stitching + +} // namespace cv + +#endif // OPENCV_STITCHING_STITCHER_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/autocalib.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/autocalib.hpp new file mode 100755 index 0000000..8eb6212 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/autocalib.hpp @@ -0,0 +1,86 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_AUTOCALIB_HPP +#define OPENCV_STITCHING_AUTOCALIB_HPP + +#include "opencv2/core.hpp" +#include "matchers.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching_autocalib +//! @{ + +/** @brief Tries to estimate focal lengths from the given homography under the assumption that the camera +undergoes rotations around its centre only. + +@param H Homography. +@param f0 Estimated focal length along X axis. +@param f1 Estimated focal length along Y axis. +@param f0_ok True, if f0 was estimated successfully, false otherwise. +@param f1_ok True, if f1 was estimated successfully, false otherwise. + +See "Construction of Panoramic Image Mosaics with Global and Local Alignment" +by Heung-Yeung Shum and Richard Szeliski. + */ +void CV_EXPORTS_W focalsFromHomography(const Mat &H, double &f0, double &f1, bool &f0_ok, bool &f1_ok); + +/** @brief Estimates focal lengths for each given camera. + +@param features Features of images. +@param pairwise_matches Matches between all image pairs. +@param focals Estimated focal lengths for each camera. + */ +void CV_EXPORTS estimateFocal(const std::vector &features, + const std::vector &pairwise_matches, + std::vector &focals); + +bool CV_EXPORTS_W calibrateRotatingCamera(const std::vector &Hs,CV_OUT Mat &K); + +//! @} stitching_autocalib + +} // namespace detail +} // namespace cv + +#endif // OPENCV_STITCHING_AUTOCALIB_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/blenders.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/blenders.hpp new file mode 100755 index 0000000..ec35aa7 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/blenders.hpp @@ -0,0 +1,184 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_BLENDERS_HPP +#define OPENCV_STITCHING_BLENDERS_HPP + +#if defined(NO) +# warning Detected Apple 'NO' macro definition, it can cause build conflicts. Please, include this header before any Apple headers. +#endif + +#include "opencv2/core.hpp" +#include "opencv2/core/cuda.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching_blend +//! @{ + +/** @brief Base class for all blenders. + +Simple blender which puts one image over another +*/ +class CV_EXPORTS_W Blender +{ +public: + virtual ~Blender() {} + + enum { NO, FEATHER, MULTI_BAND }; + CV_WRAP static Ptr createDefault(int type, bool try_gpu = false); + + /** @brief Prepares the blender for blending. + + @param corners Source images top-left corners + @param sizes Source image sizes + */ + CV_WRAP virtual void prepare(const std::vector &corners, const std::vector &sizes); + /** @overload */ + CV_WRAP virtual void prepare(Rect dst_roi); + /** @brief Processes the image. + + @param img Source image + @param mask Source image mask + @param tl Source image top-left corners + */ + CV_WRAP virtual void feed(InputArray img, InputArray mask, Point tl); + /** @brief Blends and returns the final pano. + + @param dst Final pano + @param dst_mask Final pano mask + */ + CV_WRAP virtual void blend(CV_IN_OUT InputOutputArray dst,CV_IN_OUT InputOutputArray dst_mask); + +protected: + UMat dst_, dst_mask_; + Rect dst_roi_; +}; + +/** @brief Simple blender which mixes images at its borders. + */ +class CV_EXPORTS_W FeatherBlender : public Blender +{ +public: + CV_WRAP FeatherBlender(float sharpness = 0.02f); + + CV_WRAP float sharpness() const { return sharpness_; } + CV_WRAP void setSharpness(float val) { sharpness_ = val; } + + CV_WRAP void prepare(Rect dst_roi) CV_OVERRIDE; + CV_WRAP void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE; + CV_WRAP void blend(InputOutputArray dst, InputOutputArray dst_mask) CV_OVERRIDE; + + //! Creates weight maps for fixed set of source images by their masks and top-left corners. + //! Final image can be obtained by simple weighting of the source images. + CV_WRAP Rect createWeightMaps(const std::vector &masks, const std::vector &corners, + CV_IN_OUT std::vector &weight_maps); + +private: + float sharpness_; + UMat weight_map_; + UMat dst_weight_map_; +}; + +inline FeatherBlender::FeatherBlender(float _sharpness) { setSharpness(_sharpness); } + +/** @brief Blender which uses multi-band blending algorithm (see @cite BA83). + */ +class CV_EXPORTS_W MultiBandBlender : public Blender +{ +public: + CV_WRAP MultiBandBlender(int try_gpu = false, int num_bands = 5, int weight_type = CV_32F); + + CV_WRAP int numBands() const { return actual_num_bands_; } + CV_WRAP void setNumBands(int val) { actual_num_bands_ = val; } + + CV_WRAP void prepare(Rect dst_roi) CV_OVERRIDE; + CV_WRAP void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE; + CV_WRAP void blend(CV_IN_OUT InputOutputArray dst, CV_IN_OUT InputOutputArray dst_mask) CV_OVERRIDE; + +private: + int actual_num_bands_, num_bands_; + std::vector dst_pyr_laplace_; + std::vector dst_band_weights_; + Rect dst_roi_final_; + bool can_use_gpu_; + int weight_type_; //CV_32F or CV_16S +#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING) + std::vector gpu_dst_pyr_laplace_; + std::vector gpu_dst_band_weights_; + std::vector gpu_tl_points_; + std::vector gpu_imgs_with_border_; + std::vector > gpu_weight_pyr_gauss_vec_; + std::vector > gpu_src_pyr_laplace_vec_; + std::vector > gpu_ups_; + cuda::GpuMat gpu_dst_mask_; + cuda::GpuMat gpu_mask_; + cuda::GpuMat gpu_img_; + cuda::GpuMat gpu_weight_map_; + cuda::GpuMat gpu_add_mask_; + int gpu_feed_idx_; + bool gpu_initialized_; +#endif +}; + + +////////////////////////////////////////////////////////////////////////////// +// Auxiliary functions + +void CV_EXPORTS_W normalizeUsingWeightMap(InputArray weight, CV_IN_OUT InputOutputArray src); + +void CV_EXPORTS_W createWeightMap(InputArray mask, float sharpness, CV_IN_OUT InputOutputArray weight); + +void CV_EXPORTS_W createLaplacePyr(InputArray img, int num_levels, CV_IN_OUT std::vector& pyr); +void CV_EXPORTS_W createLaplacePyrGpu(InputArray img, int num_levels, CV_IN_OUT std::vector& pyr); + +// Restores source image +void CV_EXPORTS_W restoreImageFromLaplacePyr(CV_IN_OUT std::vector& pyr); +void CV_EXPORTS_W restoreImageFromLaplacePyrGpu(CV_IN_OUT std::vector& pyr); + +//! @} + +} // namespace detail +} // namespace cv + +#endif // OPENCV_STITCHING_BLENDERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/camera.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/camera.hpp new file mode 100755 index 0000000..14ecf60 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/camera.hpp @@ -0,0 +1,78 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_CAMERA_HPP +#define OPENCV_STITCHING_CAMERA_HPP + +#include "opencv2/core.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching +//! @{ + +/** @brief Describes camera parameters. + +@note Translation is assumed to be zero during the whole stitching pipeline. : + */ +struct CV_EXPORTS_W_SIMPLE CameraParams +{ + CameraParams(); + CameraParams(const CameraParams& other); + CameraParams& operator =(const CameraParams& other); + CV_WRAP Mat K() const; + + CV_PROP_RW double focal; // Focal length + CV_PROP_RW double aspect; // Aspect ratio + CV_PROP_RW double ppx; // Principal point X + CV_PROP_RW double ppy; // Principal point Y + CV_PROP_RW Mat R; // Rotation + CV_PROP_RW Mat t; // Translation +}; + +//! @} + +} // namespace detail +} // namespace cv + +#endif // #ifndef OPENCV_STITCHING_CAMERA_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/exposure_compensate.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/exposure_compensate.hpp new file mode 100755 index 0000000..2b76d09 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/exposure_compensate.hpp @@ -0,0 +1,230 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP +#define OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP + +#if defined(NO) +# warning Detected Apple 'NO' macro definition, it can cause build conflicts. Please, include this header before any Apple headers. +#endif + +#include "opencv2/core.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching_exposure +//! @{ + +/** @brief Base class for all exposure compensators. + */ +class CV_EXPORTS_W ExposureCompensator +{ +public: + ExposureCompensator(): updateGain(true) {} + virtual ~ExposureCompensator() {} + + enum { NO, GAIN, GAIN_BLOCKS, CHANNELS, CHANNELS_BLOCKS }; + CV_WRAP static Ptr createDefault(int type); + + /** + @param corners Source image top-left corners + @param images Source images + @param masks Image masks to update (second value in pair specifies the value which should be used + to detect where image is) + */ + CV_WRAP void feed(const std::vector &corners, const std::vector &images, + const std::vector &masks); + /** @overload */ + virtual void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks) = 0; + /** @brief Compensate exposure in the specified image. + + @param index Image index + @param corner Image top-left corner + @param image Image to process + @param mask Image mask + */ + CV_WRAP virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0; + CV_WRAP virtual void getMatGains(CV_OUT std::vector& ) {CV_Error(Error::StsInternal, "");}; + CV_WRAP virtual void setMatGains(std::vector& ) { CV_Error(Error::StsInternal, ""); }; + CV_WRAP void setUpdateGain(bool b) { updateGain = b; }; + CV_WRAP bool getUpdateGain() { return updateGain; }; +protected : + bool updateGain; +}; + +/** @brief Stub exposure compensator which does nothing. + */ +class CV_EXPORTS_W NoExposureCompensator : public ExposureCompensator +{ +public: + void feed(const std::vector &/*corners*/, const std::vector &/*images*/, + const std::vector > &/*masks*/) CV_OVERRIDE { } + CV_WRAP void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) CV_OVERRIDE { } + CV_WRAP void getMatGains(CV_OUT std::vector& umv) CV_OVERRIDE { umv.clear(); return; }; + CV_WRAP void setMatGains(std::vector& umv) CV_OVERRIDE { umv.clear(); return; }; +}; + +/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image +intensities, see @cite BL07 and @cite WJ10 for details. + */ +class CV_EXPORTS_W GainCompensator : public ExposureCompensator +{ +public: + // This Constructor only exists to make source level compatibility detector happy + CV_WRAP GainCompensator() + : GainCompensator(1) {} + CV_WRAP GainCompensator(int nr_feeds) + : nr_feeds_(nr_feeds) {} + void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks) CV_OVERRIDE; + void singleFeed(const std::vector &corners, const std::vector &images, + const std::vector > &masks); + CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE; + CV_WRAP void getMatGains(CV_OUT std::vector& umv) CV_OVERRIDE ; + CV_WRAP void setMatGains(std::vector& umv) CV_OVERRIDE ; + CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; } + CV_WRAP int getNrFeeds() { return nr_feeds_; } + std::vector gains() const; + +private: + Mat_ gains_; + int nr_feeds_; +}; + +/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image +intensities on each channel independently. + */ +class CV_EXPORTS_W ChannelsCompensator : public ExposureCompensator +{ +public: + CV_WRAP ChannelsCompensator(int nr_feeds=1) : nr_feeds_(nr_feeds) {} + void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks) CV_OVERRIDE; + CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE; + CV_WRAP void getMatGains(CV_OUT std::vector& umv) CV_OVERRIDE; + CV_WRAP void setMatGains(std::vector& umv) CV_OVERRIDE; + CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; } + CV_WRAP int getNrFeeds() { return nr_feeds_; } + std::vector gains() const { return gains_; } + +private: + std::vector gains_; + int nr_feeds_; +}; + +/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image blocks. + */ +class CV_EXPORTS_W BlocksCompensator : public ExposureCompensator +{ +public: + BlocksCompensator(int bl_width=32, int bl_height=32, int nr_feeds=1) + : bl_width_(bl_width), bl_height_(bl_height), nr_feeds_(nr_feeds), nr_gain_filtering_iterations_(2) {} + CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE; + CV_WRAP void getMatGains(CV_OUT std::vector& umv) CV_OVERRIDE; + CV_WRAP void setMatGains(std::vector& umv) CV_OVERRIDE; + CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; } + CV_WRAP int getNrFeeds() { return nr_feeds_; } + CV_WRAP void setBlockSize(int width, int height) { bl_width_ = width; bl_height_ = height; } + CV_WRAP void setBlockSize(Size size) { setBlockSize(size.width, size.height); } + CV_WRAP Size getBlockSize() const { return Size(bl_width_, bl_height_); } + CV_WRAP void setNrGainsFilteringIterations(int nr_iterations) { nr_gain_filtering_iterations_ = nr_iterations; } + CV_WRAP int getNrGainsFilteringIterations() const { return nr_gain_filtering_iterations_; } + +protected: + template + void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks); + +private: + UMat getGainMap(const GainCompensator& compensator, int bl_idx, Size bl_per_img); + UMat getGainMap(const ChannelsCompensator& compensator, int bl_idx, Size bl_per_img); + + int bl_width_, bl_height_; + std::vector gain_maps_; + int nr_feeds_; + int nr_gain_filtering_iterations_; +}; + +/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block +intensities, see @cite UES01 for details. + */ +class CV_EXPORTS_W BlocksGainCompensator : public BlocksCompensator +{ +public: + // This Constructor only exists to make source level compatibility detector happy + CV_WRAP BlocksGainCompensator(int bl_width = 32, int bl_height = 32) + : BlocksGainCompensator(bl_width, bl_height, 1) {} + CV_WRAP BlocksGainCompensator(int bl_width, int bl_height, int nr_feeds) + : BlocksCompensator(bl_width, bl_height, nr_feeds) {} + + void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks) CV_OVERRIDE; + + // This function only exists to make source level compatibility detector happy + CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE { + BlocksCompensator::apply(index, corner, image, mask); } + // This function only exists to make source level compatibility detector happy + CV_WRAP void getMatGains(CV_OUT std::vector& umv) CV_OVERRIDE { BlocksCompensator::getMatGains(umv); } + // This function only exists to make source level compatibility detector happy + CV_WRAP void setMatGains(std::vector& umv) CV_OVERRIDE { BlocksCompensator::setMatGains(umv); } +}; + +/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block +on each channel. + */ +class CV_EXPORTS_W BlocksChannelsCompensator : public BlocksCompensator +{ +public: + CV_WRAP BlocksChannelsCompensator(int bl_width=32, int bl_height=32, int nr_feeds=1) + : BlocksCompensator(bl_width, bl_height, nr_feeds) {} + + void feed(const std::vector &corners, const std::vector &images, + const std::vector > &masks) CV_OVERRIDE; +}; +//! @} + +} // namespace detail +} // namespace cv + +#endif // OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/matchers.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/matchers.hpp new file mode 100755 index 0000000..c933a36 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/matchers.hpp @@ -0,0 +1,253 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_MATCHERS_HPP +#define OPENCV_STITCHING_MATCHERS_HPP + +#include "opencv2/core.hpp" +#include "opencv2/features2d.hpp" + +#include "opencv2/opencv_modules.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching_match +//! @{ + +/** @brief Structure containing image keypoints and descriptors. */ +struct CV_EXPORTS_W_SIMPLE ImageFeatures +{ + CV_PROP_RW int img_idx; + CV_PROP_RW Size img_size; + std::vector keypoints; + CV_PROP_RW UMat descriptors; + CV_WRAP std::vector getKeypoints() { return keypoints; }; +}; +/** @brief + +@param featuresFinder +@param images +@param features +@param masks +*/ +CV_EXPORTS_W void computeImageFeatures( + const Ptr &featuresFinder, + InputArrayOfArrays images, + CV_OUT std::vector &features, + InputArrayOfArrays masks = noArray()); + +/** @brief + +@param featuresFinder +@param image +@param features +@param mask +*/ +CV_EXPORTS_AS(computeImageFeatures2) void computeImageFeatures( + const Ptr &featuresFinder, + InputArray image, + CV_OUT ImageFeatures &features, + InputArray mask = noArray()); + +/** @brief Structure containing information about matches between two images. + +It's assumed that there is a transformation between those images. Transformation may be +homography or affine transformation based on selected matcher. + +@sa detail::FeaturesMatcher +*/ +struct CV_EXPORTS_W_SIMPLE MatchesInfo +{ + MatchesInfo(); + MatchesInfo(const MatchesInfo &other); + MatchesInfo& operator =(const MatchesInfo &other); + + CV_PROP_RW int src_img_idx; + CV_PROP_RW int dst_img_idx; //!< Images indices (optional) + std::vector matches; + std::vector inliers_mask; //!< Geometrically consistent matches mask + CV_PROP_RW int num_inliers; //!< Number of geometrically consistent matches + CV_PROP_RW Mat H; //!< Estimated transformation + CV_PROP_RW double confidence; //!< Confidence two images are from the same panorama + CV_WRAP std::vector getMatches() { return matches; }; + CV_WRAP std::vector getInliers() { return inliers_mask; }; +}; + +/** @brief Feature matchers base class. */ +class CV_EXPORTS_W FeaturesMatcher +{ +public: + CV_WRAP virtual ~FeaturesMatcher() {} + + /** @overload + @param features1 First image features + @param features2 Second image features + @param matches_info Found matches + */ + CV_WRAP_AS(apply) void operator ()(const ImageFeatures &features1, const ImageFeatures &features2, + CV_OUT MatchesInfo& matches_info) { match(features1, features2, matches_info); } + + /** @brief Performs images matching. + + @param features Features of the source images + @param pairwise_matches Found pairwise matches + @param mask Mask indicating which image pairs must be matched + + The function is parallelized with the TBB library. + + @sa detail::MatchesInfo + */ + CV_WRAP_AS(apply2) void operator ()(const std::vector &features, CV_OUT std::vector &pairwise_matches, + const cv::UMat &mask = cv::UMat()); + + /** @return True, if it's possible to use the same matcher instance in parallel, false otherwise + */ + CV_WRAP bool isThreadSafe() const { return is_thread_safe_; } + + /** @brief Frees unused memory allocated before if there is any. + */ + CV_WRAP virtual void collectGarbage() {} + +protected: + FeaturesMatcher(bool is_thread_safe = false) : is_thread_safe_(is_thread_safe) {} + + /** @brief This method must implement matching logic in order to make the wrappers + detail::FeaturesMatcher::operator()_ work. + + @param features1 first image features + @param features2 second image features + @param matches_info found matches + */ + virtual void match(const ImageFeatures &features1, const ImageFeatures &features2, + MatchesInfo& matches_info) = 0; + + bool is_thread_safe_; +}; + +/** @brief Features matcher which finds two best matches for each feature and leaves the best one only if the +ratio between descriptor distances is greater than the threshold match_conf + +@sa detail::FeaturesMatcher + */ +class CV_EXPORTS_W BestOf2NearestMatcher : public FeaturesMatcher +{ +public: + /** @brief Constructs a "best of 2 nearest" matcher. + + @param try_use_gpu Should try to use GPU or not + @param match_conf Match distances ration threshold + @param num_matches_thresh1 Minimum number of matches required for the 2D projective transform + estimation used in the inliers classification step + @param num_matches_thresh2 Minimum number of matches required for the 2D projective transform + re-estimation on inliers + */ + CV_WRAP BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6, + int num_matches_thresh2 = 6); + + CV_WRAP void collectGarbage() CV_OVERRIDE; + CV_WRAP static Ptr create(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6, + int num_matches_thresh2 = 6); + +protected: + + void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info) CV_OVERRIDE; + int num_matches_thresh1_; + int num_matches_thresh2_; + Ptr impl_; +}; + +class CV_EXPORTS_W BestOf2NearestRangeMatcher : public BestOf2NearestMatcher +{ +public: + CV_WRAP BestOf2NearestRangeMatcher(int range_width = 5, bool try_use_gpu = false, float match_conf = 0.3f, + int num_matches_thresh1 = 6, int num_matches_thresh2 = 6); + + void operator ()(const std::vector &features, std::vector &pairwise_matches, + const cv::UMat &mask = cv::UMat()); + + +protected: + int range_width_; +}; + +/** @brief Features matcher similar to cv::detail::BestOf2NearestMatcher which +finds two best matches for each feature and leaves the best one only if the +ratio between descriptor distances is greater than the threshold match_conf. + +Unlike cv::detail::BestOf2NearestMatcher this matcher uses affine +transformation (affine trasformation estimate will be placed in matches_info). + +@sa cv::detail::FeaturesMatcher cv::detail::BestOf2NearestMatcher + */ +class CV_EXPORTS_W AffineBestOf2NearestMatcher : public BestOf2NearestMatcher +{ +public: + /** @brief Constructs a "best of 2 nearest" matcher that expects affine trasformation + between images + + @param full_affine whether to use full affine transformation with 6 degress of freedom or reduced + transformation with 4 degrees of freedom using only rotation, translation and uniform scaling + @param try_use_gpu Should try to use GPU or not + @param match_conf Match distances ration threshold + @param num_matches_thresh1 Minimum number of matches required for the 2D affine transform + estimation used in the inliers classification step + + @sa cv::estimateAffine2D cv::estimateAffinePartial2D + */ + CV_WRAP AffineBestOf2NearestMatcher(bool full_affine = false, bool try_use_gpu = false, + float match_conf = 0.3f, int num_matches_thresh1 = 6) : + BestOf2NearestMatcher(try_use_gpu, match_conf, num_matches_thresh1, num_matches_thresh1), + full_affine_(full_affine) {} + +protected: + void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info) CV_OVERRIDE; + + bool full_affine_; +}; + +//! @} stitching_match + +} // namespace detail +} // namespace cv + +#endif // OPENCV_STITCHING_MATCHERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/motion_estimators.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/motion_estimators.hpp new file mode 100755 index 0000000..ff05af1 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/motion_estimators.hpp @@ -0,0 +1,363 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_MOTION_ESTIMATORS_HPP +#define OPENCV_STITCHING_MOTION_ESTIMATORS_HPP + +#include "opencv2/core.hpp" +#include "matchers.hpp" +#include "util.hpp" +#include "camera.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching_rotation +//! @{ + +/** @brief Rotation estimator base class. + +It takes features of all images, pairwise matches between all images and estimates rotations of all +cameras. + +@note The coordinate system origin is implementation-dependent, but you can always normalize the +rotations in respect to the first camera, for instance. : + */ +class CV_EXPORTS_W Estimator +{ +public: + virtual ~Estimator() {} + + /** @brief Estimates camera parameters. + + @param features Features of images + @param pairwise_matches Pairwise matches of images + @param cameras Estimated camera parameters + @return True in case of success, false otherwise + */ + CV_WRAP_AS(apply) bool operator ()(const std::vector &features, + const std::vector &pairwise_matches, + CV_OUT CV_IN_OUT std::vector &cameras) + { + return estimate(features, pairwise_matches, cameras); + } + +protected: + /** @brief This method must implement camera parameters estimation logic in order to make the wrapper + detail::Estimator::operator()_ work. + + @param features Features of images + @param pairwise_matches Pairwise matches of images + @param cameras Estimated camera parameters + @return True in case of success, false otherwise + */ + virtual bool estimate(const std::vector &features, + const std::vector &pairwise_matches, + CV_OUT std::vector &cameras) = 0; +}; + +/** @brief Homography based rotation estimator. + */ +class CV_EXPORTS_W HomographyBasedEstimator : public Estimator +{ +public: + CV_WRAP HomographyBasedEstimator(bool is_focals_estimated = false) + : is_focals_estimated_(is_focals_estimated) {} + +private: + virtual bool estimate(const std::vector &features, + const std::vector &pairwise_matches, + std::vector &cameras) CV_OVERRIDE; + + bool is_focals_estimated_; +}; + +/** @brief Affine transformation based estimator. + +This estimator uses pairwise transformations estimated by matcher to estimate +final transformation for each camera. + +@sa cv::detail::HomographyBasedEstimator + */ +class CV_EXPORTS_W AffineBasedEstimator : public Estimator +{ +public: + CV_WRAP AffineBasedEstimator(){} +private: + virtual bool estimate(const std::vector &features, + const std::vector &pairwise_matches, + std::vector &cameras) CV_OVERRIDE; +}; + +/** @brief Base class for all camera parameters refinement methods. + */ +class CV_EXPORTS_W BundleAdjusterBase : public Estimator +{ +public: + CV_WRAP const Mat refinementMask() const { return refinement_mask_.clone(); } + CV_WRAP void setRefinementMask(const Mat &mask) + { + CV_Assert(mask.type() == CV_8U && mask.size() == Size(3, 3)); + refinement_mask_ = mask.clone(); + } + + CV_WRAP double confThresh() const { return conf_thresh_; } + CV_WRAP void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; } + + CV_WRAP TermCriteria termCriteria() { return term_criteria_; } + CV_WRAP void setTermCriteria(const TermCriteria& term_criteria) { term_criteria_ = term_criteria; } + +protected: + /** @brief Construct a bundle adjuster base instance. + + @param num_params_per_cam Number of parameters per camera + @param num_errs_per_measurement Number of error terms (components) per match + */ + BundleAdjusterBase(int num_params_per_cam, int num_errs_per_measurement) + : num_images_(0), total_num_matches_(0), + num_params_per_cam_(num_params_per_cam), + num_errs_per_measurement_(num_errs_per_measurement), + features_(0), pairwise_matches_(0), conf_thresh_(0) + { + setRefinementMask(Mat::ones(3, 3, CV_8U)); + setConfThresh(1.); + setTermCriteria(TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 1000, DBL_EPSILON)); + } + + // Runs bundle adjustment + virtual bool estimate(const std::vector &features, + const std::vector &pairwise_matches, + std::vector &cameras) CV_OVERRIDE; + + /** @brief Sets initial camera parameter to refine. + + @param cameras Camera parameters + */ + virtual void setUpInitialCameraParams(const std::vector &cameras) = 0; + /** @brief Gets the refined camera parameters. + + @param cameras Refined camera parameters + */ + virtual void obtainRefinedCameraParams(std::vector &cameras) const = 0; + /** @brief Calculates error vector. + + @param err Error column-vector of length total_num_matches \* num_errs_per_measurement + */ + virtual void calcError(Mat &err) = 0; + /** @brief Calculates the cost function jacobian. + + @param jac Jacobian matrix of dimensions + (total_num_matches \* num_errs_per_measurement) x (num_images \* num_params_per_cam) + */ + virtual void calcJacobian(Mat &jac) = 0; + + // 3x3 8U mask, where 0 means don't refine respective parameter, != 0 means refine + Mat refinement_mask_; + + int num_images_; + int total_num_matches_; + + int num_params_per_cam_; + int num_errs_per_measurement_; + + const ImageFeatures *features_; + const MatchesInfo *pairwise_matches_; + + // Threshold to filter out poorly matched image pairs + double conf_thresh_; + + //Levenberg-Marquardt algorithm termination criteria + TermCriteria term_criteria_; + + // Camera parameters matrix (CV_64F) + Mat cam_params_; + + // Connected images pairs + std::vector > edges_; +}; + + +/** @brief Stub bundle adjuster that does nothing. + */ +class CV_EXPORTS_W NoBundleAdjuster : public BundleAdjusterBase +{ +public: + CV_WRAP NoBundleAdjuster() : BundleAdjusterBase(0, 0) {} + +private: + bool estimate(const std::vector &, const std::vector &, + std::vector &) CV_OVERRIDE + { + return true; + } + void setUpInitialCameraParams(const std::vector &) CV_OVERRIDE {} + void obtainRefinedCameraParams(std::vector &) const CV_OVERRIDE {} + void calcError(Mat &) CV_OVERRIDE {} + void calcJacobian(Mat &) CV_OVERRIDE {} +}; + + +/** @brief Implementation of the camera parameters refinement algorithm which minimizes sum of the reprojection +error squares + +It can estimate focal length, aspect ratio, principal point. +You can affect only on them via the refinement mask. + */ +class CV_EXPORTS_W BundleAdjusterReproj : public BundleAdjusterBase +{ +public: + CV_WRAP BundleAdjusterReproj() : BundleAdjusterBase(7, 2) {} + +private: + void setUpInitialCameraParams(const std::vector &cameras) CV_OVERRIDE; + void obtainRefinedCameraParams(std::vector &cameras) const CV_OVERRIDE; + void calcError(Mat &err) CV_OVERRIDE; + void calcJacobian(Mat &jac) CV_OVERRIDE; + + Mat err1_, err2_; +}; + + +/** @brief Implementation of the camera parameters refinement algorithm which minimizes sum of the distances +between the rays passing through the camera center and a feature. : + +It can estimate focal length. It ignores the refinement mask for now. + */ +class CV_EXPORTS_W BundleAdjusterRay : public BundleAdjusterBase +{ +public: + CV_WRAP BundleAdjusterRay() : BundleAdjusterBase(4, 3) {} + +private: + void setUpInitialCameraParams(const std::vector &cameras) CV_OVERRIDE; + void obtainRefinedCameraParams(std::vector &cameras) const CV_OVERRIDE; + void calcError(Mat &err) CV_OVERRIDE; + void calcJacobian(Mat &jac) CV_OVERRIDE; + + Mat err1_, err2_; +}; + + +/** @brief Bundle adjuster that expects affine transformation +represented in homogeneous coordinates in R for each camera param. Implements +camera parameters refinement algorithm which minimizes sum of the reprojection +error squares + +It estimates all transformation parameters. Refinement mask is ignored. + +@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffinePartial + */ +class CV_EXPORTS_W BundleAdjusterAffine : public BundleAdjusterBase +{ +public: + CV_WRAP BundleAdjusterAffine() : BundleAdjusterBase(6, 2) {} + +private: + void setUpInitialCameraParams(const std::vector &cameras) CV_OVERRIDE; + void obtainRefinedCameraParams(std::vector &cameras) const CV_OVERRIDE; + void calcError(Mat &err) CV_OVERRIDE; + void calcJacobian(Mat &jac) CV_OVERRIDE; + + Mat err1_, err2_; +}; + + +/** @brief Bundle adjuster that expects affine transformation with 4 DOF +represented in homogeneous coordinates in R for each camera param. Implements +camera parameters refinement algorithm which minimizes sum of the reprojection +error squares + +It estimates all transformation parameters. Refinement mask is ignored. + +@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffine + */ +class CV_EXPORTS_W BundleAdjusterAffinePartial : public BundleAdjusterBase +{ +public: + CV_WRAP BundleAdjusterAffinePartial() : BundleAdjusterBase(4, 2) {} + +private: + void setUpInitialCameraParams(const std::vector &cameras) CV_OVERRIDE; + void obtainRefinedCameraParams(std::vector &cameras) const CV_OVERRIDE; + void calcError(Mat &err) CV_OVERRIDE; + void calcJacobian(Mat &jac) CV_OVERRIDE; + + Mat err1_, err2_; +}; + + +enum WaveCorrectKind +{ + WAVE_CORRECT_HORIZ, + WAVE_CORRECT_VERT +}; + +/** @brief Tries to make panorama more horizontal (or vertical). + +@param rmats Camera rotation matrices. +@param kind Correction kind, see detail::WaveCorrectKind. + */ +void CV_EXPORTS_W waveCorrect(CV_IN_OUT std::vector &rmats, WaveCorrectKind kind); + + +////////////////////////////////////////////////////////////////////////////// +// Auxiliary functions + +// Returns matches graph representation in DOT language +String CV_EXPORTS_W matchesGraphAsString(std::vector &pathes, std::vector &pairwise_matches, + float conf_threshold); + +CV_EXPORTS_W std::vector leaveBiggestComponent( + std::vector &features, + std::vector &pairwise_matches, + float conf_threshold); + +void CV_EXPORTS findMaxSpanningTree( + int num_images, const std::vector &pairwise_matches, + Graph &span_tree, std::vector ¢ers); + +//! @} stitching_rotation + +} // namespace detail +} // namespace cv + +#endif // OPENCV_STITCHING_MOTION_ESTIMATORS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/seam_finders.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/seam_finders.hpp new file mode 100755 index 0000000..71dae7f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/seam_finders.hpp @@ -0,0 +1,291 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_SEAM_FINDERS_HPP +#define OPENCV_STITCHING_SEAM_FINDERS_HPP + +#include +#include "opencv2/core.hpp" +#include "opencv2/opencv_modules.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching_seam +//! @{ + +/** @brief Base class for a seam estimator. + */ +class CV_EXPORTS_W SeamFinder +{ +public: + CV_WRAP virtual ~SeamFinder() {} + enum { NO, VORONOI_SEAM, DP_SEAM }; + /** @brief Estimates seams. + + @param src Source images + @param corners Source image top-left corners + @param masks Source image masks to update + */ + CV_WRAP virtual void find(const std::vector &src, const std::vector &corners, + CV_IN_OUT std::vector &masks) = 0; + CV_WRAP static Ptr createDefault(int type); +}; + +/** @brief Stub seam estimator which does nothing. + */ +class CV_EXPORTS_W NoSeamFinder : public SeamFinder +{ +public: + CV_WRAP void find(const std::vector&, const std::vector&, CV_IN_OUT std::vector&) CV_OVERRIDE {} +}; + +/** @brief Base class for all pairwise seam estimators. + */ +class CV_EXPORTS_W PairwiseSeamFinder : public SeamFinder +{ +public: + CV_WRAP virtual void find(const std::vector &src, const std::vector &corners, + CV_IN_OUT std::vector &masks) CV_OVERRIDE; + +protected: + void run(); + /** @brief Resolves masks intersection of two specified images in the given ROI. + + @param first First image index + @param second Second image index + @param roi Region of interest + */ + virtual void findInPair(size_t first, size_t second, Rect roi) = 0; + + std::vector images_; + std::vector sizes_; + std::vector corners_; + std::vector masks_; +}; + +/** @brief Voronoi diagram-based seam estimator. + */ +class CV_EXPORTS_W VoronoiSeamFinder : public PairwiseSeamFinder +{ +public: + CV_WRAP virtual void find(const std::vector &src, const std::vector &corners, + CV_IN_OUT std::vector &masks) CV_OVERRIDE; + virtual void find(const std::vector &size, const std::vector &corners, + std::vector &masks); +private: + void findInPair(size_t first, size_t second, Rect roi) CV_OVERRIDE; +}; + + +class CV_EXPORTS_W DpSeamFinder : public SeamFinder +{ +public: + enum CostFunction { COLOR, COLOR_GRAD }; + + DpSeamFinder(CostFunction costFunc = COLOR); + CV_WRAP DpSeamFinder(String costFunc ); + + CostFunction costFunction() const { return costFunc_; } + void setCostFunction(CostFunction val) { costFunc_ = val; } + CV_WRAP void setCostFunction(String val); + + virtual void find(const std::vector &src, const std::vector &corners, + std::vector &masks) CV_OVERRIDE; + +private: + enum ComponentState + { + FIRST = 1, SECOND = 2, INTERS = 4, + INTERS_FIRST = INTERS | FIRST, + INTERS_SECOND = INTERS | SECOND + }; + + class ImagePairLess + { + public: + ImagePairLess(const std::vector &images, const std::vector &corners) + : src_(&images[0]), corners_(&corners[0]) {} + + bool operator() (const std::pair &l, const std::pair &r) const + { + Point c1 = corners_[l.first] + Point(src_[l.first].cols / 2, src_[l.first].rows / 2); + Point c2 = corners_[l.second] + Point(src_[l.second].cols / 2, src_[l.second].rows / 2); + int d1 = (c1 - c2).dot(c1 - c2); + + c1 = corners_[r.first] + Point(src_[r.first].cols / 2, src_[r.first].rows / 2); + c2 = corners_[r.second] + Point(src_[r.second].cols / 2, src_[r.second].rows / 2); + int d2 = (c1 - c2).dot(c1 - c2); + + return d1 < d2; + } + + private: + const Mat *src_; + const Point *corners_; + }; + + class ClosePoints + { + public: + ClosePoints(int minDist) : minDist_(minDist) {} + + bool operator() (const Point &p1, const Point &p2) const + { + int dist2 = (p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y); + return dist2 < minDist_ * minDist_; + } + + private: + int minDist_; + }; + + void process( + const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2); + + void findComponents(); + + void findEdges(); + + void resolveConflicts( + const Mat &image1, const Mat &image2, Point tl1, Point tl2, Mat &mask1, Mat &mask2); + + void computeGradients(const Mat &image1, const Mat &image2); + + bool hasOnlyOneNeighbor(int comp); + + bool closeToContour(int y, int x, const Mat_ &contourMask); + + bool getSeamTips(int comp1, int comp2, Point &p1, Point &p2); + + void computeCosts( + const Mat &image1, const Mat &image2, Point tl1, Point tl2, + int comp, Mat_ &costV, Mat_ &costH); + + bool estimateSeam( + const Mat &image1, const Mat &image2, Point tl1, Point tl2, int comp, + Point p1, Point p2, std::vector &seam, bool &isHorizontal); + + void updateLabelsUsingSeam( + int comp1, int comp2, const std::vector &seam, bool isHorizontalSeam); + + CostFunction costFunc_; + + // processing images pair data + Point unionTl_, unionBr_; + Size unionSize_; + Mat_ mask1_, mask2_; + Mat_ contour1mask_, contour2mask_; + Mat_ gradx1_, grady1_; + Mat_ gradx2_, grady2_; + + // components data + int ncomps_; + Mat_ labels_; + std::vector states_; + std::vector tls_, brs_; + std::vector > contours_; + std::set > edges_; +}; + +/** @brief Base class for all minimum graph-cut-based seam estimators. + */ +class CV_EXPORTS GraphCutSeamFinderBase +{ +public: + enum CostType { COST_COLOR, COST_COLOR_GRAD }; +}; + +/** @brief Minimum graph cut-based seam estimator. See details in @cite V03 . + */ +class CV_EXPORTS_W GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder +{ +public: + GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f, + float bad_region_penalty = 1000.f); + CV_WRAP GraphCutSeamFinder(String cost_type,float terminal_cost = 10000.f, + float bad_region_penalty = 1000.f); + + ~GraphCutSeamFinder(); + + CV_WRAP void find(const std::vector &src, const std::vector &corners, + std::vector &masks) CV_OVERRIDE; + +private: + // To avoid GCGraph dependency + class Impl; + Ptr impl_; +}; + + +#ifdef HAVE_OPENCV_CUDALEGACY +class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder +{ +public: + GraphCutSeamFinderGpu(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f, + float bad_region_penalty = 1000.f) + : cost_type_(cost_type), terminal_cost_(terminal_cost), + bad_region_penalty_(bad_region_penalty) {} + + void find(const std::vector &src, const std::vector &corners, + std::vector &masks) CV_OVERRIDE; + void findInPair(size_t first, size_t second, Rect roi) CV_OVERRIDE; + +private: + void setGraphWeightsColor(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &mask1, const cv::Mat &mask2, + cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom); + void setGraphWeightsColorGrad(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &dx1, const cv::Mat &dx2, + const cv::Mat &dy1, const cv::Mat &dy2, const cv::Mat &mask1, const cv::Mat &mask2, + cv::Mat &terminals, cv::Mat &leftT, cv::Mat &rightT, cv::Mat &top, cv::Mat &bottom); + std::vector dx_, dy_; + int cost_type_; + float terminal_cost_; + float bad_region_penalty_; +}; +#endif + +//! @} + +} // namespace detail +} // namespace cv + +#endif // OPENCV_STITCHING_SEAM_FINDERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/timelapsers.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/timelapsers.hpp new file mode 100755 index 0000000..f6f3da8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/timelapsers.hpp @@ -0,0 +1,91 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + + +#ifndef OPENCV_STITCHING_TIMELAPSERS_HPP +#define OPENCV_STITCHING_TIMELAPSERS_HPP + +#include "opencv2/core.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching +//! @{ + +// Base Timelapser class, takes a sequence of images, applies appropriate shift, stores result in dst_. + +class CV_EXPORTS_W Timelapser +{ +public: + + enum {AS_IS, CROP}; + + virtual ~Timelapser() {} + + CV_WRAP static Ptr createDefault(int type); + + CV_WRAP virtual void initialize(const std::vector &corners, const std::vector &sizes); + CV_WRAP virtual void process(InputArray img, InputArray mask, Point tl); + CV_WRAP virtual const UMat& getDst() {return dst_;} + +protected: + + virtual bool test_point(Point pt); + + UMat dst_; + Rect dst_roi_; +}; + + +class CV_EXPORTS_W TimelapserCrop : public Timelapser +{ +public: + virtual void initialize(const std::vector &corners, const std::vector &sizes) CV_OVERRIDE; +}; + +//! @} + +} // namespace detail +} // namespace cv + +#endif // OPENCV_STITCHING_TIMELAPSERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util.hpp new file mode 100755 index 0000000..bf7a390 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util.hpp @@ -0,0 +1,121 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_UTIL_HPP +#define OPENCV_STITCHING_UTIL_HPP + +#include +#include "opencv2/core.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching +//! @{ + +class CV_EXPORTS DisjointSets +{ +public: + DisjointSets(int elem_count = 0) { createOneElemSets(elem_count); } + + void createOneElemSets(int elem_count); + int findSetByElem(int elem); + int mergeSets(int set1, int set2); + + std::vector parent; + std::vector size; + +private: + std::vector rank_; +}; + + +struct CV_EXPORTS GraphEdge +{ + GraphEdge(int from, int to, float weight); + bool operator <(const GraphEdge& other) const { return weight < other.weight; } + bool operator >(const GraphEdge& other) const { return weight > other.weight; } + + int from, to; + float weight; +}; + +inline GraphEdge::GraphEdge(int _from, int _to, float _weight) : from(_from), to(_to), weight(_weight) {} + + +class CV_EXPORTS Graph +{ +public: + Graph(int num_vertices = 0) { create(num_vertices); } + void create(int num_vertices) { edges_.assign(num_vertices, std::list()); } + int numVertices() const { return static_cast(edges_.size()); } + void addEdge(int from, int to, float weight); + template B forEach(B body) const; + template B walkBreadthFirst(int from, B body) const; + +private: + std::vector< std::list > edges_; +}; + + +////////////////////////////////////////////////////////////////////////////// +// Auxiliary functions + +CV_EXPORTS_W bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi); +CV_EXPORTS_W Rect resultRoi(const std::vector &corners, const std::vector &images); +CV_EXPORTS_W Rect resultRoi(const std::vector &corners, const std::vector &sizes); +CV_EXPORTS_W Rect resultRoiIntersection(const std::vector &corners, const std::vector &sizes); +CV_EXPORTS_W Point resultTl(const std::vector &corners); + +// Returns random 'count' element subset of the {0,1,...,size-1} set +CV_EXPORTS_W void selectRandomSubset(int count, int size, std::vector &subset); + +CV_EXPORTS_W int& stitchingLogLevel(); + +//! @} + +} // namespace detail +} // namespace cv + +#include "util_inl.hpp" + +#endif // OPENCV_STITCHING_UTIL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util_inl.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util_inl.hpp new file mode 100755 index 0000000..dafab8b --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/util_inl.hpp @@ -0,0 +1,131 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_UTIL_INL_HPP +#define OPENCV_STITCHING_UTIL_INL_HPP + +#include +#include "opencv2/core.hpp" +#include "util.hpp" // Make your IDE see declarations + +//! @cond IGNORED + +namespace cv { +namespace detail { + +template +B Graph::forEach(B body) const +{ + for (int i = 0; i < numVertices(); ++i) + { + std::list::const_iterator edge = edges_[i].begin(); + for (; edge != edges_[i].end(); ++edge) + body(*edge); + } + return body; +} + + +template +B Graph::walkBreadthFirst(int from, B body) const +{ + std::vector was(numVertices(), false); + std::queue vertices; + + was[from] = true; + vertices.push(from); + + while (!vertices.empty()) + { + int vertex = vertices.front(); + vertices.pop(); + + std::list::const_iterator edge = edges_[vertex].begin(); + for (; edge != edges_[vertex].end(); ++edge) + { + if (!was[edge->to]) + { + body(*edge); + was[edge->to] = true; + vertices.push(edge->to); + } + } + } + + return body; +} + + +////////////////////////////////////////////////////////////////////////////// +// Some auxiliary math functions + +static inline +float normL2(const Point3f& a) +{ + return a.x * a.x + a.y * a.y + a.z * a.z; +} + + +static inline +float normL2(const Point3f& a, const Point3f& b) +{ + return normL2(a - b); +} + + +static inline +double normL2sq(const Mat &r) +{ + return r.dot(r); +} + + +static inline int sqr(int x) { return x * x; } +static inline float sqr(float x) { return x * x; } +static inline double sqr(double x) { return x * x; } + +} // namespace detail +} // namespace cv + +//! @endcond + +#endif // OPENCV_STITCHING_UTIL_INL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers.hpp new file mode 100755 index 0000000..47d1701 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers.hpp @@ -0,0 +1,616 @@ + /*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_WARPERS_HPP +#define OPENCV_STITCHING_WARPERS_HPP + +#include "opencv2/core.hpp" +#include "opencv2/core/cuda.hpp" +#include "opencv2/imgproc.hpp" +#include "opencv2/opencv_modules.hpp" + +namespace cv { +namespace detail { + +//! @addtogroup stitching_warp +//! @{ + +/** @brief Rotation-only model image warper interface. + */ +class CV_EXPORTS RotationWarper +{ +public: + virtual ~RotationWarper() {} + + /** @brief Projects the image point. + + @param pt Source point + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @return Projected point + */ + virtual Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) = 0; + + /** @brief Builds the projection maps according to the given camera data. + + @param src_size Source image size + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @param xmap Projection map for the x axis + @param ymap Projection map for the y axis + @return Projected image minimum bounding box + */ + virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) = 0; + + /** @brief Projects the image. + + @param src Source image + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @param interp_mode Interpolation mode + @param border_mode Border extrapolation mode + @param dst Projected image + @return Project image top-left corner + */ + virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + CV_OUT OutputArray dst) = 0; + + /** @brief Projects the image backward. + + @param src Projected image + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @param interp_mode Interpolation mode + @param border_mode Border extrapolation mode + @param dst_size Backward-projected image size + @param dst Backward-projected image + */ + virtual void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + Size dst_size, CV_OUT OutputArray dst) = 0; + + /** + @param src_size Source image bounding box + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @return Projected image minimum bounding box + */ + virtual Rect warpRoi(Size src_size, InputArray K, InputArray R) = 0; + + virtual float getScale() const { return 1.f; } + virtual void setScale(float) {} +}; + +/** @brief Base class for warping logic implementation. + */ +struct CV_EXPORTS_W_SIMPLE ProjectorBase +{ + void setCameraParams(InputArray K = Mat::eye(3, 3, CV_32F), + InputArray R = Mat::eye(3, 3, CV_32F), + InputArray T = Mat::zeros(3, 1, CV_32F)); + + float scale; + float k[9]; + float rinv[9]; + float r_kinv[9]; + float k_rinv[9]; + float t[3]; +}; + +/** @brief Base class for rotation-based warper using a detail::ProjectorBase_ derived class. + */ +template +class CV_EXPORTS_TEMPLATE RotationWarperBase : public RotationWarper +{ +public: + Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE; + + Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE; + + Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + OutputArray dst) CV_OVERRIDE; + + void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + Size dst_size, OutputArray dst) CV_OVERRIDE; + + Rect warpRoi(Size src_size, InputArray K, InputArray R) CV_OVERRIDE; + + float getScale() const CV_OVERRIDE{ return projector_.scale; } + void setScale(float val) CV_OVERRIDE { projector_.scale = val; } + +protected: + + // Detects ROI of the destination image. It's correct for any projection. + virtual void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br); + + // Detects ROI of the destination image by walking over image border. + // Correctness for any projection isn't guaranteed. + void detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br); + + P projector_; +}; + + +struct CV_EXPORTS PlaneProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + +/** @brief Warper that maps an image onto the z = 1 plane. + */ +class CV_EXPORTS PlaneWarper : public RotationWarperBase +{ +public: + /** @brief Construct an instance of the plane warper class. + + @param scale Projected image scale multiplier + */ + PlaneWarper(float scale = 1.f) { projector_.scale = scale; } + + Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE; + Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T); + + virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap); + Rect buildMaps(Size src_size, InputArray K, InputArray R, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap) CV_OVERRIDE; + + Point warp(InputArray src, InputArray K, InputArray R, + int interp_mode, int border_mode, CV_OUT OutputArray dst) CV_OVERRIDE; + virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, + CV_OUT OutputArray dst); + + Rect warpRoi(Size src_size, InputArray K, InputArray R) CV_OVERRIDE; + Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T); + +protected: + void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE; +}; + + +/** @brief Affine warper that uses rotations and translations + + Uses affine transformation in homogeneous coordinates to represent both rotation and + translation in camera rotation matrix. + */ +class CV_EXPORTS AffineWarper : public PlaneWarper +{ +public: + /** @brief Construct an instance of the affine warper class. + + @param scale Projected image scale multiplier + */ + AffineWarper(float scale = 1.f) : PlaneWarper(scale) {} + + Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE; + Rect buildMaps(Size src_size, InputArray K, InputArray R, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap) CV_OVERRIDE; + Point warp(InputArray src, InputArray K, InputArray R, + int interp_mode, int border_mode, CV_OUT OutputArray dst) CV_OVERRIDE; + Rect warpRoi(Size src_size, InputArray K, InputArray R) CV_OVERRIDE; + +protected: + /** @brief Extracts rotation and translation matrices from matrix H representing + affine transformation in homogeneous coordinates + */ + void getRTfromHomogeneous(InputArray H, Mat &R, Mat &T); +}; + + +struct CV_EXPORTS_W_SIMPLE SphericalProjector : ProjectorBase +{ + CV_WRAP void mapForward(float x, float y, float &u, float &v); + CV_WRAP void mapBackward(float u, float v, float &x, float &y); +}; + + +/** @brief Warper that maps an image onto the unit sphere located at the origin. + + Projects image onto unit sphere with origin at (0, 0, 0) and radius scale, measured in pixels. + A 360 panorama would therefore have a resulting width of 2 * scale * PI pixels. + Poles are located at (0, -1, 0) and (0, 1, 0) points. +*/ +class CV_EXPORTS SphericalWarper : public RotationWarperBase +{ +public: + /** @brief Construct an instance of the spherical warper class. + + @param scale Radius of the projected sphere, in pixels. An image spanning the + whole sphere will have a width of 2 * scale * PI pixels. + */ + SphericalWarper(float scale) { projector_.scale = scale; } + + Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE; + Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst) CV_OVERRIDE; +protected: + void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE; +}; + + +struct CV_EXPORTS CylindricalProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +/** @brief Warper that maps an image onto the x\*x + z\*z = 1 cylinder. + */ +class CV_EXPORTS CylindricalWarper : public RotationWarperBase +{ +public: + /** @brief Construct an instance of the cylindrical warper class. + + @param scale Projected image scale multiplier + */ + CylindricalWarper(float scale) { projector_.scale = scale; } + + Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE; + Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst) CV_OVERRIDE; +protected: + void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE + { + RotationWarperBase::detectResultRoiByBorder(src_size, dst_tl, dst_br); + } +}; + + +struct CV_EXPORTS FisheyeProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS FisheyeWarper : public RotationWarperBase +{ +public: + FisheyeWarper(float scale) { projector_.scale = scale; } +}; + + +struct CV_EXPORTS StereographicProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS StereographicWarper : public RotationWarperBase +{ +public: + StereographicWarper(float scale) { projector_.scale = scale; } +}; + + +struct CV_EXPORTS CompressedRectilinearProjector : ProjectorBase +{ + float a, b; + + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS CompressedRectilinearWarper : public RotationWarperBase +{ +public: + CompressedRectilinearWarper(float scale, float A = 1, float B = 1) + { + projector_.a = A; + projector_.b = B; + projector_.scale = scale; + } +}; + + +struct CV_EXPORTS CompressedRectilinearPortraitProjector : ProjectorBase +{ + float a, b; + + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS CompressedRectilinearPortraitWarper : public RotationWarperBase +{ +public: + CompressedRectilinearPortraitWarper(float scale, float A = 1, float B = 1) + { + projector_.a = A; + projector_.b = B; + projector_.scale = scale; + } +}; + + +struct CV_EXPORTS PaniniProjector : ProjectorBase +{ + float a, b; + + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS PaniniWarper : public RotationWarperBase +{ +public: + PaniniWarper(float scale, float A = 1, float B = 1) + { + projector_.a = A; + projector_.b = B; + projector_.scale = scale; + } +}; + + +struct CV_EXPORTS PaniniPortraitProjector : ProjectorBase +{ + float a, b; + + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS PaniniPortraitWarper : public RotationWarperBase +{ +public: + PaniniPortraitWarper(float scale, float A = 1, float B = 1) + { + projector_.a = A; + projector_.b = B; + projector_.scale = scale; + } + +}; + + +struct CV_EXPORTS MercatorProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS MercatorWarper : public RotationWarperBase +{ +public: + MercatorWarper(float scale) { projector_.scale = scale; } +}; + + +struct CV_EXPORTS TransverseMercatorProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS TransverseMercatorWarper : public RotationWarperBase +{ +public: + TransverseMercatorWarper(float scale) { projector_.scale = scale; } +}; + + +class CV_EXPORTS PlaneWarperGpu : public PlaneWarper +{ +public: + PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {} + + Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE + { + Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_); + d_xmap_.download(xmap); + d_ymap_.download(ymap); + return result; + } + + Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap) CV_OVERRIDE + { + Rect result = buildMaps(src_size, K, R, T, d_xmap_, d_ymap_); + d_xmap_.download(xmap); + d_ymap_.download(ymap); + return result; + } + + Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + OutputArray dst) CV_OVERRIDE + { + d_src_.upload(src); + Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_); + d_dst_.download(dst); + return result; + } + + Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, + OutputArray dst) CV_OVERRIDE + { + d_src_.upload(src); + Point result = warp(d_src_, K, R, T, interp_mode, border_mode, d_dst_); + d_dst_.download(dst); + return result; + } + + Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap); + + Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, cuda::GpuMat & xmap, cuda::GpuMat & ymap); + + Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode, + cuda::GpuMat & dst); + + Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, + cuda::GpuMat & dst); + +private: + cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_; +}; + + +class CV_EXPORTS SphericalWarperGpu : public SphericalWarper +{ +public: + SphericalWarperGpu(float scale) : SphericalWarper(scale) {} + + Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE + { + Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_); + d_xmap_.download(xmap); + d_ymap_.download(ymap); + return result; + } + + Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + OutputArray dst) CV_OVERRIDE + { + d_src_.upload(src); + Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_); + d_dst_.download(dst); + return result; + } + + Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap); + + Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode, + cuda::GpuMat & dst); + +private: + cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_; +}; + + +class CV_EXPORTS CylindricalWarperGpu : public CylindricalWarper +{ +public: + CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {} + + Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE + { + Rect result = buildMaps(src_size, K, R, d_xmap_, d_ymap_); + d_xmap_.download(xmap); + d_ymap_.download(ymap); + return result; + } + + Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + OutputArray dst) CV_OVERRIDE + { + d_src_.upload(src); + Point result = warp(d_src_, K, R, interp_mode, border_mode, d_dst_); + d_dst_.download(dst); + return result; + } + + Rect buildMaps(Size src_size, InputArray K, InputArray R, cuda::GpuMat & xmap, cuda::GpuMat & ymap); + + Point warp(const cuda::GpuMat & src, InputArray K, InputArray R, int interp_mode, int border_mode, + cuda::GpuMat & dst); + +private: + cuda::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_; +}; + + +struct CV_EXPORTS SphericalPortraitProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +// Projects image onto unit sphere with origin at (0, 0, 0). +// Poles are located NOT at (0, -1, 0) and (0, 1, 0) points, BUT at (1, 0, 0) and (-1, 0, 0) points. +class CV_EXPORTS SphericalPortraitWarper : public RotationWarperBase +{ +public: + SphericalPortraitWarper(float scale) { projector_.scale = scale; } + +protected: + void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE; +}; + +struct CV_EXPORTS CylindricalPortraitProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS CylindricalPortraitWarper : public RotationWarperBase +{ +public: + CylindricalPortraitWarper(float scale) { projector_.scale = scale; } + +protected: + void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE + { + RotationWarperBase::detectResultRoiByBorder(src_size, dst_tl, dst_br); + } +}; + +struct CV_EXPORTS PlanePortraitProjector : ProjectorBase +{ + void mapForward(float x, float y, float &u, float &v); + void mapBackward(float u, float v, float &x, float &y); +}; + + +class CV_EXPORTS PlanePortraitWarper : public RotationWarperBase +{ +public: + PlanePortraitWarper(float scale) { projector_.scale = scale; } + +protected: + void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) CV_OVERRIDE + { + RotationWarperBase::detectResultRoiByBorder(src_size, dst_tl, dst_br); + } +}; + +//! @} stitching_warp + +} // namespace detail +} // namespace cv + +#include "warpers_inl.hpp" + +#endif // OPENCV_STITCHING_WARPERS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers_inl.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers_inl.hpp new file mode 100755 index 0000000..f4a19d9 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/detail/warpers_inl.hpp @@ -0,0 +1,774 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_WARPERS_INL_HPP +#define OPENCV_STITCHING_WARPERS_INL_HPP + +#include "opencv2/core.hpp" +#include "warpers.hpp" // Make your IDE see declarations +#include + +//! @cond IGNORED + +namespace cv { +namespace detail { + +template +Point2f RotationWarperBase

    ::warpPoint(const Point2f &pt, InputArray K, InputArray R) +{ + projector_.setCameraParams(K, R); + Point2f uv; + projector_.mapForward(pt.x, pt.y, uv.x, uv.y); + return uv; +} + + +template +Rect RotationWarperBase

    ::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap) +{ + projector_.setCameraParams(K, R); + + Point dst_tl, dst_br; + detectResultRoi(src_size, dst_tl, dst_br); + + _xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F); + _ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F); + + Mat xmap = _xmap.getMat(), ymap = _ymap.getMat(); + + float x, y; + for (int v = dst_tl.y; v <= dst_br.y; ++v) + { + for (int u = dst_tl.x; u <= dst_br.x; ++u) + { + projector_.mapBackward(static_cast(u), static_cast(v), x, y); + xmap.at(v - dst_tl.y, u - dst_tl.x) = x; + ymap.at(v - dst_tl.y, u - dst_tl.x) = y; + } + } + + return Rect(dst_tl, dst_br); +} + + +template +Point RotationWarperBase

    ::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + OutputArray dst) +{ + UMat xmap, ymap; + Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap); + + dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type()); + remap(src, dst, xmap, ymap, interp_mode, border_mode); + + return dst_roi.tl(); +} + + +template +void RotationWarperBase

    ::warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + Size dst_size, OutputArray dst) +{ + projector_.setCameraParams(K, R); + + Point src_tl, src_br; + detectResultRoi(dst_size, src_tl, src_br); + + Size size = src.size(); + CV_Assert(src_br.x - src_tl.x + 1 == size.width && src_br.y - src_tl.y + 1 == size.height); + + Mat xmap(dst_size, CV_32F); + Mat ymap(dst_size, CV_32F); + + float u, v; + for (int y = 0; y < dst_size.height; ++y) + { + for (int x = 0; x < dst_size.width; ++x) + { + projector_.mapForward(static_cast(x), static_cast(y), u, v); + xmap.at(y, x) = u - src_tl.x; + ymap.at(y, x) = v - src_tl.y; + } + } + + dst.create(dst_size, src.type()); + remap(src, dst, xmap, ymap, interp_mode, border_mode); +} + + +template +Rect RotationWarperBase

    ::warpRoi(Size src_size, InputArray K, InputArray R) +{ + projector_.setCameraParams(K, R); + + Point dst_tl, dst_br; + detectResultRoi(src_size, dst_tl, dst_br); + + return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1)); +} + + +template +void RotationWarperBase

    ::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) +{ + float tl_uf = (std::numeric_limits::max)(); + float tl_vf = (std::numeric_limits::max)(); + float br_uf = -(std::numeric_limits::max)(); + float br_vf = -(std::numeric_limits::max)(); + + float u, v; + for (int y = 0; y < src_size.height; ++y) + { + for (int x = 0; x < src_size.width; ++x) + { + projector_.mapForward(static_cast(x), static_cast(y), u, v); + tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v); + br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v); + } + } + + dst_tl.x = static_cast(tl_uf); + dst_tl.y = static_cast(tl_vf); + dst_br.x = static_cast(br_uf); + dst_br.y = static_cast(br_vf); +} + + +template +void RotationWarperBase

    ::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br) +{ + float tl_uf = (std::numeric_limits::max)(); + float tl_vf = (std::numeric_limits::max)(); + float br_uf = -(std::numeric_limits::max)(); + float br_vf = -(std::numeric_limits::max)(); + + float u, v; + for (float x = 0; x < src_size.width; ++x) + { + projector_.mapForward(static_cast(x), 0, u, v); + tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v); + br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v); + + projector_.mapForward(static_cast(x), static_cast(src_size.height - 1), u, v); + tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v); + br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v); + } + for (int y = 0; y < src_size.height; ++y) + { + projector_.mapForward(0, static_cast(y), u, v); + tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v); + br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v); + + projector_.mapForward(static_cast(src_size.width - 1), static_cast(y), u, v); + tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v); + br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v); + } + + dst_tl.x = static_cast(tl_uf); + dst_tl.y = static_cast(tl_vf); + dst_br.x = static_cast(br_uf); + dst_br.y = static_cast(br_vf); +} + + +inline +void PlaneProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + x_ = t[0] + x_ / z_ * (1 - t[2]); + y_ = t[1] + y_ / z_ * (1 - t[2]); + + u = scale * x_; + v = scale * y_; +} + + +inline +void PlaneProjector::mapBackward(float u, float v, float &x, float &y) +{ + u = u / scale - t[0]; + v = v / scale - t[1]; + + float z; + x = k_rinv[0] * u + k_rinv[1] * v + k_rinv[2] * (1 - t[2]); + y = k_rinv[3] * u + k_rinv[4] * v + k_rinv[5] * (1 - t[2]); + z = k_rinv[6] * u + k_rinv[7] * v + k_rinv[8] * (1 - t[2]); + + x /= z; + y /= z; +} + + +inline +void SphericalProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + u = scale * atan2f(x_, z_); + float w = y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_); + v = scale * (static_cast(CV_PI) - acosf(w == w ? w : 0)); +} + + +inline +void SphericalProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float sinv = sinf(static_cast(CV_PI) - v); + float x_ = sinv * sinf(u); + float y_ = cosf(static_cast(CV_PI) - v); + float z_ = sinv * cosf(u); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + + +inline +void CylindricalProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + u = scale * atan2f(x_, z_); + v = scale * y_ / sqrtf(x_ * x_ + z_ * z_); +} + + +inline +void CylindricalProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float x_ = sinf(u); + float y_ = v; + float z_ = cosf(u); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void FisheyeProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + u = scale * v_ * cosf(u_); + v = scale * v_ * sinf(u_); +} + +inline +void FisheyeProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float u_ = atan2f(v, u); + float v_ = sqrtf(u*u + v*v); + + float sinv = sinf((float)CV_PI - v_); + float x_ = sinv * sinf(u_); + float y_ = cosf((float)CV_PI - v_); + float z_ = sinv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void StereographicProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = (float)CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + float r = sinf(v_) / (1 - cosf(v_)); + + u = scale * r * cos(u_); + v = scale * r * sin(u_); +} + +inline +void StereographicProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float u_ = atan2f(v, u); + float r = sqrtf(u*u + v*v); + float v_ = 2 * atanf(1.f / r); + + float sinv = sinf((float)CV_PI - v_); + float x_ = sinv * sinf(u_); + float y_ = cosf((float)CV_PI - v_); + float z_ = sinv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + u = scale * a * tanf(u_ / a); + v = scale * b * tanf(v_) / cosf(u_); +} + +inline +void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float aatg = a * atanf(u / a); + float u_ = aatg; + float v_ = atanf(v * cosf(aatg) / b); + + float cosv = cosf(v_); + float x_ = cosv * sinf(u_); + float y_ = sinf(v_); + float z_ = cosv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v) +{ + float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + u = - scale * a * tanf(u_ / a); + v = scale * b * tanf(v_) / cosf(u_); +} + +inline +void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= - scale; + v /= scale; + + float aatg = a * atanf(u / a); + float u_ = aatg; + float v_ = atanf(v * cosf( aatg ) / b); + + float cosv = cosf(v_); + float y_ = cosv * sinf(u_); + float x_ = sinf(v_); + float z_ = cosv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void PaniniProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + float tg = a * tanf(u_ / a); + u = scale * tg; + + float sinu = sinf(u_); + if ( fabs(sinu) < 1E-7 ) + v = scale * b * tanf(v_); + else + v = scale * b * tg * tanf(v_) / sinu; +} + +inline +void PaniniProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float lamda = a * atanf(u / a); + float u_ = lamda; + + float v_; + if ( fabs(lamda) > 1E-7) + v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a))); + else + v_ = atanf(v / b); + + float cosv = cosf(v_); + float x_ = cosv * sinf(u_); + float y_ = sinf(v_); + float z_ = cosv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v) +{ + float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + float tg = a * tanf(u_ / a); + u = - scale * tg; + + float sinu = sinf( u_ ); + if ( fabs(sinu) < 1E-7 ) + v = scale * b * tanf(v_); + else + v = scale * b * tg * tanf(v_) / sinu; +} + +inline +void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= - scale; + v /= scale; + + float lamda = a * atanf(u / a); + float u_ = lamda; + + float v_; + if ( fabs(lamda) > 1E-7) + v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a))); + else + v_ = atanf(v / b); + + float cosv = cosf(v_); + float y_ = cosv * sinf(u_); + float x_ = sinf(v_); + float z_ = cosv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void MercatorProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + u = scale * u_; + v = scale * logf( tanf( (float)(CV_PI/4) + v_/2 ) ); +} + +inline +void MercatorProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float v_ = atanf( sinhf(v) ); + float u_ = u; + + float cosv = cosf(v_); + float x_ = cosv * sinf(u_); + float y_ = sinf(v_); + float z_ = cosv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v) +{ + float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float u_ = atan2f(x_, z_); + float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_)); + + float B = cosf(v_) * sinf(u_); + + u = scale / 2 * logf( (1+B) / (1-B) ); + v = scale * atan2f(tanf(v_), cosf(u_)); +} + +inline +void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y) +{ + u /= scale; + v /= scale; + + float v_ = asinf( sinf(v) / coshf(u) ); + float u_ = atan2f( sinhf(u), cos(v) ); + + float cosv = cosf(v_); + float x_ = cosv * sinf(u_); + float y_ = sinf(v_); + float z_ = cosv * cosf(u_); + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0) +{ + float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float x_ = y0_; + float y_ = x0_; + float u, v; + + u = scale * atan2f(x_, z_); + v = scale * (static_cast(CV_PI) - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_))); + + u0 = -u;//v; + v0 = v;//u; +} + + +inline +void SphericalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y) +{ + float u, v; + u = -u0;//v0; + v = v0;//u0; + + u /= scale; + v /= scale; + + float sinv = sinf(static_cast(CV_PI) - v); + float x0_ = sinv * sinf(u); + float y0_ = cosf(static_cast(CV_PI) - v); + float z_ = sinv * cosf(u); + + float x_ = y0_; + float y_ = x0_; + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void CylindricalPortraitProjector::mapForward(float x, float y, float &u0, float &v0) +{ + float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float x_ = y0_; + float y_ = x0_; + float u, v; + + u = scale * atan2f(x_, z_); + v = scale * y_ / sqrtf(x_ * x_ + z_ * z_); + + u0 = -u;//v; + v0 = v;//u; +} + + +inline +void CylindricalPortraitProjector::mapBackward(float u0, float v0, float &x, float &y) +{ + float u, v; + u = -u0;//v0; + v = v0;//u0; + + u /= scale; + v /= scale; + + float x0_ = sinf(u); + float y0_ = v; + float z_ = cosf(u); + + float x_ = y0_; + float y_ = x0_; + + float z; + x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_; + y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_; + z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_; + + if (z > 0) { x /= z; y /= z; } + else x = y = -1; +} + +inline +void PlanePortraitProjector::mapForward(float x, float y, float &u0, float &v0) +{ + float x0_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2]; + float y0_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5]; + float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8]; + + float x_ = y0_; + float y_ = x0_; + + x_ = t[0] + x_ / z_ * (1 - t[2]); + y_ = t[1] + y_ / z_ * (1 - t[2]); + + float u,v; + u = scale * x_; + v = scale * y_; + + u0 = -u; + v0 = v; +} + + +inline +void PlanePortraitProjector::mapBackward(float u0, float v0, float &x, float &y) +{ + float u, v; + u = -u0; + v = v0; + + u = u / scale - t[0]; + v = v / scale - t[1]; + + float z; + x = k_rinv[0] * v + k_rinv[1] * u + k_rinv[2] * (1 - t[2]); + y = k_rinv[3] * v + k_rinv[4] * u + k_rinv[5] * (1 - t[2]); + z = k_rinv[6] * v + k_rinv[7] * u + k_rinv[8] * (1 - t[2]); + + x /= z; + y /= z; +} + + +} // namespace detail +} // namespace cv + +//! @endcond + +#endif // OPENCV_STITCHING_WARPERS_INL_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/stitching/warpers.hpp b/Prj-Win/3rd/opencv/include/opencv2/stitching/warpers.hpp new file mode 100755 index 0000000..ff43386 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/stitching/warpers.hpp @@ -0,0 +1,261 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_STITCHING_WARPER_CREATORS_HPP +#define OPENCV_STITCHING_WARPER_CREATORS_HPP + +#include "opencv2/stitching/detail/warpers.hpp" +#include + +namespace cv { + class CV_EXPORTS_W PyRotationWarper + { + Ptr rw; + + public: + CV_WRAP PyRotationWarper(String type, float scale); + CV_WRAP PyRotationWarper() {}; + ~PyRotationWarper() {} + + /** @brief Projects the image point. + + @param pt Source point + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @return Projected point + */ + CV_WRAP Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R); + + /** @brief Builds the projection maps according to the given camera data. + + @param src_size Source image size + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @param xmap Projection map for the x axis + @param ymap Projection map for the y axis + @return Projected image minimum bounding box + */ + CV_WRAP Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); + + /** @brief Projects the image. + + @param src Source image + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @param interp_mode Interpolation mode + @param border_mode Border extrapolation mode + @param dst Projected image + @return Project image top-left corner + */ + CV_WRAP Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + CV_OUT OutputArray dst); + + /** @brief Projects the image backward. + + @param src Projected image + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @param interp_mode Interpolation mode + @param border_mode Border extrapolation mode + @param dst_size Backward-projected image size + @param dst Backward-projected image + */ + CV_WRAP void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, + Size dst_size, CV_OUT OutputArray dst); + + /** + @param src_size Source image bounding box + @param K Camera intrinsic parameters + @param R Camera rotation matrix + @return Projected image minimum bounding box + */ + CV_WRAP Rect warpRoi(Size src_size, InputArray K, InputArray R); + + CV_WRAP float getScale() const { return 1.f; } + CV_WRAP void setScale(float) {} + }; + +//! @addtogroup stitching_warp +//! @{ + +/** @brief Image warper factories base class. + */ + +class CV_EXPORTS_W WarperCreator +{ +public: + CV_WRAP virtual ~WarperCreator() {} + virtual Ptr create(float scale) const = 0; +}; + + +/** @brief Plane warper factory class. + @sa detail::PlaneWarper + */ +class CV_EXPORTS PlaneWarper : public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + +/** @brief Affine warper factory class. + @sa detail::AffineWarper + */ +class CV_EXPORTS AffineWarper : public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + +/** @brief Cylindrical warper factory class. +@sa detail::CylindricalWarper +*/ +class CV_EXPORTS CylindricalWarper: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + +/** @brief Spherical warper factory class */ +class CV_EXPORTS SphericalWarper: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + +class CV_EXPORTS FisheyeWarper : public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + +class CV_EXPORTS StereographicWarper: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + +class CV_EXPORTS CompressedRectilinearWarper: public WarperCreator +{ + float a, b; +public: + CompressedRectilinearWarper(float A = 1, float B = 1) + { + a = A; b = B; + } + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale, a, b); } +}; + +class CV_EXPORTS CompressedRectilinearPortraitWarper: public WarperCreator +{ + float a, b; +public: + CompressedRectilinearPortraitWarper(float A = 1, float B = 1) + { + a = A; b = B; + } + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale, a, b); } +}; + +class CV_EXPORTS PaniniWarper: public WarperCreator +{ + float a, b; +public: + PaniniWarper(float A = 1, float B = 1) + { + a = A; b = B; + } + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale, a, b); } +}; + +class CV_EXPORTS PaniniPortraitWarper: public WarperCreator +{ + float a, b; +public: + PaniniPortraitWarper(float A = 1, float B = 1) + { + a = A; b = B; + } + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale, a, b); } +}; + +class CV_EXPORTS MercatorWarper: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + +class CV_EXPORTS TransverseMercatorWarper: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + + + +#ifdef HAVE_OPENCV_CUDAWARPING +class PlaneWarperGpu: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + + +class CylindricalWarperGpu: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; + + +class SphericalWarperGpu: public WarperCreator +{ +public: + Ptr create(float scale) const CV_OVERRIDE { return makePtr(scale); } +}; +#endif + +//! @} stitching_warp + +} // namespace cv + +#endif // OPENCV_STITCHING_WARPER_CREATORS_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/video.hpp b/Prj-Win/3rd/opencv/include/opencv2/video.hpp new file mode 100755 index 0000000..a3dde60 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/video.hpp @@ -0,0 +1,59 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_VIDEO_HPP +#define OPENCV_VIDEO_HPP + +/** + @defgroup video Video Analysis + @{ + @defgroup video_motion Motion Analysis + @defgroup video_track Object Tracking + @defgroup video_c C API + @} +*/ + +#include "opencv2/video/tracking.hpp" +#include "opencv2/video/background_segm.hpp" + +#endif //OPENCV_VIDEO_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/video/background_segm.hpp b/Prj-Win/3rd/opencv/include/opencv2/video/background_segm.hpp new file mode 100755 index 0000000..e1dfa15 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/video/background_segm.hpp @@ -0,0 +1,317 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_BACKGROUND_SEGM_HPP +#define OPENCV_BACKGROUND_SEGM_HPP + +#include "opencv2/core.hpp" + +namespace cv +{ + +//! @addtogroup video_motion +//! @{ + +/** @brief 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. + */ +class CV_EXPORTS_W BackgroundSubtractor : public Algorithm +{ +public: + /** @brief Computes a foreground mask. + + @param image Next video frame. + @param fgmask The output foreground mask as an 8-bit binary image. + @param learningRate The value between 0 and 1 that indicates how fast the background model is + learnt. Negative parameter value makes the algorithm to use some automatically chosen learning + rate. 0 means that the background model is not updated at all, 1 means that the background model + is completely reinitialized from the last frame. + */ + CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate=-1) = 0; + + /** @brief Computes a background image. + + @param backgroundImage The output background image. + + @note Sometimes the background image can be very blurry, as it contain the average background + statistics. + */ + CV_WRAP virtual void getBackgroundImage(OutputArray backgroundImage) const = 0; +}; + + +/** @brief Gaussian Mixture-based Background/Foreground Segmentation Algorithm. + +The class implements the Gaussian mixture model background subtraction described in @cite Zivkovic2004 +and @cite Zivkovic2006 . + */ +class CV_EXPORTS_W BackgroundSubtractorMOG2 : public BackgroundSubtractor +{ +public: + /** @brief Returns the number of last frames that affect the background model + */ + CV_WRAP virtual int getHistory() const = 0; + /** @brief Sets the number of last frames that affect the background model + */ + CV_WRAP virtual void setHistory(int history) = 0; + + /** @brief Returns the number of gaussian components in the background model + */ + CV_WRAP virtual int getNMixtures() const = 0; + /** @brief Sets the number of gaussian components in the background model. + + The model needs to be reinitalized to reserve memory. + */ + CV_WRAP virtual void setNMixtures(int nmixtures) = 0;//needs reinitialization! + + /** @brief Returns the "background ratio" parameter of the algorithm + + If a foreground pixel keeps semi-constant value for about backgroundRatio\*history frames, it's + considered background and added to the model as a center of a new component. It corresponds to TB + parameter in the paper. + */ + CV_WRAP virtual double getBackgroundRatio() const = 0; + /** @brief Sets the "background ratio" parameter of the algorithm + */ + CV_WRAP virtual void setBackgroundRatio(double ratio) = 0; + + /** @brief Returns the variance threshold for the pixel-model match + + The main threshold on the squared Mahalanobis distance to decide if the sample is well described by + the background model or not. Related to Cthr from the paper. + */ + CV_WRAP virtual double getVarThreshold() const = 0; + /** @brief Sets the variance threshold for the pixel-model match + */ + CV_WRAP virtual void setVarThreshold(double varThreshold) = 0; + + /** @brief Returns the variance threshold for the pixel-model match used for new mixture component generation + + Threshold for the squared Mahalanobis distance that helps decide when a sample is close to the + existing components (corresponds to Tg in the paper). If a pixel is not close to any component, it + is considered foreground or added as a new component. 3 sigma =\> Tg=3\*3=9 is default. A smaller Tg + value generates more components. A higher Tg value may result in a small number of components but + they can grow too large. + */ + CV_WRAP virtual double getVarThresholdGen() const = 0; + /** @brief Sets the variance threshold for the pixel-model match used for new mixture component generation + */ + CV_WRAP virtual void setVarThresholdGen(double varThresholdGen) = 0; + + /** @brief Returns the initial variance of each gaussian component + */ + CV_WRAP virtual double getVarInit() const = 0; + /** @brief Sets the initial variance of each gaussian component + */ + CV_WRAP virtual void setVarInit(double varInit) = 0; + + CV_WRAP virtual double getVarMin() const = 0; + CV_WRAP virtual void setVarMin(double varMin) = 0; + + CV_WRAP virtual double getVarMax() const = 0; + CV_WRAP virtual void setVarMax(double varMax) = 0; + + /** @brief Returns the complexity reduction threshold + + This parameter defines the number of samples needed to accept to prove the component exists. CT=0.05 + is a default value for all the samples. By setting CT=0 you get an algorithm very similar to the + standard Stauffer&Grimson algorithm. + */ + CV_WRAP virtual double getComplexityReductionThreshold() const = 0; + /** @brief Sets the complexity reduction threshold + */ + CV_WRAP virtual void setComplexityReductionThreshold(double ct) = 0; + + /** @brief Returns the shadow detection flag + + If true, the algorithm detects shadows and marks them. See createBackgroundSubtractorMOG2 for + details. + */ + CV_WRAP virtual bool getDetectShadows() const = 0; + /** @brief Enables or disables shadow detection + */ + CV_WRAP virtual void setDetectShadows(bool detectShadows) = 0; + + /** @brief Returns the shadow value + + Shadow value is the value used to mark shadows in the foreground mask. Default value is 127. Value 0 + in the mask always means background, 255 means foreground. + */ + CV_WRAP virtual int getShadowValue() const = 0; + /** @brief Sets the shadow value + */ + CV_WRAP virtual void setShadowValue(int value) = 0; + + /** @brief Returns the shadow threshold + + A shadow is detected if pixel is a darker version of the background. The shadow threshold (Tau in + the paper) is a threshold defining how much darker the shadow can be. Tau= 0.5 means that if a pixel + is more than twice darker then it is not shadow. See Prati, Mikic, Trivedi and Cucchiara, + *Detecting Moving Shadows...*, IEEE PAMI,2003. + */ + CV_WRAP virtual double getShadowThreshold() const = 0; + /** @brief Sets the shadow threshold + */ + CV_WRAP virtual void setShadowThreshold(double threshold) = 0; + + /** @brief Computes a foreground mask. + + @param image Next video frame. Floating point frame will be used without scaling and should be in range \f$[0,255]\f$. + @param fgmask The output foreground mask as an 8-bit binary image. + @param learningRate The value between 0 and 1 that indicates how fast the background model is + learnt. Negative parameter value makes the algorithm to use some automatically chosen learning + rate. 0 means that the background model is not updated at all, 1 means that the background model + is completely reinitialized from the last frame. + */ + CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate=-1) CV_OVERRIDE = 0; +}; + +/** @brief Creates MOG2 Background Subtractor + +@param history Length of the history. +@param varThreshold Threshold on the squared Mahalanobis distance between the pixel and the model +to decide whether a pixel is well described by the background model. This parameter does not +affect the background update. +@param detectShadows If true, the algorithm will detect shadows and mark them. It decreases the +speed a bit, so if you do not need this feature, set the parameter to false. + */ +CV_EXPORTS_W Ptr + createBackgroundSubtractorMOG2(int history=500, double varThreshold=16, + bool detectShadows=true); + +/** @brief K-nearest neighbours - based Background/Foreground Segmentation Algorithm. + +The class implements the K-nearest neighbours background subtraction described in @cite Zivkovic2006 . +Very efficient if number of foreground pixels is low. + */ +class CV_EXPORTS_W BackgroundSubtractorKNN : public BackgroundSubtractor +{ +public: + /** @brief Returns the number of last frames that affect the background model + */ + CV_WRAP virtual int getHistory() const = 0; + /** @brief Sets the number of last frames that affect the background model + */ + CV_WRAP virtual void setHistory(int history) = 0; + + /** @brief Returns the number of data samples in the background model + */ + CV_WRAP virtual int getNSamples() const = 0; + /** @brief Sets the number of data samples in the background model. + + The model needs to be reinitalized to reserve memory. + */ + CV_WRAP virtual void setNSamples(int _nN) = 0;//needs reinitialization! + + /** @brief Returns the threshold on the squared distance between the pixel and the sample + + The threshold on the squared distance between the pixel and the sample to decide whether a pixel is + close to a data sample. + */ + CV_WRAP virtual double getDist2Threshold() const = 0; + /** @brief Sets the threshold on the squared distance + */ + CV_WRAP virtual void setDist2Threshold(double _dist2Threshold) = 0; + + /** @brief Returns the number of neighbours, the k in the kNN. + + K is the number of samples that need to be within dist2Threshold in order to decide that that + pixel is matching the kNN background model. + */ + CV_WRAP virtual int getkNNSamples() const = 0; + /** @brief Sets the k in the kNN. How many nearest neighbours need to match. + */ + CV_WRAP virtual void setkNNSamples(int _nkNN) = 0; + + /** @brief Returns the shadow detection flag + + If true, the algorithm detects shadows and marks them. See createBackgroundSubtractorKNN for + details. + */ + CV_WRAP virtual bool getDetectShadows() const = 0; + /** @brief Enables or disables shadow detection + */ + CV_WRAP virtual void setDetectShadows(bool detectShadows) = 0; + + /** @brief Returns the shadow value + + Shadow value is the value used to mark shadows in the foreground mask. Default value is 127. Value 0 + in the mask always means background, 255 means foreground. + */ + CV_WRAP virtual int getShadowValue() const = 0; + /** @brief Sets the shadow value + */ + CV_WRAP virtual void setShadowValue(int value) = 0; + + /** @brief Returns the shadow threshold + + A shadow is detected if pixel is a darker version of the background. The shadow threshold (Tau in + the paper) is a threshold defining how much darker the shadow can be. Tau= 0.5 means that if a pixel + is more than twice darker then it is not shadow. See Prati, Mikic, Trivedi and Cucchiara, + *Detecting Moving Shadows...*, IEEE PAMI,2003. + */ + CV_WRAP virtual double getShadowThreshold() const = 0; + /** @brief Sets the shadow threshold + */ + CV_WRAP virtual void setShadowThreshold(double threshold) = 0; +}; + +/** @brief Creates KNN Background Subtractor + +@param history Length of the history. +@param dist2Threshold Threshold on the squared distance between the pixel and the sample to decide +whether a pixel is close to that sample. This parameter does not affect the background update. +@param detectShadows If true, the algorithm will detect shadows and mark them. It decreases the +speed a bit, so if you do not need this feature, set the parameter to false. + */ +CV_EXPORTS_W Ptr + createBackgroundSubtractorKNN(int history=500, double dist2Threshold=400.0, + bool detectShadows=true); + +//! @} video_motion + +} // cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/video/legacy/constants_c.h b/Prj-Win/3rd/opencv/include/opencv2/video/legacy/constants_c.h new file mode 100755 index 0000000..1a98f52 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/video/legacy/constants_c.h @@ -0,0 +1,16 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_VIDEO_LEGACY_CONSTANTS_H +#define OPENCV_VIDEO_LEGACY_CONSTANTS_H + +enum +{ + CV_LKFLOW_PYR_A_READY = 1, + CV_LKFLOW_PYR_B_READY = 2, + CV_LKFLOW_INITIAL_GUESSES = 4, + CV_LKFLOW_GET_MIN_EIGENVALS = 8 +}; + +#endif // OPENCV_VIDEO_LEGACY_CONSTANTS_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/video/tracking.hpp b/Prj-Win/3rd/opencv/include/opencv2/video/tracking.hpp new file mode 100755 index 0000000..e978886 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/video/tracking.hpp @@ -0,0 +1,712 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_TRACKING_HPP +#define OPENCV_TRACKING_HPP + +#include "opencv2/core.hpp" +#include "opencv2/imgproc.hpp" + +namespace cv +{ + +//! @addtogroup video_track +//! @{ + +enum { OPTFLOW_USE_INITIAL_FLOW = 4, + OPTFLOW_LK_GET_MIN_EIGENVALS = 8, + OPTFLOW_FARNEBACK_GAUSSIAN = 256 + }; + +/** @brief Finds an object center, size, and orientation. + +@param probImage Back projection of the object histogram. See calcBackProject. +@param window Initial search window. +@param criteria Stop criteria for the underlying meanShift. +returns +(in old interfaces) Number of iterations CAMSHIFT took to converge +The function implements the CAMSHIFT object tracking algorithm @cite Bradski98 . First, it finds an +object center using 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() + +See the OpenCV sample camshiftdemo.c that tracks colored objects. + +@note +- (Python) A sample explaining the camshift tracking algorithm can be found at + opencv_source_code/samples/python/camshift.py + */ +CV_EXPORTS_W RotatedRect CamShift( InputArray probImage, CV_IN_OUT Rect& window, + TermCriteria criteria ); +/** @example samples/cpp/camshiftdemo.cpp +An example using the mean-shift tracking algorithm +*/ + +/** @brief Finds an object on a back projection image. + +@param probImage Back projection of the object histogram. See calcBackProject for details. +@param window Initial search window. +@param criteria Stop criteria for the iterative search algorithm. +returns +: Number of iterations CAMSHIFT took to converge. +The function implements the iterative object search algorithm. It takes the input back projection of +an object and the initial position. The mass center in window of the back projection image is +computed and the search window center shifts to the mass center. The procedure is repeated until the +specified number of iterations criteria.maxCount is done or until the window center shifts by less +than criteria.epsilon. The algorithm is used inside CamShift and, unlike CamShift , the search +window size or orientation do not change during the search. You can simply pass the output of +calcBackProject to this function. But better results can be obtained if you pre-filter the back +projection and remove the noise. For example, you can do this by retrieving connected components +with findContours , throwing away contours with small area ( contourArea ), and rendering the +remaining contours with drawContours. + + */ +CV_EXPORTS_W int meanShift( InputArray probImage, CV_IN_OUT Rect& window, TermCriteria criteria ); + +/** @brief Constructs the image pyramid which can be passed to calcOpticalFlowPyrLK. + +@param img 8-bit input image. +@param pyramid output pyramid. +@param winSize window size of optical flow algorithm. Must be not less than winSize argument of +calcOpticalFlowPyrLK. It is needed to calculate required padding for pyramid levels. +@param maxLevel 0-based maximal pyramid level number. +@param withDerivatives set to precompute gradients for the every pyramid level. If pyramid is +constructed without the gradients then calcOpticalFlowPyrLK will calculate them internally. +@param pyrBorder the border mode for pyramid layers. +@param derivBorder the border mode for gradients. +@param tryReuseInputImage put ROI of input image into the pyramid if possible. You can pass false +to force data copying. +@return number of levels in constructed pyramid. Can be less than maxLevel. + */ +CV_EXPORTS_W int buildOpticalFlowPyramid( InputArray img, OutputArrayOfArrays pyramid, + Size winSize, int maxLevel, bool withDerivatives = true, + int pyrBorder = BORDER_REFLECT_101, + int derivBorder = BORDER_CONSTANT, + bool tryReuseInputImage = true ); + +/** @example samples/cpp/lkdemo.cpp +An example using the Lucas-Kanade optical flow algorithm +*/ + +/** @brief Calculates an optical flow for a sparse feature set using the iterative Lucas-Kanade method with +pyramids. + +@param prevImg first 8-bit input image or pyramid constructed by buildOpticalFlowPyramid. +@param nextImg second input image or pyramid of the same size and the same type as prevImg. +@param prevPts vector of 2D points for which the flow needs to be found; point coordinates must be +single-precision floating-point numbers. +@param nextPts output vector of 2D points (with single-precision floating-point coordinates) +containing the calculated new positions of input features in the second image; when +OPTFLOW_USE_INITIAL_FLOW flag is passed, the vector must have the same size as in the input. +@param status output status vector (of unsigned chars); each element of the vector is set to 1 if +the flow for the corresponding features has been found, otherwise, it is set to 0. +@param err output vector of errors; each element of the vector is set to an error for the +corresponding feature, type of the error measure can be set in flags parameter; if the flow wasn't +found then the error is not defined (use the status parameter to find such cases). +@param winSize size of the search window at each pyramid level. +@param maxLevel 0-based maximal pyramid level number; if set to 0, pyramids are not used (single +level), if set to 1, two levels are used, and so on; if pyramids are passed to input then +algorithm will use as many levels as pyramids have but no more than maxLevel. +@param criteria parameter, specifying the termination criteria of the iterative search algorithm +(after the specified maximum number of iterations criteria.maxCount or when the search window +moves by less than criteria.epsilon. +@param flags operation flags: + - **OPTFLOW_USE_INITIAL_FLOW** uses initial estimations, stored in nextPts; if the flag is + not set, then prevPts is copied to nextPts and is considered the initial estimate. + - **OPTFLOW_LK_GET_MIN_EIGENVALS** use minimum eigen values as an error measure (see + minEigThreshold description); if the flag is not set, then L1 distance between patches + around the original and a moved point, divided by number of pixels in a window, is used as a + error measure. +@param minEigThreshold the algorithm calculates the minimum eigen value of a 2x2 normal matrix of +optical flow equations (this matrix is called a spatial gradient matrix in @cite Bouguet00), divided +by number of pixels in a window; if this value is less than minEigThreshold, then a corresponding +feature is filtered out and its flow is not processed, so it allows to remove bad points and get a +performance boost. + +The function implements a sparse iterative version of the Lucas-Kanade optical flow in pyramids. See +@cite Bouguet00 . The function is parallelized with the TBB library. + +@note + +- An example using the Lucas-Kanade optical flow algorithm can be found at + opencv_source_code/samples/cpp/lkdemo.cpp +- (Python) An example using the Lucas-Kanade optical flow algorithm can be found at + opencv_source_code/samples/python/lk_track.py +- (Python) An example using the Lucas-Kanade tracker for homography matching can be found at + opencv_source_code/samples/python/lk_homography.py + */ +CV_EXPORTS_W void calcOpticalFlowPyrLK( InputArray prevImg, InputArray nextImg, + InputArray prevPts, InputOutputArray nextPts, + OutputArray status, OutputArray err, + Size winSize = Size(21,21), int maxLevel = 3, + TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01), + int flags = 0, double minEigThreshold = 1e-4 ); + +/** @brief Computes a dense optical flow using the Gunnar Farneback's algorithm. + +@param prev first 8-bit single-channel input image. +@param next second input image of the same size and the same type as prev. +@param flow computed flow image that has the same size as prev and type CV_32FC2. +@param pyr_scale parameter, specifying the image scale (\<1) to build pyramids for each image; +pyr_scale=0.5 means a classical pyramid, where each next layer is twice smaller than the previous +one. +@param levels number of pyramid layers including the initial image; levels=1 means that no extra +layers are created and only the original images are used. +@param winsize averaging window size; larger values increase the algorithm robustness to image +noise and give more chances for fast motion detection, but yield more blurred motion field. +@param iterations number of iterations the algorithm does at each pyramid level. +@param poly_n size of the pixel neighborhood used to find polynomial expansion in each pixel; +larger values mean that the image will be approximated with smoother surfaces, yielding more +robust algorithm and more blurred motion field, typically poly_n =5 or 7. +@param poly_sigma standard deviation of the Gaussian that is used to smooth derivatives used as a +basis for the polynomial expansion; for poly_n=5, you can set poly_sigma=1.1, for poly_n=7, a +good value would be poly_sigma=1.5. +@param flags operation flags that can be a combination of the following: + - **OPTFLOW_USE_INITIAL_FLOW** uses the input flow as an initial flow approximation. + - **OPTFLOW_FARNEBACK_GAUSSIAN** uses the Gaussian \f$\texttt{winsize}\times\texttt{winsize}\f$ + 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 prev pixel using the @cite Farneback2003 algorithm so that + +\f[\texttt{prev} (y,x) \sim \texttt{next} ( y + \texttt{flow} (y,x)[1], x + \texttt{flow} (y,x)[0])\f] + +@note + +- An example using the optical flow algorithm described by Gunnar Farneback can be found at + opencv_source_code/samples/cpp/fback.cpp +- (Python) An example using the optical flow algorithm described by Gunnar Farneback can be + found at opencv_source_code/samples/python/opt_flow.py + */ +CV_EXPORTS_W void calcOpticalFlowFarneback( InputArray prev, InputArray next, InputOutputArray flow, + double pyr_scale, int levels, int winsize, + int iterations, int poly_n, double poly_sigma, + int flags ); + +/** @brief Computes an optimal affine transformation between two 2D point sets. + +@param src First input 2D point set stored in std::vector or Mat, or an image stored in Mat. +@param dst Second input 2D point set of the same size and the same type as A, or another image. +@param fullAffine If true, the function finds an optimal affine transformation with no additional +restrictions (6 degrees of freedom). Otherwise, the class of transformations to choose from is +limited to combinations of translation, rotation, and uniform scaling (4 degrees of freedom). + +The function finds an optimal affine transform *[A|b]* (a 2 x 3 floating-point matrix) that +approximates best the affine transformation between: + +* Two point sets +* Two raster images. In this case, the function first finds some features in the src image and + finds the corresponding features in dst image. After that, the problem is reduced to the first + case. +In case of point sets, the problem is formulated as follows: you need to find a 2x2 matrix *A* and +2x1 vector *b* so that: + +\f[[A^*|b^*] = arg \min _{[A|b]} \sum _i \| \texttt{dst}[i] - A { \texttt{src}[i]}^T - b \| ^2\f] +where src[i] and dst[i] are the i-th points in src and dst, respectively +\f$[A|b]\f$ can be either arbitrary (when fullAffine=true ) or have a form of +\f[\begin{bmatrix} a_{11} & a_{12} & b_1 \\ -a_{12} & a_{11} & b_2 \end{bmatrix}\f] +when fullAffine=false. + +@deprecated Use cv::estimateAffine2D, cv::estimateAffinePartial2D instead. If you are using this function +with images, extract points using cv::calcOpticalFlowPyrLK and then use the estimation functions. + +@sa +estimateAffine2D, estimateAffinePartial2D, getAffineTransform, getPerspectiveTransform, findHomography + */ +CV_DEPRECATED CV_EXPORTS Mat estimateRigidTransform( InputArray src, InputArray dst, bool fullAffine ); + +enum +{ + MOTION_TRANSLATION = 0, + MOTION_EUCLIDEAN = 1, + MOTION_AFFINE = 2, + MOTION_HOMOGRAPHY = 3 +}; + +/** @brief Computes the Enhanced Correlation Coefficient value between two images @cite EP08 . + +@param templateImage single-channel template image; CV_8U or CV_32F array. +@param inputImage single-channel input image to be warped to provide an image similar to + templateImage, same type as templateImage. +@param inputMask An optional mask to indicate valid values of inputImage. + +@sa +findTransformECC + */ + +CV_EXPORTS_W double computeECC(InputArray templateImage, InputArray inputImage, InputArray inputMask = noArray()); + +/** @example samples/cpp/image_alignment.cpp +An example using the image alignment ECC algorithm +*/ + +/** @brief Finds the geometric transform (warp) between two images in terms of the ECC criterion @cite EP08 . + +@param templateImage single-channel template image; CV_8U or CV_32F array. +@param inputImage single-channel input image which should be warped with the final warpMatrix in +order to provide an image similar to templateImage, same type as templateImage. +@param warpMatrix floating-point \f$2\times 3\f$ or \f$3\times 3\f$ mapping matrix (warp). +@param motionType parameter, specifying the type of motion: + - **MOTION_TRANSLATION** sets a translational motion model; warpMatrix is \f$2\times 3\f$ with + the first \f$2\times 2\f$ part being the unity matrix and the rest two parameters being + estimated. + - **MOTION_EUCLIDEAN** sets a Euclidean (rigid) transformation as motion model; three + parameters are estimated; warpMatrix is \f$2\times 3\f$. + - **MOTION_AFFINE** sets an affine motion model (DEFAULT); six parameters are estimated; + warpMatrix is \f$2\times 3\f$. + - **MOTION_HOMOGRAPHY** sets a homography as a motion model; eight parameters are + estimated;\`warpMatrix\` is \f$3\times 3\f$. +@param criteria parameter, specifying the termination criteria of the ECC algorithm; +criteria.epsilon defines the threshold of the increment in the correlation coefficient between two +iterations (a negative criteria.epsilon makes criteria.maxcount the only termination criterion). +Default values are shown in the declaration above. +@param inputMask An optional mask to indicate valid values of inputImage. +@param gaussFiltSize An optional value indicating size of gaussian blur filter; (DEFAULT: 5) + +The function estimates the optimum transformation (warpMatrix) with respect to ECC criterion +(@cite EP08), that is + +\f[\texttt{warpMatrix} = \texttt{warpMatrix} = \arg\max_{W} \texttt{ECC}(\texttt{templateImage}(x,y),\texttt{inputImage}(x',y'))\f] + +where + +\f[\begin{bmatrix} x' \\ y' \end{bmatrix} = W \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix}\f] + +(the equation holds with homogeneous coordinates for homography). It returns the final enhanced +correlation coefficient, that is the correlation coefficient between the template image and the +final warped input image. When a \f$3\times 3\f$ matrix is given with motionType =0, 1 or 2, the third +row is ignored. + +Unlike findHomography and estimateRigidTransform, the function findTransformECC implements an +area-based alignment that builds on intensity similarities. In essence, the function updates the +initial transformation that roughly aligns the images. If this information is missing, the identity +warp (unity matrix) is used as an initialization. Note that if images undergo strong +displacements/rotations, an initial transformation that roughly aligns the images is necessary +(e.g., a simple euclidean/similarity transform that allows for the images showing the same image +content approximately). Use inverse warping in the second image to take an image close to the first +one, i.e. use the flag WARP_INVERSE_MAP with warpAffine or warpPerspective. See also the OpenCV +sample image_alignment.cpp that demonstrates the use of the function. Note that the function throws +an exception if algorithm does not converges. + +@sa +computeECC, estimateAffine2D, estimateAffinePartial2D, findHomography + */ +CV_EXPORTS_W double findTransformECC( InputArray templateImage, InputArray inputImage, + InputOutputArray warpMatrix, int motionType, + TermCriteria criteria, + InputArray inputMask, int gaussFiltSize); + +/** @overload */ +CV_EXPORTS +double findTransformECC(InputArray templateImage, InputArray inputImage, + InputOutputArray warpMatrix, int motionType = MOTION_AFFINE, + TermCriteria criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 50, 0.001), + InputArray inputMask = noArray()); + +/** @example samples/cpp/kalman.cpp +An example using the standard Kalman filter +*/ + +/** @brief Kalman filter class. + +The class implements a standard Kalman filter , +@cite Welch95 . However, you can modify transitionMatrix, controlMatrix, and measurementMatrix to get +an extended Kalman filter functionality. +@note In C API when CvKalman\* kalmanFilter structure is not needed anymore, it should be released +with cvReleaseKalman(&kalmanFilter) + */ +class CV_EXPORTS_W KalmanFilter +{ +public: + CV_WRAP KalmanFilter(); + /** @overload + @param dynamParams Dimensionality of the state. + @param measureParams Dimensionality of the measurement. + @param controlParams Dimensionality of the control vector. + @param type Type of the created matrices that should be CV_32F or CV_64F. + */ + CV_WRAP KalmanFilter( int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F ); + + /** @brief Re-initializes Kalman filter. The previous content is destroyed. + + @param dynamParams Dimensionality of the state. + @param measureParams Dimensionality of the measurement. + @param controlParams Dimensionality of the control vector. + @param type Type of the created matrices that should be CV_32F or CV_64F. + */ + void init( int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F ); + + /** @brief Computes a predicted state. + + @param control The optional input control + */ + CV_WRAP const Mat& predict( const Mat& control = Mat() ); + + /** @brief Updates the predicted state from the measurement. + + @param measurement The measured system parameters + */ + CV_WRAP const Mat& correct( const Mat& measurement ); + + CV_PROP_RW Mat statePre; //!< predicted state (x'(k)): x(k)=A*x(k-1)+B*u(k) + CV_PROP_RW Mat statePost; //!< corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) + CV_PROP_RW Mat transitionMatrix; //!< state transition matrix (A) + CV_PROP_RW Mat controlMatrix; //!< control matrix (B) (not used if there is no control) + CV_PROP_RW Mat measurementMatrix; //!< measurement matrix (H) + CV_PROP_RW Mat processNoiseCov; //!< process noise covariance matrix (Q) + CV_PROP_RW Mat measurementNoiseCov;//!< measurement noise covariance matrix (R) + CV_PROP_RW Mat errorCovPre; //!< priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q)*/ + CV_PROP_RW Mat gain; //!< Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R) + CV_PROP_RW Mat errorCovPost; //!< posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P'(k) + + // temporary matrices + Mat temp1; + Mat temp2; + Mat temp3; + Mat temp4; + Mat temp5; +}; + + +/** @brief Read a .flo file + + @param path Path to the file to be loaded + + The function readOpticalFlow loads a flow field from a file and returns it as a single matrix. + Resulting Mat has a type CV_32FC2 - floating-point, 2-channel. First channel corresponds to the + flow in the horizontal direction (u), second - vertical (v). + */ +CV_EXPORTS_W Mat readOpticalFlow( const String& path ); +/** @brief Write a .flo to disk + + @param path Path to the file to be written + @param flow Flow field to be stored + + The function stores a flow field in a file, returns true on success, false otherwise. + The flow field must be a 2-channel, floating-point matrix (CV_32FC2). First channel corresponds + to the flow in the horizontal direction (u), second - vertical (v). + */ +CV_EXPORTS_W bool writeOpticalFlow( const String& path, InputArray flow ); + +/** + Base class for dense optical flow algorithms +*/ +class CV_EXPORTS_W DenseOpticalFlow : public Algorithm +{ +public: + /** @brief Calculates an optical flow. + + @param I0 first 8-bit single-channel input image. + @param I1 second input image of the same size and the same type as prev. + @param flow computed flow image that has the same size as prev and type CV_32FC2. + */ + CV_WRAP virtual void calc( InputArray I0, InputArray I1, InputOutputArray flow ) = 0; + /** @brief Releases all inner buffers. + */ + CV_WRAP virtual void collectGarbage() = 0; +}; + +/** @brief Base interface for sparse optical flow algorithms. + */ +class CV_EXPORTS_W SparseOpticalFlow : public Algorithm +{ +public: + /** @brief Calculates a sparse optical flow. + + @param prevImg First input image. + @param nextImg Second input image of the same size and the same type as prevImg. + @param prevPts Vector of 2D points for which the flow needs to be found. + @param nextPts Output vector of 2D points containing the calculated new positions of input features in the second image. + @param status Output status vector. Each element of the vector is set to 1 if the + flow for the corresponding features has been found. Otherwise, it is set to 0. + @param err Optional output vector that contains error response for each point (inverse confidence). + */ + CV_WRAP virtual void calc(InputArray prevImg, InputArray nextImg, + InputArray prevPts, InputOutputArray nextPts, + OutputArray status, + OutputArray err = cv::noArray()) = 0; +}; + + +/** @brief Class computing a dense optical flow using the Gunnar Farneback's algorithm. + */ +class CV_EXPORTS_W FarnebackOpticalFlow : public DenseOpticalFlow +{ +public: + CV_WRAP virtual int getNumLevels() const = 0; + CV_WRAP virtual void setNumLevels(int numLevels) = 0; + + CV_WRAP virtual double getPyrScale() const = 0; + CV_WRAP virtual void setPyrScale(double pyrScale) = 0; + + CV_WRAP virtual bool getFastPyramids() const = 0; + CV_WRAP virtual void setFastPyramids(bool fastPyramids) = 0; + + CV_WRAP virtual int getWinSize() const = 0; + CV_WRAP virtual void setWinSize(int winSize) = 0; + + CV_WRAP virtual int getNumIters() const = 0; + CV_WRAP virtual void setNumIters(int numIters) = 0; + + CV_WRAP virtual int getPolyN() const = 0; + CV_WRAP virtual void setPolyN(int polyN) = 0; + + CV_WRAP virtual double getPolySigma() const = 0; + CV_WRAP virtual void setPolySigma(double polySigma) = 0; + + CV_WRAP virtual int getFlags() const = 0; + CV_WRAP virtual void setFlags(int flags) = 0; + + CV_WRAP static Ptr create( + int numLevels = 5, + double pyrScale = 0.5, + bool fastPyramids = false, + int winSize = 13, + int numIters = 10, + int polyN = 5, + double polySigma = 1.1, + int flags = 0); +}; + +/** @brief Variational optical flow refinement + +This class implements variational refinement of the input flow field, i.e. +it uses input flow to initialize the minimization of the following functional: +\f$E(U) = \int_{\Omega} \delta \Psi(E_I) + \gamma \Psi(E_G) + \alpha \Psi(E_S) \f$, +where \f$E_I,E_G,E_S\f$ are color constancy, gradient constancy and smoothness terms +respectively. \f$\Psi(s^2)=\sqrt{s^2+\epsilon^2}\f$ is a robust penalizer to limit the +influence of outliers. A complete formulation and a description of the minimization +procedure can be found in @cite Brox2004 +*/ +class CV_EXPORTS_W VariationalRefinement : public DenseOpticalFlow +{ +public: + /** @brief @ref calc function overload to handle separate horizontal (u) and vertical (v) flow components + (to avoid extra splits/merges) */ + CV_WRAP virtual void calcUV(InputArray I0, InputArray I1, InputOutputArray flow_u, InputOutputArray flow_v) = 0; + + /** @brief Number of outer (fixed-point) iterations in the minimization procedure. + @see setFixedPointIterations */ + CV_WRAP virtual int getFixedPointIterations() const = 0; + /** @copybrief getFixedPointIterations @see getFixedPointIterations */ + CV_WRAP virtual void setFixedPointIterations(int val) = 0; + + /** @brief Number of inner successive over-relaxation (SOR) iterations + in the minimization procedure to solve the respective linear system. + @see setSorIterations */ + CV_WRAP virtual int getSorIterations() const = 0; + /** @copybrief getSorIterations @see getSorIterations */ + CV_WRAP virtual void setSorIterations(int val) = 0; + + /** @brief Relaxation factor in SOR + @see setOmega */ + CV_WRAP virtual float getOmega() const = 0; + /** @copybrief getOmega @see getOmega */ + CV_WRAP virtual void setOmega(float val) = 0; + + /** @brief Weight of the smoothness term + @see setAlpha */ + CV_WRAP virtual float getAlpha() const = 0; + /** @copybrief getAlpha @see getAlpha */ + CV_WRAP virtual void setAlpha(float val) = 0; + + /** @brief Weight of the color constancy term + @see setDelta */ + CV_WRAP virtual float getDelta() const = 0; + /** @copybrief getDelta @see getDelta */ + CV_WRAP virtual void setDelta(float val) = 0; + + /** @brief Weight of the gradient constancy term + @see setGamma */ + CV_WRAP virtual float getGamma() const = 0; + /** @copybrief getGamma @see getGamma */ + CV_WRAP virtual void setGamma(float val) = 0; + + /** @brief Creates an instance of VariationalRefinement + */ + CV_WRAP static Ptr create(); +}; + +/** @brief DIS optical flow algorithm. + +This class implements the Dense Inverse Search (DIS) optical flow algorithm. More +details about the algorithm can be found at @cite Kroeger2016 . Includes three presets with preselected +parameters to provide reasonable trade-off between speed and quality. However, even the slowest preset is +still relatively fast, use DeepFlow if you need better quality and don't care about speed. + +This implementation includes several additional features compared to the algorithm described in the paper, +including spatial propagation of flow vectors (@ref getUseSpatialPropagation), as well as an option to +utilize an initial flow approximation passed to @ref calc (which is, essentially, temporal propagation, +if the previous frame's flow field is passed). +*/ +class CV_EXPORTS_W DISOpticalFlow : public DenseOpticalFlow +{ +public: + enum + { + PRESET_ULTRAFAST = 0, + PRESET_FAST = 1, + PRESET_MEDIUM = 2 + }; + + /** @brief Finest level of the Gaussian pyramid on which the flow is computed (zero level + corresponds to the original image resolution). The final flow is obtained by bilinear upscaling. + @see setFinestScale */ + CV_WRAP virtual int getFinestScale() const = 0; + /** @copybrief getFinestScale @see getFinestScale */ + CV_WRAP virtual void setFinestScale(int val) = 0; + + /** @brief Size of an image patch for matching (in pixels). Normally, default 8x8 patches work well + enough in most cases. + @see setPatchSize */ + CV_WRAP virtual int getPatchSize() const = 0; + /** @copybrief getPatchSize @see getPatchSize */ + CV_WRAP virtual void setPatchSize(int val) = 0; + + /** @brief Stride between neighbor patches. Must be less than patch size. Lower values correspond + to higher flow quality. + @see setPatchStride */ + CV_WRAP virtual int getPatchStride() const = 0; + /** @copybrief getPatchStride @see getPatchStride */ + CV_WRAP virtual void setPatchStride(int val) = 0; + + /** @brief Maximum number of gradient descent iterations in the patch inverse search stage. Higher values + may improve quality in some cases. + @see setGradientDescentIterations */ + CV_WRAP virtual int getGradientDescentIterations() const = 0; + /** @copybrief getGradientDescentIterations @see getGradientDescentIterations */ + CV_WRAP virtual void setGradientDescentIterations(int val) = 0; + + /** @brief Number of fixed point iterations of variational refinement per scale. Set to zero to + disable variational refinement completely. Higher values will typically result in more smooth and + high-quality flow. + @see setGradientDescentIterations */ + CV_WRAP virtual int getVariationalRefinementIterations() const = 0; + /** @copybrief getGradientDescentIterations @see getGradientDescentIterations */ + CV_WRAP virtual void setVariationalRefinementIterations(int val) = 0; + + /** @brief Weight of the smoothness term + @see setVariationalRefinementAlpha */ + CV_WRAP virtual float getVariationalRefinementAlpha() const = 0; + /** @copybrief getVariationalRefinementAlpha @see getVariationalRefinementAlpha */ + CV_WRAP virtual void setVariationalRefinementAlpha(float val) = 0; + + /** @brief Weight of the color constancy term + @see setVariationalRefinementDelta */ + CV_WRAP virtual float getVariationalRefinementDelta() const = 0; + /** @copybrief getVariationalRefinementDelta @see getVariationalRefinementDelta */ + CV_WRAP virtual void setVariationalRefinementDelta(float val) = 0; + + /** @brief Weight of the gradient constancy term + @see setVariationalRefinementGamma */ + CV_WRAP virtual float getVariationalRefinementGamma() const = 0; + /** @copybrief getVariationalRefinementGamma @see getVariationalRefinementGamma */ + CV_WRAP virtual void setVariationalRefinementGamma(float val) = 0; + + + /** @brief Whether to use mean-normalization of patches when computing patch distance. It is turned on + by default as it typically provides a noticeable quality boost because of increased robustness to + illumination variations. Turn it off if you are certain that your sequence doesn't contain any changes + in illumination. + @see setUseMeanNormalization */ + CV_WRAP virtual bool getUseMeanNormalization() const = 0; + /** @copybrief getUseMeanNormalization @see getUseMeanNormalization */ + CV_WRAP virtual void setUseMeanNormalization(bool val) = 0; + + /** @brief Whether to use spatial propagation of good optical flow vectors. This option is turned on by + default, as it tends to work better on average and can sometimes help recover from major errors + introduced by the coarse-to-fine scheme employed by the DIS optical flow algorithm. Turning this + option off can make the output flow field a bit smoother, however. + @see setUseSpatialPropagation */ + CV_WRAP virtual bool getUseSpatialPropagation() const = 0; + /** @copybrief getUseSpatialPropagation @see getUseSpatialPropagation */ + CV_WRAP virtual void setUseSpatialPropagation(bool val) = 0; + + /** @brief Creates an instance of DISOpticalFlow + + @param preset one of PRESET_ULTRAFAST, PRESET_FAST and PRESET_MEDIUM + */ + CV_WRAP static Ptr create(int preset = DISOpticalFlow::PRESET_FAST); +}; + +/** @brief Class used for calculating a sparse optical flow. + +The class can calculate an optical flow for a sparse feature set using the +iterative Lucas-Kanade method with pyramids. + +@sa calcOpticalFlowPyrLK + +*/ +class CV_EXPORTS_W SparsePyrLKOpticalFlow : public SparseOpticalFlow +{ +public: + CV_WRAP virtual Size getWinSize() const = 0; + CV_WRAP virtual void setWinSize(Size winSize) = 0; + + CV_WRAP virtual int getMaxLevel() const = 0; + CV_WRAP virtual void setMaxLevel(int maxLevel) = 0; + + CV_WRAP virtual TermCriteria getTermCriteria() const = 0; + CV_WRAP virtual void setTermCriteria(TermCriteria& crit) = 0; + + CV_WRAP virtual int getFlags() const = 0; + CV_WRAP virtual void setFlags(int flags) = 0; + + CV_WRAP virtual double getMinEigThreshold() const = 0; + CV_WRAP virtual void setMinEigThreshold(double minEigThreshold) = 0; + + CV_WRAP static Ptr create( + Size winSize = Size(21, 21), + int maxLevel = 3, TermCriteria crit = + TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01), + int flags = 0, + double minEigThreshold = 1e-4); +}; + +//! @} video_track + +} // cv + +#endif diff --git a/Prj-Win/3rd/opencv/include/opencv2/video/video.hpp b/Prj-Win/3rd/opencv/include/opencv2/video/video.hpp new file mode 100755 index 0000000..8267b85 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/video/video.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/video.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/videoio.hpp b/Prj-Win/3rd/opencv/include/opencv2/videoio.hpp new file mode 100755 index 0000000..5dd10fd --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/videoio.hpp @@ -0,0 +1,958 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_VIDEOIO_HPP +#define OPENCV_VIDEOIO_HPP + +#include "opencv2/core.hpp" + +/** + @defgroup videoio Video I/O + + @brief Read and write video or images sequence with OpenCV + + ### See also: + - @ref videoio_overview + - Tutorials: @ref tutorial_table_of_content_videoio + @{ + @defgroup videoio_flags_base Flags for video I/O + @defgroup videoio_flags_others Additional flags for video I/O API backends + @defgroup videoio_c C API for video I/O + @defgroup videoio_ios iOS glue for video I/O + @defgroup videoio_winrt WinRT glue for video I/O + @defgroup videoio_registry Query I/O API backends registry + @} +*/ + +////////////////////////////////// video io ///////////////////////////////// + +typedef struct CvCapture CvCapture; +typedef struct CvVideoWriter CvVideoWriter; + +namespace cv +{ + +//! @addtogroup videoio +//! @{ + +//! @addtogroup videoio_flags_base +//! @{ + + +/** @brief %VideoCapture API backends identifier. + +Select preferred API for a capture object. +To be used in the VideoCapture::VideoCapture() constructor or VideoCapture::open() + +@note Backends are available only if they have been built with your OpenCV binaries. +See @ref videoio_overview for more information. +*/ +enum VideoCaptureAPIs { + CAP_ANY = 0, //!< Auto detect == 0 + CAP_VFW = 200, //!< Video For Windows (obsolete, removed) + CAP_V4L = 200, //!< V4L/V4L2 capturing support + CAP_V4L2 = CAP_V4L, //!< Same as CAP_V4L + CAP_FIREWIRE = 300, //!< IEEE 1394 drivers + CAP_FIREWARE = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE + CAP_IEEE1394 = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE + CAP_DC1394 = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE + CAP_CMU1394 = CAP_FIREWIRE, //!< Same value as CAP_FIREWIRE + CAP_QT = 500, //!< QuickTime (obsolete, removed) + CAP_UNICAP = 600, //!< Unicap drivers (obsolete, removed) + CAP_DSHOW = 700, //!< DirectShow (via videoInput) + CAP_PVAPI = 800, //!< PvAPI, Prosilica GigE SDK + CAP_OPENNI = 900, //!< OpenNI (for Kinect) + CAP_OPENNI_ASUS = 910, //!< OpenNI (for Asus Xtion) + CAP_ANDROID = 1000, //!< Android - not used + CAP_XIAPI = 1100, //!< XIMEA Camera API + CAP_AVFOUNDATION = 1200, //!< AVFoundation framework for iOS (OS X Lion will have the same API) + CAP_GIGANETIX = 1300, //!< Smartek Giganetix GigEVisionSDK + CAP_MSMF = 1400, //!< Microsoft Media Foundation (via videoInput) + CAP_WINRT = 1410, //!< Microsoft Windows Runtime using Media Foundation + CAP_INTELPERC = 1500, //!< RealSense (former Intel Perceptual Computing SDK) + CAP_REALSENSE = 1500, //!< Synonym for CAP_INTELPERC + CAP_OPENNI2 = 1600, //!< OpenNI2 (for Kinect) + CAP_OPENNI2_ASUS = 1610, //!< OpenNI2 (for Asus Xtion and Occipital Structure sensors) + CAP_GPHOTO2 = 1700, //!< gPhoto2 connection + CAP_GSTREAMER = 1800, //!< GStreamer + CAP_FFMPEG = 1900, //!< Open and record video file or stream using the FFMPEG library + CAP_IMAGES = 2000, //!< OpenCV Image Sequence (e.g. img_%02d.jpg) + CAP_ARAVIS = 2100, //!< Aravis SDK + CAP_OPENCV_MJPEG = 2200, //!< Built-in OpenCV MotionJPEG codec + CAP_INTEL_MFX = 2300, //!< Intel MediaSDK + CAP_XINE = 2400, //!< XINE engine (Linux) + }; + +/** @brief %VideoCapture generic properties identifier. + + Reading / writing properties involves many layers. Some unexpected result might happens along this chain. + Effective behaviour depends from device hardware, driver and API Backend. + @sa videoio_flags_others, VideoCapture::get(), VideoCapture::set() +*/ +enum VideoCaptureProperties { + CAP_PROP_POS_MSEC =0, //!< Current position of the video file in milliseconds. + CAP_PROP_POS_FRAMES =1, //!< 0-based index of the frame to be decoded/captured next. + CAP_PROP_POS_AVI_RATIO =2, //!< Relative position of the video file: 0=start of the film, 1=end of the film. + CAP_PROP_FRAME_WIDTH =3, //!< Width of the frames in the video stream. + CAP_PROP_FRAME_HEIGHT =4, //!< Height of the frames in the video stream. + CAP_PROP_FPS =5, //!< Frame rate. + CAP_PROP_FOURCC =6, //!< 4-character code of codec. see VideoWriter::fourcc . + CAP_PROP_FRAME_COUNT =7, //!< Number of frames in the video file. + CAP_PROP_FORMAT =8, //!< Format of the %Mat objects returned by VideoCapture::retrieve(). + CAP_PROP_MODE =9, //!< Backend-specific value indicating the current capture mode. + CAP_PROP_BRIGHTNESS =10, //!< Brightness of the image (only for those cameras that support). + CAP_PROP_CONTRAST =11, //!< Contrast of the image (only for cameras). + CAP_PROP_SATURATION =12, //!< Saturation of the image (only for cameras). + CAP_PROP_HUE =13, //!< Hue of the image (only for cameras). + CAP_PROP_GAIN =14, //!< Gain of the image (only for those cameras that support). + CAP_PROP_EXPOSURE =15, //!< Exposure (only for those cameras that support). + CAP_PROP_CONVERT_RGB =16, //!< Boolean flags indicating whether images should be converted to RGB. + CAP_PROP_WHITE_BALANCE_BLUE_U =17, //!< Currently unsupported. + CAP_PROP_RECTIFICATION =18, //!< Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently). + CAP_PROP_MONOCHROME =19, + CAP_PROP_SHARPNESS =20, + CAP_PROP_AUTO_EXPOSURE =21, //!< DC1394: exposure control done by camera, user can adjust reference level using this feature. + CAP_PROP_GAMMA =22, + CAP_PROP_TEMPERATURE =23, + CAP_PROP_TRIGGER =24, + CAP_PROP_TRIGGER_DELAY =25, + CAP_PROP_WHITE_BALANCE_RED_V =26, + CAP_PROP_ZOOM =27, + CAP_PROP_FOCUS =28, + CAP_PROP_GUID =29, + CAP_PROP_ISO_SPEED =30, + CAP_PROP_BACKLIGHT =32, + CAP_PROP_PAN =33, + CAP_PROP_TILT =34, + CAP_PROP_ROLL =35, + CAP_PROP_IRIS =36, + CAP_PROP_SETTINGS =37, //!< Pop up video/camera filter dialog (note: only supported by DSHOW backend currently. The property value is ignored) + CAP_PROP_BUFFERSIZE =38, + CAP_PROP_AUTOFOCUS =39, + CAP_PROP_SAR_NUM =40, //!< Sample aspect ratio: num/den (num) + CAP_PROP_SAR_DEN =41, //!< Sample aspect ratio: num/den (den) + CAP_PROP_BACKEND =42, //!< Current backend (enum VideoCaptureAPIs). Read-only property + CAP_PROP_CHANNEL =43, //!< Video input or Channel Number (only for those cameras that support) + CAP_PROP_AUTO_WB =44, //!< enable/ disable auto white-balance + CAP_PROP_WB_TEMPERATURE=45, //!< white-balance color temperature +#ifndef CV_DOXYGEN + CV__CAP_PROP_LATEST +#endif + }; + +/** @brief %VideoWriter generic properties identifier. + @sa VideoWriter::get(), VideoWriter::set() +*/ +enum VideoWriterProperties { + VIDEOWRITER_PROP_QUALITY = 1, //!< Current quality (0..100%) of the encoded videostream. Can be adjusted dynamically in some codecs. + VIDEOWRITER_PROP_FRAMEBYTES = 2, //!< (Read-only): Size of just encoded video frame. Note that the encoding order may be different from representation order. + VIDEOWRITER_PROP_NSTRIPES = 3 //!< Number of stripes for parallel encoding. -1 for auto detection. +}; + +//! @} videoio_flags_base + +//! @addtogroup videoio_flags_others +//! @{ + +/** @name IEEE 1394 drivers + @{ +*/ + +/** @brief Modes of the IEEE 1394 controlling registers +(can be: auto, manual, auto single push, absolute Latter allowed with any other mode) +every feature can have only one mode turned on at a time +*/ +enum { CAP_PROP_DC1394_OFF = -4, //!< turn the feature off (not controlled manually nor automatically). + CAP_PROP_DC1394_MODE_MANUAL = -3, //!< set automatically when a value of the feature is set by the user. + CAP_PROP_DC1394_MODE_AUTO = -2, + CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO = -1, + CAP_PROP_DC1394_MAX = 31 + }; + +//! @} IEEE 1394 drivers + +/** @name OpenNI (for Kinect) + @{ +*/ + +//! OpenNI map generators +enum { CAP_OPENNI_DEPTH_GENERATOR = 1 << 31, + CAP_OPENNI_IMAGE_GENERATOR = 1 << 30, + CAP_OPENNI_IR_GENERATOR = 1 << 29, + CAP_OPENNI_GENERATORS_MASK = CAP_OPENNI_DEPTH_GENERATOR + CAP_OPENNI_IMAGE_GENERATOR + CAP_OPENNI_IR_GENERATOR + }; + +//! Properties of cameras available through OpenNI backend +enum { CAP_PROP_OPENNI_OUTPUT_MODE = 100, + CAP_PROP_OPENNI_FRAME_MAX_DEPTH = 101, //!< In mm + CAP_PROP_OPENNI_BASELINE = 102, //!< In mm + CAP_PROP_OPENNI_FOCAL_LENGTH = 103, //!< In pixels + CAP_PROP_OPENNI_REGISTRATION = 104, //!< Flag that synchronizes the remapping depth map to image map + //!< by changing depth generator's view point (if the flag is "on") or + //!< sets this view point to its normal one (if the flag is "off"). + CAP_PROP_OPENNI_REGISTRATION_ON = CAP_PROP_OPENNI_REGISTRATION, + CAP_PROP_OPENNI_APPROX_FRAME_SYNC = 105, + CAP_PROP_OPENNI_MAX_BUFFER_SIZE = 106, + CAP_PROP_OPENNI_CIRCLE_BUFFER = 107, + CAP_PROP_OPENNI_MAX_TIME_DURATION = 108, + CAP_PROP_OPENNI_GENERATOR_PRESENT = 109, + CAP_PROP_OPENNI2_SYNC = 110, + CAP_PROP_OPENNI2_MIRROR = 111 + }; + +//! OpenNI shortcuts +enum { CAP_OPENNI_IMAGE_GENERATOR_PRESENT = CAP_OPENNI_IMAGE_GENERATOR + CAP_PROP_OPENNI_GENERATOR_PRESENT, + CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE = CAP_OPENNI_IMAGE_GENERATOR + CAP_PROP_OPENNI_OUTPUT_MODE, + CAP_OPENNI_DEPTH_GENERATOR_PRESENT = CAP_OPENNI_DEPTH_GENERATOR + CAP_PROP_OPENNI_GENERATOR_PRESENT, + CAP_OPENNI_DEPTH_GENERATOR_BASELINE = CAP_OPENNI_DEPTH_GENERATOR + CAP_PROP_OPENNI_BASELINE, + CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH = CAP_OPENNI_DEPTH_GENERATOR + CAP_PROP_OPENNI_FOCAL_LENGTH, + CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION = CAP_OPENNI_DEPTH_GENERATOR + CAP_PROP_OPENNI_REGISTRATION, + CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION_ON = CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION, + CAP_OPENNI_IR_GENERATOR_PRESENT = CAP_OPENNI_IR_GENERATOR + CAP_PROP_OPENNI_GENERATOR_PRESENT, + }; + +//! OpenNI data given from depth generator +enum { CAP_OPENNI_DEPTH_MAP = 0, //!< Depth values in mm (CV_16UC1) + CAP_OPENNI_POINT_CLOUD_MAP = 1, //!< XYZ in meters (CV_32FC3) + CAP_OPENNI_DISPARITY_MAP = 2, //!< Disparity in pixels (CV_8UC1) + CAP_OPENNI_DISPARITY_MAP_32F = 3, //!< Disparity in pixels (CV_32FC1) + CAP_OPENNI_VALID_DEPTH_MASK = 4, //!< CV_8UC1 + + CAP_OPENNI_BGR_IMAGE = 5, //!< Data given from RGB image generator + CAP_OPENNI_GRAY_IMAGE = 6, //!< Data given from RGB image generator + + CAP_OPENNI_IR_IMAGE = 7 //!< Data given from IR image generator + }; + +//! Supported output modes of OpenNI image generator +enum { CAP_OPENNI_VGA_30HZ = 0, + CAP_OPENNI_SXGA_15HZ = 1, + CAP_OPENNI_SXGA_30HZ = 2, + CAP_OPENNI_QVGA_30HZ = 3, + CAP_OPENNI_QVGA_60HZ = 4 + }; + +//! @} OpenNI + +/** @name GStreamer + @{ +*/ + +enum { CAP_PROP_GSTREAMER_QUEUE_LENGTH = 200 //!< Default is 1 + }; + +//! @} GStreamer + +/** @name PvAPI, Prosilica GigE SDK + @{ +*/ + +//! PVAPI +enum { CAP_PROP_PVAPI_MULTICASTIP = 300, //!< IP for enable multicast master mode. 0 for disable multicast. + CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE = 301, //!< FrameStartTriggerMode: Determines how a frame is initiated. + CAP_PROP_PVAPI_DECIMATIONHORIZONTAL = 302, //!< Horizontal sub-sampling of the image. + CAP_PROP_PVAPI_DECIMATIONVERTICAL = 303, //!< Vertical sub-sampling of the image. + CAP_PROP_PVAPI_BINNINGX = 304, //!< Horizontal binning factor. + CAP_PROP_PVAPI_BINNINGY = 305, //!< Vertical binning factor. + CAP_PROP_PVAPI_PIXELFORMAT = 306 //!< Pixel format. + }; + +//! PVAPI: FrameStartTriggerMode +enum { CAP_PVAPI_FSTRIGMODE_FREERUN = 0, //!< Freerun + CAP_PVAPI_FSTRIGMODE_SYNCIN1 = 1, //!< SyncIn1 + CAP_PVAPI_FSTRIGMODE_SYNCIN2 = 2, //!< SyncIn2 + CAP_PVAPI_FSTRIGMODE_FIXEDRATE = 3, //!< FixedRate + CAP_PVAPI_FSTRIGMODE_SOFTWARE = 4 //!< Software + }; + +//! PVAPI: DecimationHorizontal, DecimationVertical +enum { CAP_PVAPI_DECIMATION_OFF = 1, //!< Off + CAP_PVAPI_DECIMATION_2OUTOF4 = 2, //!< 2 out of 4 decimation + CAP_PVAPI_DECIMATION_2OUTOF8 = 4, //!< 2 out of 8 decimation + CAP_PVAPI_DECIMATION_2OUTOF16 = 8 //!< 2 out of 16 decimation + }; + +//! PVAPI: PixelFormat +enum { CAP_PVAPI_PIXELFORMAT_MONO8 = 1, //!< Mono8 + CAP_PVAPI_PIXELFORMAT_MONO16 = 2, //!< Mono16 + CAP_PVAPI_PIXELFORMAT_BAYER8 = 3, //!< Bayer8 + CAP_PVAPI_PIXELFORMAT_BAYER16 = 4, //!< Bayer16 + CAP_PVAPI_PIXELFORMAT_RGB24 = 5, //!< Rgb24 + CAP_PVAPI_PIXELFORMAT_BGR24 = 6, //!< Bgr24 + CAP_PVAPI_PIXELFORMAT_RGBA32 = 7, //!< Rgba32 + CAP_PVAPI_PIXELFORMAT_BGRA32 = 8, //!< Bgra32 + }; + +//! @} PvAPI + +/** @name XIMEA Camera API + @{ +*/ + +//! Properties of cameras available through XIMEA SDK backend +enum { CAP_PROP_XI_DOWNSAMPLING = 400, //!< Change image resolution by binning or skipping. + CAP_PROP_XI_DATA_FORMAT = 401, //!< Output data format. + CAP_PROP_XI_OFFSET_X = 402, //!< Horizontal offset from the origin to the area of interest (in pixels). + CAP_PROP_XI_OFFSET_Y = 403, //!< Vertical offset from the origin to the area of interest (in pixels). + CAP_PROP_XI_TRG_SOURCE = 404, //!< Defines source of trigger. + CAP_PROP_XI_TRG_SOFTWARE = 405, //!< Generates an internal trigger. PRM_TRG_SOURCE must be set to TRG_SOFTWARE. + CAP_PROP_XI_GPI_SELECTOR = 406, //!< Selects general purpose input. + CAP_PROP_XI_GPI_MODE = 407, //!< Set general purpose input mode. + CAP_PROP_XI_GPI_LEVEL = 408, //!< Get general purpose level. + CAP_PROP_XI_GPO_SELECTOR = 409, //!< Selects general purpose output. + CAP_PROP_XI_GPO_MODE = 410, //!< Set general purpose output mode. + CAP_PROP_XI_LED_SELECTOR = 411, //!< Selects camera signalling LED. + CAP_PROP_XI_LED_MODE = 412, //!< Define camera signalling LED functionality. + CAP_PROP_XI_MANUAL_WB = 413, //!< Calculates White Balance(must be called during acquisition). + CAP_PROP_XI_AUTO_WB = 414, //!< Automatic white balance. + CAP_PROP_XI_AEAG = 415, //!< Automatic exposure/gain. + CAP_PROP_XI_EXP_PRIORITY = 416, //!< Exposure priority (0.5 - exposure 50%, gain 50%). + CAP_PROP_XI_AE_MAX_LIMIT = 417, //!< Maximum limit of exposure in AEAG procedure. + CAP_PROP_XI_AG_MAX_LIMIT = 418, //!< Maximum limit of gain in AEAG procedure. + CAP_PROP_XI_AEAG_LEVEL = 419, //!< Average intensity of output signal AEAG should achieve(in %). + CAP_PROP_XI_TIMEOUT = 420, //!< Image capture timeout in milliseconds. + CAP_PROP_XI_EXPOSURE = 421, //!< Exposure time in microseconds. + CAP_PROP_XI_EXPOSURE_BURST_COUNT = 422, //!< Sets the number of times of exposure in one frame. + CAP_PROP_XI_GAIN_SELECTOR = 423, //!< Gain selector for parameter Gain allows to select different type of gains. + CAP_PROP_XI_GAIN = 424, //!< Gain in dB. + CAP_PROP_XI_DOWNSAMPLING_TYPE = 426, //!< Change image downsampling type. + CAP_PROP_XI_BINNING_SELECTOR = 427, //!< Binning engine selector. + CAP_PROP_XI_BINNING_VERTICAL = 428, //!< Vertical Binning - number of vertical photo-sensitive cells to combine together. + CAP_PROP_XI_BINNING_HORIZONTAL = 429, //!< Horizontal Binning - number of horizontal photo-sensitive cells to combine together. + CAP_PROP_XI_BINNING_PATTERN = 430, //!< Binning pattern type. + CAP_PROP_XI_DECIMATION_SELECTOR = 431, //!< Decimation engine selector. + CAP_PROP_XI_DECIMATION_VERTICAL = 432, //!< Vertical Decimation - vertical sub-sampling of the image - reduces the vertical resolution of the image by the specified vertical decimation factor. + CAP_PROP_XI_DECIMATION_HORIZONTAL = 433, //!< Horizontal Decimation - horizontal sub-sampling of the image - reduces the horizontal resolution of the image by the specified vertical decimation factor. + CAP_PROP_XI_DECIMATION_PATTERN = 434, //!< Decimation pattern type. + CAP_PROP_XI_TEST_PATTERN_GENERATOR_SELECTOR = 587, //!< Selects which test pattern generator is controlled by the TestPattern feature. + CAP_PROP_XI_TEST_PATTERN = 588, //!< Selects which test pattern type is generated by the selected generator. + CAP_PROP_XI_IMAGE_DATA_FORMAT = 435, //!< Output data format. + CAP_PROP_XI_SHUTTER_TYPE = 436, //!< Change sensor shutter type(CMOS sensor). + CAP_PROP_XI_SENSOR_TAPS = 437, //!< Number of taps. + CAP_PROP_XI_AEAG_ROI_OFFSET_X = 439, //!< Automatic exposure/gain ROI offset X. + CAP_PROP_XI_AEAG_ROI_OFFSET_Y = 440, //!< Automatic exposure/gain ROI offset Y. + CAP_PROP_XI_AEAG_ROI_WIDTH = 441, //!< Automatic exposure/gain ROI Width. + CAP_PROP_XI_AEAG_ROI_HEIGHT = 442, //!< Automatic exposure/gain ROI Height. + CAP_PROP_XI_BPC = 445, //!< Correction of bad pixels. + CAP_PROP_XI_WB_KR = 448, //!< White balance red coefficient. + CAP_PROP_XI_WB_KG = 449, //!< White balance green coefficient. + CAP_PROP_XI_WB_KB = 450, //!< White balance blue coefficient. + CAP_PROP_XI_WIDTH = 451, //!< Width of the Image provided by the device (in pixels). + CAP_PROP_XI_HEIGHT = 452, //!< Height of the Image provided by the device (in pixels). + CAP_PROP_XI_REGION_SELECTOR = 589, //!< Selects Region in Multiple ROI which parameters are set by width, height, ... ,region mode. + CAP_PROP_XI_REGION_MODE = 595, //!< Activates/deactivates Region selected by Region Selector. + CAP_PROP_XI_LIMIT_BANDWIDTH = 459, //!< Set/get bandwidth(datarate)(in Megabits). + CAP_PROP_XI_SENSOR_DATA_BIT_DEPTH = 460, //!< Sensor output data bit depth. + CAP_PROP_XI_OUTPUT_DATA_BIT_DEPTH = 461, //!< Device output data bit depth. + CAP_PROP_XI_IMAGE_DATA_BIT_DEPTH = 462, //!< bitdepth of data returned by function xiGetImage. + CAP_PROP_XI_OUTPUT_DATA_PACKING = 463, //!< Device output data packing (or grouping) enabled. Packing could be enabled if output_data_bit_depth > 8 and packing capability is available. + CAP_PROP_XI_OUTPUT_DATA_PACKING_TYPE = 464, //!< Data packing type. Some cameras supports only specific packing type. + CAP_PROP_XI_IS_COOLED = 465, //!< Returns 1 for cameras that support cooling. + CAP_PROP_XI_COOLING = 466, //!< Start camera cooling. + CAP_PROP_XI_TARGET_TEMP = 467, //!< Set sensor target temperature for cooling. + CAP_PROP_XI_CHIP_TEMP = 468, //!< Camera sensor temperature. + CAP_PROP_XI_HOUS_TEMP = 469, //!< Camera housing temperature. + CAP_PROP_XI_HOUS_BACK_SIDE_TEMP = 590, //!< Camera housing back side temperature. + CAP_PROP_XI_SENSOR_BOARD_TEMP = 596, //!< Camera sensor board temperature. + CAP_PROP_XI_CMS = 470, //!< Mode of color management system. + CAP_PROP_XI_APPLY_CMS = 471, //!< Enable applying of CMS profiles to xiGetImage (see XI_PRM_INPUT_CMS_PROFILE, XI_PRM_OUTPUT_CMS_PROFILE). + CAP_PROP_XI_IMAGE_IS_COLOR = 474, //!< Returns 1 for color cameras. + CAP_PROP_XI_COLOR_FILTER_ARRAY = 475, //!< Returns color filter array type of RAW data. + CAP_PROP_XI_GAMMAY = 476, //!< Luminosity gamma. + CAP_PROP_XI_GAMMAC = 477, //!< Chromaticity gamma. + CAP_PROP_XI_SHARPNESS = 478, //!< Sharpness Strength. + CAP_PROP_XI_CC_MATRIX_00 = 479, //!< Color Correction Matrix element [0][0]. + CAP_PROP_XI_CC_MATRIX_01 = 480, //!< Color Correction Matrix element [0][1]. + CAP_PROP_XI_CC_MATRIX_02 = 481, //!< Color Correction Matrix element [0][2]. + CAP_PROP_XI_CC_MATRIX_03 = 482, //!< Color Correction Matrix element [0][3]. + CAP_PROP_XI_CC_MATRIX_10 = 483, //!< Color Correction Matrix element [1][0]. + CAP_PROP_XI_CC_MATRIX_11 = 484, //!< Color Correction Matrix element [1][1]. + CAP_PROP_XI_CC_MATRIX_12 = 485, //!< Color Correction Matrix element [1][2]. + CAP_PROP_XI_CC_MATRIX_13 = 486, //!< Color Correction Matrix element [1][3]. + CAP_PROP_XI_CC_MATRIX_20 = 487, //!< Color Correction Matrix element [2][0]. + CAP_PROP_XI_CC_MATRIX_21 = 488, //!< Color Correction Matrix element [2][1]. + CAP_PROP_XI_CC_MATRIX_22 = 489, //!< Color Correction Matrix element [2][2]. + CAP_PROP_XI_CC_MATRIX_23 = 490, //!< Color Correction Matrix element [2][3]. + CAP_PROP_XI_CC_MATRIX_30 = 491, //!< Color Correction Matrix element [3][0]. + CAP_PROP_XI_CC_MATRIX_31 = 492, //!< Color Correction Matrix element [3][1]. + CAP_PROP_XI_CC_MATRIX_32 = 493, //!< Color Correction Matrix element [3][2]. + CAP_PROP_XI_CC_MATRIX_33 = 494, //!< Color Correction Matrix element [3][3]. + CAP_PROP_XI_DEFAULT_CC_MATRIX = 495, //!< Set default Color Correction Matrix. + CAP_PROP_XI_TRG_SELECTOR = 498, //!< Selects the type of trigger. + CAP_PROP_XI_ACQ_FRAME_BURST_COUNT = 499, //!< Sets number of frames acquired by burst. This burst is used only if trigger is set to FrameBurstStart. + CAP_PROP_XI_DEBOUNCE_EN = 507, //!< Enable/Disable debounce to selected GPI. + CAP_PROP_XI_DEBOUNCE_T0 = 508, //!< Debounce time (x * 10us). + CAP_PROP_XI_DEBOUNCE_T1 = 509, //!< Debounce time (x * 10us). + CAP_PROP_XI_DEBOUNCE_POL = 510, //!< Debounce polarity (pol = 1 t0 - falling edge, t1 - rising edge). + CAP_PROP_XI_LENS_MODE = 511, //!< Status of lens control interface. This shall be set to XI_ON before any Lens operations. + CAP_PROP_XI_LENS_APERTURE_VALUE = 512, //!< Current lens aperture value in stops. Examples: 2.8, 4, 5.6, 8, 11. + CAP_PROP_XI_LENS_FOCUS_MOVEMENT_VALUE = 513, //!< Lens current focus movement value to be used by XI_PRM_LENS_FOCUS_MOVE in motor steps. + CAP_PROP_XI_LENS_FOCUS_MOVE = 514, //!< Moves lens focus motor by steps set in XI_PRM_LENS_FOCUS_MOVEMENT_VALUE. + CAP_PROP_XI_LENS_FOCUS_DISTANCE = 515, //!< Lens focus distance in cm. + CAP_PROP_XI_LENS_FOCAL_LENGTH = 516, //!< Lens focal distance in mm. + CAP_PROP_XI_LENS_FEATURE_SELECTOR = 517, //!< Selects the current feature which is accessible by XI_PRM_LENS_FEATURE. + CAP_PROP_XI_LENS_FEATURE = 518, //!< Allows access to lens feature value currently selected by XI_PRM_LENS_FEATURE_SELECTOR. + CAP_PROP_XI_DEVICE_MODEL_ID = 521, //!< Returns device model id. + CAP_PROP_XI_DEVICE_SN = 522, //!< Returns device serial number. + CAP_PROP_XI_IMAGE_DATA_FORMAT_RGB32_ALPHA = 529, //!< The alpha channel of RGB32 output image format. + CAP_PROP_XI_IMAGE_PAYLOAD_SIZE = 530, //!< Buffer size in bytes sufficient for output image returned by xiGetImage. + CAP_PROP_XI_TRANSPORT_PIXEL_FORMAT = 531, //!< Current format of pixels on transport layer. + CAP_PROP_XI_SENSOR_CLOCK_FREQ_HZ = 532, //!< Sensor clock frequency in Hz. + CAP_PROP_XI_SENSOR_CLOCK_FREQ_INDEX = 533, //!< Sensor clock frequency index. Sensor with selected frequencies have possibility to set the frequency only by this index. + CAP_PROP_XI_SENSOR_OUTPUT_CHANNEL_COUNT = 534, //!< Number of output channels from sensor used for data transfer. + CAP_PROP_XI_FRAMERATE = 535, //!< Define framerate in Hz. + CAP_PROP_XI_COUNTER_SELECTOR = 536, //!< Select counter. + CAP_PROP_XI_COUNTER_VALUE = 537, //!< Counter status. + CAP_PROP_XI_ACQ_TIMING_MODE = 538, //!< Type of sensor frames timing. + CAP_PROP_XI_AVAILABLE_BANDWIDTH = 539, //!< Calculate and returns available interface bandwidth(int Megabits). + CAP_PROP_XI_BUFFER_POLICY = 540, //!< Data move policy. + CAP_PROP_XI_LUT_EN = 541, //!< Activates LUT. + CAP_PROP_XI_LUT_INDEX = 542, //!< Control the index (offset) of the coefficient to access in the LUT. + CAP_PROP_XI_LUT_VALUE = 543, //!< Value at entry LUTIndex of the LUT. + CAP_PROP_XI_TRG_DELAY = 544, //!< Specifies the delay in microseconds (us) to apply after the trigger reception before activating it. + CAP_PROP_XI_TS_RST_MODE = 545, //!< Defines how time stamp reset engine will be armed. + CAP_PROP_XI_TS_RST_SOURCE = 546, //!< Defines which source will be used for timestamp reset. Writing this parameter will trigger settings of engine (arming). + CAP_PROP_XI_IS_DEVICE_EXIST = 547, //!< Returns 1 if camera connected and works properly. + CAP_PROP_XI_ACQ_BUFFER_SIZE = 548, //!< Acquisition buffer size in buffer_size_unit. Default bytes. + CAP_PROP_XI_ACQ_BUFFER_SIZE_UNIT = 549, //!< Acquisition buffer size unit in bytes. Default 1. E.g. Value 1024 means that buffer_size is in KiBytes. + CAP_PROP_XI_ACQ_TRANSPORT_BUFFER_SIZE = 550, //!< Acquisition transport buffer size in bytes. + CAP_PROP_XI_BUFFERS_QUEUE_SIZE = 551, //!< Queue of field/frame buffers. + CAP_PROP_XI_ACQ_TRANSPORT_BUFFER_COMMIT = 552, //!< Number of buffers to commit to low level. + CAP_PROP_XI_RECENT_FRAME = 553, //!< GetImage returns most recent frame. + CAP_PROP_XI_DEVICE_RESET = 554, //!< Resets the camera to default state. + CAP_PROP_XI_COLUMN_FPN_CORRECTION = 555, //!< Correction of column FPN. + CAP_PROP_XI_ROW_FPN_CORRECTION = 591, //!< Correction of row FPN. + CAP_PROP_XI_SENSOR_MODE = 558, //!< Current sensor mode. Allows to select sensor mode by one integer. Setting of this parameter affects: image dimensions and downsampling. + CAP_PROP_XI_HDR = 559, //!< Enable High Dynamic Range feature. + CAP_PROP_XI_HDR_KNEEPOINT_COUNT = 560, //!< The number of kneepoints in the PWLR. + CAP_PROP_XI_HDR_T1 = 561, //!< Position of first kneepoint(in % of XI_PRM_EXPOSURE). + CAP_PROP_XI_HDR_T2 = 562, //!< Position of second kneepoint (in % of XI_PRM_EXPOSURE). + CAP_PROP_XI_KNEEPOINT1 = 563, //!< Value of first kneepoint (% of sensor saturation). + CAP_PROP_XI_KNEEPOINT2 = 564, //!< Value of second kneepoint (% of sensor saturation). + CAP_PROP_XI_IMAGE_BLACK_LEVEL = 565, //!< Last image black level counts. Can be used for Offline processing to recall it. + CAP_PROP_XI_HW_REVISION = 571, //!< Returns hardware revision number. + CAP_PROP_XI_DEBUG_LEVEL = 572, //!< Set debug level. + CAP_PROP_XI_AUTO_BANDWIDTH_CALCULATION = 573, //!< Automatic bandwidth calculation. + CAP_PROP_XI_FFS_FILE_ID = 594, //!< File number. + CAP_PROP_XI_FFS_FILE_SIZE = 580, //!< Size of file. + CAP_PROP_XI_FREE_FFS_SIZE = 581, //!< Size of free camera FFS. + CAP_PROP_XI_USED_FFS_SIZE = 582, //!< Size of used camera FFS. + CAP_PROP_XI_FFS_ACCESS_KEY = 583, //!< Setting of key enables file operations on some cameras. + CAP_PROP_XI_SENSOR_FEATURE_SELECTOR = 585, //!< Selects the current feature which is accessible by XI_PRM_SENSOR_FEATURE_VALUE. + CAP_PROP_XI_SENSOR_FEATURE_VALUE = 586, //!< Allows access to sensor feature value currently selected by XI_PRM_SENSOR_FEATURE_SELECTOR. + }; + +//! @} XIMEA + +/** @name AVFoundation framework for iOS + OS X Lion will have the same API + @{ +*/ + +//! Properties of cameras available through AVFOUNDATION backend +enum { CAP_PROP_IOS_DEVICE_FOCUS = 9001, + CAP_PROP_IOS_DEVICE_EXPOSURE = 9002, + CAP_PROP_IOS_DEVICE_FLASH = 9003, + CAP_PROP_IOS_DEVICE_WHITEBALANCE = 9004, + CAP_PROP_IOS_DEVICE_TORCH = 9005 + }; + +/** @name Smartek Giganetix GigEVisionSDK + @{ +*/ + +//! Properties of cameras available through Smartek Giganetix Ethernet Vision backend +/* --- Vladimir Litvinenko (litvinenko.vladimir@gmail.com) --- */ +enum { CAP_PROP_GIGA_FRAME_OFFSET_X = 10001, + CAP_PROP_GIGA_FRAME_OFFSET_Y = 10002, + CAP_PROP_GIGA_FRAME_WIDTH_MAX = 10003, + CAP_PROP_GIGA_FRAME_HEIGH_MAX = 10004, + CAP_PROP_GIGA_FRAME_SENS_WIDTH = 10005, + CAP_PROP_GIGA_FRAME_SENS_HEIGH = 10006 + }; + +//! @} Smartek + +/** @name Intel Perceptual Computing SDK + @{ +*/ +enum { CAP_PROP_INTELPERC_PROFILE_COUNT = 11001, + CAP_PROP_INTELPERC_PROFILE_IDX = 11002, + CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE = 11003, + CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE = 11004, + CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD = 11005, + CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ = 11006, + CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT = 11007 + }; + +//! Intel Perceptual Streams +enum { CAP_INTELPERC_DEPTH_GENERATOR = 1 << 29, + CAP_INTELPERC_IMAGE_GENERATOR = 1 << 28, + CAP_INTELPERC_IR_GENERATOR = 1 << 27, + CAP_INTELPERC_GENERATORS_MASK = CAP_INTELPERC_DEPTH_GENERATOR + CAP_INTELPERC_IMAGE_GENERATOR + CAP_INTELPERC_IR_GENERATOR + }; + +enum { CAP_INTELPERC_DEPTH_MAP = 0, //!< Each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth. + CAP_INTELPERC_UVDEPTH_MAP = 1, //!< Each pixel contains two 32-bit floating point values in the range of 0-1, representing the mapping of depth coordinates to the color coordinates. + CAP_INTELPERC_IR_MAP = 2, //!< Each pixel is a 16-bit integer. The value indicates the intensity of the reflected laser beam. + CAP_INTELPERC_IMAGE = 3 + }; + +//! @} Intel Perceptual + +/** @name gPhoto2 connection + @{ +*/ + +/** @brief gPhoto2 properties + +If `propertyId` is less than 0 then work on widget with that __additive inversed__ camera setting ID +Get IDs by using CAP_PROP_GPHOTO2_WIDGET_ENUMERATE. +@see CvCaptureCAM_GPHOTO2 for more info +*/ +enum { CAP_PROP_GPHOTO2_PREVIEW = 17001, //!< Capture only preview from liveview mode. + CAP_PROP_GPHOTO2_WIDGET_ENUMERATE = 17002, //!< Readonly, returns (const char *). + CAP_PROP_GPHOTO2_RELOAD_CONFIG = 17003, //!< Trigger, only by set. Reload camera settings. + CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE = 17004, //!< Reload all settings on set. + CAP_PROP_GPHOTO2_COLLECT_MSGS = 17005, //!< Collect messages with details. + CAP_PROP_GPHOTO2_FLUSH_MSGS = 17006, //!< Readonly, returns (const char *). + CAP_PROP_SPEED = 17007, //!< Exposure speed. Can be readonly, depends on camera program. + CAP_PROP_APERTURE = 17008, //!< Aperture. Can be readonly, depends on camera program. + CAP_PROP_EXPOSUREPROGRAM = 17009, //!< Camera exposure program. + CAP_PROP_VIEWFINDER = 17010 //!< Enter liveview mode. + }; + +//! @} gPhoto2 + + +/** @name Images backend + @{ +*/ + +/** @brief Images backend properties + +*/ +enum { CAP_PROP_IMAGES_BASE = 18000, + CAP_PROP_IMAGES_LAST = 19000 // excluding + }; + +//! @} Images + +//! @} videoio_flags_others + + +class IVideoCapture; + +/** @brief Class for video capturing from video files, image sequences or cameras. + +The class provides C++ API for capturing video from cameras or for reading video files and image sequences. + +Here is how the class can be used: +@include samples/cpp/videocapture_basic.cpp + +@note In @ref videoio_c "C API" the black-box structure `CvCapture` is used instead of %VideoCapture. +@note +- (C++) A basic sample on using the %VideoCapture interface can be found at + `OPENCV_SOURCE_CODE/samples/cpp/videocapture_starter.cpp` +- (Python) A basic sample on using the %VideoCapture interface can be found at + `OPENCV_SOURCE_CODE/samples/python/video.py` +- (Python) A multi threaded video processing sample can be found at + `OPENCV_SOURCE_CODE/samples/python/video_threaded.py` +- (Python) %VideoCapture sample showcasing some features of the Video4Linux2 backend + `OPENCV_SOURCE_CODE/samples/python/video_v4l2.py` + */ +class CV_EXPORTS_W VideoCapture +{ +public: + /** @brief Default constructor + @note In @ref videoio_c "C API", when you finished working with video, release CvCapture structure with + cvReleaseCapture(), or use Ptr\ that calls cvReleaseCapture() automatically in the + destructor. + */ + CV_WRAP VideoCapture(); + + /** @overload + @brief Opens a video file or a capturing device or an IP video stream for video capturing with API Preference + + @param filename it can be: + - name of video file (eg. `video.avi`) + - or image sequence (eg. `img_%02d.jpg`, which will read samples like `img_00.jpg, img_01.jpg, img_02.jpg, ...`) + - or URL of video stream (eg. `protocol://host:port/script_name?script_params|auth`). + Note that each video stream or IP camera feed has its own URL scheme. Please refer to the + documentation of source stream to know the right URL. + @param apiPreference preferred Capture API backends to use. Can be used to enforce a specific reader + implementation if multiple are available: e.g. cv::CAP_FFMPEG or cv::CAP_IMAGES or cv::CAP_DSHOW. + @sa The list of supported API backends cv::VideoCaptureAPIs + */ + CV_WRAP VideoCapture(const String& filename, int apiPreference = CAP_ANY); + + /** @overload + @brief Opens a camera for video capturing + + @param index id of the video capturing device to open. To open default camera using default backend just pass 0. + (to backward compatibility usage of camera_id + domain_offset (CAP_*) is valid when apiPreference is CAP_ANY) + @param apiPreference preferred Capture API backends to use. Can be used to enforce a specific reader + implementation if multiple are available: e.g. cv::CAP_DSHOW or cv::CAP_MSMF or cv::CAP_V4L. + + @sa The list of supported API backends cv::VideoCaptureAPIs + */ + CV_WRAP VideoCapture(int index, int apiPreference = CAP_ANY); + + /** @brief Default destructor + + The method first calls VideoCapture::release to close the already opened file or camera. + */ + virtual ~VideoCapture(); + + /** @brief Opens a video file or a capturing device or an IP video stream for video capturing. + + @overload + + Parameters are same as the constructor VideoCapture(const String& filename, int apiPreference = CAP_ANY) + @return `true` if the file has been successfully opened + + The method first calls VideoCapture::release to close the already opened file or camera. + */ + CV_WRAP virtual bool open(const String& filename, int apiPreference = CAP_ANY); + + /** @brief Opens a camera for video capturing + + @overload + + Parameters are same as the constructor VideoCapture(int index, int apiPreference = CAP_ANY) + @return `true` if the camera has been successfully opened. + + The method first calls VideoCapture::release to close the already opened file or camera. + */ + CV_WRAP virtual bool open(int index, int apiPreference = CAP_ANY); + + /** @brief Returns true if video capturing has been initialized already. + + If the previous call to VideoCapture constructor or VideoCapture::open() succeeded, the method returns + true. + */ + CV_WRAP virtual bool isOpened() const; + + /** @brief Closes video file or capturing device. + + The method is automatically called by subsequent VideoCapture::open and by VideoCapture + destructor. + + The C function also deallocates memory and clears \*capture pointer. + */ + CV_WRAP virtual void release(); + + /** @brief Grabs the next frame from video file or capturing device. + + @return `true` (non-zero) in the case of success. + + The method/function grabs the next frame from video file or camera and returns 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 + VideoCapture::retrieve() one or more times with different values of the channel parameter. + + @ref tutorial_kinect_openni + */ + CV_WRAP virtual bool grab(); + + /** @brief Decodes and returns the grabbed video frame. + + @param [out] image the video frame is returned here. If no frames has been grabbed the image will be empty. + @param flag it could be a frame index or a driver specific flag + @return `false` if no frames has been grabbed + + The method decodes and returns the just grabbed frame. If no frames has been grabbed + (camera has been disconnected, or there are no more frames in video file), the method returns false + and the function returns an empty image (with %cv::Mat, test it with Mat::empty()). + + @sa read() + + @note In @ref videoio_c "C API", 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 + cvCloneImage and then do whatever you want with the copy. + */ + CV_WRAP virtual bool retrieve(OutputArray image, int flag = 0); + + /** @brief Stream operator to read the next video frame. + @sa read() + */ + virtual VideoCapture& operator >> (CV_OUT Mat& image); + + /** @overload + @sa read() + */ + virtual VideoCapture& operator >> (CV_OUT UMat& image); + + /** @brief Grabs, decodes and returns the next video frame. + + @param [out] image the video frame is returned here. If no frames has been grabbed the image will be empty. + @return `false` if no frames has been grabbed + + The method/function combines VideoCapture::grab() and VideoCapture::retrieve() in one call. This is the + most convenient method for reading video files or capturing data from decode and returns the just + grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more + frames in video file), the method returns false and the function returns empty image (with %cv::Mat, test it with Mat::empty()). + + @note In @ref videoio_c "C API", 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 + cvCloneImage and then do whatever you want with the copy. + */ + CV_WRAP virtual bool read(OutputArray image); + + /** @brief Sets a property in the VideoCapture. + + @param propId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...) + or one from @ref videoio_flags_others + @param value Value of the property. + @return `true` if the property is supported by backend used by the VideoCapture instance. + @note Even if it returns `true` this doesn't ensure that the property + value has been accepted by the capture device. See note in VideoCapture::get() + */ + CV_WRAP virtual bool set(int propId, double value); + + /** @brief Returns the specified VideoCapture property + + @param propId Property identifier from cv::VideoCaptureProperties (eg. cv::CAP_PROP_POS_MSEC, cv::CAP_PROP_POS_FRAMES, ...) + or one from @ref videoio_flags_others + @return Value for the specified property. Value 0 is returned when querying a property that is + not supported by the backend used by the VideoCapture instance. + + @note Reading / writing properties involves many layers. Some unexpected result might happens + along this chain. + @code{.txt} + VideoCapture -> API Backend -> Operating System -> Device Driver -> Device Hardware + @endcode + The returned value might be different from what really used by the device or it could be encoded + using device dependent rules (eg. steps or percentage). Effective behaviour depends from device + driver and API Backend + + */ + CV_WRAP virtual double get(int propId) const; + + /** @brief Returns used backend API name + + @note Stream should be opened. + */ + CV_WRAP String getBackendName() const; + + /** Switches exceptions mode + * + * methods raise exceptions if not successful instead of returning an error code + */ + CV_WRAP void setExceptionMode(bool enable) { throwOnFail = enable; } + + /// query if exception mode is active + CV_WRAP bool getExceptionMode() { return throwOnFail; } +protected: + Ptr cap; + Ptr icap; + bool throwOnFail; +}; + +class IVideoWriter; + +/** @example samples/cpp/tutorial_code/videoio/video-write/video-write.cpp +Check @ref tutorial_video_write "the corresponding tutorial" for more details +*/ + +/** @example samples/cpp/videowriter_basic.cpp +An example using VideoCapture and VideoWriter class +*/ + +/** @brief Video writer class. + +The class provides C++ API for writing video files or image sequences. +*/ +class CV_EXPORTS_W VideoWriter +{ +public: + /** @brief Default constructors + + The constructors/functions initialize video writers. + - On Linux FFMPEG is used to write videos; + - On Windows FFMPEG or MSWF or DSHOW is used; + - On MacOSX AVFoundation is used. + */ + CV_WRAP VideoWriter(); + + /** @overload + @param filename Name of the output video file. + @param fourcc 4-character code of codec used to compress the frames. For example, + VideoWriter::fourcc('P','I','M','1') is a MPEG-1 codec, VideoWriter::fourcc('M','J','P','G') is a + motion-jpeg codec etc. List of codes can be obtained at [Video Codecs by + FOURCC](http://www.fourcc.org/codecs.php) page. FFMPEG backend with MP4 container natively uses + other values as fourcc code: see [ObjectType](http://www.mp4ra.org/codecs.html), + so you may receive a warning message from OpenCV about fourcc code conversion. + @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). + + @b Tips: + - With some backends `fourcc=-1` pops up the codec selection dialog from the system. + - To save image sequence use a proper filename (eg. `img_%02d.jpg`) and `fourcc=0` + OR `fps=0`. Use uncompressed image format (eg. `img_%02d.BMP`) to save raw frames. + - Most codecs are lossy. If you want lossless video file you need to use a lossless codecs + (eg. FFMPEG FFV1, Huffman HFYU, Lagarith LAGS, etc...) + - If FFMPEG is enabled, using `codec=0; fps=0;` you can create an uncompressed (raw) video file. + */ + CV_WRAP VideoWriter(const String& filename, int fourcc, double fps, + Size frameSize, bool isColor = true); + + /** @overload + The `apiPreference` parameter allows to specify API backends to use. Can be used to enforce a specific reader implementation + if multiple are available: e.g. cv::CAP_FFMPEG or cv::CAP_GSTREAMER. + */ + CV_WRAP VideoWriter(const String& filename, int apiPreference, int fourcc, double fps, + Size frameSize, bool isColor = true); + + /** @brief Default destructor + + The method first calls VideoWriter::release to close the already opened file. + */ + virtual ~VideoWriter(); + + /** @brief Initializes or reinitializes video writer. + + The method opens video writer. Parameters are the same as in the constructor + VideoWriter::VideoWriter. + @return `true` if video writer has been successfully initialized + + The method first calls VideoWriter::release to close the already opened file. + */ + CV_WRAP virtual bool open(const String& filename, int fourcc, double fps, + Size frameSize, bool isColor = true); + + /** @overload + */ + CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps, + Size frameSize, bool isColor = true); + + /** @brief Returns true if video writer has been successfully initialized. + */ + CV_WRAP virtual bool isOpened() const; + + /** @brief Closes the video writer. + + The method is automatically called by subsequent VideoWriter::open and by the VideoWriter + destructor. + */ + CV_WRAP virtual void release(); + + /** @brief Stream operator to write the next video frame. + @sa write + */ + virtual VideoWriter& operator << (const Mat& image); + + /** @overload + @sa write + */ + virtual VideoWriter& operator << (const UMat& image); + + /** @brief Writes the next video frame + + @param image The written frame. In general, color images are expected in BGR format. + + The function/method writes the specified image to video file. It must have the same size as has + been specified when opening the video writer. + */ + CV_WRAP virtual void write(InputArray image); + + /** @brief Sets a property in the VideoWriter. + + @param propId Property identifier from cv::VideoWriterProperties (eg. cv::VIDEOWRITER_PROP_QUALITY) + or one of @ref videoio_flags_others + + @param value Value of the property. + @return `true` if the property is supported by the backend used by the VideoWriter instance. + */ + CV_WRAP virtual bool set(int propId, double value); + + /** @brief Returns the specified VideoWriter property + + @param propId Property identifier from cv::VideoWriterProperties (eg. cv::VIDEOWRITER_PROP_QUALITY) + or one of @ref videoio_flags_others + + @return Value for the specified property. Value 0 is returned when querying a property that is + not supported by the backend used by the VideoWriter instance. + */ + CV_WRAP virtual double get(int propId) const; + + /** @brief Concatenates 4 chars to a fourcc code + + @return a fourcc code + + This static method constructs the fourcc code of the codec to be used in the constructor + VideoWriter::VideoWriter or VideoWriter::open. + */ + CV_WRAP static int fourcc(char c1, char c2, char c3, char c4); + + /** @brief Returns used backend API name + + @note Stream should be opened. + */ + CV_WRAP String getBackendName() const; + +protected: + Ptr writer; + Ptr iwriter; + + static Ptr create(const String& filename, int fourcc, double fps, + Size frameSize, bool isColor = true); +}; + +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(CvCapture* obj) const; }; +template<> struct DefaultDeleter{ CV_EXPORTS void operator ()(CvVideoWriter* obj) const; }; + +//! @} videoio + +} // cv + +#endif //OPENCV_VIDEOIO_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/videoio/cap_ios.h b/Prj-Win/3rd/opencv/include/opencv2/videoio/cap_ios.h new file mode 100755 index 0000000..207ad46 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/videoio/cap_ios.h @@ -0,0 +1,150 @@ +/* For iOS video I/O + * by Eduard Feicho on 29/07/12 + * Copyright 2012. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#import +#import +#import +#include "opencv2/core.hpp" + +//! @addtogroup videoio_ios +//! @{ + +/////////////////////////////////////// CvAbstractCamera ///////////////////////////////////// + +@class CvAbstractCamera; + +CV_EXPORTS @interface CvAbstractCamera : NSObject +{ + UIDeviceOrientation currentDeviceOrientation; + + BOOL cameraAvailable; +} + +@property (nonatomic, strong) AVCaptureSession* captureSession; +@property (nonatomic, strong) AVCaptureConnection* videoCaptureConnection; + +@property (nonatomic, readonly) BOOL running; +@property (nonatomic, readonly) BOOL captureSessionLoaded; + +@property (nonatomic, assign) int defaultFPS; +@property (nonatomic, readonly) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer; +@property (nonatomic, assign) AVCaptureDevicePosition defaultAVCaptureDevicePosition; +@property (nonatomic, assign) AVCaptureVideoOrientation defaultAVCaptureVideoOrientation; +@property (nonatomic, assign) BOOL useAVCaptureVideoPreviewLayer; +@property (nonatomic, strong) NSString *const defaultAVCaptureSessionPreset; + +@property (nonatomic, assign) int imageWidth; +@property (nonatomic, assign) int imageHeight; + +@property (nonatomic, strong) UIView* parentView; + +- CV_UNUSED(start); +- CV_UNUSED(stop); +- CV_UNUSED(switchCameras); + +- (id)initWithParentView:(UIView*)parent; + +- CV_UNUSED(createCaptureOutput); +- CV_UNUSED(createVideoPreviewLayer); +- CV_UNUSED(updateOrientation); + +- CV_UNUSED(lockFocus); +- CV_UNUSED(unlockFocus); +- CV_UNUSED(lockExposure); +- CV_UNUSED(unlockExposure); +- CV_UNUSED(lockBalance); +- CV_UNUSED(unlockBalance); + +@end + +///////////////////////////////// CvVideoCamera /////////////////////////////////////////// + +@class CvVideoCamera; + +CV_EXPORTS @protocol CvVideoCameraDelegate + +#ifdef __cplusplus +// delegate method for processing image frames +- (void)processImage:(cv::Mat&)image; +#endif + +@end + +CV_EXPORTS @interface CvVideoCamera : CvAbstractCamera +{ + AVCaptureVideoDataOutput *videoDataOutput; + + dispatch_queue_t videoDataOutputQueue; + CALayer *customPreviewLayer; + + CMTime lastSampleTime; + +} + +@property (nonatomic, weak) id delegate; +@property (nonatomic, assign) BOOL grayscaleMode; + +@property (nonatomic, assign) BOOL recordVideo; +@property (nonatomic, assign) BOOL rotateVideo; +@property (nonatomic, strong) AVAssetWriterInput* recordAssetWriterInput; +@property (nonatomic, strong) AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor; +@property (nonatomic, strong) AVAssetWriter* recordAssetWriter; + +- (void)adjustLayoutToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; +- CV_UNUSED(layoutPreviewLayer); +- CV_UNUSED(saveVideo); +- (NSURL *)videoFileURL; +- (NSString *)videoFileString; + + +@end + +///////////////////////////////// CvPhotoCamera /////////////////////////////////////////// + +@class CvPhotoCamera; + +CV_EXPORTS @protocol CvPhotoCameraDelegate + +- (void)photoCamera:(CvPhotoCamera*)photoCamera capturedImage:(UIImage *)image; +- (void)photoCameraCancel:(CvPhotoCamera*)photoCamera; + +@end + +CV_EXPORTS @interface CvPhotoCamera : CvAbstractCamera +{ + AVCaptureStillImageOutput *stillImageOutput; +} + +@property (nonatomic, weak) id delegate; + +- CV_UNUSED(takePicture); + +@end + +//! @} videoio_ios diff --git a/Prj-Win/3rd/opencv/include/opencv2/videoio/legacy/constants_c.h b/Prj-Win/3rd/opencv/include/opencv2/videoio/legacy/constants_c.h new file mode 100755 index 0000000..4445002 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/videoio/legacy/constants_c.h @@ -0,0 +1,434 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_VIDEOIO_LEGACY_CONSTANTS_H +#define OPENCV_VIDEOIO_LEGACY_CONSTANTS_H + +enum +{ + CV_CAP_ANY =0, // autodetect + + CV_CAP_MIL =100, // MIL proprietary drivers + + CV_CAP_VFW =200, // platform native + CV_CAP_V4L =200, + CV_CAP_V4L2 =200, + + CV_CAP_FIREWARE =300, // IEEE 1394 drivers + CV_CAP_FIREWIRE =300, + CV_CAP_IEEE1394 =300, + CV_CAP_DC1394 =300, + CV_CAP_CMU1394 =300, + + CV_CAP_STEREO =400, // TYZX proprietary drivers + CV_CAP_TYZX =400, + CV_TYZX_LEFT =400, + CV_TYZX_RIGHT =401, + CV_TYZX_COLOR =402, + CV_TYZX_Z =403, + + CV_CAP_QT =500, // QuickTime + + CV_CAP_UNICAP =600, // Unicap drivers + + CV_CAP_DSHOW =700, // DirectShow (via videoInput) + CV_CAP_MSMF =1400, // Microsoft Media Foundation (via videoInput) + + CV_CAP_PVAPI =800, // PvAPI, Prosilica GigE SDK + + CV_CAP_OPENNI =900, // OpenNI (for Kinect) + CV_CAP_OPENNI_ASUS =910, // OpenNI (for Asus Xtion) + + CV_CAP_ANDROID =1000, // Android - not used + CV_CAP_ANDROID_BACK =CV_CAP_ANDROID+99, // Android back camera - not used + CV_CAP_ANDROID_FRONT =CV_CAP_ANDROID+98, // Android front camera - not used + + CV_CAP_XIAPI =1100, // XIMEA Camera API + + CV_CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API) + + CV_CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK + + CV_CAP_INTELPERC = 1500, // Intel Perceptual Computing + + CV_CAP_OPENNI2 = 1600, // OpenNI2 (for Kinect) + CV_CAP_GPHOTO2 = 1700, + CV_CAP_GSTREAMER = 1800, // GStreamer + CV_CAP_FFMPEG = 1900, // FFMPEG + CV_CAP_IMAGES = 2000, // OpenCV Image Sequence (e.g. img_%02d.jpg) + + CV_CAP_ARAVIS = 2100 // Aravis GigE SDK +}; + +enum +{ + // modes of the controlling registers (can be: auto, manual, auto single push, absolute Latter allowed with any other mode) + // every feature can have only one mode turned on at a time + CV_CAP_PROP_DC1394_OFF = -4, //turn the feature off (not controlled manually nor automatically) + CV_CAP_PROP_DC1394_MODE_MANUAL = -3, //set automatically when a value of the feature is set by the user + CV_CAP_PROP_DC1394_MODE_AUTO = -2, + CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO = -1, + CV_CAP_PROP_POS_MSEC =0, + CV_CAP_PROP_POS_FRAMES =1, + CV_CAP_PROP_POS_AVI_RATIO =2, + CV_CAP_PROP_FRAME_WIDTH =3, + CV_CAP_PROP_FRAME_HEIGHT =4, + CV_CAP_PROP_FPS =5, + CV_CAP_PROP_FOURCC =6, + CV_CAP_PROP_FRAME_COUNT =7, + CV_CAP_PROP_FORMAT =8, + CV_CAP_PROP_MODE =9, + CV_CAP_PROP_BRIGHTNESS =10, + CV_CAP_PROP_CONTRAST =11, + CV_CAP_PROP_SATURATION =12, + CV_CAP_PROP_HUE =13, + CV_CAP_PROP_GAIN =14, + CV_CAP_PROP_EXPOSURE =15, + CV_CAP_PROP_CONVERT_RGB =16, + CV_CAP_PROP_WHITE_BALANCE_BLUE_U =17, + CV_CAP_PROP_RECTIFICATION =18, + CV_CAP_PROP_MONOCHROME =19, + CV_CAP_PROP_SHARPNESS =20, + CV_CAP_PROP_AUTO_EXPOSURE =21, // exposure control done by camera, + // user can adjust reference level + // using this feature + CV_CAP_PROP_GAMMA =22, + CV_CAP_PROP_TEMPERATURE =23, + CV_CAP_PROP_TRIGGER =24, + CV_CAP_PROP_TRIGGER_DELAY =25, + CV_CAP_PROP_WHITE_BALANCE_RED_V =26, + CV_CAP_PROP_ZOOM =27, + CV_CAP_PROP_FOCUS =28, + CV_CAP_PROP_GUID =29, + CV_CAP_PROP_ISO_SPEED =30, + CV_CAP_PROP_MAX_DC1394 =31, + CV_CAP_PROP_BACKLIGHT =32, + CV_CAP_PROP_PAN =33, + CV_CAP_PROP_TILT =34, + CV_CAP_PROP_ROLL =35, + CV_CAP_PROP_IRIS =36, + CV_CAP_PROP_SETTINGS =37, + CV_CAP_PROP_BUFFERSIZE =38, + CV_CAP_PROP_AUTOFOCUS =39, + CV_CAP_PROP_SAR_NUM =40, + CV_CAP_PROP_SAR_DEN =41, + + CV_CAP_PROP_AUTOGRAB =1024, // property for videoio class CvCapture_Android only + CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING=1025, // readonly, tricky property, returns cpnst char* indeed + CV_CAP_PROP_PREVIEW_FORMAT=1026, // readonly, tricky property, returns cpnst char* indeed + + // OpenNI map generators + CV_CAP_OPENNI_DEPTH_GENERATOR = 1 << 31, + CV_CAP_OPENNI_IMAGE_GENERATOR = 1 << 30, + CV_CAP_OPENNI_IR_GENERATOR = 1 << 29, + CV_CAP_OPENNI_GENERATORS_MASK = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_OPENNI_IR_GENERATOR, + + // Properties of cameras available through OpenNI interfaces + CV_CAP_PROP_OPENNI_OUTPUT_MODE = 100, + CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH = 101, // in mm + CV_CAP_PROP_OPENNI_BASELINE = 102, // in mm + CV_CAP_PROP_OPENNI_FOCAL_LENGTH = 103, // in pixels + CV_CAP_PROP_OPENNI_REGISTRATION = 104, // flag + CV_CAP_PROP_OPENNI_REGISTRATION_ON = CV_CAP_PROP_OPENNI_REGISTRATION, // flag that synchronizes the remapping depth map to image map + // by changing depth generator's view point (if the flag is "on") or + // sets this view point to its normal one (if the flag is "off"). + CV_CAP_PROP_OPENNI_APPROX_FRAME_SYNC = 105, + CV_CAP_PROP_OPENNI_MAX_BUFFER_SIZE = 106, + CV_CAP_PROP_OPENNI_CIRCLE_BUFFER = 107, + CV_CAP_PROP_OPENNI_MAX_TIME_DURATION = 108, + + CV_CAP_PROP_OPENNI_GENERATOR_PRESENT = 109, + CV_CAP_PROP_OPENNI2_SYNC = 110, + CV_CAP_PROP_OPENNI2_MIRROR = 111, + + CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT = CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_PROP_OPENNI_GENERATOR_PRESENT, + CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE = CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_PROP_OPENNI_OUTPUT_MODE, + CV_CAP_OPENNI_DEPTH_GENERATOR_PRESENT = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_GENERATOR_PRESENT, + CV_CAP_OPENNI_DEPTH_GENERATOR_BASELINE = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_BASELINE, + CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_FOCAL_LENGTH, + CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_REGISTRATION, + CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION_ON = CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION, + CV_CAP_OPENNI_IR_GENERATOR_PRESENT = CV_CAP_OPENNI_IR_GENERATOR + CV_CAP_PROP_OPENNI_GENERATOR_PRESENT, + + // Properties of cameras available through GStreamer interface + CV_CAP_GSTREAMER_QUEUE_LENGTH = 200, // default is 1 + + // PVAPI + CV_CAP_PROP_PVAPI_MULTICASTIP = 300, // ip for anable multicast master mode. 0 for disable multicast + CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE = 301, // FrameStartTriggerMode: Determines how a frame is initiated + CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL = 302, // Horizontal sub-sampling of the image + CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL = 303, // Vertical sub-sampling of the image + CV_CAP_PROP_PVAPI_BINNINGX = 304, // Horizontal binning factor + CV_CAP_PROP_PVAPI_BINNINGY = 305, // Vertical binning factor + CV_CAP_PROP_PVAPI_PIXELFORMAT = 306, // Pixel format + + // Properties of cameras available through XIMEA SDK interface + CV_CAP_PROP_XI_DOWNSAMPLING = 400, // Change image resolution by binning or skipping. + CV_CAP_PROP_XI_DATA_FORMAT = 401, // Output data format. + CV_CAP_PROP_XI_OFFSET_X = 402, // Horizontal offset from the origin to the area of interest (in pixels). + CV_CAP_PROP_XI_OFFSET_Y = 403, // Vertical offset from the origin to the area of interest (in pixels). + CV_CAP_PROP_XI_TRG_SOURCE = 404, // Defines source of trigger. + CV_CAP_PROP_XI_TRG_SOFTWARE = 405, // Generates an internal trigger. PRM_TRG_SOURCE must be set to TRG_SOFTWARE. + CV_CAP_PROP_XI_GPI_SELECTOR = 406, // Selects general purpose input + CV_CAP_PROP_XI_GPI_MODE = 407, // Set general purpose input mode + CV_CAP_PROP_XI_GPI_LEVEL = 408, // Get general purpose level + CV_CAP_PROP_XI_GPO_SELECTOR = 409, // Selects general purpose output + CV_CAP_PROP_XI_GPO_MODE = 410, // Set general purpose output mode + CV_CAP_PROP_XI_LED_SELECTOR = 411, // Selects camera signalling LED + CV_CAP_PROP_XI_LED_MODE = 412, // Define camera signalling LED functionality + CV_CAP_PROP_XI_MANUAL_WB = 413, // Calculates White Balance(must be called during acquisition) + CV_CAP_PROP_XI_AUTO_WB = 414, // Automatic white balance + CV_CAP_PROP_XI_AEAG = 415, // Automatic exposure/gain + CV_CAP_PROP_XI_EXP_PRIORITY = 416, // Exposure priority (0.5 - exposure 50%, gain 50%). + CV_CAP_PROP_XI_AE_MAX_LIMIT = 417, // Maximum limit of exposure in AEAG procedure + CV_CAP_PROP_XI_AG_MAX_LIMIT = 418, // Maximum limit of gain in AEAG procedure + CV_CAP_PROP_XI_AEAG_LEVEL = 419, // Average intensity of output signal AEAG should achieve(in %) + CV_CAP_PROP_XI_TIMEOUT = 420, // Image capture timeout in milliseconds + CV_CAP_PROP_XI_EXPOSURE = 421, // Exposure time in microseconds + CV_CAP_PROP_XI_EXPOSURE_BURST_COUNT = 422, // Sets the number of times of exposure in one frame. + CV_CAP_PROP_XI_GAIN_SELECTOR = 423, // Gain selector for parameter Gain allows to select different type of gains. + CV_CAP_PROP_XI_GAIN = 424, // Gain in dB + CV_CAP_PROP_XI_DOWNSAMPLING_TYPE = 426, // Change image downsampling type. + CV_CAP_PROP_XI_BINNING_SELECTOR = 427, // Binning engine selector. + CV_CAP_PROP_XI_BINNING_VERTICAL = 428, // Vertical Binning - number of vertical photo-sensitive cells to combine together. + CV_CAP_PROP_XI_BINNING_HORIZONTAL = 429, // Horizontal Binning - number of horizontal photo-sensitive cells to combine together. + CV_CAP_PROP_XI_BINNING_PATTERN = 430, // Binning pattern type. + CV_CAP_PROP_XI_DECIMATION_SELECTOR = 431, // Decimation engine selector. + CV_CAP_PROP_XI_DECIMATION_VERTICAL = 432, // Vertical Decimation - vertical sub-sampling of the image - reduces the vertical resolution of the image by the specified vertical decimation factor. + CV_CAP_PROP_XI_DECIMATION_HORIZONTAL = 433, // Horizontal Decimation - horizontal sub-sampling of the image - reduces the horizontal resolution of the image by the specified vertical decimation factor. + CV_CAP_PROP_XI_DECIMATION_PATTERN = 434, // Decimation pattern type. + CV_CAP_PROP_XI_TEST_PATTERN_GENERATOR_SELECTOR = 587, // Selects which test pattern generator is controlled by the TestPattern feature. + CV_CAP_PROP_XI_TEST_PATTERN = 588, // Selects which test pattern type is generated by the selected generator. + CV_CAP_PROP_XI_IMAGE_DATA_FORMAT = 435, // Output data format. + CV_CAP_PROP_XI_SHUTTER_TYPE = 436, // Change sensor shutter type(CMOS sensor). + CV_CAP_PROP_XI_SENSOR_TAPS = 437, // Number of taps + CV_CAP_PROP_XI_AEAG_ROI_OFFSET_X = 439, // Automatic exposure/gain ROI offset X + CV_CAP_PROP_XI_AEAG_ROI_OFFSET_Y = 440, // Automatic exposure/gain ROI offset Y + CV_CAP_PROP_XI_AEAG_ROI_WIDTH = 441, // Automatic exposure/gain ROI Width + CV_CAP_PROP_XI_AEAG_ROI_HEIGHT = 442, // Automatic exposure/gain ROI Height + CV_CAP_PROP_XI_BPC = 445, // Correction of bad pixels + CV_CAP_PROP_XI_WB_KR = 448, // White balance red coefficient + CV_CAP_PROP_XI_WB_KG = 449, // White balance green coefficient + CV_CAP_PROP_XI_WB_KB = 450, // White balance blue coefficient + CV_CAP_PROP_XI_WIDTH = 451, // Width of the Image provided by the device (in pixels). + CV_CAP_PROP_XI_HEIGHT = 452, // Height of the Image provided by the device (in pixels). + CV_CAP_PROP_XI_REGION_SELECTOR = 589, // Selects Region in Multiple ROI which parameters are set by width, height, ... ,region mode + CV_CAP_PROP_XI_REGION_MODE = 595, // Activates/deactivates Region selected by Region Selector + CV_CAP_PROP_XI_LIMIT_BANDWIDTH = 459, // Set/get bandwidth(datarate)(in Megabits) + CV_CAP_PROP_XI_SENSOR_DATA_BIT_DEPTH = 460, // Sensor output data bit depth. + CV_CAP_PROP_XI_OUTPUT_DATA_BIT_DEPTH = 461, // Device output data bit depth. + CV_CAP_PROP_XI_IMAGE_DATA_BIT_DEPTH = 462, // bitdepth of data returned by function xiGetImage + CV_CAP_PROP_XI_OUTPUT_DATA_PACKING = 463, // Device output data packing (or grouping) enabled. Packing could be enabled if output_data_bit_depth > 8 and packing capability is available. + CV_CAP_PROP_XI_OUTPUT_DATA_PACKING_TYPE = 464, // Data packing type. Some cameras supports only specific packing type. + CV_CAP_PROP_XI_IS_COOLED = 465, // Returns 1 for cameras that support cooling. + CV_CAP_PROP_XI_COOLING = 466, // Start camera cooling. + CV_CAP_PROP_XI_TARGET_TEMP = 467, // Set sensor target temperature for cooling. + CV_CAP_PROP_XI_CHIP_TEMP = 468, // Camera sensor temperature + CV_CAP_PROP_XI_HOUS_TEMP = 469, // Camera housing tepmerature + CV_CAP_PROP_XI_HOUS_BACK_SIDE_TEMP = 590, // Camera housing back side tepmerature + CV_CAP_PROP_XI_SENSOR_BOARD_TEMP = 596, // Camera sensor board temperature + CV_CAP_PROP_XI_CMS = 470, // Mode of color management system. + CV_CAP_PROP_XI_APPLY_CMS = 471, // Enable applying of CMS profiles to xiGetImage (see XI_PRM_INPUT_CMS_PROFILE, XI_PRM_OUTPUT_CMS_PROFILE). + CV_CAP_PROP_XI_IMAGE_IS_COLOR = 474, // Returns 1 for color cameras. + CV_CAP_PROP_XI_COLOR_FILTER_ARRAY = 475, // Returns color filter array type of RAW data. + CV_CAP_PROP_XI_GAMMAY = 476, // Luminosity gamma + CV_CAP_PROP_XI_GAMMAC = 477, // Chromaticity gamma + CV_CAP_PROP_XI_SHARPNESS = 478, // Sharpness Strength + CV_CAP_PROP_XI_CC_MATRIX_00 = 479, // Color Correction Matrix element [0][0] + CV_CAP_PROP_XI_CC_MATRIX_01 = 480, // Color Correction Matrix element [0][1] + CV_CAP_PROP_XI_CC_MATRIX_02 = 481, // Color Correction Matrix element [0][2] + CV_CAP_PROP_XI_CC_MATRIX_03 = 482, // Color Correction Matrix element [0][3] + CV_CAP_PROP_XI_CC_MATRIX_10 = 483, // Color Correction Matrix element [1][0] + CV_CAP_PROP_XI_CC_MATRIX_11 = 484, // Color Correction Matrix element [1][1] + CV_CAP_PROP_XI_CC_MATRIX_12 = 485, // Color Correction Matrix element [1][2] + CV_CAP_PROP_XI_CC_MATRIX_13 = 486, // Color Correction Matrix element [1][3] + CV_CAP_PROP_XI_CC_MATRIX_20 = 487, // Color Correction Matrix element [2][0] + CV_CAP_PROP_XI_CC_MATRIX_21 = 488, // Color Correction Matrix element [2][1] + CV_CAP_PROP_XI_CC_MATRIX_22 = 489, // Color Correction Matrix element [2][2] + CV_CAP_PROP_XI_CC_MATRIX_23 = 490, // Color Correction Matrix element [2][3] + CV_CAP_PROP_XI_CC_MATRIX_30 = 491, // Color Correction Matrix element [3][0] + CV_CAP_PROP_XI_CC_MATRIX_31 = 492, // Color Correction Matrix element [3][1] + CV_CAP_PROP_XI_CC_MATRIX_32 = 493, // Color Correction Matrix element [3][2] + CV_CAP_PROP_XI_CC_MATRIX_33 = 494, // Color Correction Matrix element [3][3] + CV_CAP_PROP_XI_DEFAULT_CC_MATRIX = 495, // Set default Color Correction Matrix + CV_CAP_PROP_XI_TRG_SELECTOR = 498, // Selects the type of trigger. + CV_CAP_PROP_XI_ACQ_FRAME_BURST_COUNT = 499, // Sets number of frames acquired by burst. This burst is used only if trigger is set to FrameBurstStart + CV_CAP_PROP_XI_DEBOUNCE_EN = 507, // Enable/Disable debounce to selected GPI + CV_CAP_PROP_XI_DEBOUNCE_T0 = 508, // Debounce time (x * 10us) + CV_CAP_PROP_XI_DEBOUNCE_T1 = 509, // Debounce time (x * 10us) + CV_CAP_PROP_XI_DEBOUNCE_POL = 510, // Debounce polarity (pol = 1 t0 - falling edge, t1 - rising edge) + CV_CAP_PROP_XI_LENS_MODE = 511, // Status of lens control interface. This shall be set to XI_ON before any Lens operations. + CV_CAP_PROP_XI_LENS_APERTURE_VALUE = 512, // Current lens aperture value in stops. Examples: 2.8, 4, 5.6, 8, 11 + CV_CAP_PROP_XI_LENS_FOCUS_MOVEMENT_VALUE = 513, // Lens current focus movement value to be used by XI_PRM_LENS_FOCUS_MOVE in motor steps. + CV_CAP_PROP_XI_LENS_FOCUS_MOVE = 514, // Moves lens focus motor by steps set in XI_PRM_LENS_FOCUS_MOVEMENT_VALUE. + CV_CAP_PROP_XI_LENS_FOCUS_DISTANCE = 515, // Lens focus distance in cm. + CV_CAP_PROP_XI_LENS_FOCAL_LENGTH = 516, // Lens focal distance in mm. + CV_CAP_PROP_XI_LENS_FEATURE_SELECTOR = 517, // Selects the current feature which is accessible by XI_PRM_LENS_FEATURE. + CV_CAP_PROP_XI_LENS_FEATURE = 518, // Allows access to lens feature value currently selected by XI_PRM_LENS_FEATURE_SELECTOR. + CV_CAP_PROP_XI_DEVICE_MODEL_ID = 521, // Return device model id + CV_CAP_PROP_XI_DEVICE_SN = 522, // Return device serial number + CV_CAP_PROP_XI_IMAGE_DATA_FORMAT_RGB32_ALPHA = 529, // The alpha channel of RGB32 output image format. + CV_CAP_PROP_XI_IMAGE_PAYLOAD_SIZE = 530, // Buffer size in bytes sufficient for output image returned by xiGetImage + CV_CAP_PROP_XI_TRANSPORT_PIXEL_FORMAT = 531, // Current format of pixels on transport layer. + CV_CAP_PROP_XI_SENSOR_CLOCK_FREQ_HZ = 532, // Sensor clock frequency in Hz. + CV_CAP_PROP_XI_SENSOR_CLOCK_FREQ_INDEX = 533, // Sensor clock frequency index. Sensor with selected frequencies have possibility to set the frequency only by this index. + CV_CAP_PROP_XI_SENSOR_OUTPUT_CHANNEL_COUNT = 534, // Number of output channels from sensor used for data transfer. + CV_CAP_PROP_XI_FRAMERATE = 535, // Define framerate in Hz + CV_CAP_PROP_XI_COUNTER_SELECTOR = 536, // Select counter + CV_CAP_PROP_XI_COUNTER_VALUE = 537, // Counter status + CV_CAP_PROP_XI_ACQ_TIMING_MODE = 538, // Type of sensor frames timing. + CV_CAP_PROP_XI_AVAILABLE_BANDWIDTH = 539, // Calculate and return available interface bandwidth(int Megabits) + CV_CAP_PROP_XI_BUFFER_POLICY = 540, // Data move policy + CV_CAP_PROP_XI_LUT_EN = 541, // Activates LUT. + CV_CAP_PROP_XI_LUT_INDEX = 542, // Control the index (offset) of the coefficient to access in the LUT. + CV_CAP_PROP_XI_LUT_VALUE = 543, // Value at entry LUTIndex of the LUT + CV_CAP_PROP_XI_TRG_DELAY = 544, // Specifies the delay in microseconds (us) to apply after the trigger reception before activating it. + CV_CAP_PROP_XI_TS_RST_MODE = 545, // Defines how time stamp reset engine will be armed + CV_CAP_PROP_XI_TS_RST_SOURCE = 546, // Defines which source will be used for timestamp reset. Writing this parameter will trigger settings of engine (arming) + CV_CAP_PROP_XI_IS_DEVICE_EXIST = 547, // Returns 1 if camera connected and works properly. + CV_CAP_PROP_XI_ACQ_BUFFER_SIZE = 548, // Acquisition buffer size in buffer_size_unit. Default bytes. + CV_CAP_PROP_XI_ACQ_BUFFER_SIZE_UNIT = 549, // Acquisition buffer size unit in bytes. Default 1. E.g. Value 1024 means that buffer_size is in KiBytes + CV_CAP_PROP_XI_ACQ_TRANSPORT_BUFFER_SIZE = 550, // Acquisition transport buffer size in bytes + CV_CAP_PROP_XI_BUFFERS_QUEUE_SIZE = 551, // Queue of field/frame buffers + CV_CAP_PROP_XI_ACQ_TRANSPORT_BUFFER_COMMIT = 552, // Number of buffers to commit to low level + CV_CAP_PROP_XI_RECENT_FRAME = 553, // GetImage returns most recent frame + CV_CAP_PROP_XI_DEVICE_RESET = 554, // Resets the camera to default state. + CV_CAP_PROP_XI_COLUMN_FPN_CORRECTION = 555, // Correction of column FPN + CV_CAP_PROP_XI_ROW_FPN_CORRECTION = 591, // Correction of row FPN + CV_CAP_PROP_XI_SENSOR_MODE = 558, // Current sensor mode. Allows to select sensor mode by one integer. Setting of this parameter affects: image dimensions and downsampling. + CV_CAP_PROP_XI_HDR = 559, // Enable High Dynamic Range feature. + CV_CAP_PROP_XI_HDR_KNEEPOINT_COUNT = 560, // The number of kneepoints in the PWLR. + CV_CAP_PROP_XI_HDR_T1 = 561, // position of first kneepoint(in % of XI_PRM_EXPOSURE) + CV_CAP_PROP_XI_HDR_T2 = 562, // position of second kneepoint (in % of XI_PRM_EXPOSURE) + CV_CAP_PROP_XI_KNEEPOINT1 = 563, // value of first kneepoint (% of sensor saturation) + CV_CAP_PROP_XI_KNEEPOINT2 = 564, // value of second kneepoint (% of sensor saturation) + CV_CAP_PROP_XI_IMAGE_BLACK_LEVEL = 565, // Last image black level counts. Can be used for Offline processing to recall it. + CV_CAP_PROP_XI_HW_REVISION = 571, // Returns hardware revision number. + CV_CAP_PROP_XI_DEBUG_LEVEL = 572, // Set debug level + CV_CAP_PROP_XI_AUTO_BANDWIDTH_CALCULATION = 573, // Automatic bandwidth calculation, + CV_CAP_PROP_XI_FFS_FILE_ID = 594, // File number. + CV_CAP_PROP_XI_FFS_FILE_SIZE = 580, // Size of file. + CV_CAP_PROP_XI_FREE_FFS_SIZE = 581, // Size of free camera FFS. + CV_CAP_PROP_XI_USED_FFS_SIZE = 582, // Size of used camera FFS. + CV_CAP_PROP_XI_FFS_ACCESS_KEY = 583, // Setting of key enables file operations on some cameras. + CV_CAP_PROP_XI_SENSOR_FEATURE_SELECTOR = 585, // Selects the current feature which is accessible by XI_PRM_SENSOR_FEATURE_VALUE. + CV_CAP_PROP_XI_SENSOR_FEATURE_VALUE = 586, // Allows access to sensor feature value currently selected by XI_PRM_SENSOR_FEATURE_SELECTOR. + + + // Properties for Android cameras + CV_CAP_PROP_ANDROID_FLASH_MODE = 8001, + CV_CAP_PROP_ANDROID_FOCUS_MODE = 8002, + CV_CAP_PROP_ANDROID_WHITE_BALANCE = 8003, + CV_CAP_PROP_ANDROID_ANTIBANDING = 8004, + CV_CAP_PROP_ANDROID_FOCAL_LENGTH = 8005, + CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR = 8006, + CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL = 8007, + CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR = 8008, + CV_CAP_PROP_ANDROID_EXPOSE_LOCK = 8009, + CV_CAP_PROP_ANDROID_WHITEBALANCE_LOCK = 8010, + + // Properties of cameras available through AVFOUNDATION interface + CV_CAP_PROP_IOS_DEVICE_FOCUS = 9001, + CV_CAP_PROP_IOS_DEVICE_EXPOSURE = 9002, + CV_CAP_PROP_IOS_DEVICE_FLASH = 9003, + CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE = 9004, + CV_CAP_PROP_IOS_DEVICE_TORCH = 9005, + + // Properties of cameras available through Smartek Giganetix Ethernet Vision interface + /* --- Vladimir Litvinenko (litvinenko.vladimir@gmail.com) --- */ + CV_CAP_PROP_GIGA_FRAME_OFFSET_X = 10001, + CV_CAP_PROP_GIGA_FRAME_OFFSET_Y = 10002, + CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX = 10003, + CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX = 10004, + CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH = 10005, + CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH = 10006, + + CV_CAP_PROP_INTELPERC_PROFILE_COUNT = 11001, + CV_CAP_PROP_INTELPERC_PROFILE_IDX = 11002, + CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE = 11003, + CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE = 11004, + CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD = 11005, + CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ = 11006, + CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT = 11007, + + // Intel PerC streams + CV_CAP_INTELPERC_DEPTH_GENERATOR = 1 << 29, + CV_CAP_INTELPERC_IMAGE_GENERATOR = 1 << 28, + CV_CAP_INTELPERC_GENERATORS_MASK = CV_CAP_INTELPERC_DEPTH_GENERATOR + CV_CAP_INTELPERC_IMAGE_GENERATOR +}; + +enum +{ + // Data given from depth generator. + CV_CAP_OPENNI_DEPTH_MAP = 0, // Depth values in mm (CV_16UC1) + CV_CAP_OPENNI_POINT_CLOUD_MAP = 1, // XYZ in meters (CV_32FC3) + CV_CAP_OPENNI_DISPARITY_MAP = 2, // Disparity in pixels (CV_8UC1) + CV_CAP_OPENNI_DISPARITY_MAP_32F = 3, // Disparity in pixels (CV_32FC1) + CV_CAP_OPENNI_VALID_DEPTH_MASK = 4, // CV_8UC1 + + // Data given from RGB image generator. + CV_CAP_OPENNI_BGR_IMAGE = 5, + CV_CAP_OPENNI_GRAY_IMAGE = 6, + + // Data given from IR image generator. + CV_CAP_OPENNI_IR_IMAGE = 7 +}; + +// Supported output modes of OpenNI image generator +enum +{ + CV_CAP_OPENNI_VGA_30HZ = 0, + CV_CAP_OPENNI_SXGA_15HZ = 1, + CV_CAP_OPENNI_SXGA_30HZ = 2, + CV_CAP_OPENNI_QVGA_30HZ = 3, + CV_CAP_OPENNI_QVGA_60HZ = 4 +}; + +enum +{ + CV_CAP_INTELPERC_DEPTH_MAP = 0, // Each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth. + CV_CAP_INTELPERC_UVDEPTH_MAP = 1, // Each pixel contains two 32-bit floating point values in the range of 0-1, representing the mapping of depth coordinates to the color coordinates. + CV_CAP_INTELPERC_IR_MAP = 2, // Each pixel is a 16-bit integer. The value indicates the intensity of the reflected laser beam. + CV_CAP_INTELPERC_IMAGE = 3 +}; + +// gPhoto2 properties, if propertyId is less than 0 then work on widget with that __additive inversed__ camera setting ID +// Get IDs by using CAP_PROP_GPHOTO2_WIDGET_ENUMERATE. +// @see CvCaptureCAM_GPHOTO2 for more info +enum +{ + CV_CAP_PROP_GPHOTO2_PREVIEW = 17001, // Capture only preview from liveview mode. + CV_CAP_PROP_GPHOTO2_WIDGET_ENUMERATE = 17002, // Readonly, returns (const char *). + CV_CAP_PROP_GPHOTO2_RELOAD_CONFIG = 17003, // Trigger, only by set. Reload camera settings. + CV_CAP_PROP_GPHOTO2_RELOAD_ON_CHANGE = 17004, // Reload all settings on set. + CV_CAP_PROP_GPHOTO2_COLLECT_MSGS = 17005, // Collect messages with details. + CV_CAP_PROP_GPHOTO2_FLUSH_MSGS = 17006, // Readonly, returns (const char *). + CV_CAP_PROP_SPEED = 17007, // Exposure speed. Can be readonly, depends on camera program. + CV_CAP_PROP_APERTURE = 17008, // Aperture. Can be readonly, depends on camera program. + CV_CAP_PROP_EXPOSUREPROGRAM = 17009, // Camera exposure program. + CV_CAP_PROP_VIEWFINDER = 17010 // Enter liveview mode. +}; + +//! Macro to construct the fourcc code of the codec. Same as CV_FOURCC() +#define CV_FOURCC_MACRO(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24)) + +/** @brief Constructs the fourcc code of the codec function + +Simply call it with 4 chars fourcc code like `CV_FOURCC('I', 'Y', 'U', 'V')` + +List of codes can be obtained at [Video Codecs by FOURCC](http://www.fourcc.org/codecs.php) page. +FFMPEG backend with MP4 container natively uses other values as fourcc code: +see [ObjectType](http://www.mp4ra.org/codecs.html). +*/ +CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4) +{ + return CV_FOURCC_MACRO(c1, c2, c3, c4); +} + +//! (Windows only) Open Codec Selection Dialog +#define CV_FOURCC_PROMPT -1 +//! (Linux only) Use default codec for specified filename +#define CV_FOURCC_DEFAULT CV_FOURCC('I', 'Y', 'U', 'V') + +#endif // OPENCV_VIDEOIO_LEGACY_CONSTANTS_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/videoio/registry.hpp b/Prj-Win/3rd/opencv/include/opencv2/videoio/registry.hpp new file mode 100755 index 0000000..89fb5a8 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/videoio/registry.hpp @@ -0,0 +1,47 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef OPENCV_VIDEOIO_REGISTRY_HPP +#define OPENCV_VIDEOIO_REGISTRY_HPP + +#include + +namespace cv { namespace videoio_registry { +/** @addtogroup videoio_registry +This section contains API description how to query/configure available Video I/O backends. + +Runtime configuration options: +- enable debug mode: `OPENCV_VIDEOIO_DEBUG=1` +- change backend priority: `OPENCV_VIDEOIO_PRIORITY_=9999` +- disable backend: `OPENCV_VIDEOIO_PRIORITY_=0` +- specify list of backends with high priority (>100000): `OPENCV_VIDEOIO_PRIORITY_LIST=FFMPEG,GSTREAMER` + +@{ + */ + + +/** @brief Returns backend API name or "UnknownVideoAPI(xxx)" +@param api backend ID (#VideoCaptureAPIs) +*/ +CV_EXPORTS_W cv::String getBackendName(VideoCaptureAPIs api); + +/** @brief Returns list of all available backends */ +CV_EXPORTS_W std::vector getBackends(); + +/** @brief Returns list of available backends which works via `cv::VideoCapture(int index)` */ +CV_EXPORTS_W std::vector getCameraBackends(); + +/** @brief Returns list of available backends which works via `cv::VideoCapture(filename)` */ +CV_EXPORTS_W std::vector getStreamBackends(); + +/** @brief Returns list of available backends which works via `cv::VideoWriter()` */ +CV_EXPORTS_W std::vector getWriterBackends(); + +/** @brief Returns true if backend is available */ +CV_EXPORTS bool hasBackend(VideoCaptureAPIs api); + +//! @} +}} // namespace + +#endif // OPENCV_VIDEOIO_REGISTRY_HPP diff --git a/Prj-Win/3rd/opencv/include/opencv2/videoio/videoio.hpp b/Prj-Win/3rd/opencv/include/opencv2/videoio/videoio.hpp new file mode 100755 index 0000000..ec84cf7 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/videoio/videoio.hpp @@ -0,0 +1,48 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifdef __OPENCV_BUILD +#error this is a compatibility header which should not be used inside the OpenCV library +#endif + +#include "opencv2/videoio.hpp" diff --git a/Prj-Win/3rd/opencv/include/opencv2/videoio/videoio_c.h b/Prj-Win/3rd/opencv/include/opencv2/videoio/videoio_c.h new file mode 100755 index 0000000..cf1a6d0 --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/videoio/videoio_c.h @@ -0,0 +1,153 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_VIDEOIO_H +#define OPENCV_VIDEOIO_H + +#include "opencv2/core/core_c.h" + +#include "opencv2/videoio/legacy/constants_c.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + @addtogroup videoio_c + @{ +*/ + +/****************************************************************************************\ +* Working with Video Files and Cameras * +\****************************************************************************************/ + +/** @brief "black box" capture structure + +In C++ use cv::VideoCapture +*/ +typedef struct CvCapture CvCapture; + +/** @brief start capturing frames from video file +*/ +CVAPI(CvCapture*) cvCreateFileCapture( const char* filename ); + +/** @brief start capturing frames from video file. allows specifying a preferred API to use +*/ +CVAPI(CvCapture*) cvCreateFileCaptureWithPreference( const char* filename , int apiPreference); + +/** @brief start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) +*/ +CVAPI(CvCapture*) cvCreateCameraCapture( int index ); + +/** @brief grab a frame, return 1 on success, 0 on fail. + + this function is thought to be fast +*/ +CVAPI(int) cvGrabFrame( CvCapture* capture ); + +/** @brief get the frame grabbed with cvGrabFrame(..) + + This function may apply some frame processing like + frame decompression, flipping etc. + @warning !!!DO NOT RELEASE or MODIFY the retrieved frame!!! +*/ +CVAPI(IplImage*) cvRetrieveFrame( CvCapture* capture, int streamIdx CV_DEFAULT(0) ); + +/** @brief Just a combination of cvGrabFrame and cvRetrieveFrame + + @warning !!!DO NOT RELEASE or MODIFY the retrieved frame!!! +*/ +CVAPI(IplImage*) cvQueryFrame( CvCapture* capture ); + +/** @brief stop capturing/reading and free resources +*/ +CVAPI(void) cvReleaseCapture( CvCapture** capture ); + +/** @brief retrieve capture properties +*/ +CVAPI(double) cvGetCaptureProperty( CvCapture* capture, int property_id ); +/** @brief set capture properties +*/ +CVAPI(int) cvSetCaptureProperty( CvCapture* capture, int property_id, double value ); + +/** @brief Return the type of the capturer (eg, ::CV_CAP_VFW, ::CV_CAP_UNICAP) + +It is unknown if created with ::CV_CAP_ANY +*/ +CVAPI(int) cvGetCaptureDomain( CvCapture* capture); + +/** @brief "black box" video file writer structure + +In C++ use cv::VideoWriter +*/ +typedef struct CvVideoWriter CvVideoWriter; + +/** @brief initialize video file writer +*/ +CVAPI(CvVideoWriter*) cvCreateVideoWriter( const char* filename, int fourcc, + double fps, CvSize frame_size, + int is_color CV_DEFAULT(1)); + +/** @brief write frame to video file +*/ +CVAPI(int) cvWriteFrame( CvVideoWriter* writer, const IplImage* image ); + +/** @brief close video file writer +*/ +CVAPI(void) cvReleaseVideoWriter( CvVideoWriter** writer ); + +// *************************************************************************************** +//! @name Obsolete functions/synonyms +//! @{ +#define cvCaptureFromCAM cvCreateCameraCapture //!< @deprecated use cvCreateCameraCapture() instead +#define cvCaptureFromFile cvCreateFileCapture //!< @deprecated use cvCreateFileCapture() instead +#define cvCaptureFromAVI cvCaptureFromFile //!< @deprecated use cvCreateFileCapture() instead +#define cvCreateAVIWriter cvCreateVideoWriter //!< @deprecated use cvCreateVideoWriter() instead +#define cvWriteToAVI cvWriteFrame //!< @deprecated use cvWriteFrame() instead +//! @} Obsolete... + +//! @} videoio_c + +#ifdef __cplusplus +} +#endif + +#endif //OPENCV_VIDEOIO_H diff --git a/Prj-Win/3rd/opencv/include/opencv2/world.hpp b/Prj-Win/3rd/opencv/include/opencv2/world.hpp new file mode 100755 index 0000000..4902c2f --- /dev/null +++ b/Prj-Win/3rd/opencv/include/opencv2/world.hpp @@ -0,0 +1,58 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_WORLD_HPP +#define OPENCV_WORLD_HPP + +#include "opencv2/core.hpp" + +#ifdef __cplusplus +namespace cv +{ + +CV_EXPORTS_W bool initAll(); + +} + +#endif + +#endif diff --git a/Prj-Win/3rd/opencv/lib/opencv_world411.lib b/Prj-Win/3rd/opencv/lib/opencv_world411.lib new file mode 100755 index 0000000000000000000000000000000000000000..4c1ccbf45cd6397189c27821043348e35a485185 GIT binary patch literal 2451712 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�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

    >8sj)cU;=SIj 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

    vST|D`Vv_rj7x;^(-O+~lVQr{H#67Xo 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 +//#include +#include "mtcnn.h" +#include "time.h" + + + +cv::Rect boundingRect(const std::vector& pts) { + if (pts.size() > 1) + { + int xmin = pts[0].x; + int ymin = pts[0].y; + int xmax = pts[0].x; + int ymax = pts[0].y; + for (int i = 1; i < pts.size(); i++) + { + if (pts[i].x < xmin) + xmin = pts[i].x; + if (pts[i].y < ymin) + ymin = pts[i].y; + if (pts[i].x > xmax) + xmax = pts[i].x; + if (pts[i].y > ymax) + ymax = pts[i].y; + } + return cv::Rect(xmin, ymin, xmax - xmin, ymax - ymin); + } +} + + +//typedef int T; +//T i = 1; + + +class Face { +public: + + Face(int instance_id, Shape::Rect rect) { + face_id = instance_id; + + face_location = rect; + isCanShow = false; //追踪一次后待框稳定后即可显示 + + } + + Face() { + + isCanShow = false; //追踪一次后待框稳定后即可显示 + } + + Bbox faceBbox; + + int face_id = -1; + long frameId = 0; + int ptr_num = 0; + + Shape::Rect face_location; + bool isCanShow; + cv::Mat frame_face_prev; + + static cv::Rect SquarePadding(cv::Rect facebox, int margin_rows, int margin_cols, bool max) + { + int c_x = facebox.x + facebox.width / 2; + int c_y = facebox.y + facebox.height / 2; + int large = 0; + if (max) + large = std::max(facebox.height, facebox.width) / 2; + else + large = min(facebox.height, facebox.width) / 2; + cv::Rect rectNot(c_x - large, c_y - large, c_x + large, c_y + large); + rectNot.x = std::max(0, rectNot.x); + rectNot.y = std::max(0, rectNot.y); + rectNot.height = min(rectNot.height, margin_rows - 1); + rectNot.width = min(rectNot.width, margin_cols - 1); + if (rectNot.height - rectNot.y != rectNot.width - rectNot.x) + return SquarePadding(cv::Rect(rectNot.x, rectNot.y, rectNot.width - rectNot.x, rectNot.height - rectNot.y), margin_rows, margin_cols, false); + + return cv::Rect(rectNot.x, rectNot.y, rectNot.width - rectNot.x, rectNot.height - rectNot.y); + } + + static cv::Rect SquarePadding(cv::Rect facebox, int padding) + { + + int c_x = facebox.x - padding; + int c_y = facebox.y - padding; + return cv::Rect(facebox.x - padding, facebox.y - padding, facebox.width + padding * 2, facebox.height + padding * 2);; + } + + static double getDistance(cv::Point x, cv::Point y) + { + return sqrt((x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y)); + } + + + vector > faceSequence; + vector> attitudeSequence; + + +}; + + + +class FaceTracking { +public: + FaceTracking(string modelPath) + { + this->detector = new MTCNN(modelPath); + downSimpilingFactor = 1; + faceMinSize = 70; + this->detector->SetMinFace(faceMinSize); + detection_Time = -1; + + } + + ~FaceTracking() { + delete this->detector; + + } + + void detecting(cv::Mat* image) { + ncnn::Mat ncnn_img = ncnn::Mat::from_pixels(image->data, ncnn::Mat::PIXEL_BGR2RGB, image->cols, image->rows); + std::vector finalBbox; + if(isMaxFace) + detector->detectMaxFace(ncnn_img, finalBbox); + else + detector->detect(ncnn_img, finalBbox); + const int num_box = finalBbox.size(); + std::vector bbox; + bbox.resize(num_box); + candidateFaces_lock = 1; + for (int i = 0; i < num_box; i++) { + bbox[i] = cv::Rect(finalBbox[i].x1, finalBbox[i].y1, finalBbox[i].x2 - finalBbox[i].x1 + 1, + finalBbox[i].y2 - finalBbox[i].y1 + 1); + bbox[i] = Face::SquarePadding(bbox[i], image->rows, image->cols, true); + Shape::Rect f_rect(bbox[i].x / static_cast(image->cols), + bbox[i].y / static_cast(image->rows), + bbox[i].width / static_cast(image->cols), + bbox[i].height / static_cast(image->rows) + ); + std::shared_ptr face(new Face(trackingID, f_rect)); + (*image)(bbox[i]).copyTo(face->frame_face_prev); + + trackingID = trackingID + 1; + candidateFaces.push_back(*face); + } + candidateFaces_lock = 0; + } + + void Init(cv::Mat& image) { + ImageHighDP = image; + cv::Size lowDpSize(ImageHighDP.cols / downSimpilingFactor, ImageHighDP.rows / downSimpilingFactor); + cv::resize(image, ImageLowDP, lowDpSize); + trackingID = 0; + detection_Interval = 200; //detect faces every 200 ms + detecting(&image); + stabilization = false; + UI_height = image.rows; + UI_width = image.cols; + } + + void doingLandmark_onet(cv::Mat& face, Bbox& faceBbox, int zeroadd_x, int zeroadd_y, int stable_state = 0) { + ncnn::Mat in = ncnn::Mat::from_pixels_resize(face.data, ncnn::Mat::PIXEL_BGR, face.cols, face.rows, 48, 48); + faceBbox = detector->onet(in, zeroadd_x, zeroadd_y, face.cols, face.rows); + + } + + + void tracking_corrfilter(const cv::Mat& frame, const cv::Mat& model, cv::Rect& trackBox, float scale) + { + trackBox.x /= scale; + trackBox.y /= scale; + trackBox.height /= scale; + trackBox.width /= scale; + int zeroadd_x = 0; + int zeroadd_y = 0; + cv::Mat frame_; + cv::Mat model_; + cv::resize(frame, frame_, cv::Size(), 1 / scale, 1 / scale); + cv::resize(model, model_, cv::Size(), 1 / scale, 1 / scale); + cv::Mat gray; + cvtColor(frame_, gray, cv::COLOR_RGB2GRAY); + cv::Mat gray_model; + cvtColor(model_, gray_model, cv::COLOR_RGB2GRAY); + cv::Rect searchWindow; + searchWindow.width = trackBox.width * 3; + searchWindow.height = trackBox.height * 3; + searchWindow.x = trackBox.x + trackBox.width * 0.5 - searchWindow.width * 0.5; + searchWindow.y = trackBox.y + trackBox.height * 0.5 - searchWindow.height * 0.5; + searchWindow &= cv::Rect(0, 0, frame_.cols, frame_.rows); + cv::Mat similarity; + matchTemplate(gray(searchWindow), gray_model, similarity, cv::TM_CCOEFF_NORMED); + double mag_r; + cv::Point point; + minMaxLoc(similarity, 0, &mag_r, 0, &point); + trackBox.x = point.x + searchWindow.x; + trackBox.y = point.y + searchWindow.y; + trackBox.x *= scale; + trackBox.y *= scale; + trackBox.height *= scale; + trackBox.width *= scale; + } + + bool tracking(cv::Mat& image, Face& face) + { + cv::Rect faceROI = face.face_location.convert_cv_rect(image.rows, image.cols); + cv::Mat faceROI_Image; + tracking_corrfilter(image, face.frame_face_prev, faceROI, tpm_scale); + image(faceROI).copyTo(faceROI_Image); + + cv::Rect bdbox; + + doingLandmark_onet(faceROI_Image, face.faceBbox, faceROI.x, faceROI.y, face.frameId > 1); + + bdbox.x = face.faceBbox.x1; + bdbox.y = face.faceBbox.y1; + bdbox.width = face.faceBbox.x2 - face.faceBbox.x1; + bdbox.height = face.faceBbox.y2 - face.faceBbox.y1; + + bdbox = Face::SquarePadding(bdbox, static_cast(bdbox.height * -0.05)); + bdbox = Face::SquarePadding(bdbox, image.rows, image.cols, 1); + + Shape::Rect boxfloat(bdbox.x / static_cast(image.cols), + bdbox.y / static_cast(image.rows), + bdbox.width / static_cast(image.cols), + bdbox.height / static_cast(image.rows)); + + face.faceBbox.x1 = bdbox.x; + face.faceBbox.y1 = bdbox.y; + face.faceBbox.x2 = bdbox.x + bdbox.width; + face.faceBbox.y2 = bdbox.y + bdbox.height; + + + face.face_location = boxfloat; + faceROI = face.face_location.convert_cv_rect(image.rows, image.cols); + + image(faceROI).copyTo(face.frame_face_prev); + face.frameId += 1; + ncnn::Mat rnet_data = ncnn::Mat::from_pixels_resize(faceROI_Image.data, ncnn::Mat::PIXEL_BGR2RGB, faceROI_Image.cols, faceROI_Image.rows, 24, 24); + + float sim = detector->rnet(rnet_data); + + face.isCanShow = true; + if (sim > 0.9) { + //stablize + float diff_x = 0; + float diff_y = 0; + return true; + } + return false; + + } + void setMask(cv::Mat& image, cv::Rect& rect_mask) + { + + int height = image.rows; + int width = image.cols; + cv::Mat subImage = image(rect_mask); + subImage.setTo(0); + } + + void update(cv::Mat& image) + { + ImageHighDP = image; + //std::cout << trackingFace.size() << std::endl; + if (candidateFaces.size() > 0 && !candidateFaces_lock) + { + for (int i = 0; i < candidateFaces.size(); i++) + { + trackingFace.push_back(candidateFaces[i]); + } + candidateFaces.clear(); + } + for (vector::iterator iter = trackingFace.begin(); iter != trackingFace.end();) + { + if (!tracking(image, *iter)) + { + iter = trackingFace.erase(iter); //追踪失败 则删除此人脸 + } + else { + iter++; + } + } + + if (trackingFace.size() <= 0) + { + detection_Interval = 200; + } + else + { + detection_Interval = 1000; + } + + if (detection_Time < 0) + { + detection_Time = (double)cv::getTickCount(); + } + else { + double diff = (double)(cv::getTickCount() - detection_Time) * 1000 / cv::getTickFrequency(); + if (diff > detection_Interval) + { + cv::Size lowDpSize(ImageHighDP.cols / downSimpilingFactor, ImageHighDP.rows / downSimpilingFactor); + cv::resize(image, ImageLowDP, lowDpSize); + //set Mask to protect the tracking face not to be detected. + for (auto& face : trackingFace) + { + Shape::Rect rect = face.face_location; + cv::Rect rect1 = rect.convert_cv_rect(ImageLowDP.rows, ImageLowDP.cols); + setMask(ImageLowDP, rect1); + } + detection_Time = (double)cv::getTickCount(); + // do detection in thread + detecting(&ImageLowDP); + } + + } + } + + + + vector trackingFace; //跟踪中的人脸 + int UI_width; + int UI_height; + + +private: + + int isLostDetection; + int isTracking; + int isDetection; + cv::Mat ImageHighDP; + cv::Mat ImageLowDP; + int downSimpilingFactor; + int faceMinSize; + MTCNN* detector; + vector candidateFaces; // 将检测到的人脸放入此列队 待跟踪的人脸 + bool candidateFaces_lock; + double detection_Time; + double detection_Interval; + int trackingID; + bool stabilization; + int tpm_scale = 2; + bool isMaxFace = true; +}; +#endif //ZEUSEESFACETRACKING_H diff --git a/Prj-Win/Ncnn_FaceTrack.sln b/Prj-Win/Ncnn_FaceTrack.sln new file mode 100755 index 0000000..57f0302 --- /dev/null +++ b/Prj-Win/Ncnn_FaceTrack.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ncnn_FaceTrack", "Ncnn_FaceTrack.vcxproj", "{3B42A14B-6FFE-4CF1-881B-720C2F693394}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Debug|x64.ActiveCfg = Debug|x64 + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Debug|x64.Build.0 = Debug|x64 + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Debug|x86.ActiveCfg = Debug|Win32 + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Debug|x86.Build.0 = Debug|Win32 + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Release|x64.ActiveCfg = Release|x64 + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Release|x64.Build.0 = Release|x64 + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Release|x86.ActiveCfg = Release|Win32 + {3B42A14B-6FFE-4CF1-881B-720C2F693394}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Prj-Win/Ncnn_FaceTrack.vcxproj b/Prj-Win/Ncnn_FaceTrack.vcxproj new file mode 100755 index 0000000..fe44ad0 --- /dev/null +++ b/Prj-Win/Ncnn_FaceTrack.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {3B42A14B-6FFE-4CF1-881B-720C2F693394} + Win32Proj + Ncnn_FaceTrack + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 3rd\ncnn\include;3rd\opencv\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + 3rd\ncnn\lib;3rd\opencv\lib;%(AdditionalLibraryDirectories) + ncnn.lib;opencv_world411.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + F:\ncnn\install_r\include;F:\opencv4.0.0\install\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Prj-Win/Ncnn_FaceTrack.vcxproj.filters b/Prj-Win/Ncnn_FaceTrack.vcxproj.filters new file mode 100755 index 0000000..2c14296 --- /dev/null +++ b/Prj-Win/Ncnn_FaceTrack.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + + + 源文件 + + + 源文件 + + + \ No newline at end of file diff --git a/Prj-Win/Ncnn_FaceTrack.vcxproj.user b/Prj-Win/Ncnn_FaceTrack.vcxproj.user new file mode 100755 index 0000000..88a5509 --- /dev/null +++ b/Prj-Win/Ncnn_FaceTrack.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Prj-Win/README.md b/Prj-Win/README.md new file mode 100755 index 0000000..e3b2b47 --- /dev/null +++ b/Prj-Win/README.md @@ -0,0 +1,17 @@ +# Ncnn_FaceTrack + +基于mtcnn人脸检测+onet人脸跟踪 + +#开发环境 + +win7 +vs2015 + + +#开源框架 ++ [ncnn](https://github.com/Tencent/ncnn) + ++ [opencv](https://github.com/opencv/opencv) + +# 引用 +[HyperFT](https://github.com/zeusees/HyperFT) diff --git a/Prj-Win/main.cpp b/Prj-Win/main.cpp new file mode 100755 index 0000000..707e09f --- /dev/null +++ b/Prj-Win/main.cpp @@ -0,0 +1,299 @@ +#include "LandmarkTracking.h" + + +#ifdef CV_CXX11 +#include +#include +#include +#endif + + +#ifdef CV_CXX11 +template +class QueueFPS : public std::queue +{ +public: + QueueFPS() : counter(0) {} + + void push(const T& entry) + { + std::lock_guard lock(mutex); + + std::queue::push(entry); + counter += 1; + if (counter == 1) + { + // Start counting from a second frame (warmup). + tm.reset(); + tm.start(); + } + } + + T get() + { + std::lock_guard lock(mutex); + T entry = this->front(); + this->pop(); + return entry; + } + + float getFPS() + { + tm.stop(); + double fps = counter / tm.getTimeSec(); + tm.start(); + return static_cast(fps); + } + + void clear() + { + std::lock_guard lock(mutex); + while (!this->empty()) + this->pop(); + } + + unsigned int counter; + +private: + cv::TickMeter tm; + std::mutex mutex; +}; + +template +class Queue : public std::queue +{ +public: + Queue(){} + + void push(const T& entry) + { + std::lock_guard lock(mutex); + std::queue::push(entry); + + } + + T get() + { + std::lock_guard lock(mutex); + T entry = this->front(); + this->pop(); + return entry; + } + + void clear() + { + std::lock_guard lock(mutex); + while (!this->empty()) + this->pop(); + } + +private: + + std::mutex mutex; +}; +#endif // CV_CXX11 + +int main() +{ + + string model_path = "./models"; + FaceTracking faceTrack(model_path); + cv::Mat frame; + cv::VideoCapture cap(0); + if (!cap.isOpened()) + { + return -1; + } + + int frameIndex = 0; + vector IDs; + vector Colors; + cv::Scalar color; + srand((unsigned int)time(0));//ʼΪֵ + Queue framesQueue; + std::vector faces; + +#ifdef CV_CXX11 + bool process = true; + + Queue > predictionsQueue; + std::thread processingThread([&]() { + //std::queue futureOutputs; + cv::Mat blob; + for (;process;) + { + // Get a next frame + cv::Mat frame; + { + if (!framesQueue.empty()) + { + frame = framesQueue.get(); + framesQueue.clear(); // Skip the rest of frames + } + } + + // Process the frame + if (!frame.empty()) + { + double t1 = (double)cv::getTickCount(); + if (frameIndex == 0) + { + faceTrack.Init(frame); + frameIndex = 1; + } + else { + faceTrack.update(frame); + } + printf("total %gms\n", ((double)cv::getTickCount() - t1) * 1000 / cv::getTickFrequency()); + printf("------------------\n"); + //Sleep(200); + predictionsQueue.push(faceTrack.trackingFace); + } + + + } + }); + for (;;) { + + if (!cap.read(frame)) + { + break; + } + + //cv::transpose(frame, frame); + //cv::flip(frame, frame, -1); + //cv::flip(frame, frame, 1); + + framesQueue.push(frame.clone()); + + if (!predictionsQueue.empty()) + { + + faces.clear(); + faces = predictionsQueue.get(); + + + + for (int i = 0; i < faces.size(); i++) + { + const Face &info = faces[i]; + cv::Rect rect; + rect.x = info.faceBbox.x1; + rect.y = info.faceBbox.y1; + rect.width = info.faceBbox.x2 - info.faceBbox.x1; + rect.height = info.faceBbox.y2 - info.faceBbox.y1; + + bool isExist = false; + for (int j = 0; j < IDs.size(); j++) + { + if (IDs[j] == info.face_id) + { + color = Colors[j]; + isExist = true; + break; + } + } + + if (!isExist) + { + IDs.push_back(info.face_id); + int r = rand() % 255 + 1; + int g = rand() % 255 + 1; + int b = rand() % 255 + 1; + color = cv::Scalar(r, g, b); + Colors.push_back(color); + } + + cv::rectangle(frame, rect, color, 2); + for (int j = 0; j < 5; j++) + { + cv::Point p = cv::Point(info.faceBbox.ppoint[j], info.faceBbox.ppoint[j + 5]); + cv::circle(frame, p, 2, color,2); + } + } + + } + + + imshow("frame", frame); + + int q = cv::waitKey(30); + if (q == 27) break; + } + + process = false; + processingThread.join(); + +#else // CV_CXX11 + for (;;) { + if (!cap.read(frame)) + { + break; + } + int q = cv::waitKey(1); + if (q == 27) break; + + + //cv::transpose(frame, frame); + //cv::flip(frame, frame, -1); + //cv::flip(frame, frame, 1); + double t1 = (double)cv::getTickCount(); + + if (frameIndex == 0) + { + faceTrack.Init(frame); + frameIndex = 1; + } + else { + faceTrack.update(frame); + } + printf("total %gms\n", ((double)cv::getTickCount() - t1) * 1000 / cv::getTickFrequency()); + printf("------------------\n"); + + std::vector faceActions = faceTrack.trackingFace; + for (int i = 0; i < faceActions.size(); i++) + { + const Face &info = faceActions[i]; + cv::Rect rect; + rect.x = info.faceBbox.x1; + rect.y = info.faceBbox.y1; + rect.width = info.faceBbox.x2 - info.faceBbox.x1; + rect.height = info.faceBbox.y2 - info.faceBbox.y1; + + bool isExist = false; + for (int j = 0; j < IDs.size(); j++) + { + if (IDs[j] == info.face_id) + { + color = Colors[j]; + isExist = true; + break; + } + } + + if (!isExist) + { + IDs.push_back(info.face_id); + int r = rand() % 255 + 1; + int g = rand() % 255 + 1; + int b = rand() % 255 + 1; + color = cv::Scalar(r, g, b); + Colors.push_back(color); + } + + rectangle(frame, rect, color, 2); + for (int j = 0; j < 5; j++) + { + cv::Point p = cv::Point(info.faceBbox.ppoint[j], info.faceBbox.ppoint[j + 5]); + cv::circle(frame, p, 2, color, 2); + } + } + imshow("frame", frame); + } +#endif // CV_CXX11 + IDs.clear(); + Colors.clear(); + cap.release(); + cv::destroyAllWindows(); + return 0; +} \ No newline at end of file diff --git a/Prj-Win/models/det1.bin b/Prj-Win/models/det1.bin new file mode 100755 index 0000000000000000000000000000000000000000..3290928e05fecd3b0813eed6e6b09ef898d86888 GIT binary patch literal 26548 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 literal 0 HcmV?d00001 diff --git a/Prj-Win/models/det1.param b/Prj-Win/models/det1.param new file mode 100755 index 0000000..abd7478 --- /dev/null +++ b/Prj-Win/models/det1.param @@ -0,0 +1,14 @@ +7767517 +12 13 +Input data 0 1 data 0=3 1=12 2=12 +Convolution conv1 1 1 data conv1 0=10 1=3 2=1 3=1 4=0 5=1 6=270 +PReLU PReLU1 1 1 conv1 conv1_PReLU1 0=10 +Pooling pool1 1 1 conv1_PReLU1 pool1 0=0 1=2 2=2 3=0 4=0 +Convolution conv2 1 1 pool1 conv2 0=16 1=3 2=1 3=1 4=0 5=1 6=1440 +PReLU PReLU2 1 1 conv2 conv2_PReLU2 0=16 +Convolution conv3 1 1 conv2_PReLU2 conv3 0=32 1=3 2=1 3=1 4=0 5=1 6=4608 +PReLU PReLU3 1 1 conv3 conv3_PReLU3 0=32 +Split splitncnn_0 1 2 conv3_PReLU3 conv3_PReLU3_splitncnn_0 conv3_PReLU3_splitncnn_1 +Convolution conv4-1 1 1 conv3_PReLU3_splitncnn_1 conv4-1 0=2 1=1 2=1 3=1 4=0 5=1 6=64 +Convolution conv4-2 1 1 conv3_PReLU3_splitncnn_0 conv4-2 0=4 1=1 2=1 3=1 4=0 5=1 6=128 +Softmax prob1 1 1 conv4-1 prob1 0=0 diff --git a/Prj-Win/models/det2.bin b/Prj-Win/models/det2.bin new file mode 100755 index 0000000000000000000000000000000000000000..97ffe9f72629a3d6016a80251a80573ff37f45a2 GIT binary patch literal 400736 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%0AYt8U^j;!JAG{iZovXdz zUh;pmM$3Ty+ZhSL+7U4C#R6zKZvc*WHKF^3KE>FV@ngb&v(f3d_-B)p*tEl%a5vHx zvdk>taL!r2J?9XHzTCu;=iXt@qLslnM+W@-uVR+=Rd(*$Zd%?v4L7}dhWYbfQKO;w z*;(9^=DeXw)6=9D9!2ZZ_Tcjk0|eDNo;*q&2-ld4XUpg8Mz$$yT(Sl7<+4y?o*$~0 z_2w>|K1tUcqcC%rmN0vdKuz3mX6?HV62q)W?R_P8-CAhDdKNiK4UxK(q!|pMob^zEf1PJxY2pPMT%T>VhjYlC| z^$#CX)5Dq}3ua$eg^@Db;ndZ&kX`+djSQqHSH+N>UTjgO^8Di(K z2e9yCI~=blK#${wl(u{;L_g{;nB|KOxKHVDw<3Y*9{)=E<`U?6J_=$VyTIY%gJfHC z6g}3TU>$QWpsIq%-KcwjUl;Wfs*RRFNOcQ)7hgy*c{lMv%_JBIGPKKo8a6MJ6^@Dg z@jA&@COyWH^_W3aa3Yqy@E=MO9>!we_iPAU*Ms^l{_M0-uHE&@UHrtUvhZP^RGiga z$4_^<(C&2ug}3-qmrH*ZrzI=2mfGTUFC%c7xtHud>%!*ZFDxu;IThx~z;(F-njYss zk}IM*rPt}xp49L_vbL9hE;ux(xDG)U2u zY=Zol%5QfrO3WucluKb%`Q@zTtqq&hB=X39E@6oUde|YogeNkrY1P9a81q#YukSVI zejHuJ%XxaC>WS~nZeTvYz&8giZ1phAB_9?(xQIRVYUI?a2yLVPu-}U9bl_HBcr+&t zq6*)!pfFoDp{#=SY2VGR%SOV$rBd*8b{F4=H&MD(f5`K+5;~sx(od607SC^?l`^|A zqGSa(o&QS3xgPXrxs1^LVW{xMyh&>KK~`99_zDeY9Am8!FRAJJP~pNGdur}EPQS(u56p zA}=lcI}Y7Bh+Z7O#L7j^z~QHhAiyvaq~a|6hSM}M*mN4T?E~mfPBL%kBSqO4XIOU0 zJ*ZW(j-# zI#%en;?8k@S@ZOLWEs1Rj=O%t0zZ4Uc&!%mobVr8G%}ry7(0d%4LS7R*o&m)TWHC^ zzVz67CHTdsG6ma+6nVWizqhyEQpntS0{nSE*s$f86b2RXS6h zOWJClbjN^$F+UDTH7~uxXnk3H@im*pN4N8W%?ipnafRRBvW09-EZLwJLF~UTMuPvK zX<+Q|3^)85kEg0;@yDL;q!s5TvfC}9)8x)BnxgChW|BW>eM{^Le_h819G0iIkp`Sc zbBA=8&SMra!jx3JyRc&9U0&U-A9D>!!k;_N@?-z>CeBQYra8W6e_OU-ZfXJh;Z{a! zM%TzQz8QA%G3+X;k7B*@y=q!DUfnlM%<(@*EUYAAfZB10T zxSVSoP{h(!70`>nlj(ciN;3Q5&ps`cp;2k4XnLt8rS2+X%AbS4K{tmT-aZ@#T}oxD zPaGjooZt4jXU|)>MX*^P9x(4Ey^ zHlCfT!nH}`=qm)Vi{61WQFbi-a}RF^%ufSZ=8^Of0&^ zMsYjwi0)$?J->vCF2&gWel&(nj=De}V#-*X|Yk1JhrI7&~ZX40`=3bfj=p7hV3 zC-o1RbbRSi^1mr<7CywHPt8>{~|)Jvy`~M2T+gXrsjjrF`?N-Qv7RhsN)oOFGe` z#P$6*|50NgJ~nSbuhIzmyV8p`#d=UdrVNE#-pM`~8UkCK!BQW5Vei_H^7gjQFtA`3 zS8-OIWgj>Rs^t^mPp1czja?3N^*UKxRW~!+qXGxs9^!m$^X!z;-m_>sRZ3f2Ocpxs zOi^ziIajq(|8QlN%NbDDj!fFaM0ReRIvt+37`#Vn310CnG)rt@L>?(8->?@nbGj?O zyKtUOP+vz89pW1K*_qpL?l*3Igw)$tmnkIwL=)~4?-M7^w1>OWJ4ZVTHIRX#DX&;Z z@IL;p==xF}GP>s0s*#*g)-`-v7fnj0+u0GhLSCb~7j2qd!LKkhq?MRTbJ~Yc^qq&8 zaIcoBnt$P%%k8PG9Ds>zNCnYrs6E^iJVuTbFY;Eg{#A$A@dY2@Uiv;ZMz4%qo{dL8 zYzEcI>Qr&=0;L}u2)A9&;z*G_J8!5jTyk54Tl)KQek$KMndR9i^KP?_iusRj{VY+A4l6=9d89)3I3E|ScN5O{kZeHlR>4n44kTM!PE8?o^o`df47Rr z+(3?6LZ*>_u>s8tu)#%7Gx2up7`hdtrJs~#t|=n7<%%riEg1lv zE_;~PZFS+&sCwF&G=ciRTuolB2IQZ-5^sKbk15-d*rX%Hpf%(KDNN=`*JdXL9V(*; zjoDN;FOZ}*^Ks;YHm0%C51kFfeE-{c8a0?B$@^ZkVU9AzYRRE|uUa(ubRHd2p3tV2 z2Q1n?1cu#Age$=lQ14qTJ72IB(w3ytUq@RzKj|Le64S_gSR~G{@Pwp|QPj)v1D-Q7 zgI4ua_BLY|1kV%g+WVr=*X=wr9~^@zdQVw~*A=EGX4QK+M{`=|cd?Yy8d$xf9hXf! z%%8{#!;YsnsK3HWwE5x2uAH4AjH=8dS)YeYvtbswci2#9(q@YB)52vMJhwRJ0v1Ks zq1C5y9PTj@hpWj6-<)F6t3@BIT?Cq|n1gX6PI5Bd%EBFqn1!lz%7`|i zq;(&e>yZ2Gm~1g_dN3NMc!>Af@5QM?;dba7U5{<*^~^p`QKQRJ?)JYqKuSu^%R}1zKG@yjaW7ylkF``Bfs=czTS2- z+c@htJ>QaolbTjS`bSqf`mjG;nbyeN@NOW}Hb*L*=gI0rS5ih*Fx{VGNgt+d!ELim zXus$^Z_=#ddJhSc_AwGLetjt6XMHNUcn+8KY-ex7PQc!ScVWK8P&}Tu87>AFL&jhW zup9M`#iXmlZebv+94q0}t<31de>oWWR-Q|8mnD0LrFQR2YMDv55y?BM^FA)}_(-V=+yMuHwV4wX;Vs2n*)?VK*img|^a-V&}Su8SI({ zcds7gvh?~$1}_kuXX71to7*8^>t}(#C-i0?j?1H(jt6NCXYAF*Dv=L8hSu1Or(T1r zX!>4R(tCInFR#$2%J0wk-ZBAbWH^>0@AaVdh%3CN*K7)LT1l|B5r>b;!Fb~qTzDY| z_kYfzKjLgUWX)RUZWK>zp0A-pTLxm!12}qE>dmZw#?s>4-Bh+TmfaHh z1WFs1;p2y6=Sj%^wmfDop&>B+p&}HBP^FRYTe-M2 zMYbKqZu!>=^t?P3C0qXRJ9pXJEpHXO1%nS`9oLt6C0j#Q(rT>rJ&sRSTw^o7ALLfL z>a(KMQQ~>0l#AOxo(0@=%76hy%+6t+n>%f@7$~fDVPQdHb1<`gzd9qw`i=B-cM(aiPvVV;o^idj2 zR&%G*2&Dk*Ei!zbSSr!5f&uhv#V-1~yO@q%kD_vIZ(0={OhXsC@(2wCa5n z^^HxyvX&~2yBPxB7gp2T3H`~aW*8i5M?PC;Gq#tjLQ>!1Y+#{|^!kV$%ze8F|8;mc z-n2N!JNGQ3fjx%gf8G#>>ubTCSCggn_Z^w^UojhVHkTh)Y0Z>;LZpw**z?1l>9CQ3 zMwIsII@8(zTRQ1WHk;Md58kgz!!4aY>`L#wY~Z??q_W-$Z}!W^>c9UmZqPrwyQjUm zNQoVb(VB{H46btKK_2*Zk0&#m7=!OBb!cV5Wd6+3`D|C06WvQ}mY!1@2UfG~*vHj8 zTeHfV0$t-!Y1nW&pPxkd+KlEX7jmhyLF)BX^g(|-&d&95f-23cd~4V()-^pIEJlW4 z(uG(mwcp3*t$4}r-|-RGxFlk^lMDNOUCeKEx-*N^7HO<(2w5p9(yPc{_&r~Po`08T ziFsYTdcP>Fc=??BpQ7{d$Lf9Kcs5Cq6=hUNQb`i$zK&I*y(p!$C0ewHvPniVqC!MU zloWFA>z2qap^}Kc4QZz|w14OK2Y7j2p2vCa`?@}#_uKT+UwTr`TXeq7A{xEh>CVT) zxD_g4UQ_88--_#L#uYzgiDIS5xS>EQI% zttE%l5^0gKISx_H<}ST_Oe5wr)8@={(UEBi)1HX)+p_DgFH0aq-2o!6-k@2&m#nX~<%)cybh^u0iqrhL8VYig$?xX@q^%|ijuz&F zctn8yWv`&@buK4w$U ze{vB@yG2kJZ6{6>M}dc-Gr4 zwMS(CpWD{k&s1`g75!-a*cn9iSp&^eP{X6UByhyBbGYY$KKWZ0!d)N1W7uMKXtInG zB80ivd2bcndgTLMv{#9XpEwRjSZ87TtJR>Y^|KJ>1MN{f*c)a6CwDcG;nJD+<#V=aGHNa`-qe0zbKT zlf9PCWTe$Y?o-q_Zb?}SDbLe|+s6k&Y5G0V_x>B1P!~(WTLN%cv;xgpaLrnJ(sAL| zlPYU{k38zrHAVmosN8 zxtk@>g;!sZ#5<$t@PbCVV3Iy*lTsqnD`bR3oJN8=#O~LTRl@yfTfFDdMI%2q;n}yj zcxR?OCO95O4ciU4FjfV7UJYc&y8ltdkWj4dzfUJoSqS%ENe{lzA)kAWgZI$skQUuX z%Kc}+x#O__i#hsU!j#j#5(9k(He^?VEQ}1Phs(Cdp!KzuwLzB|T4YRxvNe=kty+T@ zEHrR`&3w>RDxy`bu5@<%8!C7A0wosebbR-Dt2xDf!mhQ8sBq~YSvohB+{>z<{@E$Q zmy#h6=^{sG`x!yqT|0QEwmnzp;Rjhta7Y_D={rwXmQ~fpd5V}Dk zr3ETqsYBXtGu-^u9@fg_LgAF3)V)sz;?ibXf4wk9^xXd@gVHSMopDukd2cGsQqH8k z&K>mVl$$i#MFzF>M7H!DIdt_CXUo4olI$HGqJP~SZ|$RGi(wAAEfmrHh98BagMU(V z3CE|l@;pCeI;?+}K<=@9;Pph0+IdXFAu|K4b1L2tx%*?=f0rFP$+rvvzIs=nT0>Uo})iB1IX3y)j0BE9R22Yk|_PqgO%rd$*`t5 zOS+|_VMTo$@fi_C%d;dAUM|Gi8IMTb(m*O5_Xw}olyDNEqQiCk2Q=SsihJMF1_ND7 zaFd-LL`e$}-_$}~^Jid3G7=4`0I+_s6DxeeAY-EeS$kZE7Jt|Ww{a?X;ZfB3HkQop z6muE!H^tn!HyLXxgP*h}<87~U&aZ3;U8)sEb2f=A+$SD5f3i6}kv|nY6U^`ef5dvz zt!Anr&f+Z}jfQAxMQd5r?PSoOBG5{E4`tptc>h5zu~L5n9V-)%Z>MyQ(G|MqjF{2- zK91xKiG=6_^@0sIlD!;J1sa9N$eeR|xZdqN^t(IK@|!d9UbrdUx3ZEv?T#TwKiOdC zCM|Md#uOO0au;TbGuj`!&q8YRH0sk@#@&j%Npqrx!^QDk!m6??s_Qcv|BEq!C-(cf z;Fb5$_5i?zzHfBv`)suT{hOGz7ZS_Fc0us%CLKcqz}{#*cH1AofInK~tgaJIYFvTC z(;acGW+86z8ii-~%o80PNw|z!3R6bNqVbBWxNn9uXXCw|d-&Cku0Iz^R9Y2ap>-R* zyhM&XsA(>J^7lVFDba{#%bXyb^?&62sGoFUj~6#h5=tG9edB~3b;5!Ha`byf3#~Y2 ziq$@KFkn&%+2d%2Yj5&suv-oHzBI(6;v3l&+&~|Mt6Ts6kE5D;@2Nt95lM1-KyQyI zBQ3ODpwFo)^56bBsJ3i0c=(+ngPn9y5Z$s%Zn$B{K4mCr6TLhe9r5J*ZLoRc zc=}8C40Z5W1A0fNsmAijjljY;A5GZR`cJdPaP zkqoil9#NCr-Dt3J0IcJGlWnspiI$21ix0VY_}xfqnkXZ_E_*z^-H2S@dXzJD+Dc@% z6q2=%eh98l_7X^zrpw-05Fuo(aLscN#yY(c;;)L?)MGC6{Iz!O?^knN%CCgJ@dNRb zOF6DRBKjgiE2+YREtvmkAL&%JqWQcoygZag(_i^wx7g#e(on=#yPI&Bn-)~LS}J<18>{AUfy{$vsFo>Y>WF`VYaDk76G zB5Opi*1{bMIBI_bcTsx`tiKmT*?LVfFK+@|eVT^TtHd*0>JTzzdogW3Xo*?MN5vVN z3D?j)oLa9ifjKu{(qju%Y3S&7GB!u_Cf7F5;xXT;!2!li*b&ApzcCT#ok=44cNU?d z+gb5B(ncOud?5Zet%PlhbV1SVDXhBsTbLl9Pd$hF(xkE*lpmP^i+>&$6xURu`j9D* zW;7b?To~?ZUeATzn}m`j+sMlNIPy^`jXFR6O6pHH5N&%)ND9}bu{QbSV?iaoE$;n? zmcNIM<9|@qTlv;+E}Vrcd_E@XC6J<%pJ81%2d8H};CfCUfjvzl!FZvJF!^UO{T8nQ zTjt8q-;?f9U$0qE7<`M{*)^ziL6tmsD*K~B=^46SLzQ~#%H!c@@zxWw>LDiEj{THo z)Yj%Xob7yre?On1jTR=nZ}keySYm*ljmI(Ji4ocTHxkXB1Yn`aR4X@BBL^EP&Yqq~ zKGeng7n!{P00p2$}Jq5oAD(^fZ6?79>! zR9D0b_C`(gW~_Ko_#lSaUFOrfNuN;j*b(Ay_?*_2p2e%PN3eL_8#l+MQbmWaI9y+r zb!aY!^6odV^ldt^`QQn6uC9kyD^7A3mL7njh;!sp+bl5Nua6OVL(y?xAQ>*dozl{| zs8{}&G_)&1_)iHeZuCH@JQ;L!*QB2%KhuClJ&ZhWK>v$!5YpChX#c{TwzuD;8_vEV z&P%7lr)3@x@?;-Y9|<8EuWyq1?|V4w-30Ds#?u>D_R-u0fjU{~Z?GSPOB}pW~C>#k8<73iPI4$I}~) zF}ivNq#uqF8D63ICxt+eZ#t>S{)O`lj$A*nQcdh*o<=)w1=zbod_T?yfTB+xn7z!tj=8^5=UX!I0yUEhz&!m0W65{`MH<9bK7JGGN zLSnw?D6dR|d+nAG5wQiwS1Z7hh`XfkWE$xWwgb(+f8@B?dZ@8kPLg+QBmPnA1)s5j zR4-r_`Z$XZFn>9EMa;v!Ygna6 zl*R{V3e#odXk2Rmq}0Ug?EW{(RZp*H<{Rm?ISJIM&Rzh zJojmEAAOL#73Z4<0yj|3YIw{IVn1>T?mD9<&JM-iPenD|DbHwu>=*9igK;$9`z7~L zy_^n96r|1vkVfM^#Jxuxx<5oU$lMy3|{@CDL8x^gWq=Xyl0d+<1Ei3ABY2l zJEW1n-lF5$Gmn;R5K*BQ9+RnqGGX=g<6O;z0d&SvN#^co$ZQK;@npOzJ32yvg>?nt za*cSn9wIuc6VmZ~!X~^Ba+<4HD@948CFbu`qpwR2kmaKD#j4<*uu?sqcobfP^2K9u z?a>Zgm^MV51Bnhti+`osJ3QDG-J^KIFCGg}A62HNpp@wMx>qaB9UK@T-XV72@=^0x z|4Ab@AI^x-odGN*^)76_Ys&Y}lw|O82J!u)%7vl&crhXo56y;pQ-N};3ZcUkl26Itde z`WfTxWL)Sqq>taKh@?dS%OQ{4_T-7TP5(;5`)wV6|kF@ODf78&@p z41M%;VUMXUTi*H@SFia6-U;r!W0@siQ}z%F_Ju(Gfj7kIiTicW+XuKRadsiybrSRb zi2N`g1$L?WJ*MWQ2&=!ZMd9p2ktuD;o=gj&l82YFKBF#Bol*^M)PMzAW1DD0Xv|s%qe=!X5U9Qs$zZKb~A!6pEejiqz z*I}BE{CKIa+o0&=NdDiSRM>G-mJfW_59xmHG+p$JEy?gA!%NN*>Z!}uw2tA6FE>F? z@B=7fqd+riHDBN6%6~XI0XoV?@Ua7jfc^A=^h1m}e{qQ~*;qSUc+fhC|NJNx6Kh*& z{`%!iCN&AJ+73Y(+37$&S@F`>&G~=+5rX`TQ1Ar@aL$vrxvu&dBBIvuyq*C+IH?L( zNt*J;L!a?Jp@Z16{NFG&K*Hu>bTaznm(W^MC*G`Y5c3w#47PKg^Y6Wvv4hUnp~b+4 zDOOv7ox?adJt>h~nxo7&-522*mSdpVU5{Nq)eoV6?~~30!O*`u7b6m1W7M*d7}zFH z`g0Fpw!R84Z#;|tWBCtbrk9af2BF~ZTZC@rXE8`Ro=$f1;s+frfw61fLuN)C$xxEx zi|m&0&!0KMPv66kb0CDT2${t<2U+nNAH`FJrxq(-=fciDEyYyVrI_$e3V*mMVs4Nf zZa4G8Eiwt*5=CX^E;kmt`xSU=btgR7!h?N#Da4JrfRag1$%x63xJE@}qFUS~w^NE? zpWy}kEdH${rWy0k{z!`~!jm|5sJJidibu% zhEt1XkR^IYs9DV^(pZmBZ@G?TM+NYM?QC5M6w@cRxF$@Ddj#O=l0At(dQ&5o@=u#&rWY z)>NCr298T)=l4x#2jyPTjTTd2fu1_2GA@ryNmM3TE^53}ojLdT_)y4Cbpv((y*R)k z3yVg&GufT4?6vj;W_te;OBMNv&Le8+fGINUaLq8jw4|RD9qQrJ`xfGypO3I+b{dJ+ z>qGg^fAL4>Dac{v_$}rPGWYway!b5MI6arSZa;&qs`7l=T3IG(G*a1!B7=}^JmkTQv^3br`Yc{&DbMOG-ce7t zA8>HG3LEyc2A=)Q7iKhwy`l}SrTa}&`C$+K!LOz5z$-1}7c@=hXVyB>=igSrhTugI zWxWp%{7A(qV!mhPLOXD-{3}e4>%pZP1Mz-!D*rx7g>5bcbe;>mSJ+^LN@fHb`y&zgx%HCevs&3ms|8 z+t(cCKb9_qld8+`@Ln5!|0hJ<;9X2IGLM%yy-65SGn{4oZ4w!)>bzU~AWS$#iRtYW zXkO;V-rA~D*SjL4!A_kmcySi=XBE()bKLQD;!OzLcAOO5G)5_}BmCYe&7iQb5{3o` zuvfFw*{lks`5gCd_yXIs zo5|`yi5M=r=PkvVeMjRM#Mj-VUFccXGxpvcT@tkt$1DvU;)Dvnn!0 z|2xhwynF#@oPST8s$Xue|dK5bjZh^zw{&CSCCt--D z{o;O3$2SXD$T05ZDnf3HSa5z*<8k81#K8`F+O#a<7bXN4Ay;rLnOs}guw+}>S%rf!k!<5jVb4F ze{d;kdZj_HoCcQ7?`JND$cYtK5W}{$v3wI7~5FjQ1-t@}ip!UC{u1X#^ zIi5g2`4~E~u!b04yhES4z9)I&94GzJU~=QtC~kFU!S$Z1mvn1-f#6-`h22kLa7n^c z{9>{d9iQsJv6ehK(ESg6bG{jdXe>joYjto;+7g_5GVw&Y8X3FvBzDP<$1kfcki{E6 zlf!ZQq3Y;X@LMYOTJy}{dq@P8=Yqkr_!>kVlfl%dc9_5KDEz&W2rJ??3!~l0Fc=th44_xD#RruYo#yj^Xt$m!o+7!E*~UX~Vp! z*m&F*%e^e|@j6YsHY^iAu6l{n4j#ZuqL1?P*9Z)_nM+%&Rp7vhTww?eBj0zs4u{3b`dstlybwqUczBFAJUQ9Ixu%q7JYC_4cA;Qrn+-9xGk%X0M|4De0MCsl@oTO zc#Wp3$G#!cri?~2YE0}U1lYc-1!up!itp6E&<5QY)GY2tmDw(sewR{>Y5jP7(*bJk za13uObprXWmmq&EywoUPl27^D2W?KTV6sjh?Cie`vrb2mWt+skc~k>A|0Is?(-!wg zj(S+NYCf#ejl|Ikv3THOrr=a3z@hDLVV1uEESNY@xRAXD-YHJt7s=j){dkF+zx^wi z6zKAvyS_vBDt(Y}8%GV76;bbvEwCt72PPy>0!8&D;8&>uZxxS2RJ%GqGkPA8QHdh^ zn@ssb(vzvQ#yFDoVgT5VoP%yo*{HK%8!>ve54GJ&(Kc^6IT2BaZR)r2UCA2G$K@kE zHn@aV+vGuOWG#I@_Zn&(Q02o~_womQCxVK@EzGW6MW6eefosi~m_5V*k9jv&Tj1Tca?YdBWP%?~!JgyQdT@j|(j}-awWAIGoAsAe| z0j|0{#q!>nrSB9{M28)rMLBVp(GtVGUtGo2Drm81VbW}LVh`OEZ^87 z5+?NxPTym);C>YNcCXYTsIz@i0<8nW6RCq-FnG#lCn1ws# zccQBFSzJBx7?SBa^Dx8r5o4JPkzX$WhUHdNllwASU zPcGnvBT-nOTn4G?;wtZpD`vc|7u`6X%;Y~p56*3&gYJJtr|>*n^Gc3wTb_olGv?z& zC08b)JCg+lUd5UBqac1nDIM?mklO8F!X(vwU^Z9Yn5 zE;N!0KYox2i^oyh6%F)J%1vR)_Rn;G*C(ND+Z60**2dM_Wr$b9M})PjQN<3#Ia@Nm zmdeIdkL@HUeLgfQ=-~~&eQ3P(8!<_h6plHM5L$e^xDDTc`2UE9OWN{Gt2h^jF0@9g zcm6o+`zvc_e{(pq!5^1@MCuzX1BMcoaC^KH*|B;&9O@bdi8sf?DIZQ4ow%MWf9t}9 z^^L;L$M@jUv%N4YAOS9qi3Rrt8JOiD=DK4hz<%vbP(36U97+|@L}LW1$|j+BCCBvA zy_})gxtWt6f?Hyak$L;m$&(Z6SiNQhj2avUKj!P;s?KbVUu#d#-usVE0Ap}b&=H=j zeu5GTari+#7xRk(NbN*t(sgbW4Y^eSdD_OXK|>2Jtj-1%m4omk$`^`)r@=s{5oG$% zdOCFYQ~IJM1U|d`#(r2sEfd4kYmK8~4^wU5v^lyXO>!GmedaZR? zP7?jHA{=JjD4=f7hm(BY^Tg#Lp(oc~5~M$jB%>Q0VCEzl7-OkN3`Sqf2x53ALhexh;5L=6UFCOyA^4l)=h?3oRGvyTc*VB_11}MsuD+o|1t}np2t2YaR zaqJ=b=9>e)?d+oUHHBzg;EZSXQ=x4nM>~Ivz=r_YfR#sf(Kuaz*&9G!XAaZ^CK!;%HRLQ1G)pi251@)Kl~-Z`n2v zJ7;TRlToF(^RLA9T8ilL-jceXG{zUtr;5y#!J_-_0(ERyD{L)lBlbS#>}y~a8t5&; zB0oReWfLvDGLPZPkIumN;(HO{*h_|2{iI!6l(BuxRCFC`0+A2G=pPM9EIfV;6z{I2 z!wxMXJ?%Eo6BbQ8CmNH!!*_{yr#bmhZVfMw2EkK}8)QMjXJYFdiaFOfEPiN66V}Ag zZyM#+`NQuBVQ1gcKIykK_20?T_V43)#~lU`?I%U$Mc(JI8~xl3ufx{oe&xX;=?HQn zcP}}s{)qbg-M}@@HWrSe1L5ayfT!0cL7uBK^(h!j9&8#S@}2`}U&wec-#QnxWMoLV z$Ryw5>kD(AyW@;1Z<1W7ZvEnv2($T-O7_+Ik+bEa;eN_W641~?(zs-D;hF;JkCTDI zLz(2t1z$SXDw#HmIlzb((Q9}_krY}?pfT9AhbNMB z$Cp?!kM2v`P1>yQ4Vp;2KS=Oq^e~ttd%*s>dXipNP--)zfm3|ZO^I)VaO+V&(M%D) z3$uJ6^B9GujowsG|2G#aF1wc*nM1R6p^yNf)a(2dnE6KZpT4Ok69UJ;sqM>g?;m9} zIW`_zcH85TudleAn?W%6YCgoR1elXCgBnLKAS?PsHrGkO?X4@wqyztv)3YS-ZDKfK z;?LdM(M$S!2Z02+N^G(wLxj>lQsi?Gw3cKLvm;aSeA*2h@Cfja$!MZD)D+jPcEa=9 z7U9znJ6zVil&@Bw;=1(;lmy(e-qB%AzT~YgbquX0Z@SFExMUQlY&}i2C+5+f z!N%laJJq;y9&()VT!FceYB`#k&0UgdSBt`o(slQn9 zx#uKyHmi{zT{H2+R6-3>d#IA-0g<<@fhXteqd{W7@I@rh$hX0;=Fwdtqir?J*P4V^ z_T=K)>vbiTZy&;>eLIkYm8Em6i{Q1I=!u)|2<~M^aL!?h$${Ug)0D?Tt~g(NdUGAd zo{FG9=10&wZA+=M&p1-#HVR&a6cVM(UBZGob0~k{4JIbz@p!)u={q+{2%fQ-UOV1; zeVQ;BzkH0O^D-Rh=_Vfw<}j7BHrUTHOX#8|IRsp%jiY4^eN;Ii3MU8FmW~|viF4^OK@&M?u2Qdw z9?I&p9uc2K^6ssnUu{)klE*6wyHdFu;cdh~){&^G8k1(%Bi!ksY1I74C~MoAtuRUV zJMlQBDVXME6N}Re;dOSY@SwgzxFZ)zi-HsAjf-jY;pu4VduKE~sWOjlmz^hcjCo83 z$oSIN3k_+1L>k$ksY$Z6Hlytp8{94OyIrdDIUL>ID0H%~=;K z-6n2N*;Ao%?@E+-#u3f4Q?8H8eMUd>HPEfw&guU{c%;RF;Bbj3ET(XMyAk#UEdZ&V z$=23ulzFGYO6VT`h;*2*$3)+FR1o=V4ku301tpVku9!_9|IrUt-K+qib|$H*JVR9W z%hMS~;#|u@hL0IEKsdHW?9#jcrb^4MV*L*_eowXmxl+?cE2lYQf$thT;nR)_CPv|q zd@HajbApif>qyDvp_m+X5UL)YCVBq?In#qzg#neX@Y(MQ()BAvIBst}!bygj3lCT_nC-i`cvJ9{HFi&t(o(K=ZK9G!aUS!y&!F=e$rA)1{psPp%Y3)aXzTuOu{@$sySgOx+!Qsax9|Ttsq(8*|r?ELUrs`ME|| ztdtEI_J;h--RgL+Ne0sOZNc_^5e5fo(vH|HICBMH<#Jt-gCoPc-fQOGyc&dkdb0ex zyXjYeH^KmggIz!$R-0P2GDptH&CpXrMGsbaiwn;5oygVjBFXo+UDt!kQWtXy_zI! z)G#5c34yR7Oa~Gl>+qSKA$W284*0p}A=OE~L8j{M1#hhZ!aDbdcyLq<_`eGy>0Lw6 zAA+o7@AlI!RguZ??Wged<_^kFSinyW6}wrF<8eXBGFqAX7n@WV z$^XZ*zv`kRY}z6|dUP;Vb!;znygmn?vwZwKs)#Ny^2EhPa`@Lm64D&R1FSl72M4bsFJo z1y-&f!y69Uiw8Obi0%zJ9MmYo{1XP?!{$^HH~$s=SS~}(JLcitIx`mb>LU%gl1i_f z)5Ev}7spz z)qQAtbW=F8Ta!=GJ_mRHxx=l4JB9rI<@{_lI~--!MqiCT2Wd0s(#_#g>_}T0DKS3+ z=V!IjUxPj9_}E{kF==Kt>Oksqu^rbX$eA7wGWUE0{`7V(8GeEElfK7j% z3I7?tfWi5fsHjWC3%w`EI@NyiVrVGZT|Wty7C~5@sfohv5=^e2V=YWmhlt+}kHo&no-?=Idn z72W9@w6URh94WulPHaVAb5(pK*y@S-i`N}E;rt=EyJ0WP>r27qmd{c5Zxgkf+60~_ z9+Ilr;>^%Rg5BPn41Y7ez?QvgXl$8MdeOUHeBTb?slG6gM?3=iXAk1H%^Asmyp;;O zita;Wzz?DlKb$w|%7th8U&udkU;FdvJgmI`7H*GDHCy-xfGvV?LU3|HA3ND&Cj#mA2BCoW~;jbda z1-0%}XMT)T=w(+XdoK-!3>(9%Zi~a4Sc$PmAEA--Eup|5lJqtoLY0}~Gq>MNm^7+| zWXLJAD5Vf^Q8S0YkSa8^awApm?{nky;+fnTYiL{CM<&-zgV=dh!iUaCZrL{;+*CFa z1C!&(xeNvJeW^0#^ z6>i5dzVkO)NE}DE_elt!B$@t@<9O}AB3e|f#|_@5!D$@hNW$NEC>U}Q;(KloQ@=Y< zY@x<~ykvlqGlOA;&H#R9OCd_u$3w>7D{%7FUg~*x5bRiW9?m9>MZFXb2P$=v5~*7l zFL{mJS`&(ooCG{pHyU^SvBX~P57y6VFa6ca?+bT@dn!Juw#Vx(%IK1_2LqzrY31aRe3F*|>>blYb+nRr;deMTln1bZgZc!oNq(&7 zmL+zD?O@8~@$BpheU>No+YX8@2&XrPQFc*@5Q}cSw0$jTZ!bb~jmJ1xJqz7+dc|k- zO5wMD4O)W@|2o$b+K-On3l|5%!!PCF^C=Z?7i7XAI+?$E_XNCN_ZkxwUXX%Q6uE|Y zZin7iRDZD?>f3Voyo9rS^Gts>J;sh@he@(mC*44qOQ9E=%J8*;6CHg1Dw^ltA|_?d zczn-irc^P3Rn6BEjod@{2PymcoLO07N4%52xG|Df+W(dv>a>JEPCNL`D>kq@zgDs9 z4`?Zi|4BO%O!>2qOIZ9$fu-w6@$(-gvABo9to*Mxl!mpk$JZ~x{rE86YyEb?WqdPw zj?Up}Ll#^tcvspnW+Okp@H2MH)iJrSP0aPq6fBzXp6|>zVNDUqB2xDvZ`S@F?D_0K zvU=6{y7)x)=+#~}O3xl9@nLLC>~1FcWHA5i(|X1VR*(Z;o3Pd77jwH7!F-%H@Qc-y z%T7oFt4!Xfk5*$>KR;ocx?S0rVmtn!l^IKQ=%JM@ zx%_RJK^WRSn12BByvOfw*cOzAK|PJ&yX_xu<)**_=I>y!QpWt!gN95=ZY{gg&tQhr zXV~`U2hzHecqG>YmKQJJUEK9-+77ISD;v(ixiDFNnz1&kk5Ohbp3ma%4eo^92jd|< zTY^QeD1)=>#`8b!SWt&@9rpUtLSCY?jGlkK9mA4yp>@1kS<1~B_-gD!UViE|Ry{`# zdN+4dr?@VzFvOc*AF0fy4Ung;&X+}=ygqLK9L0C7N#SQ#A3~FRqR*xHCNy?!Lc`1@ zto&jKza^lLpJ6zj*&Qjw`2VzE`PeqxwYU+6H?3#&nZeBALp9z%uE8Eem64Mhe-N2z zge0X5Vrwc_KwSsHZK~7x?`NCgoS4is4?l$tOB88KP6_e5x*I>541nYJkD%JlA zY!+Cm#_}0WlbBLhJ4?}T<89hHcp2u!(6SU3D=mXNuAkVvJ&ydIsq&cpx`@kPKpJKk_vY8=v;P4p&q`^Ud80E znKR4BufaU-IREqRDyUznBHlZ$kSir(SO4K$x<{=6XSDe;*Xfe{7&4gc-L#D5OsK^j z_UqZpi9syReIk545{;Hp$}HgfT)@J6{6N>M{BHYN3{o4(kD6}Fr)BhzAe#^z6!8kH zMhax=w_#;Y<@PL5_cGp7%3`esmQ1_!AB?+@!|soLhKnBlgPk9XSd*1J?yGR;qyNle zdRj_MZkqt!yLwU^$S4pJ83wRm4jvuqhpWnVsm5-LW1fDr&H?2_Q%a^OO`~89ZtUe=N z=ada@UlPd|4E_gWGmD{cS2feO?7)+*7F@066n5jJG4o6aCgnv=eBBy1YOeGE`|clS zr9n|_ztvtg?duD0kT(_kyvNw&k(cr+t_hZh^7v*eV}7uT z_<5_n%@0`=hC*xtd;2vOdgHD6qupgJykt8Ic&-7Bk`M4i)NOn}RrD7o1u?g0wd`k* zGD|k`<7YJGf{*StJTdni8kA{s{VNG`UmAqJ--%h91IPKZ_L;oCb`rU6s|Mrdhe6aR zY5s;uo9LhXQIfoBc-in$4IK0$l8^6*Wc|8DT*to{KJCy0(sek7PmmCq7T6-(A9*&eb`Oa)7|&#@ zuAqfX3VfCwDMWofi_glYgKOa;_#0o%jvX@N8#;{mpBK6@ZSoKBBquQPPAn_@7RtYQ zHxgWov-$DK{jlei9llr7;`eCP2n$xtW+Sv>v2xFHc7E=4l6C40CQX=&BQs~><8vYG z`@_?4V7WK1GCbR1iW{P=$lefDGfI>^@S{9SgEwlnNpEGu;K;o4?I9Ox1Y6ou{9OX zg^yzOiz_g@_!7T${B-76FqrMg*1~xSk9oZnf55NzB|2T~;(zyz6TgR&AS2Y+M#4OU z54$m&O_+CtKePOqb@prV|3+#VJv7jSzdvIpKWv*HZ!TX9)&&<6(SWM zL(3qNj%bP{-q+%3?5D}NV@U<6I$bZMjR~idyyQuh)CW@c`Xce!piaLzrQ#p=5*&5V zf!#IXMMwJ?9RBMHnjcZXU9uwEj90_7xrTVxBbkiUQW0n1uCP2Io2rIg1Fb%Hk~Kz} zCM~uteb+M@{3?oY=YL2Yo)5%L@{h2zZ4dtVHiIl5#qjyzjo5CnAGYNThS#pj(Baid zY(h;zZe2XAoa;i?P7I?Zy*oj5Q9K=V;w#Y#9|R9Z&!fQ*jGzBn<92=-K7Gew#>B;f zul-=~kPv5uwU?;T-%Z3bESJ=_CDSPRc0qHe40d^Sm%gh10jD|);d7xPw0W)~3))|C z-nm1sYswnI)a~oY2BW!PU0g!i6t2*M#_6EHTvK#7*9bc+GPvg(T4~m6MpjjAEnWfk#oJR&FCADt>>QD;P$d7Vib$h+Avk#YlPOtN5aF!@ z4=x2k?Dtb}Og){1mWaO2cOBHIKT1gN@+1c`XHk8bmeSjqU51YloAx#8;fIj?_w{yNN&M-J}uVel?^y_)B!w4V(HsfRg_kUIxHHK=Xr#k;T0eL!lRSHkHk+&`KRz9$S!aA)Kc0X!kMlNg+n~7}!9fFRi3M7ly;Ki>vAJ z?qDuBWhn}8qhaIpauO7hfs2o2!|0S&IyY<{N>=`&*PPFhnxrCFJwu%F`!6T`Bh|^e z2r+{(=|6H|<}hekdzAeBt}keR=OFKy6xW`ykUlGNp;-gfpnr!NsFvx|3v=VR+su%T zUpor2-E3hoIRQ(bZGxG}fka<#8i8BJVAi^n)>0t8cA0ceL?e~)>ElM&Z>)vwyYuOa=w=L80yLYe^(dhw&${dkBn)@z{1iy`v^9^n}!~#dqn>K z8*12JObj3E!Gbpr{$PT~@Ax#hv-M3s^k^NPg%#yr?=I1xL7KG2QQ zTj-9?n{<+T4EG5p0oA-l?K6<16t9N2my0lW>~_TP5W2VII8OGqLl#}k{Whs4&#m07 zX9>>S#hvrPJvNT?+&>Fn{%GUW(@}^!1Mug^3=-2)$W0KRanYTcFkz+}Tn(=xK93S< zs=gW9^QRQUF9*Z(S`T{B=P4T1-lLNPt?=IhF|QxuO$K-l!_eyE)JI2~T-fk}Y`Zs9 z7&o*9R&AX^8jco_gO@*9-N?QoB-C|5dyc+f6!Mpp1et(PcxjYVY5 ziWzkDhKHqje?AMvVs@rzy&YI&%WyO}jp$w3N7Sl2=)@Nl@UQ3%sS@|7LANE~-kfbB zS9K=bU6YKv=j+q{8_@&~7?XsN4j{GI2ySi2fNN8ak?BRDSmVEyj1`$Pa!Y#zGwE94 zvDnLbc_xu|54C_l0|r3fkjpsX&UO6TI~T8LdU48$2LLZzp~F4=F*1G*&gpE#j7^?+ z`p7*R@K+TjRFjDI`1K@6#}Lyd>>{CN@=&iBOvu~+O58ULhroB^LA9v=e-xd0R8C(P z$D5={g9b$!R5X&(bkBZ5LM2JcP#H?7L?}hZX3eEUsYC-6nnc~RZ$*eA5|I#!pO7&! z_uluv)@rR*>v`_E=bXL2`|}~UvoavZPe!nBODrs(DhxRdlDH_}lI)pMVEyWND2)lp zAv#sf4gHcuL=R=aF);^(6*c&|EloP^YZh72B}ydABH_mhSrB=r0S#CC$WO(0j8Z_*i0IY<9NS8E{PXg%4+KE zL-&k)Cgg(+y(RIEDEJ>DrrX_!$o?>Pl2|@d{donQ+_xCUA4?&5PwGkMk67w-`zT%c zUs8QjYckXJ@F~$=AVY^Qog$|z#*@`+1}PW?F&`tIGQBOzB>UDAGGwa;V|Gfy`oiTj zJ#;Kd7*t^9`#M63ng$l(xf>M6 zM8I%B1(jKGmQ1YXJ&dO&(Cvd-5cKCY%-sJ1@^2j=p7%o`V{{3MACSa3-$IDn`BeO% zn8VDY3*k!te0+A0ul3BA#6tBJo{8~n6biqPAP|493!P02yZ3G94JDD+_Sxi>A z3Vx5D3omMK)hh*x&;xrc;L=}ZJZ*i8zT7FmS@#oh-F0ueNU0CYe^@Zv&(+#kWw+tn z`kAoq_ci*;f@jGs9$>o{l(AQL#emPREKrIb1fTKC1n(a_slTwH1+10k3W^5iq9UJl zyn-T}+w@x6zUmT)E=Wi9c?ZaBp7pSFe>6_zvneBTyGVg$h2X)2pX5@^3;Od~AxXa< z0pD*=!|g`r1OszYskAHuNyP$mG!Mgj%ChwNpIyw9kWe-=K|u91JWy(g|GtioC-W23 zP_yzH8S1=8Dn?i0q7%|kAe#&Sww%Ot_l2O^UkSwpIRf?jIZ&Ya2}T|T3Rc?xfJOf~ z3T9cW3)b>|&t0WecxxVuMy+qy)yK4G*Zxx0`13zzZc#b5ZW_ZC%-9NBX8Xh2T{&=^ z-{*;AF&tNtg4Gw#f$YyQKo^!`(MS+x{M(0jC%?m6joZ*M*%C+dEBUjU5NAJn6zxY+ zsKVCe*uO!HxVH(QUpJB3W`4D4wNZv!twYp(NS>(ZstfY##lh;m8N5_3fkeM1W`|V+ zyjDI5t}AkIXO$TQ1%AQ7i)zqv@-+Q4$&8a!3x}2GkoZTn;qFD#*(3o+4)ArFjG;)# zx)={Sx)n5hE6;eVjRDQ4n=$^~UcToch8{0HxrVtDm}%=Jz+34pn$NmVZQteK-jI1* z;e)aG-sBqH_RpL<-{46ar)m<-H3!kqSsP9!O8`}aSDhFNQMkIkfqbo8j*Tt5>Tf3erTHDk=ypU2SM$t?H^#{r*rJcY#|)u- z$2;1K~@sjmSNYQE6oSjs8{rH~ySt>AU%PQ!zq7vyN$R-*Z38-AZB1s5*};pmH__;6aZ z;Oy@oboqaK@ZDi?3}4ki%BIhxZeo-bKCKK^SE5PTO)VTZl5eAKq|7uvzKZn*Vz6?* zBJ8&|u_?>wB!BPB#giZMa2=c4@G&5driYwBOJO&V(y$`0jPlr7&pbg*>l#_eeS`z~ z8RW>dJnA~R4kd&qlJ};u)bN5d7p8j~jn}_GrSt1KgH8Q(hlnQH&DF;P%DOfgRr08C z@;lF?Vc~h~R9tJijOX&@uu^MdAjhJWtV)tZd9Ra@q&oo()L0zj4AgS3D%XAED{bDi z6wNB~FgxiZT}4h(y+{A3i386EyVOLN?iOIVNgLl2_dw&Fudq(Po!#=*7R`pIa!C#4 z)amazoIb~#yBYnA&N!+M!k@MaX1#K!{X+K8Xl^UWQuL(CP6ZG%&rz`b;%Ued7lkFt ze(19^8qOsy2MbP=IiIKu_6`EvpWcTX-)AvZ3+{sTmPerCEDGM+YCuRe6HOKc!IVcn zAi3ZpF0(5F4;W;VgiQqrTECe2g;Pnj(IN017$wzlPB_bKtYFX8rF3iiWO62RGFJV-m`h~Bu@7Wlhb;W%l=Wx}HV_5ks2cy`@ z+&L*l8`1x&Xp^4{Y`$%Rl0}9nvn-B&40XVdr*z;!^jdgg>q+$!kHG97T{s|`ObjZ^ zh<>>!4yKuJ0y-LS5ITd?-%E0Ki7k_b<(`sV>@cSvO#K+iDLOioU*M8 z{++FZ7YAoxz>hs-x|J8WPFz|4_d*wV$teiNmp+BS|CXbVgBIrK^-}4~eA*&E4^O*U zV{Nn$jB8iNDQ|UggUD$dwYrGsqrGs&>Iho%;u(GIcN|Ok9<6oh0-SCYiwVl!kQ;La zv~oA&afc~z`Cl=-QEtQBb1!*syfvx2-He$pHQ>|wcd#K#Twwje2gWA`L;iQ(n^q-4 zdYk!-v{y9ooYP2)&hdAe#aqc&Un{!3;0?VH`I%T1G%@cDOX!N_Hwjg%CwI>IfymBU z5a0Kn-joZ5m3Jw;xgy|ai*GSi+3O(3I3A;JSJM+CYp_TsfPO0XV;{V!XFsRz!QR}z zw5E9x^4v7+^NC}=s*V+y=6a(`L?Ql#JrKD)3h#W}iCsp~0{#H+Jm>X$`+uV5mOG^v2yqAb3EB>OgXn!9muy&?^8^-E%w ztI1`Ee8t_n4KYro5+`PxV&OaA2G>GM?xC$H-o1R2XgqU;LwnZ4D}ILiRL&aaaqKKO z;=CT-@5}?ss;hANdI`Fm)FxTV&!M^?fJr=OiLW;%6PtpuU>CLo7wg;t+r#U?_iPer zFUf+(UdoW(u^R8a$%l2hzsaIjKhU{tEKp%CW0-CrnPe_Qw=4Rfuk>7aqp*Pte^J40 z$B#3oxpH=`y*$2nxQ2NW8Uz`?tZre?<8~i zODWlsy8}E#ETPF(i@ez|23Bw1juF3n;7{l@B6&Ryt|k{ju8$NE-**7mBp-Mf&4a6k z-q4i;r!YjN6*uww_t5p5v~kE2v+TZ-i|;?sDrHaHbRvg8TeM=oR~8Hu?h};HnuvF_ zJjrc34O~Rl;bWPVaD_1z;Ave_h1gPGc<>D?!s$2P$i1fEU&t zhUFGc#I)5EpFbH7d*;n2n}_1**=2FC((XN}9OknxOV1Gh3EN=iOdFU+qG`9tBHrC7 z2^N`YME&1XHtpU^a&4Us%nJ}D8E31}uSSmaxMz_UFw-Cywyu~c=orA1kz_i#?ijntY&zOr>p;=ZZcIQG&jW4dpZjyI ztfYXyXF4`PZ!tgnK3^X8BtC~5>BUs@<5BvceJd0ki=^v$R-UVNJ-joUgEzJ(L0k7l zlJzGA<+q9Oj+9o0m*(MXtt0H(h$!mdpG}(j!}$Hsf;)8Y4s)%1Jj`!DgP}SH$?7HM zq({{fL#`f%wrF>FT;78j_W`UE++g>GPjqC$M*2OnoF4Jwxo(*$Se-i_%BJjN!W{OX zq=2K}y$z^hcnltrmGh^5!sw9-SnLXTM$=nt|pVHs})rsFnT1gsS~uM`jum3#C%hHf{=?P##Yb zc9_CT#seoi7m=HK6JUnLH1MDdmFrmr4F=x$?bRmIrBOh*hcWnXr9Z0n-5^tYd{_~l z0pn{k5AK%6kzMV4wqlJDdnw$BJW+avSrI)f1n@bJ_cI|t?J@>iBizd_fH*ZJkPzMg zt2-}Jp_4D^t#C1}uB8dS_?pn+PjgUn_#QK72k(m5oq(G+1fpl@Y^Yi~4)>NDf>x$E zls^|I2gSyL)9ZOqZ&bwQZPAB@0abp+yoCBCOX8h{ccIA`sms=xsOc~aw?Dn4`V$#k zdfr$t;F{9#-)FQ@tmW&FCSEl4u>&-HyuMDH~C`bP-2uC67bsmmcM=N7p&v=p=?pHQdraEcsfTsXnIBB zhE3LZsm2s1O5DW$ca%-*45r`PQt{rsMWp{tH*xlHMbDq^Xn9?p3|AYmUJ3pv@t}9=RfkfI~uaT<**~K<%!`^5qR*U7!v(!iQkb$ATg|oZRUA& z<)lO8m-b;adc<>$yyD+C`6{gQZCr# zG%U!q0U@2w7!z#*9?P_uz6Bggq>Y7{G2>y*s%C7MzL1<=><0~-bg0bI^UR6OUmDEJ z!dYv+N^Z%s627aXqN~PCxT;!1N~~0=hPgL;qt_31HJl{6@)tle!i-uvt1*I`Az;5v zozHe2M5odHaK)yDdHFjXgKHzOyucJb8a;s@OenkD>@>TeYCCLuxd-oE|3*!}odKJ| z7P$N2F{;dx7bIOzfvn9daQ}acaLGG=#*b%sDM*)6g|PJ`xJ(VYrG&VGAZ@5Tk_X`x zYTO-DZv;(KxOOQQOI%{9g^W23o|g>2M$5^EyAo8i={i|^dN0TR92+J)v?t$*Flba7f+)rs3lHvwk4;k2&1ZPh!O$!nUd+{ zblfZhRvgoeWkk-hlzvzu;XBEuyF2M~$XQ zak2kghqzl_hYJP`fVJ(*1mv!TD^GSiwn$pbqDP)lws4^1Xz4Ag6|hK zG55#EB7VVz1F1vs?Ok+*Pqbw_#b9(XAuo5Oh8eA5Sm^nz>Q6Q z%p!bD=O{%&Q7F%(-1eBgt8@!Og%zk)btmbmX@aGH%&79zJ~Adfn`-nj5TaoOODfmk z=&w>*51DvjSZwv+h%e^~vShWr|FfgQ&@;m}rDSfA9v>ZOIT1~DT<{PlUNqu_*F zZym;BGefQ?{SNMZa|VN-`Qg)dOS!ef{TRPY85jK#$Jl4PP&Q-+{kG-(om4g>8qb1)kzhTNAXp8I`$0QL>r$dntb~j4c6aHrC0r91^Hnpv->vHUb>vt z5kPIDB7C3mhD^~oN!(qMNNCUipJ5k3PKqzwh*zT*4s6H2B01>WcLLlD9#d%@qD>7nFuP`J|F#c#?ZM##mLOe z!-!*u=}ULu^x>&+iJ#{?m;RUfp6nzHKT~rvb1XMQl&>+Hse_aBHzIP@48DubXmC%` zMJ{>NX7bNBc=5n`l11YJ1=t$>CGig=z(jv1 zaWf_HcEI(V{(-ws;s%KE0@+_mP4P+ixqSAs*m{etlcgv%2?%Urq zZSHlN>#4^|*pJ6mLpL$7;W4hV)90=|@4#1XOJOKbNO19sN=S&7JC*+ zP_LAWSnDQA&cy?#gi2gE2~y4(?B|LU zYct_mW@P7dI=kXJooOxvR~F>}*FFOd89pTsyM~$OdA=mXq?EcF3$v*cJ~vE1?@7;x z5;8frow6Y^+>hA?+!Qql?%~`NoN^)*+uKHIxbbAT82^VDUS&bz=_Q!Bww&6{_(vn; zPvDfDW4RSkao8*-4O2H?gvGbQf%Is>6hkl467V1NO`6Bp9_=72)<;qk%`_6R+7(g` z)IjR`(@=B03>@w_!l4%pjC-{fir1wwjj8kLf!IGhzfloq$a}Jv@2#g!RW;18Oc9m! zRVCMFPQcKbE}D7#4V`V1g@uo23C{Gy!lUb(fbCnwb<0?C!A(oJ#yc-?`p+(W&>N27 zM|I(rq8H>YeFAm-Y)sAfHY|yifHf;3QAIJB?mFv3OBDI%c-D6Ap}Geb7%wd7J}e}7 z>Tna>jw*x1uk-Ye$|&tWz`;4`GqkH(A6;y7>D0w4*mL9n+&mBrrhKM+!yP4_zZnh3 zo{bf3JO2mPmo30Gb_$q$MFc-DcwMvn4Ptw2o;izD@q+%%qbPHa6sF zI+CyQ#~Qpcg(2|NB-lR23Sa2A!;4M5;5OzKlq-B736o!erh5Tg+kKlvWi5k8d~G=V z%T79JpFg&?exj2;?10lEil7*o4HtvPk|RY?7-Mm{Va--GJfmjKEqtrRH9Bgc^L%TR z{py2O`j5%+qMvxdVFvejLKEDJ8KQr`c98yqj^J1Em3*DQ6|RNP<2Ea;J5dqY9SoP!VX~o`Q=G zIbi?jHR{1%cn7I{Cvc-Y)V5r9O;n;jxOjuh_Y`uGX3rjRDNlSCe@X6tfn{`xWv@k+&zM) z^mK3^KBSYPVej|) z;*bZ7sbK)lX&BE8y>Y_Ea06_UI>cnHnvR1nT~YtqV*amMLpncfyKBODxIQ)C?P+-}8{ZzgcUha2!jkRm4%=D-aeu;E73Cvx+decbhjc^E(WFcC{1N4D&g2R#!V zj9O&|hx&^7nU^s7*6R}S>G=zOWfW=jJiIHCfKd(m>6puIRHeX;EOD^q#u>lH*)klm z=S|`Ah&*+xABQ8)9*_g$67XT|DJ(FXk6&fgx%>XVaE6pLMui+9syg*_^381gv1tp{ zIOERue6(rs?^AFO z?oE%e89h-ZV>bppDkB?$Yl!|VZJh0u0r>`Tv{ibewZ(~O8raZ7Cm8ub@t3(EXCeu! zbtZ80R`lQwhYef_qmUV`0)(Cc~r=I{g;n`c;ovsfSfiR+oiC zeovUT5IKS7okqyeF%f*!=19yBdF-yOfT0_N#$DyT0?rD8t3MLK*GU4eTn)xk@86(v z_zjG+=s_okeyov(e`#X;_y@UhcNXYW^PH^wNa* ze&B1^_kI8f47pdPf!NR^CGfZ`&)qO?#hBqpU@T6alO zaCnOsEbtsJ_@$#M7=)Lwy@pVU2kS6j=npP0Rl%ogPS9rijp$_+L!^w%@PY0X>~EjQ zz5eHo4Vz-%{3jXiPu>mMy*Um1ul&T1FcZZ$q>!C2TG+3P`1y)C^4!sX>Q}jGr zhG7=9s1kG?r!VWFdYLl?%F4k4aXksamAX2zYRMZ&7wKh$b|irArRy+k`4##OmtYRN zjavA7U}S(8cV&SN=fNDssRsR+pFN#3i!|gSUtYqZLyGW9`Yi6$DS~GQ(_#IJCbDOC zJDc-B^k( z?-McEw3}Ry=SbehYEpak4GFkp%jbUuaH+eFtUl{RCAvx*tTaSfqrj6`^>~nVUbC3$ z@_E)x;}4?5u0FP}FaQN}_T@^^+HVt)@5 zUYsg$>sp6l=UZr#d>|;8wBnT$^4QgX44mLL+S5XmOP+v6!p7_c!;^5S{SO$={z8Q! zZ$d6@14R)P>~+w_;s3PY{Q(!Kl=3F8jw6`wSw}Umdg5E&m-BJ$Ny8n zx!bV;ki)%&@kw(yU%t-rHhd7|Mm@Noc@{)kY5;`#J`=;%3nX%NI1WfJ!0k#L9OCx| zje>0Yu3ZjfZky8PL~X7k@Ct4`n2lGe{-Y09OdxT&5lmM4Jz6&EOG|loLJ!Y`l$rRF zzEIzYvN0CSiTg`v=%ZBh-jRbHuHP~9Qyx}39L4tiJoDh17>U)r>^QZEWlqW1fw6 zo6O7+;kt_-VdItWn18DeyA#jh(-K9D(G27MtB~NPEOI30JGHRJ@Fk5(5=Ot~r<6F) z2Du4iVg9iVc%a;$TsqzfC1PG!T%?WzuV$eB<#OD(Cx%h^D1nP3q&Q2;XYA&*lfoox zL6XM+?4A`MP@S6qwGNf!jKeK3soaktXXfAmy-%>M;4UjSG>Oxh*NKb6JIVcB$1r>I zal{A3M0L|R?w@c4ep*+ElS8EVUZM==nR=0Op$eE5?1W-1ML1zs9U5gnLQ8icZd{Tj zx6VBrE!jorzNd#upF2ly@UAuQ7i!S)h_9Q5^LZ+hU{dNB%0IIFKC9nDm(IEac5#C! z(v^k7|`|J&6S>>?dTL&5b6$M(u>H_g~TWN#WI%?c$ zKy_{(q5hG44UeC5@=<6+m3)7k6;w-Nm~7%XXiOGrodnzS8Q>}HMK0H7f{bVo94b2x z!V$_`RrGl#d1@heM&@9;|oF@-ZhbsqZ;?3>!Z(kQVzgd}n{`8GGeEJG?m;X(lUw%PW4BJtM8BehE<}IQ! zM+mId4xk`Qa0-N}){2TQ2>hdNRy@|rBDw`8l& z`;gV*LvYOXF#jBEA=BDdLE!sz^sbwRzO5!qe@`8)eR&<#nt6uPHM<65rRmrgCj;)P z$H}FmeROzS0a4mePQC2c@@MMls4icIWBnx2^yC%la!U&aM;4L;Gak|5@ckq*xP)#D zHl%62i=bhRH1TnNN1xoXhw=A3;C^X2mAIG3P797?<9j$8(XV&#hC&YmExF9z!4|A^ z@`cozi=eLai%6{#5ukk^n3P#v$v+=`57~C%s?a=_raF#7?dV~ zmuu;Yfl;dQw}M38-HLtHIat+yoH*UCW5svQMFrU1n7s z$b*z@?-IK_KU%7yM+O~raqjG+v@Yui^}3}+9qWJ7CH={?!Q(3ZRauIX3*X?Pw5vGB zw4Wx}9>j^8Ly%>!(pBSxQ0RvkuB}fYewRft>FHQ>dX-KG=B!}7wf=+npFCShPMdk+ zz~@X7+(Bb6ul+l50B3yeBwis3uz&ag(GwGgS$oz}tqH>DzAKSFc&3XxgbT^D?SI(P zx=Zx%%PKlDYZ3czY%>+w;Yd`iupMadQz zHR=sHzU?sIsSt`E$AhEFCpKxKEgb0&#{e69W?N@4#LWu@Hxv`NO}7+?6&^>EqjPAQ zoH)$p^2yC3HmGB+L=P~P@VU$#EuKuGx#y;$W4R)KUp-Cp$BtvuyuTCwfr;>Xqynn9 z6w>1BFCoNX3%O|NjOW^#=|cHtcJR(`a(bK_*)234UPXD5S%-~4GAj#qXyq{8-z$ls zO=m-5L?b@Gl}fYRHJNSm^Qp6^q2R#vV0u?s6Rd6c^ND*5{ZM94j&2PlvIieDC|zAh zNI)SeoSi_dn$|GsPbQMKK69d|NQrNMF*rV7$?hj3?Dlb|i5$;CHe3`-K8MwjuXkL) zD`1rTTcL`jPv_E$uD6LzzBsgG3qja-A=r6ln7-Uz$qXJ{NSm+Q;hP1z+^6CvxaOM) z)|y(j^WJp%JDRM;Wki!xv_g;jsHgS!MU?x zH$VRsEX^}MCkke2ynm81(u3^Jav5A!I2qa$S&~<-MGS8U zq2(b_eE2F4V|08_Z^wQtFO($X;djyf)ARmP)Zcm{0J1Lo}Q*ai>x(>T!Z zl?h8IL8^~_bZ`Bd^O5%9LGJ$s;6}eS7A_{1H?Ybr!r^` zt`md=GtVTD|K`7>;cIMZX@`hlxnn2!nfjANeBJ^L=lFBJl`4#OJHmoF+ITKwHt5M~ z2<&wC!Azq@qB=Db_7^NC>*MUnSF2#~ysAlFuaiN|?)S`s%)EM2pEGRwgAwZG;ST|I zO>~0iPI@y@1iHHvaQ612SQoEO6Z+a=P*Rx0eB8!=7w+Vs2c_QTa$qPOPo%TT=#v@m z7~{P~fS$l4?Vck&GBtsrH9qh8?WtbotT9nrUjpAX+T3&*EA5ZzvTGW;$Z!%nOtt5>IB zMV=S#z9x%X`1Lh)j0EwD7lz5bXW)1F>3aXx<2K_Jidg-{fn;ov8YqqVPRDIEfC053 zuzY&~^Y|Rxj?a8H&)*6S+k4n{J7cor6YnZsqe72+dfX~;3-z=3J#U+_1&m%^1Oaig z_$NpN6^-C|K(Tr-kDZqkWu>FCWs*|yHbtx0_?gc%4Q6AUCO$X(T zbLqGI1~ToZ1kaUPOe35h5|u@t*n1M`7&4qiKbKArO#8eEt-mi~!}R3@l9OXFE?OUq zx>7)1H~`6fG49-DBT{6(oVYnX2Sq-|n%4LTL+9KCr@0J#*t~#Kek&>n-6|vayYC;4 z+2u@f?IOs<#*){EdHJqbmnKjF~4=WuLL5W%n9Fyw>57jIp5CYYkjyFP2wk z@wT&*q~Xa^c<&WWcbLxwTP{jaSEokTw(>R3+=T+6#4Pj)JB7Qc8{a$8;D(Mp#g6r1 zX!j=-!=8lUfRP(|4anl4Nj&DZ?ZL3qdhA&Bt@v^AX=>jgPu05@;ch+`+$C*;dm_Sxn!XA~tVFG6~fRhkcfHSe7nAk_w-~8Vv^;H@TOX zdYpiOSNV|t*OR$pWliiXcvh-Q4Ba+f0cKjfb1YaVNJ|L5{n1 z?*y|+b14MXUqJonI-(%61uBJfxx;q3ETmKuQxiqp)M1KpykD%{@hUwVIREo|_>?1g?d>MdQgIAk{N-gk{8&PZb>>=noA#vAx+`3I8s z=@%Vd!F$|yULehZYG5ssMw99;k%d3xXtHS!6*re+*RJ`Ed)H0Hid^qY*KVz(3dQ2| z#e#mOV1^9+({&V>gdHGx`xwcucEj5*i-`VsH6}jV8z*zBRQ`k$=#JCEjEvRTIejTk zT%8L(rr~VJgUd9?`zg$wy$rXB9YTk)$7uG7pF=#TEs&nIjsLvnQHzygf(a?nWLQ%e z)_q(8jlWmJ@s=NSoCfbUUwQ;SZJ$ivu9!nZztq7BGy+}OHb$iK4kME$f`5t)1=pQY zA$asUzB>3BJdVi0+q0jk;}&f}=*hL<+QGn3R5O`mTtO1IKcrqSAJf2Fx1i6NfrbCI zkh9zXeDHitAFWV?GQnR+l4+(FXQfaV^8&aL=t)&3&7g&3eM{vuf3;5N` zmG&F1$0a?fxOOlP3$7@0OTGEeQ_&vPloz1=?P9K~W)jCm330b;Tsg0bot)zaCF<14 z^Yui9!PX+VA+5#~6qswU*yR+S+9*%VeEIpM@gML=?;%{+aT(LxSD`}!OKn{C(X+yK z*!lN9U2;2(im%P1ODzW*3~P6w#w}T3Bz8f3!#N@$AH#FdPr}>Pnz-rLVJdCh%hx|N z;L78z=%UDH2KAS~ho^uSeD_1(G+*nKu3t>u$s$NK=6#&2vT^K_4X`IWhFKcngNg?F zw42K&d$vvBjE!gV?B^8_tsISSMaD4a+mDj@j{bQ2OgY`WJcDGq%fW^8$=vHX0Zdc2 z9<;7f;8rB&VBcCXT6)BsYIL5#)e{W_zL)d_`{bJO%1{36P@*Gnxt4+ZfBj*N_-v@h zNGSVynKn1PHvuFhodxggjJf^Vp*F;0mLTkpFN!T%0F8Ac&?_|p3p-@7ai$@Boj}Qc zzeqGTv17cO;^~v5Kj0+e3!j%ZgLq>+^J7ysCSRx{`y({Tx#eFN^OZYD`NcANWmFfc zHVxCw@o5l|Y>GpF-&3LRK>mGsgPxJdLI>ekQgX!tyi6-X~!4o}a%rI$Od!?W62;{ERe zSY3V#D=Vf5{O)=P!klB^*Sc!Pr1Gplz|Y0Y`g)_?$6`T=n!TVZeg}~)Mp!ZbA@j4_ z4h*~_VVzthX-?B3iE%j)rZ)>X=O%VZ%Xygo-$pL_@IQ=6RS?umd2v6q?KrOkuR+RS zIk%zr7Dn;!GB3BW+%mZ-T&(C`wqjZlW-W|HgWSE4X&;99B4=s3k|=yDSWPz$$I|lA zGgSP55S{#eDaw5hCT7-Osiuz?9n9zR_{QNlw#yn7<{l+4RygC8ncjTwRS)BwCD1Z? z8hR83kZ`S7dQQrLtypb~jS&_o=2S`BvW}71bsG53UcF)M;|?-5sFV3`REOMp`nFBx`RaQ`h&roBQ4{jV?J!C*6~V$iHgPWM%|*Kd0fleJ2~9yG4=9 z8tJfVR0>Q)uaRngW}>aFf_$#A}z9iKv9F=pYQia12 zBs;|c?26tI$2;Y;+1HMU{26l^y(JOtOC*QRKBl3YbZMls zI2dL(;@htqncAm()*{*teE51rK~W5K9km8a=hHlA(Tm7zZYN)b*OQ$C8qDwkd#XP+ zntYJ?OG3*hKtV%%ztyxfkPs$|G`9_vixDNv{{${}4kpf2hF`Mz|DLdvsF=>m7 zrO`?v__N|X)BCZNe)_nd@lfcaL35I@QFb30T&%#mIlIWu)-*h9riTx=&qJ?_SY}sC zHqBqM3B@kuQ$z2qR8RLeF+DT~kHnWzg}^jsIA9z7QrE(ieyCz*xQL_Dk6=c)Wthl4 zF(pP957DbjQ_0U|cL>wfMZ~7~;D__u$o=bX4OT;v+{>Md&}3dLdr=?-9j6~NBwG?j zg0<*ja)PNhp99LgU&nvtTw0=+0Ftson0sg!J>#j2#>ya> zEQ=xD%J4$|JNq%q95rKa6ORXGZM3>n7VY2qj<@-TAH_>$-4JeFmU>E;kR(!invy~q(5s?~X*{>^X-8o6J zDMy*o_p8WA=R_j$={+-UKopPflca~94?_R80m5~pS|{7BN%!SAG;MUkot+LN##N z0TqnC>`(99l){*B5wdxXFMH=;B(0s1LN~iB(YTygax_|j{@4=6t{HgM5c2#k-H_5k z%F--(k9RGd;=s@6Dx79lxjt_gS<}x&j|;M0vXWVwx1a- zy~g`dzcMiwYe`SgSNdm18|8E#vt%bf`jP608YgDpO|6Nz#8s7yTdar;cb3tmisq=& zZh>3FwMg@ltvDrU8XLU&jg4>URvLTb3DeXzMEt|#sFhv`n_6N-+{PJ^5f?SMs=OXv z{PTtRo%^Bg*g>WqyIuJ5+Q)3z80H6N@}?kos|!oEHhS}OY1}zS8Xjv#1d`_Lg^Qx7qH~87cUY3$^==TfKZ{1{6cbW0 z$W9IsMNv5e+%MNiue`OOKgbXb-1`_+4^M!XeE+Ze#u1PnGYc{|T9K8nlNyfG?Zl5i zM{9^YCmQ!D8~5oQdC(OEYu(%EhGUX+m*)}KnL2~c-WY&eW1qqy@jMd4&&j8JG>3QY zip;lvXXt7XWB9MPmRyeLWmaazgFuIp2|b4!I;SX-yk2iI*VmOy>7PfU>p8Z=Cz}n+ zjRqO}7I3)W2TN5a0s1RZ=hKUsr0PTh>(>&=7k60u+A`9*iy_mER-j$^R_3$S5%%Zw zXN=u~UF5*sT};c`=?$Y*rl>OAmcF}OLhP2+)3-KhG}ZPdz541lRnq*)?CPCMrE?sK z6JI~l^VmwdJa#bco!Ufu*?3mq6v!;IH70Y?Yl!>(bM$7{8#1S@iw|U77_Ao+IsrlSd3iSR!X`>uh0&SpUg&10K;C{ zjH00^b>(}!^1W?z+R!sH&gnO6v+oOS{lWm~9j9kKk%k^WOUCUequq&)*taQxRUWA( zhrE=Cu^^F+a6ZiBT#To7)PqdamvUxdo2!G#Dr1R5^avbj@Tax&Uywqxbn0fl%w|);Got6Jz-9l@pt`avK$GWj z{u<<+C+jXzAKpP>?7R0=I5^G^W_^ zWAm71e4^!qPVWoJ+eaMC|F??#wd{IRV;wvEc zc5B1&qsTbeOXJP$sZ6Pz6PnrVB_kWx!i=ZSU{Ir#NVrTvbI*P-+cQe!i8n|^2ZEy+ z&!yQX!uLQ@VesA@`d;oCdwQ!m?4IU;GUofqiJx&0_iQnv8|qALCSOKVE{DDs>con8 z4s*5MkUdXRa9ge-7xDN2$t-$---Gh-yM`0<&+iR+^eqMRO%4#R@2_aI>~8d&aEF}o z%!O;M{q&xNDOAKr0ofD;*OW?Fw+B(Ma>W*S>gjF$ZtwzGl(}6X{y&D!!=I}!jN?{T zMmEWcLPjOzd(U%)hLjXaNlT@qqM`juHVGvvGLwo#W_<5?E^U-(FD)gB_R{2c{{ye< zd(XM&IiJt_tsywLXQjbKW5U`fofh)xS%Rxjoqe_33LN^SP;QteKVGAe+MO)mh7XD` ze3}j_Z?Gn%4zqYhrx`DOJb)WFB#_~X$>3@522RBv!j`gB7_vPX`VMLEyW@@EQdm2g z@I!EvI~|~d1E=VWN7-mJBML73+(0Y5<*2cmHjFwl7MXf4y6nMi;$}3CWNEDA`Z8aT zo(-yWw*;W%ra}77@g`O-MJx~|*mk=3j|z+qO5!bq>{NWwB6>eP8NfnPVEh&XbNn=EsF1+B4)$<9 z_7ORw;s-Ck6@fv*FuvGWpLsCt0=dCS@FvZhuypqbTvs_33zr+>HT&`8(>_bK zWy%O(6!wzqnWNFz(vnzReM!vqOR++uf@G;Sq1mBGp_lNRs+yIfvBFfGTPlwprYX40 zznfe30qH<_B)NR`1>@X#P?R`oKG%NA1jl{TB+4d6L|Hr>6OS(EzSmSz(ch0m`bR1K z5fg~d?Ip2RO9l)loPeE=C1CKCIb32?*_6LSsZxss-e6o{`|MI?N3bNycPFzuf(^(o zyZzXuC&!j5q~bCcDfYV66WktoO!pR?f(dLR2sV`2&FIua) zA^IytQtRw+>V$Jb|Ehv%dTELkIVay0!GW{1I*E9u>Li#o3*ml(W?4{|l6(T+vSYbjJoY+ z78<_F3g>DK$8{z)$g1Yj#9j+J;+O}hc)no{{<}>hnqBFbE5}45xAikq1P>8!Go3oD z+e3{XuO&}~S!cEU7R>&m1$xy(iSywI>`}~RcI@*eO3;iii!^ZgEjjpFGnd7yWiTbO znsnKjvXMgf#q|6z!Pzy5)vX)~7vy`n6Ib_%FV9>FrGe2_)#8bj%J zp-1>D{vTZszFhbwmgArKh=o0u!zr^1Frf21HcmK2b##w$gQxD|qC;u;IZp%gB_^TE zbYVfxe?(g!wo{KbZ`jt_%3T$hy~iykFdZhQ=ogXzDjA2!jT;kS>Vcc&*9GDGYf1|Z zjgP0LE~&WPY&4ZAc|?5EBB}XnMK-lnpQLRB2&z2D7%okLhTBuP1=5r}4cdxd&GV?( z=RLM3mSU@W1oKj<9VI*6vEOnC$?x*O8}4J_pX57md$b8oCnu2jQ$ZjzO%>V?g+l5q zTj*bJgH}FqP*^n&3a*a9#sEpEQkzDs3MMf(*xN8CaTU#8BIJUWOe0rrEZ`!K7!$?y zvJ~Mi{WUiZJ62nu&Gc3hdVDn4|LjNIn0r+F?IQN;9d~-TvH~>Zc0fwOL~z~G14|lJ zxX)s1)Do#M?WzXscb)xo&97kkzF`AAQPG95=f04&p8oi-rGw%kd14yU0$}x(nHA$e zU#z|Z^&cnEwNC4B{-v#KoM985{h3PZQcpqN-)#Ca)e+CwSi|&BpSf$&rs#V6K1ouG zWb(UaVNs7gYeUJdtvx$}n;-RuG!>Dob^wT`n-_g^4JBXgiLYdTC;e#E6jydw*j zGR#vS5zZc?it|?gfmPMX`0R@l|GIlS&bR$aMAsZ4wK)!@s*jNL^r!T3mXHCv+zd<4 zETBJ&Z<3nH_T1L*f1E51ej|y)VZu(F9B)H9ZM*nnwCFvC>FimAHcX{}H@RayT z56MbXn}IK+;+8W~3ro^bm<<&@S4q&*3bNKI3gfKKlZ->7>8LPcTwUjg$G)ahqpMeG zYLyf}%6dAkP5MP*M!dr5f}`*6Z(FEoGZVTm!$Fi<1M{M*nJX%iLe69X7R&r1njVG&FeaQ1X-lG6qO){~#!LEM zGYLDDY|(t=HtPH99$tB_4^_HTX~+FEWRKPpd9IfZUHKT7SH$BZ^I9^h%MYDE0R{Xs zx=z!?1)uz}%QqZ7|5)L$Vn3Wey_^2dROOEbr=q2+6y{vc!YQv*(WbA2%XpcLi^oS} z!lod4^66i4(N`Pnt|&vd+ES8l`GMMap2sOiN5aYK2GldjCa&wG*i*Tu$=D@w`15%z z{5z6>cY;c=XpugwU$26ScBin-KY@;U_k<3RF=%1-hOSEJB2wy_e1_g$;1Wl$`__iC z^V=oa@3!|qyHohSJl;(mit=Hl;Q%a9UXQW)TD;%CXXv&+gWOzIQs1EuOp+ZD2`hpaC9Le3jA`s$$Xdl~Ipm&@2+)F%sb<8a9LCi-iu1i-Ed{Me8h6tF_V zyYi5lI-EmwjRGqBwu$ImkAwcd=c$?a39WS%liYRo(4Sy~P6lDPSUQXH{|TM3%;n;u zJ*RMy;s&VF(!)3Z70|a1gN&4u4ZU+ojgnusF!7Q%tysJXzo8TPwW5anc%%b!%silY zr?W6S9>E{jJOs;!X$h>$Rs0gAKs@MMf`09;@F7$U<5G^|k!hcyeMcL}i`=R78zX*c zWCc=1eJXijHeG+@CDVER2Q{}y!;QLo$?Nh#8o4rsiPt&{JJj3p&eYX7^nxQU`B1=( zW)m59swx)AyTYk`YX~GS0ykSZ=AW?>H$-y`?C{oyriWA50iELnoYO@wbLOzhI?qHA zR|x!Bvx}aU+e$UBPp2=O)0h>bogqxI7lOq_*jt-H^-32&&uAMAVveJB)hLX)DF^H2 z_d@)XGjQy!Cf`yk$v;lmg)9FI<9K{L4`D)e5_a#}XVb!X6(#xtm?mNsVfnvG0NzMB63<{QmhteXkE|=BLK)8$L+hyt>WV-BU!x*RnYCR{(t%z5=GNEv8#u zoTGl%q*$+)ZFrvtux~jfN?N#=yLqROT5Svmhy4olN0l@r+-hERl!1M>ldi4|I|f z_jFht8xx4)V&H1nHzq*lHC=yPh5WFJVd?_KSf)Vf^~M|Y=fahsth*lmo=b)aF}0lf zeOb`jnJEgHWX^Ycj^>AD=HufX7Hr?;I>@`~3#VJAI;BsRWgmWQfULJ8_-(Qyani|y zqG?CH;A>C<5w>pl@8w}!J0%UZ|7%2r)@~fTUYEam$%y}!_?UXU6ZnvDg0%k`gNsu} z(Fa$1h{J?p&gr3Mj&Lxi}_gP+^$yt@~RzX?%D@Fp}fl=BMW{S5jt8yb| zRZ-o&D=?tf3AHv{pt`0-)I2c`fA{T0+0GMiuBQ|@-*$MXULx|8kY{H!AA{L+4s>kc zpsOq$njg;vO*;lwELaKJFV0~^vLy*`6>>KPR{WK!A^hK!TfyeiD%3~}#*iDjw4xvq z%SIuSHkboP6oi>}Ya!+vA7LWk6aL%~h9~oc9N*OyyhCmzS}Bi&uVyp(SKIPYCHyOm zyLA}-hoxg8J;U7_F2hfra~u<%1`>b!%XlCr3=CIPVo7)gp0?#tO?;3Ji4bxdx3bah zfhxaBW)>)oIYj;U4w9rV|KO6Z0^ID72i>BfEDhG8mu_~G!=Wc2uDMlU7uc~ck1ZyR zTZ8e)fn1z9bv;DxaD!)qd&SFtrNG5rIlMVuhI^fu%B(#x0ptu*aPoL*a^F4$w63#M zb%8w`hy7p{puuhLG=zUiwV*3!2FuK=sjay?vhKAwWBnTT6KBQNmf665Z&i9fXDSN& zA-)(a0rRO*^!pkQ#^BgA){BIK?}NW|k*zwOEK&!FK7w! zrG9hQfllsuQGCKXxIfwc?a@apM*FTY(HldtHX|C}MG8G~ z0WLiC>oLp@egX>w7E;jb0*I=r0n_n6;oT;dy=K;krE}h*Wm=(l+^_S{rH-IpwThZX z>auH{4npSOZ(^PQ3ib6f>5T`4v^=+p9`&x`=1#o^k7qjY*G5m~XPKJd?)YF*^-&oz zZfep|m1&f1oP{4Ys*}ss+89yifq}U#BJQUxHSW`apxyPb2XE3?NhH=???_SNIMPow z>9)u??4Q|54B{Vh_a~*$gtt?;FB-pT&49pwQ4+FzIVZTJ-HF7wem2oi5Wx>)8^|43 z!|W68a4xPk19JN=XZmgrjoLOGM)~D%PxH5fkN!o`58f2ZkBq@w$?Np@vqd!W>;>91 z%7OGAQO4OKx-+5|fxQ5cugKxq8|YGyTtq{th|K+_|odf1E=oE$d}Mr%lHA zPZi|(%N#J-Vhnk=N|==SPaxt&EeW|Out4O_LZa3~26cwVLQM+j}tWfpAIS=pHHWCrjo4ETHF^> zg!*PNqXi!M13?d)E% zaK9y8QfSMB9=S%_rX-Q6$9fsvud6XYVmif+GSZk`jj85K;n_J8%p2nc6K)4G6X75# z*8O(+A+n|q{)ljosS&1+GZ9UG^ny#Rzasv6_7|CypbWiwdU*bjFQz@XL_hCLp??D2 zaxeWqaejC9L(0D>BCcG>8L!v@lH(Lm-s3WN+Qy#@4mgRf#{fR_5Wvp$^cxr<+>7^2hVXn}q%O z6SsHeRvbM4oLb&gfbBKMa9zq?bZh~7GWjsQG%yX$Id6fo-FLWy?Fsa_(EX7AypFUk z+Cye4lTDW5X(@QGN!w zaW{x*%-9Ui`@@O%vRvW&T$=A*A&2F=FO$UQhcL9cm}zjn$&^04fO_gj=!frxT>i@o z+#+^6*zVd!pKDlvgv|<=u~{EiA5SO$o*I(_)}36oaF!2oxIyi5jWON4mZrDfrz?VF z1(*9G5-{N?-RafFeBS9#OPy}kEiN{|F%gH!lT#{O_;Y8p(C4YvFjf35n0?mt-lR#X zAL-a>Hnd7cc)ybjaDUknsv)-myCmMx?N+mJyITz0aB2jl#slQ>v!USEtPU;z2E>ml zP3XsS>p{vel}nudgF4FVqv3xRv{OG1GcR&fGC7hK$t=aGmu8}Wn+Mi@^u+g{b2zcU zGFl z{an75afkb982UwFk896kVwLZAL( zq&XfBsU=4L=|T9FKw=U*AI3dl;7U~hlv+O`<=gYft)LXp?{NWZH#cxj)`VM&&EQUC z3KJ`T2i4u2=+X#P9Cu?ER{BfAYtJCk+c%dc+FFu>0XiUSoJ;-|yk=ZVhLWe1=iuZ1 zJ4^<>LZ9hGLVL<=&TjZ?T6L>}Zd~kxrr(Y=?L^GfUJN1sAGn{ta8Xjspf20EaDe>j+#ycJLTA#hC} z?x%BKy`=lr%Aw)>^<1y9jX1W^0;6TOQ;DInWGs7w)&zVI4?CxiNBusaTj{()QKB6jKZ3R5PY&~HoY+2ke<;LQxypvdZk$krdzbvUy%uw(q`=zU{lutK z8c(@yCNGP9M5`wMq?f;$Gi!vL=IV$_a{u@t(%n@7VhLmBvRft{V&MogN2t)Gf7V6jqzmPZAF?J zxdR;(e=}}V=Ww}d3(-wA3cOmzl0nJgbk&2k0vm0kIN5k8PVsopRK{QACYH~~zzd3` zv@nzY%Q`^gUo4{YLoYMemekW3e#goA69ON!=_7s8xmTDopP~ls5p=q6Pj9eV35O*= zpl`;$qxmR@hnA_bXIHIa{kkNaRSq8}Szi({JuVCsj50v2_!!B}yGhK2d0geTOnA*6 zWrI#t@Tc|E<~?3~LBg)VX%rs)sm@7P7bov63A-Y)Opc=u+O)3jx~&)Ty|?KbR6>uQV<{NN8p zUIA&Z9c*o86?g8@3;yT$y|AI=4USkT*Kj*;0_*T-ujs<-P5hDizV-1NZ}i*R(Aty4+QfQ8iw*Fa|rZ2 zSLNOInWF!<5|CId!+y{DP1iq8f$EVttex*_)_Ctx*mFtnP?kl}v-Y!KrpaU~nHk7$ zR1ooP6?cU12t9Vpk3oFt{1-Gv-vZ13=HTg8Wp=m3CiZ&xXH+@x8%uTWfg$sS=EUCO zM=UGmfBRZdeb1YCXu3J?-cZXflagi21W(muMJu+x@V$6j)d@cS(H6)oWSb^F4ie0#QFq?n!f&YYFrHIl78RS0LIrTLIwa_sQk z7vQ0N9Lx?0Vl&^D^K-`S<~Q%XhepErcgZ;&z9>$PKK*!=-?L7IpIcH)H+ajj=L%Bz zW;sbPo^zQkX)>pYwZCvjaW=ccq6Rbv1NmmPVl;XjOH&N&;Y{%izAH$Wje2Xq=byuP zgZnNZr!$xJcL>CmEA41BIhEhj_W(O@zorUP_4rM*?$c7kIn0s1LG;!g&;Qro1Bcc( z(cm*@@a0wwwu_sFS5&6*FH~Z1_^~^Dv`z^4+*e|YoeX%d@Ctg&@vH=ptf24KZQOCiFvf%>*dBW5w1zUBbq8WrO#u)98G65kGXB zG4zKB9Xjtglz-+A0fnYKZPw!VZ#l)9_VFmAzmN~w&F=MaFn?hh9lyR(gQX;LeL_R{1*%b*M{(uUJBjSC%0Dg-zC}nM~RF4vz1EFyDSA&+i&ynt4~smokr}T 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 t^uku3+sl1sv2@FD(9u4gxQhM|H|9zXt> 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�@E7C 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

    1. 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

      `Lh+IOW;jpxjzt2kGN$wM1 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

      =xVzS&Aljl@RZfDt4n` z_Vws}u`%n}Ys5QojbNdXKR$l+Fp`beV{x^o@Ve+AawYdC%p0A6CmvkE_BKSZHC!g4 zR>>siILAAILP){4E`d)&51Cgpy?EB|PrPIOCl}N`g)EwT63b+9SY17yyeXbd)@NSC z1AlbU(@E<1MD%n#ATpPoDP6&oZA9=Bb!lpO&w@aZ81pqT2Xj7aSyJ*59s9hQ>^8eX zcB~B|V$(BOv(rp=n7S}=Z$I`yZ3UEmc?jwM_l>>%1Q8R8>dwUJ7k& z-Wx=o%}gVidP7)j72@*A$Op%>*^#<*}9| z@4bhf?)1U8v&(QO?@Ndr20TIyz{<^ntjTOAf2PhRvO1et)qzkJH@vFkm5~_UM^dnb zs6Bc2`ZFg!HHvJiNG6kIRZD`mhBLp6X!a>rk!>nygwx$?*}tdNxX#cQF1hLAWxr&} zu&XRPcS()hdKJ%Ziq^3qgAgc`m;yfwE!f$$DNHciiFUYe=e9cWbJ|IjI3`}1%>SxI zQUr&nO(D9&7NMk$gDRC zF>goAq|dsumo5GRGxd7(T(5`(F8PO?R|jDM&-v({!Ow;UIDzBV1DuJ7E_^t%gL>w4 zAO$;Zz9TP2yihk+ZZ{K|4`7a-bx`q!_#Vu&Z;m;776%Dxu=0LyQSKMA0%}ovM$I&`l$e~JWBHT8QERrvPf6j<){pW+; z2F}5;ok2XW;Q~?6iXbOWXA+egUx?m!3*)%0s>I{EANGbD_#BZTZ!a;TuqTjw*Li_Y zsQe-%>L!T|T7#F8SW;}(N)DTtk+Yi5NTTcuV*9g$4k$f=jNTng|MhBC@x*{BI{t)1 zJ$y#d$rXRyF^NH4K9=mzz~`3-Vx_~LF#UTWT3$Aa{&rj@^&5^5ALVdTWMqo0w&${I zhTGVU%z4-_W+GE>62j*WPF=h{-yO8BI}4UOM`M?BchS_BPN=~xpCB}rWh?2^k8m-Z=oCTOKpllX0w5{TExi z_9v|qnoW+dS)}&^?@}`zL%xm*$e`C#bmR3F^8VRv$gk+eWmiQ}E#G5EI4a6+65f;h z;|i1>Za{@;>shrV$NK&*p|SE?*o=#bOm0;L2;Qi%83qaLEIr6lGSa|cD2tV;7~nT| zH-Uh^t87mxg}F+?tYLWuEYmy4o+@2rBioO`(K$KP^j|T4x-t(R`nQ4gS%1bCdo@_; z%?5ZHSkLr34ltLu`-r;pbK)l(L#!?H=ohq=Jb2WPl~ca5;rc}OVnZ1FMNZ>O31_gy zo1;AYkKZTgMRPg>&tT+HB^YU$QK7pg>l|kdr)B1$DN)afT*);;3?*=1_;1+n zcam5;YZKkedaStd2}&EW10&5vQ08es(ncil&!P;n|3VCW`=CLbf2NZ`i#POkpS|`?ViP9&;mhJiWc;+Nm{}G>Ynu`FS(HLAC2ePO6vbGU z*DUaGyNWGGmw?S5Pkb|f1G%`n3jZA2fQ>soAgROg*sW2QP?Z&+(#pH3q{7k2hg|w6 zvKzm&b0SqcY{_+qBeoiqcuV9Wc1f_8ZArfd_jHt*WKA5~vy*2jyH00{Y%a@tco(Qe zHo7(?TUHKYV^{Xhb|7uCc^)>p%j%0AGn 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%0D?dYbT@<7yhbBQ~7ndn{ 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 z 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 z

      rl#dS1X=>XTz_TVFpcR-}faK0;BlFJKy#w&jgK+70K zG@CgY{oe+_{w7&w`TPgWe@a9msr{r?ZY`9ZU@m8i4=aQPk;dKPb4JWT%DC%}h|_FKy*{;}Z?o zoM4Gr3w6t7FUnF4;{Y6y`B>P?y`$wgo9~)9*DCn$RnWHf7hTz`X!V^dSXFj5<48#r zu5mz~p4#vXZ5jqr$1esDS)0Tp&Rk^$@4k`fQ;Tuf8BaRBIsk`HP~)w~!l+ud4vt%N z3v-OjXxf=@=*?DQai5Lo&g53SQJW}szitEzoP~Ve*$;wy@iRPCc}ZGBoQZv~Je1b0 z68b%IG-<*p`bc{%?ZIYJ^SH}$j^L(i`=>+BeIEph6Wo}WyO76}K82qMWF-Zt;UxPOv04*NLD&<91vN1u9JQZ z2c_zA<)Y)5r?DKfr!1u(R@K6`;X(NI`B)4tI*mSVuhDqyHf}00g4@pfffeR6_@own z*yPg#4=tw9?_X5;&-6OdH%$Bw-g&y#q$4AlX#T;CwssoQNaGWsCn_4X~1-*6g z@YvBuB++9;I}cQ_%{Ow`49#k?Ab%N=`Dn)u2mArDwH1aPvc%k37nxzxCpJ;|8!kT3 z;r3Ggc;U$q9`IR(+2^~V!J`Xgcz7H8vN=iAIU|Kfc$~o>Dg$}%zm;h9Bn_6n3c-ZS z%kcW~-w+$HgqsZVW7o#pvS+V~LGtSyI%WD!Txs1U4$+%KRX0}STQ3E^#4HGsgskMN zlT&!#>A6s#H-~(CEzPB8sL?jJXuMvKgIBIg@kSd@I%#yaILe}#``meoD~3E}O;nxw zpXq?%&xg{QFSD?yy#s>cPvE9c(K!0EG}K)Wg-)^_{8Wy?a`6XfT~$xcn$IP12a6%8 zCj!jZJVwu{gYdi0C2~qR0}O0C!DYe%e&Bv8i~IKuZ?XeaPUkkP|I)(}wXAv5jbzca zAClayMw0Jq@B)qW3H;#kacC9wn9N%&i*ffxf&G+Dy1A~L4JgQmfc+`--TXTEe4+uP z-H(%d%C|tC1aZs#F5Gsd0o%K1K*hv8mAtriJ`8y%!Cx;b;Vrk+c;coom|FH0G$#qH z%@_JmI{FZCrh2sd)lalbm9jKC=*QhmazWY8(Q509ARe}C8>;S~Y_-vF3fkQe@gwR# zanvFZwl2m8<_evKQ?M^XpC^BJLo08f zHbyr1{pL8-&OgX9H{69syB(S821Ty(&XZ{zSSs|Z-LbVgk|kcVqi0^a^2LgKdFB4Q zxUKCIyLLsD`k%9*7qw*IRY$du@r-5abq~p@VU*HaR&>D36mfLNc${w-jD}gm=%T|p zID44z{(m<~@VUw3LB)6YUtGJu#BQOZ(@OBBFz?jHEEs9v4k?3@X}E3(F7kB2?~MvH zp=}L`J;y{vM_=LrnYFlcl^(b`PvRecy~p{rnxOq<8J`ek&xYz>f|@bs@p`=;P7W;- zf1r6nrtT{aNM8r8Rf<-2b?S(U?+V1l+bYRkT6 zR!cMCLhl>PoJqG~w|f&l|Ej@7y>DUGv>oCLv1j>a^Ax((^*iPnT;~~8qv@VoHoR%5 z@PFU0LXSP(!s9A9bg0b7z1MG|ZB)6qx+ouPx^_{G$iL+K@quKo-fZgMTMrKJ3V6EV zNU~jZEIlnfjQ+Lzi;s(UasBEPP)$wb&*y{^y7d9%%A7*Ch`mr?UJqp(r&Ht5ENG9= zq@_AH=&Ah4Fmcuqs`BETsQI@A2_8ArD(q++&8iOJr|R9T9!_6Fuk}h+Y>>W1#rLZ* zWac0IusD~t7>t3(S3I*%5*OY^^%PhrBcVrsqQ7(V>ZfS-woVD{JRVdb8)!W?Y} z?fle0;#a0%$_`=nJ|m{QQpgvpPfsB0ofoqyUmdt%ZZ!!OcIUZ8v3%&`c)VKVg1--L zMWwn^_`xTDrjH)S;}?zOv05qA@*JV>1^1LAjG{grtLVn3!|3Lh;XGC$j^EtjNjBVM zT(TnrTjljY>Z8DlJ`m0G=lrJAoVDSBN+ZrXrcaDNo`LmW3(&ejA14MI!rXdc)}nU| z_w0FsN%c}>v)fMgJ`}M{`5dawUI%k4E3v07gs*(3&*!Fx@z&ahT;-rU*!FsI)AJd; zMCQBDBa=i=A3y%+XbiiQ{*#682}hL`EwD_!jul<@MzdFIsB-8`Saq?COz$6PW!T-q z-}XEOD1S}!?Z@!3TQZS^1PbhfV_-VH0dtvfyBJ&v`&NG@Vd{4wcg;E4D)f#wH2;K2 zo3rSZ!o8sGYYFnwj`WtnbJ+bL4^m2ALGHN4_&oXv%SgKgx4Q??;;~6o-}@F{oT$nT zg*pG&oMdhqKC;5VU>TiXf06HW@~`OM@&iBY-bI(>xWS)Ksyt)4aPqagg(t!ZkIol( z1?9E)Vtxb5U2~rs#wv23^}~gCV-Kb-xx|$v1oyOgBB;NaFP`?zpWa<@PvCqwgJ#EI zzJ1Ihru+|KS!XDJ8nOlBGfp9K)1dFRm0-%_8Z0p>00Y&}_;>6fcc{0(SkkidT_AC3#uF#DfkLg(Y|y7^%0j$%NhIv>9U8Y zY*YfnGOX!y#|`BtW7P!ir-<4vQ{<&%QlUAz5`tAH@SQ~uVx8Dw*SWVGcmld{h|1mkSn{>5GmTVS4H$f zQwn$dw*vkN?8MBXAo%;_rtqE*hqGlFQ1E1J*?#9h+~|8BqCB!;u-9(bnk$Cd^j&an z#bK}>FqjM~Zz3=MC}WqtA%;e5hOc%Ph{NhAW-ZYIkG4v{;$fSyNN*^YYRQJRs*B)h z^c@5t7kJ)j65Q;6j2}w{$B<|RZjpL`AGYeF^AdGTpF9;hRt~`N(J^A3fJ~CR&zej) zx|8IskbstrFNvu^y|`6iAdKMxlga!KOKi+RH_JG3>RcI{BtMpH)gYMFIt5)0JreKg z%MkClNwMaAD0$fKUS{#(6I(Jq8FMd$ihF%W!Kkcb;zP?@ML}oOsa4=F@Eds?E1yOP zpRGvK)Xw9d!4I*sKat&#`OKQ-_K9kzKN96wWHXQFOUm!mh2!3m4dh~^4^uOc;)YVH zto$fv+qMYYLa!veZX?0cUYpaCf3}jWvL^Ag#|m_?`w-X^^-d&NxQ}$iJO_guJ5Cc){nOW5*i z1jy>kz{xY`*wsI3aH;Vi8y^?Mk~es>%XjUVS@vx9_(NfN%#(AL4pS#%-?0e6fBb=j zb_{1r4vApRL??*qJ|>#o?Frkj*~7?`Q=seNO0G}vgo25qaP`KaBIRT5Y|L_j0j2eX z_1&3=+c$i{N#3_G!Y-bNr2QfL;(8(Vk``=U^#qj5-@>BaCdgQ%4O1+}ksQ6TkT&@; zJX;*Y23lyrQu_(e-{*xp4i<>}Cpw6(zY~}|&jhcybvQe=U?Waikp)o_s_60QHgW!0 zgeG%lL;Sj>q5T8F1v4HkMy+|t6q7BrmBz^tcExKej6q-T_%&4BIrTC9x|CBw;OA2WDSBMHq#|3Q7OH4B<& zERqhK0_l&Jk*TW&&~;bxp)_6rF7IB4M@+7w-MShuj>}~=A5YkVCIk);!7=iM9O}Z@YTTq7w1+n zX|rZhiNndb+V^Ntw1^4bVK!W;hnd^;vevk2yyriKbnaDxtwS@Qv8RqL@!N~LZxTz5 ztwZ?TF2V7XP>c2lj-sOA8t|0;fW1S{ve&<-Lisp(oM9A0es$kO$<<2aZha~n`)LPe z$=0$1NsiDy@(om;8qB9Q3@4rsc3^*zJDQxBi0&r{`+YN*ZC$v}B0jSJ#H*+r?~`ZxU!coB`S6hq0ONO312SvlAB4AQ_)0npC5Ml3UEU?E-;^ ze!`X#!?Y5XW?i?z*aY;d} z_^t%vy;_NV#|9Ws^B<%YWU`*cz2t|H5?yX6aFX|Ai*|>Gk$HvZ*#nC*^2RX`!zR~b zwVM^X#}$;%U2DrjGvjdQ(&wTbJEC#LFby_oT@kz+-i09&P9X1h7hX%afKi(So{C)u z>();vk^a>_t@>k#IOCDwR!P6;8=r3^<}!_bU{&^&!LR9P!9*%406zVS4kUL(vL=ZFcj zk%K*cuf*;@(!sN>4*Zp)VQJ_D7}RgiF8{hOu1uKEhV%d~a1CIpyB?LR)L4T`$7QhA z3TI0NXnH_ieEIink`SjOO~qZ|@TmMS*v@DwZ-0HC-TSbOth!|d<$>?nfHps}X607m zEi%V&Q%9Uv6NM9F58+}ZOUx!pIQV7{o=O@8&zhz|{-UiIy7V{%znlp*F`GqJ{l{Sz z{=bW^LQC|Fv9a^6=wa3vzicg{2b7c)bW==nvI@^l0g%SB-9*gvS}wH0!E zY{~l#$1!f5Dp&Qrg7c0<1m+}shiqk2_*9%khWrbL zaBWr0wVg?3`<*2Na`mw~Vi;UhPa}c7FWBx1feBmZYa#vH0rd{c(T~p-kYxv@sm~^D z@dFPB$o_d4maJI~zB5vZW?L*Ae{4eTd>u;0N(I239V2o7m?8YN*>;fizaoy`xRg1D zCXsPVSME^z)fJYZ@v4@Voz&)=MuB15$E;}vJ@m3x9@4#Yo`eVRvwJ*Xs zF&)Gt=BrrVTmc8Y(}YKN0wMfB2pSEx!IH=`gq|6}Qh&^cIF<$rPe+OtPN;w}osx9Z z+!c_d+=putaRpWU>BFwEftcDq6&0g1u!CK+40d=WdfIZ1WSFb6J+sH+&QD83BY6@Y z)R_%A#-&8jdj$X8+*BUeqzPl^+`u&^qgcK8qTr)A4ogC3!Ma^XF>cxbSm@#jEz`_l zgJ~X%T0=;({Q}rgz;XP45Alru46vQ`lAO)yAZ~597=O?q-jcT*vaNoxAqui+pIpwA zB24hQMmP(@;TWHnj@v(@(A5lL?!W(v6sP&)!C787_4-e+leNW1z0>h>+ez`OapPF! zS~)c8uoieh#Uhm_a-grF3R$IsyUaMTJab?y?zf9Z9lK`qyf_Ee{}Xy$)90efEH8+$ zaL2%)vluBYf(>$tyyDVR*0&=DP7mFIwjRgPqE&E3{fxr+qA+F?V<+CEJ_T!r?6LHj z?a1b+o8X}CHh3i+i<{qn#CN`3B>jt!kMvw^IksO4lhgjP=ca2|^qgo+BKkBsPK(H_ z?M8YVXiAhX>Q=U}H>$<3&Z`h?wf=x}V>}FZ&Sh^7=L1BPkh+@tnCunLGOj%=YoB@r z-g~|fA59&|SI!V-8EIS5qih8Cyds=oZY;-z?WyqPJG>Ce|pR%c{>}osE9D&o_a9-&^ADe3kvY(X^iKgSP;v=^e_+*Qi*#`a-SCtLI84fnAes2U64-6$ka;jmSO(n=} zJcEX(*0VTB#S+H_=;kW}6I|nQG4H`OCk?RZ+hOb&aDdT=dF*=H8Il^OiuVfw*e7EN z^i=xIN_3)#Tg-S`9VGY?l@$26)Cv-FwU?Q%nJ!vdm?tp6%Glf&d*H>xnd~pT1m_*6 z@x|$Kw!8Hr&Wd@@L{ILq^RqADhG#L*lcCE7Np<4Uz+f;kD}|QWF)aJ5KR9=fr((~= zmNQO{hU`mc;p4}_c=L2R>C^fQGpvf4$+7}=T-Oywhn8EikQ9 zp3U_5DsuB(jG-QnNn(ElW=UNjYx0W4HySLkhr2@R&IWQrMH-xgJj?Sv4A_zJQhZ~j zaE7jqK-uw!arg8~X#Q{pp1Crd8HNP0`nVB1X=`^xk1V&IQ*(?d-#qHrO4X>7nytE0@+dmIl|y@_+X zSBsYgMX`L31niYm!lT=%>sC^prmOnRIQp6kw_?!hRW|27iOuC(I{=W}6Z>SSAlaJY1tPC@@}y`@3?wP zr5x^&BR0E9A7{`08(mb_VH(zLa%2V$&Q`Z8N>P$^iZZO30G+dvI(db$q-yNok`N};sey^BW7*#st!(z4KkV$^ z7uX=(gZ$@bL6LRQ5!O^+mssx%6 z9UPm%^n_%xNv3Je?~%g>9EyPB(d$lalAeJn;ll2jq#$Dv_9x=!NYAjSgm;$ z7tYfJ^|DA3!ZRGBwrS%YyEfvoSeN)GYe9PKZ{~M~5_4(yN*HS@Ne7zmz=@DXvSzBhY^-4ycd)eb!!{9~lQ>cxP6g<1k;JVxb{x;monoDlL4N>cn zdYvQhCO(6J#m$7PDPVS89S`G=sK8bxlsH+96RwE(PCnYKf_1@<$bwj&N8G-fo>*H% zMmd{ffmR2_=t*ewcZinxjl*;1x}b1S9>z#ykX+4B2tT$JhWO4ae<+6MiPOO5u{Q+0 zPGg-`%CKW%ztM-XT~yt08ri(yEDi2K z4X&XfTMkjx)uDo`lkDk#TN24)zMp6|S)G=*{}nub)J6WjEhTj1Ivf3N2~C)0PBT3D zpLGwV31=f{(}RyREh_?tH@RZM_0d>8ya`=jui)=inlQR_FS#+oGqvnj(NVlNvDKd? ziB~Vtc~Xmu^7q!#Gc_ULcy}WNhb;k#?<~W2nxV@)ob3GlhcQX_rJGG`v3AWO=#cRz zbrW^y#QHuGI?;*Y-W?(3ze9+k@C=dZI!sUXI?x5Xoay5UtLS@+g}6&Y11%Q1qsj|^ z{Gp|aBMwV&>z}dY9G`W|Fz|qU6+RnmzL9Kqa-b#?bIAOr4Rri|d0aeu7WURBkgxo1 z+ZoT(tl|+ibnp`!YkiV>yu8d%MimgV!P4Brvcdep*3 z_eo>ReHnOi`W)SOq?M#(wK0uFm)YKFJd2Ed#Z>k=lP}lXn4al>1!0G>S&air$X2Tq z!L8+!$iZjUd@i?>3J=Yojk1~a)Jv9G`!9JBScxcf*%U+XzOACqn)=y;9sluY!Atv>s&P_(AeHqsQgI;_VLDyMga1I!O?5$@^3#y@5S- z{vU15osTo*E;BR9c52Oc=6@J}p-t>M61YnR&+W^=ne`f&Rk8s(BE#tDi}JW+vlMcM zRrGeMGyPEK!h##`o~ZHT-#4DjuBKUda9=Lwd4+?@^dS;uvWi&DcuczbCKEr?JLJ<2 z!kSE;M?Z)75ZO(IWX;+Tde^m-Oe@h`*TcT9<6%~NK=4&z$2Fh%eu_p1(VjSnEuIL4JmpGW|^pe!W1aC*ka;GCG?4!75ai`H!aLv3weGk1Tir^kDYaoc}!RIj3ftkx;Pu%Zj7b7Lc(3=}2sJi4$|unCWu z9I`O26;Q<^6Y=K@L)?`7LLm0}24nMY8CZ#3BS#ZCa&IV{Ht6yEp}RSl)XDekEW>e4 z`%#?VGzF)7#;~zU>#iZIz8BZ?|Is2L5 zp?R2uL{$l-~-Cu0Avoza#NRosfmZHrM zTG>)zNr8cR1(BW@PE%AKGIJ}G0c-CwqK2YyH*o?!s*)qogF(=^<_wL>D5oDMZepy? zSYY3NF~)Lg8aXEx1qlf($+bylm8OM5@Kyj@?=MWQ1<#$hU`F)nmy&lPGjQh#BRXx8 zJZ#x8nYI^4)4y@;tYXVfk`Vly@448*!b{uWMgW0rcG*Ns>=LN*>XuvMbU{DQ96ZK< zB2}WPaAU0!tQxlqavm;#2|9IT#dsC$V5o zA=NjQy)j2el`l+nXCyu!3iOz3O5Oj(UNYwg)WOc-Uh5hQ%Pa+XE^N zjwfEZub2rXRpgb^IcCSp*$^9}2GeV*$*(s{$g5O-pVP$B$f;YgY+^m#3;6@O<7Lv`yTZqojQM7F7NA`tMKJ~uzkmagOi9)^(pKs76Qq2i;$UXpKLqlk2 zvJ||puOo*uo9M2c6VQQkL7VKgcxv_uoY|d(=G$$cRpl!aU7iM+Qs0Wi_ZaeS=bfa7 z=d>)ou#Y@;noiaZ&Vl9SbI8!YeA4kv6z)w@fQ#KCF!|UhnCkq7L@)Fpm+s7f^wSSW z?kiCyI$Lbiiv`Hkj$$q8V)rcJzLw$;+=( zfx~D%qjLnWIxnQqF+@`A5Td4EpM5ajZ4cYxg zhjtd0k{}Tec-wj%X6I?c{M-J-)l~~bKAM5u;WSqNYXqtJ{eql5F9{-={^XBTHIe-h z$IQOe&1$TcM%$!JxO8A1q^=(-Fg;ZcD&H5vHxn5uud^N}*remckK@pxI-2@@kD=ig zrSbQJQ|y5+4YYG=AWodM4r0V|$z!YABuwlRi8mPo+iPu6S0{mlz7K-n&UEIel`5Wp zv&TZG2gOIpv;Ahuv=V)6#X|9$44U^3?<~NpDa`zy^Z^B{h|xx z-08217kIqvCB0QIM-SMAV;Z}UmcK59r4qJy9(d%>vp@9C>;yb>@(ta)EE!#dX=ux5 zsRpy&(%2Q6!do3P$yrZ6)3QZEc==iw2|N%-EIw%q=SRoDmkl|BYJLX3JY0#QW%(#9 z=I6^@p;&9b0H=NnAQzsVW+jtz=$OE5q_z1zIk2{$PDuYsZoBjB+LBUcTWUFdpio&P z746E5DHNm1Jys~v;cj{2^;rfsPeiq*Qd%6g5g+@EL)2mEp&ola)2xcA_7kyv`*m`W z_g}a7=;NwG*XdIWDfCqHVa@;Mv2Wk?(iXAhG(Tc5m0l;x#Fi`4Y1~aZZ=WY&pFCtM zvcIF*<0sgB>H)f!{=jEWH!;C)6P{Uf2ZR64K{4z3IO3Cl`fk$roZn}vkI$xymB+xT zzu$?Dssx<$Ng;cF`;ww^8S*FdBKc;!f=tzmg8e7?>}QxGedqK4x#-0+rR!q7RJD6HnK-MC0WTX1wbY@?7wMcs!S< z!S5E3&&N;Fg{Le@@Pt+5ZpKxn;-^0;KBkIC*QI0PQ!za5wUOpsyh}eR&qdL6o?Fvs z4xLKscyZEdI=nEHn7&(r(>X;b=5)b6>^y!mn2mSrys`b7J6g?`!wP*%{BMmaX6I>Q zU7IMn--vShmVU6%sYV1W{+2NSKZs9DH(!97wrOe7D*{ zh-v`jHrYbVOCcCvR)st5tz=Ay9Q)+%IG9?0k+h7`!w2PSnNfeM$kZHJT(P!@#tTcR zyvHOcYw&3p0A=X-V0a;mPg9c6wMH(VMEKBXg zu-SJhRm+`;>Ipnos7@I(N1bJ&MOM=0a&5G%FejHAMo|~fR1$DZ04|Fx$SZk8Sn>5M ziCWo6UJ7oJw3JzplV3${JMLw~FC2qJ<$Pv`oF-YDs!#VxxT8z^dp0>E9zRaD!Zegd z<4G6LO#KNhJqx6^TN(eU_0ovj<`^&(MiN&lfwBJp`PDlH53S5ClJE2*qhAH0vL?SD z93I6+v*Xe8-C=wq9?RC%`cbz4z8k>~)A|XsS$$nk8mcr3HocFfg*oY@Zi*Td+-ak` zUq!N4;Q^T*sZO)JD#^4bN@UaC6vkzWJjwmnO#H?iX6`NTU}jj4C*|w*p};JFz4`44 zBinTZJ-kn|El1! zL){Mz(1)k*GMll4c3?VHy!nAz7g=L^xE>;m(8z)WnmaNEOW2SVW*%}hqpN!fHVKh}a zl87A*!|l_ASZqwG(Z6lft?n+V-?NA1mN{dnAdjxnx1rwe^5`11z3gwLUG#fVD!uUI z3XQgxMl;(g(xZQqT-w62YtE$;dmn2s5GIhC-9fD9@L6g;bw2+4dxk*&!lIX+rZ{)+ zN7ke8J>BN(k6OJF_~C9CRrU8G3#-&|YrF&reBH(lSnLv9ikU(>;(DnQKZBHi@uJZU zd5krjv;5rY#ypx*!KQ!Q31TCsNVCxqX!>uQ&^oY`DDCcrc-eH|I#$Eoqe4Nz9x-0k+{qk%V+T6WPJz8V% zh*K-hT3n5>!3=lMJDfB6Zv`j*c{JoLbs;IQGN8$KE6}pJ;2L)d?z+8$-jHH2oggh# zuo8j)-lx%-DJ)HU`iSxHr>y(BOvb9)3?k3}C9BqqAv)7R*e&7&hWiSc^gZ{W`wD@( zj?39IQC`B|S7v~Ajs^*LIR(F_uZHf)&BReN5!NsaxK0X&*I&=`@AI8#OzgSFb*~BW zmnDgZ9t(#5yFdnc7tmVU<2Yql9S7VJFi2+_N7_D;NqIw^t7f9{^u2f&+ico zt&_qNa{yP}oP+mtSXS!6SL#rw#eE$(hu`Cp@arFn`M-TIn{GnL4W;vxqrvWH5}sca z0zCtMR2J5oOoE0e3t*egKt!WR zU~rE2UYE`!1>bbB-O&@R4*Q{--7?1Na5O!$Y!8mM>!AmG=3}SD5tz|k1SaEl!&_L) z`L$fYLL+I??be2~f92ux?`cfCYNDmXF+OWqrUA~4#=?EUZe--jT1fu?-u-SYl1thc zIwgVse2Anwy|zN1|6F*uDw}>8dJjF*ma!H;`8yTg*KpC82RWX7WPjgwl$&@QRZaBi zdXsomdU_Fa_c*Zs{o(uOdihwTKEO=QsHEoSl+nzauZO%Uqr#K%MD|b+eCw=(j&*@N zTdjcT^;ki-MmFg6eFRtCZxHx?h{RX#hwU#ZoO%A6@2HuBl-Lfqp*v3KH}MJxE@#1H z=X{b7)z8c`PbCk&U8Z@03%Gmw3EWqZ4|LgKPzt{VYfiSX?NYXgk9w$?wLi*tdEoC; z%TasVV*2UjU)I*M1@C{~OZu*bqJ^|RH}};}d{-~Q!I}-+nCmUTooIq+SO?#1jNsm( zScqJ40$!~g58re8VYU1iVN;DM%v!V=W= zAcS=G9)>sV!^CX13gnC=kpQ1dcyL7o^h!Np%{Ta=l~fxRKAgjQXOh9);2H`iibCo) zWw zJio(|@SWSS^1laoEi@L(&bHz}gbvqWHh^O!%5a0BCTHPLj-sbB$%TtUjOJOM1)k&y znT2|=Vpb2E(5V52Ip*;0@GA0%^`rgymx$3PTNwNsg6`dO&{F3=GV|P8uKuhtH>G_l zTIYn~7su;#+xbm2aHJMQQlugIo*^8L$c2WVA<$>BAGqNFXlpNk#J&!wyn7I;?W539 zJd`|r{11{lXOelgKOk{+A!fJw;_&6y*e)`i6I=ZcdsnD)M~p-`hl?d>OfTbeZ4qH~ zzPK=J!CS~Y)&Ma5H0ZlN2P^L;vd>){B6$|g2CHOpd+$Z|x8+9MQDp%0Pllq){Ha`+ z<8)x2U!@Z3R-;e-b_&5A45OJ0qelhe`xCD8!dWl6W%Mwfx}1k8l{K_=(E!o0DbBeDL~R4?4QYn6iS^9)S~+lZR)BeTo$2`hEOF%Ue(F2>Ai1ekf{~A_c$c~< ze#|c7_e`e{v?X9`r6n{bjRw;-3m{!nKxLjPfsq*{eU_RKT{9EH)ITuG`5W*H!6E@p zTZN8kreGM+1rrut!X=)MC^>YJI4$*NW)3|k9(t2t`uZ4{csh%?4yaOYbSZQlRs$`W z7UEgx1y=)B!}iCaB*232Oo#cPcHMD2_c9$;|CK=|ryA>hyCAOX3N$-3F#fSx+(`8S z%rm)+bIb}cS2_e`R(7J*xmvt@&Kx!RZ{z(p6}ai-Im~ymMeDL+Y%}e`7F#^Pg@>i@>L6V`RfbpbKbz~_ug=Ap*Vaw>O6}_GqdZ`ihFO zeSVTcoGS*N_R++;Y&Jd(iaN)(}f=7e&cM27)XH4ckICT%Q{F}+y#rL z^pT$zFM|BaWRSJ}Nd~h2lG?f^dUt$-ps%`vs7PI4yh8kGT)=x$c1IK!9BVJSY!yKD zx5uz@O}WfI<&PvsMHdGX4536Dyxh zfYXNuiCj%QbsoM!$9xqp!Ump8X?zya#S-D_?Gh+D9RUdrdmwz>1&9;uhR0@$Auuft zo~RXKUBwSP;$n*LF7^A1BDZp|Z>+oL%99JEFwlv|Bh+_*apYFzW*K zZc2_Fv4phk-c%R9GEMKKNmjyb-2EXPjTu=o|I!F4Tk8R}%Y{OXF>B!IXgw(FDJCj@ zXNmc(jl?YVGAVxgfm|Epd0V=!;LS?FLw5;qIy{ZOnR1={tMP`%Z}mvn=GSzS$VIAm zY!7tl)sPi$Z!+?FNS<&-@OO)baOZ(DLR0xZ{=O3e=l53duAxX~y!>1ClFAVhx8gjw z8THXOtM9_R314CPeJSDZ?{;vcKM>5;O@(z~R&?^$(L|SLtB=g@re{9Jlh(C$WQ$w_ z+7I-TTLn|0U)+%FigAHA(u3rwrv^rR42Qpd6ESRm00ya>L&oze!Kf2qG?GkON$No$_2~}$DU4)qth5DN#WeVs zRY+MIJG}Xzo9dP3;g~9UZk6|g`wE@K$KF8fzx}Qk)twiVe|$<@|Rp5@&AWM*45!``#Y(SJvme_J+Z?!u8Pg z*bz2O5I~KrK49M@h%u5BPJSSbZv$rGB=-vF7|;;DO;r(gj`|4u_i74nHV?xJ$!lQo z#0j+jU4Z^h;1W#Cx%GRGaN>L)$!x~}?)CbL-v=)7+0<}quKtCUw9dqHe-=V$*C1*A zHyJ*vA>evZXT6z@CIPe7KZC(o* ztr=wP*$zn4cR`f^Gp?(^5WcI;#6IIx9NHfW(w#5JOczs#PSA(N^X7qQx(bxNl!7O< zD|iNjK7BlI61?(Z>DGt8*$Co~QX(B_AtA>-l4_x^;2u`T^N{0p4YFPK)T~IWplWh5ZnR*r^ zll0hd0GkSa!RkoX*5yL?hxa7-VILjK8ymV-NYQ@v-?U=&U6i|_!gciebHzstc%E(q zbU$q(?$g9AuMVe>us6Jap?NIqY`+Yrw^e}mPX@Eas!%)q7FOR;;udy|6H}b!>!m>Zw6T$XLR}FzESm9E8j<6in5(MaNTG+^TF7PG(XA zdWiqT*b_Ush;${+<8>BpD62)QnlyYBl1{C)Cu7WpIrx=lsGeKB1niw9prPYBI4;*G z;=A&xO!yP39=?~Z+!b9UvR;hbUV`lQj0&dKJQ(8DT)_R1ywE7K7{5tn5h=4f#+G9*I_2!8kv34bBmmNyX;X?{M^oC8SmDFcu5X(sebaRJHRCdjAP#`M)1}y+x6` z^(7Q%O&`ULEO8*uW`{uVh$|_1;eiJ-Y{}2raky1$2CXYNN*23cfi!<7+*}_(?y2OH z7fy{tJ8l848XZm?j@v?a+)eO*T?hKXpJ3PhcVK7R2?dhZA*bpQ?0cdhw7sKD)}7r< z4k$*WFf9x;74EYN9SvmS%~;Z{r3^Ne5zOb_`?z%DEBsNrhO>ENjQZ{~u|&2Gt1P47 z(g!=zUfM)g&~4B-Tup9{SAwWnG8kptVqxfKPvg2~a-*zOxy$;!C~0tpKHsqrANi1!j7M!t)E(FwOEj`|)!v5e^wJ zP_yRH$f8Q18sfGWQ49>T8PVTD)D=CY<1LX;)Q zS!qSCFKZh&b!s}-HT@JfSNS#(wfWApNiKyMr@TNhARpe_H^5R0U18&xF+%0dn!*Q8 zQ(@Yz#ng1eGaN7LL0%S~B5@N8ad>4Dv>mL1@v&l1zC}U!Q}F>g)>24R=k$=-Gp6C3 z{n@l?w4Lxy=m^amH6Cqa55Tn>&TzG~oxCgYfr{GYBzt=xXk-Ob2l;SJ8NHQTJxc?Y zR;!bwDf?;8Zc!33`3>D9BhA&X`ovmBG~mFh^;~4(dU9XwDtPrq3TsUK1(&>Hi;e}9 zk?Ia3jIiu0I+HOOk4^7|qxR`=^5ivA#zex+#682zp^)b$1?FxaS$Z(_31b=3|0Tz#Lm-0($-lO4>wh}UetvOUIZ zl*Cd0WN~qg1ai(f)I9Vsovt#0x!1Ie+w7N%pXv%QeW@aM&@CI=g&Xkc8wd1AY9&FE zR_J|<=PH~}1R=Q!;R<@Jr=>r8=EN*o71sqzQ!1gRMo0MRbpbrw-^w$A-$TL9tFUuI zIp`>}@J7*;E8H}MhE0`RWX*cT--`??+I~&8UI}3KUg%gV=T#v)`g&tENsvJ zNgT%+;qm*+(As_(^!&BMclotw=GTlDe3O{)J1b!R-e??{c9tIMO(*rbjxZ7~fE9-e zVCuc4T=LCJ_~)J|sESshR{2SMYZ*yy56XcjDln2I`#?$7SlF0t2@b`Fp}zG#z3ZKT z!wZM0;=WVtlQxw*+9Ie-U6m(6Kq)e3>&sD$9?m%ss3D^ zqtCC&=QQhZZ70WI&)_F45t+|v%sxQfV*a3JjyuN%2~hvdC~mX0H}`(yR~Q@A52bfc zfwoT??EVuES%;Rv$}$BgIwvmtGeKQg>wE&bechmg$poG0(L_--h@KOD$Uc6Pgq7$H zC#>X9eJsa2p(>(02Y9t{}~k%UnL2I~F9v9hqpz9b5hY zs|ueLsVsZP?EKGW(2JY)+(-;ZRnh8bycR3&4N z>XX;oPYIWtpAN1a9^g6pIC?A^%T>SsgfIEo^QhfQ?%@Ri=P*i~%TJoY^)Vx;zITLF z>pY}Xwa2*Qy-T5ceD`ff015lipLteRFC8eqtNLBk>@Jg(LuHMt=lx>8+J^3ze zqY>x3btMToxJyN~bvSdSCfpWeLEdGw;KGNaxU>V8 z;OM3M)c>^)wp=md8jdQWVCi=J6MKhe$ehDJjj8xTB!cgtuEt8uA>6<52I{|xz;xqt zcz@R#E`eRbZBsYqQk*N%+(nvmOP1hDjaLhA8PpOL)ks#~zzSZ*X`tpqIXEry1tc`( z7_W%g@aBYyP)1cwSblXqOqJ9W{u*&h-Bn*G@$xgQ`u7Ur|2YaL_jbb5bF#v@ zr^~@_Fc^}`Q^3h_Dr~hs$vhvZfXd8$!gZN7kU3~1w3Cq#9u(aOqm$3U{HP1?Er268 zUyFc?Oe@~_Gl-KvjOQN3chHG@%jhB#Mb2hJGS0lU8?)BV;O;54(=WfJ@#HuUR@3zi zK9-Ror}yeH&jZ?v4n9&O>&rV~rd19eeC$KwQtmTfSA^27FAYJSo`>3^muzzGCStWu zk9U|?!o9fN@a^npV#jxvKODM9n>UYvgkDi$kJ13sTV=;g4PQrg2D!5v(_*N^=0@uG zXB_{%OW?R!FvvgXJ%jf^6A9(}Sp;lntss?)=x4?zR z?O@zBn~d)Whk9s)tvqX@voadaZT}62v$8=q)dB8|LQwD-1M2s-fNOsX8*%3)-4*zP z8hw6%cawfntw~GqO7#*H&yYgASwKr>Zo%t{(zr5mfXs4P2!Fzx8CN0$dPd3QGh`Co z|2*knfdY8Dydhb_`LJWo3izcS2cHUR$;vb9ICG11!KD&$;THuJj34A3QmwCu!tF+8 z`S2l{r}qffHCN-RR%>j~FU0t-JMfSH6{eOQL)`>&cwkNiDV~=`!q2>gLjf;gPx=>N zjhkU}U<9n3UBd6;dcY&m1P))D3KNB&(09f#RzJwbK_gqpGdKo6Z%<}-hV+ppPkneW z{E=j3*OFYbXhB}lOZaD?N75&m!tUAxD4JRc69elY-fxX?>C@x1?9VT>abJR|@~`NM zW9_)2+80f?ABPW}dtj%>G%~B!LYO~M6OJ?~!^@?5F!qBVQ52|*VU{~)8;PSE&y3!} z$e>i=Mo5|A3@7IYf%O>yS~VAvBmdolokpL@ey<#&E~x~wcjm&Z`QpMwra{8qlVd22 zbA{V)S@CLCQOc{cL$Gv=_&#dZlmG%)m&(cQ3ToaUb4o<6Y|>5koH%L z(N0|xj9W2;U|F8+w-$r?ss;Vmj$-XhN4ysC ziA|T#gqWqN(B^*{LPDd6js0jC68XTapIU^uEvNYWhAj7D!||dMP4D1}#0;U))DcU2 zNfws66~RA=2R!>bm`wWegJ^L7;bV)(sJ2-YU;kF&d|Rx!(mj%#?mcVHW|}>BYN8r9 z<@^B6P*#CUP7(0D#)8z;w37?IN1$bUk>JSt2$YtX2H%e#0ne->aP*3zkkW9*5$3Y1 zEB(Or#tb~o^{}gIWXUP+J9fD6^GTjAcWci#TsLbDXTH>yv1~$FX7<%EC?M*0@3wRa9(5vJSdEWob79bs+L_uG^?NV?A8$`y_Xf< zyEsO;(IErel<&ZMi!s7XK5OZ`ObQ0a*n!&l`P^|=bUUw`0c6>!93Z}ud`mdzVdnFuK3xz(3U_qa8Hf-<@2aRA8PDxsUyRmK? zJ-SQ|)3!dQ%UlxaT{#Vymc%m%%fD08Q{#jyBZAOA61b0k-{G}1ka=VFTh3hl1FGgu z1Nr_GV5tZXFPEV&{C?3kw-j>o!6ssq6@+c;d7su4SyVW<92?He!FJVn{1E4cTYRUn z=erraF?1VCVwEwtCX`wZe50S1h~P`@MHuJe0Sgs>kS&9qT^Rs8Rrx6crG&a-+kuLO}J@L~xwC85UhuA$P8xhg`?2%#fcHoZ0`4T$j+G zotwT)csywT7(P6LuWC`m5;L3`NsG)f|iJ~3(}C9mV5Mg9{Mxbe>Q zM@RAOia;FdslZ=4z39f(;^=V+7#(ZOadUp7sDB5|Fe_$X56OXMpDAg4y&0dbzlEA( z?!h9Dv2a_DXWafWdB62yf9GZt?A^zrgT7Tg_^)U!0QM<=tujBQiWkb3+<)bT#n@kWE z!gum$5kgX&1x8P7Am=2{Lj3*$bgZ~uj#?2PH`A2PA9`&2kGbX-Q=mgHYiEX1^d@(c&8)@I$Um}S$rRgDP@uQ2VY?{ zwo;#cTC~T}n~HGBkSkuv&TNz8v=0d|{Bbv4EE8px>*N4WpYaPBrett zw5Ypqk>{YWAbXMFENbehi~0~5y=^-l`!5dXjJ1WKr4q2CI0!79Tj6p^DZE?N2GKnT z5+3<5LHHf2V3ct3J`+~;>70k zPsFa}BxYYhi=Ps>%_$hIv;BD&+)LJFS_`c!?uHrbpFp{YJ($1NNB4*rlBR5h7keJ? zj)g_sX9roXb$koSHoQk4yzK<{A`4LW4I#Gg>dBPjChY1~DfaE}*Nobe_t2HaARD)i zOtY<|j$TyKBR{ct`m5M`eSPNy%jgysmCj^_E@9vj#_x!W6I6darRs- zJlS)NbVPMRsZdQAd2Fi?riVkn*An=p84IKDT_jtp2Y{P9LHIB3FP^wifd9UoLz9s> zYLjOHm&^5FPTCsO`mBgs4E0bh2{%AohF-#`5u= z?ZNYo-rR+1**|P#u{@lmd8}IP`&N$pycoiP4x&k&5*B~Qz5B%&4 zf)#f>Kp}K4NWA~a6f5$d`_Ed5M$82~EyzVrla08fzE@CsGY6VR>2i&Sx^dk^eiuA@ zkx*>!TR@xb@bI~a@XbmAL==a?e21$-!?}rYDK8#etA5aS`49m6SIi|%eN@qyU+6w= z1DTX|4K446;2oJ_Y^ew*veyi8R`GM{{`@km@M&dvdKxy|9wYQf`2$in1f)HX1=nIp zVeYmg!l`rD5MQ4n_L650xSZWd>dg4NvA?7+@5f}E{h<-}4ZK9ZumaNLbrQdbRZx-J zS3y}<6^<^*WuNY}roJ(Kyt`K)b)&kN@uMP0{ni{haYZClm~E$-txM5imI!XU^@Co` zSb!}_)5r5M(-m$7SP^g+4eI;xru;^F#`Fa}OeHwI_S2aA_^N&qr`DXwGPA;%h!S7y=NwUI)m@q>xsDU|euJ}LWrQic*21^h zkD+Qc2aDF72D>;*q3CxLp~HT0;n~9vFr_RV|8swUQws-?8~+@y87iWEXFpCWZo>RK z;iwodU?0sA3g+*>1qY9Opv~tdO&Mo-EZU!q= zKSdaSJPjldWy3O4z;4?Fs+OD&r{;!XI#)BDwq3$Oq&u6kNi2hvH3hZ{;&|*j-R8``!0|j-ml0q z&00E9If(}Iw=nxe-dpCwKf??r;|+y1c-WzY24=jW&lT0UxRU$mSR%`MbKDQ2#)BKun2(92U|&?9(|X!%>gxAEfm-C2cI z-YFYM*#CxQ`>fUrJUY%W(dgKXl z`}Bc)8;E1t-+p9#6lP)%{lID*JxQmwN(#d+|Ad=1k3iATA3}uHblQ~d=$@%33|%rF zt*5QTBrO9@^KBnSy_Uz3)a&S)bs4X{i^qoN6zS>|yu3LJ_sl(?W2qRpVv~I z0N&%4zl7Svyrzi-=5TwYk9J+zgH=~KIIcCDcP0?0t{1RvQ96u>UIFs< zC3tLo2z9O1V8HLcRt5SH{oq(Zbp923^V1@7sNheLaa;*G+G_;{#(&7X7ZnhaUk;nR zU%>SLCPG`%W9Yk`4HZ^X*&OKvVV8xtu&jTvP)RKV{dWDpeMb`TSNAh?T7DUCcqrn0 zQi94ot{A5Hg`N$0LV8^*plZ$n;feyjt0^J?S6anrwS*OFF4JX;mL%{!^H^~34uDCf ztH8TuAE?I71B(zhI{WdiqLLm_>^|d*QymuK$|8R@V|x(>oSp+Qslc>;jez`3^_0sv zgOzKV>FAHrTu!Jrj;Tq+ofRECQ{X;sns*j+o>XJ1OdggU3r5lBzc9tW6~EdIOB_WwM>9b!?W;fb}3Alr!AbKDJR@DSP89Gk+3o-5_WmI!kXOEuu68c za7r78e>$%t6PJN{daKxXTlgFA=o&n0l!r>!e(=6jA#QtTKs@IPz#}6WL_17y&&ybH z+pL+5n#uR#`jT)`-bU&(@1LOdu83gd#|!dg=~!k^YX_Sr7ey4Jcn2--byMt7U^e`o zjveb%K$H*TDy{S&3#Y7u37c;hWt>)n!6*A^Sdt+&e*8w3&kclKw@RRS{1>|Nk1ADA zEr3lc9?&!|L)Zh)z+cA~9((&iL5C7Jf9@w|XUkLK_l&vb_L!_|iUyaEYapw2fw)w1 zyzDaQzios#@o=yWYXtM7`yrx_zscDrLaV4F4P7KlzgK6H z(Mqv!<6%EDTR|MghE0NWzmuT0XN2#w?&sVi#ke2)XL7RVw7DFyR$OVR#JxTL98Gie9Upk!dq8lEZB*<1}YF zSMu4EQ%ab~jq{M=zVn~SF^T-0{9-1mgf2p_p>3$WM;or}u!YU9L*eiLC^`>Es@^}2 zXJ=$&Q^+VQC53yQ=b(_0BIBD#qC|+6l$Pv~JyRK_q$n!mp67Ea(Jm3Cl4P_fEv4;u ze*eMc-t(N#=kt8tua~wp7E}9#?ESQ9o$5DuaJLDrdwLd&-8hO$ayj02X+B;-ahY0+ z2`W#?9q)WPix!lv#gVgK;|~_UP;6}hSMyoYxq`*G>AFAe&+WpcPWRBQ))~+sFbl?| z&G3Ki%b2Eje^9HB45}Ra{~g;OwEfH*Or#E?{G@}J1SCNOnP-{dEXF<-<)-udC(yTP zyU8PZ8`=NX6!)Gxj2anPHZjf|8WhfAP09|YiIx+$&;{7X_b{ZmuZN1JA@ng=oXYf< zz)wSpAU-LCa&1yW#f$)H0w2gFDD0t~%3DJwNYMBA-Y!aby(sa7&LwPtcDV=RN?|%cw}&#d8Nzn6<>=G-j$FUD2hkxmSj8%j-uc53 z#N}%Ut)WOWdbg-suR5s5E()~S;56K2T|!P8?yJ<0~F|&KW5R>eEwm@v>I9|RSNGLTY|h}c{qRGUsBH$ zfPA?On22A;UlL|wsU3s(frim=YkT4dAI zL3|H?YzjR8TurDhx|NuoGka?qt_)~P;}rwaFf?1U%yl!(XY8U^xUBvq7OR7$=@shkum)#;W&Z@K?GUow{)vFLRn8 zyRO%e5Z9;pg>n>VglB`%A1-6jJxXME+=qax`Ea1I9i3WZ34&p6kR3K)8L+Ai30IC| zm9{pHEw~q-cRYsqwqB%j@qT=ls|BSaj$kR3VN7|((uTR3cva;;Vx*`{zfJmq#Oj`q zCv%5!_^dO0hxNfAv}z5Am}QeTbn`G~hBQMJE)Z|gv z&KjZJR3NVZdKYT;*YTF7_E6=E)PUI|4&`2pAq3`A%7fC{)eX&B2KdMogm4C!0ww)Kpw?Iky0RpwD*t$iVq0-vl|2i>|tC`7L0{If=Y`G zdQdzI_|>h9{82|@@$no}>RJd(UrEE)hHE_iI(-NiiA6>#w{gJBJ7})D9d?^ui0Fn= zRKF(!zxu9?&H3N)vmY1H;?@iZG!DQ)4^x|~zxPsm^PK3~efHR4$~7eQI02F#j*<7{ zwuItxz3AobRkB z1tvmHgNs==B)P2y5v3|{{dgIwwu<1@y?OW=KMs$j3ghKFZSb)rRrvkIGRxhTx5=G? zHX^~@0X)pV!bF6uB*ruK@W-W+Sjl)hs{HFfPa83$?SJXfORQ&r?ccA&uj2<N z53PR|P=20zu%$VS98lGPWb;2nJt6~se|-x5LWOYPy*>H%@ddp3vxxm5=|g_jjWdh3 zt|ppR5BaUG?qpU(6cIW4lcbg(AwAb)Auu-&tBsDMh%+hV-R=4GYv*n(l9Gc5jCDze zHEA{wr150ZW6E2<3vEh0fQNOASTXh}oQ~#ZQ`{ZA#n#_A#aVz>&6!46%_tFXO>5wAa9rCq624Cu!;UMxH>Bq_ovIII|h;mISok8y9U{s#lo>PQHWt%;O7?` z*dW)I?swu^PZ@V|8MfX6GTdiEep?lAN5w)^SNz)|bh9}5Q|(4ftR6CZM>jL? z)#cDV=R(vH(u^XfB%<%T{ZWf%H!8F=z`j9C_&OUhaaF|^bna3cQ#+BzBL|Md&QwJ- zH{~|}>h0}}K$0F`WTXroJ7!|heKVf;Ns5BB!zLX4VIEbbw4Y>3T_a@+F7XrJFCs2Q zW@O5m-6Zp$G)a~+wDj;1;`s1>bOXBf zEtzEh^~ZBpm7)iS?a?ful^iqnC6!`7$kf`p@f4*0W2VZjV)QS@Q_Zv7(aS55rqG<4b>I?8EKq^EBL$>Kw~iWU+eS8TjwD8g ze!R-!BDChElx6ml6-Z7*0PQtc!%ukE%oML2K_343WVE=1cb{g+mjo^To$rPGpD#XB zPqy5k5*|)Lw-<$@Mx!lMN=p+ua!wxai%KQukFH|AEV83oBrK6{RwC288x!r;{ru23 zOBpjdmUyixBDtNRXx;m2>S|5~m8af?B0iNd`B@1ZYqH9<}i2jisV_uU<2S z?y``2WSshHaD~6%)oSK!=LL>^%DEp5i_yxWy-2^I3XRlPP%{{P^dnJ%3HSVilxpXo zzt_cy;OZ}w&#-&zFIYkbv+9w)wHiKWScuT_M#eMs4BB^14Aq>EB*RNL zk&jEd`TN(pkS4n{lD5T$1e{t&s-pK$m*aI9<*@?ln9)mSgUx+D)nI|LRiB{Qu2)DN zQ%mj8e!|VaKQf~_2blxax(Fxm&|Kv{^lW|?Q@d;pdJt(%T!M8N6554rV{=ETtw$1hFXa8GY2`PmUYkeEjhiK?*!B}Sb>K9)zUL?jUOf#ttSn(vm-rJm zwfT(QR52uKmqZy4s8d}i6CGB>WNfcKvdPXz4n^Hexl24#^7#n$-ts&@=7BrB73xDT z78>An;oa0`lUiy?rvORLuVR*OYoPihk5S{)2Gp;24qfrwP5#aIBPON2%zCYJ{5X>u z6nkhIx#HZ8UYwrIM9o%5-@8RI6IX%O?ayS`5-(I)p@Ter9zsuW8S=7SjCB7VCLzZY ziSlwSq$3qUmUBEKku)>py_{i&u81OEdo`G-NoMRHd85BJx0oWuZPfG`xyVDZ38imb zOtL>Gp;<#w=w$7Ba_Zx8n5k7vef~|*(Me4d^Wi$l()Ok1qzX}rD?n7mslf<`{}GOAhrD86M4F)>vnsNM?gejSd^%M~-d zeV_Pw9zUsp^i=faIm=H@XhxwCrsUhbB+^rnLluNeLgvRJrudl;ipIsvqj#oMlif~c zN1!n-cAAcjg{`RSvUsHaB@_L0zRUYuPvg)?Yt(2ciJ$4oVJ{myv~ZH5!iEZov5XJV zTiw-E)T}`q&3c%Y<2F>ZT!%$$n>ErK?BcudoG3F}Q4;ydjPZ4y#Xk|nFlI!D>UOUs zioq)UQ*953>)ylU-Nv(wY@Y(*MenA*f1XOLQwxZ_|5Fm=Xp1)=k3?Mt3y{RFA3P7t z?R_tnp>#ZxsCsc9)V(Q#-!p`$YZY-sHaVWTx!qZ3&O`ncK+2mW(3GK1=xNkzX2S)} zJ38e6sT6hj;Cczr?@=k(^0nH>qt=qAod z56dBK;Z(A7gBbZ1KA$=|R~kz4H!_jx4W!UWlH5C~K&cz~k!%Tu*=wtWOJWsK^kGeO zQZt!o8U3P4Ke*taN2+{<8=_RqdqCf~ntJw`%?!y?A?26V&`wtkBGV(u2wQT|C-pY8 zw>pr-FW3TG>j@>9S;aIJK4ZF!8k^giS1{p=HWH_MV@$SRD;ai!kFA?vP z9q669Hp<)HN||Y;F~gH}$adXXVxJ*E>NC~IOlG)Ab#o>YlQ@rr4sN2_buW_OaC@}Z z^eT}ME+NN4K9a?f&E!E(3^}E(1l!H^kU@em>HE+_mZ&r{SEoesvKuW(SXv^bT5s!}~9`8hneX7ip99L-8cj0r0Q)X$CFD1HA3U%+cC&$lxV&=svkx#QRc~#6b z5AMk(Jc|M5c*+NA_BcX=rh8LFiA92}<_hAXN491}UieR>#f5&SQspWs8oGiS92Q= zZoYu_?2y2J8eWp3@(Yx)n=X~my@lkMPNJdR9OJnEQuChq+&MXxhz2&vqZIFcWN#Xa zCN=euSLb79!ebHIs^3n9KRCl&Y{|8h+>?%uznzM*OADCIsT#ypXUwAg->+t`@3Z-~ z;YN)7u1&mBj_V)!B9olajb?P`*^=7}EXd5DbLh-EMItkzMr?(}u%MqP{Q1^OLbqg5 zdl@wpHuoVaJ9MAf!!hc&4pPd6F2seM!#TNFrsPrlIBbRAJ3@Zznv3w^I`PrYCUM!-9k|Uc>G?r3gY%Y4y z)yVjO0g+Ar!PJMhF+yq**yCs}QmEfZ=I6X+&R>#2m(BMQk1Z8_><^b`BlbB^b4t(Ok{rB=QB4>&mp(uR`9-fsDaOO3$Ux)1^WU7NZjB` zDrH0ifA+8<;?b)S&+jkQm>h#0-%Mt-0t5{NZZ&Z_V{LovA%tf@rnq zO_cb}oN!UK<~Iw9kfz;Lbg(Cv)MyG3vn`rrptzn#FR>+q8L}iU<}I-73_bXR7FlvIAbkbW?S=w=oib z_@qEs8?B}1qX5NQTs^oC8J&=(Dp&0%9m7|t@5qNY<$xMmb$ycBaAB$CPMX4Fy3gq=9ckZ>+Gn(piiFRHR zEOGPpKMrTaFadede~ zT{3|}+W+wkE&&AfE%R9|MPTm0aHyVIsdkk}bNgDHYPZr7CtbqIe6(gJT zBTUqrb5!8;X^j0cmU?Zzoa9LwpiTAmlzqN7(HeTn)2qCS=GCZC(@SoUBgZq5RzN%n zoNdbNKXse@;oS3L-0c0&8qOiNzW{yUGUODmFIa7*ur^4qxcl* z_OO9X%^K9q=9#=jhnADx!Ap#HsS+bACkxlPp7Y<10_NpiigyF061gL)RFUCcG#dGa zF|f-(VyY%2S9BA}UjfV)1+ZM#t4$0;KUmh}=ut`a<*2N=(OoA`wOPxF0>}uA>{K%3;mp^1OmX(jFOukM(;;X0%GSM|LG|W2}ETGd~wmh}SPclHwPj z$s-S#rK2~|j4)YbLYts>+uxx}=CUNza0f|#A%O0OZy+KQmwA0Qzo{P6Typ5<0$j!( zMeimkGWNN|s|$!{;#PYQR|i4dyz3Q-TPhCk&%AF|+F*|IawbSIJ)2a1 zf52C~w+cGv?j^VO_3);y%s}a_C-IW7#YA9dily^XG2Fi6CAl(#dk@%&&{3C`t?ui9p#yxN5vSZB6OlNXd$BSCA(2m*LV1rLq_o1oDaX93ZA(p^l zc*E&BcznGZH+n3^y6^0vsq7UI_ZEkh<>z3}t~*GD8D@Nhl;NU~0e(=eM|9M}(LQZ1 z^XBc3dv4Z{xG{5_qSeVvlgh-Fx!2Ils7|!JSDcn^@FmUrZu2spWkJ_-C)mL(2RlXv zFJGvQgH0u{y_zRhoKuhVoV{V5?RL7n?N$RxH6(U^3eh1apr7TH&wXn4LYw>Ua6@|^)F5?d$eXvi*U!HUSSAP2kWk_3V1y8gG$b!V5q`A!=LO#yoA8V1oqQ{z{ zeZK>m@FEgwlLEm_!ywvc3I?~^Q1ZGik~m<450AEDXLc=Y`Wu8M zz!1x9vLc$EWsFXCD&%zf;{Y2U>{X*nb_uP->)S1HCp8OO`RSkpx$9JXdm{c-Z4c^M ziKz6$Z0Z%d$5`6FqE1V_A*xHKuX1O{ z7;)$PCC3cEGcrFfQ?@J4!6wg>Tn=hG7ZWjPCC2fpH8@AXf@-Am zt_0b~-XaT<+liByAN0&0CI^}(i2neAOEWpgc+o!yJUt4pAB}_Ol*{nT<|&jnyHdr; zt<3P6vvBx_Iv5M+pu~Hx$XekR#(C*s=Fly~F_8bFbuHYpO%+1-+S%x7Z!In;Yk~}y zVPu-V7oYLGOC-P;ns^6E>jf2jyh9aeVhUdIr^$%eL2%hx0?R}dh`_cg+*bD*t2l*_ zqJ0%uEk}x8Z<9vqqy*{eTnXAw_YC81okY(5-inV`SE2sZYR#42T>i0W502gK%jJkW zNyQgwXi=*tw|18!g{P6QZ}oBT?!X}7vm&Bvp>$rE=31`@)a0=xuPsQ2~gm6kmIivM!7xkYU=M@`x0(!X`u%-Jt5#06^ zohP~q(M40Dwzvd;tB5CFp`i?KR!15fPm%1FI4m>g8L60ANBkKn z5Ua3)by16;Z2d9vvR(uJw3rg{BSMh!;tSc>AppUPlptlBGxf+GBX_H_{EPw-gc`b- zk?HL`-JK@L_T(LE^Z7C&wJ@hygsXRi)nB8EHx>AVUkXm1ahG`+Gm0i-9GL`rNfZ&( zg*v7cLZQnEjOurz3ok@r(qRR2(Z>z1M^T)U%Yc8O-2hakUVyz4?@^<$4z~Xq3CmI~ zz-a1W^y<)5GOT=A`0WgL+;}`1yEf_a(q8R`CB}Y?{P%1K5sia&Gc16&YntZ}pFLqj#O)f1On65=>s9fWr8GhMl;iOJb8dOLToJ5GtGOXAdBnsBvCo_aj{JsNx^hzn-k z#*=c^q~hyWzU4QJ_3h#bGI+?{xvoKnPK)BB($ZMp-w%@=5x{6~M-NM!7;o3d5ZKfL zzKs^J=kRo5xOp*XJxv3b#~L7Fkj->ntRrg^2Z-bhZck>VBN=Wl!k!v!XhahsizVa8 zC(8(LHa`brtDV7Xvki>>O#?4cPe|Li2wT7G!Wv=kNqOjIY&x$1OZZ1%^vn-eMqWf7 zavPX8T|nx7x|8y_N2EE(4fA(4qdezJB+6S49qiQsZJ!);KYtSzQ+|L_$CXg)M@-bz zESWz&RcN#EaVAhw6*}w7V2YC}MAkWy5eETQQTYTYzEDOoi3wmOR1T^t-^uv6Dt78N z#LL}-@Y^7B__oakZJK!iP4hCq&ELK80R;^h@O1(e_fK$fqzG>HltAJ@6RfD>{BAj7 z@PKTFuQ82;V|S6aLj@4jRRDM2?jaMk0&LrZx8OBx2KjIMd>mUh&NKKE3{7=DAa=(d z*IriSIBnK^UYROs(W?M{{d3~hW(7LFJ|KU00oi0d1-8#i=R5AWgKjFebGt?%u-h+% z(ez&rkw*@~_V_@eG@oO8E{TFEI`U*`a5@-?V|a7j9STzl$g0amh%LU3nlc)RU#cip z3|WUBtlx_^yfs31!?{`U$#$w}y*mnZ3#0UwW|BkGW0;5G56F2p9q9eA3xU)rIQGk# zh$nd>gSw-*{PhPEw0SD7t#LwoQ4Bu%{69FmQHo<(Zox+$v1sY{CVa;|3?B47=jY4Z zMez@>lFT&{5PQoSd2cxZDRYwffyyUgp!Qaok{zb+;+5eJ;H(EUoP zW{VRMFM5SydgVz%@faLtB-w3W4}-{xagcl*2XYlW$enl(KUG$Ok%}6;6AVKFS4>e} z4G#{!c|m>rXNEQYaqh<$C!%=zA$m4qg3rzQi~>GrA~6X|thVShe)-T48yr4^?v=MQ zYfgM;R0X}swh1Xv_Z0@4@h6n;SrIU5KLpxGbx3BIA53`vBhNmTG6pGrIAF#u98>iO zna>Hs<4Ee2w~*1~={ZQ`||4Py5l2K&!**vM90Hn35Y zJ>W=V$uq0q(3N%IQ}T?dU4D);<&1LmRtl=KR3cAOwLCtF`h&`g1IZ;a*wPz#YNQ#_|QKu}*RbaTd z49|M`6v`fR-L zWGOx)Z^#UBj4f8vi2fuv11F5tkd5ZDsGnKiEWJV$=cw;SIaiv{#8@c$^!7H?Zs7ig zB?9Q{Z3gX2cV_16nPZRt&e7K z0X%%O1KjKqq3qRlI2BR@Yscndv3UxZjqXIH^8Uni;ap@EXMrxI=z?=@21*K&Atu*l zV7jpj1jNNMS=;WzRn`e4Hig2om>}5wHWEI4Rflx}60GjdDEJ~83B`VzIH;`=>7TDh zhoo=dU8R3Xrali$Ui2dIr4l%)zYGFvlyMbT8|j>!Ac`B8U~|q&lTL#d= zk4f09=n7~=CSjkblhjBRD2`t964+y%=+IH1S{QOi1nDt>bQu) zyi+Xr&(DDLln4B$#gEa1^$H~GevK);c^kF~XTaGP4a|#m0&st49d!Luf*i@yu*jz6kho{p%oE8}%oxyK5?f343xTPn#ed((l_Px9Gs6^5*+aU0G(xeqH} ze}exmufYe!Qqe{CFX&ACQds=NUp5uF3xK3aXZWu`iFYgBE+q((JMZ7{+H!NXe zRC3|*>({W$^dB6sf{DRU0gQ3tLIoWrh=)o1n2)u2;PtB4zw%MKp?Lte_v zqn~_Y;CJd-qBU}xJk4i(uQDp=5R2Z;2z2b^@g4$|!a zUX5qrov8v|bt#vc*DK0~(tfOg)@|I8pGAK%Nu)Ehz47THS6bOTl)hIt3O7EL;UIxB z6d)Ch$B!4`GfrCcqYn)vIzEL&YfE4=En#*h=PU8vKg#^4JBJnLNwG3%sq8cbe|FgO z0K0N9on08{&Q>2$XHS0~hL{-#>Ecx`r0?V&qOHL(;sPYu1^bQY?VmO2%hM+DY*Sr& zn$&cwve<86-L{7MDY241)+WeaH)&*^TV&B5HjnY}i&WZT>M&eOs|2UlZm{A?DBC6< z1tQKF_)#flw`B0x{xUJ1!65^{nyoy@Z*tCb>%hTk=OMtBm;F7|{u~mSQx;^e~#=- z*h;%@@uWKujU`r1rQi5!;yuaM^i?rGbbg5^w}bQ_yp#~6lha1w-cp8SXx+qLWBkWq`uY7?5Pf<%T{2dM%lK1i zwVYU3JHr>s1Ga&POBTD)F%ZwXTgGR!YQaUs9HiDJLMMF#Omu{?_6#lPR@GyD1SmB4 z&VcG$dLAx3zYM-3wN%KR2V~8b$4vZhWmL5DI>p|RAR!lT<9l&WklJJ{7AfdPZ>E;u z83$6Zz*;T%H!MVgvIU_i;s+XD{RL(hy2GWt(pde~d>Tt%f`=7f!RkQ_{o%U_{rbRM z^3|-7e&;eDzPhGUPfBMa6YgE!XJQ9tA=dzWOz@NLIq>Z42DWfP5R0k<*tJKjSQt{q zk33G`X|}=mZg>z*{C=Ie?78fN3~%(1HCnZ7w~S5K4R8^kP@-`HVxJ zoWx_>ucNMnG3LWW5a>S;LNE6nf)~54fOKj;o^CgrQsK_iL!Nf@+mESu%Kex4*!Or^ z&O?Ph_i_t8-@A&Q_fefb`LK~545)yux(~o~iws-&pc;I<&q1I=ABc1U65F4Jm!@V@ z=g&CMCyHL+dunRf>h3l!V_tym7JJbNQU&ai)I>ISARfsa(xLxoA$q{|3{UH9Ii9p! z0ymRF(fLQ|xV~uwf{*>iU)I&**0aWVBu1LwIA;js9vNEA^)Onq`Z%iann!P%W$l7oL1~f=)m63{9S232mu8=!Iw# zT5v;{j#Ujr1D*=>#Kogn(>Mv&hIY~6|BhqDWIOu1(L%Dde+hQUR;6VXMA`TiPB^wQ z53XPLVJ#13VvoP)$i9gyY(>rryus@>PO(|S=ATff9mi+Unxl=Za&14XtWl%WwD!?D zEemO(rySc^Y5~38nvdseN@CFyy|_qd8){?`z2%Yx>#V57N)K|MH=_Xrf)b&jTYwE~ zEkc38lJrT5G^pF(j;9^9VS`L8AZ>anj(*w#7fS>n$9f2RZZ@Q+T#|$W|A)9c`xNs% z&4g|1If^VUR-ww9{-AJHnVpt*j`;h_B8g9msL)HE?0L^el{IE~+$b6^ShugawQU)h zIV?cb&qq;=$^kfA#u+;I94+YzxlNfe_ZAP zH{;^aw;gKeVP`Fo6t5yN>g#U*hN$ia@99&?`CSw&}~|?5uZJ z!1|B}3y;q+YARU_WxNJ&k&%b33$x+p84H8;4&*IT9fO| zhv_0}&B!Fq^aawFDny?fbK_l|`WVLR9+S0>*${3JN0#a%JS8FkzbI2?wHL)<_umC5 z@4FVBtUQjFUvS3rXA83S30ADJbS1gWeOFQ6q}gNZuEAV`%lOHbnd~-FhxYhgz)len z;Cuf*`t$JydKDc2E^aTd{6G`#FV08n8*K4G_>R3heAvf$E}$o3wB%K3HflBl0*ihE z8P1_+uewdUd89MFjsf%t%cEy>EoMEw%F@BRP9o{{Wz=w6Keej;BDqxCPu#Bg!G(T+ z=2uc6Wj&k71wVq$E^U0aq8#CLw0rG7bz+1^6^Z( zXjc;|JulAMZHmL4Q!e9%-lKS%!yI~cpA96xyoG8Fz z*M{NMqIgeB85Fynfy--su)O+N(w#SkTD?wVnwG$8&7|o6_NO4v&znKS$dQ#++yY6# zG4QR2u(9>&ctS{>MfdiysjX7<)7rW0{d9rLGLDy-W{VyW`nwM1wbS@vCD&tkOR!f; zs)1>;W#cBLSjxB!nwpH+tgU)%Q~h0VJ7Ug`Jv3-34c2kZ#>z2mxEB}6jFM=tsHtPhOdm_XxmcIl4>XOM0;Y+Zf zua@-OD`)&{4zSiE3anin3(j8>*$d)T?71z@?5kOu*|rINYO9$VD{x^3J8$_RT)t%* zb5(pD`>V>6{d!!8y)~Lh-Yd_?ksNR7?Z)?bn`{QUHE{)obOJ$9Tc2_SIS@K<2NHkH zqvyUcpna=q(K`GUKa(`0r|fB`zbX5pq~%F;a9k=0RpENNRCCx5ilOHmvpQigI`++&f4+u!GtYn~HO z^eF-xac8%olQ$HE|AV<)E#B_ZjKuVg;a!QBa82nOocM&sKjzF}0~+=4%?WV;#VkDb zLy&g+sX*(W%_3WqoY_08meERI7qGYbW|3d1Q(1H6Hu}=!S18XK05g>n^!kPwtX!ES zlv|n7M^+2br(Eyg1#6eE@eNaHkK@w#;?i#*Be9Tt3+GY>C)xv&9Uz5tN4Px1ufdM0eAJ)V@pAfFY!eR#=>rp?7`pU-o2}2acMRF z`FJY6RHca|H5F<9zFvf)Eb!c8yV)n%hz)f;1@qrbXC26L)@PYAYq9Gjgp>-gOP75B zE3c<0P%0UF8tC%3u6zW7dv=hmhy1xLl@{3SkYt%98)4%zD|~DG7&UWh6&4P8hWR1} zc(l`-*1cRqSLj;cNEgnvQdqz?&&T+3R{&mXfbmVsMYPHMd9+!zIvt|yOVbs7=+5!a zICQ5H9p8(oy7XS{63G6_*Q{CGLt-RMTgw-J0qA%VWosYj2NufP}O^5|a89^~X$ zjrU*7rS0`fu<-2v;6x+0`yZ;#IcW@N$+aU`Hq4n_YW@i_x@p>Tb{X)3-9Vtf5zl{P zOe+q#;>LPQ`sf>B`j?|TU8SnPK8-4&w;owVS8O}R_U+rjQZ}jVYKwJHzwRi*wHl(yPV$ZWpmGDj&!@Xvdb95(r0kAUZu$KqUVl__Vr1#~(n7g&A1nkQDv7_qvtj%(VM2^gWiWsqH!Yw&rKR3TU}$}o=hazJh_J&KYv73 z=?d7StdL!2KMG4vrm(ApEm-ATSNIj>%+AUn2ej%@!8k2i4MX(f1`zvABqzzmDYyf{9ZNbVu^|&Q%Ivt#J z9gA!k#wXkL>G=W+X|acQ`NmIov%MiwtZ{%py^j>IRfU<*7-2xWe%?w>uhF1w??>Z> zSL|sMH4hvR^9LDM2GIXKu7fQ98SMSpV)VYK(|q|dPu%+7$#lG1GDM+t}uGQ?KiGw4efACYw~H}S-D zH~R3h1GH_Z1a?S!ft6JwXxeTAEnqo{PsLVa8)E~k(s_ip%)%d&b8Cp@m3&;CV}LaJ zd*I>zB$(Q}1bc0F#tlZbIKgW!D-x&5#B62Jnby5v<0U~F%p}>MNdr0~s0p8&x)SGQ z|Kb=dXR-I5P|`YXL(8V!LbBb4w1gPvaxSsC_0wJ!#6As;sC>Gbk|4{ z?HinnvKP7H36C;N2E52ipOy5RNq_o`pC%jZScCJ`He#=0Q5e?F$6q{l;xpM>=*znu zz^7k|o)EExg@0&rbg4V$)yj|?0~Xln*MIm#2ItZqdX4`RKY+YH=2ASnStQzK5A&~~ zo(g#4MwQ_f{-DPa6nvD+O_k^qQKe^$Ra8Hf)pnO3`FAl4U%CbZ&f2i#&05sCPzZ8F zrAWuCD)Qm=5h9`1K&D*N<=fZfQkK$$s=3`n#5d4LMzI#Xzg0o01Yc(wOyBXWMB4d! zY#nbHJ)qpowaM?m>DWV84_{re0o~m=k18oROl8)VlMIDyiu@;l!lPoy?Gi;Y=UX{C za`XdLoVy$u))XL%_$kEbKouEKdd$dkdqzs1cEZ}@y5O17L+L(BMbD)XBJuisQF;Y( zc)k#oZ*5?L6T_MPGVzwb604gYuFGWh9ueX4u74@H=p9UbTL|i&a)Ouhq=0l;pFr~B z!NeWsGjFb4A*&kVNND#Ro(<>2tqZ%rbY3t+lz1c6(j$lV9o$LzYQLvylgrSq&QmB& ztb(kZSA;TtxpMP)MdEpQCb2$NL*{QTVb1G{!qpA0$j-0n+%9%Hu@+0Co^(fZ`_AVn zIVoTC-IY(N-LR#+{|F;qQZafKwx8OPpHA7nO+YL4PoS5-Tu^&l4r<+-LDg;@;OH z-QALmVDoiGUE(wEVZ|i1VA&iZ&~*s0Mu(`;zzlNT(hlj{zo)L<6+ps%Q;?31baVB{ zTV~B`8*)u8mnqmMMt)GbWaHOsq+t3FDn0u+l{mAL!BRIVtvM0o*WPjFsq`#zCpDg| z+`X0jlv#sj{q5$(uX7_ij`$H;s*1ds6oS;ai`4n+W#kLT72e%zL=7!7BcCm8v9gUC zO6yg|uF2YziDVKpUqGtq!L|3~75ARH+^WhfYAI)g@-LD7|6WkyKbt7Gpy{N<@Dnrj zAKU!neFf!_zL6Kr0Y!?;;y zwlX4wlvGkY=RQhPDMBF)4T^?P-%66Q6(TEJWwf+~=iEm_O41;e_M|Bl6)k?B-~ayl zcwXn+=f1A%eSw1#cfI)t=4?!XRhI8Whs^7kcjp>hTU)_8dy3e`+E!M&qfESc)f?h6 zrH~y6NnmQP4zu9rPFy58gT4E32=7<6W9^0xX6KPBj*%G){;mUIx${dFcvYQiBI0(#w-dr%+*uJCRFt7t zA&iNRSb?ZwA37?U;tPu!Vg#q-bKXCTikbTx}dhrtBLEgmCaZ|X?K z$P9eG!i{0bH7W?|_1Sn{lT3W}HKGK=5e z$Y?b;EUACUbRWJZ1BKm%Q&!lmE>DMn)jedn+*)XPvjSFp$`(gj$O|5qB;kE<7WWys zvyhT>Hov(DkDEoZO0|5ZGGjC)mmO@a|K+nSd(A`utsz!(vcQqtKj_%wa+C{%WUw->!ElcCI$Tmx!}&@BeCS+H9VF$ zkKelChQsei6RABq==)$Re%!i7bkU-S{atMfp)n57I;j`M-bpN^WhTCAyN0hUuGuE4 z2|2CXUE+#?cW{8M0pB!d7^XXl#A7Bnuwy;NIJ1yI=8Ij36HXD2UB05*LpHNq4+&7$ z7y~w|ZTZ_d=h&MbWAN7e2OFCV>7fcw{NO1t(XX4K^WRIXbeRiTRK0@j+3UbM`pa3~ z$wu_IN?~rN_Tq~h^-TAE16EG&B*Tsvg6xc!BFo1FG~Y(EH=)5e+Sm%3xC8za@Sh4`P7 zplpsNk82J@Z!=YVF)t9Wc?FY)Ls~_HTb?kcjC=S>H0Piv zIa@H1yq#1Fr-d$_{Lhxv4Mm#d#n99n)EsrzOPu)k357I(QeWg4zLJ zMZc~xrWojtxj!{AV|@q6R}UxASN6h?%3mP=#}o%Uo(@ucrG-F;G<)hO1EwZtVC&gF(WkS+$mo52u)k#>7IlPT z=^}IduVV#-pB=^<)#h`P$oZhIz6RAVTt`hl6c3-hiTU^9m|N0e!9)Lt+_@wvcw=KR zf5uO8==KSb!PGjY9d8fkT+g%QN3V&06kzew!B`;N!Sj_K+Nq>oWx4-VGAV1yY6>Ue zuHb<@Ywdab8PbmNvVTQ)Hhf~!g`-lyXw#^p zxFkjkvODjK!@fF^GsBOHi>FF3y&uX@{#1*|j$eS9gS?dC2ml#PazfOzG>wG57<*S2|N0>0M;%8w;^&-3nZ=FI9ZbZwmY7aDe6P zc`JUnznd-Du!yzhwvjE#OVH(*oY1=*ib@mHnYhOjtzFv1jY?bDhG|bldjefW8B2A+ zUFR_ju8Sq=E;X<-jzHF_gYfrLWwp=1%cNre5y<&fNDl4_5naDUstrzbK=ideVEFL@ zI_wyL)+-B1VL=4j=WD{G+Lyq@RBM*gSj*0>?Iw>ODzQOo`cS0tjcryn#QLB-(6O8- zx;NAc_4XcQn=Fh(hB3w%c*zW2^yUzmU5fCb+DbIYV<;N!ek`iAN@9mr<=W0jnakeA z8lgwtS@z+~0A3_OjF;({kmt?Qv1jg7R6klp^!;V{mm(!FvuY;or{viBlNum9aTEFU zxEzmo-z2IQFGcQS^_lgpMQ~zW2Rq~W1OsKYiC63xxO_kZ)Z<;SFR4nDWA4o!db#4W z%kONhM;wA*KYH0V&Ex1UMbT2i1bpv|7cZ1^1E1kranqGM;$0>h)wc)A^7X+&u50v0 zI2bUH|9*R)WcvIN`Bf|fL#YK2rlE&QQ&&QhuR1%nCIAci?~pGiE>zZUHNu9dS~7d< zG^XIHNY%rp!fK)arlPKfoP4Pc9kD-%yv{7nPv$Ugd#740LBz~bWw~^mG`6LxLV}?Z zKcu!1q6}$B?|Dxz60cVOc|aHp2tg6yV(4SgXm>(i*3HJ z2aeuw=Guk2d|_HHY5SJ~Eo-O4adih6@qd5BO(SNs{Ha~MW3hPo_zE)Z=zg*)?SS9@n^<`3QiwaE1GHl$m`qHDm&wWSrqmf)X0_!>)1U9?=h__xl0>|B+kjX!qMbmcP6?Mpkf`nKNSWXhGCs$zLntZ67egd|> zdJKCX7T_#x8K#_anXFE$XU3@u$vMwS@IVN5EP0+pDt#p|UuP5;9&v`Hy#e5K|F|I6*C|P{Of42Tu<5tSl2ZxKD-rN_-L@r{l6wI(!RSD-8Ze!ze zVnyf62e3MITda9z&5J56dH?&^YU$SfsC!KjD^0T?@VE)vbN!*vtL(^qZmslz9>GUYx=Eq8(IN8P~Vj=+Zy#fc(+ zr$F7aSaJM|S~AwlgWY_xio8kbW8*)2G0T9%jW39h$cM6 zqYGyGDP-+~0#wjaMzg8r2!h;&#@@~ZZv5)FjVMC`zPKSScjX>4&ZJN4+#;mC7>vr zJGq8JvrtJY?sAmjH;4BV=gZGT=ChtvHL6#M?*$DMd45ZQdHe1VOOu6U>@#^9y8Z#~ zX*z$)$ zEOvV9YrLGU&;0@|aON)|$KG=h{U)k_>DQ}dr-2@pklcNAM)*#x^T^^xB2 z6gJt(4kms!f=dol+0=W3AVAF>E=$yav33>f=|)_w^p>r8bc~t1=i`$ruH@yejV#_z z3M`~7Nqh2IP#p4t&5v+FgNQ|pyjS3}!_Hvo72qK+Vp;!_4i=>(k6#tb+4Bw`oUHH( z%&OjsY#J}ZIF(0m>EJoM9Z&d$)eE@TK1?*|=W~4dxL4FRIGyDODUiC*x5T!wLaZ=k zKe;P?OEhh;7H-(zNPIW{VA8^SAnA=d7}G)gkkw= z=EzdFC}EgHnrOhOQu0^S#R_|_lGRDEV(UU9cK=tiop2Ol{`JWuEwY8UwEn|9zehMW zVLs{JLUGfYQxMghPbMGx2b!avvP18)n9KD_@$k7PF>&!?JUvPUCp(S;+eL)Ew_hsu zuPK6<+8wOLG!%NZKjXzjIbzqSftCAI(QdsenwA!eOx`&0DS<`kFSizr109I###p%P zyaq;XD66X3RYr0e6^K?sC>?S1Jz0503%aN2(8G79QY(csFf-Vh6>JW$?H)Z8n#QEz zjWgY7aeNux{k)9%I2~lC4E<<+sx)=GK7jkUh@tq!4>DF=hriNO;g`ctL0s_xj4@W` zTHG4aI$XKtE;a5u&xx#h*3Cmh9GK&SRqT$?ZJs_nPnf;$vi#Dw*f!3XZ&urcHgdDU z)zAh@u3cwui{-$?)RaB*UB?UK*YYk$2QE2eCQtk*Ut=D72)&fzu#WE`*T)CK!Ypg{ zs8#tv&NJ^ z-8qwAEzqDD>;AIRWCi};$ZQL9841PVI@Ui24r*cCSxlPosF_gjiQ zz~&O4eSR+AUt55eCM5C37NedUyD>X$_t7-(I+1l7?$vc;I69)5L$w6%5^bi5-&A z6BRh6A8 zyVZ(y3#95$x$+ z&VLJgm7`&oVUm?2FTC`R1#2y)mbE&>-O`D^F_fV19yF2dCa1xA$_4SVb1O*aj@|4` zpB0oCb=VCy@P*DxZ`hZHTf{kS7#*k>hAJ0x_~XEHxbOTY^a$?eff@Utf6N_Pq5F>i z@E%VupKGLbofRBIk_DfEnmuv1pep5I1PP`OH%J*R)HlSb5@eq-WkA;oHW3@IeT#X z%MZAJ`)~A%;rQd-Bvg2wB>v*{5l1Y}N7cE*N$Ke}IOOpJmNjRynhUmck5V>#`00<~ zf?m4YB!KT&=E0|2e9SCnP2iysPf+DxKEy6Oh(l+7!o2ydMD2`*h)1vFx}WFa)s2pH zj;g>MH`ju{&n|;aqZca>{?8^+5`!mu0@o7k`m|nEJ zOv+z6asS9$sAahj1JnfXrKu|KtuBYyrg%1|dnYX;1wTDc{8b`Fr!KlL zdU#w6_X-b^I}r)!nYsvGsG8&In${WyNDhcdJogzZlS#stKpQ8K@0D5 zsy^%dj7<3;#|tG#QzPZ6Y)Q^x%nd2UPqU4<^@0_G?}H&VzQjkA$?*Z}kvj@I)8rxg zv^(8E*!jqjX}^ovtZ6gosKshDbBhDSt`6W1_J8Om?J+C~V=?Pg8ytNoK_d!h(eU&f zn$o37J5CCnsFfPXJ_+pG^a9xV%Te%VQ|7Jw33l5S{El)lh$)j2W@XPgbyc+Y2p4KUZu@_vqym2Az^D?2EBw`^< zZ4m8g@#U`N5@@S%2lU^kqqcH3oTGhUU85=FTgHI#N_v4E+eT=aN z;N9?HzYgeZxh(KI)M4zahwN^yG5Ad@gg$ji=%2TMt2^YN@>6MQa3PfUjp!utCmC@Y zn~ZG6EeM{T0Bb5t>3^4nvu%w%zWKU{hE368+rk%fjiJtTpX4|?%VQ$ld0P@BkA>0! zk|}t3Z~!KIT_J0e#9+F693H&A1^%^|@Jb?NapOK=LztM1*`&iaj(&@-K{wH}qF(%b zUkUo3n8EdXG?>gqYq8pajWl%1GW_!NI6YOqoq83_pxj2*{=7y6)&AzqU#_UND{oey z?ZXmztGkFQ_w1zAe(nOB_z{eoc^BG;dGT(?G`eor1?qpsjcY0Zb=bL>nq8IRow8$T z=#fBrZ7Qu{6-vB*~>~V4W+)n+VR9zHG1a4LcBcc0ZLz7!|O`( zu<5Ue4_KwdC!bsh8G_cHZ?KG$%p4f-SC^T8HQ`l;KT6!*u43fx1ha)k3MUym_UYXA}yjA9bG!DN1Xn_~%i|})HA1rPhL(Ni-lK$3V z=(eN|?iiWTyTYF0a=}H`am1UB8&(BxD_Bn$REGD6qCeR1NqD1 z1nT+vAS@}~!$U$UXl>kgygOqvxASnJT44?FZqPdHT|9>Rd==3T(E%&UGwe!| ze7N<&Z)n{21Han-VD|6c;;U&|T;ju2degFii~k-X;(`#m$S0W&b|1){R94`dH`ky+ z*inu9>_nD)Z-aJ`0d9DoOo^TZwNQwGTA{YXFX;q%qoPiiYuV8g6Ph5~c0WCTWh~ce zJq!7x^1yzK4tG9jjxJ|fgxymTYzh^031Po}(kO)0%uWaDszsl~)Pa%ecGQ|Mg8xfW zpd;EdaBT2Tv0m3#s{79ehx804**ACa!KEumMNv1VD9Q34?vhwhl!|ZTn#ejYEpE`W z9pC=9Q#{pSCB}s2z-G_c5SzFcb&Hj0-h^Xx;^-u@GVX*(bHj7o+9pFwjK|TqBm2Qu zf|CcAwP@kRK|Dq09L*Xufu8pX6!vrFwAZf$W?w#K_sg+@ma0vq(bn#*;HOq{R`G!_J`rMFR^jPLbCAc2h0vS#gF73hLNgI1g0R+G~){( zd+!!|d2t>Nj2zCd{kbRFd~6#_PwU1t*;4G|&=s_2`+Zn-btw0^@sl|!j1iqBdNnFYw8}e7^2n!wHk6- zxDUQF?U6}TeUBZVw8V#Xn0wKJPG{J?XD9vOpAUmtMB>DZMU@V%F1TjYZ&)6$L-*s{uUB$I`HHoqX|`YBO}i1IIQ=g=*~ z*P!VWKQLXIVOuuAgXg_w_%b^N8uwo1xuzGs^xz5I=rtp>rG6;DMzVmIEc zLeg?0J3BdcLq=FPu=hf-;w~vDN1;?AKeu=WTt&B9mufrP~Jn$g2Rd0yXHk znX~b4bSkXcCS-+N3rN9@VzN3soywCknxL1$Cud|)=yRop8)Gm}V0@feUP^S97}E9m z`?%V8C0@F4Jl(v<0Pov8XKSoO;N$OmI4zgK3$Ky1UD6X;#@xZzPWt4H*%V$-5=~Zp z`z3Jg+U?$7NhiM3?C9Ua-jMxVjUNfR3WM+H3p=Xu)OrYF-cTbv5H7>kH9B#AI}K4c z33Y|tB5%-y+r$cX^+~aAC0{uGYCpOr)PskWG2R^&3FrO}o_O^iDQ=#>8B-Rx zpm$s&)Px6M+P}T{GKbJtQ*JRw*HHezItLPDwe4HmtST$#c%!_oAG#Pt0ekp}wMd+X z(=Ss|XS={t7(aymXCcFb?3?L?wSu4T)OZ@^{uvZIX7ZrcFJ#}46#DeRBHk2qfZuM3 z5}1Fp`09J3dGMv7*lQ?evx2Pn62DtOcbugBraw3MQHPG?5i{?~BMU`q&_5&vvK7zL zpuSX`s@4PH3ybN9N#pSA^l74n^E+XO`g;tYycz<(yn^4Bp`ZskiHIHc` zNg2v~seT@S%w`_+{x#ck_&@sO#Z*|4??pr0jOd95p?hS!931_pPp8`zqQtl$G`l?u zeFLRYG5I$%9=QnOp`l~wqRDllxS0e7t)m^p7Feo@yDRh1>-QX6+#Wjl+p zz$5IeC>#E~&0!u3Y+!Z08-2ffAJsm;gp?Vp*t?24sq0u>_>>ndin{oKNdNc*tEbI{ zIa^-C=!l```_D9vn>( z?at%0+G%1(ji*FgqZ4%3?}qz@+87g*L1tYNdaM>Jqszq-<~`zEhg_D-A9|S@6cvD6J-uMp;5InOuL>0TPGW#((zUj{!Ip~ zn?|tbnw`*e>=^z~SE8$TIOAijLgFGLNq67bOZEro($_Ja7{S%-a(jP>5|i!F$N#l9%DtKlPKMG99exR9GkfYEXThg)5nex zc1=2>gSrR6<@i{HXvR{I~LWU`#CuS(wQx6vndcu@z8x^&lAJ-6x&~*Z2Wjp*y!( zfenr}M)h$EFn954wEoV}!m0?T+qH^DO(@0bPb4tps3nehX9l*nQ=#eVWZ?7x9)HF$ z^QaylbwraF%#Y%o0~$oP?#WS`&wp6ze=Dg)^L~0W#*WT#X~Xq9#?|QbCG+n@hwfZ9 zh-0G@R>*Xt?51r*VZ&9NXnGz8Oew5dTiXx&o=6Ctt=(j}c?@Wcieqb=;<4#T5_{;l z2Szj-@x*tt>BNS4e65=u=4c#3(WwSD$L$2JF}aWXf2F~KWvaOSk1-Bjy@XZBFubEb zjji(tfRDF^i4J=m1*2R;+AKQ2Jr7w5422UYI^P10zuj?~b7Rm9u5*EU;fLin;hXyd zF#Ft#PBKey#*!-Lrg|CwE!+*iv$XNnpPjhxiZ?H4l;LbtG#_yE2_FA1g84xNYHhsobwfs5k^ zcJ5j*I?Y**1y+k-LzoedQ`I4twnoBxgCuUdBoKSAKZT#syIF$ejfq(oWnh!935kdg zffdp2@F=JnTVHwMM}b-P%`u3@-k2g1h*Y?<{vEhATcBfP2@Ehjh!szU@wl7vyzYR| zrx~;lJA9_2V%2V(yg-Z3x%&;iYmMPDQWJRV!~6Iuz=_nJrlQd|ufaF1&jKfSDmiQ> zk6ZH2(koIKFt5&&J@<-d1>xt(VjFq7RbmPHn$2W;i%)^GO9p?NeH*{(M)0R2qwSWs zZDbcMU%?u`7Ey1q8n>CU4Ys6>q3;A=;h$Ry^h1^f#IBhjGC!`$3OaRZ(rgPnT~P&t z9&ezU^IPCn+iP5?GYe;4HQ@4VBCtk30P?4A!U@5-WKKXL_AVNa?ZZbyk4X_~<%)5I z+&2=Pcp0r19%U{69iCw~=d`Anf z9_hmHr*c&DST8pFrHa3+ji9G?=<-augl;HIVDk2}1TWMy{#3Gr+bDTr(Ytc!-d9ST z-X_wU6Q%j!^X?!n@u=A){=)AG-7Z6pNn={DvAB1`0rntNo?N?;3DMr4?LG*su1H=?%VN8pKc2J;45gkw-U

      >xkC5)85< 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 gYJ)HQz0oN8jivmo)LD?2EP`bY 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 z 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%0D>W3Zg?{mV`!npTyqYjyh^N*% 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

      iDej#-vau1`{zbsKxtXx>Z6-Vnd?e*?YT@=& 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
      uoW}?%RFCPAY?qgf@)|W8?VM# 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∈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 +#include "mtcnn.h" + +bool cmpScore(Bbox lsh, Bbox rsh) { + if (lsh.score < rsh.score) + return true; + else + return false; +} + +bool cmpArea(Bbox lsh, Bbox rsh) { + if (lsh.area < rsh.area) + return false; + else + return true; +} + +//MTCNN::MTCNN(){} +MTCNN::MTCNN(const string &model_path) { + + vector param_files = { + model_path+"/det1.param", + model_path+"/det2.param", + model_path+"/det3.param" + }; + + vector bin_files = { + model_path+"/det1.bin", + model_path+"/det2.bin", + model_path+"/det3.bin" + }; + + Pnet.load_param(param_files[0].data()); + Pnet.load_model(bin_files[0].data()); + Rnet.load_param(param_files[1].data()); + Rnet.load_model(bin_files[1].data()); + Onet.load_param(param_files[2].data()); + Onet.load_model(bin_files[2].data()); +} + +MTCNN::MTCNN(const vector param_files, const vector bin_files){ + Pnet.load_param(param_files[0].data()); + Pnet.load_model(bin_files[0].data()); + Rnet.load_param(param_files[1].data()); + Rnet.load_model(bin_files[1].data()); + Onet.load_param(param_files[2].data()); + Onet.load_model(bin_files[2].data()); +} + + +MTCNN::~MTCNN(){ + Pnet.clear(); + Rnet.clear(); + Onet.clear(); +} +void MTCNN::SetMinFace(int minSize){ + minsize = minSize; +} +void MTCNN::generateBbox(ncnn::Mat score, ncnn::Mat location, vector& boundingBox_, float scale){ + const int stride = 2; + const int cellsize = 12; + //score p + float *p = score.channel(1);//score.data + score.cstep; + //float *plocal = location.data; + Bbox bbox; + float inv_scale = 1.0f/scale; + for(int row=0;rowthreshold[0]){ + bbox.score = *p; + bbox.x1 = round((stride*col+1)*inv_scale); + bbox.y1 = round((stride*row+1)*inv_scale); + bbox.x2 = round((stride*col+1+cellsize)*inv_scale); + bbox.y2 = round((stride*row+1+cellsize)*inv_scale); + bbox.area = (bbox.x2 - bbox.x1) * (bbox.y2 - bbox.y1); + const int index = row * score.w + col; + for(int channel=0;channel<4;channel++){ + bbox.regreCoord[channel]=location.channel(channel)[index]; + } + boundingBox_.push_back(bbox); + } + p++; + //plocal++; + } + } +} + +void MTCNN::nmsTwoBoxs(vector& boundingBox_, vector& previousBox_, const float overlap_threshold, string modelname) +{ + if (boundingBox_.empty()) { + return; + } + sort(boundingBox_.begin(), boundingBox_.end(), cmpScore); + float IOU = 0; + float maxX = 0; + float maxY = 0; + float minX = 0; + float minY = 0; + //cout << boundingBox_.size() << " "; + for (vector::iterator ity = previousBox_.begin(); ity != previousBox_.end(); ity++) { + for (vector::iterator itx = boundingBox_.begin(); itx != boundingBox_.end();) { + int i = itx - boundingBox_.begin(); + int j = ity - previousBox_.begin(); + maxX = max(boundingBox_.at(i).x1, previousBox_.at(j).x1); + maxY = max(boundingBox_.at(i).y1, previousBox_.at(j).y1); + minX = min(boundingBox_.at(i).x2, previousBox_.at(j).x2); + minY = min(boundingBox_.at(i).y2, previousBox_.at(j).y2); + //maxX1 and maxY1 reuse + maxX = ((minX - maxX + 1)>0) ? (minX - maxX + 1) : 0; + maxY = ((minY - maxY + 1)>0) ? (minY - maxY + 1) : 0; + //IOU reuse for the area of two bbox + IOU = maxX * maxY; + if (!modelname.compare("Union")) + IOU = IOU / (boundingBox_.at(i).area + previousBox_.at(j).area - IOU); + else if (!modelname.compare("Min")) { + IOU = IOU / ((boundingBox_.at(i).area < previousBox_.at(j).area) ? boundingBox_.at(i).area : previousBox_.at(j).area); + } + if (IOU > overlap_threshold&&boundingBox_.at(i).score>previousBox_.at(j).score) { + //if (IOU > overlap_threshold) { + itx = boundingBox_.erase(itx); + } + else { + itx++; + } + } + } + //cout << boundingBox_.size() << endl; +} + +void MTCNN::nms(vector &boundingBox_, const float overlap_threshold, string modelname){ + if(boundingBox_.empty()){ + return; + } + sort(boundingBox_.begin(), boundingBox_.end(), cmpScore); + float IOU = 0; + float maxX = 0; + float maxY = 0; + float minX = 0; + float minY = 0; + vector vPick; + int nPick = 0; + multimap vScores; + const int num_boxes = boundingBox_.size(); + vPick.resize(num_boxes); + for (int i = 0; i < num_boxes; ++i){ + vScores.insert(pair(boundingBox_[i].score, i)); + } + while(vScores.size() > 0){ + int last = vScores.rbegin()->second; + vPick[nPick] = last; + nPick += 1; + for (multimap::iterator it = vScores.begin(); it != vScores.end();){ + int it_idx = it->second; + maxX = max(boundingBox_.at(it_idx).x1, boundingBox_.at(last).x1); + maxY = max(boundingBox_.at(it_idx).y1, boundingBox_.at(last).y1); + minX = min(boundingBox_.at(it_idx).x2, boundingBox_.at(last).x2); + minY = min(boundingBox_.at(it_idx).y2, boundingBox_.at(last).y2); + //maxX1 and maxY1 reuse + maxX = ((minX-maxX+1)>0)? (minX-maxX+1) : 0; + maxY = ((minY-maxY+1)>0)? (minY-maxY+1) : 0; + //IOU reuse for the area of two bbox + IOU = maxX * maxY; + if(!modelname.compare("Union")) + IOU = IOU/(boundingBox_.at(it_idx).area + boundingBox_.at(last).area - IOU); + else if(!modelname.compare("Min")){ + IOU = IOU/((boundingBox_.at(it_idx).area < boundingBox_.at(last).area)? boundingBox_.at(it_idx).area : boundingBox_.at(last).area); + } + if(IOU > overlap_threshold){ + it = vScores.erase(it); + }else{ + it++; + } + } + } + + vPick.resize(nPick); + vector tmp_; + tmp_.resize(nPick); + for(int i = 0; i < nPick; i++){ + tmp_[i] = boundingBox_[vPick[i]]; + } + boundingBox_ = tmp_; +} +void MTCNN::refine(vector &vecBbox, const int &height, const int &width, bool square){ + if(vecBbox.empty()){ + cout<<"Bbox is empty!!"<::iterator it=vecBbox.begin(); it!=vecBbox.end();it++){ + bbw = (*it).x2 - (*it).x1 + 1; + bbh = (*it).y2 - (*it).y1 + 1; + x1 = (*it).x1 + (*it).regreCoord[0]*bbw; + y1 = (*it).y1 + (*it).regreCoord[1]*bbh; + x2 = (*it).x2 + (*it).regreCoord[2]*bbw; + y2 = (*it).y2 + (*it).regreCoord[3]*bbh; + + + + if(square){ + w = x2 - x1 + 1; + h = y2 - y1 + 1; + maxSide = (h>w)?h:w; + x1 = x1 + w*0.5 - maxSide*0.5; + y1 = y1 + h*0.5 - maxSide*0.5; + (*it).x2 = round(x1 + maxSide - 1); + (*it).y2 = round(y1 + maxSide - 1); + (*it).x1 = round(x1); + (*it).y1 = round(y1); + } + + //boundary check + if((*it).x1<0)(*it).x1=0; + if((*it).y1<0)(*it).y1=0; + if((*it).x2>width)(*it).x2 = width - 1; + if((*it).y2>height)(*it).y2 = height - 1; + + it->area = (it->x2 - it->x1)*(it->y2 - it->y1); + } +} + +void MTCNN::extractMaxFace(vector& boundingBox_) +{ + if (boundingBox_.empty()) { + return; + } + sort(boundingBox_.begin(), boundingBox_.end(), cmpArea); + for (vector::iterator itx = boundingBox_.begin() + 1; itx != boundingBox_.end();) { + itx = boundingBox_.erase(itx); + } +} + +void MTCNN::PNet(float scale) +{ + //first stage + int hs = (int)ceil(img_h*scale); + int ws = (int)ceil(img_w*scale); + ncnn::Mat in; + resize_bilinear(img, in, ws, hs); + ncnn::Extractor ex = Pnet.create_extractor(); + ex.set_light_mode(true); + //sex.set_num_threads(4); + ex.input("data", in); + ncnn::Mat score_, location_; + ex.extract("prob1", score_); + ex.extract("conv4-2", location_); + vector boundingBox_; + + generateBbox(score_, location_, boundingBox_, scale); + nms(boundingBox_, nms_threshold[0]); + + firstBbox_.insert(firstBbox_.end(), boundingBox_.begin(), boundingBox_.end()); + boundingBox_.clear(); +} + +void MTCNN::PNet(){ + firstBbox_.clear(); + float minl = img_w < img_h? img_w: img_h; + float m = (float)MIN_DET_SIZE/minsize; + minl *= m; + float factor = pre_facetor; + vector scales_; + while(minl>MIN_DET_SIZE){ + scales_.push_back(m); + minl *= factor; + m = m*factor; + } + for (size_t i = 0; i < scales_.size(); i++) { + int hs = (int)ceil(img_h*scales_[i]); + int ws = (int)ceil(img_w*scales_[i]); + ncnn::Mat in; + resize_bilinear(img, in, ws, hs); + ncnn::Extractor ex = Pnet.create_extractor(); + //ex.set_num_threads(2); + ex.set_light_mode(true); + ex.input("data", in); + ncnn::Mat score_, location_; + ex.extract("prob1", score_); + ex.extract("conv4-2", location_); + vector boundingBox_; + generateBbox(score_, location_, boundingBox_, scales_[i]); + nms(boundingBox_, nms_threshold[0]); + firstBbox_.insert(firstBbox_.end(), boundingBox_.begin(), boundingBox_.end()); + boundingBox_.clear(); + } +} +void MTCNN::RNet(){ + secondBbox_.clear(); + int count = 0; + for(vector::iterator it=firstBbox_.begin(); it!=firstBbox_.end();it++){ + ncnn::Mat tempIm; + copy_cut_border(img, tempIm, (*it).y1, img_h-(*it).y2, (*it).x1, img_w-(*it).x2); + ncnn::Mat in; + resize_bilinear(tempIm, in, 24, 24); + ncnn::Extractor ex = Rnet.create_extractor(); + //ex.set_num_threads(2); + ex.set_light_mode(true); + ex.input("data", in); + ncnn::Mat score, bbox; + ex.extract("prob1", score); + ex.extract("conv5-2", bbox); + if ((float)score[1] > threshold[1]) { + for (int channel = 0; channel<4; channel++) { + it->regreCoord[channel] = (float)bbox[channel];//*(bbox.data+channel*bbox.cstep); + } + it->area = (it->x2 - it->x1)*(it->y2 - it->y1); + it->score = score.channel(1)[0];//*(score.data+score.cstep); + secondBbox_.push_back(*it); + } + } +} + + +float MTCNN::rnet(ncnn::Mat& img) { + + ncnn::Extractor ex = Rnet.create_extractor(); + const float mean_vals[3] = { 127.5f, 127.5f, 127.5f }; + const float norm_vals[3] = { 1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5 }; + img.substract_mean_normalize(mean_vals, norm_vals); + ex.set_light_mode(true); + ex.input("data", img); + ncnn::Mat score; + ex.extract("prob1", score); + return (float)score[1]; +} + + +void MTCNN::ONet(){ + thirdBbox_.clear(); + for(vector::iterator it=secondBbox_.begin(); it!=secondBbox_.end();it++){ + ncnn::Mat tempIm; + copy_cut_border(img, tempIm, (*it).y1, img_h-(*it).y2, (*it).x1, img_w-(*it).x2); + ncnn::Mat in; + resize_bilinear(tempIm, in, 48, 48); + ncnn::Extractor ex = Onet.create_extractor(); + //ex.set_num_threads(2); + ex.set_light_mode(true); + ex.input("data", in); + ncnn::Mat score, bbox, keyPoint; + ex.extract("prob1", score); + ex.extract("conv6-2", bbox); + ex.extract("conv6-3", keyPoint); + if ((float)score[1] > threshold[2]) { + for (int channel = 0; channel < 4; channel++) { + it->regreCoord[channel] = (float)bbox[channel]; + } + it->area = (it->x2 - it->x1) * (it->y2 - it->y1); + it->score = score.channel(1)[0]; + for (int num = 0; num<5; num++) { + (it->ppoint)[num] = it->x1 + (it->x2 - it->x1) * keyPoint[num]; + (it->ppoint)[num + 5] = it->y1 + (it->y2 - it->y1) * keyPoint[num + 5]; + } + + thirdBbox_.push_back(*it); + } + } +} + +Bbox MTCNN::onet(ncnn::Mat& img, int x, int y, int w, int h) { + + Bbox faceBbox; + const float mean_vals[3] = { 127.5f, 127.5f, 127.5f }; + const float norm_vals[3] = { 1.0 / 127.5, 1.0 / 127.5, 1.0 / 127.5 }; + img.substract_mean_normalize(mean_vals, norm_vals); + ncnn::Extractor ex = Onet.create_extractor(); + + ex.set_light_mode(true); + ex.input("data", img); + ncnn::Mat score, bbox, keyPoint; + ex.extract("prob1", score); + ex.extract("conv6-2", bbox); + ex.extract("conv6-3", keyPoint); + faceBbox.score = score.channel(1)[0]; + faceBbox.x1 = static_cast(bbox[0] * w) + x; + faceBbox.y1 = static_cast(bbox[1] * h) + y; + faceBbox.x2 = static_cast(bbox[2] * w) + h + x; + faceBbox.y2 = static_cast(bbox[3] * h) + h + y; + for (int num = 0; num<5; num++) { + (faceBbox.ppoint)[num] = x + w * keyPoint[num]; + (faceBbox.ppoint)[num + 5] = y + h * keyPoint[num + 5]; + } + + return faceBbox; + +} + + +void MTCNN::detect(ncnn::Mat& img_, vector& finalBbox_){ + img = img_; + img_w = img.w; + img_h = img.h; + img.substract_mean_normalize(mean_vals, norm_vals); + + PNet(); + //the first stage's nms + if(firstBbox_.size() < 1) return; + nms(firstBbox_, nms_threshold[0]); + refine(firstBbox_, img_h, img_w, true); + //printf("firstBbox_.size()=%d\n", firstBbox_.size()); + + + //second stage + RNet(); + //printf("secondBbox_.size()=%d\n", secondBbox_.size()); + if(secondBbox_.size() < 1) return; + nms(secondBbox_, nms_threshold[1]); + refine(secondBbox_, img_h, img_w, true); + + //third stage + ONet(); + //printf("thirdBbox_.size()=%d\n", thirdBbox_.size()); + if(thirdBbox_.size() < 1) return; + refine(thirdBbox_, img_h, img_w, true); + nms(thirdBbox_, nms_threshold[2], "Min"); + finalBbox_ = thirdBbox_; + if (smooth) + SmoothBbox(finalBbox_); +} + + +void MTCNN::detectMaxFace(ncnn::Mat& img_, vector& finalBbox) { + firstPreviousBbox_.clear(); + secondPreviousBbox_.clear(); + thirdPrevioussBbox_.clear(); + firstBbox_.clear(); + secondBbox_.clear(); + thirdBbox_.clear(); + + //norm + img = img_; + img_w = img.w; + img_h = img.h; + img.substract_mean_normalize(mean_vals, norm_vals); + + //pyramid size + float minl = img_w < img_h ? img_w : img_h; + float m = (float)MIN_DET_SIZE / minsize; + minl *= m; + float factor = pre_facetor; + vector scales_; + while (minl>MIN_DET_SIZE) { + scales_.push_back(m); + minl *= factor; + m = m*factor; + } + sort(scales_.begin(), scales_.end()); + //printf("scales_.size()=%d\n", scales_.size()); + + //Change the sampling process. + for (size_t i = 0; i < scales_.size(); i++) + { + //first stage + PNet(scales_[i]); + nms(firstBbox_, nms_threshold[0]); + nmsTwoBoxs(firstBbox_, firstPreviousBbox_, nms_threshold[0]); + if (firstBbox_.size() < 1) { + firstBbox_.clear(); + continue; + } + firstPreviousBbox_.insert(firstPreviousBbox_.end(), firstBbox_.begin(), firstBbox_.end()); + refine(firstBbox_, img_h, img_w, true); + //printf("firstBbox_.size()=%d\n", firstBbox_.size()); + + //second stage + RNet(); + nms(secondBbox_, nms_threshold[1]); + nmsTwoBoxs(secondBbox_, secondPreviousBbox_, nms_threshold[0]); + secondPreviousBbox_.insert(secondPreviousBbox_.end(), secondBbox_.begin(), secondBbox_.end()); + if (secondBbox_.size() < 1) { + firstBbox_.clear(); + secondBbox_.clear(); + continue; + } + refine(secondBbox_, img_h, img_w, true); + + //third stage + ONet(); + + if (thirdBbox_.size() < 1) { + firstBbox_.clear(); + secondBbox_.clear(); + thirdBbox_.clear(); + continue; + } + refine(thirdBbox_, img_h, img_w, true); + nms(thirdBbox_, nms_threshold[2], "Min"); + + if (thirdBbox_.size() > 0) { + extractMaxFace(thirdBbox_); + finalBbox = thirdBbox_;//if largest face size is similar,. + if (smooth) + SmoothBbox(finalBbox); + break; + } + } + +} + +float MTCNN::iou(Bbox & b1, Bbox & b2, string modelname) +{ + float IOU = 0; + float maxX = 0; + float maxY = 0; + float minX = 0; + float minY = 0; + maxX = max(b1.x1, b2.x1); + maxY = max(b1.y1, b2.y1); + minX = min(b1.x2, b2.x2); + minY = min(b1.y2, b2.y2); + //maxX1 and maxY1 reuse + maxX = ((minX - maxX + 1)>0) ? (minX - maxX + 1) : 0; + maxY = ((minY - maxY + 1)>0) ? (minY - maxY + 1) : 0; + IOU = maxX * maxY; + + if (!modelname.compare("Union")) + IOU = IOU / (b1.area + b2.area - IOU); + else if (!modelname.compare("Min")) { + IOU = IOU / ((b1.area < b2.area) ? b1.area : b2.area); + } + return IOU; +} + +void MTCNN::SmoothBbox(std::vector& finalBbox) +{ + static std::vector preBbox_; + for (int i = 0; i < finalBbox.size(); i++) { + for (int j = 0; j < preBbox_.size(); j++) { + if (iou(finalBbox[i], preBbox_[j]) > 0.90) + { + finalBbox[i] = preBbox_[j]; + } + else if (iou(finalBbox[i], preBbox_[j]) > 0.6) { + finalBbox[i].x1 = (finalBbox[i].x1 + preBbox_[j].x1) / 2; + finalBbox[i].y1 = (finalBbox[i].y1 + preBbox_[j].y1) / 2; + finalBbox[i].x2 = (finalBbox[i].x2 + preBbox_[j].x2) / 2; + finalBbox[i].y2 = (finalBbox[i].y2 + preBbox_[j].y2) / 2; + //finalBbox[i].area = (finalBbox[i].x2 - finalBbox[i].x1)*(finalBbox[i].y2 - finalBbox[i].y1); + for (int k = 0; k < 10; k++) + { + finalBbox[i].ppoint[k] = (finalBbox[i].ppoint[k] + preBbox_[j].ppoint[k]) / 2; + } + } + } + } + preBbox_ = finalBbox; + +} + + +//void MTCNN::detection(const cv::Mat& img, vector& rectangles){ +// ncnn::Mat ncnn_img = ncnn::Mat::from_pixels(img.data, ncnn::Mat::PIXEL_BGR2RGB, img.cols, img.rows); +// vector finalBbox; +// detect(ncnn_img, finalBbox); +// const int num_box = finalBbox.size(); +// rectangles.resize(num_box); +// for(int i = 0; i < num_box; i++){ +// rectangles[i] = cv::Rect(finalBbox[i].x1, finalBbox[i].y1, finalBbox[i].x2 - finalBbox[i].x1 + 1, finalBbox[i].y2 - finalBbox[i].y1 + 1); +// } +//} diff --git a/Prj-Win/mtcnn.h b/Prj-Win/mtcnn.h new file mode 100755 index 0000000..10bc3c1 --- /dev/null +++ b/Prj-Win/mtcnn.h @@ -0,0 +1,99 @@ +#ifndef __MTCNN_NCNN_H__ +#define __MTCNN_NCNN_H__ +#include "net.h" + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +struct Bbox +{ + float score; + int x1; + int y1; + int x2; + int y2; + float area; + float ppoint[10]; + float regreCoord[4]; +}; + +namespace Shape { + + template class Rect { + public: + Rect() {} + Rect(T x, T y, T w, T h) { + this->x = x; + this->y = y; + this->width = w; + height = h; + + } + T x; + T y; + T width; + T height; + + cv::Rect convert_cv_rect(int _height, int _width) + { + cv::Rect Rect_(static_cast(x*_width), static_cast(y*_height), + static_cast(width*_width), static_cast(height*_height)); + return Rect_; + } + }; +} + +class MTCNN { + +public: + MTCNN(const string &model_path); + MTCNN(const std::vector param_files, const std::vector bin_files); + ~MTCNN(); + + void SetMinFace(int minSize); + void detect(ncnn::Mat& img_, std::vector& finalBbox); + void detectMaxFace(ncnn::Mat& img_, std::vector& finalBbox); + float rnet(ncnn::Mat& img); + Bbox onet(ncnn::Mat& img,int x, int y,int w,int h); + ncnn::Net Pnet, Rnet, Onet; + + + //void detection(const cv::Mat& img, std::vector& rectangles); +private: + void generateBbox(ncnn::Mat score, ncnn::Mat location, vector& boundingBox_, float scale); + void nmsTwoBoxs(vector &boundingBox_, vector &previousBox_, const float overlap_threshold, string modelname = "Union"); + void nms(vector &boundingBox_, const float overlap_threshold, string modelname = "Union"); + void refine(vector &vecBbox, const int &height, const int &width, bool square); + void extractMaxFace(vector &boundingBox_); + float iou(Bbox & b1, Bbox & b2, string modelname = "Union"); + void SmoothBbox(std::vector& winList); + void PNet(float scale); + void PNet(); + void RNet(); + void ONet(); + + ncnn::Mat img; + + const float nms_threshold[3] = { 0.5f, 0.7f, 0.7f }; + const float mean_vals[3] = { 127.5, 127.5, 127.5 }; + const float norm_vals[3] = { 0.0078125, 0.0078125, 0.0078125 }; + const int MIN_DET_SIZE = 12; + std::vector firstPreviousBbox_, secondPreviousBbox_, thirdPrevioussBbox_; + std::vector firstBbox_, secondBbox_, thirdBbox_; + int img_w, img_h; + +private: + const float threshold[3] = { 0.8f, 0.8f, 0.9f }; + int minsize = 80; + const float pre_facetor = 0.7090f; + bool smooth = true;//ȶ +}; + + +#endif //__MTCNN_NCNN_H__

      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