From 245146711825f9a0515ec8bf300e90621d60401d Mon Sep 17 00:00:00 2001 From: amass <168062547@qq.com> Date: Mon, 17 Mar 2025 10:53:52 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E8=80=81opencv=E5=BA=93?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdparty/libopencv/include/opencv/cv.h | 73 - 3rdparty/libopencv/include/opencv/cv.hpp | 60 - 3rdparty/libopencv/include/opencv/cvaux.h | 57 - 3rdparty/libopencv/include/opencv/cvaux.hpp | 52 - 3rdparty/libopencv/include/opencv/cvwimage.h | 46 - 3rdparty/libopencv/include/opencv/cxcore.h | 52 - 3rdparty/libopencv/include/opencv/cxcore.hpp | 53 - 3rdparty/libopencv/include/opencv/cxeigen.hpp | 48 - 3rdparty/libopencv/include/opencv/cxmisc.h | 8 - 3rdparty/libopencv/include/opencv/highgui.h | 48 - 3rdparty/libopencv/include/opencv/ml.h | 47 - .../libopencv/include/opencv2/calib3d.hpp | 2433 -------- .../include/opencv2/calib3d/calib3d.hpp | 48 - .../include/opencv2/calib3d/calib3d_c.h | 427 -- 3rdparty/libopencv/include/opencv2/core.hpp | 3265 ----------- .../libopencv/include/opencv2/core/affine.hpp | 678 --- .../libopencv/include/opencv2/core/base.hpp | 762 --- .../include/opencv2/core/bufferpool.hpp | 40 - .../libopencv/include/opencv2/core/core.hpp | 48 - .../libopencv/include/opencv2/core/core_c.h | 3184 ----------- .../libopencv/include/opencv2/core/cuda.hpp | 1015 ---- .../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 | 1980 ------- .../opencv2/core/cuda/detail/reduce.hpp | 365 -- .../core/cuda/detail/reduce_key_val.hpp | 502 -- .../core/cuda/detail/transform_detail.hpp | 399 -- .../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 | 811 --- .../include/opencv2/core/cuda/limits.hpp | 128 - .../include/opencv2/core/cuda/reduce.hpp | 209 - .../opencv2/core/cuda/saturate_cast.hpp | 292 - .../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 | 930 ---- .../include/opencv2/core/cuda/vec_traits.hpp | 288 - .../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 | 135 - .../include/opencv2/core/cv_cpu_dispatch.h | 239 - .../include/opencv2/core/cv_cpu_helper.h | 274 - .../libopencv/include/opencv2/core/cvdef.h | 501 -- .../libopencv/include/opencv2/core/cvstd.hpp | 1040 ---- .../include/opencv2/core/cvstd.inl.hpp | 286 - .../include/opencv2/core/directx.hpp | 184 - .../libopencv/include/opencv2/core/eigen.hpp | 280 - .../include/opencv2/core/fast_math.hpp | 271 - .../include/opencv2/core/hal/hal.hpp | 250 - .../include/opencv2/core/hal/interface.h | 182 - .../include/opencv2/core/hal/intrin.hpp | 472 -- .../include/opencv2/core/hal/intrin_cpp.hpp | 1959 ------- .../include/opencv2/core/hal/intrin_neon.hpp | 1303 ----- .../include/opencv2/core/hal/intrin_sse.hpp | 1921 ------- .../include/opencv2/core/hal/intrin_vsx.hpp | 962 ---- .../include/opencv2/core/ippasync.hpp | 195 - .../libopencv/include/opencv2/core/mat.hpp | 3661 ------------ .../include/opencv2/core/mat.inl.hpp | 3939 ------------- .../libopencv/include/opencv2/core/matx.hpp | 1476 ----- .../include/opencv2/core/neon_utils.hpp | 128 - .../libopencv/include/opencv2/core/ocl.hpp | 842 --- .../include/opencv2/core/ocl_genbase.hpp | 69 - .../include/opencv2/core/opencl/ocl_defs.hpp | 75 - .../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 | 370 -- .../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 - .../libopencv/include/opencv2/core/opengl.hpp | 729 --- .../include/opencv2/core/operations.hpp | 538 -- .../libopencv/include/opencv2/core/optim.hpp | 302 - .../libopencv/include/opencv2/core/ovx.hpp | 28 - .../include/opencv2/core/persistence.hpp | 1359 ----- .../include/opencv2/core/ptr.inl.hpp | 379 -- .../include/opencv2/core/saturate.hpp | 165 - .../include/opencv2/core/softfloat.hpp | 514 -- .../include/opencv2/core/sse_utils.hpp | 652 --- .../libopencv/include/opencv2/core/traits.hpp | 397 -- .../libopencv/include/opencv2/core/types.hpp | 2358 -------- .../libopencv/include/opencv2/core/types_c.h | 1837 ------ .../include/opencv2/core/utility.hpp | 1240 ----- .../include/opencv2/core/utils/filesystem.hpp | 71 - .../opencv2/core/utils/logger.defines.hpp | 22 - .../include/opencv2/core/utils/logger.hpp | 87 - .../include/opencv2/core/utils/trace.hpp | 250 - .../include/opencv2/core/va_intel.hpp | 77 - .../include/opencv2/core/version.hpp | 26 - .../include/opencv2/core/vsx_utils.hpp | 1095 ---- .../libopencv/include/opencv2/core/wimage.hpp | 603 -- 3rdparty/libopencv/include/opencv2/cvconfig.h | 248 - 3rdparty/libopencv/include/opencv2/dnn.hpp | 64 - .../include/opencv2/dnn/all_layers.hpp | 589 -- .../libopencv/include/opencv2/dnn/dict.hpp | 152 - .../libopencv/include/opencv2/dnn/dnn.hpp | 794 --- .../libopencv/include/opencv2/dnn/dnn.inl.hpp | 373 -- .../include/opencv2/dnn/layer.details.hpp | 78 - .../libopencv/include/opencv2/dnn/layer.hpp | 85 - .../include/opencv2/dnn/shape_utils.hpp | 206 - .../libopencv/include/opencv2/features2d.hpp | 1424 ----- .../include/opencv2/features2d/features2d.hpp | 48 - .../opencv2/features2d/hal/interface.h | 33 - 3rdparty/libopencv/include/opencv2/flann.hpp | 531 -- .../include/opencv2/flann/all_indices.h | 155 - .../include/opencv2/flann/allocator.h | 192 - .../libopencv/include/opencv2/flann/any.h | 330 -- .../include/opencv2/flann/autotuned_index.h | 591 -- .../include/opencv2/flann/composite_index.h | 194 - .../libopencv/include/opencv2/flann/config.h | 38 - .../libopencv/include/opencv2/flann/defines.h | 164 - .../libopencv/include/opencv2/flann/dist.h | 905 --- .../libopencv/include/opencv2/flann/dummy.h | 13 - .../include/opencv2/flann/dynamic_bitset.h | 159 - .../libopencv/include/opencv2/flann/flann.hpp | 48 - .../include/opencv2/flann/flann_base.hpp | 295 - .../libopencv/include/opencv2/flann/general.h | 50 - .../include/opencv2/flann/ground_truth.h | 94 - .../libopencv/include/opencv2/flann/hdf5.h | 231 - .../libopencv/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 | 1171 ---- .../include/opencv2/flann/linear_index.h | 132 - .../libopencv/include/opencv2/flann/logger.h | 135 - .../include/opencv2/flann/lsh_index.h | 392 -- .../include/opencv2/flann/lsh_table.h | 513 -- .../libopencv/include/opencv2/flann/matrix.h | 116 - .../include/opencv2/flann/miniflann.hpp | 162 - .../include/opencv2/flann/nn_index.h | 177 - .../include/opencv2/flann/object_factory.h | 91 - .../libopencv/include/opencv2/flann/params.h | 99 - .../libopencv/include/opencv2/flann/random.h | 155 - .../include/opencv2/flann/result_set.h | 543 -- .../include/opencv2/flann/sampling.h | 81 - .../libopencv/include/opencv2/flann/saving.h | 187 - .../include/opencv2/flann/simplex_downhill.h | 186 - .../libopencv/include/opencv2/flann/timer.h | 94 - .../libopencv/include/opencv2/highgui.hpp | 844 --- .../include/opencv2/highgui/highgui.hpp | 48 - .../include/opencv2/highgui/highgui_c.h | 260 - .../libopencv/include/opencv2/imgcodecs.hpp | 247 - .../include/opencv2/imgcodecs/imgcodecs.hpp | 48 - .../include/opencv2/imgcodecs/imgcodecs_c.h | 149 - .../libopencv/include/opencv2/imgcodecs/ios.h | 57 - .../libopencv/include/opencv2/imgproc.hpp | 4910 ----------------- .../imgproc/detail/distortion_model.hpp | 123 - .../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 | 1210 ---- .../include/opencv2/imgproc/types_c.h | 629 --- 3rdparty/libopencv/include/opencv2/ml.hpp | 1961 ------- 3rdparty/libopencv/include/opencv2/ml/ml.hpp | 48 - .../libopencv/include/opencv2/ml/ml.inl.hpp | 60 - .../libopencv/include/opencv2/objdetect.hpp | 683 --- .../objdetect/detection_based_tracker.hpp | 227 - .../include/opencv2/objdetect/objdetect.hpp | 48 - .../include/opencv2/objdetect/objdetect_c.h | 166 - 3rdparty/libopencv/include/opencv2/opencv.hpp | 139 - .../include/opencv2/opencv_modules.hpp | 31 - 3rdparty/libopencv/include/opencv2/photo.hpp | 876 --- .../libopencv/include/opencv2/photo/cuda.hpp | 132 - .../libopencv/include/opencv2/photo/photo.hpp | 48 - .../libopencv/include/opencv2/photo/photo_c.h | 74 - 3rdparty/libopencv/include/opencv2/shape.hpp | 57 - .../libopencv/include/opencv2/shape/emdL1.hpp | 72 - .../include/opencv2/shape/hist_cost.hpp | 111 - .../libopencv/include/opencv2/shape/shape.hpp | 48 - .../include/opencv2/shape/shape_distance.hpp | 227 - .../opencv2/shape/shape_transformer.hpp | 132 - .../libopencv/include/opencv2/stitching.hpp | 321 -- .../opencv2/stitching/detail/autocalib.hpp | 86 - .../opencv2/stitching/detail/blenders.hpp | 171 - .../opencv2/stitching/detail/camera.hpp | 78 - .../stitching/detail/exposure_compensate.hpp | 136 - .../opencv2/stitching/detail/matchers.hpp | 355 -- .../stitching/detail/motion_estimators.hpp | 359 -- .../opencv2/stitching/detail/seam_finders.hpp | 285 - .../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 | 192 - .../libopencv/include/opencv2/superres.hpp | 207 - .../include/opencv2/superres/optical_flow.hpp | 203 - 3rdparty/libopencv/include/opencv2/video.hpp | 63 - .../include/opencv2/video/background_segm.hpp | 317 -- .../include/opencv2/video/tracking.hpp | 628 --- .../include/opencv2/video/tracking_c.h | 232 - .../libopencv/include/opencv2/video/video.hpp | 48 - .../libopencv/include/opencv2/videoio.hpp | 957 ---- .../include/opencv2/videoio/cap_ios.h | 150 - .../include/opencv2/videoio/videoio.hpp | 48 - .../include/opencv2/videoio/videoio_c.h | 587 -- .../libopencv/include/opencv2/videostab.hpp | 81 - .../include/opencv2/videostab/deblurring.hpp | 116 - .../opencv2/videostab/fast_marching.hpp | 121 - .../opencv2/videostab/fast_marching_inl.hpp | 165 - .../opencv2/videostab/frame_source.hpp | 94 - .../opencv2/videostab/global_motion.hpp | 300 - .../include/opencv2/videostab/inpainting.hpp | 212 - .../include/opencv2/videostab/log.hpp | 80 - .../include/opencv2/videostab/motion_core.hpp | 129 - .../opencv2/videostab/motion_stabilizing.hpp | 174 - .../opencv2/videostab/optical_flow.hpp | 150 - .../opencv2/videostab/outlier_rejection.hpp | 101 - .../include/opencv2/videostab/ring_buffer.hpp | 72 - .../include/opencv2/videostab/stabilizer.hpp | 200 - .../opencv2/videostab/wobble_suppression.hpp | 140 - 3rdparty/libopencv/libs/libopencv_core.so | 1 - 3rdparty/libopencv/libs/libopencv_core.so.3.4 | Bin 3155120 -> 0 bytes .../libopencv/libs/libopencv_imgcodecs.so | 1 - .../libopencv/libs/libopencv_imgcodecs.so.3.4 | Bin 962224 -> 0 bytes 3rdparty/libopencv/libs/libopencv_imgproc.so | 1 - .../libopencv/libs/libopencv_imgproc.so.3.4 | Bin 3529368 -> 0 bytes 243 files changed, 97745 deletions(-) delete mode 100644 3rdparty/libopencv/include/opencv/cv.h delete mode 100644 3rdparty/libopencv/include/opencv/cv.hpp delete mode 100644 3rdparty/libopencv/include/opencv/cvaux.h delete mode 100644 3rdparty/libopencv/include/opencv/cvaux.hpp delete mode 100644 3rdparty/libopencv/include/opencv/cvwimage.h delete mode 100644 3rdparty/libopencv/include/opencv/cxcore.h delete mode 100644 3rdparty/libopencv/include/opencv/cxcore.hpp delete mode 100644 3rdparty/libopencv/include/opencv/cxeigen.hpp delete mode 100644 3rdparty/libopencv/include/opencv/cxmisc.h delete mode 100644 3rdparty/libopencv/include/opencv/highgui.h delete mode 100644 3rdparty/libopencv/include/opencv/ml.h delete mode 100644 3rdparty/libopencv/include/opencv2/calib3d.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/calib3d/calib3d.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/calib3d/calib3d_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/core.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/affine.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/base.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/bufferpool.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/core.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/core_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda.inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/block.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/border_interpolate.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/color.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/common.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/datamov_utils.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/detail/color_detail.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/detail/transform_detail.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/dynamic_smem.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/emulation.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/filters.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/funcattrib.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/functional.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/limits.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/reduce.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/saturate_cast.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/scan.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/simd_functions.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/transform.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/type_traits.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/utility.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/vec_distance.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/vec_math.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/vec_traits.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/warp.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/warp_reduce.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda/warp_shuffle.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda_stream_accessor.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cuda_types.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cv_cpu_dispatch.h delete mode 100644 3rdparty/libopencv/include/opencv2/core/cv_cpu_helper.h delete mode 100644 3rdparty/libopencv/include/opencv2/core/cvdef.h delete mode 100644 3rdparty/libopencv/include/opencv2/core/cvstd.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/cvstd.inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/directx.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/eigen.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/fast_math.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/hal/hal.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/hal/interface.h delete mode 100644 3rdparty/libopencv/include/opencv2/core/hal/intrin.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/hal/intrin_cpp.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/hal/intrin_neon.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/hal/intrin_sse.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/hal/intrin_vsx.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/ippasync.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/mat.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/mat.inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/matx.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/neon_utils.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/ocl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/ocl_genbase.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/ocl_defs.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/opencl_info.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/opencl_svm.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/opengl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/operations.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/optim.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/ovx.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/persistence.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/ptr.inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/saturate.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/softfloat.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/sse_utils.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/traits.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/types.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/types_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/core/utility.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/utils/filesystem.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/utils/logger.defines.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/utils/logger.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/utils/trace.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/va_intel.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/version.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/vsx_utils.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/core/wimage.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/cvconfig.h delete mode 100644 3rdparty/libopencv/include/opencv2/dnn.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/dnn/all_layers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/dnn/dict.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/dnn/dnn.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/dnn/dnn.inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/dnn/layer.details.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/dnn/layer.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/dnn/shape_utils.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/features2d.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/features2d/features2d.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/features2d/hal/interface.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/flann/all_indices.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/allocator.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/any.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/autotuned_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/composite_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/config.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/defines.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/dist.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/dummy.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/dynamic_bitset.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/flann.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/flann/flann_base.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/flann/general.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/ground_truth.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/hdf5.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/heap.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/hierarchical_clustering_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/index_testing.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/kdtree_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/kdtree_single_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/kmeans_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/linear_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/logger.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/lsh_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/lsh_table.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/matrix.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/miniflann.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/flann/nn_index.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/object_factory.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/params.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/random.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/result_set.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/sampling.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/saving.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/simplex_downhill.h delete mode 100644 3rdparty/libopencv/include/opencv2/flann/timer.h delete mode 100644 3rdparty/libopencv/include/opencv2/highgui.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/highgui/highgui.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/highgui/highgui_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/imgcodecs.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/imgcodecs/ios.h delete mode 100644 3rdparty/libopencv/include/opencv2/imgproc.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/imgproc/detail/distortion_model.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/imgproc/hal/hal.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/imgproc/hal/interface.h delete mode 100644 3rdparty/libopencv/include/opencv2/imgproc/imgproc.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/imgproc/imgproc_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/imgproc/types_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/ml.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/ml/ml.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/ml/ml.inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/objdetect.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/objdetect/detection_based_tracker.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/objdetect/objdetect.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/objdetect/objdetect_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/opencv.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/opencv_modules.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/photo.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/photo/cuda.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/photo/photo.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/photo/photo_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/shape.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/shape/emdL1.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/shape/hist_cost.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/shape/shape.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/shape/shape_distance.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/shape/shape_transformer.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/autocalib.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/blenders.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/camera.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/exposure_compensate.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/matchers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/motion_estimators.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/seam_finders.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/timelapsers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/util.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/util_inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/warpers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/detail/warpers_inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/stitching/warpers.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/superres.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/superres/optical_flow.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/video.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/video/background_segm.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/video/tracking.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/video/tracking_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/video/video.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videoio.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videoio/cap_ios.h delete mode 100644 3rdparty/libopencv/include/opencv2/videoio/videoio.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videoio/videoio_c.h delete mode 100644 3rdparty/libopencv/include/opencv2/videostab.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/deblurring.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/fast_marching.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/fast_marching_inl.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/frame_source.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/global_motion.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/inpainting.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/log.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/motion_core.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/motion_stabilizing.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/optical_flow.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/outlier_rejection.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/ring_buffer.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/stabilizer.hpp delete mode 100644 3rdparty/libopencv/include/opencv2/videostab/wobble_suppression.hpp delete mode 120000 3rdparty/libopencv/libs/libopencv_core.so delete mode 100644 3rdparty/libopencv/libs/libopencv_core.so.3.4 delete mode 120000 3rdparty/libopencv/libs/libopencv_imgcodecs.so delete mode 100644 3rdparty/libopencv/libs/libopencv_imgcodecs.so.3.4 delete mode 120000 3rdparty/libopencv/libs/libopencv_imgproc.so delete mode 100644 3rdparty/libopencv/libs/libopencv_imgproc.so.3.4 diff --git a/3rdparty/libopencv/include/opencv/cv.h b/3rdparty/libopencv/include/opencv/cv.h deleted file mode 100644 index 19a74e2..0000000 --- a/3rdparty/libopencv/include/opencv/cv.h +++ /dev/null @@ -1,73 +0,0 @@ -/*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_OLD_CV_H -#define OPENCV_OLD_CV_H - -#if defined(_MSC_VER) - #define CV_DO_PRAGMA(x) __pragma(x) - #define __CVSTR2__(x) #x - #define __CVSTR1__(x) __CVSTR2__(x) - #define __CVMSVCLOC__ __FILE__ "("__CVSTR1__(__LINE__)") : " - #define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (__CVMSVCLOC__ _msg)) -#elif defined(__GNUC__) - #define CV_DO_PRAGMA(x) _Pragma (#x) - #define CV_MSG_PRAGMA(_msg) CV_DO_PRAGMA(message (_msg)) -#else - #define CV_DO_PRAGMA(x) - #define CV_MSG_PRAGMA(_msg) -#endif -#define CV_WARNING(x) CV_MSG_PRAGMA("Warning: " #x) - -//CV_WARNING("This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module") - -#include "opencv2/core/core_c.h" -#include "opencv2/imgproc/imgproc_c.h" -#include "opencv2/photo/photo_c.h" -#include "opencv2/video/tracking_c.h" -#include "opencv2/objdetect/objdetect_c.h" - -#if !defined(CV_IMPL) -#define CV_IMPL extern "C" -#endif //CV_IMPL - -#endif // __OPENCV_OLD_CV_H_ diff --git a/3rdparty/libopencv/include/opencv/cv.hpp b/3rdparty/libopencv/include/opencv/cv.hpp deleted file mode 100644 index 8673956..0000000 --- a/3rdparty/libopencv/include/opencv/cv.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/*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_OLD_CV_HPP -#define OPENCV_OLD_CV_HPP - -//#if defined(__GNUC__) -//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" -//#endif - -#include "cv.h" -#include "opencv2/core.hpp" -#include "opencv2/imgproc.hpp" -#include "opencv2/photo.hpp" -#include "opencv2/video.hpp" -#include "opencv2/highgui.hpp" -#include "opencv2/features2d.hpp" -#include "opencv2/calib3d.hpp" -#include "opencv2/objdetect.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv/cvaux.h b/3rdparty/libopencv/include/opencv/cvaux.h deleted file mode 100644 index c0367cc..0000000 --- a/3rdparty/libopencv/include/opencv/cvaux.h +++ /dev/null @@ -1,57 +0,0 @@ -/*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_OLD_AUX_H -#define OPENCV_OLD_AUX_H - -//#if defined(__GNUC__) -//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" -//#endif - -#include "opencv2/core/core_c.h" -#include "opencv2/imgproc/imgproc_c.h" -#include "opencv2/photo/photo_c.h" -#include "opencv2/video/tracking_c.h" -#include "opencv2/objdetect/objdetect_c.h" - -#endif - -/* End of file. */ diff --git a/3rdparty/libopencv/include/opencv/cvaux.hpp b/3rdparty/libopencv/include/opencv/cvaux.hpp deleted file mode 100644 index 4888eef..0000000 --- a/3rdparty/libopencv/include/opencv/cvaux.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/*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_OLD_AUX_HPP -#define OPENCV_OLD_AUX_HPP - -//#if defined(__GNUC__) -//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" -//#endif - -#include "cvaux.h" -#include "opencv2/core/utility.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv/cvwimage.h b/3rdparty/libopencv/include/opencv/cvwimage.h deleted file mode 100644 index ec0ab14..0000000 --- a/3rdparty/libopencv/include/opencv/cvwimage.h +++ /dev/null @@ -1,46 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// 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) 2008, Google, 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 or contributors 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. - - -#ifndef OPENCV_OLD_WIMAGE_HPP -#define OPENCV_OLD_WIMAGE_HPP - -#include "opencv2/core/wimage.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv/cxcore.h b/3rdparty/libopencv/include/opencv/cxcore.h deleted file mode 100644 index dc070c7..0000000 --- a/3rdparty/libopencv/include/opencv/cxcore.h +++ /dev/null @@ -1,52 +0,0 @@ -/*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_OLD_CXCORE_H -#define OPENCV_OLD_CXCORE_H - -//#if defined(__GNUC__) -//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" -//#endif - -#include "opencv2/core/core_c.h" - -#endif diff --git a/3rdparty/libopencv/include/opencv/cxcore.hpp b/3rdparty/libopencv/include/opencv/cxcore.hpp deleted file mode 100644 index c371677..0000000 --- a/3rdparty/libopencv/include/opencv/cxcore.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/*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_OLD_CXCORE_HPP -#define OPENCV_OLD_CXCORE_HPP - -//#if defined(__GNUC__) -//#warning "This is a deprecated opencv header provided for compatibility. Please include a header from a corresponding opencv module" -//#endif - -#include "cxcore.h" -#include "opencv2/core.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv/cxeigen.hpp b/3rdparty/libopencv/include/opencv/cxeigen.hpp deleted file mode 100644 index 1d3df91..0000000 --- a/3rdparty/libopencv/include/opencv/cxeigen.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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_OLD_EIGEN_HPP -#define OPENCV_OLD_EIGEN_HPP - -#include "opencv2/core/eigen.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv/cxmisc.h b/3rdparty/libopencv/include/opencv/cxmisc.h deleted file mode 100644 index 9b9bc82..0000000 --- a/3rdparty/libopencv/include/opencv/cxmisc.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef OPENCV_OLD_CXMISC_H -#define OPENCV_OLD_CXMISC_H - -#ifdef __cplusplus -# include "opencv2/core/utility.hpp" -#endif - -#endif diff --git a/3rdparty/libopencv/include/opencv/highgui.h b/3rdparty/libopencv/include/opencv/highgui.h deleted file mode 100644 index 69b394e..0000000 --- a/3rdparty/libopencv/include/opencv/highgui.h +++ /dev/null @@ -1,48 +0,0 @@ -/*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_OLD_HIGHGUI_H -#define OPENCV_OLD_HIGHGUI_H - -#include "opencv2/core/core_c.h" -#include "opencv2/highgui/highgui_c.h" - -#endif diff --git a/3rdparty/libopencv/include/opencv/ml.h b/3rdparty/libopencv/include/opencv/ml.h deleted file mode 100644 index 0c376ba..0000000 --- a/3rdparty/libopencv/include/opencv/ml.h +++ /dev/null @@ -1,47 +0,0 @@ -/*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 -// -// 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_OLD_ML_H -#define OPENCV_OLD_ML_H - -#include "opencv2/core/core_c.h" -#include "opencv2/ml.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv2/calib3d.hpp b/3rdparty/libopencv/include/opencv2/calib3d.hpp deleted file mode 100644 index 54b193c..0000000 --- a/3rdparty/libopencv/include/opencv2/calib3d.hpp +++ /dev/null @@ -1,2433 +0,0 @@ -/*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_HPP -#define OPENCV_CALIB3D_HPP - -#include "opencv2/core.hpp" -#include "opencv2/features2d.hpp" -#include "opencv2/core/affine.hpp" - -/** - @defgroup calib3d Camera Calibration and 3D Reconstruction - -The functions in this section use a so-called pinhole camera model. In this model, a scene view is -formed by projecting 3D points into the image plane using a perspective transformation. - -\f[s \; m' = A [R|t] M'\f] - -or - -\f[s \vecthree{u}{v}{1} = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1} -\begin{bmatrix} -r_{11} & r_{12} & r_{13} & t_1 \\ -r_{21} & r_{22} & r_{23} & t_2 \\ -r_{31} & r_{32} & r_{33} & t_3 -\end{bmatrix} -\begin{bmatrix} -X \\ -Y \\ -Z \\ -1 -\end{bmatrix}\f] - -where: - -- \f$(X, Y, Z)\f$ are the coordinates of a 3D point in the world coordinate space -- \f$(u, v)\f$ are the coordinates of the projection point in pixels -- \f$A\f$ is a camera matrix, or a matrix of intrinsic parameters -- \f$(cx, cy)\f$ is a principal point that is usually at the image center -- \f$fx, fy\f$ are the focal lengths expressed in pixel units. - -Thus, if an image from the camera is scaled by a factor, all of these parameters should be scaled -(multiplied/divided, respectively) by the same factor. The matrix of intrinsic parameters does not -depend on the scene viewed. So, once estimated, it can be re-used as long as the focal length is -fixed (in case of zoom lens). The joint rotation-translation matrix \f$[R|t]\f$ is called a matrix of -extrinsic parameters. It is used to describe the camera motion around a static scene, or vice versa, -rigid motion of an object in front of a still camera. That is, \f$[R|t]\f$ translates coordinates of a -point \f$(X, Y, Z)\f$ to a coordinate system, fixed with respect to the camera. The transformation above -is equivalent to the following (when \f$z \ne 0\f$ ): - -\f[\begin{array}{l} -\vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\ -x' = x/z \\ -y' = y/z \\ -u = f_x*x' + c_x \\ -v = f_y*y' + c_y -\end{array}\f] - -The following figure illustrates the pinhole camera model. - -![Pinhole camera model](pics/pinhole_camera_model.png) - -Real lenses usually have some distortion, mostly radial distortion and slight tangential distortion. -So, the above model is extended as: - -\f[\begin{array}{l} -\vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\ -x' = x/z \\ -y' = y/z \\ -x'' = x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + 2 p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4 \\ -y'' = y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\ -\text{where} \quad r^2 = x'^2 + y'^2 \\ -u = f_x*x'' + c_x \\ -v = f_y*y'' + c_y -\end{array}\f] - -\f$k_1\f$, \f$k_2\f$, \f$k_3\f$, \f$k_4\f$, \f$k_5\f$, and \f$k_6\f$ are radial distortion coefficients. \f$p_1\f$ and \f$p_2\f$ are -tangential distortion coefficients. \f$s_1\f$, \f$s_2\f$, \f$s_3\f$, and \f$s_4\f$, are the thin prism distortion -coefficients. Higher-order coefficients are not considered in OpenCV. - -The next figure shows two common types of radial distortion: barrel distortion (typically \f$ k_1 > 0 \f$ and pincushion distortion (typically \f$ k_1 < 0 \f$). - -![](pics/distortion_examples.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 sample of an artificially generated camera and chessboard patterns can be - found at opencv_source_code/samples/cpp/calibration_artificial.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 { 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_MAX_COUNT //!< Used for count -}; - -enum { CALIB_CB_ADAPTIVE_THRESH = 1, - CALIB_CB_NORMALIZE_IMAGE = 2, - CALIB_CB_FILTER_QUADS = 4, - CALIB_CB_FAST_CHECK = 8 - }; - -enum { CALIB_CB_SYMMETRIC_GRID = 1, - CALIB_CB_ASYMMETRIC_GRID = 2, - CALIB_CB_CLUSTERING = 4 - }; - -enum { 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. - }; - - - -/** @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() ); - -/** @example 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 -@param dr3dt1 -@param dr3dr2 -@param dr3dt2 -@param dt3dr1 -@param dt3dt1 -@param dt3dr2 -@param dt3dt2 Optional output derivatives of rvec3 or tvec3 with regard to rvec1, rvec2, tvec1 and -tvec2, respectively. - -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, 2xN/Nx2 1-channel or 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 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. - -@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 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_AP3P** Method is based on the paper of Tong Ke and Stergios I. 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. - -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 to transform -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. - */ -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 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 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 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 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 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 Tong Ke and Stergios I. 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. - */ -CV_EXPORTS_W int solveP3P( InputArray objectPoints, InputArray imagePoints, - InputArray cameraMatrix, InputArray distCoeffs, - OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, - int flags ); - -/** @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 = cvSize(points_per_row,points_per_colum) = cvSize(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 ); - -//! finds subpixel-accurate positions of the chessboard corners -CV_EXPORTS 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 ); - -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; -}; - -struct CV_EXPORTS_W_SIMPLE CirclesGridFinderParameters2 : public CirclesGridFinderParameters -{ - CV_WRAP CirclesGridFinderParameters2(); - - 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. -}; - -/** @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, - CirclesGridFinderParameters parameters); - -/** @overload */ -CV_EXPORTS_W bool findCirclesGrid2( InputArray image, Size patternSize, - OutputArray centers, int flags, - const Ptr &blobDetector, - CirclesGridFinderParameters2 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 - 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 double calibrateCamera( InputArrayOfArrays objectPoints, - InputArrayOfArrays imagePoints, Size imageSize, - InputOutputArray cameraMatrix, InputOutputArray distCoeffs, - OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, - OutputArray stdDeviations, OutputArray perViewErrors, - int flags = 0, TermCriteria criteria = TermCriteria( - TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON) ) - */ -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 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 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 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 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); -}; - -//! @} 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 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 - @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 - @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 - -#ifndef DISABLE_OPENCV_24_COMPATIBILITY -#include "opencv2/calib3d/calib3d_c.h" -#endif - -#endif diff --git a/3rdparty/libopencv/include/opencv2/calib3d/calib3d.hpp b/3rdparty/libopencv/include/opencv2/calib3d/calib3d.hpp deleted file mode 100644 index b3da45e..0000000 --- a/3rdparty/libopencv/include/opencv2/calib3d/calib3d.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/calib3d/calib3d_c.h b/3rdparty/libopencv/include/opencv2/calib3d/calib3d_c.h deleted file mode 100644 index 8ec6390..0000000 --- a/3rdparty/libopencv/include/opencv2/calib3d/calib3d_c.h +++ /dev/null @@ -1,427 +0,0 @@ -/*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/core_c.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup calib3d_c - @{ - */ - -/****************************************************************************************\ -* Camera Calibration, Pose Estimation and Stereo * -\****************************************************************************************/ - -typedef struct CvPOSITObject CvPOSITObject; - -/* Allocates and initializes CvPOSITObject structure before doing cvPOSIT */ -CVAPI(CvPOSITObject*) cvCreatePOSITObject( CvPoint3D32f* points, int point_count ); - - -/* Runs POSIT (POSe from ITeration) algorithm for determining 3d position of - an object given its model and projection in a weak-perspective case */ -CVAPI(void) cvPOSIT( CvPOSITObject* posit_object, CvPoint2D32f* image_points, - double focal_length, CvTermCriteria criteria, - float* rotation_matrix, float* translation_vector); - -/* Releases CvPOSITObject structure */ -CVAPI(void) cvReleasePOSITObject( CvPOSITObject** posit_object ); - -/* updates the number of RANSAC iterations */ -CVAPI(int) cvRANSACUpdateNumIters( double p, double err_prob, - int model_points, int max_iters ); - -CVAPI(void) cvConvertPointsHomogeneous( const CvMat* src, CvMat* dst ); - -/* 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" -}; - -CVAPI(int) cvFindFundamentalMat( const CvMat* points1, const CvMat* points2, - CvMat* fundamental_matrix, - int method CV_DEFAULT(CV_FM_RANSAC), - double param1 CV_DEFAULT(3.), double param2 CV_DEFAULT(0.99), - CvMat* status CV_DEFAULT(NULL) ); - -/* For each input point on one of images - computes parameters of the corresponding - epipolar line on the other image */ -CVAPI(void) cvComputeCorrespondEpilines( const CvMat* points, - int which_image, - const CvMat* fundamental_matrix, - CvMat* correspondent_lines ); - -/* Triangulation functions */ - -CVAPI(void) cvTriangulatePoints(CvMat* projMatr1, CvMat* projMatr2, - CvMat* projPoints1, CvMat* projPoints2, - CvMat* points4D); - -CVAPI(void) cvCorrectMatches(CvMat* F, CvMat* points1, CvMat* points2, - CvMat* new_points1, CvMat* new_points2); - - -/* Computes the optimal new camera matrix according to the free scaling parameter alpha: - alpha=0 - only valid pixels will be retained in the undistorted image - alpha=1 - all the source image pixels will be retained in the undistorted image -*/ -CVAPI(void) cvGetOptimalNewCameraMatrix( const CvMat* camera_matrix, - const CvMat* dist_coeffs, - CvSize image_size, double alpha, - CvMat* new_camera_matrix, - CvSize new_imag_size CV_DEFAULT(cvSize(0,0)), - CvRect* valid_pixel_ROI CV_DEFAULT(0), - int center_principal_point CV_DEFAULT(0)); - -/* Converts rotation vector to rotation matrix or vice versa */ -CVAPI(int) cvRodrigues2( const CvMat* src, CvMat* dst, - CvMat* jacobian CV_DEFAULT(0) ); - -/* Finds perspective transformation between the object plane and image (view) plane */ -CVAPI(int) cvFindHomography( const CvMat* src_points, - const CvMat* dst_points, - CvMat* homography, - int method CV_DEFAULT(0), - double ransacReprojThreshold CV_DEFAULT(3), - CvMat* mask CV_DEFAULT(0), - int maxIters CV_DEFAULT(2000), - double confidence CV_DEFAULT(0.995)); - -/* Computes RQ decomposition for 3x3 matrices */ -CVAPI(void) cvRQDecomp3x3( const CvMat *matrixM, CvMat *matrixR, CvMat *matrixQ, - CvMat *matrixQx CV_DEFAULT(NULL), - CvMat *matrixQy CV_DEFAULT(NULL), - CvMat *matrixQz CV_DEFAULT(NULL), - CvPoint3D64f *eulerAngles CV_DEFAULT(NULL)); - -/* Computes projection matrix decomposition */ -CVAPI(void) cvDecomposeProjectionMatrix( const CvMat *projMatr, CvMat *calibMatr, - CvMat *rotMatr, CvMat *posVect, - CvMat *rotMatrX CV_DEFAULT(NULL), - CvMat *rotMatrY CV_DEFAULT(NULL), - CvMat *rotMatrZ CV_DEFAULT(NULL), - CvPoint3D64f *eulerAngles CV_DEFAULT(NULL)); - -/* Computes d(AB)/dA and d(AB)/dB */ -CVAPI(void) cvCalcMatMulDeriv( const CvMat* A, const CvMat* B, CvMat* dABdA, CvMat* dABdB ); - -/* Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)), - t3 = rodrigues(r2)*t1 + t2 and the respective derivatives */ -CVAPI(void) cvComposeRT( const CvMat* _rvec1, const CvMat* _tvec1, - const CvMat* _rvec2, const CvMat* _tvec2, - CvMat* _rvec3, CvMat* _tvec3, - CvMat* dr3dr1 CV_DEFAULT(0), CvMat* dr3dt1 CV_DEFAULT(0), - CvMat* dr3dr2 CV_DEFAULT(0), CvMat* dr3dt2 CV_DEFAULT(0), - CvMat* dt3dr1 CV_DEFAULT(0), CvMat* dt3dt1 CV_DEFAULT(0), - CvMat* dt3dr2 CV_DEFAULT(0), CvMat* dt3dt2 CV_DEFAULT(0) ); - -/* Projects object points to the view plane using - the specified extrinsic and intrinsic camera parameters */ -CVAPI(void) cvProjectPoints2( const CvMat* object_points, const CvMat* rotation_vector, - const CvMat* translation_vector, const CvMat* camera_matrix, - const CvMat* distortion_coeffs, CvMat* image_points, - CvMat* dpdrot CV_DEFAULT(NULL), CvMat* dpdt CV_DEFAULT(NULL), - CvMat* dpdf CV_DEFAULT(NULL), CvMat* dpdc CV_DEFAULT(NULL), - CvMat* dpddist CV_DEFAULT(NULL), - double aspect_ratio CV_DEFAULT(0)); - -/* Finds extrinsic camera parameters from - a few known corresponding point pairs and intrinsic parameters */ -CVAPI(void) cvFindExtrinsicCameraParams2( const CvMat* object_points, - const CvMat* image_points, - const CvMat* camera_matrix, - const CvMat* distortion_coeffs, - CvMat* rotation_vector, - CvMat* translation_vector, - int use_extrinsic_guess CV_DEFAULT(0) ); - -/* Computes initial estimate of the intrinsic camera parameters - in case of planar calibration target (e.g. chessboard) */ -CVAPI(void) cvInitIntrinsicParams2D( const CvMat* object_points, - const CvMat* image_points, - const CvMat* npoints, CvSize image_size, - CvMat* camera_matrix, - double aspect_ratio CV_DEFAULT(1.) ); - -#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 - -// Performs a fast check if a chessboard is in the input image. This is a workaround to -// a problem of cvFindChessboardCorners being slow on images with no chessboard -// - src: input image -// - size: chessboard size -// Returns 1 if a chessboard can be in this image and findChessboardCorners should be called, -// 0 if there is no chessboard, -1 in case of error -CVAPI(int) cvCheckChessboard(IplImage* src, CvSize size); - - /* Detects corners on a chessboard calibration pattern */ -CVAPI(int) cvFindChessboardCorners( const void* image, CvSize pattern_size, - CvPoint2D32f* corners, - int* corner_count CV_DEFAULT(NULL), - int flags CV_DEFAULT(CV_CALIB_CB_ADAPTIVE_THRESH+CV_CALIB_CB_NORMALIZE_IMAGE) ); - -/* Draws individual chessboard corners or the whole chessboard detected */ -CVAPI(void) cvDrawChessboardCorners( CvArr* image, CvSize pattern_size, - CvPoint2D32f* corners, - int count, int pattern_was_found ); - -#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 - -/* Finds intrinsic and extrinsic camera parameters - from a few views of known calibration pattern */ -CVAPI(double) cvCalibrateCamera2( const CvMat* object_points, - const CvMat* image_points, - const CvMat* point_counts, - CvSize image_size, - CvMat* camera_matrix, - CvMat* distortion_coeffs, - CvMat* rotation_vectors CV_DEFAULT(NULL), - CvMat* translation_vectors CV_DEFAULT(NULL), - int flags CV_DEFAULT(0), - CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria( - CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,DBL_EPSILON)) ); - -/* Computes various useful characteristics of the camera from the data computed by - cvCalibrateCamera2 */ -CVAPI(void) cvCalibrationMatrixValues( const CvMat *camera_matrix, - CvSize image_size, - double aperture_width CV_DEFAULT(0), - double aperture_height CV_DEFAULT(0), - double *fovx CV_DEFAULT(NULL), - double *fovy CV_DEFAULT(NULL), - double *focal_length CV_DEFAULT(NULL), - CvPoint2D64f *principal_point CV_DEFAULT(NULL), - double *pixel_aspect_ratio CV_DEFAULT(NULL)); - -#define CV_CALIB_FIX_INTRINSIC 256 -#define CV_CALIB_SAME_FOCAL_LENGTH 512 - -/* Computes the transformation from one camera coordinate system to another one - from a few correspondent views of the same calibration target. Optionally, calibrates - both cameras */ -CVAPI(double) cvStereoCalibrate( const CvMat* object_points, const CvMat* image_points1, - const CvMat* image_points2, const CvMat* npoints, - CvMat* camera_matrix1, CvMat* dist_coeffs1, - CvMat* camera_matrix2, CvMat* dist_coeffs2, - CvSize image_size, CvMat* R, CvMat* T, - CvMat* E CV_DEFAULT(0), CvMat* F CV_DEFAULT(0), - int flags CV_DEFAULT(CV_CALIB_FIX_INTRINSIC), - CvTermCriteria term_crit CV_DEFAULT(cvTermCriteria( - CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,1e-6)) ); - -#define CV_CALIB_ZERO_DISPARITY 1024 - -/* Computes 3D rotations (+ optional shift) for each camera coordinate system to make both - views parallel (=> to make all the epipolar lines horizontal or vertical) */ -CVAPI(void) cvStereoRectify( const CvMat* camera_matrix1, const CvMat* camera_matrix2, - const CvMat* dist_coeffs1, const CvMat* dist_coeffs2, - CvSize image_size, const CvMat* R, const CvMat* T, - CvMat* R1, CvMat* R2, CvMat* P1, CvMat* P2, - CvMat* Q CV_DEFAULT(0), - int flags CV_DEFAULT(CV_CALIB_ZERO_DISPARITY), - double alpha CV_DEFAULT(-1), - CvSize new_image_size CV_DEFAULT(cvSize(0,0)), - CvRect* valid_pix_ROI1 CV_DEFAULT(0), - CvRect* valid_pix_ROI2 CV_DEFAULT(0)); - -/* Computes rectification transformations for uncalibrated pair of images using a set - of point correspondences */ -CVAPI(int) cvStereoRectifyUncalibrated( const CvMat* points1, const CvMat* points2, - const CvMat* F, CvSize img_size, - CvMat* H1, CvMat* H2, - double threshold CV_DEFAULT(5)); - - - -/* stereo correspondence parameters and functions */ - -#define CV_STEREO_BM_NORMALIZED_RESPONSE 0 -#define CV_STEREO_BM_XSOBEL 1 - -/* Block matching algorithm structure */ -typedef struct CvStereoBMState -{ - // pre-filtering (normalization of input images) - int preFilterType; // =CV_STEREO_BM_NORMALIZED_RESPONSE now - int preFilterSize; // averaging window size: ~5x5..21x21 - int preFilterCap; // the output of pre-filtering is clipped by [-preFilterCap,preFilterCap] - - // correspondence using Sum of Absolute Difference (SAD) - int SADWindowSize; // ~5x5..21x21 - int minDisparity; // minimum disparity (can be negative) - int numberOfDisparities; // maximum disparity - minimum disparity (> 0) - - // post-filtering - int textureThreshold; // the disparity is only computed for pixels - // with textured enough neighborhood - int uniquenessRatio; // accept the computed disparity d* only if - // SAD(d) >= SAD(d*)*(1 + uniquenessRatio/100.) - // for any d != d*+/-1 within the search range. - int speckleWindowSize; // disparity variation window - int speckleRange; // acceptable range of variation in window - - int trySmallerWindows; // if 1, the results may be more accurate, - // at the expense of slower processing - CvRect roi1, roi2; - int disp12MaxDiff; - - // temporary buffers - CvMat* preFilteredImg0; - CvMat* preFilteredImg1; - CvMat* slidingSumBuf; - CvMat* cost; - CvMat* disp; -} CvStereoBMState; - -#define CV_STEREO_BM_BASIC 0 -#define CV_STEREO_BM_FISH_EYE 1 -#define CV_STEREO_BM_NARROW 2 - -CVAPI(CvStereoBMState*) cvCreateStereoBMState(int preset CV_DEFAULT(CV_STEREO_BM_BASIC), - int numberOfDisparities CV_DEFAULT(0)); - -CVAPI(void) cvReleaseStereoBMState( CvStereoBMState** state ); - -CVAPI(void) cvFindStereoCorrespondenceBM( const CvArr* left, const CvArr* right, - CvArr* disparity, CvStereoBMState* state ); - -CVAPI(CvRect) cvGetValidDisparityROI( CvRect roi1, CvRect roi2, int minDisparity, - int numberOfDisparities, int SADWindowSize ); - -CVAPI(void) cvValidateDisparity( CvArr* disparity, const CvArr* cost, - int minDisparity, int numberOfDisparities, - int disp12MaxDiff CV_DEFAULT(1) ); - -/* Reprojects the computed disparity image to the 3D space using the specified 4x4 matrix */ -CVAPI(void) cvReprojectImageTo3D( const CvArr* disparityImage, - CvArr* _3dImage, const CvMat* Q, - int handleMissingValues CV_DEFAULT(0) ); - -/** @} calib3d_c */ - -#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/3rdparty/libopencv/include/opencv2/core.hpp b/3rdparty/libopencv/include/opencv2/core.hpp deleted file mode 100644 index 2f8039d..0000000 --- a/3rdparty/libopencv/include/opencv2/core.hpp +++ /dev/null @@ -1,3265 +0,0 @@ -/*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_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_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 - @} - @} -@} - */ - -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(); - 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 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 -}; - -//! type of line -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 -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 -}; - -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 copyMakeBorder_demo.cpp -An example using copyMakeBorder function - */ -/** @brief Forms a border around an image. - -The function copies the source image into the middle of the destination image. The areas to the -left, to the right, above and below the copied source image will be filled with extrapolated -pixels. This is not what filtering functions based on it do (they extrapolate pixels on-fly), but -what other more complex functions, including your own, may do to simplify image boundary handling. - -The function supports the mode when src is already in the middle of dst . In this case, the -function does not copy src itself but simply constructs the border, for example: - -@code{.cpp} - // let border be the same in all directions - int border=2; - // constructs a larger image to fit both the image and the border - Mat gray_buf(rgb.rows + border*2, rgb.cols + border*2, rgb.depth()); - // select the middle part of it w/o copying data - Mat gray(gray_canvas, Rect(border, border, rgb.cols, rgb.rows)); - // convert image from RGB to grayscale - cvtColor(rgb, gray, COLOR_RGB2GRAY); - // form a border in-place - copyMakeBorder(gray, gray_buf, border, border, - border, border, BORDER_REPLICATE); - // now do some custom filtering ... - ... -@endcode -@note When the source image is a part (ROI) of a bigger image, the function will try to use the -pixels outside of the ROI to form a border. To disable this feature and always do extrapolation, as -if src was not a ROI, use borderType | #BORDER_ISOLATED. - -@param src Source image. -@param dst Destination image of the same type as src and the size Size(src.cols+left+right, -src.rows+top+bottom) . -@param top -@param bottom -@param left -@param right Parameter specifying how many pixels in each direction from the source image rectangle -to extrapolate. For example, top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs -to be built. -@param borderType Border type. See borderInterpolate for details. -@param value Border value if borderType==BORDER_CONSTANT . - -@sa borderInterpolate -*/ -CV_EXPORTS_W void copyMakeBorder(InputArray src, OutputArray dst, - int top, int bottom, int left, int right, - int borderType, const Scalar& value = Scalar() ); - -/** @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] - -When src2(I) is zero, dst(I) will also be zero. Different channels of -multi-channel arrays are processed independently. - -@note Saturation is not applied when the output array has the depth CV_32S. You may even get -result of an incorrect sign in the case of overflow. -@param src1 first input array. -@param src2 second input array of the same size and type as src1. -@param scale scalar factor. -@param dst output array of the same size and type as src2. -@param dtype optional depth of the output array; if -1, dst will have depth src2.depth(), but in -case of an array-by-array division, you can only pass -1 when src1.depth()==src2.depth(). -@sa multiply, add, subtract -*/ -CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst, - double scale = 1, int dtype = -1); - -/** @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 AddingImagesTrackbar.cpp - - */ -/** @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). 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 (type CV_8UC1) -@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. Arrays must have depth CV_8U. - -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 CV_8U (255) 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. - - */ -CV_EXPORTS_W double PSNR(InputArray src1, InputArray src2); - -/** @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, //Rotate 90 degrees clockwise - ROTATE_180 = 1, //Rotate 180 degrees clockwise - ROTATE_90_COUNTERCLOCKWISE = 2, //Rotate 270 degrees clockwise -}; -/** @brief Rotates a 2D array in multiples of 90 degrees. -The function rotate rotates the array in one of three different ways: -* Rotate by 90 degrees clockwise (rotateCode = ROTATE_90). -* Rotate by 180 degrees clockwise (rotateCode = ROTATE_180). -* Rotate by 270 degrees clockwise (rotateCode = ROTATE_270). -@param src input array. -@param dst output array of the same type as src. The size is the same with ROTATE_180, -and the rows and cols are switched for ROTATE_90 and ROTATE_270. -@param rotateCode an enum to specify how to rotate the array; see the enum RotateFlags -@sa transpose , repeat , completeSymm, flip, RotateFlags -*/ -CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode); - -/** @brief Fills the output array with repeated copies of the input array. - -The function cv::repeat duplicates the input array one or more times along each of the two axes: -\f[\texttt{dst} _{ij}= \texttt{src} _{i\mod src.rows, \; j\mod src.cols }\f] -The second variant of the function is more convenient to use with @ref MatrixExpressions. -@param src input array to replicate. -@param ny Flag to specify how many times the `src` is repeated along the -vertical axis. -@param nx Flag to specify how many times the `src` is repeated along the -horizontal axis. -@param dst output array of the same type as `src`. -@sa cv::reduce -*/ -CV_EXPORTS_W void repeat(InputArray src, int ny, int nx, OutputArray dst); - -/** @overload -@param src input array to replicate. -@param ny Flag to specify how many times the `src` is repeated along the -vertical axis. -@param nx Flag to specify how many times the `src` is repeated along the -horizontal axis. - */ -CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx); - -/** @brief Applies horizontal concatenation to given matrices. - -The function horizontally concatenates two or more cv::Mat matrices (with the same number of rows). -@code{.cpp} - cv::Mat matArray[] = { 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( matArray, 3, 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 nsrc number of matrices in src. -@param dst output array. It has the same number of rows and depth as the src, and the sum of cols of the src. -@sa cv::vconcat(const Mat*, size_t, OutputArray), @sa cv::vconcat(InputArrayOfArrays, OutputArray) and @sa cv::vconcat(InputArray, InputArray, OutputArray) -*/ -CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst); -/** @overload - @code{.cpp} - cv::Mat_ 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 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() */ -CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean, - OutputArray eigenvectors, double retainedVariance); - -/** wrap PCA::project */ -CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean, - InputArray eigenvectors, OutputArray result); - -/** wrap PCA::backProject */ -CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean, - InputArray eigenvectors, OutputArray result); - -/** 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 pca.cpp - An example using %PCA for dimensionality reduction while maintaining an amount of variance - */ - -/** - @brief Linear Discriminant Analysis - @todo document this class - */ -class CV_EXPORTS LDA -{ -public: - /** @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: - bool _dataAsRow; // unused, but needed for 3.0 ABI compatibility. - 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 kmeans.cpp - An example on K-means clustering -*/ - -/** @brief Finds centers of clusters and groups input samples around the clusters. - -The function kmeans implements a k-means algorithm that finds the centers of cluster_count clusters -and groups the input samples around the clusters. As an output, \f$\texttt{labels}_i\f$ contains a -0-based cluster index for the sample stored in the \f$i^{th}\f$ row of the samples matrix. - -@note -- (Python) An example on K-means clustering can be found at - opencv_source_code/samples/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 { 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 set32fPrecision(int p = 8) = 0; - virtual void set64fPrecision(int p = 16) = 0; - virtual void setMultiline(bool ml = true) = 0; - - static Ptr get(int 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 { (void)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) { (void)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; -}; - -struct Param { - enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, - UNSIGNED_INT=8, UINT64=9, UCHAR=11 }; -}; - - - -template<> struct ParamType -{ - typedef bool const_param_type; - typedef bool member_type; - - enum { type = Param::BOOLEAN }; -}; - -template<> struct ParamType -{ - typedef int const_param_type; - typedef int member_type; - - enum { type = Param::INT }; -}; - -template<> struct ParamType -{ - typedef double const_param_type; - typedef double member_type; - - enum { type = Param::REAL }; -}; - -template<> struct ParamType -{ - typedef const String& const_param_type; - typedef String member_type; - - enum { type = Param::STRING }; -}; - -template<> struct ParamType -{ - typedef const Mat& const_param_type; - typedef Mat member_type; - - enum { type = Param::MAT }; -}; - -template<> struct ParamType > -{ - typedef const std::vector& const_param_type; - typedef std::vector member_type; - - enum { type = Param::MAT_VECTOR }; -}; - -template<> struct ParamType -{ - typedef const Ptr& const_param_type; - typedef Ptr member_type; - - enum { type = Param::ALGORITHM }; -}; - -template<> struct ParamType -{ - typedef float const_param_type; - typedef float member_type; - - enum { type = Param::FLOAT }; -}; - -template<> struct ParamType -{ - typedef unsigned const_param_type; - typedef unsigned member_type; - - enum { type = Param::UNSIGNED_INT }; -}; - -template<> struct ParamType -{ - typedef uint64 const_param_type; - typedef uint64 member_type; - - enum { type = Param::UINT64 }; -}; - -template<> struct ParamType -{ - typedef uchar const_param_type; - typedef uchar member_type; - - enum { type = Param::UCHAR }; -}; - -//! @} 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/3rdparty/libopencv/include/opencv2/core/affine.hpp b/3rdparty/libopencv/include/opencv2/core/affine.hpp deleted file mode 100644 index 66853a7..0000000 --- a/3rdparty/libopencv/include/opencv2/core/affine.hpp +++ /dev/null @@ -1,678 +0,0 @@ -/*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_Assert(!"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/3rdparty/libopencv/include/opencv2/core/base.hpp b/3rdparty/libopencv/include/opencv2/core/base.hpp deleted file mode 100644 index 61144e9..0000000 --- a/3rdparty/libopencv/include/opencv2/core/base.hpp +++ /dev/null @@ -1,762 +0,0 @@ -/*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_L2}\) } - \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 -//! @{ - -//! @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 - -#if defined __GNUC__ && !defined __EXCEPTIONS -#define CV_TRY -#define CV_CATCH(A, B) for (A B; false; ) -#define CV_CATCH_ALL if (false) -#define CV_THROW(A) abort() -#define CV_RETHROW() abort() -#else -#define CV_TRY try -#define CV_CATCH(A, B) catch(const A & B) -#define CV_CATCH_ALL catch(...) -#define CV_THROW(A) throw A -#define CV_RETHROW() throw -#endif - -//! @endcond - -/*! @brief Signals an error and raises the exception. - -By default the function prints information about the error to stderr, -then it either stops if setBreakOnError() had been called before or raises the exception. -It is possible to alternate error processing by using redirectError(). -@param _code - error code (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_ErrorNoReturn, CV_ErrorNoReturn_, CV_Assert, CV_DbgAssert - */ -CV_EXPORTS void error(int _code, const String& _err, const char* _func, const char* _file, int _line); - -#ifdef __GNUC__ -# if defined __clang__ || defined __APPLE__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Winvalid-noreturn" -# endif -#endif - -/** same as cv::error, but does not return */ -CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const char* _func, const char* _file, int _line) -{ - error(_code, _err, _func, _file, _line); -#ifdef __GNUC__ -# if !defined __clang__ && !defined __APPLE__ - // this suppresses this warning: "noreturn" function does return [enabled by default] - __builtin_trap(); - // or use infinite loop: for (;;) {} -# endif -#endif -} -#ifdef __GNUC__ -# if defined __clang__ || defined __APPLE__ -# pragma GCC diagnostic pop -# endif -#endif - -#if defined __GNUC__ -#define CV_Func __func__ -#elif defined _MSC_VER -#define CV_Func __FUNCTION__ -#else -#define CV_Func "" -#endif - -#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(...) do { abort(); } while (0) -#define CV_Error_( code, args ) do { cv::format args; abort(); } while (0) -#define CV_ErrorNoReturn(...) do { abort(); } while (0) -#define CV_ErrorNoReturn_(...) do { abort(); } while (0) -#define CV_Assert_1( 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_( CV_StsOutOfRange, - ("the value at (%d, %d)=%g is out of range", badPt.x, badPt.y, badValue)); -@endcode -@param code one of Error::Code -@param args printf-like formatted error message in parentheses -*/ -#define CV_Error_( code, args ) cv::error( code, cv::format args, CV_Func, __FILE__, __LINE__ ) - -/** same as CV_Error(code,msg), but does not return */ -#define CV_ErrorNoReturn( code, msg ) cv::errorNoReturn( code, msg, CV_Func, __FILE__, __LINE__ ) - -/** same as CV_Error_(code,args), but does not return */ -#define CV_ErrorNoReturn_( code, args ) cv::errorNoReturn( code, cv::format args, CV_Func, __FILE__, __LINE__ ) - -#define CV_Assert_1( expr ) if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ ) - -#endif // CV_STATIC_ANALYSIS - -#define CV_Assert_2( expr1, expr2 ) CV_Assert_1(expr1); CV_Assert_1(expr2) -#define CV_Assert_3( expr1, expr2, expr3 ) CV_Assert_2(expr1, expr2); CV_Assert_1(expr3) -#define CV_Assert_4( expr1, expr2, expr3, expr4 ) CV_Assert_3(expr1, expr2, expr3); CV_Assert_1(expr4) -#define CV_Assert_5( expr1, expr2, expr3, expr4, expr5 ) CV_Assert_4(expr1, expr2, expr3, expr4); CV_Assert_1(expr5) -#define CV_Assert_6( expr1, expr2, expr3, expr4, expr5, expr6 ) CV_Assert_5(expr1, expr2, expr3, expr4, expr5); CV_Assert_1(expr6) -#define CV_Assert_7( expr1, expr2, expr3, expr4, expr5, expr6, expr7 ) CV_Assert_6(expr1, expr2, expr3, expr4, expr5, expr6 ); CV_Assert_1(expr7) -#define CV_Assert_8( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8 ) CV_Assert_7(expr1, expr2, expr3, expr4, expr5, expr6, expr7 ); CV_Assert_1(expr8) -#define CV_Assert_9( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9 ) CV_Assert_8(expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8 ); CV_Assert_1(expr9) -#define CV_Assert_10( expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9, expr10 ) CV_Assert_9(expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8, expr9 ); CV_Assert_1(expr10) - -#define CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N -#define CV_VA_NUM_ARGS(...) CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) - -/** @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(...) do { CVAUX_CONCAT(CV_Assert_, CV_VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__); } while(0) - -/** replaced with CV_Assert(expr) in Debug configuration */ -#ifdef _DEBUG -# define CV_DbgAssert(expr) CV_Assert(expr) -#else -# 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 -{ - enum { 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 -{ -#if OPENCV_ABI_COMPATIBILITY > 300 -CV_EXPORTS unsigned long long getIppFeatures(); -#else -CV_EXPORTS int getIppFeatures(); -#endif -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 to much direct or indirect impact on accuracy tests. -CV_EXPORTS_W bool useIPP_NE(); -CV_EXPORTS_W void setUseIPP_NE(bool flag); - -} // ipp - -//! @endcond - -//! @} core_utils - - - - -} // cv - -#include "opencv2/core/neon_utils.hpp" -#include "opencv2/core/vsx_utils.hpp" - -#endif //OPENCV_CORE_BASE_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/bufferpool.hpp b/3rdparty/libopencv/include/opencv2/core/bufferpool.hpp deleted file mode 100644 index 4698e5d..0000000 --- a/3rdparty/libopencv/include/opencv2/core/bufferpool.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// 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/3rdparty/libopencv/include/opencv2/core/core.hpp b/3rdparty/libopencv/include/opencv2/core/core.hpp deleted file mode 100644 index 4389183..0000000 --- a/3rdparty/libopencv/include/opencv2/core/core.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/core_c.h b/3rdparty/libopencv/include/opencv2/core/core_c.h deleted file mode 100644 index c8c9d2e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/core_c.h +++ /dev/null @@ -1,3184 +0,0 @@ -/*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 simulteneously - (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 * -\****************************************************************************************/ - -/********************************** 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 three ways -are the same: -@snippet samples/cpp/filestorage_base64.cpp suffix_in_file_name -@snippet samples/cpp/filestorage_base64.cpp flag_write_base64 -@snippet samples/cpp/filestorage_base64.cpp flag_write_and_flag_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". - -Consider the following two examples where their output is the same: -@snippet samples/cpp/filestorage_base64.cpp without_base64_flag -and -@snippet samples/cpp/filestorage_base64.cpp with_write_base64_flag - -@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 ); - -/** @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 ); - -/** @brief Saves an object to a file. - -The function saves an object to a file. It provides a simple interface to cvWrite . -@param filename File name -@param struct_ptr Object to save -@param name Optional object name. If it is NULL, the name will be formed from filename . -@param comment Optional comment to put in the beginning of the file -@param attributes Optional attributes passed to cvWrite - */ -CVAPI(void) cvSave( const char* filename, const void* struct_ptr, - const char* name CV_DEFAULT(NULL), - const char* comment CV_DEFAULT(NULL), - CvAttrList attributes CV_DEFAULT(cvAttrList())); - -/** @brief Loads an object from a file. - -The function loads an object from a file. It basically reads the specified file, find the first -top-level node and calls cvRead for that node. If the file node does not have type information or -the type information can not be found by the type name, the function returns NULL. After the object -is loaded, the file storage is closed and all the temporary buffers are deleted. Thus, to load a -dynamic structure, such as a sequence, contour, or graph, one should pass a valid memory storage -destination to the function. -@param filename File name -@param memstorage Memory storage for dynamic structures, such as CvSeq or CvGraph . It is not used -for matrices or images. -@param name Optional object name. If it is NULL, the first top-level object in the storage will be -loaded. -@param real_name Optional output parameter that will contain the name of the loaded object -(useful if name=NULL ) - */ -CVAPI(void*) cvLoad( const char* filename, - CvMemStorage* memstorage CV_DEFAULT(NULL), - const char* name CV_DEFAULT(NULL), - const char** real_name CV_DEFAULT(NULL) ); - -/*********************************** 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 - -//! @addtogroup core_c_glue -//! @{ - -//! class for automatic module/RTTI data registration/unregistration -struct CV_EXPORTS CvType -{ - CvType( const char* type_name, - CvIsInstanceFunc is_instance, CvReleaseFunc release=0, - CvReadFunc read=0, CvWriteFunc write=0, CvCloneFunc clone=0 ); - ~CvType(); - CvTypeInfo* info; - - static CvTypeInfo* first; - static CvTypeInfo* last; -}; - -//! @} - -#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<> CV_EXPORTS void DefaultDeleter::operator ()(CvMat* obj) const; -template<> CV_EXPORTS void DefaultDeleter::operator ()(IplImage* obj) const; -template<> CV_EXPORTS void DefaultDeleter::operator ()(CvMatND* obj) const; -template<> CV_EXPORTS void DefaultDeleter::operator ()(CvSparseMat* obj) const; -template<> CV_EXPORTS void DefaultDeleter::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], 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/3rdparty/libopencv/include/opencv2/core/cuda.hpp b/3rdparty/libopencv/include/opencv2/core/cuda.hpp deleted file mode 100644 index e6cb79e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda.hpp +++ /dev/null @@ -1,1015 +0,0 @@ -/*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. - -@sa Mat - */ -class CV_EXPORTS GpuMat -{ -public: - class CV_EXPORTS 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 - static Allocator* defaultAllocator(); - static void setDefaultAllocator(Allocator* allocator); - - //! default constructor - explicit GpuMat(Allocator* allocator = defaultAllocator()); - - //! constructs GpuMat of the specified size and type - GpuMat(int rows, int cols, int type, Allocator* allocator = defaultAllocator()); - GpuMat(Size size, int type, Allocator* allocator = defaultAllocator()); - - //! constucts GpuMat and fills it with the specified value _s - GpuMat(int rows, int cols, int type, Scalar s, Allocator* allocator = defaultAllocator()); - GpuMat(Size size, int type, Scalar s, Allocator* allocator = defaultAllocator()); - - //! copy constructor - 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 - GpuMat(const GpuMat& m, Range rowRange, Range colRange); - GpuMat(const GpuMat& m, Rect roi); - - //! builds GpuMat from host memory (Blocking call) - explicit GpuMat(InputArray arr, Allocator* allocator = 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 - void create(int rows, int cols, int type); - void create(Size size, int type); - - //! decreases reference counter, deallocate the data when reference counter reaches 0 - void release(); - - //! swaps with other smart pointer - void swap(GpuMat& mat); - - //! pefroms upload data to GpuMat (Blocking call) - void upload(InputArray arr); - - //! pefroms upload data to GpuMat (Non-Blocking call) - void upload(InputArray arr, Stream& stream); - - //! pefroms download data from device to host memory (Blocking call) - void download(OutputArray dst) const; - - //! pefroms download data from device to host memory (Non-Blocking call) - void download(OutputArray dst, Stream& stream) const; - - //! returns deep copy of the GpuMat, i.e. the data is copied - GpuMat clone() const; - - //! copies the GpuMat content to device memory (Blocking call) - void copyTo(OutputArray dst) const; - - //! copies the GpuMat content to device memory (Non-Blocking call) - void copyTo(OutputArray dst, Stream& stream) const; - - //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Blocking call) - void copyTo(OutputArray dst, InputArray mask) const; - - //! copies those GpuMat elements to "m" that are marked with non-zero mask elements (Non-Blocking call) - void copyTo(OutputArray dst, InputArray mask, Stream& stream) const; - - //! sets some of the GpuMat elements to s (Blocking call) - GpuMat& setTo(Scalar s); - - //! sets some of the GpuMat elements to s (Non-Blocking call) - GpuMat& setTo(Scalar s, Stream& stream); - - //! sets some of the GpuMat elements to s, according to the mask (Blocking call) - GpuMat& setTo(Scalar s, InputArray mask); - - //! sets some of the GpuMat elements to s, according to the mask (Non-Blocking call) - GpuMat& setTo(Scalar s, InputArray mask, Stream& stream); - - //! converts GpuMat to another datatype (Blocking call) - void convertTo(OutputArray dst, int rtype) const; - - //! converts GpuMat to another datatype (Non-Blocking call) - void convertTo(OutputArray dst, int rtype, Stream& stream) const; - - //! converts GpuMat to another datatype with scaling (Blocking call) - void convertTo(OutputArray dst, int rtype, double alpha, double beta = 0.0) const; - - //! converts GpuMat to another datatype with scaling (Non-Blocking call) - void convertTo(OutputArray dst, int rtype, double alpha, Stream& stream) const; - - //! converts GpuMat to another datatype with scaling (Non-Blocking call) - void convertTo(OutputArray dst, int rtype, double alpha, double beta, Stream& stream) const; - - 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 - GpuMat row(int y) const; - - //! returns a new GpuMat header for the specified column - GpuMat col(int x) const; - - //! ... for the specified row span - GpuMat rowRange(int startrow, int endrow) const; - GpuMat rowRange(Range r) const; - - //! ... for the specified column span - GpuMat colRange(int startcol, int endcol) const; - 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 - GpuMat reshape(int cn, int rows = 0) const; - - //! locates GpuMat header within a parent GpuMat - void locateROI(Size& wholeSize, Point& ofs) const; - - //! moves/resizes the current GpuMat ROI inside the parent GpuMat - 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) - bool isContinuous() const; - - //! returns element size in bytes - size_t elemSize() const; - - //! returns the size of element channel in bytes - size_t elemSize1() const; - - //! returns element type - int type() const; - - //! returns element type - int depth() const; - - //! returns number of channels - int channels() const; - - //! returns step/elemSize1() - size_t step1() const; - - //! returns GpuMat size : width == number of columns, height == number of rows - Size size() const; - - //! returns true if GpuMat data is NULL - bool empty() const; - - /*! 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 - 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 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 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 BufferPool -{ -public: - - //! Gets the BufferPool for the given stream. - explicit BufferPool(Stream& stream); - - //! Allocates a new GpuMat of given size and type. - GpuMat getBuffer(int rows, int cols, int type); - - //! Allocates a new GpuMat of given size and type. - GpuMat getBuffer(Size size, int type) { return getBuffer(size.height, size.width, type); } - - //! Returns the allocator associated with the stream. - Ptr getAllocator() const { return allocator_; } - -private: - Ptr allocator_; -}; - -//! BufferPool management (must be called before Stream creation) -CV_EXPORTS void setBufferPoolUsage(bool on); -CV_EXPORTS 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 HostMem -{ -public: - enum AllocType { PAGE_LOCKED = 1, SHARED = 2, WRITE_COMBINED = 4 }; - - static MatAllocator* getAllocator(AllocType alloc_type = PAGE_LOCKED); - - explicit HostMem(AllocType alloc_type = PAGE_LOCKED); - - HostMem(const HostMem& m); - - HostMem(int rows, int cols, int type, AllocType alloc_type = PAGE_LOCKED); - HostMem(Size size, int type, AllocType alloc_type = PAGE_LOCKED); - - //! creates from host memory with coping data - explicit HostMem(InputArray arr, AllocType alloc_type = PAGE_LOCKED); - - ~HostMem(); - - HostMem& operator =(const HostMem& m); - - //! swaps with other smart pointer - void swap(HostMem& b); - - //! returns deep copy of the matrix, i.e. the data is copied - HostMem clone() const; - - //! allocates new matrix data unless the matrix already has specified size and type. - 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 - 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. - 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 - bool isContinuous() const; - size_t elemSize() const; - size_t elemSize1() const; - int type() const; - int depth() const; - int channels() const; - size_t step1() const; - Size size() const; - bool empty() const; - - // Please see cv::Mat for descriptions - int flags; - int rows, cols; - 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 void registerPageLocked(Mat& m); - -/** @brief Unmaps the memory of matrix and makes it pageable again. - -@param m Input matrix. - */ -CV_EXPORTS 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 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 - Stream(); - - //! creates a new asynchronous stream with custom allocator - Stream(const Ptr& allocator); - - /** @brief Returns true if the current stream queue is finished. Otherwise, it returns false. - */ - bool queryIfComplete() const; - - /** @brief Blocks the current CPU thread until all operations in the stream are complete. - */ - void waitForCompletion(); - - /** @brief Makes a compute stream wait on an event. - */ - 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 - 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 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 */ - }; - - explicit Event(CreateFlags flags = DEFAULT); - - //! records an event - void record(Stream& stream = Stream::Null()); - - //! queries an event's status - bool queryIfComplete() const; - - //! waits for an event to complete - void waitForCompletion(); - - //! computes the elapsed time between events - 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 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 void setDevice(int device); - -/** @brief Returns the current device index set by cuda::setDevice or initialized by default. - */ -CV_EXPORTS 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 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 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. - */ - static bool has(int major, int minor); - static bool hasPtx(int major, int minor); - static bool hasBin(int major, int minor); - - static bool hasEqualOrLessPtx(int major, int minor); - static bool hasEqualOrGreater(int major, int minor); - static bool hasEqualOrGreaterPtx(int major, int minor); - static bool hasEqualOrGreaterBin(int major, int minor); -}; - -/** @brief Class providing functionality for querying the specified GPU properties. - */ -class CV_EXPORTS DeviceInfo -{ -public: - //! creates DeviceInfo object for the current GPU - 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. - */ - DeviceInfo(int device_id); - - /** @brief Returns system index of the CUDA device starting with 0. - */ - int deviceID() const; - - //! ASCII string identifying device - const char* name() const; - - //! global memory available on device in bytes - size_t totalGlobalMem() const; - - //! shared memory available per block in bytes - size_t sharedMemPerBlock() const; - - //! 32-bit registers available per block - int regsPerBlock() const; - - //! warp size in threads - int warpSize() const; - - //! maximum pitch in bytes allowed by memory copies - size_t memPitch() const; - - //! maximum number of threads per block - int maxThreadsPerBlock() const; - - //! maximum size of each dimension of a block - Vec3i maxThreadsDim() const; - - //! maximum size of each dimension of a grid - Vec3i maxGridSize() const; - - //! clock frequency in kilohertz - int clockRate() const; - - //! constant memory available on device in bytes - size_t totalConstMem() const; - - //! major compute capability - int majorVersion() const; - - //! minor compute capability - int minorVersion() const; - - //! alignment requirement for textures - size_t textureAlignment() const; - - //! pitch alignment requirement for texture references bound to pitched memory - size_t texturePitchAlignment() const; - - //! number of multiprocessors on device - int multiProcessorCount() const; - - //! specified whether there is a run time limit on kernels - bool kernelExecTimeoutEnabled() const; - - //! device is integrated as opposed to discrete - bool integrated() const; - - //! device can map host memory with cudaHostAlloc/cudaHostGetDevicePointer - 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 - ComputeMode computeMode() const; - - //! maximum 1D texture size - int maxTexture1D() const; - - //! maximum 1D mipmapped texture size - int maxTexture1DMipmap() const; - - //! maximum size for 1D textures bound to linear memory - int maxTexture1DLinear() const; - - //! maximum 2D texture dimensions - Vec2i maxTexture2D() const; - - //! maximum 2D mipmapped texture dimensions - Vec2i maxTexture2DMipmap() const; - - //! maximum dimensions (width, height, pitch) for 2D textures bound to pitched memory - Vec3i maxTexture2DLinear() const; - - //! maximum 2D texture dimensions if texture gather operations have to be performed - Vec2i maxTexture2DGather() const; - - //! maximum 3D texture dimensions - Vec3i maxTexture3D() const; - - //! maximum Cubemap texture dimensions - int maxTextureCubemap() const; - - //! maximum 1D layered texture dimensions - Vec2i maxTexture1DLayered() const; - - //! maximum 2D layered texture dimensions - Vec3i maxTexture2DLayered() const; - - //! maximum Cubemap layered texture dimensions - Vec2i maxTextureCubemapLayered() const; - - //! maximum 1D surface size - int maxSurface1D() const; - - //! maximum 2D surface dimensions - Vec2i maxSurface2D() const; - - //! maximum 3D surface dimensions - Vec3i maxSurface3D() const; - - //! maximum 1D layered surface dimensions - Vec2i maxSurface1DLayered() const; - - //! maximum 2D layered surface dimensions - Vec3i maxSurface2DLayered() const; - - //! maximum Cubemap surface dimensions - int maxSurfaceCubemap() const; - - //! maximum Cubemap layered surface dimensions - Vec2i maxSurfaceCubemapLayered() const; - - //! alignment requirements for surfaces - size_t surfaceAlignment() const; - - //! device can possibly execute multiple kernels concurrently - bool concurrentKernels() const; - - //! device has ECC support enabled - bool ECCEnabled() const; - - //! PCI bus ID of the device - int pciBusID() const; - - //! PCI device ID of the device - int pciDeviceID() const; - - //! PCI domain ID of the device - int pciDomainID() const; - - //! true if device is a Tesla device using TCC driver, false otherwise - bool tccDriver() const; - - //! number of asynchronous engines - int asyncEngineCount() const; - - //! device shares a unified address space with the host - bool unifiedAddressing() const; - - //! peak memory clock frequency in kilohertz - int memoryClockRate() const; - - //! global memory bus width in bits - int memoryBusWidth() const; - - //! size of L2 cache in bytes - int l2CacheSize() const; - - //! maximum resident threads per multiprocessor - int maxThreadsPerMultiProcessor() const; - - //! gets free and total device memory - void queryMemory(size_t& totalMemory, size_t& freeMemory) const; - size_t freeMemory() const; - 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 . - */ - bool isCompatible() const; - -private: - int device_id_; -}; - -CV_EXPORTS void printCudaDeviceInfo(int device); -CV_EXPORTS 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/3rdparty/libopencv/include/opencv2/core/cuda.inl.hpp b/3rdparty/libopencv/include/opencv2/core/cuda.inl.hpp deleted file mode 100644 index 35ae2e4..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda.inl.hpp +++ /dev/null @@ -1,631 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/block.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/block.hpp deleted file mode 100644 index c277f0e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/block.hpp +++ /dev/null @@ -1,211 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/border_interpolate.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/border_interpolate.hpp deleted file mode 100644 index 874f705..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/border_interpolate.hpp +++ /dev/null @@ -1,722 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/color.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/color.hpp deleted file mode 100644 index dcce280..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/color.hpp +++ /dev/null @@ -1,309 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/common.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/common.hpp deleted file mode 100644 index 14b1f3f..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/common.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/datamov_utils.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/datamov_utils.hpp deleted file mode 100644 index 6820d0f..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/datamov_utils.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/detail/color_detail.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/detail/color_detail.hpp deleted file mode 100644 index bfb4055..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/detail/color_detail.hpp +++ /dev/null @@ -1,1980 +0,0 @@ -/*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; - } - - enum - { - yuv_shift = 14, - xyz_shift = 12, - R2Y = 4899, - G2Y = 9617, - B2Y = 1868, - 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) * B2Y + ((t >> 3) & 0xfc) * G2Y + ((t >> 8) & 0xf8) * R2Y, yuv_shift); - } - }; - - template <> struct RGB5x52GrayConverter<5> - { - static __device__ __forceinline__ uchar cvt(uint t) - { - return (uchar)CV_DESCALE(((t << 3) & 0xf8) * B2Y + ((t >> 2) & 0xf8) * G2Y + ((t >> 7) & 0xf8) * R2Y, yuv_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] * B2Y + src[1] * G2Y + src[bidx^2] * R2Y), yuv_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 * B2Y + g * G2Y + r * R2Y), yuv_shift); - } - - template static __device__ __forceinline__ float RGB2GrayConvert(const float* src) - { - return src[bidx] * 0.114f + src[1] * 0.587f + src[bidx^2] * 0.299f; - } - - 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] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; - __constant__ int c_RGB2YUVCoeffs_i[5] = { B2Y, G2Y, R2Y, 8061, 14369 }; - - 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] = { 2.032f, -0.395f, -0.581f, 1.140f }; - __constant__ int c_YUV2RGBCoeffs_i[5] = { 33292, -6472, -9519, 18678 }; - - 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] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f}; - __constant__ int c_RGB2YCrCbCoeffs_i[5] = {R2Y, G2Y, B2Y, 11682, 9241}; - - 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] = {1.403f, -0.714f, -0.344f, 1.773f}; - __constant__ int c_YCrCb2RGBCoeffs_i[5] = {22987, -11698, -5636, 29049}; - - 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/3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce.hpp deleted file mode 100644 index ff82c3c..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce.hpp +++ /dev/null @@ -1,365 +0,0 @@ -/*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 - (void) smem; - (void) 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/3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp deleted file mode 100644 index 6a537c9..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/detail/reduce_key_val.hpp +++ /dev/null @@ -1,502 +0,0 @@ -/*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 - (void) skeys; - (void) svals; - (void) 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/3rdparty/libopencv/include/opencv2/core/cuda/detail/transform_detail.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/detail/transform_detail.hpp deleted file mode 100644 index 3b72b03..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/detail/transform_detail.hpp +++ /dev/null @@ -1,399 +0,0 @@ -/*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]; - write_type dst_n_el = ((const write_type*)dst)[x]; - - OpUnroller::unroll(src_n_el, dst_n_el, mask, op, x_shifted, y); - - ((write_type*)dst)[x] = dst_n_el; - } - 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]; - write_type dst_n_el = ((const write_type*)dst)[x]; - - OpUnroller::unroll(src1_n_el, src2_n_el, dst_n_el, mask, op, x_shifted, y); - - ((write_type*)dst)[x] = dst_n_el; - } - 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/3rdparty/libopencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp deleted file mode 100644 index a78bd2c..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/detail/type_traits_detail.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp deleted file mode 100644 index 8283a99..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/detail/vec_distance_detail.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/dynamic_smem.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/dynamic_smem.hpp deleted file mode 100644 index 42570c6..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/dynamic_smem.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/emulation.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/emulation.hpp deleted file mode 100644 index d346865..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/emulation.hpp +++ /dev/null @@ -1,269 +0,0 @@ -/*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 - (void) address; - (void) 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 - (void) address; - (void) 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 - (void) address; - (void) 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 - (void) address; - (void) 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 - (void) address; - (void) val; - return 0.0; - #endif - } - }; - }; //struct Emulation -}}} // namespace cv { namespace cuda { namespace cudev - -//! @endcond - -#endif /* OPENCV_CUDA_EMULATION_HPP_ */ diff --git a/3rdparty/libopencv/include/opencv2/core/cuda/filters.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/filters.hpp deleted file mode 100644 index c2e24dd..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/filters.hpp +++ /dev/null @@ -1,286 +0,0 @@ -/*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_) - { - (void)fx; - (void)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_) - { - (void)fx; - (void)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_) - { - (void)fx; - (void)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/3rdparty/libopencv/include/opencv2/core/cuda/funcattrib.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/funcattrib.hpp deleted file mode 100644 index f582080..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/funcattrib.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/functional.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/functional.hpp deleted file mode 100644 index b28f7a5..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/functional.hpp +++ /dev/null @@ -1,811 +0,0 @@ -/*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" -#include "device_functions.h" - -/** @file - * @deprecated Use @ref cudev instead. - */ - -//! @cond IGNORED - -namespace cv { namespace cuda { namespace device -{ - // Function Objects -#ifdef CV_CXX11 - 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; - }; -#else - template struct unary_function : public std::unary_function {}; - template struct binary_function : public std::binary_function {}; -#endif - - // 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_) {(void)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_) {(void)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_) {(void)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/3rdparty/libopencv/include/opencv2/core/cuda/limits.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/limits.hpp deleted file mode 100644 index 7e15ed6..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/limits.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/reduce.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/reduce.hpp deleted file mode 100644 index 5de3650..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/reduce.hpp +++ /dev/null @@ -1,209 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/saturate_cast.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/saturate_cast.hpp deleted file mode 100644 index c3a3d1c..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/saturate_cast.hpp +++ /dev/null @@ -1,292 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/scan.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/scan.hpp deleted file mode 100644 index e07ee65..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/scan.hpp +++ /dev/null @@ -1,258 +0,0 @@ -/*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) { (void)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) { (void)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) { (void)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/3rdparty/libopencv/include/opencv2/core/cuda/simd_functions.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/simd_functions.hpp deleted file mode 100644 index 3d8c2e0..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/simd_functions.hpp +++ /dev/null @@ -1,869 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/transform.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/transform.hpp deleted file mode 100644 index 42aa6ea..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/transform.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/type_traits.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/type_traits.hpp deleted file mode 100644 index 8b7a3fd..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/type_traits.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/utility.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/utility.hpp deleted file mode 100644 index 7f5db48..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/utility.hpp +++ /dev/null @@ -1,230 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/vec_distance.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/vec_distance.hpp deleted file mode 100644 index ef6e510..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/vec_distance.hpp +++ /dev/null @@ -1,232 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/vec_math.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/vec_math.hpp deleted file mode 100644 index 9085b92..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/vec_math.hpp +++ /dev/null @@ -1,930 +0,0 @@ -/*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, /*::abs*/, uchar, uchar) -CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::abs, char, char) -CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, ushort, ushort) -CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::abs, short, short) -CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::abs, int, int) -CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, uint, uint) -CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::fabsf, float, float) -CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::fabs, double, double) - -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/3rdparty/libopencv/include/opencv2/core/cuda/vec_traits.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/vec_traits.hpp deleted file mode 100644 index b5ff281..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/vec_traits.hpp +++ /dev/null @@ -1,288 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/warp.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/warp.hpp deleted file mode 100644 index 8af7e6a..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/warp.hpp +++ /dev/null @@ -1,139 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/warp_reduce.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/warp_reduce.hpp deleted file mode 100644 index 530303d..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/warp_reduce.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda/warp_shuffle.hpp b/3rdparty/libopencv/include/opencv2/core/cuda/warp_shuffle.hpp deleted file mode 100644 index 0da54ae..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda/warp_shuffle.hpp +++ /dev/null @@ -1,162 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda_stream_accessor.hpp b/3rdparty/libopencv/include/opencv2/core/cuda_stream_accessor.hpp deleted file mode 100644 index deaf356..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda_stream_accessor.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/cuda_types.hpp b/3rdparty/libopencv/include/opencv2/core/cuda_types.hpp deleted file mode 100644 index f13a847..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cuda_types.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/*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 - -/** @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 PtrStepSzf; - typedef PtrStepSz PtrStepSzi; - - typedef PtrStep PtrStepb; - typedef PtrStep PtrStepf; - typedef PtrStep PtrStepi; - - } -} - -//! @endcond - -#endif /* OPENCV_CORE_CUDA_TYPES_HPP */ diff --git a/3rdparty/libopencv/include/opencv2/core/cv_cpu_dispatch.h b/3rdparty/libopencv/include/opencv2/core/cv_cpu_dispatch.h deleted file mode 100644 index bb0fed4..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cv_cpu_dispatch.h +++ /dev/null @@ -1,239 +0,0 @@ -// 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 } -#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_SKX -# include -# define CV_AVX512_SKX 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 - -#if defined(__VSX__) && defined(__PPC64__) && defined(__LITTLE_ENDIAN__) -# include -# undef vector -# undef pixel -# undef bool -# define CV_VSX 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(); } -}; -#define __CV_AVX_GUARD VZeroUpperGuard __vzeroupper_guard; (void)__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_512IFMA512 -# define CV_AVX_512IFMA512 0 -#endif -#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_AVX512_SKX -# define CV_AVX512_SKX 0 -#endif - -#ifndef CV_NEON -# define CV_NEON 0 -#endif - -#ifndef CV_VSX -# define CV_VSX 0 -#endif diff --git a/3rdparty/libopencv/include/opencv2/core/cv_cpu_helper.h b/3rdparty/libopencv/include/opencv2/core/cv_cpu_helper.h deleted file mode 100644 index 385617d..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cv_cpu_helper.h +++ /dev/null @@ -1,274 +0,0 @@ -// 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_SKX -# define CV_TRY_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_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_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_NEON -# define CV_TRY_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_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_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_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_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_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__)) - -#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/3rdparty/libopencv/include/opencv2/core/cvdef.h b/3rdparty/libopencv/include/opencv2/core/cvdef.h deleted file mode 100644 index c073d65..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cvdef.h +++ /dev/null @@ -1,501 +0,0 @@ -/*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 - - -// 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 - -#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_NEON 100 - -#define CV_CPU_VSX 200 - -// CPU features groups -#define CV_CPU_AVX512_SKX 256 - -// 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_NEON = 100, - - CPU_VSX = 200, - - CPU_AVX512_SKX = 256, //!< Skylake-X with AVX-512F/CD/BW/DQ/VL - - 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; -#if CV_FP16_TYPE - __fp16 h; -#endif - struct _fp16Format - { - unsigned int significand : 10; - unsigned int exponent : 5; - unsigned int sign : 1; - } fmt; -} -Cv16suf; - -typedef union Cv32suf -{ - int i; - unsigned u; - float f; - struct _fp32Format - { - unsigned int significand : 23; - unsigned int exponent : 8; - unsigned int sign : 1; - } fmt; -} -Cv32suf; - -typedef union Cv64suf -{ - int64 i; - uint64 u; - double f; -} -Cv64suf; - -#define OPENCV_ABI_COMPATIBILITY 300 - -#ifdef __OPENCV_BUILD -# define DISABLE_OPENCV_24_COMPATIBILITY -#endif - -#ifdef CVAPI_EXPORTS -# if (defined _WIN32 || defined WINCE || defined __CYGWIN__) -# define CV_EXPORTS __declspec(dllexport) -# elif defined __GNUC__ && __GNUC__ >= 4 -# 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_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) - -/****************************************************************************************\ -* 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, - 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) - -/** 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 MIN -# define MIN(a,b) ((a) > (b) ? (b) : (a)) -#endif - -#ifndef MAX -# define MAX(a,b) ((a) < (b) ? (b) : (a)) -#endif - -/****************************************************************************************\ -* 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 -# 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__) -# 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 - - -/****************************************************************************************\ -* 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 - - -/****************************************************************************************\ -* C++ Move semantics * -\****************************************************************************************/ - -#ifndef CV_CXX_MOVE_SEMANTICS -# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && _MSC_VER >= 1600) -# define CV_CXX_MOVE_SEMANTICS 1 -# elif defined(__clang) -# if __has_feature(cxx_rvalue_references) -# define CV_CXX_MOVE_SEMANTICS 1 -# endif -# endif -#else -# if CV_CXX_MOVE_SEMANTICS == 0 -# undef CV_CXX_MOVE_SEMANTICS -# endif -#endif - -/****************************************************************************************\ -* C++11 std::array * -\****************************************************************************************/ - -#ifndef CV_CXX_STD_ARRAY -# if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900/*MSVS 2015*/) -# define CV_CXX_STD_ARRAY 1 -# include -# endif -#else -# if CV_CXX_STD_ARRAY == 0 -# undef CV_CXX_STD_ARRAY -# endif -#endif - - -// Integer types portatibility -#ifdef OPENCV_STDINT_HEADER -#include OPENCV_STDINT_HEADER -#else -#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 -#endif - - -//! @} - -#endif // OPENCV_CORE_CVDEF_H diff --git a/3rdparty/libopencv/include/opencv2/core/cvstd.hpp b/3rdparty/libopencv/include/opencv2/core/cvstd.hpp deleted file mode 100644 index 0a3f553..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cvstd.hpp +++ /dev/null @@ -1,1040 +0,0 @@ -/*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; -} - -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-compilant 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 - -//! @cond IGNORED - -namespace detail -{ - -// Metafunction to avoid taking a reference to void. -template -struct RefOrVoid { typedef T& type; }; - -template<> -struct RefOrVoid{ typedef void type; }; - -template<> -struct RefOrVoid{ typedef const void type; }; - -template<> -struct RefOrVoid{ typedef volatile void type; }; - -template<> -struct RefOrVoid{ typedef const volatile void type; }; - -// This class would be private to Ptr, if it didn't have to be a non-template. -struct PtrOwner; - -} - -template -struct DefaultDeleter -{ - void operator () (Y* p) const; -}; - -//! @endcond - -//! @addtogroup core_basic -//! @{ - -/** @brief Template class for smart pointers with shared ownership - -A Ptr\ pretends to be a pointer to an object of type T. Unlike an ordinary pointer, however, the -object will be automatically cleaned up once all Ptr instances pointing to it are destroyed. - -Ptr is similar to boost::shared_ptr that is part of the Boost library -() and std::shared_ptr from -the [C++11](http://en.wikipedia.org/wiki/C++11) standard. - -This class provides the following advantages: -- Default constructor, copy constructor, and assignment operator for an arbitrary C++ class or C - structure. For some objects, like files, windows, mutexes, sockets, and others, a copy - constructor or an assignment operator are difficult to define. For some other objects, like - complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally, - some of complex OpenCV and your own data structures may be written in C. However, copy - constructors and default constructors can simplify programming a lot. Besides, they are often - required (for example, by STL containers). By using a Ptr to such an object instead of the - object itself, you automatically get all of the necessary constructors and the assignment - operator. -- *O(1)* complexity of the above-mentioned operations. While some structures, like std::vector, - provide a copy constructor and an assignment operator, the operations may take a considerable - amount of time if the data structures are large. But if the structures are put into a Ptr, the - overhead is small and independent of the data size. -- Automatic and customizable cleanup, even for C structures. See the example below with FILE\*. -- Heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers - can store only objects of the same type and the same size. The classical solution to store - objects of different types in the same container is to store pointers to the base class (Base\*) - instead but then you lose the automatic memory management. Again, by using Ptr\ instead - of raw pointers, you can solve the problem. - -A Ptr is said to *own* a pointer - that is, for each Ptr there is a pointer that will be deleted -once all Ptr instances that own it are destroyed. The owned pointer may be null, in which case -nothing is deleted. Each Ptr also *stores* a pointer. The stored pointer is the pointer the Ptr -pretends to be; that is, the one you get when you use Ptr::get or the conversion to T\*. It's -usually the same as the owned pointer, but if you use casts or the general shared-ownership -constructor, the two may diverge: the Ptr will still own the original pointer, but will itself point -to something else. - -The owned pointer is treated as a black box. The only thing Ptr needs to know about it is how to -delete it. This knowledge is encapsulated in the *deleter* - an auxiliary object that is associated -with the owned pointer and shared between all Ptr instances that own it. The default deleter is an -instance of DefaultDeleter, which uses the standard C++ delete operator; as such it will work with -any pointer allocated with the standard new operator. - -However, if the pointer must be deleted in a different way, you must specify a custom deleter upon -Ptr construction. A deleter is simply a callable object that accepts the pointer as its sole -argument. For example, if you want to wrap FILE, you may do so as follows: -@code - Ptr f(fopen("myfile.txt", "w"), fclose); - if(!f) throw ...; - fprintf(f, ....); - ... - // the file will be closed automatically by f's destructor. -@endcode -Alternatively, if you want all pointers of a particular type to be deleted the same way, you can -specialize DefaultDeleter::operator() for that type, like this: -@code - namespace cv { - template<> void DefaultDeleter::operator ()(FILE * obj) const - { - fclose(obj); - } - } -@endcode -For convenience, the following types from the OpenCV C API already have such a specialization that -calls the appropriate release function: -- CvCapture -- CvFileStorage -- CvHaarClassifierCascade -- CvMat -- CvMatND -- CvMemStorage -- CvSparseMat -- CvVideoWriter -- IplImage -@note The shared ownership mechanism is implemented with reference counting. As such, cyclic -ownership (e.g. when object a contains a Ptr to object b, which contains a Ptr to object a) will -lead to all involved objects never being cleaned up. Avoid such situations. -@note It is safe to concurrently read (but not write) a Ptr instance from multiple threads and -therefore it is normally safe to use it in multi-threaded applications. The same is true for Mat and -other C++ OpenCV classes that use internal reference counts. -*/ -template -struct Ptr -{ - /** Generic programming support. */ - typedef T element_type; - - /** The default constructor creates a null Ptr - one that owns and stores a null pointer. - */ - Ptr(); - - /** - If p is null, these are equivalent to the default constructor. - Otherwise, these constructors assume ownership of p - that is, the created Ptr owns and stores p - and assumes it is the sole owner of it. Don't use them if p is already owned by another Ptr, or - else p will get deleted twice. - With the first constructor, DefaultDeleter\() becomes the associated deleter (so p will - eventually be deleted with the standard delete operator). Y must be a complete type at the point - of invocation. - With the second constructor, d becomes the associated deleter. - Y\* must be convertible to T\*. - @param p Pointer to own. - @note It is often easier to use makePtr instead. - */ - template -#ifdef DISABLE_OPENCV_24_COMPATIBILITY - explicit -#endif - Ptr(Y* p); - - /** @overload - @param d Deleter to use for the owned pointer. - @param p Pointer to own. - */ - template - Ptr(Y* p, D d); - - /** - These constructors create a Ptr that shares ownership with another Ptr - that is, own the same - pointer as o. - With the first two, the same pointer is stored, as well; for the second, Y\* must be convertible - to T\*. - With the third, p is stored, and Y may be any type. This constructor allows to have completely - unrelated owned and stored pointers, and should be used with care to avoid confusion. A relatively - benign use is to create a non-owning Ptr, like this: - @code - ptr = Ptr(Ptr(), dont_delete_me); // owns nothing; will not delete the pointer. - @endcode - @param o Ptr to share ownership with. - */ - Ptr(const Ptr& o); - - /** @overload - @param o Ptr to share ownership with. - */ - template - Ptr(const Ptr& o); - - /** @overload - @param o Ptr to share ownership with. - @param p Pointer to store. - */ - template - Ptr(const Ptr& o, T* p); - - /** The destructor is equivalent to calling Ptr::release. */ - ~Ptr(); - - /** - Assignment replaces the current Ptr instance with one that owns and stores same pointers as o and - then destroys the old instance. - @param o Ptr to share ownership with. - */ - Ptr& operator = (const Ptr& o); - - /** @overload */ - template - Ptr& operator = (const Ptr& o); - - /** If no other Ptr instance owns the owned pointer, deletes it with the associated deleter. Then sets - both the owned and the stored pointers to NULL. - */ - void release(); - - /** - `ptr.reset(...)` is equivalent to `ptr = Ptr(...)`. - @param p Pointer to own. - */ - template - void reset(Y* p); - - /** @overload - @param d Deleter to use for the owned pointer. - @param p Pointer to own. - */ - template - void reset(Y* p, D d); - - /** - Swaps the owned and stored pointers (and deleters, if any) of this and o. - @param o Ptr to swap with. - */ - void swap(Ptr& o); - - /** Returns the stored pointer. */ - T* get() const; - - /** Ordinary pointer emulation. */ - typename detail::RefOrVoid::type operator * () const; - - /** Ordinary pointer emulation. */ - T* operator -> () const; - - /** Equivalent to get(). */ - operator T* () const; - - /** ptr.empty() is equivalent to `!ptr.get()`. */ - bool empty() const; - - /** Returns a Ptr that owns the same pointer as this, and stores the same - pointer as this, except converted via static_cast to Y*. - */ - template - Ptr staticCast() const; - - /** Ditto for const_cast. */ - template - Ptr constCast() const; - - /** Ditto for dynamic_cast. */ - template - Ptr dynamicCast() const; - -#ifdef CV_CXX_MOVE_SEMANTICS - Ptr(Ptr&& o); - Ptr& operator = (Ptr&& o); -#endif - -private: - detail::PtrOwner* owner; - T* stored; - - template - friend struct Ptr; // have to do this for the cross-type copy constructor -}; - -/** Equivalent to ptr1.swap(ptr2). Provided to help write generic algorithms. */ -template -void swap(Ptr& ptr1, Ptr& ptr2); - -/** Return whether ptr1.get() and ptr2.get() are equal and not equal, respectively. */ -template -bool operator == (const Ptr& ptr1, const Ptr& ptr2); -template -bool operator != (const Ptr& ptr1, const Ptr& ptr2); - -/** `makePtr(...)` is equivalent to `Ptr(new T(...))`. It is shorter than the latter, and it's -marginally safer than using a constructor or Ptr::reset, since it ensures that the owned pointer -is new and thus not owned by any other Ptr instance. -Unfortunately, perfect forwarding is impossible to implement in C++03, and so makePtr is limited -to constructors of T that have up to 10 arguments, none of which are non-const references. - */ -template -Ptr makePtr(); -/** @overload */ -template -Ptr makePtr(const A1& a1); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9); -/** @overload */ -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10); - -//////////////////////////////// string class //////////////////////////////// - -class CV_EXPORTS FileNode; //for string constructor from FileNode - -class CV_EXPORTS String -{ -public: - typedef char value_type; - typedef char& reference; - typedef const char& const_reference; - typedef char* pointer; - typedef const char* const_pointer; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef char* iterator; - typedef const char* const_iterator; - - static const size_t npos = size_t(-1); - - String(); - String(const String& str); - String(const String& str, size_t pos, size_t len = npos); - String(const char* s); - String(const char* s, size_t n); - String(size_t n, char c); - String(const char* first, const char* last); - template String(Iterator first, Iterator last); - explicit String(const FileNode& fn); - ~String(); - - String& operator=(const String& str); - String& operator=(const char* s); - String& operator=(char c); - - String& operator+=(const String& str); - String& operator+=(const char* s); - String& operator+=(char c); - - size_t size() const; - size_t length() const; - - char operator[](size_t idx) const; - char operator[](int idx) const; - - const char* begin() const; - const char* end() const; - - const char* c_str() const; - - bool empty() const; - void clear(); - - int compare(const char* s) const; - int compare(const String& str) const; - - void swap(String& str); - String substr(size_t pos = 0, size_t len = npos) const; - - size_t find(const char* s, size_t pos, size_t n) const; - size_t find(char c, size_t pos = 0) const; - size_t find(const String& str, size_t pos = 0) const; - size_t find(const char* s, size_t pos = 0) const; - - size_t rfind(const char* s, size_t pos, size_t n) const; - size_t rfind(char c, size_t pos = npos) const; - size_t rfind(const String& str, size_t pos = npos) const; - size_t rfind(const char* s, size_t pos = npos) const; - - size_t find_first_of(const char* s, size_t pos, size_t n) const; - size_t find_first_of(char c, size_t pos = 0) const; - size_t find_first_of(const String& str, size_t pos = 0) const; - size_t find_first_of(const char* s, size_t pos = 0) const; - - size_t find_last_of(const char* s, size_t pos, size_t n) const; - size_t find_last_of(char c, size_t pos = npos) const; - size_t find_last_of(const String& str, size_t pos = npos) const; - size_t find_last_of(const char* s, size_t pos = npos) const; - - friend String operator+ (const String& lhs, const String& rhs); - friend String operator+ (const String& lhs, const char* rhs); - friend String operator+ (const char* lhs, const String& rhs); - friend String operator+ (const String& lhs, char rhs); - friend String operator+ (char lhs, const String& rhs); - - String toLowerCase() const; - - String(const std::string& str); - String(const std::string& str, size_t pos, size_t len = npos); - String& operator=(const std::string& str); - String& operator+=(const std::string& str); - operator std::string() const; - - friend String operator+ (const String& lhs, const std::string& rhs); - friend String operator+ (const std::string& lhs, const String& rhs); - -private: - char* cstr_; - size_t len_; - - char* allocate(size_t len); // len without trailing 0 - void deallocate(); - - String(int); // disabled and invalid. Catch invalid usages like, commandLineParser.has(0) problem -}; - -//! @} core_basic - -////////////////////////// cv::String implementation ///////////////////////// - -//! @cond IGNORED - -inline -String::String() - : cstr_(0), len_(0) -{} - -inline -String::String(const String& str) - : cstr_(str.cstr_), len_(str.len_) -{ - if (cstr_) - CV_XADD(((int*)cstr_)-1, 1); -} - -inline -String::String(const String& str, size_t pos, size_t len) - : cstr_(0), len_(0) -{ - pos = min(pos, str.len_); - len = min(str.len_ - pos, len); - if (!len) return; - if (len == str.len_) - { - CV_XADD(((int*)str.cstr_)-1, 1); - cstr_ = str.cstr_; - len_ = str.len_; - return; - } - memcpy(allocate(len), str.cstr_ + pos, len); -} - -inline -String::String(const char* s) - : cstr_(0), len_(0) -{ - if (!s) return; - size_t len = strlen(s); - if (!len) return; - memcpy(allocate(len), s, len); -} - -inline -String::String(const char* s, size_t n) - : cstr_(0), len_(0) -{ - if (!n) return; - if (!s) return; - memcpy(allocate(n), s, n); -} - -inline -String::String(size_t n, char c) - : cstr_(0), len_(0) -{ - if (!n) return; - memset(allocate(n), c, n); -} - -inline -String::String(const char* first, const char* last) - : cstr_(0), len_(0) -{ - size_t len = (size_t)(last - first); - if (!len) return; - memcpy(allocate(len), first, len); -} - -template inline -String::String(Iterator first, Iterator last) - : cstr_(0), len_(0) -{ - size_t len = (size_t)(last - first); - if (!len) return; - char* str = allocate(len); - while (first != last) - { - *str++ = *first; - ++first; - } -} - -inline -String::~String() -{ - deallocate(); -} - -inline -String& String::operator=(const String& str) -{ - if (&str == this) return *this; - - deallocate(); - if (str.cstr_) CV_XADD(((int*)str.cstr_)-1, 1); - cstr_ = str.cstr_; - len_ = str.len_; - return *this; -} - -inline -String& String::operator=(const char* s) -{ - deallocate(); - if (!s) return *this; - size_t len = strlen(s); - if (len) memcpy(allocate(len), s, len); - return *this; -} - -inline -String& String::operator=(char c) -{ - deallocate(); - allocate(1)[0] = c; - return *this; -} - -inline -String& String::operator+=(const String& str) -{ - *this = *this + str; - return *this; -} - -inline -String& String::operator+=(const char* s) -{ - *this = *this + s; - return *this; -} - -inline -String& String::operator+=(char c) -{ - *this = *this + c; - return *this; -} - -inline -size_t String::size() const -{ - return len_; -} - -inline -size_t String::length() const -{ - return len_; -} - -inline -char String::operator[](size_t idx) const -{ - return cstr_[idx]; -} - -inline -char String::operator[](int idx) const -{ - return cstr_[idx]; -} - -inline -const char* String::begin() const -{ - return cstr_; -} - -inline -const char* String::end() const -{ - return len_ ? cstr_ + len_ : NULL; -} - -inline -bool String::empty() const -{ - return len_ == 0; -} - -inline -const char* String::c_str() const -{ - return cstr_ ? cstr_ : ""; -} - -inline -void String::swap(String& str) -{ - cv::swap(cstr_, str.cstr_); - cv::swap(len_, str.len_); -} - -inline -void String::clear() -{ - deallocate(); -} - -inline -int String::compare(const char* s) const -{ - if (cstr_ == s) return 0; - return strcmp(c_str(), s); -} - -inline -int String::compare(const String& str) const -{ - if (cstr_ == str.cstr_) return 0; - return strcmp(c_str(), str.c_str()); -} - -inline -String String::substr(size_t pos, size_t len) const -{ - return String(*this, pos, len); -} - -inline -size_t String::find(const char* s, size_t pos, size_t n) const -{ - if (n == 0 || pos + n > len_) return npos; - const char* lmax = cstr_ + len_ - n; - for (const char* i = cstr_ + pos; i <= lmax; ++i) - { - size_t j = 0; - while (j < n && s[j] == i[j]) ++j; - if (j == n) return (size_t)(i - cstr_); - } - return npos; -} - -inline -size_t String::find(char c, size_t pos) const -{ - return find(&c, pos, 1); -} - -inline -size_t String::find(const String& str, size_t pos) const -{ - return find(str.c_str(), pos, str.len_); -} - -inline -size_t String::find(const char* s, size_t pos) const -{ - if (pos >= len_ || !s[0]) return npos; - const char* lmax = cstr_ + len_; - for (const char* i = cstr_ + pos; i < lmax; ++i) - { - size_t j = 0; - while (s[j] && s[j] == i[j]) - { if(i + j >= lmax) return npos; - ++j; - } - if (!s[j]) return (size_t)(i - cstr_); - } - return npos; -} - -inline -size_t String::rfind(const char* s, size_t pos, size_t n) const -{ - if (n > len_) return npos; - if (pos > len_ - n) pos = len_ - n; - for (const char* i = cstr_ + pos; i >= cstr_; --i) - { - size_t j = 0; - while (j < n && s[j] == i[j]) ++j; - if (j == n) return (size_t)(i - cstr_); - } - return npos; -} - -inline -size_t String::rfind(char c, size_t pos) const -{ - return rfind(&c, pos, 1); -} - -inline -size_t String::rfind(const String& str, size_t pos) const -{ - return rfind(str.c_str(), pos, str.len_); -} - -inline -size_t String::rfind(const char* s, size_t pos) const -{ - return rfind(s, pos, strlen(s)); -} - -inline -size_t String::find_first_of(const char* s, size_t pos, size_t n) const -{ - if (n == 0 || pos + n > len_) return npos; - const char* lmax = cstr_ + len_; - for (const char* i = cstr_ + pos; i < lmax; ++i) - { - for (size_t j = 0; j < n; ++j) - if (s[j] == *i) - return (size_t)(i - cstr_); - } - return npos; -} - -inline -size_t String::find_first_of(char c, size_t pos) const -{ - return find_first_of(&c, pos, 1); -} - -inline -size_t String::find_first_of(const String& str, size_t pos) const -{ - return find_first_of(str.c_str(), pos, str.len_); -} - -inline -size_t String::find_first_of(const char* s, size_t pos) const -{ - if (len_ == 0) return npos; - if (pos >= len_ || !s[0]) return npos; - const char* lmax = cstr_ + len_; - for (const char* i = cstr_ + pos; i < lmax; ++i) - { - for (size_t j = 0; s[j]; ++j) - if (s[j] == *i) - return (size_t)(i - cstr_); - } - return npos; -} - -inline -size_t String::find_last_of(const char* s, size_t pos, size_t n) const -{ - if (len_ == 0) return npos; - if (pos >= len_) pos = len_ - 1; - for (const char* i = cstr_ + pos; i >= cstr_; --i) - { - for (size_t j = 0; j < n; ++j) - if (s[j] == *i) - return (size_t)(i - cstr_); - } - return npos; -} - -inline -size_t String::find_last_of(char c, size_t pos) const -{ - return find_last_of(&c, pos, 1); -} - -inline -size_t String::find_last_of(const String& str, size_t pos) const -{ - return find_last_of(str.c_str(), pos, str.len_); -} - -inline -size_t String::find_last_of(const char* s, size_t pos) const -{ - if (len_ == 0) return npos; - if (pos >= len_) pos = len_ - 1; - for (const char* i = cstr_ + pos; i >= cstr_; --i) - { - for (size_t j = 0; s[j]; ++j) - if (s[j] == *i) - return (size_t)(i - cstr_); - } - return npos; -} - -inline -String String::toLowerCase() const -{ - if (!cstr_) - return String(); - String res(cstr_, len_); - for (size_t i = 0; i < len_; ++i) - res.cstr_[i] = (char) ::tolower(cstr_[i]); - - return res; -} - -//! @endcond - -// ************************* cv::String non-member functions ************************* - -//! @relates cv::String -//! @{ - -inline -String operator + (const String& lhs, const String& rhs) -{ - String s; - s.allocate(lhs.len_ + rhs.len_); - if (lhs.len_) memcpy(s.cstr_, lhs.cstr_, lhs.len_); - if (rhs.len_) memcpy(s.cstr_ + lhs.len_, rhs.cstr_, rhs.len_); - return s; -} - -inline -String operator + (const String& lhs, const char* rhs) -{ - String s; - size_t rhslen = strlen(rhs); - s.allocate(lhs.len_ + rhslen); - if (lhs.len_) memcpy(s.cstr_, lhs.cstr_, lhs.len_); - if (rhslen) memcpy(s.cstr_ + lhs.len_, rhs, rhslen); - return s; -} - -inline -String operator + (const char* lhs, const String& rhs) -{ - String s; - size_t lhslen = strlen(lhs); - s.allocate(lhslen + rhs.len_); - if (lhslen) memcpy(s.cstr_, lhs, lhslen); - if (rhs.len_) memcpy(s.cstr_ + lhslen, rhs.cstr_, rhs.len_); - return s; -} - -inline -String operator + (const String& lhs, char rhs) -{ - String s; - s.allocate(lhs.len_ + 1); - if (lhs.len_) memcpy(s.cstr_, lhs.cstr_, lhs.len_); - s.cstr_[lhs.len_] = rhs; - return s; -} - -inline -String operator + (char lhs, const String& rhs) -{ - String s; - s.allocate(rhs.len_ + 1); - s.cstr_[0] = lhs; - if (rhs.len_) memcpy(s.cstr_ + 1, rhs.cstr_, rhs.len_); - return s; -} - -static inline bool operator== (const String& lhs, const String& rhs) { return 0 == lhs.compare(rhs); } -static inline bool operator== (const char* lhs, const String& rhs) { return 0 == rhs.compare(lhs); } -static inline bool operator== (const String& lhs, const char* rhs) { return 0 == lhs.compare(rhs); } -static inline bool operator!= (const String& lhs, const String& rhs) { return 0 != lhs.compare(rhs); } -static inline bool operator!= (const char* lhs, const String& rhs) { return 0 != rhs.compare(lhs); } -static inline bool operator!= (const String& lhs, const char* rhs) { return 0 != lhs.compare(rhs); } -static inline bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; } -static inline bool operator< (const char* lhs, const String& rhs) { return rhs.compare(lhs) > 0; } -static inline bool operator< (const String& lhs, const char* rhs) { return lhs.compare(rhs) < 0; } -static inline bool operator<= (const String& lhs, const String& rhs) { return lhs.compare(rhs) <= 0; } -static inline bool operator<= (const char* lhs, const String& rhs) { return rhs.compare(lhs) >= 0; } -static inline bool operator<= (const String& lhs, const char* rhs) { return lhs.compare(rhs) <= 0; } -static inline bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; } -static inline bool operator> (const char* lhs, const String& rhs) { return rhs.compare(lhs) < 0; } -static inline bool operator> (const String& lhs, const char* rhs) { return lhs.compare(rhs) > 0; } -static inline bool operator>= (const String& lhs, const String& rhs) { return lhs.compare(rhs) >= 0; } -static inline bool operator>= (const char* lhs, const String& rhs) { return rhs.compare(lhs) <= 0; } -static inline bool operator>= (const String& lhs, const char* rhs) { return lhs.compare(rhs) >= 0; } - -//! @} relates cv::String - -} // cv - -namespace std -{ - static inline void swap(cv::String& a, cv::String& b) { a.swap(b); } -} - -#include "opencv2/core/ptr.inl.hpp" - -#endif //OPENCV_CORE_CVSTD_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/cvstd.inl.hpp b/3rdparty/libopencv/include/opencv2/core/cvstd.inl.hpp deleted file mode 100644 index 85230f5..0000000 --- a/3rdparty/libopencv/include/opencv2/core/cvstd.inl.hpp +++ /dev/null @@ -1,286 +0,0 @@ -/*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; -}; - -inline -String::String(const std::string& str) - : cstr_(0), len_(0) -{ - if (!str.empty()) - { - size_t len = str.size(); - if (len) memcpy(allocate(len), str.c_str(), len); - } -} - -inline -String::String(const std::string& str, size_t pos, size_t len) - : cstr_(0), len_(0) -{ - size_t strlen = str.size(); - pos = min(pos, strlen); - len = min(strlen - pos, len); - if (!len) return; - memcpy(allocate(len), str.c_str() + pos, len); -} - -inline -String& String::operator = (const std::string& str) -{ - deallocate(); - if (!str.empty()) - { - size_t len = str.size(); - if (len) memcpy(allocate(len), str.c_str(), len); - } - return *this; -} - -inline -String& String::operator += (const std::string& str) -{ - *this = *this + str; - return *this; -} - -inline -String::operator std::string() const -{ - return std::string(cstr_, len_); -} - -inline -String operator + (const String& lhs, const std::string& rhs) -{ - String s; - size_t rhslen = rhs.size(); - s.allocate(lhs.len_ + rhslen); - if (lhs.len_) memcpy(s.cstr_, lhs.cstr_, lhs.len_); - if (rhslen) memcpy(s.cstr_ + lhs.len_, rhs.c_str(), rhslen); - return s; -} - -inline -String operator + (const std::string& lhs, const String& rhs) -{ - String s; - size_t lhslen = lhs.size(); - s.allocate(lhslen + rhs.len_); - if (lhslen) memcpy(s.cstr_, lhs.c_str(), lhslen); - if (rhs.len_) memcpy(s.cstr_ + lhslen, rhs.cstr_, rhs.len_); - return s; -} - -inline -FileNode::operator std::string() const -{ - String value; - read(*this, value, value); - return value; -} - -template<> inline -void operator >> (const FileNode& n, std::string& value) -{ - read(n, value, std::string()); -} - -template<> inline -FileStorage& operator << (FileStorage& fs, const std::string& value) -{ - return fs << cv::String(value); -} - -static inline -std::ostream& operator << (std::ostream& os, const String& str) -{ - return os << str.c_str(); -} - -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.p[-1]; - for( i = 0; i < dims; i++ ) - { - out << msize.p[i]; - if( i < dims-1 ) - out << " x "; - } - return out; -} - -} // cv - -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - -//! @endcond - -#endif // OPENCV_CORE_CVSTDINL_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/directx.hpp b/3rdparty/libopencv/include/opencv2/core/directx.hpp deleted file mode 100644 index 056a85a..0000000 --- a/3rdparty/libopencv/include/opencv2/core/directx.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/eigen.hpp b/3rdparty/libopencv/include/opencv2/core/eigen.hpp deleted file mode 100644 index c8603ac..0000000 --- a/3rdparty/libopencv/include/opencv2/core/eigen.hpp +++ /dev/null @@ -1,280 +0,0 @@ -/*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, Mat& 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/3rdparty/libopencv/include/opencv2/core/fast_math.hpp b/3rdparty/libopencv/include/opencv2/core/fast_math.hpp deleted file mode 100644 index 7858d40..0000000 --- a/3rdparty/libopencv/include/opencv2/core/fast_math.hpp +++ /dev/null @@ -1,271 +0,0 @@ -/*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 - -#ifdef HAVE_TEGRA_OPTIMIZATION -# include "tegra_round.hpp" -#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; \ - (void)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 _MSC_VER && defined _M_ARM) || defined CV_ICC || \ - defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION - TEGRA_ROUND_DBL(value); -#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 _MSC_VER && defined _M_ARM) || defined CV_ICC || \ - defined __GNUC__) && defined HAVE_TEGRA_OPTIMIZATION - TEGRA_ROUND_FLT(value); -#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/3rdparty/libopencv/include/opencv2/core/hal/hal.hpp b/3rdparty/libopencv/include/opencv2/core/hal/hal.hpp deleted file mode 100644 index 68900ec..0000000 --- a/3rdparty/libopencv/include/opencv2/core/hal/hal.hpp +++ /dev/null @@ -1,250 +0,0 @@ -/*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 ); - -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/3rdparty/libopencv/include/opencv2/core/hal/interface.h b/3rdparty/libopencv/include/opencv2/core/hal/interface.h deleted file mode 100644 index 8f64025..0000000 --- a/3rdparty/libopencv/include/opencv2/core/hal/interface.h +++ /dev/null @@ -1,182 +0,0 @@ -#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_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)) -//! @} - -//! @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/3rdparty/libopencv/include/opencv2/core/hal/intrin.hpp b/3rdparty/libopencv/include/opencv2/core/hal/intrin.hpp deleted file mode 100644 index 9dcfc56..0000000 --- a/3rdparty/libopencv/include/opencv2/core/hal/intrin.hpp +++ /dev/null @@ -1,472 +0,0 @@ -/*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) - -// 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 { - -#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; -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN -#endif - -//! @addtogroup core_hal_intrin -//! @{ - -//! @cond IGNORED -template struct V_TypeTraits -{ - typedef _Tp int_type; - typedef _Tp uint_type; - typedef _Tp abs_type; - typedef _Tp sum_type; - - enum { delta = 0, shift = 0 }; - - static int_type reinterpret_int(_Tp x) { return x; } - static uint_type reinterpet_uint(_Tp x) { return x; } - static _Tp reinterpret_from_int(int_type x) { return (_Tp)x; } -}; - -template<> struct V_TypeTraits -{ - typedef uchar value_type; - typedef schar int_type; - typedef uchar uint_type; - typedef uchar abs_type; - typedef int sum_type; - - typedef ushort w_type; - typedef unsigned q_type; - - enum { delta = 128, shift = 8 }; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - -template<> struct V_TypeTraits -{ - typedef schar value_type; - typedef schar int_type; - typedef uchar uint_type; - typedef uchar abs_type; - typedef int sum_type; - - typedef short w_type; - typedef int q_type; - - enum { delta = 128, shift = 8 }; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - -template<> struct V_TypeTraits -{ - typedef ushort value_type; - typedef short int_type; - typedef ushort uint_type; - typedef ushort abs_type; - typedef int sum_type; - - typedef unsigned w_type; - typedef uchar nu_type; - - enum { delta = 32768, shift = 16 }; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - -template<> struct V_TypeTraits -{ - typedef short value_type; - typedef short int_type; - typedef ushort uint_type; - typedef ushort abs_type; - typedef int sum_type; - - typedef int w_type; - typedef uchar nu_type; - typedef schar n_type; - - enum { delta = 128, shift = 8 }; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - -template<> struct V_TypeTraits -{ - typedef unsigned value_type; - typedef int int_type; - typedef unsigned uint_type; - typedef unsigned abs_type; - typedef unsigned sum_type; - - typedef uint64 w_type; - typedef ushort nu_type; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - -template<> struct V_TypeTraits -{ - typedef int value_type; - typedef int int_type; - typedef unsigned uint_type; - typedef unsigned abs_type; - typedef int sum_type; - - typedef int64 w_type; - typedef short n_type; - typedef ushort nu_type; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - -template<> struct V_TypeTraits -{ - typedef uint64 value_type; - typedef int64 int_type; - typedef uint64 uint_type; - typedef uint64 abs_type; - typedef uint64 sum_type; - - typedef unsigned nu_type; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - -template<> struct V_TypeTraits -{ - typedef int64 value_type; - typedef int64 int_type; - typedef uint64 uint_type; - typedef uint64 abs_type; - typedef int64 sum_type; - - typedef int nu_type; - - static int_type reinterpret_int(value_type x) { return (int_type)x; } - static uint_type reinterpret_uint(value_type x) { return (uint_type)x; } - static value_type reinterpret_from_int(int_type x) { return (value_type)x; } -}; - - -template<> struct V_TypeTraits -{ - typedef float value_type; - typedef int int_type; - typedef unsigned uint_type; - typedef float abs_type; - typedef float sum_type; - - typedef double w_type; - - static int_type reinterpret_int(value_type x) - { - Cv32suf u; - u.f = x; - return u.i; - } - static uint_type reinterpet_uint(value_type x) - { - Cv32suf u; - u.f = x; - return u.u; - } - static value_type reinterpret_from_int(int_type x) - { - Cv32suf u; - u.i = x; - return u.f; - } -}; - -template<> struct V_TypeTraits -{ - typedef double value_type; - typedef int64 int_type; - typedef uint64 uint_type; - typedef double abs_type; - typedef double sum_type; - static int_type reinterpret_int(value_type x) - { - Cv64suf u; - u.f = x; - return u.i; - } - static uint_type reinterpet_uint(value_type x) - { - Cv64suf u; - u.f = x; - return u.u; - } - static value_type reinterpret_from_int(int_type x) - { - Cv64suf u; - u.i = x; - return u.f; - } -}; - -template struct V_SIMD128Traits -{ - enum { nlanes = 16 / sizeof(T) }; -}; - -//! @endcond - -//! @} - -#ifndef CV_DOXYGEN -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END -#endif -} - -#ifdef CV_DOXYGEN -# undef CV_SSE2 -# undef CV_NEON -# undef CV_VSX -#endif - -#if CV_SSE2 - -#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 - -#include "opencv2/core/hal/intrin_cpp.hpp" - -#endif - -//! @addtogroup core_hal_intrin -//! @{ - -#ifndef CV_SIMD128 -//! Set to 1 if current compiler supports vector extensions (NEON or SSE is enabled) -#define CV_SIMD128 0 -#endif - -#ifndef CV_SIMD128_64F -//! Set to 1 if current intrinsics implementation supports 64-bit float vectors -#define CV_SIMD128_64F 0 -#endif - -//! @} - -//================================================================================================== - -//! @cond IGNORED - -namespace cv { - -#ifndef CV_DOXYGEN -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN -#endif - -template struct V_RegTrait128; - -template <> struct V_RegTrait128 { - typedef v_uint8x16 reg; - typedef v_uint16x8 w_reg; - typedef v_uint32x4 q_reg; - typedef v_uint8x16 u_reg; - static v_uint8x16 zero() { return v_setzero_u8(); } - static v_uint8x16 all(uchar val) { return v_setall_u8(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_int8x16 reg; - typedef v_int16x8 w_reg; - typedef v_int32x4 q_reg; - typedef v_uint8x16 u_reg; - static v_int8x16 zero() { return v_setzero_s8(); } - static v_int8x16 all(schar val) { return v_setall_s8(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_uint16x8 reg; - typedef v_uint32x4 w_reg; - typedef v_int16x8 int_reg; - typedef v_uint16x8 u_reg; - static v_uint16x8 zero() { return v_setzero_u16(); } - static v_uint16x8 all(ushort val) { return v_setall_u16(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_int16x8 reg; - typedef v_int32x4 w_reg; - typedef v_uint16x8 u_reg; - static v_int16x8 zero() { return v_setzero_s16(); } - static v_int16x8 all(short val) { return v_setall_s16(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_uint32x4 reg; - typedef v_uint64x2 w_reg; - typedef v_int32x4 int_reg; - typedef v_uint32x4 u_reg; - static v_uint32x4 zero() { return v_setzero_u32(); } - static v_uint32x4 all(unsigned val) { return v_setall_u32(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_int32x4 reg; - typedef v_int64x2 w_reg; - typedef v_uint32x4 u_reg; - static v_int32x4 zero() { return v_setzero_s32(); } - static v_int32x4 all(int val) { return v_setall_s32(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_uint64x2 reg; - static v_uint64x2 zero() { return v_setzero_u64(); } - static v_uint64x2 all(uint64 val) { return v_setall_u64(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_int64x2 reg; - static v_int64x2 zero() { return v_setzero_s64(); } - static v_int64x2 all(int64 val) { return v_setall_s64(val); } -}; - -template <> struct V_RegTrait128 { - typedef v_float32x4 reg; - typedef v_int32x4 int_reg; - typedef v_float32x4 u_reg; - static v_float32x4 zero() { return v_setzero_f32(); } - static v_float32x4 all(float val) { return v_setall_f32(val); } -}; - -#if CV_SIMD128_64F -template <> struct V_RegTrait128 { - typedef v_float64x2 reg; - typedef v_int32x4 int_reg; - typedef v_float64x2 u_reg; - static v_float64x2 zero() { return v_setzero_f64(); } - static v_float64x2 all(double val) { return v_setall_f64(val); } -}; -#endif - -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; -#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 -} - -#ifndef CV_DOXYGEN -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END -#endif - -} // cv:: - -//! @endcond - -#endif diff --git a/3rdparty/libopencv/include/opencv2/core/hal/intrin_cpp.hpp b/3rdparty/libopencv/include/opencv2/core/hal/intrin_cpp.hpp deleted file mode 100644 index e7ea899..0000000 --- a/3rdparty/libopencv/include/opencv2/core/hal/intrin_cpp.hpp +++ /dev/null @@ -1,1959 +0,0 @@ -/*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 -- Pack: @ref v_pack, @ref v_pack_u, @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 - -### 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_q | x | x | | | | | -|add, sub | x | x | x | x | x | x | -|add_wrap, sub_wrap | x | x | x | x | | | -|mul | | | x | x | x | x | -|mul_expand | | | 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 | -|reduce | | | | | x | x | -|mask | x | x | x | x | x | x | -|pack | x | x | x | x | x | x | -|pack_u | x | | x | | | | -|unpack | x | x | x | x | x | x | -|extract | 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 | - -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 | | - - - @{ */ - -template struct v_reg -{ -//! @cond IGNORED - typedef _Tp lane_type; - typedef v_reg::int_type, n> int_vec; - typedef v_reg::abs_type, n> abs_vec; - 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 and return 4 values - -Scheme: -@code -{A1 A2 A3 ...} => popcount(A1) -@endcode -Any types but result will be in v_uint32x4*/ -template inline v_uint32x4 v_popcount(const v_reg<_Tp, n>& a) -{ - v_uint8x16 b; - b = v_reinterpret_as_u8(a); - for( int i = 0; i < v_uint8x16::nlanes; i++ ) - { - b.s[i] = popCountTable[b.s[i]]; - } - v_uint32x4 c; - for( int i = 0; i < v_uint32x4::nlanes; i++ ) - { - c.s[i] = b.s[i*4] + b.s[i*4+1] + b.s[i*4+2] + b.s[i*4+3]; - } - return c; -} - - -//! @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(!=) - -//! @brief Helper macro -//! @ingroup core_hal_intrin_impl -#define OPENCV_HAL_IMPL_ADD_SUB_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_ADD_SUB_OP(v_add_wrap, +, (_Tp), _Tp) - -/** @brief Subtract values without saturation - -For 8- and 16-bit integer values. */ -OPENCV_HAL_IMPL_ADD_SUB_OP(v_sub_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 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 only. */ -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) -{ - 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 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 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)]; - } -} - -//! @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 Get negative values mask - -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 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 Bitwise select - -Return value will be built by combining values a and b using the following scheme: -If the i-th bit in _mask_ is 1 - select i-th bit from _a_ -else - select i-th bit from _b_ */ -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]); - c.s[i] = Traits::reinterpret_from_int((Traits::reinterpret_int(a.s[i]) & m) - | (Traits::reinterpret_int(b.s[i]) & ~m)); - } - 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)]; - } -} - -//! @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_SIMD128Traits<_Tp>::nlanes> v_load(const _Tp* ptr) -{ - return v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes>(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_SIMD128Traits<_Tp>::nlanes> v_load_aligned(const _Tp* ptr) -{ - return v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes>(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_SIMD128Traits<_Tp>::nlanes> v_load_low(const _Tp* ptr) -{ - v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes> 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_SIMD128Traits<_Tp>::nlanes> v_load_halves(const _Tp* loptr, const _Tp* hiptr) -{ - v_reg<_Tp, V_SIMD128Traits<_Tp>::nlanes> 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_SIMD128Traits<_Tp>::nlanes / 2> -v_load_expand(const _Tp* ptr) -{ - typedef typename V_TypeTraits<_Tp>::w_type w_type; - v_reg::nlanes> 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_SIMD128Traits<_Tp>::nlanes / 4> -v_load_expand_q(const _Tp* ptr) -{ - typedef typename V_TypeTraits<_Tp>::q_type q_type; - v_reg::nlanes> 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) -{ - 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) -{ - 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) -{ - 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]; -} - -/** @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 integer types only. */ -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; -} - -/** @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; -} - -/** @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; -} - -/** @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) -//! @} - -/** @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]); -} - -//! @} - -//! @name Check SIMD support -//! @{ -//! @brief Check CPU capability of SIMD operation -static inline bool hasSIMD128() -{ - return false; -} - -//! @} - -#ifndef CV_DOXYGEN -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END -#endif -} - -#endif diff --git a/3rdparty/libopencv/include/opencv2/core/hal/intrin_neon.hpp b/3rdparty/libopencv/include/opencv2/core/hal/intrin_neon.hpp deleted file mode 100644 index c3c49c9..0000000 --- a/3rdparty/libopencv/include/opencv2/core/hal/intrin_neon.hpp +++ /dev/null @@ -1,1303 +0,0 @@ -/*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 - -#if CV_FP16 -// Workaround for old compilers -template static inline int16x4_t vreinterpret_s16_f16(T a) -{ return (int16x4_t)a; } -template static inline float16x4_t vreinterpret_f16_s16(T a) -{ return (float16x4_t)a; } -template static inline float16x4_t cv_vld1_f16(const T* ptr) -{ -#ifndef vld1_f16 // APPLE compiler defines vld1_f16 as macro - return vreinterpret_f16_s16(vld1_s16((const short*)ptr)); -#else - return vld1_f16((const __fp16*)ptr); -#endif -} -template static inline void cv_vst1_f16(T* ptr, float16x4_t a) -{ -#ifndef vst1_f16 // APPLE compiler defines vst1_f16 as macro - vst1_s16((short*)ptr, vreinterpret_s16_f16(a)); -#else - vst1_f16((__fp16*)ptr, a); -#endif -} - -struct v_float16x4 -{ - typedef short lane_type; - enum { nlanes = 4 }; - - v_float16x4() {} - explicit v_float16x4(float16x4_t v) : val(v) {} - v_float16x4(short v0, short v1, short v2, short v3) - { - short v[] = {v0, v1, v2, v3}; - val = cv_vld1_f16(v); - } - short get0() const - { - return vget_lane_s16(vreinterpret_s16_f16(val), 0); - } - float16x4_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) - -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_uint16x8, vmulq_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_int16x8, vmulq_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 - -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_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])); -} - -#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 - -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) - -// TODO: absdiff for signed integers -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 - -#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_muladd(const v_float32x4& a, const v_float32x4& b, const v_float32x4& c) -{ - return v_float32x4(vmlaq_f32(c.val, a.val, b.val)); -} - -#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_muladd(const v_float64x2& a, const v_float64x2& b, const v_float64x2& c) -{ - return v_float64x2(vaddq_f64(c.val, vmulq_f64(a.val, b.val))); -} -#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)); } \ -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_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)); } - -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_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)); } \ -inline _Tpvec v_load_low(const _Tp* ptr) \ -{ return _Tpvec(vcombine_##suffix(vld1_##suffix(ptr), vdup_n_##suffix((_Tp)0))); } \ -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_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 - -#if CV_FP16 -// Workaround for old comiplers -inline v_float16x4 v_load_f16(const short* ptr) -{ return v_float16x4(cv_vld1_f16(ptr)); } -inline void v_store_f16(short* ptr, v_float16x4& a) -{ cv_vst1_f16(ptr, a.val); } -#endif - -#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 short, sum, add, u16) -OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, unsigned short, max, max, u16) -OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_uint16x8, uint16x4, unsigned short, min, min, u16) -OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, sum, add, s16) -OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, max, max, s16) -OPENCV_HAL_IMPL_NEON_REDUCE_OP_8(v_int16x8, int16x4, short, 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 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)); -} - -#define OPENCV_HAL_IMPL_NEON_POPCOUNT(_Tpvec, cast) \ -inline v_uint32x4 v_popcount(const _Tpvec& a) \ -{ \ - uint8x16_t t = vcntq_u8(cast(a.val)); \ - uint16x8_t t0 = vpaddlq_u8(t); /* 16 -> 8 */ \ - uint32x4_t t1 = vpaddlq_u16(t0); /* 8 -> 4 */ \ - return v_uint32x4(t1); \ -} - -OPENCV_HAL_IMPL_NEON_POPCOUNT(v_uint8x16, OPENCV_HAL_NOP) -OPENCV_HAL_IMPL_NEON_POPCOUNT(v_uint16x8, vreinterpretq_u8_u16) -OPENCV_HAL_IMPL_NEON_POPCOUNT(v_uint32x4, vreinterpretq_u8_u32) -OPENCV_HAL_IMPL_NEON_POPCOUNT(v_int8x16, vreinterpretq_u8_s8) -OPENCV_HAL_IMPL_NEON_POPCOUNT(v_int16x8, vreinterpretq_u8_s16) -OPENCV_HAL_IMPL_NEON_POPCOUNT(v_int32x4, vreinterpretq_u8_s32) - -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)); } -#if CV_SIMD128_64F -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_float64x2& a) -{ return v_signmask(v_reinterpret_as_u64(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_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) -{ - uint8x8_t v0 = vcreate_u8(*(unsigned*)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) -{ - int8x8_t v0 = vcreate_s8(*(unsigned*)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 - -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)))); -} - -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_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) \ -{ \ - _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) \ -{ \ - _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) \ -{ \ - _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); \ -} - -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 - -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_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 - -#if CV_FP16 -inline v_float32x4 v_cvt_f32(const v_float16x4& a) -{ - return v_float32x4(vcvt_f32_f16(a.val)); -} - -inline v_float16x4 v_cvt_f16(const v_float32x4& a) -{ - return v_float16x4(vcvt_f16_f32(a.val)); -} -#endif - -//! @name Check SIMD support -//! @{ -//! @brief Check CPU capability of SIMD operation -static inline bool hasSIMD128() -{ - return (CV_CPU_HAS_SUPPORT_NEON) ? true : false; -} - -//! @} - -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END - -//! @endcond - -} - -#endif diff --git a/3rdparty/libopencv/include/opencv2/core/hal/intrin_sse.hpp b/3rdparty/libopencv/include/opencv2/core/hal/intrin_sse.hpp deleted file mode 100644 index 0e740f6..0000000 --- a/3rdparty/libopencv/include/opencv2/core/hal/intrin_sse.hpp +++ /dev/null @@ -1,1921 +0,0 @@ -/*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 - -namespace cv -{ - -//! @cond IGNORED - -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN - -struct v_uint8x16 -{ - typedef uchar lane_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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; - 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; -}; - -#if CV_FP16 -struct v_float16x4 -{ - typedef short lane_type; - enum { nlanes = 4 }; - - v_float16x4() : val(_mm_setzero_si128()) {} - explicit v_float16x4(__m128i v) : val(v) {} - v_float16x4(short v0, short v1, short v2, short v3) - { - val = _mm_setr_epi16(v0, v1, v2, v3, 0, 0, 0, 0); - } - short get0() const - { - return (short)_mm_cvtsi128_si32(val); - } - __m128i val; -}; -#endif - -#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, char, OPENCV_HAL_NOP) -OPENCV_HAL_IMPL_SSE_INITVEC(v_int8x16, schar, s8, si128, epi8, char, 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, 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)); -} - - -// bit-wise "mask ? a : b" -inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b) -{ - return _mm_xor_si128(b, _mm_and_si128(_mm_xor_si128(a, b), mask)); -} - -inline v_uint16x8 v_pack(const v_uint32x4& a, const v_uint32x4& b) -{ - __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 b1 = _mm_sub_epi32(v_select_si128(_mm_cmpgt_epi32(z, b.val), maxval32, b.val), delta32); - __m128i r = _mm_packs_epi32(a1, b1); - return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768))); -} - -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) -{ - __m128i delta32 = _mm_set1_epi32(32768); - __m128i r = _mm_packs_epi32(_mm_sub_epi32(a.val, delta32), _mm_sub_epi32(b.val, delta32)); - return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768))); -} - -inline void v_pack_u_store(ushort* ptr, const v_int32x4& a) -{ - __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); -} - -template inline -v_uint16x8 v_rshr_pack_u(const v_int32x4& a, const v_int32x4& b) -{ - __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)); -} - -template inline -void v_rshr_pack_u_store(ushort* ptr, const v_int32x4& a) -{ - __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); -} - -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); -} - -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_uint16x8, _mm_mullo_epi16) -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_int16x8, _mm_mullo_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_int32x4, _mm_add_epi32) -OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int32x4, _mm_sub_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) - -inline v_uint32x4 operator * (const v_uint32x4& a, const v_uint32x4& b) -{ - __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)); - __m128i d0 = _mm_unpacklo_epi32(c0, c1); - __m128i d1 = _mm_unpackhi_epi32(c0, c1); - return v_uint32x4(_mm_unpacklo_epi64(d0, d1)); -} -inline v_int32x4 operator * (const v_int32x4& a, const v_int32x4& b) -{ - __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)); - __m128i d0 = _mm_unpacklo_epi32(c0, c1); - __m128i d1 = _mm_unpackhi_epi32(c0, c1); - return v_int32x4(_mm_unpacklo_epi64(d0, d1)); -} -inline v_uint32x4& operator *= (v_uint32x4& a, const v_uint32x4& b) -{ - a = a * b; - return a; -} -inline v_int32x4& operator *= (v_int32x4& a, const v_int32x4& b) -{ - a = a * b; - return a; -} - -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_int32x4 v_dotprod(const v_int16x8& a, const v_int16x8& b) -{ - return v_int32x4(_mm_madd_epi16(a.val, b.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) -{ - static 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) -{ - static 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) -{ - __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)))); -} -inline v_int8x16 v_max(const v_int8x16& a, const v_int8x16& b) -{ - __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)))); -} -inline v_uint16x8 v_min(const v_uint16x8& a, const v_uint16x8& b) -{ - return v_uint16x8(_mm_subs_epu16(a.val, _mm_subs_epu16(a.val, b.val))); -} -inline v_uint16x8 v_max(const v_uint16x8& a, const v_uint16x8& b) -{ - return v_uint16x8(_mm_adds_epu16(_mm_subs_epu16(a.val, b.val), b.val)); -} -inline v_uint32x4 v_min(const v_uint32x4& a, const v_uint32x4& b) -{ - __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)); -} -inline v_uint32x4 v_max(const v_uint32x4& a, const v_uint32x4& b) -{ - __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)); -} -inline v_int32x4 v_min(const v_int32x4& a, const v_int32x4& b) -{ - return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), b.val, a.val)); -} -inline v_int32x4 v_max(const v_int32x4& a, const v_int32x4& b) -{ - return v_int32x4(v_select_si128(_mm_cmpgt_epi32(a.val, b.val), a.val, b.val)); -} - -#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); - -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) - -#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, smask32) \ -inline _Tpuvec v_absdiff(const _Tpuvec& a, const _Tpuvec& b) \ -{ \ - return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a.val, b.val), _mm_subs_epu##bits(b.val, a.val))); \ -} \ -inline _Tpuvec v_absdiff(const _Tpsvec& a, const _Tpsvec& b) \ -{ \ - __m128i smask = _mm_set1_epi32(smask32); \ - __m128i a1 = _mm_xor_si128(a.val, smask); \ - __m128i b1 = _mm_xor_si128(b.val, smask); \ - return _Tpuvec(_mm_add_epi##bits(_mm_subs_epu##bits(a1, b1), _mm_subs_epu##bits(b1, a1))); \ -} - -OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint8x16, v_int8x16, 8, (int)0x80808080) -OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(v_uint16x8, v_int16x8, 16, (int)0x80008000) - -inline v_uint32x4 v_absdiff(const v_uint32x4& a, const v_uint32x4& b) -{ - return v_max(a, b) - v_min(a, b); -} - -inline v_uint32x4 v_absdiff(const v_int32x4& a, const v_int32x4& b) -{ - __m128i d = _mm_sub_epi32(a.val, b.val); - __m128i m = _mm_cmpgt_epi32(b.val, a.val); - return v_uint32x4(_mm_sub_epi32(_mm_xor_si128(d, m), m)); -} - -#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) \ -{ \ - _Tpreg res = _mm_add_##suffix(_mm_mul_##suffix(a.val, a.val), _mm_mul_##suffix(b.val, b.val)); \ - return _Tpvec(_mm_sqrt_##suffix(res)); \ -} \ -inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ -{ \ - _Tpreg res = _mm_add_##suffix(_mm_mul_##suffix(a.val, a.val), _mm_mul_##suffix(b.val, b.val)); \ - return _Tpvec(res); \ -} \ -inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ -{ \ - return _Tpvec(_mm_add_##suffix(_mm_mul_##suffix(a.val, b.val), c.val)); \ -} - -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) - -template -inline _Tpvec v_rotate_right(const _Tpvec &a) -{ - enum { CV_SHIFT = imm*(sizeof(typename _Tpvec::lane_type)) }; - return _Tpvec(_mm_srli_si128(a.val, CV_SHIFT)); -} -template -inline _Tpvec v_rotate_left(const _Tpvec &a) -{ - enum { CV_SHIFT = imm*(sizeof(typename _Tpvec::lane_type)) }; - return _Tpvec(_mm_slli_si128(a.val, CV_SHIFT)); -} -template -inline _Tpvec v_rotate_right(const _Tpvec &a, const _Tpvec &b) -{ - enum { CV_SHIFT1 = imm*(sizeof(typename _Tpvec::lane_type)) }; - enum { CV_SHIFT2 = 16 - imm*(sizeof(typename _Tpvec::lane_type)) }; - return _Tpvec(_mm_or_si128(_mm_srli_si128(a.val, CV_SHIFT1), _mm_slli_si128(b.val, CV_SHIFT2))); -} -template -inline _Tpvec v_rotate_left(const _Tpvec &a, const _Tpvec &b) -{ - enum { CV_SHIFT1 = imm*(sizeof(typename _Tpvec::lane_type)) }; - enum { CV_SHIFT2 = 16 - imm*(sizeof(typename _Tpvec::lane_type)) }; - return _Tpvec(_mm_or_si128(_mm_slli_si128(a.val, CV_SHIFT1), _mm_srli_si128(b.val, CV_SHIFT2))); -} - -#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_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_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) - -#if CV_FP16 -inline v_float16x4 v_load_f16(const short* ptr) -{ return v_float16x4(_mm_loadl_epi64((const __m128i*)ptr)); } -inline void v_store_f16(short* ptr, v_float16x4& a) -{ _mm_storel_epi64((__m128i*)ptr, a.val); } -#endif - -#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); \ -} -#define OPENCV_HAL_IMPL_SSE_REDUCE_OP_8_SUM(_Tpvec, scalartype, suffix) \ -inline scalartype v_reduce_sum(const v_##_Tpvec& a) \ -{ \ - __m128i val = a.val; \ - val = _mm_adds_epi##suffix(val, _mm_srli_si128(val, 8)); \ - val = _mm_adds_epi##suffix(val, _mm_srli_si128(val, 4)); \ - val = _mm_adds_epi##suffix(val, _mm_srli_si128(val, 2)); \ - return (scalartype)_mm_cvtsi128_si32(val); \ -} \ -inline unsigned scalartype v_reduce_sum(const v_u##_Tpvec& a) \ -{ \ - __m128i val = a.val; \ - val = _mm_adds_epu##suffix(val, _mm_srli_si128(val, 8)); \ - val = _mm_adds_epu##suffix(val, _mm_srli_si128(val, 4)); \ - val = _mm_adds_epu##suffix(val, _mm_srli_si128(val, 2)); \ - return (unsigned scalartype)_mm_cvtsi128_si32(val); \ -} -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) -OPENCV_HAL_IMPL_SSE_REDUCE_OP_8_SUM(int16x8, short, 16) - -#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 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) - -#define OPENCV_HAL_IMPL_SSE_POPCOUNT(_Tpvec) \ -inline v_uint32x4 v_popcount(const _Tpvec& 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)); \ - p = _mm_adds_epi8(p, _mm_srli_si128(p, 1)); \ - p = _mm_adds_epi8(p, _mm_srli_si128(p, 2)); \ - return v_uint32x4(_mm_and_si128(p, _mm_set1_epi32(0x000000ff))); \ -} - -OPENCV_HAL_IMPL_SSE_POPCOUNT(v_uint8x16) -OPENCV_HAL_IMPL_SSE_POPCOUNT(v_uint16x8) -OPENCV_HAL_IMPL_SSE_POPCOUNT(v_uint32x4) -OPENCV_HAL_IMPL_SSE_POPCOUNT(v_int8x16) -OPENCV_HAL_IMPL_SSE_POPCOUNT(v_int16x8) -OPENCV_HAL_IMPL_SSE_POPCOUNT(v_int32x4) - -#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) - -#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) - -#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpuvec, _Tpwuvec, _Tpu, _Tpsvec, _Tpwsvec, _Tps, suffix, wsuffix, shift) \ -inline void v_expand(const _Tpuvec& a, _Tpwuvec& b0, _Tpwuvec& b1) \ -{ \ - __m128i z = _mm_setzero_si128(); \ - b0.val = _mm_unpacklo_##suffix(a.val, z); \ - b1.val = _mm_unpackhi_##suffix(a.val, z); \ -} \ -inline _Tpwuvec v_load_expand(const _Tpu* ptr) \ -{ \ - __m128i z = _mm_setzero_si128(); \ - return _Tpwuvec(_mm_unpacklo_##suffix(_mm_loadl_epi64((const __m128i*)ptr), z)); \ -} \ -inline void v_expand(const _Tpsvec& a, _Tpwsvec& b0, _Tpwsvec& b1) \ -{ \ - b0.val = _mm_srai_##wsuffix(_mm_unpacklo_##suffix(a.val, a.val), shift); \ - b1.val = _mm_srai_##wsuffix(_mm_unpackhi_##suffix(a.val, a.val), shift); \ -} \ -inline _Tpwsvec v_load_expand(const _Tps* ptr) \ -{ \ - __m128i a = _mm_loadl_epi64((const __m128i*)ptr); \ - return _Tpwsvec(_mm_srai_##wsuffix(_mm_unpacklo_##suffix(a, a), shift)); \ -} - -OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, v_int8x16, v_int16x8, schar, epi8, epi16, 8) -OPENCV_HAL_IMPL_SSE_EXPAND(v_uint16x8, v_uint32x4, ushort, v_int16x8, v_int32x4, short, epi16, epi32, 16) - -inline void v_expand(const v_uint32x4& a, v_uint64x2& b0, v_uint64x2& b1) -{ - __m128i z = _mm_setzero_si128(); - b0.val = _mm_unpacklo_epi32(a.val, z); - b1.val = _mm_unpackhi_epi32(a.val, z); -} -inline v_uint64x2 v_load_expand(const unsigned* ptr) -{ - __m128i z = _mm_setzero_si128(); - return v_uint64x2(_mm_unpacklo_epi32(_mm_loadl_epi64((const __m128i*)ptr), z)); -} -inline void v_expand(const v_int32x4& a, v_int64x2& b0, v_int64x2& b1) -{ - __m128i s = _mm_srai_epi32(a.val, 31); - b0.val = _mm_unpacklo_epi32(a.val, s); - b1.val = _mm_unpackhi_epi32(a.val, s); -} -inline v_int64x2 v_load_expand(const int* ptr) -{ - __m128i a = _mm_loadl_epi64((const __m128i*)ptr); - __m128i s = _mm_srai_epi32(a, 31); - return v_int64x2(_mm_unpacklo_epi32(a, s)); -} - -inline v_uint32x4 v_load_expand_q(const uchar* ptr) -{ - __m128i z = _mm_setzero_si128(); - __m128i a = _mm_cvtsi32_si128(*(const int*)ptr); - return v_uint32x4(_mm_unpacklo_epi16(_mm_unpacklo_epi8(a, z), z)); -} - -inline v_int32x4 v_load_expand_q(const schar* ptr) -{ - __m128i a = _mm_cvtsi32_si128(*(const int*)ptr); - a = _mm_unpacklo_epi8(a, a); - a = _mm_unpacklo_epi8(a, a); - return v_int32x4(_mm_srai_epi32(a, 24)); -} - -#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) -{ - const int w = sizeof(typename _Tpvec::lane_type); - const int n = _Tpvec::nlanes; - __m128i ra, rb; - ra = _mm_srli_si128(a.val, s*w); - rb = _mm_slli_si128(b.val, (n-s)*w); - return _Tpvec(_mm_or_si128(ra, rb)); -} - -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_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) - -// adopted from sse_utils.hpp -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) -{ - __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)); -} - -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, v_uint16x8& c) -{ - __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)); -} - -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, 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 u0(_mm_loadu_si128((const __m128i*)ptr)); // a0 b0 c0 d0 - v_uint32x4 u1(_mm_loadu_si128((const __m128i*)(ptr + 4))); // a1 b1 c1 d1 - v_uint32x4 u2(_mm_loadu_si128((const __m128i*)(ptr + 8))); // a2 b2 c2 d2 - v_uint32x4 u3(_mm_loadu_si128((const __m128i*)(ptr + 12))); // a3 b3 c3 d3 - - v_transpose4x4(u0, u1, u2, u3, a, b, c, d); -} - -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); - __m128i t1 = _mm_loadu_si128((const __m128i*)(ptr + 2)); - __m128i t2 = _mm_loadu_si128((const __m128i*)(ptr + 4)); - - a = v_uint64x2(_mm_unpacklo_epi64(t0, _mm_unpackhi_epi64(t1, t1))); - b = v_uint64x2(_mm_unpacklo_epi64(_mm_unpackhi_epi64(t0, t0), t2)); - c = v_uint64x2(_mm_unpacklo_epi64(t1, _mm_unpackhi_epi64(t2, t2))); -} - -inline void v_load_deinterleave(const int64 *ptr, v_int64x2& a, v_int64x2& b, v_int64x2& c) -{ - v_uint64x2 t0, t1, t2; - v_load_deinterleave((const uint64*)ptr, t0, t1, t2); - a = v_reinterpret_as_s64(t0); - b = v_reinterpret_as_s64(t1); - c = v_reinterpret_as_s64(t2); -} - -inline void v_load_deinterleave(const double *ptr, v_float64x2& a, v_float64x2& b, v_float64x2& c) -{ - v_uint64x2 t0, t1, t2; - v_load_deinterleave((const uint64*)ptr, t0, t1, t2); - a = v_reinterpret_as_f64(t0); - b = v_reinterpret_as_f64(t1); - c = v_reinterpret_as_f64(t2); -} - -// 2-channel, float only -inline void v_load_deinterleave(const float* ptr, v_float32x4& a, v_float32x4& b) -{ - const int mask_lo = _MM_SHUFFLE(2, 0, 2, 0), mask_hi = _MM_SHUFFLE(3, 1, 3, 1); - - __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, mask_lo); // a0 a1 a2 a3 - b.val = _mm_shuffle_ps(u0, u1, mask_hi); // b0 b1 ab b3 -} - -inline void v_store_interleave( short* ptr, const v_int16x8& a, const v_int16x8& b ) -{ - __m128i t0, t1; - t0 = _mm_unpacklo_epi16(a.val, b.val); - t1 = _mm_unpackhi_epi16(a.val, b.val); - _mm_storeu_si128((__m128i*)(ptr), t0); - _mm_storeu_si128((__m128i*)(ptr + 8), t1); -} - -inline void v_store_interleave( uchar* ptr, const v_uint8x16& a, const v_uint8x16& b) -{ - __m128i v0 = _mm_unpacklo_epi8(a.val, b.val); - __m128i v1 = _mm_unpackhi_epi8(a.val, b.val); - - _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 ) -{ - __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)); - - _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) -{ - // 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_unpacklo_epi8(u1, u3); // a8 b8 c8 d8 ... - __m128i v2 = _mm_unpackhi_epi8(u0, u2); // a4 b4 c4 d4 ... - __m128i v3 = _mm_unpackhi_epi8(u1, u3); // a12 b12 c12 d12 ... - - _mm_storeu_si128((__m128i*)ptr, v0); - _mm_storeu_si128((__m128i*)(ptr + 16), v2); - _mm_storeu_si128((__m128i*)(ptr + 32), v1); - _mm_storeu_si128((__m128i*)(ptr + 48), v3); -} - -inline void v_store_interleave( ushort* ptr, const v_uint16x8& a, - const v_uint16x8& b, - const v_uint16x8& c ) -{ - __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)); - - _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) -{ - // 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_unpacklo_epi16(u1, u3); // a4 b4 c4 d4 ... - __m128i v2 = _mm_unpackhi_epi16(u0, u2); // a2 b2 c2 d2 ... - __m128i v3 = _mm_unpackhi_epi16(u1, u3); // a6 b6 c6 d6 ... - - _mm_storeu_si128((__m128i*)ptr, v0); - _mm_storeu_si128((__m128i*)(ptr + 8), v2); - _mm_storeu_si128((__m128i*)(ptr + 16), v1); - _mm_storeu_si128((__m128i*)(ptr + 24), v3); -} - -inline void v_store_interleave( unsigned* ptr, const v_uint32x4& a, const v_uint32x4& b, - const v_uint32x4& c ) -{ - 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)); - - _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) -{ - v_uint32x4 t0, t1, t2, t3; - v_transpose4x4(a, b, c, d, t0, t1, t2, t3); - v_store(ptr, t0); - v_store(ptr + 4, t1); - v_store(ptr + 8, t2); - v_store(ptr + 12, t3); -} - -// 2-channel, float only -inline void v_store_interleave(float* ptr, const v_float32x4& a, const v_float32x4& b) -{ - // a0 a1 a2 a3 ... - // b0 b1 b2 b3 ... - __m128 u0 = _mm_unpacklo_ps(a.val, b.val); // a0 b0 a1 b1 - __m128 u1 = _mm_unpackhi_ps(a.val, b.val); // a2 b2 a3 b3 - - _mm_storeu_ps(ptr, u0); - _mm_storeu_ps((ptr + 4), u1); -} - -inline void v_store_interleave(uint64 *ptr, const v_uint64x2& a, const v_uint64x2& b, const v_uint64x2& c) -{ - __m128i t0 = _mm_unpacklo_epi64(a.val, b.val); - __m128i t1 = _mm_unpacklo_epi64(c.val, _mm_unpackhi_epi64(a.val, a.val)); - __m128i t2 = _mm_unpackhi_epi64(b.val, c.val); - - _mm_storeu_si128((__m128i*)ptr, t0); - _mm_storeu_si128((__m128i*)(ptr + 2), t1); - _mm_storeu_si128((__m128i*)(ptr + 4), t2); -} - -inline void v_store_interleave(int64 *ptr, const v_int64x2& a, const v_int64x2& b, const v_int64x2& c) -{ - v_store_interleave((uint64*)ptr, v_reinterpret_as_u64(a), v_reinterpret_as_u64(b), v_reinterpret_as_u64(c)); -} - -inline void v_store_interleave(double *ptr, const v_float64x2& a, const v_float64x2& b, const v_float64x2& c) -{ - v_store_interleave((uint64*)ptr, v_reinterpret_as_u64(a), v_reinterpret_as_u64(b), v_reinterpret_as_u64(c)); -} - -#define OPENCV_HAL_IMPL_SSE_LOADSTORE_INTERLEAVE(_Tpvec, _Tp, suffix, _Tpuvec, _Tpu, usuffix) \ -inline void v_load_deinterleave( const _Tp* ptr, _Tpvec& a0, \ - _Tpvec& b0, _Tpvec& c0 ) \ -{ \ - _Tpuvec a1, b1, c1; \ - v_load_deinterleave((const _Tpu*)ptr, a1, b1, c1); \ - a0 = v_reinterpret_as_##suffix(a1); \ - b0 = v_reinterpret_as_##suffix(b1); \ - c0 = v_reinterpret_as_##suffix(c1); \ -} \ -inline void v_load_deinterleave( const _Tp* ptr, _Tpvec& a0, \ - _Tpvec& b0, _Tpvec& c0, _Tpvec& d0 ) \ -{ \ - _Tpuvec a1, b1, c1, d1; \ - v_load_deinterleave((const _Tpu*)ptr, a1, b1, c1, d1); \ - a0 = v_reinterpret_as_##suffix(a1); \ - b0 = v_reinterpret_as_##suffix(b1); \ - c0 = v_reinterpret_as_##suffix(c1); \ - d0 = v_reinterpret_as_##suffix(d1); \ -} \ -inline void v_store_interleave( _Tp* ptr, const _Tpvec& a0, \ - const _Tpvec& b0, const _Tpvec& c0 ) \ -{ \ - _Tpuvec a1 = v_reinterpret_as_##usuffix(a0); \ - _Tpuvec b1 = v_reinterpret_as_##usuffix(b0); \ - _Tpuvec c1 = v_reinterpret_as_##usuffix(c0); \ - v_store_interleave((_Tpu*)ptr, a1, b1, c1); \ -} \ -inline void v_store_interleave( _Tp* ptr, const _Tpvec& a0, const _Tpvec& b0, \ - const _Tpvec& c0, const _Tpvec& d0 ) \ -{ \ - _Tpuvec a1 = v_reinterpret_as_##usuffix(a0); \ - _Tpuvec b1 = v_reinterpret_as_##usuffix(b0); \ - _Tpuvec c1 = v_reinterpret_as_##usuffix(c0); \ - _Tpuvec d1 = v_reinterpret_as_##usuffix(d0); \ - v_store_interleave((_Tpu*)ptr, a1, b1, c1, d1); \ -} - -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_float32x4, float, f32, v_uint32x4, unsigned, u32) - -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_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_castsi128_ps(_mm_srli_si128(_mm_castps_si128(a.val),8)))); -} - -#if CV_FP16 -inline v_float32x4 v_cvt_f32(const v_float16x4& a) -{ - return v_float32x4(_mm_cvtph_ps(a.val)); -} - -inline v_float16x4 v_cvt_f16(const v_float32x4& a) -{ - return v_float16x4(_mm_cvtps_ph(a.val, 0)); -} -#endif - -//! @name Check SIMD support -//! @{ -//! @brief Check CPU capability of SIMD operation -static inline bool hasSIMD128() -{ - return (CV_CPU_HAS_SUPPORT_SSE2) ? true : false; -} - -//! @} - -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END - -//! @endcond - -} - -#endif diff --git a/3rdparty/libopencv/include/opencv2/core/hal/intrin_vsx.hpp b/3rdparty/libopencv/include/opencv2/core/hal/intrin_vsx.hpp deleted file mode 100644 index 9f050f7..0000000 --- a/3rdparty/libopencv/include/opencv2/core/hal/intrin_vsx.hpp +++ /dev/null @@ -1,962 +0,0 @@ -/*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_VSX_HPP -#define OPENCV_HAL_VSX_HPP - -#include -#include "opencv2/core/utility.hpp" - -#define CV_SIMD128 1 -#define CV_SIMD128_64F 1 - -/** - * todo: supporting half precision for power9 - * convert instractions xvcvhpsp, xvcvsphp -**/ - -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_INT_OP(_Tpvec, _Tp, ld_func, st_func) \ -inline _Tpvec v_load(const _Tp* ptr) \ -{ return _Tpvec(ld_func(0, ptr)); } \ -inline _Tpvec v_load_aligned(const _Tp* ptr) \ -{ return _Tpvec(ld_func(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_func(a.val, 0, ptr); } \ -inline void v_store_aligned(_Tp* ptr, const _Tpvec& a) \ -{ st_func(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); } - -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_uint8x16, uchar, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_int8x16, schar, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_uint16x8, ushort, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_int16x8, short, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_uint32x4, uint, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_int32x4, int, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_float32x4, float, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_float64x2, double, vsx_ld, vsx_st) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_uint64x2, uint64, vsx_ld2, vsx_st2) -OPENCV_HAL_IMPL_VSX_LOADSTORE_INT_OP(v_int64x2, int64, vsx_ld2, 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) \ -{ vec_st_interleave(a.val, b.val, ptr); } \ -inline void v_store_interleave(_Tp* ptr, const _Tpvec& a, \ - const _Tpvec& b, const _Tpvec& c) \ -{ 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) \ -{ 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) - -/* 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_load_expand(const _Tp* ptr) \ -{ return _Tpwvec(fh(vsx_ld(0, 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_ld_buw(ptr)); } - -inline v_int32x4 v_load_expand_q(const schar* ptr) -{ return v_int32x4(vec_ld_bsw(ptr)); } - -/* 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) - -/* 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); -} - -/* Extract */ -template -inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) -{ - const int w = sizeof(typename _Tpvec::lane_type); - const int n = _Tpvec::nlanes; - const unsigned int sf = ((w * n) - (s * w)); - if (s == 0) - return _Tpvec(a.val); - else if (sf > 15) - return _Tpvec(); - // bitwise it just to make xlc happy - return _Tpvec(vec_sld(b.val, a.val, sf & 15)); -} - -#define OPENCV_HAL_IMPL_VSX_EXTRACT_2(_Tpvec) \ -template \ -inline _Tpvec v_extract(const _Tpvec& a, const _Tpvec& b) \ -{ \ - switch(s) { \ - case 0: return _Tpvec(a.val); \ - case 2: return _Tpvec(b.val); \ - case 1: return _Tpvec(vec_sldw(b.val, a.val, 2)); \ - default: return _Tpvec(); \ - } \ -} -OPENCV_HAL_IMPL_VSX_EXTRACT_2(v_uint64x2) -OPENCV_HAL_IMPL_VSX_EXTRACT_2(v_int64x2) - - -////////// 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_uint16x8, vec_mul) -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_int16x8, vec_mul) -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) - -inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b, v_int32x4& c, v_int32x4& d) -{ - c.val = vec_mul(vec_unpackh(a.val), vec_unpackh(b.val)); - d.val = vec_mul(vec_unpackl(a.val), vec_unpackl(b.val)); -} -inline void v_mul_expand(const v_uint16x8& a, const v_uint16x8& b, v_uint32x4& c, v_uint32x4& 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 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)); -} - -/** 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) - -/** 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) - -/** 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_uint64x2, vec_udword2) -OPENCV_IMPL_VSX_ROTATE_LR(v_int64x2, vec_dword2) - - -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(_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; \ -} - -OPENCV_IMPL_VSX_ROTATE_64(v_int64x2, right, a, b) -OPENCV_IMPL_VSX_ROTATE_64(v_uint64x2, right, a, b) - -OPENCV_IMPL_VSX_ROTATE_64(v_int64x2, left, b, a) -OPENCV_IMPL_VSX_ROTATE_64(v_uint64x2, left, b, a) - -////////// Reduce and mask ///////// - -/** Reduce **/ -inline short 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 ushort 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) - -#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) - -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)); -} - -/** Popcount **/ -template -inline v_uint32x4 v_popcount(const _Tpvec& a) -{ return v_uint32x4(vec_popcntu(vec_uint4_c(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)); } - - -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)); } - -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)); } - -////////// 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_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) - -// 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)); } - -OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_absdiff, vec_absd) - -#define OPENCV_HAL_IMPL_VSX_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_VSX_BIN_FUNC2(v_int8x16, v_uint8x16, vec_uchar16_c, v_absdiff, vec_absd) -OPENCV_HAL_IMPL_VSX_BIN_FUNC2(v_int16x8, v_uint16x8, vec_ushort8_c, v_absdiff, vec_absd) -OPENCV_HAL_IMPL_VSX_BIN_FUNC2(v_int32x4, v_uint32x4, vec_uint4_c, v_absdiff, vec_absd) -OPENCV_HAL_IMPL_VSX_BIN_FUNC2(v_int64x2, v_uint64x2, vec_udword2_c, v_absdiff, vec_absd) - -////////// Conversions ///////// - -/** Rounding **/ -inline v_int32x4 v_round(const v_float32x4& a) -{ return v_int32x4(vec_cts(vec_round(a.val))); } - -inline v_int32x4 v_round(const v_float64x2& a) -{ return v_int32x4(vec_mergesqo(vec_ctso(vec_round(a.val)), vec_int4_z)); } - -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_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))); } - -/** 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_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) - -//! @name Check SIMD support -//! @{ -//! @brief Check CPU capability of SIMD operation -static inline bool hasSIMD128() -{ - return (CV_CPU_HAS_SUPPORT_VSX) ? true : false; -} - -//! @} - -CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END - -//! @endcond - -} - -#endif // OPENCV_HAL_VSX_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/ippasync.hpp b/3rdparty/libopencv/include/opencv2/core/ippasync.hpp deleted file mode 100644 index 0ed8264..0000000 --- a/3rdparty/libopencv/include/opencv2/core/ippasync.hpp +++ /dev/null @@ -1,195 +0,0 @@ -/*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, 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_IPPASYNC_HPP -#define OPENCV_CORE_IPPASYNC_HPP - -#ifdef HAVE_IPP_A - -#include "opencv2/core.hpp" -#include -#include - -namespace cv -{ - -namespace hpp -{ - -/** @addtogroup core_ipp -This section describes conversion between OpenCV and [Intel® IPP Asynchronous -C/C++](http://software.intel.com/en-us/intel-ipp-preview) library. [Getting Started -Guide](http://registrationcenter.intel.com/irc_nas/3727/ipp_async_get_started.htm) help you to -install the library, configure header and library build paths. - */ -//! @{ - - //! convert OpenCV data type to hppDataType - inline int toHppType(const int cvType) - { - int depth = CV_MAT_DEPTH(cvType); - int hppType = depth == CV_8U ? HPP_DATA_TYPE_8U : - depth == CV_16U ? HPP_DATA_TYPE_16U : - depth == CV_16S ? HPP_DATA_TYPE_16S : - depth == CV_32S ? HPP_DATA_TYPE_32S : - depth == CV_32F ? HPP_DATA_TYPE_32F : - depth == CV_64F ? HPP_DATA_TYPE_64F : -1; - CV_Assert( hppType >= 0 ); - return hppType; - } - - //! convert hppDataType to OpenCV data type - inline int toCvType(const int hppType) - { - int cvType = hppType == HPP_DATA_TYPE_8U ? CV_8U : - hppType == HPP_DATA_TYPE_16U ? CV_16U : - hppType == HPP_DATA_TYPE_16S ? CV_16S : - hppType == HPP_DATA_TYPE_32S ? CV_32S : - hppType == HPP_DATA_TYPE_32F ? CV_32F : - hppType == HPP_DATA_TYPE_64F ? CV_64F : -1; - CV_Assert( cvType >= 0 ); - return cvType; - } - - /** @brief Convert hppiMatrix to Mat. - - This function allocates and initializes new matrix (if needed) that has the same size and type as - input matrix. Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F. - @param src input hppiMatrix. - @param dst output matrix. - @param accel accelerator instance (see hpp::getHpp for the list of acceleration framework types). - @param cn number of channels. - */ - inline void copyHppToMat(hppiMatrix* src, Mat& dst, hppAccel accel, int cn) - { - hppDataType type; - hpp32u width, height; - hppStatus sts; - - if (src == NULL) - return dst.release(); - - sts = hppiInquireMatrix(src, &type, &width, &height); - - CV_Assert( sts == HPP_STATUS_NO_ERROR); - - int matType = CV_MAKETYPE(toCvType(type), cn); - - CV_Assert(width%cn == 0); - - width /= cn; - - dst.create((int)height, (int)width, (int)matType); - - size_t newSize = (size_t)(height*(hpp32u)(dst.step)); - - sts = hppiGetMatrixData(accel,src,(hpp32u)(dst.step),dst.data,&newSize); - - CV_Assert( sts == HPP_STATUS_NO_ERROR); - } - - /** @brief Create Mat from hppiMatrix. - - This function allocates and initializes the Mat that has the same size and type as input matrix. - Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F. - @param src input hppiMatrix. - @param accel accelerator instance (see hpp::getHpp for the list of acceleration framework types). - @param cn number of channels. - @sa howToUseIPPAconversion, hpp::copyHppToMat, hpp::getHpp. - */ - inline Mat getMat(hppiMatrix* src, hppAccel accel, int cn) - { - Mat dst; - copyHppToMat(src, dst, accel, cn); - return dst; - } - - /** @brief Create hppiMatrix from Mat. - - This function allocates and initializes the hppiMatrix that has the same size and type as input - matrix, returns the hppiMatrix*. - - If you want to use zero-copy for GPU you should to have 4KB aligned matrix data. See details - [hppiCreateSharedMatrix](http://software.intel.com/ru-ru/node/501697). - - Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F. - - @note The hppiMatrix pointer to the image buffer in system memory refers to the src.data. Control - the lifetime of the matrix and don't change its data, if there is no special need. - @param src input matrix. - @param accel accelerator instance. Supports type: - - **HPP_ACCEL_TYPE_CPU** - accelerated by optimized CPU instructions. - - **HPP_ACCEL_TYPE_GPU** - accelerated by GPU programmable units or fixed-function - accelerators. - - **HPP_ACCEL_TYPE_ANY** - any acceleration or no acceleration available. - @sa howToUseIPPAconversion, hpp::getMat - */ - inline hppiMatrix* getHpp(const Mat& src, hppAccel accel) - { - int htype = toHppType(src.type()); - int cn = src.channels(); - - CV_Assert(src.data); - hppAccelType accelType = hppQueryAccelType(accel); - - if (accelType!=HPP_ACCEL_TYPE_CPU) - { - hpp32u pitch, size; - hppQueryMatrixAllocParams(accel, src.cols*cn, src.rows, htype, &pitch, &size); - if (pitch!=0 && size!=0) - if ((int)(src.data)%4096==0 && pitch==(hpp32u)(src.step)) - { - return hppiCreateSharedMatrix(htype, src.cols*cn, src.rows, src.data, pitch, size); - } - } - - return hppiCreateMatrix(htype, src.cols*cn, src.rows, src.data, (hpp32s)(src.step));; - } - -//! @} -}} - -#endif - -#endif diff --git a/3rdparty/libopencv/include/opencv2/core/mat.hpp b/3rdparty/libopencv/include/opencv2/core/mat.hpp deleted file mode 100644 index ca1b3aa..0000000 --- a/3rdparty/libopencv/include/opencv2/core/mat.hpp +++ /dev/null @@ -1,3661 +0,0 @@ -/*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" - -#ifdef CV_CXX11 -#include -#endif - -namespace cv -{ - -//! @addtogroup core_basic -//! @{ - -enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25, - ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 }; - -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. - */ -class CV_EXPORTS _InputArray -{ -public: - enum { - 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 >&); - 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); - -#ifdef CV_CXX_STD_ARRAY - template _InputArray(const std::array<_Tp, _Nm>& arr); - template _InputArray(const std::array& arr); -#endif - - 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; - - int 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 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); -}; - - -/** @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 - { - 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_ALL = (DEPTH_MASK_64F<<1)-1, - DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S, - 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); - template _OutputArray(std::vector >& vec); - _OutputArray(std::vector >&); - 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); - -#ifdef CV_CXX_STD_ARRAY - 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); -#endif - - 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, int fixedDepthMask=0) const; - void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; - void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=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; -}; - - -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); - 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); - -#ifdef CV_CXX_STD_ARRAY - 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); -#endif - -}; - -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, int flags, UMatUsageFlags usageFlags) const = 0; - virtual bool allocate(UMatData* data, int accessflags, UMatUsageFlags usageFlags) const = 0; - virtual void deallocate(UMatData* data) const = 0; - virtual void map(UMatData* data, int 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 { 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; - - int flags; - void* handle; - void* userdata; - int allocatorFlags_; - int mapcount; - UMatData* originalUMatData; -}; - - -struct CV_EXPORTS MatSize -{ - explicit MatSize(int* _p); - Size operator()() const; - const int& operator[](int i) const; - int& operator[](int i); - operator const int*() const; - 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 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 fully compatible with CvMat, IplImage, and CvMatND types from OpenCV -1.x. It is also compatible with the majority of dense array types from the standard toolkits and -SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any -array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this -compatibility, it is possible to make a Mat header for user-allocated data and process it in-place -using OpenCV functions. - -There are many different ways to create a Mat object. The most popular options are listed below: - -- Use the create(nrows, ncols, type) method or the similar Mat(nrows, ncols, type[, fillValue]) -constructor. A new array of the specified size and type is allocated. type has the same meaning as -in the cvCreateMat method. For example, CV_8UC1 means a 8-bit single-channel array, CV_32FC2 -means a 2-channel (complex) floating-point array, and so on. -@code - // make a 7x7 complex matrix filled with 1+3j. - Mat M(7,7,CV_32FC2,Scalar(1,3)); - // and now turn M to a 100x60 15-channel 8-bit matrix. - // The old content will be deallocated - M.create(100,60,CV_8UC(15)); -@endcode -As noted in the introduction to this chapter, create() allocates only a new array when the shape -or type of the current array are different from the specified ones. - -- Create a multi-dimensional array: -@code - // create a 100x100x100 8-bit array - int sz[] = {100, 100, 100}; - Mat bigCube(3, sz, CV_8U, Scalar::all(0)); -@endcode -It passes the number of dimensions =1 to the Mat constructor but the created array will be -2-dimensional with the number of columns set to 1. So, Mat::dims is always \>= 2 (can also be 0 -when the array is empty). - -- Use a copy constructor or assignment operator where there can be an array or expression on the -right side (see below). As noted in the introduction, the array assignment is an O(1) operation -because it only copies the header and increases the reference counter. The Mat::clone() method can -be used to get a full (deep) copy of the array when you need it. - -- Construct a header for a part of another array. It can be a single row, single column, several -rows, several columns, rectangular region in the array (called a *minor* in algebra) or a -diagonal. Such operations are also O(1) because the new header references the same data. You can -actually modify a part of the array using this feature, for example: -@code - // add the 5-th row, multiplied by 3 to the 3rd row - M.row(3) = M.row(3) + M.row(5)*3; - // now copy the 7-th column to the 1-st column - // M.col(1) = M.col(7); // this will not work - Mat M1 = M.col(1); - M.col(7).copyTo(M1); - // create a new 320x240 image - Mat img(Size(320,240),CV_8UC3); - // select a ROI - Mat roi(img, Rect(10,10,100,100)); - // fill the ROI with (0,255,0) (which is green in RGB space); - // the original 320x240 image will be modified - roi = Scalar(0,255,0); -@endcode -Due to the additional datastart and dataend members, it is possible to compute a relative -sub-array position in the main *container* array using locateROI(): -@code - Mat A = Mat::eye(10, 10, CV_32S); - // extracts A columns, 1 (inclusive) to 3 (exclusive). - Mat B = A(Range::all(), Range(1, 3)); - // extracts B rows, 5 (inclusive) to 9 (exclusive). - // that is, C \~ A(Range(5, 9), Range(1, 3)) - Mat C = B(Range(5, 9), Range::all()); - Size size; Point ofs; - C.locateROI(size, ofs); - // size will be (width=10,height=10) and the ofs will be (x=1, y=5) -@endcode -As in case of whole matrices, if you need a deep copy, use the `clone()` method of the extracted -sub-matrices. - -- Make a header for user-allocated data. It can be useful to do the following: - -# Process "foreign" data using OpenCV (for example, when you implement a DirectShow\* filter or - a processing module for gstreamer, and so on). For example: - @code - void process_video_frame(const unsigned char* pixels, - int width, int height, int step) - { - Mat img(height, width, CV_8UC3, pixels, step); - GaussianBlur(img, img, Size(7,7), 1.5, 1.5); - } - @endcode - -# Quickly initialize small matrices and/or get a super-fast element access. - @code - double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; - Mat M = Mat(3, 3, CV_64F, m).inv(); - @endcode - . - Partial yet very common cases of this *user-allocated data* case are conversions from CvMat and - IplImage to Mat. For this purpose, there is function cv::cvarrToMat taking pointers to CvMat or - IplImage and the optional flag indicating whether to copy the data or not. - @snippet samples/cpp/image.cpp iplimage - -- 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); - -#ifdef CV_CXX11 - /** @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); -#endif - -#ifdef CV_CXX_STD_ARRAY - /** @overload - */ - template explicit Mat(const std::array<_Tp, _Nm>& arr, bool copyData=false); -#endif - - /** @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(int 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; - - /** @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. - @param rows Number of rows. - @param cols Number of columns. - @param type Created matrix type. - */ - static MatExpr ones(int rows, int cols, int type); - - /** @overload - @param size Alternative to the matrix size specification Size(cols, rows) . - @param type Created matrix type. - */ - static MatExpr ones(Size size, int type); - - /** @overload - @param ndims Array dimensionality. - @param sz Array of integers specifying the array shape. - @param type Created matrix type. - */ - static MatExpr ones(int ndims, const int* sz, int type); - - /** @brief Returns an identity matrix of the specified size and type. - - The method returns a Matlab-style identity matrix initializer, similarly to Mat::zeros. Similarly to - Mat::ones, you can use a scale operation to create a scaled identity matrix efficiently: - @code - // make a 4x4 diagonal matrix with 0.1's on the diagonal. - Mat A = Mat::eye(4, 4, CV_32F)*0.1; - @endcode - @param rows Number of rows. - @param cols Number of columns. - @param type Created matrix type. - */ - static MatExpr eye(int rows, int cols, int type); - - /** @overload - @param size Alternative matrix size specification as Size(cols, rows) . - @param type Created matrix type. - */ - static MatExpr eye(Size size, int type); - - /** @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; - - // //! converts header to CvMat; no data is copied - // operator CvMat() const; - // //! converts header to CvMatND; no data is copied - // operator CvMatND() const; - // //! converts header to IplImage; no data is copied - // operator IplImage() const; - - template operator std::vector<_Tp>() const; - template operator Vec<_Tp, n>() const; - template operator Matx<_Tp, m, n>() const; - -#ifdef CV_CXX_STD_ARRAY - template operator std::array<_Tp, _Nm>() const; -#endif - - /** @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; - -#ifdef CV_CXX_MOVE_SEMANTICS - Mat(Mat&& m); - Mat& operator = (Mat&& m); -#endif - - 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); - - //! 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); - -#ifdef CV_CXX11 - Mat_(std::initializer_list<_Tp> values); - explicit Mat_(const std::initializer_list sizes, const std::initializer_list<_Tp> values); -#endif - -#ifdef CV_CXX_STD_ARRAY - template explicit Mat_(const std::array<_Tp, _Nm>& arr, bool copyData=false); -#endif - - 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; - - //! 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; - -#ifdef CV_CXX_STD_ARRAY - //! conversion to array. - template operator std::array<_Tp, _Nm>() const; -#endif - - //! conversion to Vec - template operator Vec::channel_type, n>() const; - //! conversion to Matx - template operator Matx::channel_type, m, n>() const; - -#ifdef CV_CXX_MOVE_SEMANTICS - Mat_(Mat_&& m); - Mat_& operator = (Mat_&& m); - - Mat_(Mat&& m); - Mat_& operator = (Mat&& m); - - Mat_(MatExpr&& e); -#endif -}; - -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(int 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; - //! 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; - -#ifdef CV_CXX_MOVE_SEMANTICS - UMat(UMat&& m); - UMat& operator = (UMat&& m); -#endif - - /*! 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(int 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(); - - // 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; - - //! 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; - //! 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); - -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); - -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); - -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); - -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 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 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 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 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 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 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 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 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 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); - -CV_EXPORTS MatExpr max(const Mat& a, const Mat& b); -CV_EXPORTS MatExpr max(const Mat& a, double s); -CV_EXPORTS MatExpr max(double s, const Mat& a); - -/** @brief Calculates an absolute value of each matrix element. - -abs is a meta-function that is expanded to one of absdiff or convertScaleAbs forms: -- C = abs(A-B) is equivalent to `absdiff(A, B, C)` -- C = abs(A) is equivalent to `absdiff(A, Scalar::all(0), C)` -- C = `Mat_ >(abs(A*alpha + beta))` is equivalent to `convertScaleAbs(A, C, alpha, -beta)` - -The output matrix has the same size and the same type as the input one except for the last case, -where C is depth=CV_8U . -@param m matrix. -@sa @ref MatrixExpressions, absdiff, convertScaleAbs - */ -CV_EXPORTS MatExpr abs(const Mat& m); -/** @overload -@param e matrix expression. -*/ -CV_EXPORTS MatExpr abs(const MatExpr& e); -//! @} relates cv::MatExpr - -} // cv - -#include "opencv2/core/mat.inl.hpp" - -#endif // OPENCV_CORE_MAT_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/mat.inl.hpp b/3rdparty/libopencv/include/opencv2/core/mat.inl.hpp deleted file mode 100644 index 5f54d1f..0000000 --- a/3rdparty/libopencv/include/opencv2/core/mat.inl.hpp +++ /dev/null @@ -1,3939 +0,0 @@ -/*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 - -//////////////////////// 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(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); } - -#ifdef CV_CXX_STD_ARRAY -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)); } -#endif - -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); } - -inline -_InputArray::_InputArray(const std::vector >&) -{ CV_Error(Error::StsUnsupportedFormat, "std::vector > is not supported!\n"); } - -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); } - -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::isGpuMatVector() const { return kind() == _InputArray::STD_VECTOR_CUDA_GPU_MAT; } - -//////////////////////////////////////////////////////////////////////////////////////// - -inline _OutputArray::_OutputArray() { init(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); } - -#ifdef CV_CXX_STD_ARRAY -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)); } -#endif - -inline -_OutputArray::_OutputArray(std::vector&) -{ CV_Error(Error::StsUnsupportedFormat, "std::vector cannot be an output array\n"); } - -template inline -_OutputArray::_OutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } - -inline -_OutputArray::_OutputArray(std::vector >&) -{ CV_Error(Error::StsUnsupportedFormat, "std::vector > cannot be an output array\n"); } - -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); } - -#ifdef CV_CXX_STD_ARRAY -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)); } -#endif - -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); } - -/////////////////////////////////////////////////////////////////////////////////////////// - -inline _InputOutputArray::_InputOutputArray() { init(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); } - -#ifdef CV_CXX_STD_ARRAY -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)); } -#endif - -inline _InputOutputArray::_InputOutputArray(std::vector&) -{ CV_Error(Error::StsUnsupportedFormat, "std::vector cannot be an input/output array\n"); } - -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); } - -#ifdef CV_CXX_STD_ARRAY -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)); } -#endif - -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); } - -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; - flags |= CONTINUOUS_FLAG; - } - else - { - CV_DbgAssert( _step >= minstep ); - - if (_step % esz1 != 0) - { - CV_Error(Error::BadStep, "Step must be a multiple of esz1"); - } - - if (_step == minstep || rows == 1) - flags |= CONTINUOUS_FLAG; - } - step[0] = _step; - step[1] = esz; - datalimit = datastart + _step * rows; - dataend = datalimit - _step + minstep; -} - -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; - flags |= CONTINUOUS_FLAG; - } - else - { - CV_DbgAssert( _step >= minstep ); - - if (_step % esz1 != 0) - { - CV_Error(Error::BadStep, "Step must be a multiple of esz1"); - } - - if (_step == minstep || rows == 1) - flags |= CONTINUOUS_FLAG; - } - step[0] = _step; - step[1] = esz; - datalimit = datastart + _step*rows; - dataend = datalimit - _step + minstep; -} - -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); -} - -#ifdef CV_CXX11 -template inline -Mat::Mat(const std::initializer_list<_Tp> list) - : flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)list.size()), - cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) -{ - if(list.size() == 0) - return; - 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; - int *sz = (int*)sizes.begin(); - for(auto s : sizes) - size_total *= s; - CV_Assert(list.size() != 0 || size_total == list.size()); - Mat((int)sizes.size(), sz, traits::Type<_Tp>::value, (uchar*)list.begin()).copyTo(*this); -} -#endif - -#ifdef CV_CXX_STD_ARRAY -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); -} -#endif - -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 -{ - return dims > 0 ? step.p[dims - 1] : 0; -} - -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 && data && (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; -} - -#ifdef CV_CXX_STD_ARRAY -template inline -Mat::operator std::array<_Tp, _Nm>() const -{ - std::array<_Tp, _Nm> v; - copyTo(v); - return v; -} -#endif - -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)); -} - -#ifdef CV_CXX_MOVE_SEMANTICS - -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; -} - -#endif - - -///////////////////////////// MatSize //////////////////////////// - -inline -MatSize::MatSize(int* _p) - : p(_p) {} - -inline -Size MatSize::operator()() const -{ - CV_DbgAssert(p[-1] <= 2); - return Size(p[1], p[0]); -} - -inline -const int& MatSize::operator[](int i) const -{ - return p[i]; -} - -inline -int& MatSize::operator[](int i) -{ - return p[i]; -} - -inline -MatSize::operator const int*() const -{ - return p; -} - -inline -bool MatSize::operator == (const MatSize& sz) const -{ - int d = p[-1]; - int dsz = sz.p[-1]; - 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) -{} - -#ifdef CV_CXX11 -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) -{} -#endif - -#ifdef CV_CXX_STD_ARRAY -template template inline -Mat_<_Tp>::Mat_(const std::array<_Tp, _Nm>& arr, bool copyData) - : Mat(arr, copyData) -{} -#endif - -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_DbgAssert(DataType<_Tp>::channels == m.channels()); - 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; -} - -#ifdef CV_CXX_STD_ARRAY -template template inline -Mat_<_Tp>::operator std::array<_Tp, _Nm>() const -{ - std::array<_Tp, _Nm> a; - copyTo(a); - return a; -} -#endif - -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); -} - -#ifdef CV_CXX_MOVE_SEMANTICS - -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); -} - -#endif - -///////////////////////////// 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 -{ - return dims > 0 ? step.p[dims - 1] : 0; -} - -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; -} - -#ifdef CV_CXX_MOVE_SEMANTICS - -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; -} - -#endif - - -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/3rdparty/libopencv/include/opencv2/core/matx.hpp b/3rdparty/libopencv/include/opencv2/core/matx.hpp deleted file mode 100644 index e664a3e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/matx.hpp +++ /dev/null @@ -1,1476 +0,0 @@ -/*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" - -#ifdef CV_CXX11 -#include -#endif - -namespace cv -{ - -//! @addtogroup core_basic -//! @{ - -////////////////////////////// Small Matrix /////////////////////////// - -//! @cond IGNORED -struct CV_EXPORTS Matx_AddOp {}; -struct CV_EXPORTS Matx_SubOp {}; -struct CV_EXPORTS Matx_ScaleOp {}; -struct CV_EXPORTS Matx_MulOp {}; -struct CV_EXPORTS Matx_DivOp {}; -struct CV_EXPORTS Matx_MatMulOp {}; -struct CV_EXPORTS Matx_TOp {}; -//! @endcond - -/** @brief Template class for small matrices whose type and size are known at compilation time - -If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the -M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are -available. To do an operation on Matx that is not implemented, you can easily convert the matrix to -Mat and backwards: -@code{.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(); - - 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 - -#ifdef CV_CXX11 - Matx(std::initializer_list<_Tp>); //!< initialize from an initializer list -#endif - - 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 i, int j) 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 i, int j) const; - _Tp& operator ()(int i, int j); - - //! 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); - -#ifdef CV_CXX11 - Vec(std::initializer_list<_Tp>); -#endif - - 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); - - 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]; -} - -#ifdef CV_CXX11 -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; - } -} -#endif - -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 i, int j) const -{ - CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+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)(i+di, j+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 i, int j) const -{ - CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); - return this->val[i*n + j]; -} - -template inline -_Tp& Matx<_Tp, m, n>::operator ()(int i, int j) -{ - CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n ); - return val[i*n + j]; -} - -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) {} - -#ifdef CV_CXX11 -template inline -Vec<_Tp, cn>::Vec(std::initializer_list<_Tp> list) - : Matx<_Tp, cn, 1>(list) {} -#endif - -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/3rdparty/libopencv/include/opencv2/core/neon_utils.hpp b/3rdparty/libopencv/include/opencv2/core/neon_utils.hpp deleted file mode 100644 index 573ba99..0000000 --- a/3rdparty/libopencv/include/opencv2/core/neon_utils.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/ocl.hpp b/3rdparty/libopencv/include/opencv2/core/ocl.hpp deleted file mode 100644 index 888477e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/ocl.hpp +++ /dev/null @@ -1,842 +0,0 @@ -/*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 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 Device -{ -public: - Device(); - explicit Device(void* d); - Device(const Device& d); - Device& operator = (const Device& d); - ~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 - }; - - String name() const; - String extensions() const; - bool isExtensionSupported(const String& extensionName) const; - String version() const; - String vendorName() const; - String OpenCL_C_Version() const; - String OpenCLVersion() const; - int deviceVersionMajor() const; - int deviceVersionMinor() const; - String driverVersion() const; - void* ptr() const; - - int type() const; - - int addressBits() const; - bool available() const; - bool compilerAvailable() const; - 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) - }; - int doubleFPConfig() const; - int singleFPConfig() const; - int halfFPConfig() const; - - bool endianLittle() const; - bool errorCorrectionSupport() const; - - enum - { - EXEC_KERNEL=(1 << 0), - EXEC_NATIVE_KERNEL=(1 << 1) - }; - int executionCapabilities() const; - - size_t globalMemCacheSize() const; - - enum - { - NO_CACHE=0, - READ_ONLY_CACHE=1, - READ_WRITE_CACHE=2 - }; - int globalMemCacheType() const; - int globalMemCacheLineSize() const; - size_t globalMemSize() const; - - size_t localMemSize() const; - enum - { - NO_LOCAL_MEM=0, - LOCAL_IS_LOCAL=1, - LOCAL_IS_GLOBAL=2 - }; - int localMemType() const; - bool hostUnifiedMemory() const; - - bool imageSupport() const; - - bool imageFromBufferSupport() const; - uint imagePitchAlignment() const; - uint imageBaseAddressAlignment() const; - - /// deprecated, use isExtensionSupported() method (probably with "cl_khr_subgroups" value) - bool intelSubgroupsSupport() const; - - size_t image2DMaxWidth() const; - size_t image2DMaxHeight() const; - - size_t image3DMaxWidth() const; - size_t image3DMaxHeight() const; - size_t image3DMaxDepth() const; - - size_t imageMaxBufferSize() const; - size_t imageMaxArraySize() const; - - enum - { - UNKNOWN_VENDOR=0, - VENDOR_AMD=1, - VENDOR_INTEL=2, - VENDOR_NVIDIA=3 - }; - 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() - inline bool isAMD() const { return vendorID() == VENDOR_AMD; } - inline bool isIntel() const { return vendorID() == VENDOR_INTEL; } - inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; } - - int maxClockFrequency() const; - int maxComputeUnits() const; - int maxConstantArgs() const; - size_t maxConstantBufferSize() const; - - size_t maxMemAllocSize() const; - size_t maxParameterSize() const; - - int maxReadImageArgs() const; - int maxWriteImageArgs() const; - int maxSamplers() const; - - size_t maxWorkGroupSize() const; - int maxWorkItemDims() const; - void maxWorkItemSizes(size_t*) const; - - int memBaseAddrAlign() const; - - int nativeVectorWidthChar() const; - int nativeVectorWidthShort() const; - int nativeVectorWidthInt() const; - int nativeVectorWidthLong() const; - int nativeVectorWidthFloat() const; - int nativeVectorWidthDouble() const; - int nativeVectorWidthHalf() const; - - int preferredVectorWidthChar() const; - int preferredVectorWidthShort() const; - int preferredVectorWidthInt() const; - int preferredVectorWidthLong() const; - int preferredVectorWidthFloat() const; - int preferredVectorWidthDouble() const; - int preferredVectorWidthHalf() const; - - size_t printfBufferSize() const; - size_t profilingTimerResolution() const; - - 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() { return KernelArg(LOCAL, 0); } - 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)); } - - template - Kernel& args(const _Tp0& a0) - { - set(0, a0); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1) - { - int i = set(0, a0); set(i, a1); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2) - { - int i = set(0, a0); i = set(i, a1); set(i, a2); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, - const _Tp3& a3, const _Tp4& a4) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); - i = set(i, a3); set(i, a4); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, - const _Tp3& a3, const _Tp4& a4, const _Tp5& a5) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); - i = set(i, a3); i = set(i, a4); set(i, a5); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); - i = set(i, a4); i = set(i, a5); set(i, a6); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); - i = set(i, a4); i = set(i, a5); i = set(i, a6); set(i, a7); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); - i = set(i, a5); i = set(i, a6); i = set(i, a7); set(i, a8); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8, const _Tp9& a9) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5); - i = set(i, a6); i = set(i, a7); i = set(i, a8); set(i, a9); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8, const _Tp9& a9, const _Tp10& a10) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5); - i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); set(i, a10); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5); - i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); set(i, a11); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11, - const _Tp12& a12) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5); - i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11); - set(i, a12); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11, - const _Tp12& a12, const _Tp13& a13) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5); - i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11); - i = set(i, a12); set(i, a13); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11, - const _Tp12& a12, const _Tp13& a13, const _Tp14& a14) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5); - i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11); - i = set(i, a12); i = set(i, a13); set(i, a14); return *this; - } - - template - Kernel& args(const _Tp0& a0, const _Tp1& a1, const _Tp2& a2, const _Tp3& a3, - const _Tp4& a4, const _Tp5& a5, const _Tp6& a6, const _Tp7& a7, - const _Tp8& a8, const _Tp9& a9, const _Tp10& a10, const _Tp11& a11, - const _Tp12& a12, const _Tp13& a13, const _Tp14& a14, const _Tp15& a15) - { - int i = set(0, a0); i = set(i, a1); i = set(i, a2); i = set(i, a3); i = set(i, a4); i = set(i, a5); - i = set(i, a6); i = set(i, a7); i = set(i, a8); i = set(i, a9); i = set(i, a10); i = set(i, a11); - i = set(i, a12); i = set(i, a13); i = set(i, a14); set(i, a15); 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/3rdparty/libopencv/include/opencv2/core/ocl_genbase.hpp b/3rdparty/libopencv/include/opencv2/core/ocl_genbase.hpp deleted file mode 100644 index 5334cf1..0000000 --- a/3rdparty/libopencv/include/opencv2/core/ocl_genbase.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/opencl/ocl_defs.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/ocl_defs.hpp deleted file mode 100644 index 605a65f..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/ocl_defs.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// 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, ...) \ - if (cv::ocl::isOpenCLActivated() && (condition) && func) \ - { \ - CV_IMPL_ADD(CV_IMPL_OCL); \ - return __VA_ARGS__; \ - } -#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/3rdparty/libopencv/include/opencv2/core/opencl/opencl_info.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/opencl_info.hpp deleted file mode 100644 index fdd2703..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/opencl_info.hpp +++ /dev/null @@ -1,198 +0,0 @@ -// 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_ErrorNoReturn(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/3rdparty/libopencv/include/opencv2/core/opencl/opencl_svm.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/opencl_svm.hpp deleted file mode 100644 index 7453082..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/opencl_svm.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp deleted file mode 100644 index 65c8493..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp +++ /dev/null @@ -1,714 +0,0 @@ -// -// 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp deleted file mode 100644 index 1457d7e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// -// 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp deleted file mode 100644 index fdaf469..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp +++ /dev/null @@ -1,370 +0,0 @@ -// -// 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__ -#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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp deleted file mode 100644 index 216b22b..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp +++ /dev/null @@ -1,272 +0,0 @@ -// -// 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp deleted file mode 100644 index 0b12aed..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp deleted file mode 100644 index 12f342b..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp deleted file mode 100644 index 2ad8ac0..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp deleted file mode 100644 index a328f72..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core.hpp deleted file mode 100644 index ea9a7ff..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/*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_ErrorNoReturn(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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp deleted file mode 100644 index 38fcae9..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp deleted file mode 100644 index 659c7d8..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp deleted file mode 100644 index 9700004..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp deleted file mode 100644 index 9636b19..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp deleted file mode 100644 index 97c927b..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* 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/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp b/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp deleted file mode 100644 index 497bc3d..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp +++ /dev/null @@ -1,166 +0,0 @@ -/* 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/3rdparty/libopencv/include/opencv2/core/opengl.hpp b/3rdparty/libopencv/include/opencv2/core/opengl.hpp deleted file mode 100644 index 5e88cb8..0000000 --- a/3rdparty/libopencv/include/opencv2/core/opengl.hpp +++ /dev/null @@ -1,729 +0,0 @@ -/*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, int 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 { - -//! @addtogroup cuda -//! @{ - -/** @brief Sets a CUDA device and initializes it for the current thread with OpenGL interoperability. - -This function should be explicitly called after OpenGL context creation and before any CUDA calls. -@param device System index of a CUDA device starting with 0. -@ingroup core_opengl - */ -CV_EXPORTS void setGlDevice(int device = 0); - -//! @} - -}} - -//! @cond IGNORED - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -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/3rdparty/libopencv/include/opencv2/core/operations.hpp b/3rdparty/libopencv/include/opencv2/core/operations.hpp deleted file mode 100644 index e5d1a7e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/operations.hpp +++ /dev/null @@ -1,538 +0,0 @@ -/*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 - -//! @cond IGNORED - -namespace cv -{ - -////////////////////////////// Matx methods depending on core API ///////////////////////////// - -namespace internal -{ - -template struct Matx_FastInvOp -{ - bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const - { - 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; - } -}; - -template struct Matx_FastInvOp<_Tp, 2> -{ - bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) 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> -{ - bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) 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, m>& a, const Matx<_Tp, m, n>& b, - Matx<_Tp, m, n>& x, int method) const - { - 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; - } -}; - -template struct Matx_FastSolveOp<_Tp, 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, 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; - if( method == DECOMP_LU || method == DECOMP_CHOLESKY ) - ok = cv::internal::Matx_FastInvOp<_Tp, m>()(*this, b, method); - else - { - Mat A(*this, false), B(b, false); - ok = (invert(A, B, method) != 0); - } - if( NULL != 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; - if( method == DECOMP_LU || method == DECOMP_CHOLESKY ) - ok = cv::internal::Matx_FastSolveOp<_Tp, m, l>()(*this, rhs, x, method); - else - { - Mat A(*this, false), B(rhs, false), X(x, false); - ok = cv::solve(A, B, 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) - -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 (-=, 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 (*=, 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 (/=, 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 (&=, 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 (|=, 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 (^=, 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>) - -#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 unifomly-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. - */ -CV_EXPORTS String format( const char* fmt, ... ); - -///////////////////////////////// Formatted output of cv::Mat ///////////////////////////////// - -static inline -Ptr format(InputArray mtx, int 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/3rdparty/libopencv/include/opencv2/core/optim.hpp b/3rdparty/libopencv/include/opencv2/core/optim.hpp deleted file mode 100644 index c4729a9..0000000 --- a/3rdparty/libopencv/include/opencv2/core/optim.hpp +++ /dev/null @@ -1,302 +0,0 @@ -/*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 accompilished via the getGradient method of a -MinProblemSolver::Function interface (which represents function being optimized). This method takes -point a point in *n*-dimensional space (first argument represents the array of coordinates of that -point) and comput its gradient (it should be stored in the second argument as an array). - -@note class ConjGradSolver thus does not add any new methods to the basic MinProblemSolver interface. - -@note term criteria should meet following condition: -@code - termcrit.type == (TermCriteria::MAX_ITER + TermCriteria::EPS) && termcrit.epsilon > 0 && termcrit.maxCount > 0 - // or - termcrit.type == TermCriteria::MAX_ITER) && termcrit.maxCount > 0 -@endcode - */ -class CV_EXPORTS ConjGradSolver : public MinProblemSolver -{ -public: - /** @brief This function returns the reference to the ready-to-use ConjGradSolver object. - - All the parameters are optional, so this procedure can be called even without parameters at - all. In this case, the default values will be used. As default value for terminal criteria are - the only sensible ones, MinProblemSolver::setFunction() should be called upon the obtained - object, if the function was not given to create(). Otherwise, the two ways (submit it to - create() or miss it out and call the MinProblemSolver::setFunction()) are absolutely equivalent - (and will drop the same errors in the same way, should invalid input be detected). - @param f Pointer to the function that will be minimized, similarly to the one you submit via - MinProblemSolver::setFunction. - @param termcrit Terminal criteria to the algorithm, similarly to the one you submit via - MinProblemSolver::setTermCriteria. - */ - static Ptr create(const Ptr& f=Ptr(), - TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001)); -}; - -//! 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(const Mat& Func, const Mat& Constr, Mat& z); - -//! @} - -}// cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/core/ovx.hpp b/3rdparty/libopencv/include/opencv2/core/ovx.hpp deleted file mode 100644 index 8bb7d54..0000000 --- a/3rdparty/libopencv/include/opencv2/core/ovx.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// 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/3rdparty/libopencv/include/opencv2/core/persistence.hpp b/3rdparty/libopencv/include/opencv2/core/persistence.hpp deleted file mode 100644 index 6d8ad20..0000000 --- a/3rdparty/libopencv/include/opencv2/core/persistence.hpp +++ /dev/null @@ -1,1359 +0,0 @@ -/*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. - */ -typedef struct CvFileStorage CvFileStorage; -typedef struct CvFileNode CvFileNode; -typedef struct CvMat CvMat; -typedef struct CvMatND CvMatND; - -//! @} 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 filestorage.cpp -*/ - -//! @{ - -/** @example 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 - { - 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()); - - /** @overload */ - FileStorage(CvFileStorage* fs, bool owning=true); - - //! 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 Returns the obsolete C FileStorage structure. - @returns Pointer to the underlying C FileStorage structure - */ - CvFileStorage* operator *() { return fs.get(); } - - /** @overload */ - const CvFileStorage* operator *() const { return fs.get(); } - - /** @brief Writes multiple numbers. - - Writes one or more numbers of the specified format to the currently written structure. Usually it is - more convenient to use operator `<<` instead of this method. - @param fmt Specification of each array element, see @ref format_spec "format specification" - @param vec Pointer to the written array. - @param len Number of the uchar elements to write. - */ - void writeRaw( const String& fmt, const uchar* vec, size_t len ); - - /** @brief Writes the registered C structure (CvMat, CvMatND, CvSeq). - @param name Name of the written object. - @param obj Pointer to the object. - @see ocvWrite for details. - */ - void writeObj( const String& name, const void* obj ); - - /** - * @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, double val); - /// @overload - CV_WRAP void write(const String& name, const String& val); - /// @overload - CV_WRAP void write(const String& name, InputArray val); - - /** @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); - - /** @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; - - Ptr fs; //!< the underlying C FileStorage structure - String elname; //!< the currently written element - std::vector structs; //!< the stack of written structures - int state; //!< the writer state -}; - -template<> CV_EXPORTS void DefaultDeleter::operator ()(CvFileStorage* obj) const; - -/** @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 Type - { - 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 - REF = 4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others - SEQ = 5, //!< sequence - MAP = 6, //!< mapping - TYPE_MASK = 7, - FLOW = 8, //!< compact representation of a sequence or mapping. Used only by YAML writer - USER = 16, //!< a registered object (e.g. a matrix) - EMPTY = 32, //!< empty structure (sequence or mapping) - NAMED = 64 //!< 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 obsolete file storage structure. - @param node File node to be used as initialization for the created file node. - */ - FileNode(const CvFileStorage* fs, const CvFileNode* node); - - /** @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 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 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 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 - operator String() const; - operator std::string() const; - - //! returns pointer to the underlying file node - CvFileNode* operator *(); - //! returns pointer to the underlying file node - const CvFileNode* operator* () 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, uchar* vec, size_t len ) const; - - //! reads the registered object and returns pointer to it - void* readObj() const; - - //! Simplified reading API to use with bindings. - CV_WRAP double real() const; - //! Simplified reading API to use with bindings. - CV_WRAP String string() const; - //! Simplified reading API to use with bindings. - CV_WRAP Mat mat() const; - - // do not use wrapper pointer classes for better efficiency - const CvFileStorage* fs; - const CvFileNode* node; -}; - - -/** @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 fs File storage for the iterator. - @param node File node for the iterator. - @param ofs Index of the element in the node. The created iterator will point to this element. - */ - FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0); - - /** @overload - @param it Iterator to be used as initialization for the created iterator. - */ - FileNodeIterator(const FileNodeIterator& it); - - //! returns the currently observed element - FileNode operator *() const; - //! accesses the currently observed element methods - FileNode operator ->() const; - - //! moves iterator to the next node - FileNodeIterator& operator ++ (); - //! moves iterator to the next node - FileNodeIterator operator ++ (int); - //! moves iterator to the previous node - FileNodeIterator& operator -- (); - //! moves iterator to the previous node - FileNodeIterator operator -- (int); - //! moves iterator forward by the specified offset (possibly negative) - FileNodeIterator& operator += (int ofs); - //! moves iterator backward 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, uchar* vec, - size_t maxCount=(size_t)INT_MAX ); - - struct SeqReader - { - int header_size; - void* seq; /* sequence, beign read; CvSeq */ - void* block; /* current block; CvSeqBlock */ - 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 */ - }; - - const CvFileStorage* fs; - const CvFileNode* container; - SeqReader reader; - size_t remaining; -}; - -//! @} core_xml - -/////////////////// XML & YAML I/O implementation ////////////////// - -//! @relates cv::FileStorage -//! @{ - -CV_EXPORTS void write( FileStorage& fs, const String& name, int value ); -CV_EXPORTS void write( FileStorage& fs, const String& name, float value ); -CV_EXPORTS void write( FileStorage& fs, const String& name, double value ); -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, String& value, const String& 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, 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 ? count : remaining1; - 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 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 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 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 static inline -void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() ) -{ - if(!node.node) - 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.node) - vec = default_value; - else - read(node, vec); -} - -static inline -void read( const FileNode& node, std::vector& vec, const std::vector& default_value ) -{ - if(!node.node) - 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 -//! @{ - -static inline -bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2) -{ - return it1.fs == it2.fs && it1.container == it2.container && - it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining; -} - -static inline -bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2) -{ - return !(it1 == 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 - -//! @cond IGNORED - -inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); } -inline FileNode::FileNode() : fs(0), node(0) {} -inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {} -inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {} -inline bool FileNode::empty() const { return node == 0; } -inline bool FileNode::isNone() const { return type() == NONE; } -inline bool FileNode::isSeq() const { return type() == SEQ; } -inline bool FileNode::isMap() const { return type() == MAP; } -inline bool FileNode::isInt() const { return type() == INT; } -inline bool FileNode::isReal() const { return type() == REAL; } -inline bool FileNode::isString() const { return type() == STR; } -inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; } -inline const CvFileNode* FileNode::operator* () const { return node; } -inline FileNode::operator int() const { int value; read(*this, value, 0); return value; } -inline FileNode::operator float() const { float value; read(*this, value, 0.f); return value; } -inline FileNode::operator double() const { double value; read(*this, value, 0.); return value; } -inline FileNode::operator String() const { String value; read(*this, value, value); return value; } -inline double FileNode::real() const { return double(*this); } -inline String FileNode::string() const { return String(*this); } -inline Mat FileNode::mat() const { Mat value; read(*this, value, value); return value; } -inline FileNodeIterator FileNode::begin() const { return FileNodeIterator(fs, node); } -inline FileNodeIterator FileNode::end() const { return FileNodeIterator(fs, node, size()); } -inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const { begin().readRaw( fmt, vec, len ); } -inline FileNode FileNodeIterator::operator *() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); } -inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); } -inline String::String(const FileNode& fn): cstr_(0), len_(0) { read(fn, *this, *this); } - -//! @endcond - - -CV_EXPORTS void cvStartWriteRawData_Base64(::CvFileStorage * fs, const char* name, int len, const char* dt); - -CV_EXPORTS void cvWriteRawData_Base64(::CvFileStorage * fs, const void* _data, int len); - -CV_EXPORTS void cvEndWriteRawData_Base64(::CvFileStorage * fs); - -CV_EXPORTS void cvWriteMat_Base64(::CvFileStorage* fs, const char* name, const ::CvMat* mat); - -CV_EXPORTS void cvWriteMatND_Base64(::CvFileStorage* fs, const char* name, const ::CvMatND* mat); - -} // cv - -#endif // OPENCV_CORE_PERSISTENCE_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/ptr.inl.hpp b/3rdparty/libopencv/include/opencv2/core/ptr.inl.hpp deleted file mode 100644 index 3c095a1..0000000 --- a/3rdparty/libopencv/include/opencv2/core/ptr.inl.hpp +++ /dev/null @@ -1,379 +0,0 @@ -/*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, NVIDIA Corporation, all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or implied warranties, including, but not limited to, the implied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the 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_PTR_INL_HPP -#define OPENCV_CORE_PTR_INL_HPP - -#include - -//! @cond IGNORED - -namespace cv { - -template -void DefaultDeleter::operator () (Y* p) const -{ - delete p; -} - -namespace detail -{ - -struct PtrOwner -{ - PtrOwner() : refCount(1) - {} - - void incRef() - { - CV_XADD(&refCount, 1); - } - - void decRef() - { - if (CV_XADD(&refCount, -1) == 1) deleteSelf(); - } - -protected: - /* This doesn't really need to be virtual, since PtrOwner is never deleted - directly, but it doesn't hurt and it helps avoid warnings. */ - virtual ~PtrOwner() - {} - - virtual void deleteSelf() = 0; - -private: - unsigned int refCount; - - // noncopyable - PtrOwner(const PtrOwner&); - PtrOwner& operator = (const PtrOwner&); -}; - -template -struct PtrOwnerImpl : PtrOwner -{ - PtrOwnerImpl(Y* p, D d) : owned(p), deleter(d) - {} - - void deleteSelf() - { - deleter(owned); - delete this; - } - -private: - Y* owned; - D deleter; -}; - - -} - -template -Ptr::Ptr() : owner(NULL), stored(NULL) -{} - -template -template -Ptr::Ptr(Y* p) - : owner(p - ? new detail::PtrOwnerImpl >(p, DefaultDeleter()) - : NULL), - stored(p) -{} - -template -template -Ptr::Ptr(Y* p, D d) - : owner(p - ? new detail::PtrOwnerImpl(p, d) - : NULL), - stored(p) -{} - -template -Ptr::Ptr(const Ptr& o) : owner(o.owner), stored(o.stored) -{ - if (owner) owner->incRef(); -} - -template -template -Ptr::Ptr(const Ptr& o) : owner(o.owner), stored(o.stored) -{ - if (owner) owner->incRef(); -} - -template -template -Ptr::Ptr(const Ptr& o, T* p) : owner(o.owner), stored(p) -{ - if (owner) owner->incRef(); -} - -template -Ptr::~Ptr() -{ - release(); -} - -template -Ptr& Ptr::operator = (const Ptr& o) -{ - Ptr(o).swap(*this); - return *this; -} - -template -template -Ptr& Ptr::operator = (const Ptr& o) -{ - Ptr(o).swap(*this); - return *this; -} - -template -void Ptr::release() -{ - if (owner) owner->decRef(); - owner = NULL; - stored = NULL; -} - -template -template -void Ptr::reset(Y* p) -{ - Ptr(p).swap(*this); -} - -template -template -void Ptr::reset(Y* p, D d) -{ - Ptr(p, d).swap(*this); -} - -template -void Ptr::swap(Ptr& o) -{ - std::swap(owner, o.owner); - std::swap(stored, o.stored); -} - -template -T* Ptr::get() const -{ - return stored; -} - -template -typename detail::RefOrVoid::type Ptr::operator * () const -{ - return *stored; -} - -template -T* Ptr::operator -> () const -{ - return stored; -} - -template -Ptr::operator T* () const -{ - return stored; -} - - -template -bool Ptr::empty() const -{ - return !stored; -} - -template -template -Ptr Ptr::staticCast() const -{ - return Ptr(*this, static_cast(stored)); -} - -template -template -Ptr Ptr::constCast() const -{ - return Ptr(*this, const_cast(stored)); -} - -template -template -Ptr Ptr::dynamicCast() const -{ - return Ptr(*this, dynamic_cast(stored)); -} - -#ifdef CV_CXX_MOVE_SEMANTICS - -template -Ptr::Ptr(Ptr&& o) : owner(o.owner), stored(o.stored) -{ - o.owner = NULL; - o.stored = NULL; -} - -template -Ptr& Ptr::operator = (Ptr&& o) -{ - if (this == &o) - return *this; - - release(); - owner = o.owner; - stored = o.stored; - o.owner = NULL; - o.stored = NULL; - return *this; -} - -#endif - - -template -void swap(Ptr& ptr1, Ptr& ptr2){ - ptr1.swap(ptr2); -} - -template -bool operator == (const Ptr& ptr1, const Ptr& ptr2) -{ - return ptr1.get() == ptr2.get(); -} - -template -bool operator != (const Ptr& ptr1, const Ptr& ptr2) -{ - return ptr1.get() != ptr2.get(); -} - -template -Ptr makePtr() -{ - return Ptr(new T()); -} - -template -Ptr makePtr(const A1& a1) -{ - return Ptr(new T(a1)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2) -{ - return Ptr(new T(a1, a2)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3) -{ - return Ptr(new T(a1, a2, a3)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4) -{ - return Ptr(new T(a1, a2, a3, a4)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) -{ - return Ptr(new T(a1, a2, a3, a4, a5)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) -{ - return Ptr(new T(a1, a2, a3, a4, a5, a6)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) -{ - return Ptr(new T(a1, a2, a3, a4, a5, a6, a7)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) -{ - return Ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9) -{ - return Ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) -{ - return Ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11) -{ - return Ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)); -} - -template -Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10, const A11& a11, const A12& a12) -{ - return Ptr(new T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)); -} -} // namespace cv - -//! @endcond - -#endif // OPENCV_CORE_PTR_INL_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/saturate.hpp b/3rdparty/libopencv/include/opencv2/core/saturate.hpp deleted file mode 100644 index 118599f..0000000 --- a/3rdparty/libopencv/include/opencv2/core/saturate.hpp +++ /dev/null @@ -1,165 +0,0 @@ -/*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); } - -//! @} - -} // cv - -#endif // OPENCV_CORE_SATURATE_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/softfloat.hpp b/3rdparty/libopencv/include/opencv2/core/softfloat.hpp deleted file mode 100644 index 5470980..0000000 --- a/3rdparty/libopencv/include/opencv2/core/softfloat.hpp +++ /dev/null @@ -1,514 +0,0 @@ -// 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/3rdparty/libopencv/include/opencv2/core/sse_utils.hpp b/3rdparty/libopencv/include/opencv2/core/sse_utils.hpp deleted file mode 100644 index 69efffe..0000000 --- a/3rdparty/libopencv/include/opencv2/core/sse_utils.hpp +++ /dev/null @@ -1,652 +0,0 @@ -/*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) -{ - const int 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) -{ - const int 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) -{ - const int 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/3rdparty/libopencv/include/opencv2/core/traits.hpp b/3rdparty/libopencv/include/opencv2/core/traits.hpp deleted file mode 100644 index 6cb10f4..0000000 --- a/3rdparty/libopencv/include/opencv2/core/traits.hpp +++ /dev/null @@ -1,397 +0,0 @@ -/*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) - }; -}; - - -/** @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; -}; - -#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/3rdparty/libopencv/include/opencv2/core/types.hpp b/3rdparty/libopencv/include/opencv2/core/types.hpp deleted file mode 100644 index 6d87820..0000000 --- a/3rdparty/libopencv/include/opencv2/core/types.hpp +++ /dev/null @@ -1,2358 +0,0 @@ -/*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_(const Size_<_Tp>& sz); - Point_(const Vec<_Tp, 2>& v); - - Point_& operator = (const Point_& pt); - //! 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); - explicit Point3_(const Point_<_Tp>& pt); - Point3_(const Vec<_Tp, 3>& v); - - Point3_& operator = (const Point3_& pt); - //! conversion to another data type - template operator Point3_<_Tp2>() const; - //! conversion to cv::Vec<> -#if OPENCV_ABI_COMPATIBILITY > 300 - template operator Vec<_Tp2, 3>() const; -#else - operator Vec<_Tp, 3>() const; -#endif - - //! 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_(const Point_<_Tp>& pt); - - Size_& operator = (const Size_& sz); - //! the area (width*height) - _Tp area() 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_(const Point_<_Tp>& org, const Size_<_Tp>& sz); - Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2); - - Rect_& operator = ( const Rect_& r ); - //! 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); - - 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); - - 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_(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 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; -} - - - -//////////////////////////////// 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_(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)); -} - -#if OPENCV_ABI_COMPATIBILITY > 300 -template template inline -Point3_<_Tp>::operator Vec<_Tp2, 3>() const -{ - return Vec<_Tp2, 3>(x, y, z); -} -#else -template inline -Point3_<_Tp>::operator Vec<_Tp, 3>() const -{ - return Vec<_Tp, 3>(x, y, z); -} -#endif - -template inline -Point3_<_Tp>& Point3_<_Tp>::operator = (const Point3_& pt) -{ - x = pt.x; y = pt.y; z = 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_(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 -_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 -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_(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 -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 ) -{ - a.width -= b.width; - a.height -= b.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 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 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/3rdparty/libopencv/include/opencv2/core/types_c.h b/3rdparty/libopencv/include/opencv2/core/types_c.h deleted file mode 100644 index 65f354e..0000000 --- a/3rdparty/libopencv/include/opencv2/core/types_c.h +++ /dev/null @@ -1,1837 +0,0 @@ -/*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 - -#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 - -/** The IplImage is taken from the Intel Image Processing Library, in which the format is native. OpenCV -only supports a subset of possible IplImage formats, as outlined in the parameter list above. - -In addition to the above restrictions, OpenCV handles ROIs differently. OpenCV functions require -that the image size or ROI size of all source and destination images match exactly. On the other -hand, the Intel Image Processing Library processes the area of intersection between the source and -destination images (or ROIs), allowing them to vary independently. -*/ -typedef struct -#ifdef __cplusplus - CV_EXPORTS -#endif -_IplImage -{ - int nSize; /**< sizeof(IplImage) */ - int ID; /**< version (=0)*/ - int nChannels; /**< Most of OpenCV functions support 1,2,3 or 4 channels */ - int alphaChannel; /**< Ignored by OpenCV */ - int depth; /**< Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, - 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 */ - -#ifdef __cplusplus - _IplImage() {} - _IplImage(const cv::Mat& m); -#endif -} -IplImage; - -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" - -/** 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 - - -#ifdef __cplusplus - CvMat() {} - CvMat(const CvMat& m) { memcpy(this, &m, sizeof(CvMat));} - CvMat(const cv::Mat& 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 -inline CvMat::CvMat(const cv::Mat& m) -{ - CV_DbgAssert(m.dims <= 2); - *this = cvMat(m.rows, m.dims == 1 ? 1 : m.cols, m.type(), m.data); - step = (int)m.step[0]; - type = (type & ~cv::Mat::CONTINUOUS_FLAG) | (m.flags & cv::Mat::CONTINUOUS_FLAG); -} -#endif - - -#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 -#define CV_MAX_DIM_HEAP 1024 - -/** - @deprecated consider using cv::Mat instead - */ -typedef struct -#ifdef __cplusplus - CV_EXPORTS -#endif -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]; - -#ifdef __cplusplus - CvMatND() {} - CvMatND(const cv::Mat& m); -#endif -} -CvMatND; - -#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 -#ifdef __cplusplus - CV_EXPORTS -#endif -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 - 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 __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)) {} - 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 ) -{ - CvRect r; - - r.x = x; - r.y = y; - r.width = width; - r.height = height; - - return r; -} - - -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; - -#ifdef __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) {} - operator cv::TermCriteria() const { return cv::TermCriteria(type, max_iter, epsilon); } -#endif - -} -CvTermCriteria; - -CV_INLINE CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon ) -{ - CvTermCriteria t; - - t.type = type; - t.max_iter = max_iter; - t.epsilon = (float)epsilon; - - return t; -} - - -/******************************* CvPoint and variants ***********************************/ - -typedef struct CvPoint -{ - int x; - int y; - -#ifdef __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) {} - 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 ) -{ - CvPoint p; - - p.x = x; - p.y = y; - - return p; -} - - -typedef struct CvPoint2D32f -{ - float x; - float y; - -#ifdef __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) {} - 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 ) -{ - CvPoint2D32f p; - - p.x = (float)x; - p.y = (float)y; - - return p; -} - -/** converts CvPoint to CvPoint2D32f. */ -CV_INLINE CvPoint2D32f cvPointTo32f( CvPoint point ) -{ - return cvPoint2D32f( (float)point.x, (float)point.y ); -} - -/** converts CvPoint2D32f to CvPoint. */ -CV_INLINE CvPoint cvPointFrom32f( CvPoint2D32f point ) -{ - CvPoint ipt; - ipt.x = cvRound(point.x); - ipt.y = cvRound(point.y); - - return ipt; -} - - -typedef struct CvPoint3D32f -{ - float x; - float y; - float z; - -#ifdef __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) {} - 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 ) -{ - CvPoint3D32f p; - - p.x = (float)x; - p.y = (float)y; - p.z = (float)z; - - return p; -} - - -typedef struct CvPoint2D64f -{ - double x; - double y; -} -CvPoint2D64f; - -/** constructs CvPoint2D64f structure.*/ -CV_INLINE CvPoint2D64f cvPoint2D64f( double x, double y ) -{ - CvPoint2D64f p; - - p.x = x; - p.y = y; - - return p; -} - - -typedef struct CvPoint3D64f -{ - double x; - double y; - double z; -} -CvPoint3D64f; - -/** constructs CvPoint3D64f structure. */ -CV_INLINE CvPoint3D64f cvPoint3D64f( double x, double y, double z ) -{ - CvPoint3D64f p; - - p.x = x; - p.y = y; - p.z = z; - - return p; -} - - -/******************************** CvSize's & CvBox **************************************/ - -typedef struct CvSize -{ - int width; - int height; - -#ifdef __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)) {} - 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 ) -{ - CvSize s; - - s.width = width; - s.height = height; - - return s; -} - -typedef struct CvSize2D32f -{ - float width; - float height; - -#ifdef __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)) {} - 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 ) -{ - CvSize2D32f s; - - s.width = (float)width; - s.height = (float)height; - - return s; -} - -/** @sa RotatedRect - */ -typedef struct CvBox2D -{ - CvPoint2D32f center; /**< Center of the box. */ - CvSize2D32f size; /**< Box width and length. */ - float angle; /**< Angle between the horizontal axis */ - /**< and the first side (i.e. length) in degrees */ - -#ifdef __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) {} - operator cv::RotatedRect() const { return cv::RotatedRect(center, size, angle); } -#endif -} -CvBox2D; - - -/** 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; - -#if 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 ) -{ - CvSlice slice; - slice.start_index = start; - slice.end_index = end; - - return slice; -} - - - -/************************************* CvScalar *****************************************/ -/** @sa Scalar_ - */ -typedef struct CvScalar -{ - double val[4]; - -#ifdef __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 - 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])); } - 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 -} -CvScalar; - -CV_INLINE CvScalar cvScalar( double val0, double val1 CV_DEFAULT(0), - double val2 CV_DEFAULT(0), double val3 CV_DEFAULT(0)) -{ - CvScalar scalar; - scalar.val[0] = val0; scalar.val[1] = val1; - scalar.val[2] = val2; scalar.val[3] = val3; - return scalar; -} - - -CV_INLINE CvScalar cvRealScalar( double val0 ) -{ - CvScalar scalar; - scalar.val[0] = val0; - scalar.val[1] = scalar.val[2] = scalar.val[3] = 0; - return scalar; -} - -CV_INLINE CvScalar cvScalarAll( double val0123 ) -{ - CvScalar scalar; - 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_USRTYPE1 -#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /**< &(x,y) */ -#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /**< #(x,y) */ -#define CV_SEQ_ELTYPE_GRAPH_EDGE 0 /**< &next_o, &next_d, &vtx_o, &vtx_d */ -#define CV_SEQ_ELTYPE_GRAPH_VERTEX 0 /**< first_edge, &(x,y) */ -#define CV_SEQ_ELTYPE_TRIAN_ATR 0 /**< vertex of the binary tree */ -#define CV_SEQ_ELTYPE_CONNECTED_COMP 0 /**< connected component */ -#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /**< (x,y,z) */ - -#define CV_SEQ_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 * -\****************************************************************************************/ - -/** "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 readed file storage - are stored in the hash to speed up the lookup operations: */ -typedef struct CvStringHashNode -{ - unsigned hashval; - CvString str; - struct CvStringHashNode* next; -} -CvStringHashNode; - -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; - - -/**** System data types ******/ - -typedef struct CvPluginFuncInfo -{ - void** func_addr; - void* default_func_addr; - const char* func_names; - int search_modules; - int loaded_from; -} -CvPluginFuncInfo; - -typedef struct CvModuleInfo -{ - struct CvModuleInfo* next; - const char* name; - const char* version; - CvPluginFuncInfo* func_tab; -} -CvModuleInfo; - -/** @} */ - -#endif /*OPENCV_CORE_TYPES_H*/ - -/* End of file. */ diff --git a/3rdparty/libopencv/include/opencv2/core/utility.hpp b/3rdparty/libopencv/include/opencv2/core/utility.hpp deleted file mode 100644 index 0f60d1a..0000000 --- a/3rdparty/libopencv/include/opencv2/core/utility.hpp +++ /dev/null @@ -1,1240 +0,0 @@ -/*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 - -#ifdef CV_CXX11 -#include -#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 -*/ -template class AutoBuffer -{ -public: - typedef _Tp value_type; - - //! the default constructor - AutoBuffer(); - //! constructor taking the real buffer size - 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 - operator _Tp* (); - //! returns read-only pointer to the real buffer, stack-allocated or heap-allocated - operator const _Tp* () const; - -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 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 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 Enables or disables the optimized code. - -The function can be used to dynamically turn on and off optimized code (code that uses SSE2, AVX, -and other instructions on the platforms that support it). It sets a global flag that is further -checked by OpenCV functions. Since the flag is not checked in the inner OpenCV loops, it is only -safe to call the function on the very top level in your application where you can be sure that no -other OpenCV function is currently executed. - -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.); - -#ifdef CV_CXX11 -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 - { - m_functor(range); - } -}; - -inline void parallel_for_(const Range& range, std::function functor, double nstripes=-1.) -{ - parallel_for_(range, ParallelLoopBodyLambdaWrapper(functor), nstripes); -} -#endif - -/////////////////////////////// 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 { - 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 /////////////////////////////// - -class CV_EXPORTS Mutex -{ -public: - Mutex(); - ~Mutex(); - Mutex(const Mutex& m); - Mutex& operator = (const Mutex& m); - - void lock(); - bool trylock(); - void unlock(); - - struct Impl; -protected: - Impl* impl; -}; - -class CV_EXPORTS AutoLock -{ -public: - AutoLock(Mutex& m) : mutex(&m) { mutex->lock(); } - ~AutoLock() { mutex->unlock(); } -protected: - Mutex* mutex; -private: - AutoLock(const AutoLock&); - AutoLock& operator = (const AutoLock&); -}; - -// TLS interface -class CV_EXPORTS TLSDataContainer -{ -protected: - TLSDataContainer(); - virtual ~TLSDataContainer(); - - void gatherData(std::vector &data) const; -#if OPENCV_ABI_COMPATIBILITY > 300 - void* getData() const; - void release(); - -private: -#else - void release(); - -public: - void* getData() const; -#endif - 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 {return new T;} // Wrapper to allocate data by template - virtual void deleteDataInstance(void* pData) const {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, int type, void* dst) const; - void getByIndex(int index, bool space_delete, int 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; } - -template inline -AutoBuffer<_Tp, fixed_size>::operator _Tp* () -{ return ptr; } - -template inline -AutoBuffer<_Tp, fixed_size>::operator const _Tp* () const -{ return ptr; } - -template<> inline std::string CommandLineParser::get(int index, bool space_delete) const -{ - return get(index, space_delete); -} -template<> inline std::string CommandLineParser::get(const String& name, bool space_delete) const -{ - return get(name, space_delete); -} - -//! @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 utils { - -CV_EXPORTS int getThreadID(); - -} // namespace - -} //namespace cv - -#ifndef DISABLE_OPENCV_24_COMPATIBILITY -#include "opencv2/core/core_c.h" -#endif - -#endif //OPENCV_CORE_UTILITY_H diff --git a/3rdparty/libopencv/include/opencv2/core/utils/filesystem.hpp b/3rdparty/libopencv/include/opencv2/core/utils/filesystem.hpp deleted file mode 100644 index 12b10a7..0000000 --- a/3rdparty/libopencv/include/opencv2/core/utils/filesystem.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// 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(); - -/** Join path components */ -CV_EXPORTS cv::String join(const cv::String& base, const cv::String& 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/3rdparty/libopencv/include/opencv2/core/utils/logger.defines.hpp b/3rdparty/libopencv/include/opencv2/core/utils/logger.defines.hpp deleted file mode 100644 index b2dfc41..0000000 --- a/3rdparty/libopencv/include/opencv2/core/utils/logger.defines.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// 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. - -//! @} - -#endif // OPENCV_LOGGER_DEFINES_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/utils/logger.hpp b/3rdparty/libopencv/include/opencv2/core/utils/logger.hpp deleted file mode 100644 index 47094f9..0000000 --- a/3rdparty/libopencv/include/opencv2/core/utils/logger.hpp +++ /dev/null @@ -1,87 +0,0 @@ -// 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" - -//! @addtogroup core_logging -// This section describes OpenCV logging utilities. -// -//! @{ - -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 -}; - -/** Set global logging level -@return previous logging level -*/ -CV_EXPORTS LogLevel setLogLevel(LogLevel logLevel); -/** Get global logging level */ -CV_EXPORTS LogLevel getLogLevel(); - -namespace internal { -/** Write log message */ -CV_EXPORTS void writeLogMessage(LogLevel logLevel, const char* message); -} // namespace - -/** - * \def CV_LOG_STRIP_LEVEL - * - * Define CV_LOG_STRIP_LEVEL=CV_LOG_LEVEL_[DEBUG|INFO|WARN|ERROR|FATAL|DISABLED] 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_LOG_FATAL(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_FATAL) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_FATAL, ss.str().c_str()); break; } -#define CV_LOG_ERROR(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_ERROR) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_ERROR, ss.str().c_str()); break; } -#define CV_LOG_WARNING(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_WARNING) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_WARNING, ss.str().c_str()); break; } -#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_INFO -#define CV_LOG_INFO(tag, ...) -#else -#define CV_LOG_INFO(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_INFO) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_INFO, ss.str().c_str()); break; } -#endif -#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_DEBUG -#define CV_LOG_DEBUG(tag, ...) -#else -#define CV_LOG_DEBUG(tag, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_DEBUG) break; std::stringstream ss; ss << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_DEBUG, ss.str().c_str()); break; } -#endif -#if CV_LOG_STRIP_LEVEL <= CV_LOG_LEVEL_VERBOSE -#define CV_LOG_VERBOSE(tag, v, ...) -#else -#define CV_LOG_VERBOSE(tag, v, ...) for(;;) { if (cv::utils::logging::getLogLevel() < cv::utils::logging::LOG_LEVEL_VERBOSE) break; std::stringstream ss; ss << "[VERB" << v << ":" << cv::utils::getThreadID() << "] " << __VA_ARGS__; cv::utils::logging::internal::writeLogMessage(cv::utils::logging::LOG_LEVEL_VERBOSE, ss.str().c_str()); break; } -#endif - - -}}} // namespace - -//! @} - -#endif // OPENCV_LOGGER_HPP diff --git a/3rdparty/libopencv/include/opencv2/core/utils/trace.hpp b/3rdparty/libopencv/include/opencv2/core/utils/trace.hpp deleted file mode 100644 index 1539fb9..0000000 --- a/3rdparty/libopencv/include/opencv2/core/utils/trace.hpp +++ /dev/null @@ -1,250 +0,0 @@ -// 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 - -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/3rdparty/libopencv/include/opencv2/core/va_intel.hpp b/3rdparty/libopencv/include/opencv2/core/va_intel.hpp deleted file mode 100644 index 3325848..0000000 --- a/3rdparty/libopencv/include/opencv2/core/va_intel.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// 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_MSDK_ROOT for Media SDK -(default is "/opt/intel/mediasdk"), and 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/3rdparty/libopencv/include/opencv2/core/version.hpp b/3rdparty/libopencv/include/opencv2/core/version.hpp deleted file mode 100644 index c999a80..0000000 --- a/3rdparty/libopencv/include/opencv2/core/version.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// 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 3 -#define CV_VERSION_MINOR 4 -#define CV_VERSION_REVISION 1 -#define CV_VERSION_STATUS "" - -#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/3rdparty/libopencv/include/opencv2/core/vsx_utils.hpp b/3rdparty/libopencv/include/opencv2/core/vsx_utils.hpp deleted file mode 100644 index c377551..0000000 --- a/3rdparty/libopencv/include/opencv2/core/vsx_utils.hpp +++ /dev/null @@ -1,1095 +0,0 @@ -/*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_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, c)) -#define vec_uchar16_c(v) ((vec_uchar16)(v)) -#define vec_uchar16_mx vec_uchar16_sp(0xFF) -#define vec_uchar16_mn vec_uchar16_sp(0) -#define vec_uchar16_z vec_uchar16_mn - -typedef __vector signed char vec_char16; -#define vec_char16_set(...) (vec_char16){__VA_ARGS__} -#define vec_char16_sp(c) (__VSX_S16__(vec_char16, c)) -#define vec_char16_c(v) ((vec_char16)(v)) -#define vec_char16_mx vec_char16_sp(0x7F) -#define vec_char16_mn vec_char16_sp(-0x7F-1) -#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, c)) -#define vec_ushort8_c(v) ((vec_ushort8)(v)) -#define vec_ushort8_mx vec_ushort8_sp(0xFFFF) -#define vec_ushort8_mn vec_ushort8_sp(0) -#define vec_ushort8_z vec_ushort8_mn - -typedef __vector signed short vec_short8; -#define vec_short8_set(...) (vec_short8){__VA_ARGS__} -#define vec_short8_sp(c) (__VSX_S8__(vec_short8, c)) -#define vec_short8_c(v) ((vec_short8)(v)) -#define vec_short8_mx vec_short8_sp(0x7FFF) -#define vec_short8_mn vec_short8_sp(-0x7FFF-1) -#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, c)) -#define vec_uint4_c(v) ((vec_uint4)(v)) -#define vec_uint4_mx vec_uint4_sp(0xFFFFFFFFU) -#define vec_uint4_mn vec_uint4_sp(0) -#define vec_uint4_z vec_uint4_mn - -typedef __vector signed int vec_int4; -#define vec_int4_set(...) (vec_int4){__VA_ARGS__} -#define vec_int4_sp(c) (__VSX_S4__(vec_int4, c)) -#define vec_int4_c(v) ((vec_int4)(v)) -#define vec_int4_mx vec_int4_sp(0x7FFFFFFF) -#define vec_int4_mn vec_int4_sp(-0x7FFFFFFF-1) -#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_mx vec_float4_sp(3.40282347E+38F) -#define vec_float4_mn vec_float4_sp(1.17549435E-38F) -#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, c)) -#define vec_udword2_c(v) ((vec_udword2)(v)) -#define vec_udword2_mx vec_udword2_sp(18446744073709551615ULL) -#define vec_udword2_mn vec_udword2_sp(0) -#define vec_udword2_z vec_udword2_mn - -typedef __vector signed long long vec_dword2; -#define vec_dword2_set(...) (vec_dword2){__VA_ARGS__} -#define vec_dword2_sp(c) (__VSX_S2__(vec_dword2, c)) -#define vec_dword2_c(v) ((vec_dword2)(v)) -#define vec_dword2_mx vec_dword2_sp(9223372036854775807LL) -#define vec_dword2_mn vec_dword2_sp(-9223372036854775807LL-1) -#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_mx vec_double2_sp(1.7976931348623157E+308) -#define vec_double2_mn vec_double2_sp(2.2250738585072014E-308) -#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_bchar16_f (__VSX_S16__(vec_bchar16, 0)) -#define vec_bchar16_t (__VSX_S16__(vec_bchar16, 1)) - -#define vec_bshort8 __vector __bool short -#define vec_bshort8_set(...) (vec_bshort8){__VA_ARGS__} -#define vec_bshort8_c(v) ((vec_bshort8)(v)) -#define vec_bshort8_f (__VSX_S8__(vec_bshort8, 0)) -#define vec_bshort8_t (__VSX_S8__(vec_bshort8, 1)) - -#define vec_bint4 __vector __bool int -#define vec_bint4_set(...) (vec_bint4){__VA_ARGS__} -#define vec_bint4_c(v) ((vec_bint4)(v)) -#define vec_bint4_f (__VSX_S4__(vec_bint4, 0)) -#define vec_bint4_t (__VSX_S4__(vec_bint4, 1)) - -#define vec_bdword2 __vector __bool long long -#define vec_bdword2_set(...) (vec_bdword2){__VA_ARGS__} -#define vec_bdword2_c(v) ((vec_bdword2)(v)) -#define vec_bdword2_f (__VSX_S2__(vec_bdword2, 0)) -#define vec_bdword2_t (__VSX_S2__(vec_bdword2, 1)) - - -#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 16-bit multiplication in ISA 2.07, - * XLC Implement it by using instruction "multiply even", "multiply odd" and "permute" - * todo: Do I need to support 8-bit ? -**/ -# define VSX_IMPL_MULH(Tvec, Tcast) \ - VSX_FINLINE(Tvec) vec_mul(const Tvec& a, const Tvec& b) \ - { \ - static const vec_uchar16 even_perm = {0, 1, 16, 17, 4, 5, 20, 21, \ - 8, 9, 24, 25, 12, 13, 28, 29}; \ - return vec_perm(Tcast(vec_mule(a, b)), Tcast(vec_mulo(a, b)), even_perm); \ - } - VSX_IMPL_MULH(vec_short8, vec_short8_c) - VSX_IMPL_MULH(vec_ushort8, vec_ushort8_c) - // 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 -*/ - -// 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); \ - (void)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 - -// load 4 unsigned bytes into uint4 vector -#define vec_ld_buw(p) vec_uint4_set((p)[0], (p)[1], (p)[2], (p)[3]) - -// load 4 signed bytes into int4 vector -#define vec_ld_bsw(p) vec_int4_set((p)[0], (p)[1], (p)[2], (p)[3]) - -// load 4 unsigned bytes into float vector -#define vec_ld_bps(p) vec_ctf(vec_ld_buw(p), 0) - -// 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) - -/* - * vec_ld_l8(ptr) -> Load 64-bits of integer data to lower part - * vec_ldz_l8(ptr) -> Load 64-bits of integer data to lower part and zero upper 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_FINLINE(Tvec) vec_ldz_l8(const Tp *p) \ -{ \ - /* TODO: try (Tvec)(vec_udword2{*((uint64*)p), 0}) */ \ - static const vec_bdword2 mask = {0xFFFFFFFFFFFFFFFF, 0x0000000000000000}; \ - return vec_and(vec_ld_l8(p), (Tvec)mask); \ -} -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 reinterpret_cast(vec_mergel(a, zero)); } \ -VSX_FINLINE(rt) vec_unpackhu(const rg& a) \ -{ return reinterpret_cast(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/3rdparty/libopencv/include/opencv2/core/wimage.hpp b/3rdparty/libopencv/include/opencv2/core/wimage.hpp deleted file mode 100644 index c7b6efa..0000000 --- a/3rdparty/libopencv/include/opencv2/core/wimage.hpp +++ /dev/null @@ -1,603 +0,0 @@ -/*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) 2008, Google, 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 or contributors 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_WIMAGE_HPP -#define OPENCV_CORE_WIMAGE_HPP - -#include "opencv2/core/core_c.h" - -#ifdef __cplusplus - -namespace cv { - -//! @addtogroup core -//! @{ - -template class WImage; -template class WImageBuffer; -template class WImageView; - -template class WImageC; -template class WImageBufferC; -template class WImageViewC; - -// Commonly used typedefs. -typedef WImage WImage_b; -typedef WImageView WImageView_b; -typedef WImageBuffer WImageBuffer_b; - -typedef WImageC WImage1_b; -typedef WImageViewC WImageView1_b; -typedef WImageBufferC WImageBuffer1_b; - -typedef WImageC WImage3_b; -typedef WImageViewC WImageView3_b; -typedef WImageBufferC WImageBuffer3_b; - -typedef WImage WImage_f; -typedef WImageView WImageView_f; -typedef WImageBuffer WImageBuffer_f; - -typedef WImageC WImage1_f; -typedef WImageViewC WImageView1_f; -typedef WImageBufferC WImageBuffer1_f; - -typedef WImageC WImage3_f; -typedef WImageViewC WImageView3_f; -typedef WImageBufferC WImageBuffer3_f; - -// There isn't a standard for signed and unsigned short so be more -// explicit in the typename for these cases. -typedef WImage WImage_16s; -typedef WImageView WImageView_16s; -typedef WImageBuffer WImageBuffer_16s; - -typedef WImageC WImage1_16s; -typedef WImageViewC WImageView1_16s; -typedef WImageBufferC WImageBuffer1_16s; - -typedef WImageC WImage3_16s; -typedef WImageViewC WImageView3_16s; -typedef WImageBufferC WImageBuffer3_16s; - -typedef WImage WImage_16u; -typedef WImageView WImageView_16u; -typedef WImageBuffer WImageBuffer_16u; - -typedef WImageC WImage1_16u; -typedef WImageViewC WImageView1_16u; -typedef WImageBufferC WImageBuffer1_16u; - -typedef WImageC WImage3_16u; -typedef WImageViewC WImageView3_16u; -typedef WImageBufferC WImageBuffer3_16u; - -/** @brief Image class which provides a thin layer around an IplImage. - -The goals of the class design are: - - -# All the data has explicit ownership to avoid memory leaks - -# No hidden allocations or copies for performance. - -# Easy access to OpenCV methods (which will access IPP if available) - -# Can easily treat external data as an image - -# Easy to create images which are subsets of other images - -# Fast pixel access which can take advantage of number of channels if known at compile time. - -The WImage class is the image class which provides the data accessors. The 'W' comes from the fact -that it is also a wrapper around the popular but inconvenient IplImage class. A WImage can be -constructed either using a WImageBuffer class which allocates and frees the data, or using a -WImageView class which constructs a subimage or a view into external data. The view class does no -memory management. Each class actually has two versions, one when the number of channels is known -at compile time and one when it isn't. Using the one with the number of channels specified can -provide some compile time optimizations by using the fact that the number of channels is a -constant. - -We use the convention (c,r) to refer to column c and row r with (0,0) being the upper left corner. -This is similar to standard Euclidean coordinates with the first coordinate varying in the -horizontal direction and the second coordinate varying in the vertical direction. Thus (c,r) is -usually in the domain [0, width) X [0, height) - -Example usage: -@code -WImageBuffer3_b im(5,7); // Make a 5X7 3 channel image of type uchar -WImageView3_b sub_im(im, 2,2, 3,3); // 3X3 submatrix -vector vec(10, 3.0f); -WImageView1_f user_im(&vec[0], 2, 5); // 2X5 image w/ supplied data - -im.SetZero(); // same as cvSetZero(im.Ipl()) -*im(2, 3) = 15; // Modify the element at column 2, row 3 -MySetRand(&sub_im); - -// Copy the second row into the first. This can be done with no memory -// allocation and will use SSE if IPP is available. -int w = im.Width(); -im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1)); - -// Doesn't care about source of data since using WImage -void MySetRand(WImage_b* im) { // Works with any number of channels -for (int r = 0; r < im->Height(); ++r) { - float* row = im->Row(r); - for (int c = 0; c < im->Width(); ++c) { - for (int ch = 0; ch < im->Channels(); ++ch, ++row) { - *row = uchar(rand() & 255); - } - } -} -} -@endcode - -Functions that are not part of the basic image allocation, viewing, and access should come from -OpenCV, except some useful functions that are not part of OpenCV can be found in wimage_util.h -*/ -template -class WImage -{ -public: - typedef T BaseType; - - // WImage is an abstract class with no other virtual methods so make the - // destructor virtual. - virtual ~WImage() = 0; - - // Accessors - IplImage* Ipl() {return image_; } - const IplImage* Ipl() const {return image_; } - T* ImageData() { return reinterpret_cast(image_->imageData); } - const T* ImageData() const { - return reinterpret_cast(image_->imageData); - } - - int Width() const {return image_->width; } - int Height() const {return image_->height; } - - // WidthStep is the number of bytes to go to the pixel with the next y coord - int WidthStep() const {return image_->widthStep; } - - int Channels() const {return image_->nChannels; } - int ChannelSize() const {return sizeof(T); } // number of bytes per channel - - // Number of bytes per pixel - int PixelSize() const {return Channels() * ChannelSize(); } - - // Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number - // of bits per channel and with the signed bit set. - // This is known at compile time using specializations. - int Depth() const; - - inline const T* Row(int r) const { - return reinterpret_cast(image_->imageData + r*image_->widthStep); - } - - inline T* Row(int r) { - return reinterpret_cast(image_->imageData + r*image_->widthStep); - } - - // Pixel accessors which returns a pointer to the start of the channel - inline T* operator() (int c, int r) { - return reinterpret_cast(image_->imageData + r*image_->widthStep) + - c*Channels(); - } - - inline const T* operator() (int c, int r) const { - return reinterpret_cast(image_->imageData + r*image_->widthStep) + - c*Channels(); - } - - // Copy the contents from another image which is just a convenience to cvCopy - void CopyFrom(const WImage& src) { cvCopy(src.Ipl(), image_); } - - // Set contents to zero which is just a convenient to cvSetZero - void SetZero() { cvSetZero(image_); } - - // Construct a view into a region of this image - WImageView View(int c, int r, int width, int height); - -protected: - // Disallow copy and assignment - WImage(const WImage&); - void operator=(const WImage&); - - explicit WImage(IplImage* img) : image_(img) { - assert(!img || img->depth == Depth()); - } - - void SetIpl(IplImage* image) { - assert(!image || image->depth == Depth()); - image_ = image; - } - - IplImage* image_; -}; - - -/** Image class when both the pixel type and number of channels -are known at compile time. This wrapper will speed up some of the operations -like accessing individual pixels using the () operator. -*/ -template -class WImageC : public WImage -{ -public: - typedef typename WImage::BaseType BaseType; - enum { kChannels = C }; - - explicit WImageC(IplImage* img) : WImage(img) { - assert(!img || img->nChannels == Channels()); - } - - // Construct a view into a region of this image - WImageViewC View(int c, int r, int width, int height); - - // Copy the contents from another image which is just a convenience to cvCopy - void CopyFrom(const WImageC& src) { - cvCopy(src.Ipl(), WImage::image_); - } - - // WImageC is an abstract class with no other virtual methods so make the - // destructor virtual. - virtual ~WImageC() = 0; - - int Channels() const {return C; } - -protected: - // Disallow copy and assignment - WImageC(const WImageC&); - void operator=(const WImageC&); - - void SetIpl(IplImage* image) { - assert(!image || image->depth == WImage::Depth()); - WImage::SetIpl(image); - } -}; - -/** Image class which owns the data, so it can be allocated and is always -freed. It cannot be copied but can be explicitly cloned. -*/ -template -class WImageBuffer : public WImage -{ -public: - typedef typename WImage::BaseType BaseType; - - // Default constructor which creates an object that can be - WImageBuffer() : WImage(0) {} - - WImageBuffer(int width, int height, int nchannels) : WImage(0) { - Allocate(width, height, nchannels); - } - - // Constructor which takes ownership of a given IplImage so releases - // the image on destruction. - explicit WImageBuffer(IplImage* img) : WImage(img) {} - - // Allocate an image. Does nothing if current size is the same as - // the new size. - void Allocate(int width, int height, int nchannels); - - // Set the data to point to an image, releasing the old data - void SetIpl(IplImage* img) { - ReleaseImage(); - WImage::SetIpl(img); - } - - // Clone an image which reallocates the image if of a different dimension. - void CloneFrom(const WImage& src) { - Allocate(src.Width(), src.Height(), src.Channels()); - CopyFrom(src); - } - - ~WImageBuffer() { - ReleaseImage(); - } - - // Release the image if it isn't null. - void ReleaseImage() { - if (WImage::image_) { - IplImage* image = WImage::image_; - cvReleaseImage(&image); - WImage::SetIpl(0); - } - } - - bool IsNull() const {return WImage::image_ == NULL; } - -private: - // Disallow copy and assignment - WImageBuffer(const WImageBuffer&); - void operator=(const WImageBuffer&); -}; - -/** Like a WImageBuffer class but when the number of channels is known at compile time. -*/ -template -class WImageBufferC : public WImageC -{ -public: - typedef typename WImage::BaseType BaseType; - enum { kChannels = C }; - - // Default constructor which creates an object that can be - WImageBufferC() : WImageC(0) {} - - WImageBufferC(int width, int height) : WImageC(0) { - Allocate(width, height); - } - - // Constructor which takes ownership of a given IplImage so releases - // the image on destruction. - explicit WImageBufferC(IplImage* img) : WImageC(img) {} - - // Allocate an image. Does nothing if current size is the same as - // the new size. - void Allocate(int width, int height); - - // Set the data to point to an image, releasing the old data - void SetIpl(IplImage* img) { - ReleaseImage(); - WImageC::SetIpl(img); - } - - // Clone an image which reallocates the image if of a different dimension. - void CloneFrom(const WImageC& src) { - Allocate(src.Width(), src.Height()); - CopyFrom(src); - } - - ~WImageBufferC() { - ReleaseImage(); - } - - // Release the image if it isn't null. - void ReleaseImage() { - if (WImage::image_) { - IplImage* image = WImage::image_; - cvReleaseImage(&image); - WImageC::SetIpl(0); - } - } - - bool IsNull() const {return WImage::image_ == NULL; } - -private: - // Disallow copy and assignment - WImageBufferC(const WImageBufferC&); - void operator=(const WImageBufferC&); -}; - -/** View into an image class which allows treating a subimage as an image or treating external data -as an image -*/ -template class WImageView : public WImage -{ -public: - typedef typename WImage::BaseType BaseType; - - // Construct a subimage. No checks are done that the subimage lies - // completely inside the original image. - WImageView(WImage* img, int c, int r, int width, int height); - - // Refer to external data. - // If not given width_step assumed to be same as width. - WImageView(T* data, int width, int height, int channels, int width_step = -1); - - // Refer to external data. This does NOT take ownership - // of the supplied IplImage. - WImageView(IplImage* img) : WImage(img) {} - - // Copy constructor - WImageView(const WImage& img) : WImage(0) { - header_ = *(img.Ipl()); - WImage::SetIpl(&header_); - } - - WImageView& operator=(const WImage& img) { - header_ = *(img.Ipl()); - WImage::SetIpl(&header_); - return *this; - } - -protected: - IplImage header_; -}; - - -template -class WImageViewC : public WImageC -{ -public: - typedef typename WImage::BaseType BaseType; - enum { kChannels = C }; - - // Default constructor needed for vectors of views. - WImageViewC(); - - virtual ~WImageViewC() {} - - // Construct a subimage. No checks are done that the subimage lies - // completely inside the original image. - WImageViewC(WImageC* img, - int c, int r, int width, int height); - - // Refer to external data - WImageViewC(T* data, int width, int height, int width_step = -1); - - // Refer to external data. This does NOT take ownership - // of the supplied IplImage. - WImageViewC(IplImage* img) : WImageC(img) {} - - // Copy constructor which does a shallow copy to allow multiple views - // of same data. gcc-4.1.1 gets confused if both versions of - // the constructor and assignment operator are not provided. - WImageViewC(const WImageC& img) : WImageC(0) { - header_ = *(img.Ipl()); - WImageC::SetIpl(&header_); - } - WImageViewC(const WImageViewC& img) : WImageC(0) { - header_ = *(img.Ipl()); - WImageC::SetIpl(&header_); - } - - WImageViewC& operator=(const WImageC& img) { - header_ = *(img.Ipl()); - WImageC::SetIpl(&header_); - return *this; - } - WImageViewC& operator=(const WImageViewC& img) { - header_ = *(img.Ipl()); - WImageC::SetIpl(&header_); - return *this; - } - -protected: - IplImage header_; -}; - - -// Specializations for depth -template<> -inline int WImage::Depth() const {return IPL_DEPTH_8U; } -template<> -inline int WImage::Depth() const {return IPL_DEPTH_8S; } -template<> -inline int WImage::Depth() const {return IPL_DEPTH_16S; } -template<> -inline int WImage::Depth() const {return IPL_DEPTH_16U; } -template<> -inline int WImage::Depth() const {return IPL_DEPTH_32S; } -template<> -inline int WImage::Depth() const {return IPL_DEPTH_32F; } -template<> -inline int WImage::Depth() const {return IPL_DEPTH_64F; } - -template inline WImage::~WImage() {} -template inline WImageC::~WImageC() {} - -template -inline void WImageBuffer::Allocate(int width, int height, int nchannels) -{ - if (IsNull() || WImage::Width() != width || - WImage::Height() != height || WImage::Channels() != nchannels) { - ReleaseImage(); - WImage::image_ = cvCreateImage(cvSize(width, height), - WImage::Depth(), nchannels); - } -} - -template -inline void WImageBufferC::Allocate(int width, int height) -{ - if (IsNull() || WImage::Width() != width || WImage::Height() != height) { - ReleaseImage(); - WImageC::SetIpl(cvCreateImage(cvSize(width, height),WImage::Depth(), C)); - } -} - -template -WImageView::WImageView(WImage* img, int c, int r, int width, int height) - : WImage(0) -{ - header_ = *(img->Ipl()); - header_.imageData = reinterpret_cast((*img)(c, r)); - header_.width = width; - header_.height = height; - WImage::SetIpl(&header_); -} - -template -WImageView::WImageView(T* data, int width, int height, int nchannels, int width_step) - : WImage(0) -{ - cvInitImageHeader(&header_, cvSize(width, height), WImage::Depth(), nchannels); - header_.imageData = reinterpret_cast(data); - if (width_step > 0) { - header_.widthStep = width_step; - } - WImage::SetIpl(&header_); -} - -template -WImageViewC::WImageViewC(WImageC* img, int c, int r, int width, int height) - : WImageC(0) -{ - header_ = *(img->Ipl()); - header_.imageData = reinterpret_cast((*img)(c, r)); - header_.width = width; - header_.height = height; - WImageC::SetIpl(&header_); -} - -template -WImageViewC::WImageViewC() : WImageC(0) { - cvInitImageHeader(&header_, cvSize(0, 0), WImage::Depth(), C); - header_.imageData = reinterpret_cast(0); - WImageC::SetIpl(&header_); -} - -template -WImageViewC::WImageViewC(T* data, int width, int height, int width_step) - : WImageC(0) -{ - cvInitImageHeader(&header_, cvSize(width, height), WImage::Depth(), C); - header_.imageData = reinterpret_cast(data); - if (width_step > 0) { - header_.widthStep = width_step; - } - WImageC::SetIpl(&header_); -} - -// Construct a view into a region of an image -template -WImageView WImage::View(int c, int r, int width, int height) { - return WImageView(this, c, r, width, height); -} - -template -WImageViewC WImageC::View(int c, int r, int width, int height) { - return WImageViewC(this, c, r, width, height); -} - -//! @} core - -} // end of namespace - -#endif // __cplusplus - -#endif diff --git a/3rdparty/libopencv/include/opencv2/cvconfig.h b/3rdparty/libopencv/include/opencv2/cvconfig.h deleted file mode 100644 index 8f857c6..0000000 --- a/3rdparty/libopencv/include/opencv2/cvconfig.h +++ /dev/null @@ -1,248 +0,0 @@ -#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 "" - -/* AVFoundation video libraries */ -/* #undef HAVE_AVFOUNDATION */ - -/* V4L capturing support */ -/* #undef HAVE_CAMV4L */ - -/* V4L2 capturing support */ -#define HAVE_CAMV4L2 - -/* Carbon windowing environment */ -/* #undef HAVE_CARBON */ - -/* 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 */ - -/* C= */ -/* #undef HAVE_CSTRIPES */ - -/* NVidia Cuda Basic Linear Algebra Subprograms (BLAS) API*/ -/* #undef HAVE_CUBLAS */ - -/* NVidia Cuda Runtime API*/ -/* #undef HAVE_CUDA */ - -/* NVidia Cuda Fast Fourier Transform (FFT) API*/ -/* #undef HAVE_CUFFT */ - -/* IEEE1394 capturing support */ -/* #undef HAVE_DC1394 */ - -/* IEEE1394 capturing support - libdc1394 v2.x */ -/* #undef HAVE_DC1394_2 */ - -/* DirectX */ -/* #undef HAVE_DIRECTX */ -/* #undef HAVE_DIRECTX_NV12 */ -/* #undef HAVE_D3D11 */ -/* #undef HAVE_D3D10 */ -/* #undef HAVE_D3D9 */ - -/* DirectShow Video Capture library */ -/* #undef HAVE_DSHOW */ - -/* Eigen Matrix & Linear Algebra Library */ -/* #undef HAVE_EIGEN */ - -/* FFMpeg video library */ -/* #undef HAVE_FFMPEG */ - -/* Geospatial Data Abstraction Library */ -/* #undef HAVE_GDAL */ - -/* GStreamer multimedia framework */ -/* #undef HAVE_GSTREAMER */ - -/* GTK+ 2.0 Thread support */ -/* #undef HAVE_GTHREAD */ - -/* GTK+ 2.x toolkit */ -/* #undef HAVE_GTK */ - -/* Halide support */ -/* #undef HAVE_HALIDE */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Intel Perceptual Computing SDK library */ -/* #undef HAVE_INTELPERC */ - -/* Intel Integrated Performance Primitives */ -/* #undef HAVE_IPP */ -/* #undef HAVE_IPP_ICV */ -/* #undef HAVE_IPP_IW */ - -/* Intel IPP Async */ -/* #undef HAVE_IPP_A */ - -/* 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 */ - -/* V4L/V4L2 capturing support via libv4l */ -/* #undef HAVE_LIBV4L */ - -/* Microsoft Media Foundation Capture library */ -/* #undef HAVE_MSMF */ - -/* 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 */ - -/* OpenEXR codec */ -#define HAVE_OPENEXR - -/* OpenGL support*/ -/* #undef HAVE_OPENGL */ - -/* OpenNI library */ -/* #undef HAVE_OPENNI */ - -/* OpenNI library */ -/* #undef HAVE_OPENNI2 */ - -/* PNG codec */ -#define HAVE_PNG - -/* Posix threads (pthreads) */ -#define HAVE_PTHREAD - -/* parallel_for with pthreads */ -#define HAVE_PTHREADS_PF - -/* Qt support */ -/* #undef HAVE_QT */ - -/* Qt OpenGL support */ -/* #undef HAVE_QT_OPENGL */ - -/* QuickTime video libraries */ -/* #undef HAVE_QUICKTIME */ - -/* QTKit video libraries */ -/* #undef HAVE_QTKIT */ - -/* Intel Threading Building Blocks */ -/* #undef HAVE_TBB */ - -/* TIFF codec */ -#define HAVE_TIFF - -/* Unicap video capture library */ -/* #undef HAVE_UNICAP */ - -/* Video for Windows support */ -/* #undef HAVE_VFW */ - -/* V4L2 capturing support in videoio.h */ -/* #undef HAVE_VIDEOIO */ - -/* Win32 UI */ -/* #undef HAVE_WIN32UI */ - -/* XIMEA camera support */ -/* #undef HAVE_XIMEA */ - -/* Xine video library */ -/* #undef HAVE_XINE */ - -/* Define if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ - -/* gPhoto2 library */ -/* #undef HAVE_GPHOTO2 */ - -/* VA library (libva) */ -/* #undef HAVE_VA */ - -/* Intel VA-API/OpenCL */ -/* #undef HAVE_VA_INTEL */ - -/* Intel Media SDK */ -/* #undef HAVE_MFX */ - -/* Lapack */ -/* #undef HAVE_LAPACK */ - -/* Library was compiled with functions instrumentation */ -/* #undef ENABLE_INSTRUMENTATION */ - -/* OpenVX */ -/* #undef HAVE_OPENVX */ - -#if defined(HAVE_XINE) || \ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - /*defined(HAVE_OPENNI) || too specialized */ \ - defined(HAVE_FFMPEG) || \ - defined(HAVE_MSMF) -#define HAVE_VIDEO_INPUT -#endif - -#if /*defined(HAVE_XINE) || */\ - defined(HAVE_GSTREAMER) || \ - defined(HAVE_QUICKTIME) || \ - defined(HAVE_QTKIT) || \ - defined(HAVE_AVFOUNDATION) || \ - defined(HAVE_FFMPEG) || \ - defined(HAVE_MSMF) -#define HAVE_VIDEO_OUTPUT -#endif - -/* OpenCV trace utilities */ -#define OPENCV_TRACE - - -#endif // OPENCV_CVCONFIG_H_INCLUDED diff --git a/3rdparty/libopencv/include/opencv2/dnn.hpp b/3rdparty/libopencv/include/opencv2/dnn.hpp deleted file mode 100644 index 57a564b..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/*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 umbrealla 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 constuct 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. - @} -*/ -#include - -#endif /* OPENCV_DNN_HPP */ diff --git a/3rdparty/libopencv/include/opencv2/dnn/all_layers.hpp b/3rdparty/libopencv/include/opencv2/dnn/all_layers.hpp deleted file mode 100644 index 34f5616..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn/all_layers.hpp +++ /dev/null @@ -1,589 +0,0 @@ -/*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_EXPERIMENTAL_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 partuclar, 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); - }; - - //! 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 contacentaion 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 abovemtioned notation is @f$ W_h @f$) - @param Wx is matrix defining how current input is transformed to internal gates (i.e. according to abovemtioned notation is @f$ W_x @f$) - @param b is bias vector (i.e. according to abovemtioned 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 fase 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); - int outputNameToIndex(String outputName); - }; - - /** @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: - Size kernel, stride, pad, dilation, adjustPad; - 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; - Size kernel, stride, pad; - 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); - }; - - /** - * @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: - int startAxis; - std::vector offset; - - static Ptr create(const LayerParams ¶ms); - }; - - class CV_EXPORTS EltwiseLayer : public Layer - { - public: - static Ptr create(const LayerParams ¶ms); - }; - - class CV_EXPORTS BatchNormLayer : public Layer - { - 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 cooridnates, `c` - channel. - * - * An every sample in the batch is normalized separately. Optionally, - * output is scaled by the trained parameters. - */ - class NormalizeBBoxLayer : public Layer - { - public: - float pnorm, epsilon; - bool acrossSpatial; - - static Ptr create(const LayerParams& params); - }; - - /** - * @brief Resize input 4-dimensional blob by nearest neghbor strategy. - * - * Layer is used to support TensorFlow's resize_nearest_neighbor op. - */ - class CV_EXPORTS ResizeNearestNeighborLayer : public Layer - { - public: - static Ptr create(const LayerParams& params); - }; - - class CV_EXPORTS ProposalLayer : public Layer - { - public: - static Ptr create(const LayerParams& params); - }; - -//! @} -//! @} -CV__DNN_EXPERIMENTAL_NS_END -} -} -#endif diff --git a/3rdparty/libopencv/include/opencv2/dnn/dict.hpp b/3rdparty/libopencv/include/opencv2/dnn/dict.hpp deleted file mode 100644 index 43cb58a..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn/dict.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/*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_EXPERIMENTAL_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(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: - - int type; - - union - { - AutoBuffer *pi; - AutoBuffer *pd; - AutoBuffer *ps; - void *pv; - }; - - DictValue(int _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); - - friend std::ostream &operator<<(std::ostream &stream, const Dict &dict); -}; - -//! @} -CV__DNN_EXPERIMENTAL_NS_END -} -} - -#endif diff --git a/3rdparty/libopencv/include/opencv2/dnn/dnn.hpp b/3rdparty/libopencv/include/opencv2/dnn/dnn.hpp deleted file mode 100644 index 54f33a6..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn/dnn.hpp +++ /dev/null @@ -1,794 +0,0 @@ -/*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 - -#if !defined CV_DOXYGEN && !defined CV_DNN_DONT_ADD_EXPERIMENTAL_NS -#define CV__DNN_EXPERIMENTAL_NS_BEGIN namespace experimental_dnn_v4 { -#define CV__DNN_EXPERIMENTAL_NS_END } -namespace cv { namespace dnn { namespace experimental_dnn_v4 { } using namespace experimental_dnn_v4; }} -#else -#define CV__DNN_EXPERIMENTAL_NS_BEGIN -#define CV__DNN_EXPERIMENTAL_NS_END -#endif - -#include - -namespace cv { -namespace dnn { -CV__DNN_EXPERIMENTAL_NS_BEGIN -//! @addtogroup dnn -//! @{ - - typedef std::vector MatShape; - - /** - * @brief Enum of computation backends supported by layers. - */ - enum Backend - { - DNN_BACKEND_DEFAULT, - DNN_BACKEND_HALIDE, - DNN_BACKEND_INFERENCE_ENGINE - }; - - /** - * @brief Enum of target devices for computations. - */ - enum Target - { - DNN_TARGET_CPU, - DNN_TARGET_OPENCL - }; - - /** @brief This class provides all data needed to initialize layer. - * - * It includes dictionary with scalar params (which can be readed 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 - * associented 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; - class CV_EXPORTS BatchNormLayer; - class CV_EXPORTS ScaleLayer; - - /** @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. - * @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. - */ - virtual void finalize(const std::vector &input, std::vector &output); - - /** @brief Given the @p input blobs, computes the output @p blobs. - * @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 - */ - virtual void forward(std::vector &input, std::vector &output, std::vector &internals) = 0; - - /** @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) = 0; - - /** @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 */ - CV_WRAP void finalize(const std::vector &inputs, CV_OUT std::vector &outputs); - - /** @brief @overload */ - CV_WRAP std::vector finalize(const std::vector &inputs); - - /** @brief Allocates layer and computes output. */ - 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() - */ - virtual int outputNameToIndex(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); - - /** - * @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 {(void)inputs; (void)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. - - /** Returns true if there are no layers in the network. */ - CV_WRAP bool empty() const; - - /** @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 Delete layer for the network (not implemented yet) */ - CV_WRAP void deleteLayer(LayerId layer); - - /** @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 inpLayerId identifier of the second layer - * @param outNum number of the first layer output - * @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 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 - */ - CV_WRAP void setPreferableBackend(int backendId); - - /** - * @brief Ask network to make computations on specific target device. - * @param[in] targetId target identifier. - * @see Target - */ - CV_WRAP void setPreferableTarget(int targetId); - - /** @brief Sets the new value for the layer output blob - * @param name descriptor of the updating layer output blob. - * @param blob new blob. - * @see connect(String, String) to know format of the descriptor. - * @note If updating blob is not empty then @p blob must have the same shape, - * because network reshaping is not implemented yet. - */ - CV_WRAP void setInput(InputArray blob, const String& name = ""); - - /** @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 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 requered 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 requered 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 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. - * @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. - * @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. - * @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); - - /** @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 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 - * @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-dimansional 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=true, bool crop=true); - - /** @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=true, bool crop=true); - - - /** @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 - * @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-dimansional 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=true, bool crop=true); - - /** @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=true, bool crop=true); - - /** @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 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__DNN_EXPERIMENTAL_NS_END -} -} - -#include -#include - -#endif /* OPENCV_DNN_DNN_HPP */ diff --git a/3rdparty/libopencv/include/opencv2/dnn/dnn.inl.hpp b/3rdparty/libopencv/include/opencv2/dnn/dnn.inl.hpp deleted file mode 100644 index c30185b..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn/dnn.inl.hpp +++ /dev/null @@ -1,373 +0,0 @@ -/*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_EXPERIMENTAL_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 - { - CV_Assert(isInt() || isReal()); - 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 - { - CV_Assert(isReal() || isInt()); - 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; - } -} - -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(); - break; - case Param::STRING: - return (int)ps->size(); - break; - case Param::REAL: - return (int)pd->size(); - break; - default: - CV_Error(Error::StsInternal, ""); - return -1; - } -} - -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 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; -} - -CV__DNN_EXPERIMENTAL_NS_END -} -} - -#endif diff --git a/3rdparty/libopencv/include/opencv2/dnn/layer.details.hpp b/3rdparty/libopencv/include/opencv2/dnn/layer.details.hpp deleted file mode 100644 index 82bd3b1..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn/layer.details.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// 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_EXPERIMENTAL_NS_BEGIN - -/** @brief Registers layer constructor in runtime. -* @param type string, containing type name of the layer. -* @param constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer. -* @details This macros must be placed inside the function code. -*/ -#define CV_DNN_REGISTER_LAYER_FUNC(type, constuctorFunc) \ - cv::dnn::LayerFactory::registerLayer(#type, constuctorFunc); - -/** @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 constuctorFunc pointer to the function of type LayerRegister::Constuctor, which creates the layer. -* @details This macros must be placed outside the function code. -*/ -#define CV_DNN_REGISTER_LAYER_FUNC_STATIC(type, constuctorFunc) \ -static cv::dnn::details::_LayerStaticRegisterer __LayerStaticRegisterer_##type(#type, constuctorFunc); - -/** @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::Constuctor layerConstuctor) - { - this->type = layerType; - LayerFactory::registerLayer(layerType, layerConstuctor); - } - - ~_LayerStaticRegisterer() - { - LayerFactory::unregisterLayer(type); - } -}; - -} // namespace -CV__DNN_EXPERIMENTAL_NS_END -}} // namespace - -#endif diff --git a/3rdparty/libopencv/include/opencv2/dnn/layer.hpp b/3rdparty/libopencv/include/opencv2/dnn/layer.hpp deleted file mode 100644 index 3fb81f3..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn/layer.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/*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_EXPERIMENTAL_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(*Constuctor)(LayerParams ¶ms); - - //! Registers the layer class with typename @p type and specified @p constructor. Thread-safe. - static void registerLayer(const String &type, Constuctor 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_EXPERIMENTAL_NS_END -} -} -#endif diff --git a/3rdparty/libopencv/include/opencv2/dnn/shape_utils.hpp b/3rdparty/libopencv/include/opencv2/dnn/shape_utils.hpp deleted file mode 100644 index fa4b497..0000000 --- a/3rdparty/libopencv/include/opencv2/dnn/shape_utils.hpp +++ /dev/null @@ -1,206 +0,0 @@ -/*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 -#include - -namespace cv { -namespace dnn { -CV__DNN_EXPERIMENTAL_NS_BEGIN - -//Useful shortcut -inline std::ostream &operator<< (std::ostream &s, cv::Range &r) -{ - return s << "[" << r.start << ", " << r.end << ")"; -} - -//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 = 4) -{ - 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 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); - 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; -} - -inline void print(const MatShape& shape, const String& name = "") -{ - printf("%s: [", name.c_str()); - size_t i, n = shape.size(); - for( i = 0; i < n; i++ ) - printf(" %d", shape[i]); - printf(" ]\n"); -} - -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(clamped.start < clamped.end, clamped.end <= axisSize); - return clamped; -} - -CV__DNN_EXPERIMENTAL_NS_END -} -} -#endif diff --git a/3rdparty/libopencv/include/opencv2/features2d.hpp b/3rdparty/libopencv/include/opencv2/features2d.hpp deleted file mode 100644 index 06e15ac..0000000 --- a/3rdparty/libopencv/include/opencv2/features2d.hpp +++ /dev/null @@ -1,1424 +0,0 @@ -/*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 -*/ -class CV_EXPORTS_W Feature2D : public virtual Algorithm -{ -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; - - // see corresponding cv::Algorithm method - CV_WRAP virtual void read( const FileNode&); - - //! Return true if detector object is empty - CV_WRAP virtual bool empty() const; - CV_WRAP virtual String getDefaultName() const; - - // 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; -}; - -/** @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 { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 }; - - /** @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 - */ - 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, int 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(int scoreType) = 0; - CV_WRAP virtual int 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; -}; - -/** @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; -}; - -/** @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 cv2.FAST_FEATURE_DETECTOR_TYPE_5_8, -cv2.FAST_FEATURE_DETECTOR_TYPE_7_12 and cv2.FAST_FEATURE_DETECTOR_TYPE_9_16. For corner -detection, use cv2.FAST.detect() method. - */ -CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector& keypoints, - int threshold, bool nonmaxSuppression, int type ); - -//! @} features2d_main - -//! @addtogroup features2d_main -//! @{ - -/** @brief Wrapping class for feature detection using the FAST method. : - */ -class CV_EXPORTS_W FastFeatureDetector : public Feature2D -{ -public: - enum - { - TYPE_5_8 = 0, TYPE_7_12 = 1, TYPE_9_16 = 2, - THRESHOLD = 10000, NONMAX_SUPPRESSION=10001, FAST_N=10002, - }; - - CV_WRAP static Ptr create( int threshold=10, - bool nonmaxSuppression=true, - int 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(int type) = 0; - CV_WRAP virtual int getType() const = 0; - CV_WRAP virtual String getDefaultName() const; -}; - -/** @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, int 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 - { - AGAST_5_8 = 0, AGAST_7_12d = 1, AGAST_7_12s = 2, OAST_9_16 = 3, - THRESHOLD = 10000, NONMAX_SUPPRESSION = 10001, - }; - - CV_WRAP static Ptr create( int threshold=10, - bool nonmaxSuppression=true, - int 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(int type) = 0; - CV_WRAP virtual int getType() const = 0; - CV_WRAP virtual String getDefaultName() const; -}; - -/** @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; -}; - -/** @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; -}; - -//! @} 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 - { - 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, - int 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(int diff) = 0; - CV_WRAP virtual int getDiffusivity() const = 0; - CV_WRAP virtual String getDefaultName() const; -}; - -/** @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 - { - 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(int descriptor_type=AKAZE::DESCRIPTOR_MLDB, - int descriptor_size = 0, int descriptor_channels = 3, - float threshold = 0.001f, int nOctaves = 4, - int nOctaveLayers = 4, int diffusivity = KAZE::DIFF_PM_G2); - - CV_WRAP virtual void setDescriptorType(int dtype) = 0; - CV_WRAP virtual int 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(int diff) = 0; - CV_WRAP virtual int getDiffusivity() const = 0; - CV_WRAP virtual String getDefaultName() const; -}; - -//! @} 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 -{ - enum { 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 -{ - enum { 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 -{ - enum { 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 - { - 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(); - - /** @brief Returns true if there are no train descriptors in the both collections. - */ - CV_WRAP virtual bool empty() const; - - /** @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& ); - // Writes matcher object to a file storage - virtual void write( FileStorage& ) const; - - /** @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( int 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 { 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; -protected: - virtual void knnMatchImpl( InputArray queryDescriptors, std::vector >& matches, int k, - InputArrayOfArrays masks=noArray(), bool compactResult=false ); - virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector >& matches, float maxDistance, - InputArrayOfArrays masks=noArray(), bool compactResult=false ); - - 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 ); - virtual void clear(); - - // Reads matcher object from a file node - virtual void read( const FileNode& ); - // Writes matcher object to a file storage - virtual void write( FileStorage& ) const; - - virtual void train(); - virtual bool isMaskSupported() const; - - CV_WRAP static Ptr create(); - - virtual Ptr clone( bool emptyTrainData=false ) const; -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 ); - virtual void radiusMatchImpl( InputArray queryDescriptors, std::vector >& matches, float maxDistance, - InputArrayOfArrays masks=noArray(), bool compactResult=false ); - - Ptr indexParams; - Ptr searchParams; - Ptr flannIndex; - - DescriptorCollection mergedDescriptors; - int addedDescCount; -}; - -#endif - -//! @} features2d_match - -/****************************************************************************************\ -* Drawing functions * -\****************************************************************************************/ - -//! @addtogroup features2d_draw -//! @{ - -struct CV_EXPORTS DrawMatchesFlags -{ - enum{ 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. - }; -}; - -/** @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 cv2.DRAW_MATCHES_FLAGS_DEFAULT, -cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG, -cv2.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), int 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(), int 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 >(), int 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_WRAP virtual Mat cluster( const Mat& descriptors ) const; - -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/3rdparty/libopencv/include/opencv2/features2d/features2d.hpp b/3rdparty/libopencv/include/opencv2/features2d/features2d.hpp deleted file mode 100644 index e81df0a..0000000 --- a/3rdparty/libopencv/include/opencv2/features2d/features2d.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/features2d/hal/interface.h b/3rdparty/libopencv/include/opencv2/features2d/hal/interface.h deleted file mode 100644 index bcc6577..0000000 --- a/3rdparty/libopencv/include/opencv2/features2d/hal/interface.h +++ /dev/null @@ -1,33 +0,0 @@ -#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/3rdparty/libopencv/include/opencv2/flann.hpp b/3rdparty/libopencv/include/opencv2/flann.hpp deleted file mode 100644 index 22c6ffc..0000000 --- a/3rdparty/libopencv/include/opencv2/flann.hpp +++ /dev/null @@ -1,531 +0,0 @@ -/*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. - */ -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); - - 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 nnIndex->size(); } - - ::cvflann::IndexParams getParameters() { return nnIndex->getParameters(); } - - CV_DEPRECATED const ::cvflann::IndexParams* getIndexParameters() { return nnIndex->getIndexParameters(); } - -private: - ::cvflann::Index* nnIndex; -}; - -//! @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) -{ - 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/3rdparty/libopencv/include/opencv2/flann/all_indices.h b/3rdparty/libopencv/include/opencv2/flann/all_indices.h deleted file mode 100644 index ff53fd8..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/all_indices.h +++ /dev/null @@ -1,155 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/allocator.h b/3rdparty/libopencv/include/opencv2/flann/allocator.h deleted file mode 100644 index f347f88..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/allocator.h +++ /dev/null @@ -1,192 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/any.h b/3rdparty/libopencv/include/opencv2/flann/any.h deleted file mode 100644 index e829162..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/any.h +++ /dev/null @@ -1,330 +0,0 @@ -#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() { return sizeof(T); } - virtual const std::type_info& type() { return typeid(T); } - -}; - -template -struct small_any_policy : typed_base_any_policy -{ - virtual void static_delete(void**) { } - virtual void copy_from_value(void const* src, void** dest) - { - new (dest) T(* reinterpret_cast(src)); - } - virtual void clone(void* const* src, void** dest) { *dest = *src; } - virtual void move(void* const* src, void** dest) { *dest = *src; } - virtual void* get_value(void** src) { return reinterpret_cast(src); } - virtual const void* get_value(void* const * src) { return reinterpret_cast(src); } - virtual void print(std::ostream& out, void* const* src) { out << *reinterpret_cast(src); } -}; - -template -struct big_any_policy : typed_base_any_policy -{ - virtual void static_delete(void** x) - { - if (* x) delete (* reinterpret_cast(x)); - *x = NULL; - } - virtual void copy_from_value(void const* src, void** dest) - { - *dest = new T(*reinterpret_cast(src)); - } - virtual void clone(void* const* src, void** dest) - { - *dest = new T(**reinterpret_cast(src)); - } - virtual void move(void* const* src, void** dest) - { - (*reinterpret_cast(dest))->~T(); - **reinterpret_cast(dest) = **reinterpret_cast(src); - } - virtual void* get_value(void** src) { return *src; } - virtual const void* get_value(void* const * src) { return *src; } - virtual void print(std::ostream& out, void* const* src) { 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/3rdparty/libopencv/include/opencv2/flann/autotuned_index.h b/3rdparty/libopencv/include/opencv2/flann/autotuned_index.h deleted file mode 100644 index e9abbf7..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/autotuned_index.h +++ /dev/null @@ -1,591 +0,0 @@ -/*********************************************************************** - * 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() - { - 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) - { - 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) - { - 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) - { - 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 - { - return bestIndex_->getParameters(); - } - - SearchParams getSearchParameters() const - { - return bestSearchParams_; - } - - float getSpeedup() const - { - return speedup_; - } - - - /** - * Number of features in this index. - */ - virtual size_t size() const - { - return bestIndex_->size(); - } - - /** - * The length of each vector in this index. - */ - virtual size_t veclen() const - { - return bestIndex_->veclen(); - } - - /** - * The amount of memory (in bytes) this index uses. - */ - virtual int usedMemory() const - { - return bestIndex_->usedMemory(); - } - - /** - * Algorithm name - */ - virtual flann_algorithm_t getType() const - { - 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/3rdparty/libopencv/include/opencv2/flann/composite_index.h b/3rdparty/libopencv/include/opencv2/flann/composite_index.h deleted file mode 100644 index 527ca1a..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/composite_index.h +++ /dev/null @@ -1,194 +0,0 @@ -/*********************************************************************** - * 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 - { - return FLANN_INDEX_COMPOSITE; - } - - /** - * @return Size of the index - */ - size_t size() const - { - return kdtree_index_->size(); - } - - /** - * \returns The dimensionality of the features in this index. - */ - size_t veclen() const - { - return kdtree_index_->veclen(); - } - - /** - * \returns The amount of memory (in bytes) used by the index. - */ - int usedMemory() const - { - return kmeans_index_->usedMemory() + kdtree_index_->usedMemory(); - } - - /** - * \brief Builds the index - */ - void buildIndex() - { - 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) - { - 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) - { - kmeans_index_->loadIndex(stream); - kdtree_index_->loadIndex(stream); - } - - /** - * \returns The index parameters - */ - IndexParams getParameters() const - { - return index_params_; - } - - /** - * \brief Method that searches for nearest-neighbours - */ - void findNeighbors(ResultSet& result, const ElementType* vec, const SearchParams& searchParams) - { - 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/3rdparty/libopencv/include/opencv2/flann/config.h b/3rdparty/libopencv/include/opencv2/flann/config.h deleted file mode 100644 index 56832fd..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/config.h +++ /dev/null @@ -1,38 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/defines.h b/3rdparty/libopencv/include/opencv2/flann/defines.h deleted file mode 100644 index 6fd53c2..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/defines.h +++ /dev/null @@ -1,164 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/dist.h b/3rdparty/libopencv/include/opencv2/flann/dist.h deleted file mode 100644 index eedaeff..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/dist.h +++ /dev/null @@ -1,905 +0,0 @@ -/*********************************************************************** - * 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 - -#ifdef __ARM_NEON__ -# 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 = *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; -#ifdef __ARM_NEON__ - { - 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 - typedef unsigned long long pop_t; - HammingLUT lut; - result = lut(reinterpret_cast (a), - reinterpret_cast (b), size * sizeof(pop_t)); -#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/3rdparty/libopencv/include/opencv2/flann/dummy.h b/3rdparty/libopencv/include/opencv2/flann/dummy.h deleted file mode 100644 index d6837e5..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/dummy.h +++ /dev/null @@ -1,13 +0,0 @@ - -#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/3rdparty/libopencv/include/opencv2/flann/dynamic_bitset.h b/3rdparty/libopencv/include/opencv2/flann/dynamic_bitset.h deleted file mode 100644 index 923b658..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/dynamic_bitset.h +++ /dev/null @@ -1,159 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/flann.hpp b/3rdparty/libopencv/include/opencv2/flann/flann.hpp deleted file mode 100644 index 227683f..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/flann.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/flann/flann_base.hpp b/3rdparty/libopencv/include/opencv2/flann/flann_base.hpp deleted file mode 100644 index f3fd4fb..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/flann_base.hpp +++ /dev/null @@ -1,295 +0,0 @@ -/*********************************************************************** - * 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() - { - 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) - { - 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) - { - nnIndex_->loadIndex(stream); - } - - /** - * \returns number of features in this index. - */ - size_t veclen() const - { - return nnIndex_->veclen(); - } - - /** - * \returns The dimensionality of the features in this index. - */ - size_t size() const - { - return nnIndex_->size(); - } - - /** - * \returns The index type (kdtree, kmeans,...) - */ - flann_algorithm_t getType() const - { - return nnIndex_->getType(); - } - - /** - * \returns The amount of memory (in bytes) used by the index. - */ - virtual int usedMemory() const - { - return nnIndex_->usedMemory(); - } - - - /** - * \returns The index parameters - */ - IndexParams getParameters() const - { - 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) - { - 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) - { - 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) - { - 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/3rdparty/libopencv/include/opencv2/flann/general.h b/3rdparty/libopencv/include/opencv2/flann/general.h deleted file mode 100644 index 9d5402a..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/general.h +++ /dev/null @@ -1,50 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/ground_truth.h b/3rdparty/libopencv/include/opencv2/flann/ground_truth.h deleted file mode 100644 index fd8f3ae..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/ground_truth.h +++ /dev/null @@ -1,94 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/hdf5.h b/3rdparty/libopencv/include/opencv2/flann/hdf5.h deleted file mode 100644 index 80d23b9..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/hdf5.h +++ /dev/null @@ -1,231 +0,0 @@ -/*********************************************************************** - * 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_HDF5_H_ -#define OPENCV_FLANN_HDF5_H_ - -#include - -#include "matrix.h" - - -namespace cvflann -{ - -namespace -{ - -template -hid_t get_hdf5_type() -{ - throw FLANNException("Unsupported type for IO operations"); -} - -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_CHAR; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_UCHAR; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_SHORT; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_USHORT; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_INT; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_UINT; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_LONG; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_ULONG; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_FLOAT; } -template<> -hid_t get_hdf5_type() { return H5T_NATIVE_DOUBLE; } -} - - -#define CHECK_ERROR(x,y) if ((x)<0) throw FLANNException((y)); - -template -void save_to_file(const cvflann::Matrix& dataset, const String& filename, const String& name) -{ - -#if H5Eset_auto_vers == 2 - H5Eset_auto( H5E_DEFAULT, NULL, NULL ); -#else - H5Eset_auto( NULL, NULL ); -#endif - - herr_t status; - hid_t file_id; - file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); - if (file_id < 0) { - file_id = H5Fcreate(filename.c_str(), H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT); - } - CHECK_ERROR(file_id,"Error creating hdf5 file."); - - hsize_t dimsf[2]; // dataset dimensions - dimsf[0] = dataset.rows; - dimsf[1] = dataset.cols; - - hid_t space_id = H5Screate_simple(2, dimsf, NULL); - hid_t memspace_id = H5Screate_simple(2, dimsf, NULL); - - hid_t dataset_id; -#if H5Dcreate_vers == 2 - dataset_id = H5Dcreate2(file_id, name.c_str(), get_hdf5_type(), space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); -#else - dataset_id = H5Dcreate(file_id, name.c_str(), get_hdf5_type(), space_id, H5P_DEFAULT); -#endif - - if (dataset_id<0) { -#if H5Dopen_vers == 2 - dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT); -#else - dataset_id = H5Dopen(file_id, name.c_str()); -#endif - } - CHECK_ERROR(dataset_id,"Error creating or opening dataset in file."); - - status = H5Dwrite(dataset_id, get_hdf5_type(), memspace_id, space_id, H5P_DEFAULT, dataset.data ); - CHECK_ERROR(status, "Error writing to dataset"); - - H5Sclose(memspace_id); - H5Sclose(space_id); - H5Dclose(dataset_id); - H5Fclose(file_id); - -} - - -template -void load_from_file(cvflann::Matrix& dataset, const String& filename, const String& name) -{ - herr_t status; - hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); - CHECK_ERROR(file_id,"Error opening hdf5 file."); - - hid_t dataset_id; -#if H5Dopen_vers == 2 - dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT); -#else - dataset_id = H5Dopen(file_id, name.c_str()); -#endif - CHECK_ERROR(dataset_id,"Error opening dataset in file."); - - hid_t space_id = H5Dget_space(dataset_id); - - hsize_t dims_out[2]; - H5Sget_simple_extent_dims(space_id, dims_out, NULL); - - dataset = cvflann::Matrix(new T[dims_out[0]*dims_out[1]], dims_out[0], dims_out[1]); - - status = H5Dread(dataset_id, get_hdf5_type(), H5S_ALL, H5S_ALL, H5P_DEFAULT, dataset[0]); - CHECK_ERROR(status, "Error reading dataset"); - - H5Sclose(space_id); - H5Dclose(dataset_id); - H5Fclose(file_id); -} - - -#ifdef HAVE_MPI - -namespace mpi -{ -/** - * Loads a the hyperslice corresponding to this processor from a hdf5 file. - * @param flann_dataset Dataset where the data is loaded - * @param filename HDF5 file name - * @param name Name of dataset inside file - */ -template -void load_from_file(cvflann::Matrix& dataset, const String& filename, const String& name) -{ - MPI_Comm comm = MPI_COMM_WORLD; - MPI_Info info = MPI_INFO_NULL; - - int mpi_size, mpi_rank; - MPI_Comm_size(comm, &mpi_size); - MPI_Comm_rank(comm, &mpi_rank); - - herr_t status; - - hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); - H5Pset_fapl_mpio(plist_id, comm, info); - hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDWR, plist_id); - CHECK_ERROR(file_id,"Error opening hdf5 file."); - H5Pclose(plist_id); - hid_t dataset_id; -#if H5Dopen_vers == 2 - dataset_id = H5Dopen2(file_id, name.c_str(), H5P_DEFAULT); -#else - dataset_id = H5Dopen(file_id, name.c_str()); -#endif - CHECK_ERROR(dataset_id,"Error opening dataset in file."); - - hid_t space_id = H5Dget_space(dataset_id); - hsize_t dims[2]; - H5Sget_simple_extent_dims(space_id, dims, NULL); - - hsize_t count[2]; - hsize_t offset[2]; - - hsize_t item_cnt = dims[0]/mpi_size+(dims[0]%mpi_size==0 ? 0 : 1); - hsize_t cnt = (mpi_rank(), memspace_id, space_id, plist_id, dataset.data); - CHECK_ERROR(status, "Error reading dataset"); - - H5Pclose(plist_id); - H5Sclose(space_id); - H5Sclose(memspace_id); - H5Dclose(dataset_id); - H5Fclose(file_id); -} -} -#endif // HAVE_MPI -} // namespace cvflann::mpi - -#endif /* OPENCV_FLANN_HDF5_H_ */ diff --git a/3rdparty/libopencv/include/opencv2/flann/heap.h b/3rdparty/libopencv/include/opencv2/flann/heap.h deleted file mode 100644 index 92a6ea6..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/heap.h +++ /dev/null @@ -1,165 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/hierarchical_clustering_index.h b/3rdparty/libopencv/include/opencv2/flann/hierarchical_clustering_index.h deleted file mode 100644 index 9d890d4..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/hierarchical_clustering_index.h +++ /dev/null @@ -1,848 +0,0 @@ -/*********************************************************************** - * 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 - { - return FLANN_INDEX_HIERARCHICAL; - } - - - void saveIndex(FILE* stream) - { - 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) - { - - 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/3rdparty/libopencv/include/opencv2/flann/index_testing.h b/3rdparty/libopencv/include/opencv2/flann/index_testing.h deleted file mode 100644 index d764004..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/index_testing.h +++ /dev/null @@ -1,318 +0,0 @@ -/*********************************************************************** - * 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() - { - /* 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 - { - return FLANN_INDEX_KDTREE; - } - - - void saveIndex(FILE* stream) - { - save_value(stream, trees_); - for (int i=0; i& result, const ElementType* vec, const SearchParams& searchParams) - { - 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 - { - 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/3rdparty/libopencv/include/opencv2/flann/kdtree_single_index.h b/3rdparty/libopencv/include/opencv2/flann/kdtree_single_index.h deleted file mode 100644 index ef15392..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/kdtree_single_index.h +++ /dev/null @@ -1,635 +0,0 @@ -/*********************************************************************** - * 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() - { - 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) - { - 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 - { - 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) - { - 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/3rdparty/libopencv/include/opencv2/flann/kmeans_index.h b/3rdparty/libopencv/include/opencv2/flann/kmeans_index.h deleted file mode 100644 index 7da4e26..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/kmeans_index.h +++ /dev/null @@ -1,1171 +0,0 @@ -/*********************************************************************** - * 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 - { - 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, - int* _count, int* _belongs_to, std::vector& _radiuses, bool& _converged, cv::Mutex& _mtx) - : distance(_distance) - , dataset(_dataset) - , branching(_branching) - , indices(_indices) - , dcenters(_dcenters) - , veclen(_veclen) - , count(_count) - , belongs_to(_belongs_to) - , radiuses(_radiuses) - , converged(_converged) - , mtx(_mtx) - { - } - - void operator()(const cv::Range& range) const - { - 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; - } - } - 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; - mtx.lock(); - converged = false; - mtx.unlock(); - } - } - } - - private: - Distance distance; - const Matrix& dataset; - const int branching; - const int* indices; - const Matrix& dcenters; - const size_t veclen; - int* count; - int* belongs_to; - std::vector& radiuses; - bool& converged; - cv::Mutex& mtx; - 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 - { - return size_; - } - - /** - * Returns the length of an index feature. - */ - size_t veclen() const - { - 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 - { - return pool_.usedMemory+pool_.wastedMemory+memoryCounter_; - } - - /** - * Builds the index - */ - void buildIndex() - { - 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) - { - 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) - { - 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) - { - - 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 = (int*)centers_idx_buf; - 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((double*)dcenters_buf,branching,veclen_); - for (int i=0; i radiuses(branching); - cv::AutoBuffer count_buf(branching); - int* count = (int*)count_buf; - for (int i=0; i belongs_to_buf(indices_length); - int* belongs_to = (int*)belongs_to_buf; - 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 && iterationchilds = 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/3rdparty/libopencv/include/opencv2/flann/linear_index.h b/3rdparty/libopencv/include/opencv2/flann/linear_index.h deleted file mode 100644 index 5aa7a5c..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/linear_index.h +++ /dev/null @@ -1,132 +0,0 @@ -/*********************************************************************** - * 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 - { - return FLANN_INDEX_LINEAR; - } - - - size_t size() const - { - return dataset_.rows; - } - - size_t veclen() const - { - return dataset_.cols; - } - - - int usedMemory() const - { - return 0; - } - - void buildIndex() - { - /* nothing to do here for linear search */ - } - - void saveIndex(FILE*) - { - /* nothing to do here for linear search */ - } - - - void loadIndex(FILE*) - { - /* nothing to do here for linear search */ - - index_params_["algorithm"] = getType(); - } - - void findNeighbors(ResultSet& resultSet, const ElementType* vec, const SearchParams& /*searchParams*/) - { - 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 - { - 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/3rdparty/libopencv/include/opencv2/flann/logger.h b/3rdparty/libopencv/include/opencv2/flann/logger.h deleted file mode 100644 index 32618db..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/logger.h +++ /dev/null @@ -1,135 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/lsh_index.h b/3rdparty/libopencv/include/opencv2/flann/lsh_index.h deleted file mode 100644 index 4d4670e..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/lsh_index.h +++ /dev/null @@ -1,392 +0,0 @@ -/*********************************************************************** - * 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() - { - 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 - { - return FLANN_INDEX_LSH; - } - - - void saveIndex(FILE* stream) - { - save_value(stream,table_number_); - save_value(stream,key_size_); - save_value(stream,multi_probe_level_); - save_value(stream, dataset_); - } - - void loadIndex(FILE* stream) - { - 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 - { - return dataset_.rows; - } - - /** - * Returns the length of an index feature. - */ - size_t veclen() const - { - return feature_size_; - } - - /** - * Computes the index memory usage - * Returns: memory used by the index - */ - int usedMemory() const - { - return (int)(dataset_.rows * sizeof(int)); - } - - - IndexParams getParameters() const - { - 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) - { - 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*/) - { - 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/3rdparty/libopencv/include/opencv2/flann/lsh_table.h b/3rdparty/libopencv/include/opencv2/flann/lsh_table.h deleted file mode 100644 index 1db9960..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/lsh_table.h +++ /dev/null @@ -1,513 +0,0 @@ -/*********************************************************************** - * 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; - (void)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/3rdparty/libopencv/include/opencv2/flann/matrix.h b/3rdparty/libopencv/include/opencv2/flann/matrix.h deleted file mode 100644 index f6092d1..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/matrix.h +++ /dev/null @@ -1,116 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/miniflann.hpp b/3rdparty/libopencv/include/opencv2/flann/miniflann.hpp deleted file mode 100644 index bda2ed4..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/miniflann.hpp +++ /dev/null @@ -1,162 +0,0 @@ -/*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 -{ - -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); - - 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/3rdparty/libopencv/include/opencv2/flann/nn_index.h b/3rdparty/libopencv/include/opencv2/flann/nn_index.h deleted file mode 100644 index 381d4bc..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/nn_index.h +++ /dev/null @@ -1,177 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/object_factory.h b/3rdparty/libopencv/include/opencv2/flann/object_factory.h deleted file mode 100644 index 7f971c5..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/object_factory.h +++ /dev/null @@ -1,91 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/params.h b/3rdparty/libopencv/include/opencv2/flann/params.h deleted file mode 100644 index 95ef4cd..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/params.h +++ /dev/null @@ -1,99 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/random.h b/3rdparty/libopencv/include/opencv2/flann/random.h deleted file mode 100644 index d678474..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/random.h +++ /dev/null @@ -1,155 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/result_set.h b/3rdparty/libopencv/include/opencv2/flann/result_set.h deleted file mode 100644 index 7c09093..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/result_set.h +++ /dev/null @@ -1,543 +0,0 @@ -/*********************************************************************** - * 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 - { - return count == capacity; - } - - - void addPoint(DistanceType dist, int index) - { - 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 - { - return count == capacity; - } - - - void addPoint(DistanceType dist, int index) - { - 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 - { - 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 - { - 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 - { - 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) - { - // 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() - { - 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) - { - if (dist <= radius_) dist_indices_.insert(DistIndex(dist, index)); - } - - /** Remove all elements in the set - */ - inline void clear() - { - dist_indices_.clear(); - } - - - /** Check the status of the set - * @return alwys false - */ - inline bool full() const - { - 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 - { - 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/3rdparty/libopencv/include/opencv2/flann/sampling.h b/3rdparty/libopencv/include/opencv2/flann/sampling.h deleted file mode 100644 index 396f177..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/sampling.h +++ /dev/null @@ -1,81 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/flann/simplex_downhill.h b/3rdparty/libopencv/include/opencv2/flann/simplex_downhill.h deleted file mode 100644 index 145901a..0000000 --- a/3rdparty/libopencv/include/opencv2/flann/simplex_downhill.h +++ /dev/null @@ -1,186 +0,0 @@ -/*********************************************************************** - * 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/3rdparty/libopencv/include/opencv2/highgui.hpp b/3rdparty/libopencv/include/opencv2/highgui.hpp deleted file mode 100644 index 0394c7d..0000000 --- a/3rdparty/libopencv/include/opencv2/highgui.hpp +++ /dev/null @@ -1,844 +0,0 @@ -/*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); - -/** @brief Sets mouse handler for the specified window - -@param winname Name of the window. -@param onMouse Mouse callback. See OpenCV samples, such as -, 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 (or NULL) 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 (or NULL) 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 (or NULL) 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 (or NULL) 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 (or NULL) 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(NULL,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 - -#ifndef DISABLE_OPENCV_24_COMPATIBILITY -#include "opencv2/highgui/highgui_c.h" -#endif - -#endif diff --git a/3rdparty/libopencv/include/opencv2/highgui/highgui.hpp b/3rdparty/libopencv/include/opencv2/highgui/highgui.hpp deleted file mode 100644 index 160c9cf..0000000 --- a/3rdparty/libopencv/include/opencv2/highgui/highgui.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/highgui/highgui_c.h b/3rdparty/libopencv/include/opencv2/highgui/highgui_c.h deleted file mode 100644 index 1eb414a..0000000 --- a/3rdparty/libopencv/include/opencv2/highgui/highgui_c.h +++ /dev/null @@ -1,260 +0,0 @@ -/*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 HAVE_OPENCV_IMGCODECS -#include "opencv2/imgcodecs/imgcodecs_c.h" -#endif -#ifdef HAVE_OPENCV_VIDEOIO -#include "opencv2/videoio/videoio_c.h" -#endif - -#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); - -/* Get window image rectangle coordinates, width and height */ -CVAPI(cv::Rect)cvGetWindowImageRect(const char* name); - -/* 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/3rdparty/libopencv/include/opencv2/imgcodecs.hpp b/3rdparty/libopencv/include/opencv2/imgcodecs.hpp deleted file mode 100644 index dcb038a..0000000 --- a/3rdparty/libopencv/include/opencv2/imgcodecs.hpp +++ /dev/null @@ -1,247 +0,0 @@ -/*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. - 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 - }; - -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 *Notes* section) -- JPEG 2000 files - \*.jp2 (see the *Notes* section) -- Portable Network Graphics - \*.png (see the *Notes* section) -- WebP - \*.webp (see the *Notes* section) -- Portable image format - \*.pbm, \*.pgm, \*.ppm \*.pxm, \*.pnm (always supported) -- Sun rasters - \*.sr, \*.ras (always supported) -- TIFF files - \*.tiff, \*.tif (see the *Notes* section) -- OpenEXR Image files - \*.exr (see the *Notes* section) -- Radiance HDR - \*.hdr, \*.pic (always supported) -- Raster and Vector geospatial data supported by Gdal (see the *Notes* 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. -- 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 [GDAL](http://www.gdal.org) driver will be used in order to decode the image by 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. -@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). Only 8-bit (or 16-bit unsigned (CV_16U) -in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with 'BGR' channel order) images -can be saved using this function. If the format, depth or channel order is different, use -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. - -It is possible to store PNG images with an alpha channel 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. - -The sample below shows how to create such a BGRA image and store to 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()); - -//! @} imgcodecs - -} // cv - -#endif //OPENCV_IMGCODECS_HPP diff --git a/3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs.hpp b/3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs.hpp deleted file mode 100644 index a3cd232..0000000 --- a/3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs_c.h b/3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs_c.h deleted file mode 100644 index c36dac3..0000000 --- a/3rdparty/libopencv/include/opencv2/imgcodecs/imgcodecs_c.h +++ /dev/null @@ -1,149 +0,0 @@ -/*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_IMGCODECS_H -#define OPENCV_IMGCODECS_H - -#include "opencv2/core/core_c.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** @addtogroup imgcodecs_c - @{ - */ - -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 -}; - -/* load image from file - iscolor can be a combination of above flags where CV_LOAD_IMAGE_UNCHANGED - overrides the other flags - using CV_LOAD_IMAGE_ANYCOLOR alone is equivalent to CV_LOAD_IMAGE_UNCHANGED - unless CV_LOAD_IMAGE_ANYDEPTH is specified images are converted to 8bit -*/ -CVAPI(IplImage*) cvLoadImage( const char* filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); -CVAPI(CvMat*) cvLoadImageM( const char* filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); - -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, -}; - - - -/* save image to file */ -CVAPI(int) cvSaveImage( const char* filename, const CvArr* image, - const int* params CV_DEFAULT(0) ); - -/* decode image stored in the buffer */ -CVAPI(IplImage*) cvDecodeImage( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); -CVAPI(CvMat*) cvDecodeImageM( const CvMat* buf, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); - -/* encode image and store the result as a byte vector (single-row 8uC1 matrix) */ -CVAPI(CvMat*) cvEncodeImage( const char* ext, const CvArr* image, - const int* params CV_DEFAULT(0) ); - -enum -{ - CV_CVTIMG_FLIP =1, - CV_CVTIMG_SWAP_RB =2 -}; - -/* utility function: convert one image to another with optional vertical flip */ -CVAPI(void) cvConvertImage( const CvArr* src, CvArr* dst, int flags CV_DEFAULT(0)); - -CVAPI(int) cvHaveImageReader(const char* filename); -CVAPI(int) cvHaveImageWriter(const char* filename); - - -/****************************************************************************************\ -* Obsolete functions/synonyms * -\****************************************************************************************/ - -#define cvvLoadImage(name) cvLoadImage((name),1) -#define cvvSaveImage cvSaveImage -#define cvvConvertImage cvConvertImage - -/** @} imgcodecs_c */ - -#ifdef __cplusplus -} -#endif - -#endif // OPENCV_IMGCODECS_H diff --git a/3rdparty/libopencv/include/opencv2/imgcodecs/ios.h b/3rdparty/libopencv/include/opencv2/imgcodecs/ios.h deleted file mode 100644 index fbd6371..0000000 --- a/3rdparty/libopencv/include/opencv2/imgcodecs/ios.h +++ /dev/null @@ -1,57 +0,0 @@ - -/*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 -//! @{ - -UIImage* MatToUIImage(const cv::Mat& image); -void UIImageToMat(const UIImage* image, - cv::Mat& m, bool alphaExist = false); - -//! @} diff --git a/3rdparty/libopencv/include/opencv2/imgproc.hpp b/3rdparty/libopencv/include/opencv2/imgproc.hpp deleted file mode 100644 index 1f2fc96..0000000 --- a/3rdparty/libopencv/include/opencv2/imgproc.hpp +++ /dev/null @@ -1,4910 +0,0 @@ -/*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 - @{ - @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_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: - -@code -#include -#include -#include -#include -using namespace cv; - -#include -using namespace std; - -int main(int argc, const char *argv[]) -{ - // We need an input image. (can be grayscale or color) - if (argc < 2) - { - cerr << "We need an image to process here. Please run: colorMap [path_to_image]" << endl; - return -1; - } - Mat img_in = imread(argv[1]); - if(img_in.empty()) - { - cerr << "Sample image (" << argv[1] << ") is empty. Please adjust your path, so it points to a valid input image!" << endl; - return -1; - } - // Holds the colormap version of the image: - Mat img_color; - // Apply the colormap: - applyColorMap(img_in, img_color, COLORMAP_JET); - // Show the result: - imshow("colorMap", img_color); - waitKey(0); - return 0; -} -@endcode - -@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 -//! @{ - -//! 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 -}; - -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 -}; - -//! cv::undistort mode -enum UndistortTypes { - PROJ_SPHERICAL_ORTHO = 0, - PROJ_SPHERICAL_EQRECT = 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 -}; - -//! 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 - -//! 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 -//! @ingroup imgproc_feature -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. -}; - -/** 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 code -@see @ref imgproc_color_conversions -@ingroup imgproc_misc - */ -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 -}; - -/** types of intersection between rectangles -@ingroup imgproc_shape -*/ -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 -}; - -//! finds arbitrary template in the grayscale image using Generalized Hough Transform -class CV_EXPORTS GeneralizedHough : public Algorithm -{ -public: - //! set template to search - virtual void setTemplate(InputArray templ, Point templCenter = Point(-1, -1)) = 0; - virtual void setTemplate(InputArray edges, InputArray dx, InputArray dy, Point templCenter = Point(-1, -1)) = 0; - - //! find template on image - virtual void detect(InputArray image, OutputArray positions, OutputArray votes = noArray()) = 0; - virtual void detect(InputArray edges, InputArray dx, InputArray dy, OutputArray positions, OutputArray votes = noArray()) = 0; - - //! Canny low threshold. - virtual void setCannyLowThresh(int cannyLowThresh) = 0; - virtual int getCannyLowThresh() const = 0; - - //! Canny high threshold. - virtual void setCannyHighThresh(int cannyHighThresh) = 0; - virtual int getCannyHighThresh() const = 0; - - //! Minimum distance between the centers of the detected objects. - virtual void setMinDist(double minDist) = 0; - virtual double getMinDist() const = 0; - - //! Inverse ratio of the accumulator resolution to the image resolution. - virtual void setDp(double dp) = 0; - virtual double getDp() const = 0; - - //! Maximal size of inner buffers. - virtual void setMaxBufferSize(int maxBufferSize) = 0; - virtual int getMaxBufferSize() const = 0; -}; - -//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122. -//! Detects position only without translation and rotation -class CV_EXPORTS GeneralizedHoughBallard : public GeneralizedHough -{ -public: - //! R-Table levels. - virtual void setLevels(int levels) = 0; - 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. - virtual void setVotesThreshold(int votesThreshold) = 0; - virtual int getVotesThreshold() const = 0; -}; - -//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038. -//! Detects position, translation and rotation -class CV_EXPORTS GeneralizedHoughGuil : public GeneralizedHough -{ -public: - //! Angle difference in degrees between two points in feature. - virtual void setXi(double xi) = 0; - virtual double getXi() const = 0; - - //! Feature table levels. - virtual void setLevels(int levels) = 0; - virtual int getLevels() const = 0; - - //! Maximal difference between angles that treated as equal. - virtual void setAngleEpsilon(double angleEpsilon) = 0; - virtual double getAngleEpsilon() const = 0; - - //! Minimal rotation angle to detect in degrees. - virtual void setMinAngle(double minAngle) = 0; - virtual double getMinAngle() const = 0; - - //! Maximal rotation angle to detect in degrees. - virtual void setMaxAngle(double maxAngle) = 0; - virtual double getMaxAngle() const = 0; - - //! Angle step in degrees. - virtual void setAngleStep(double angleStep) = 0; - virtual double getAngleStep() const = 0; - - //! Angle votes threshold. - virtual void setAngleThresh(int angleThresh) = 0; - virtual int getAngleThresh() const = 0; - - //! Minimal scale to detect. - virtual void setMinScale(double minScale) = 0; - virtual double getMinScale() const = 0; - - //! Maximal scale to detect. - virtual void setMaxScale(double maxScale) = 0; - virtual double getMaxScale() const = 0; - - //! Scale step. - virtual void setScaleStep(double scaleStep) = 0; - virtual double getScaleStep() const = 0; - - //! Scale votes threshold. - virtual void setScaleThresh(int scaleThresh) = 0; - virtual int getScaleThresh() const = 0; - - //! Position votes threshold. - virtual void setPosThresh(int posThresh) = 0; - virtual int getPosThresh() const = 0; -}; - -/** @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 with CV_8UC1 type. - @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; -}; - - -//! @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 -//! @{ - -/** @example lsd_lines.cpp -An example using the LineSegmentDetector -\image html building_lsd.png "Sample output image" width=434 height=300 -*/ - -/** @brief Line segment detector class - -following the algorithm described at @cite Rafael12 . -*/ -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. - */ -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=CV_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 CV_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 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 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 = #CV_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, CV_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 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 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 below. -@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) - \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 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 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 two-element vector -\f$(\rho, \theta)\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$ ). -@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: - -@code - #include - #include - - using namespace cv; - using namespace std; - - int main(int argc, char** argv) - { - Mat src, dst, color_dst; - if( argc != 2 || !(src=imread(argv[1], 0)).data) - return -1; - - Canny( src, dst, 50, 200, 3 ); - cvtColor( dst, color_dst, COLOR_GRAY2BGR ); - - #if 0 - vector lines; - HoughLines( dst, lines, 1, CV_PI/180, 100 ); - - for( size_t i = 0; i < lines.size(); i++ ) - { - float rho = lines[i][0]; - float theta = lines[i][1]; - double a = cos(theta), b = sin(theta); - double x0 = a*rho, y0 = b*rho; - Point pt1(cvRound(x0 + 1000*(-b)), - cvRound(y0 + 1000*(a))); - Point pt2(cvRound(x0 - 1000*(-b)), - cvRound(y0 - 1000*(a))); - line( color_dst, pt1, pt2, Scalar(0,0,255), 3, 8 ); - } - #else - vector lines; - HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 ); - for( size_t i = 0; i < lines.size(); i++ ) - { - line( color_dst, Point(lines[i][0], lines[i][1]), - Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 ); - } - #endif - namedWindow( "Source", 1 ); - imshow( "Source", src ); - - namedWindow( "Detected Lines", 1 ); - imshow( "Detected Lines", color_dst ); - - waitKey(0); - return 0; - } -@endcode -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 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: : -@code - #include - #include - #include - - using namespace cv; - using namespace std; - - int main(int argc, char** argv) - { - Mat img, gray; - if( argc != 2 || !(img=imread(argv[1], 1)).data) - return -1; - cvtColor(img, gray, COLOR_BGR2GRAY); - // smooth it, otherwise a lot of false circles may be detected - GaussianBlur( gray, gray, Size(9, 9), 2, 2 ); - vector circles; - HoughCircles(gray, circles, HOUGH_GRADIENT, - 2, gray.rows/4, 200, 100 ); - for( size_t i = 0; i < circles.size(); i++ ) - { - Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); - int radius = cvRound(circles[i][2]); - // draw the circle center - circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 ); - // draw the circle outline - circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 ); - } - namedWindow( "circles", 1 ); - imshow( "circles", img ); - - waitKey(0); - return 0; - } -@endcode - -@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 a 3-element -floating-point vector \f$(x, y, radius)\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 morphology2.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 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 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 ); - -//! returns 3x3 perspective transformation for the corresponding 4 point pairs. -CV_EXPORTS Mat getPerspectiveTransform( const Point2f src[], const Point2f dst[] ); - -/** @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. - -@sa findHomography, warpPerspective, perspectiveTransform - */ -CV_EXPORTS_W Mat getPerspectiveTransform( InputArray src, InputArray dst ); - -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 polar_transforms.cpp -An example using the cv::linearPolar and cv::logPolar operations -*/ - -/** @brief Remaps an image to semilog-polar coordinates space. - -Transform the source image using the following transformation (See @ref polar_remaps_reference_image "Polar remaps reference image"): -\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 = Ky \cdot \texttt{angle} (I)_{0..360 deg} \\ -\end{array}\f] - -and -\f[\begin{array}{l} - M = src.cols / log_e(maxRadius) \\ - Ky = src.rows / 360 \\ -\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. -*/ -CV_EXPORTS_W void logPolar( InputArray src, OutputArray dst, - Point2f center, double M, int flags ); - -/** @brief Remaps an image to 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[\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 = Kx \cdot \texttt{magnitude} (I) ,\\ - \phi = Ky \cdot \texttt{angle} (I)_{0..360 deg} -\end{array}\f] - -and -\f[\begin{array}{l} - Kx = src.cols / maxRadius \\ - Ky = src.rows / 360 -\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. - -*/ -CV_EXPORTS_W void linearPolar( InputArray src, OutputArray dst, - 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 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_transform -//! @{ - -/** @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_W float initWideAngleProjMap( InputArray cameraMatrix, InputArray distCoeffs, - Size imageSize, int destImageWidth, - int m1type, OutputArray map1, OutputArray map2, - int projType = PROJ_SPHERICAL_EQRECT, double alpha = 0); - -/** @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, 1xN or Nx1 2-channel (CV_32FC2 or CV_64FC2). -@param dst Output ideal point coordinates 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); - -//! @} imgproc_transform - -//! @addtogroup imgproc_hist -//! @{ - -/** @example 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. : -@code - #include - #include - - using namespace cv; - - int main( int argc, char** argv ) - { - Mat src, hsv; - if( argc != 2 || !(src=imread(argv[1], 1)).data ) - return -1; - - cvtColor(src, hsv, COLOR_BGR2HSV); - - // Quantize the hue to 30 levels - // and the saturation to 32 levels - int hbins = 30, sbins = 32; - int histSize[] = {hbins, sbins}; - // hue varies from 0 to 179, see cvtColor - float hranges[] = { 0, 180 }; - // saturation varies from 0 (black-gray-white) to - // 255 (pure spectrum color) - float sranges[] = { 0, 256 }; - const float* ranges[] = { hranges, sranges }; - MatND hist; - // we compute the histogram from the 0-th and 1-st channels - int channels[] = {0, 1}; - - calcHist( &hsv, 1, channels, Mat(), // do not use mask - hist, 2, histSize, ranges, - true, // the histogram is uniform - false ); - double maxVal=0; - minMaxLoc(hist, 0, &maxVal, 0, 0); - - int scale = 10; - Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3); - - for( int h = 0; h < hbins; h++ ) - for( int s = 0; s < sbins; s++ ) - { - float binVal = hist.at(h, s); - int intensity = cvRound(binVal*255/maxVal); - rectangle( histImg, Point(h*scale, s*scale), - Point( (h+1)*scale - 1, (s+1)*scale - 1), - Scalar::all(intensity), - CV_FILLED ); - } - - namedWindow( "Source", 1 ); - imshow( "Source", src ); - - namedWindow( "H-S Histogram", 1 ); - imshow( "H-S Histogram", histImg ); - waitKey(); - } -@endcode - -@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 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 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 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 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 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 ); - -/** @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 ); - -CV_EXPORTS_W void cvtColorTwoPlane( InputArray src1, InputArray src2, OutputArray dst, int code ); - -//! @} imgproc_misc - -// main function for all demosaicing processes -CV_EXPORTS_W void demosaicing(InputArray _src, OutputArray _dst, int code, int dcn = 0); - -//! @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 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 -//! @{ - -/** @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( InputOutputArray image, OutputArrayOfArrays contours, - OutputArray hierarchy, int mode, - int method, Point offset = Point()); - -/** @overload */ -CV_EXPORTS void findContours( InputOutputArray image, OutputArrayOfArrays contours, - int mode, int method, Point offset = Point()); - -/** @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. - -The function calculates and returns the minimal up-right bounding rectangle for the specified point set. - -@param points Input 2D point set, stored in std::vector or Mat. - */ -CV_EXPORTS_W Rect boundingRect( InputArray points ); - -/** @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 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 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. - */ -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 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 ); - -//! @} imgproc_shape -/** @brief Creates implementation for cv::CLAHE . - -@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)); - -//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122. -//! Detects position only without translation and rotation -CV_EXPORTS Ptr createGeneralizedHoughBallard(); - -//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038. -//! Detects position, translation and rotation -CV_EXPORTS Ptr createGeneralizedHoughGuil(); - -//! 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); - -//! @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) -}; - -/** @example 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 -//! @{ - -/** @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 void rectangle(CV_IN_OUT Mat& img, Rect rec, - const Scalar& color, int thickness = 1, - int lineType = LINE_8, int shift = 0); - -/** @example 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 */ -/* ----------------------------------------------------------------------------------------- */ - -//! Possible set of marker types used for the cv::drawMarker function -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 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(CV_IN_OUT Mat& 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(Mat& 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(Mat& img, const Point** pts, - const int* npts, int ncontours, - const Scalar& color, int lineType = LINE_8, int shift = 0, - Point offset = Point() ); - -/** @example Drawing_1.cpp -An example using drawing functions - */ -/** @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(Mat& 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 contours2.cpp - An example program illustrates the use of cv::findContours and cv::drawContours - \image html WindowsQtContoursOutput.png "Screenshot of the program" -*/ - -/** @example 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: : -@code - #include "opencv2/imgproc.hpp" - #include "opencv2/highgui.hpp" - - using namespace cv; - using namespace std; - - int main( int argc, char** argv ) - { - Mat src; - // the first command-line parameter must be a filename of the binary - // (black-n-white) image - if( argc != 2 || !(src=imread(argv[1], 0)).data) - return -1; - - Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3); - - src = src > 1; - namedWindow( "Source", 1 ); - imshow( "Source", src ); - - vector > contours; - vector hierarchy; - - findContours( src, contours, hierarchy, - RETR_CCOMP, CHAIN_APPROX_SIMPLE ); - - // iterate through all the top-level contours, - // draw each connected component with its own random color - int idx = 0; - for( ; idx >= 0; idx = hierarchy[idx][0] ) - { - Scalar color( rand()&255, rand()&255, rand()&255 ); - drawContours( dst, contours, idx, color, FILLED, 8, hierarchy ); - } - - namedWindow( "Components", 1 ); - imshow( "Components", dst ); - waitKey(0); - } -@endcode - -@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 - -#ifndef DISABLE_OPENCV_24_COMPATIBILITY -#include "opencv2/imgproc/imgproc_c.h" -#endif - -#endif diff --git a/3rdparty/libopencv/include/opencv2/imgproc/detail/distortion_model.hpp b/3rdparty/libopencv/include/opencv2/imgproc/detail/distortion_model.hpp deleted file mode 100644 index a9c3dde..0000000 --- a/3rdparty/libopencv/include/opencv2/imgproc/detail/distortion_model.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/*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_DETAIL_DISTORTION_MODEL_HPP -#define OPENCV_IMGPROC_DETAIL_DISTORTION_MODEL_HPP - -//! @cond IGNORED - -namespace cv { namespace detail { -/** -Computes the matrix for the projection onto a tilted image sensor -\param tauX angular parameter rotation around x-axis -\param tauY angular parameter rotation around y-axis -\param matTilt if not NULL returns the matrix -\f[ -\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) -\f] -where -\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] -\param dMatTiltdTauX if not NULL it returns the derivative of matTilt with -respect to \f$\tau_x\f$. -\param dMatTiltdTauY if not NULL it returns the derivative of matTilt with -respect to \f$\tau_y\f$. -\param invMatTilt if not NULL it returns the inverse of matTilt -**/ -template -void computeTiltProjectionMatrix(FLOAT tauX, - FLOAT tauY, - Matx* matTilt = 0, - Matx* dMatTiltdTauX = 0, - Matx* dMatTiltdTauY = 0, - Matx* invMatTilt = 0) -{ - FLOAT cTauX = cos(tauX); - FLOAT sTauX = sin(tauX); - FLOAT cTauY = cos(tauY); - FLOAT sTauY = sin(tauY); - Matx matRotX = Matx(1,0,0,0,cTauX,sTauX,0,-sTauX,cTauX); - Matx matRotY = Matx(cTauY,0,-sTauY,0,1,0,sTauY,0,cTauY); - Matx matRotXY = matRotY * matRotX; - Matx matProjZ = Matx(matRotXY(2,2),0,-matRotXY(0,2),0,matRotXY(2,2),-matRotXY(1,2),0,0,1); - if (matTilt) - { - // Matrix for trapezoidal distortion of tilted image sensor - *matTilt = matProjZ * matRotXY; - } - if (dMatTiltdTauX) - { - // Derivative with respect to tauX - Matx dMatRotXYdTauX = matRotY * Matx(0,0,0,0,-sTauX,cTauX,0,-cTauX,-sTauX); - Matx dMatProjZdTauX = Matx(dMatRotXYdTauX(2,2),0,-dMatRotXYdTauX(0,2), - 0,dMatRotXYdTauX(2,2),-dMatRotXYdTauX(1,2),0,0,0); - *dMatTiltdTauX = (matProjZ * dMatRotXYdTauX) + (dMatProjZdTauX * matRotXY); - } - if (dMatTiltdTauY) - { - // Derivative with respect to tauY - Matx dMatRotXYdTauY = Matx(-sTauY,0,-cTauY,0,0,0,cTauY,0,-sTauY) * matRotX; - Matx dMatProjZdTauY = Matx(dMatRotXYdTauY(2,2),0,-dMatRotXYdTauY(0,2), - 0,dMatRotXYdTauY(2,2),-dMatRotXYdTauY(1,2),0,0,0); - *dMatTiltdTauY = (matProjZ * dMatRotXYdTauY) + (dMatProjZdTauY * matRotXY); - } - if (invMatTilt) - { - FLOAT inv = 1./matRotXY(2,2); - Matx invMatProjZ = Matx(inv,0,inv*matRotXY(0,2),0,inv,inv*matRotXY(1,2),0,0,1); - *invMatTilt = matRotXY.t()*invMatProjZ; - } -} -}} // namespace detail, cv - - -//! @endcond - -#endif // OPENCV_IMGPROC_DETAIL_DISTORTION_MODEL_HPP diff --git a/3rdparty/libopencv/include/opencv2/imgproc/hal/hal.hpp b/3rdparty/libopencv/include/opencv2/imgproc/hal/hal.hpp deleted file mode 100644 index a435fd6..0000000 --- a/3rdparty/libopencv/include/opencv2/imgproc/hal/hal.hpp +++ /dev/null @@ -1,241 +0,0 @@ -#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 warpPerspectve(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/3rdparty/libopencv/include/opencv2/imgproc/hal/interface.h b/3rdparty/libopencv/include/opencv2/imgproc/hal/interface.h deleted file mode 100644 index f8dbcfe..0000000 --- a/3rdparty/libopencv/include/opencv2/imgproc/hal/interface.h +++ /dev/null @@ -1,46 +0,0 @@ -#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/3rdparty/libopencv/include/opencv2/imgproc/imgproc.hpp b/3rdparty/libopencv/include/opencv2/imgproc/imgproc.hpp deleted file mode 100644 index 4175bd0..0000000 --- a/3rdparty/libopencv/include/opencv2/imgproc/imgproc.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/imgproc/imgproc_c.h b/3rdparty/libopencv/include/opencv2/imgproc/imgproc_c.h deleted file mode 100644 index d11db4b..0000000 --- a/3rdparty/libopencv/include/opencv2/imgproc/imgproc_c.h +++ /dev/null @@ -1,1210 +0,0 @@ -/*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_RGB( r, g, b ) cvScalar( (b), (g), (r), 0 ) -#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; - axes.width = cvRound(box.size.width*0.5); - axes.height = 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/3rdparty/libopencv/include/opencv2/imgproc/types_c.h b/3rdparty/libopencv/include/opencv2/imgproc/types_c.h deleted file mode 100644 index 13ffe1b..0000000 --- a/3rdparty/libopencv/include/opencv2/imgproc/types_c.h +++ /dev/null @@ -1,629 +0,0 @@ -/*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; - -/** 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/3rdparty/libopencv/include/opencv2/ml.hpp b/3rdparty/libopencv/include/opencv2/ml.hpp deleted file mode 100644 index aa25db9..0000000 --- a/3rdparty/libopencv/include/opencv2/ml.hpp +++ /dev/null @@ -1,1961 +0,0 @@ -/*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 then 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 Mat getVarSymbolFlags() const; - 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 Mat getTestSamples() const; - - /** @brief Returns vector of symbolic names captured in loadFromCSV() */ - CV_WRAP void getNames(std::vector& names) const; - - CV_WRAP static Mat getSubVector(const Mat& vec, const Mat& idx); - - /** @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; - - /** @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(); -}; - -/****************************************************************************************\ -* 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 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); - - /** @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 Mat getUncompressedSupportVectors() const; - - /** @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 = 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 - @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 void getVotes(InputArray samples, OutputArray results, int flags) const; - - /** 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 double getAnnealInitialT() const; - /** @copybrief getAnnealInitialT @see getAnnealInitialT */ - CV_WRAP void setAnnealInitialT(double val); - - /** ANNEAL: Update final temperature. - It must be \>=0 and less than initialT. Default value is 0.1.*/ - /** @see setAnnealFinalT */ - CV_WRAP double getAnnealFinalT() const; - /** @copybrief getAnnealFinalT @see getAnnealFinalT */ - CV_WRAP void setAnnealFinalT(double val); - - /** ANNEAL: Update cooling ratio. - It must be \>0 and less than 1. Default value is 0.95.*/ - /** @see setAnnealCoolingRatio */ - CV_WRAP double getAnnealCoolingRatio() const; - /** @copybrief getAnnealCoolingRatio @see getAnnealCoolingRatio */ - CV_WRAP void setAnnealCoolingRatio(double val); - - /** ANNEAL: Update iteration per step. - It must be \>0 . Default value is 10.*/ - /** @see setAnnealItePerStep */ - CV_WRAP int getAnnealItePerStep() const; - /** @copybrief getAnnealItePerStep @see getAnnealItePerStep */ - CV_WRAP void setAnnealItePerStep(int val); - - /** @brief Set/initialize anneal RNG */ - void setAnnealEnergyRNG(const RNG& rng); - - /** 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); - -}; - -/****************************************************************************************\ -* 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 = 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); - -/** @brief Artificial Neural Networks - Multi-Layer Perceptrons. - -@sa @ref ml_intro_ann -*/ -class CV_EXPORTS_W ANN_MLP_ANNEAL : public ANN_MLP -{ -public: - /** @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; -}; - - -/****************************************************************************************\ -* 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/3rdparty/libopencv/include/opencv2/ml/ml.hpp b/3rdparty/libopencv/include/opencv2/ml/ml.hpp deleted file mode 100644 index f6f9cd8..0000000 --- a/3rdparty/libopencv/include/opencv2/ml/ml.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/ml/ml.inl.hpp b/3rdparty/libopencv/include/opencv2/ml/ml.inl.hpp deleted file mode 100644 index dc9c783..0000000 --- a/3rdparty/libopencv/include/opencv2/ml/ml.inl.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// 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/3rdparty/libopencv/include/opencv2/objdetect.hpp b/3rdparty/libopencv/include/opencv2/objdetect.hpp deleted file mode 100644 index 5c6c221..0000000 --- a/3rdparty/libopencv/include/opencv2/objdetect.hpp +++ /dev/null @@ -1,683 +0,0 @@ -/*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<> CV_EXPORTS void DefaultDeleter::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 = 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 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 { L2Hys = 0 //!< Default histogramNormType - }; - enum { DEFAULT_NLEVELS = 64 //!< Default nlevels value. - }; - /**@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, 1 ) - */ - 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, - int _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 of the trained 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 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 file node. - @param fn File node - */ - virtual bool read(FileNode& fn); - - /** @brief Stores HOGDescriptor parameters in a file storage. - @param fs File storage - @param objname Object name - */ - virtual void write(FileStorage& fs, const String& objname) const; - - /** @brief loads coefficients for the linear SVM classifier from a 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). - */ - CV_WRAP virtual bool load(const String& filename, const String& objname = String()); - - /** @brief saves 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 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(const Mat& 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(const Mat& 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(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& 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 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 int 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(const cv::Mat& 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(const cv::Mat& img, - CV_OUT std::vector& foundLocations, - std::vector& locations, - double hitThreshold = 0, - int groupThreshold = 0) const; - - /** @brief read/parse Dalal's alt model file - @param modelfile Path of Dalal's alt model file. - */ - void readALTModel(String modelfile); - - /** @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; -}; - -//! @} objdetect - -} - -#include "opencv2/objdetect/detection_based_tracker.hpp" - -#ifndef DISABLE_OPENCV_24_COMPATIBILITY -#include "opencv2/objdetect/objdetect_c.h" -#endif - -#endif diff --git a/3rdparty/libopencv/include/opencv2/objdetect/detection_based_tracker.hpp b/3rdparty/libopencv/include/opencv2/objdetect/detection_based_tracker.hpp deleted file mode 100644 index 07dd587..0000000 --- a/3rdparty/libopencv/include/opencv2/objdetect/detection_based_tracker.hpp +++ /dev/null @@ -1,227 +0,0 @@ -/*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 - -// After this condition removal update blacklist for bindings: modules/python/common.cmake -#if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(__ANDROID__) || \ - defined(CV_CXX11) - -#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 - -#endif diff --git a/3rdparty/libopencv/include/opencv2/objdetect/objdetect.hpp b/3rdparty/libopencv/include/opencv2/objdetect/objdetect.hpp deleted file mode 100644 index 3ee284f..0000000 --- a/3rdparty/libopencv/include/opencv2/objdetect/objdetect.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/objdetect/objdetect_c.h b/3rdparty/libopencv/include/opencv2/objdetect/objdetect_c.h deleted file mode 100644 index 67dc2f4..0000000 --- a/3rdparty/libopencv/include/opencv2/objdetect/objdetect_c.h +++ /dev/null @@ -1,166 +0,0 @@ -/*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_C_H -#define OPENCV_OBJDETECT_C_H - -#include "opencv2/core/core_c.h" - -#ifdef __cplusplus -#include -#include - -extern "C" { -#endif - -/** @addtogroup objdetect_c - @{ - */ - -/****************************************************************************************\ -* Haar-like Object Detection functions * -\****************************************************************************************/ - -#define CV_HAAR_MAGIC_VAL 0x42500000 -#define CV_TYPE_NAME_HAAR "opencv-haar-classifier" - -#define CV_IS_HAAR_CLASSIFIER( haar ) \ - ((haar) != NULL && \ - (((const CvHaarClassifierCascade*)(haar))->flags & CV_MAGIC_MASK)==CV_HAAR_MAGIC_VAL) - -#define CV_HAAR_FEATURE_MAX 3 -#define CV_HAAR_STAGE_MAX 1000 - -typedef struct CvHaarFeature -{ - int tilted; - struct - { - CvRect r; - float weight; - } rect[CV_HAAR_FEATURE_MAX]; -} CvHaarFeature; - -typedef struct CvHaarClassifier -{ - int count; - CvHaarFeature* haar_feature; - float* threshold; - int* left; - int* right; - float* alpha; -} CvHaarClassifier; - -typedef struct CvHaarStageClassifier -{ - int count; - float threshold; - CvHaarClassifier* classifier; - - int next; - int child; - int parent; -} CvHaarStageClassifier; - -typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade; - -typedef struct CvHaarClassifierCascade -{ - int flags; - int count; - CvSize orig_window_size; - CvSize real_window_size; - double scale; - CvHaarStageClassifier* stage_classifier; - CvHidHaarClassifierCascade* hid_cascade; -} CvHaarClassifierCascade; - -typedef struct CvAvgComp -{ - CvRect rect; - int neighbors; -} CvAvgComp; - -/* Loads haar classifier cascade from a directory. - It is obsolete: convert your cascade to xml and use cvLoad instead */ -CVAPI(CvHaarClassifierCascade*) cvLoadHaarClassifierCascade( - const char* directory, CvSize orig_window_size); - -CVAPI(void) cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** cascade ); - -#define CV_HAAR_DO_CANNY_PRUNING 1 -#define CV_HAAR_SCALE_IMAGE 2 -#define CV_HAAR_FIND_BIGGEST_OBJECT 4 -#define CV_HAAR_DO_ROUGH_SEARCH 8 - -CVAPI(CvSeq*) cvHaarDetectObjects( const CvArr* image, - CvHaarClassifierCascade* cascade, CvMemStorage* storage, - double scale_factor CV_DEFAULT(1.1), - int min_neighbors CV_DEFAULT(3), int flags CV_DEFAULT(0), - CvSize min_size CV_DEFAULT(cvSize(0,0)), CvSize max_size CV_DEFAULT(cvSize(0,0))); - -/* sets images for haar classifier cascade */ -CVAPI(void) cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade, - const CvArr* sum, const CvArr* sqsum, - const CvArr* tilted_sum, double scale ); - -/* runs the cascade on the specified window */ -CVAPI(int) cvRunHaarClassifierCascade( const CvHaarClassifierCascade* cascade, - CvPoint pt, int start_stage CV_DEFAULT(0)); - -/** @} objdetect_c */ - -#ifdef __cplusplus -} - -CV_EXPORTS CvSeq* cvHaarDetectObjectsForROC( const CvArr* image, - CvHaarClassifierCascade* cascade, CvMemStorage* storage, - std::vector& rejectLevels, std::vector& levelWeightds, - double scale_factor = 1.1, - int min_neighbors = 3, int flags = 0, - CvSize min_size = cvSize(0, 0), CvSize max_size = cvSize(0, 0), - bool outputRejectLevels = false ); - -#endif - -#endif /* OPENCV_OBJDETECT_C_H */ diff --git a/3rdparty/libopencv/include/opencv2/opencv.hpp b/3rdparty/libopencv/include/opencv2/opencv.hpp deleted file mode 100644 index 4048158..0000000 --- a/3rdparty/libopencv/include/opencv2/opencv.hpp +++ /dev/null @@ -1,139 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/opencv_modules.hpp b/3rdparty/libopencv/include/opencv2/opencv_modules.hpp deleted file mode 100644 index e14f3ec..0000000 --- a/3rdparty/libopencv/include/opencv2/opencv_modules.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * ** 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_HIGHGUI -#define HAVE_OPENCV_IMGCODECS -#define HAVE_OPENCV_IMGPROC -#define HAVE_OPENCV_ML -#define HAVE_OPENCV_OBJDETECT -#define HAVE_OPENCV_PHOTO -#define HAVE_OPENCV_SHAPE -#define HAVE_OPENCV_STITCHING -#define HAVE_OPENCV_SUPERRES -#define HAVE_OPENCV_VIDEO -#define HAVE_OPENCV_VIDEOIO -#define HAVE_OPENCV_VIDEOSTAB - - diff --git a/3rdparty/libopencv/include/opencv2/photo.hpp b/3rdparty/libopencv/include/opencv2/photo.hpp deleted file mode 100644 index 487b720..0000000 --- a/3rdparty/libopencv/include/opencv2/photo.hpp +++ /dev/null @@ -1,876 +0,0 @@ -/*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 -@{ - @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_clone Seamless Cloning - @defgroup photo_render Non-Photorealistic Rendering - @defgroup photo_c C API -@} - */ - -namespace cv -{ - -//! @addtogroup photo -//! @{ - -//! the inpainting algorithm -enum -{ - INPAINT_NS = 0, // Navier-Stokes algorithm - INPAINT_TELEA = 1 // A. Telea algorithm -}; - -enum -{ - NORMAL_CLONE = 1, - MIXED_CLONE = 2, - MONOCHROME_TRANSFER = 3 -}; - -enum -{ - RECURS_FILTER = 1, - NORMCONV_FILTER = 2 -}; - -/** @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 one of the following: -- **INPAINT_NS** Navier-Stokes based method [Navier01] -- **INPAINT_TELEA** Method by Alexandru Telea @cite Telea04 . - -The function reconstructs the selected image area from the pixel near the area boundary. The -function may be used to remove dust and scratches from a scanned photo, or to remove undesirable -objects from still images or video. See 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 ); - -//! @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 - 32-bit 3-channel Mat - @param dst destination image - 32-bit 3-channel 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 algorithm decomposes image into two layers: base layer and detail layer using bilateral filter -and compresses contrast of the base layer thus preserving all the details. - -This implementation uses regular bilateral filter from opencv. - -Saturation enhancement is possible as in ocvTonemapDrago. - -For more information see @cite DD02 . - */ -class CV_EXPORTS_W TonemapDurand : public Tonemap -{ -public: - - CV_WRAP virtual float getSaturation() const = 0; - CV_WRAP virtual void setSaturation(float saturation) = 0; - - CV_WRAP virtual float getContrast() const = 0; - CV_WRAP virtual void setContrast(float contrast) = 0; - - CV_WRAP virtual float getSigmaSpace() const = 0; - CV_WRAP virtual void setSigmaSpace(float sigma_space) = 0; - - CV_WRAP virtual float getSigmaColor() const = 0; - CV_WRAP virtual void setSigmaColor(float sigma_color) = 0; -}; - -/** @brief Creates TonemapDurand object - -@param gamma gamma value for gamma correction. See createTonemap -@param contrast resulting contrast on logarithmic scale, i. e. log(max / min), where max and min -are maximum and minimum luminance values of the resulting image. -@param saturation saturation enhancement value. See createTonemapDrago -@param sigma_space bilateral filter sigma in color space -@param sigma_color bilateral filter sigma in coordinate space - */ -CV_EXPORTS_W Ptr -createTonemapDurand(float gamma = 1.0f, float contrast = 4.0f, float saturation = 1.0f, float sigma_space = 2.0f, float sigma_color = 2.0f); - -/** @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) = 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) = 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) = 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) = 0; - CV_WRAP virtual void process(InputArrayOfArrays src, OutputArray dst, InputArray times) = 0; -}; - -/** @brief Creates MergeRobertson object - */ -CV_EXPORTS_W Ptr createMergeRobertson(); - -//! @} photo_hdr - -/** @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); - -//! @addtogroup photo_clone -//! @{ - -/** @example 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 one of the following: -- **NORMAL_CLONE** The power of the method is fully expressed when inserting objects with -complex outlines into a new background -- **MIXED_CLONE** 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. -- **MONOCHROME_TRANSFER** Monochrome transfer allows the user to easily replace certain features of -one object by alternative features. - */ -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 -//! @{ - -/** @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: -- **RECURS_FILTER** = 1 -- **NORMCONV_FILTER** = 2 -@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 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 - -#ifndef DISABLE_OPENCV_24_COMPATIBILITY -#include "opencv2/photo/photo_c.h" -#endif - -#endif diff --git a/3rdparty/libopencv/include/opencv2/photo/cuda.hpp b/3rdparty/libopencv/include/opencv2/photo/cuda.hpp deleted file mode 100644 index a2f3816..0000000 --- a/3rdparty/libopencv/include/opencv2/photo/cuda.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/photo/photo.hpp b/3rdparty/libopencv/include/opencv2/photo/photo.hpp deleted file mode 100644 index 8af5e9f..0000000 --- a/3rdparty/libopencv/include/opencv2/photo/photo.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/photo/photo_c.h b/3rdparty/libopencv/include/opencv2/photo/photo_c.h deleted file mode 100644 index cd623c1..0000000 --- a/3rdparty/libopencv/include/opencv2/photo/photo_c.h +++ /dev/null @@ -1,74 +0,0 @@ -/*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_C_H -#define OPENCV_PHOTO_C_H - -#include "opencv2/core/core_c.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup photo_c - @{ - */ - -/* Inpainting algorithms */ -enum InpaintingModes -{ - CV_INPAINT_NS =0, - CV_INPAINT_TELEA =1 -}; - - -/* Inpaints the selected region in the image */ -CVAPI(void) cvInpaint( const CvArr* src, const CvArr* inpaint_mask, - CvArr* dst, double inpaintRange, int flags ); - -/** @} */ - -#ifdef __cplusplus -} //extern "C" -#endif - -#endif //OPENCV_PHOTO_C_H diff --git a/3rdparty/libopencv/include/opencv2/shape.hpp b/3rdparty/libopencv/include/opencv2/shape.hpp deleted file mode 100644 index f302b6b..0000000 --- a/3rdparty/libopencv/include/opencv2/shape.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/*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-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_SHAPE_HPP -#define OPENCV_SHAPE_HPP - -#include "opencv2/shape/emdL1.hpp" -#include "opencv2/shape/shape_transformer.hpp" -#include "opencv2/shape/hist_cost.hpp" -#include "opencv2/shape/shape_distance.hpp" - -/** - @defgroup shape Shape Distance and Matching - */ - -#endif - -/* End of file. */ diff --git a/3rdparty/libopencv/include/opencv2/shape/emdL1.hpp b/3rdparty/libopencv/include/opencv2/shape/emdL1.hpp deleted file mode 100644 index a15d68c..0000000 --- a/3rdparty/libopencv/include/opencv2/shape/emdL1.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/*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-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_EMD_L1_HPP -#define OPENCV_EMD_L1_HPP - -#include "opencv2/core.hpp" - -namespace cv -{ -/****************************************************************************************\ -* EMDL1 Function * -\****************************************************************************************/ - -//! @addtogroup shape -//! @{ - -/** @brief Computes the "minimal work" distance between two weighted point configurations base on the papers -"EMD-L1: An efficient and Robust Algorithm for comparing histogram-based descriptors", by Haibin -Ling and Kazunori Okuda; and "The Earth Mover's Distance is the Mallows Distance: Some Insights from -Statistics", by Elizaveta Levina and Peter Bickel. - -@param signature1 First signature, a single column floating-point matrix. Each row is the value of -the histogram in each bin. -@param signature2 Second signature of the same format and size as signature1. - */ -CV_EXPORTS float EMDL1(InputArray signature1, InputArray signature2); - -//! @} - -}//namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/shape/hist_cost.hpp b/3rdparty/libopencv/include/opencv2/shape/hist_cost.hpp deleted file mode 100644 index 21d0d68..0000000 --- a/3rdparty/libopencv/include/opencv2/shape/hist_cost.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/*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_HIST_COST_HPP -#define OPENCV_HIST_COST_HPP - -#include "opencv2/imgproc.hpp" - -namespace cv -{ - -//! @addtogroup shape -//! @{ - -/** @brief Abstract base class for histogram cost algorithms. - */ -class CV_EXPORTS_W HistogramCostExtractor : public Algorithm -{ -public: - CV_WRAP virtual void buildCostMatrix(InputArray descriptors1, InputArray descriptors2, OutputArray costMatrix) = 0; - - CV_WRAP virtual void setNDummies(int nDummies) = 0; - CV_WRAP virtual int getNDummies() const = 0; - - CV_WRAP virtual void setDefaultCost(float defaultCost) = 0; - CV_WRAP virtual float getDefaultCost() const = 0; -}; - -/** @brief A norm based cost extraction. : - */ -class CV_EXPORTS_W NormHistogramCostExtractor : public HistogramCostExtractor -{ -public: - CV_WRAP virtual void setNormFlag(int flag) = 0; - CV_WRAP virtual int getNormFlag() const = 0; -}; - -CV_EXPORTS_W Ptr - createNormHistogramCostExtractor(int flag=DIST_L2, int nDummies=25, float defaultCost=0.2f); - -/** @brief An EMD based cost extraction. : - */ -class CV_EXPORTS_W EMDHistogramCostExtractor : public HistogramCostExtractor -{ -public: - CV_WRAP virtual void setNormFlag(int flag) = 0; - CV_WRAP virtual int getNormFlag() const = 0; -}; - -CV_EXPORTS_W Ptr - createEMDHistogramCostExtractor(int flag=DIST_L2, int nDummies=25, float defaultCost=0.2f); - -/** @brief An Chi based cost extraction. : - */ -class CV_EXPORTS_W ChiHistogramCostExtractor : public HistogramCostExtractor -{}; - -CV_EXPORTS_W Ptr createChiHistogramCostExtractor(int nDummies=25, float defaultCost=0.2f); - -/** @brief An EMD-L1 based cost extraction. : - */ -class CV_EXPORTS_W EMDL1HistogramCostExtractor : public HistogramCostExtractor -{}; - -CV_EXPORTS_W Ptr - createEMDL1HistogramCostExtractor(int nDummies=25, float defaultCost=0.2f); - -//! @} - -} // cv -#endif diff --git a/3rdparty/libopencv/include/opencv2/shape/shape.hpp b/3rdparty/libopencv/include/opencv2/shape/shape.hpp deleted file mode 100644 index 5c4da3c..0000000 --- a/3rdparty/libopencv/include/opencv2/shape/shape.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/shape.hpp" diff --git a/3rdparty/libopencv/include/opencv2/shape/shape_distance.hpp b/3rdparty/libopencv/include/opencv2/shape/shape_distance.hpp deleted file mode 100644 index 3a778f0..0000000 --- a/3rdparty/libopencv/include/opencv2/shape/shape_distance.hpp +++ /dev/null @@ -1,227 +0,0 @@ -/*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_SHAPE_SHAPE_DISTANCE_HPP -#define OPENCV_SHAPE_SHAPE_DISTANCE_HPP -#include "opencv2/core.hpp" -#include "opencv2/shape/hist_cost.hpp" -#include "opencv2/shape/shape_transformer.hpp" - -namespace cv -{ - -//! @addtogroup shape -//! @{ - -/** @example shape_example.cpp -An example using shape distance algorithm -*/ -/** @brief Abstract base class for shape distance algorithms. - */ -class CV_EXPORTS_W ShapeDistanceExtractor : public Algorithm -{ -public: - /** @brief Compute the shape distance between two shapes defined by its contours. - - @param contour1 Contour defining first shape. - @param contour2 Contour defining second shape. - */ - CV_WRAP virtual float computeDistance(InputArray contour1, InputArray contour2) = 0; -}; - -/***********************************************************************************/ -/***********************************************************************************/ -/***********************************************************************************/ -/** @brief Implementation of the Shape Context descriptor and matching algorithm - -proposed by Belongie et al. in "Shape Matching and Object Recognition Using Shape Contexts" (PAMI -2002). This implementation is packaged in a generic scheme, in order to allow you the -implementation of the common variations of the original pipeline. -*/ -class CV_EXPORTS_W ShapeContextDistanceExtractor : public ShapeDistanceExtractor -{ -public: - /** @brief Establish the number of angular bins for the Shape Context Descriptor used in the shape matching - pipeline. - - @param nAngularBins The number of angular bins in the shape context descriptor. - */ - CV_WRAP virtual void setAngularBins(int nAngularBins) = 0; - CV_WRAP virtual int getAngularBins() const = 0; - - /** @brief Establish the number of radial bins for the Shape Context Descriptor used in the shape matching - pipeline. - - @param nRadialBins The number of radial bins in the shape context descriptor. - */ - CV_WRAP virtual void setRadialBins(int nRadialBins) = 0; - CV_WRAP virtual int getRadialBins() const = 0; - - /** @brief Set the inner radius of the shape context descriptor. - - @param innerRadius The value of the inner radius. - */ - CV_WRAP virtual void setInnerRadius(float innerRadius) = 0; - CV_WRAP virtual float getInnerRadius() const = 0; - - /** @brief Set the outer radius of the shape context descriptor. - - @param outerRadius The value of the outer radius. - */ - CV_WRAP virtual void setOuterRadius(float outerRadius) = 0; - CV_WRAP virtual float getOuterRadius() const = 0; - - CV_WRAP virtual void setRotationInvariant(bool rotationInvariant) = 0; - CV_WRAP virtual bool getRotationInvariant() const = 0; - - /** @brief Set the weight of the shape context distance in the final value of the shape distance. The shape - context distance between two shapes is defined as the symmetric sum of shape context matching costs - over best matching points. The final value of the shape distance is a user-defined linear - combination of the shape context distance, an image appearance distance, and a bending energy. - - @param shapeContextWeight The weight of the shape context distance in the final distance value. - */ - CV_WRAP virtual void setShapeContextWeight(float shapeContextWeight) = 0; - CV_WRAP virtual float getShapeContextWeight() const = 0; - - /** @brief Set the weight of the Image Appearance cost in the final value of the shape distance. The image - appearance cost is defined as the sum of squared brightness differences in Gaussian windows around - corresponding image points. The final value of the shape distance is a user-defined linear - combination of the shape context distance, an image appearance distance, and a bending energy. If - this value is set to a number different from 0, is mandatory to set the images that correspond to - each shape. - - @param imageAppearanceWeight The weight of the appearance cost in the final distance value. - */ - CV_WRAP virtual void setImageAppearanceWeight(float imageAppearanceWeight) = 0; - CV_WRAP virtual float getImageAppearanceWeight() const = 0; - - /** @brief Set the weight of the Bending Energy in the final value of the shape distance. The bending energy - definition depends on what transformation is being used to align the shapes. The final value of the - shape distance is a user-defined linear combination of the shape context distance, an image - appearance distance, and a bending energy. - - @param bendingEnergyWeight The weight of the Bending Energy in the final distance value. - */ - CV_WRAP virtual void setBendingEnergyWeight(float bendingEnergyWeight) = 0; - CV_WRAP virtual float getBendingEnergyWeight() const = 0; - - /** @brief Set the images that correspond to each shape. This images are used in the calculation of the Image - Appearance cost. - - @param image1 Image corresponding to the shape defined by contours1. - @param image2 Image corresponding to the shape defined by contours2. - */ - CV_WRAP virtual void setImages(InputArray image1, InputArray image2) = 0; - CV_WRAP virtual void getImages(OutputArray image1, OutputArray image2) const = 0; - - CV_WRAP virtual void setIterations(int iterations) = 0; - CV_WRAP virtual int getIterations() const = 0; - - /** @brief Set the algorithm used for building the shape context descriptor cost matrix. - - @param comparer Smart pointer to a HistogramCostExtractor, an algorithm that defines the cost - matrix between descriptors. - */ - CV_WRAP virtual void setCostExtractor(Ptr comparer) = 0; - CV_WRAP virtual Ptr getCostExtractor() const = 0; - - /** @brief Set the value of the standard deviation for the Gaussian window for the image appearance cost. - - @param sigma Standard Deviation. - */ - CV_WRAP virtual void setStdDev(float sigma) = 0; - CV_WRAP virtual float getStdDev() const = 0; - - /** @brief Set the algorithm used for aligning the shapes. - - @param transformer Smart pointer to a ShapeTransformer, an algorithm that defines the aligning - transformation. - */ - CV_WRAP virtual void setTransformAlgorithm(Ptr transformer) = 0; - CV_WRAP virtual Ptr getTransformAlgorithm() const = 0; -}; - -/* Complete constructor */ -CV_EXPORTS_W Ptr - createShapeContextDistanceExtractor(int nAngularBins=12, int nRadialBins=4, - float innerRadius=0.2f, float outerRadius=2, int iterations=3, - const Ptr &comparer = createChiHistogramCostExtractor(), - const Ptr &transformer = createThinPlateSplineShapeTransformer()); - -/***********************************************************************************/ -/***********************************************************************************/ -/***********************************************************************************/ -/** @brief A simple Hausdorff distance measure between shapes defined by contours - -according to the paper "Comparing Images using the Hausdorff distance." by D.P. Huttenlocher, G.A. -Klanderman, and W.J. Rucklidge. (PAMI 1993). : - */ -class CV_EXPORTS_W HausdorffDistanceExtractor : public ShapeDistanceExtractor -{ -public: - /** @brief Set the norm used to compute the Hausdorff value between two shapes. It can be L1 or L2 norm. - - @param distanceFlag Flag indicating which norm is used to compute the Hausdorff distance - (NORM_L1, NORM_L2). - */ - CV_WRAP virtual void setDistanceFlag(int distanceFlag) = 0; - CV_WRAP virtual int getDistanceFlag() const = 0; - - /** @brief This method sets the rank proportion (or fractional value) that establish the Kth ranked value of - the partial Hausdorff distance. Experimentally had been shown that 0.6 is a good value to compare - shapes. - - @param rankProportion fractional value (between 0 and 1). - */ - CV_WRAP virtual void setRankProportion(float rankProportion) = 0; - CV_WRAP virtual float getRankProportion() const = 0; -}; - -/* Constructor */ -CV_EXPORTS_W Ptr createHausdorffDistanceExtractor(int distanceFlag=cv::NORM_L2, float rankProp=0.6f); - -//! @} - -} // cv -#endif diff --git a/3rdparty/libopencv/include/opencv2/shape/shape_transformer.hpp b/3rdparty/libopencv/include/opencv2/shape/shape_transformer.hpp deleted file mode 100644 index 3c3ce20..0000000 --- a/3rdparty/libopencv/include/opencv2/shape/shape_transformer.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/*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_SHAPE_SHAPE_TRANSFORM_HPP -#define OPENCV_SHAPE_SHAPE_TRANSFORM_HPP -#include -#include "opencv2/core.hpp" -#include "opencv2/imgproc.hpp" - -namespace cv -{ - -//! @addtogroup shape -//! @{ - -/** @brief Abstract base class for shape transformation algorithms. - */ -class CV_EXPORTS_W ShapeTransformer : public Algorithm -{ -public: - /** @brief Estimate the transformation parameters of the current transformer algorithm, based on point matches. - - @param transformingShape Contour defining first shape. - @param targetShape Contour defining second shape (Target). - @param matches Standard vector of Matches between points. - */ - CV_WRAP virtual void estimateTransformation(InputArray transformingShape, InputArray targetShape, - std::vector& matches) = 0; - - /** @brief Apply a transformation, given a pre-estimated transformation parameters. - - @param input Contour (set of points) to apply the transformation. - @param output Output contour. - */ - CV_WRAP virtual float applyTransformation(InputArray input, OutputArray output=noArray()) = 0; - - /** @brief Apply a transformation, given a pre-estimated transformation parameters, to an Image. - - @param transformingImage Input image. - @param output Output image. - @param flags Image interpolation method. - @param borderMode border style. - @param borderValue border value. - */ - CV_WRAP virtual void warpImage(InputArray transformingImage, OutputArray output, - int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, - const Scalar& borderValue=Scalar()) const = 0; -}; - -/***********************************************************************************/ -/***********************************************************************************/ - -/** @brief Definition of the transformation - -occupied in the paper "Principal Warps: Thin-Plate Splines and Decomposition of Deformations", by -F.L. Bookstein (PAMI 1989). : - */ -class CV_EXPORTS_W ThinPlateSplineShapeTransformer : public ShapeTransformer -{ -public: - /** @brief Set the regularization parameter for relaxing the exact interpolation requirements of the TPS - algorithm. - - @param beta value of the regularization parameter. - */ - CV_WRAP virtual void setRegularizationParameter(double beta) = 0; - CV_WRAP virtual double getRegularizationParameter() const = 0; -}; - -/** Complete constructor */ -CV_EXPORTS_W Ptr - createThinPlateSplineShapeTransformer(double regularizationParameter=0); - -/***********************************************************************************/ -/***********************************************************************************/ - -/** @brief Wrapper class for the OpenCV Affine Transformation algorithm. : - */ -class CV_EXPORTS_W AffineTransformer : public ShapeTransformer -{ -public: - CV_WRAP virtual void setFullAffine(bool fullAffine) = 0; - CV_WRAP virtual bool getFullAffine() const = 0; -}; - -/** Complete constructor */ -CV_EXPORTS_W Ptr createAffineTransformer(bool fullAffine); - -//! @} - -} // cv -#endif diff --git a/3rdparty/libopencv/include/opencv2/stitching.hpp b/3rdparty/libopencv/include/opencv2/stitching.hpp deleted file mode 100644 index 8b1bcc1..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching.hpp +++ /dev/null @@ -1,321 +0,0 @@ -/*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 -//! @{ - -/** @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 detailed example on image stitching can be found at - opencv_source_code/samples/cpp/stitching_detailed.cpp - */ -class CV_EXPORTS_W Stitcher -{ -public: - enum { ORIG_RESOL = -1 }; - 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, - - }; - - // Stitcher() {} - /** @brief Creates a stitcher with the default parameters. - - @param try_use_gpu Flag indicating whether GPU should be used whenever it's possible. - @return Stitcher class instance. - */ - static Stitcher createDefault(bool try_use_gpu = false); - /** @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. - @param try_use_gpu Flag indicating whether GPU should be used whenever it's possible. - @return Stitcher class instance. - */ - static Ptr create(Mode mode = PANORAMA, bool try_use_gpu = false); - - 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; } - - 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; } - - /* TODO OpenCV ABI 4.x - 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; } - - /** @overload */ - CV_WRAP Status estimateTransform(InputArrayOfArrays images); - /** @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 rois Region of interest rectangles. - @return Status code. - */ - Status estimateTransform(InputArrayOfArrays images, const std::vector > &rois); - - /** @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 rois Region of interest rectangles. - @param pano Final pano. - @return Status code. - */ - Status stitch(InputArrayOfArrays images, const std::vector > &rois, OutputArray pano); - - std::vector component() const { return indices_; } - std::vector cameras() const { return cameras_; } - CV_WRAP double workScale() const { return work_scale_; } - -private: - //Stitcher() {} - - Status matchImages(); - Status estimateCameraParams(); - - double registr_resol_; - double seam_est_resol_; - double compose_resol_; - double conf_thresh_; - Ptr features_finder_; - Ptr features_matcher_; - cv::UMat matching_mask_; - Ptr bundle_adjuster_; - /* TODO OpenCV ABI 4.x - 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 > rois_; - std::vector full_img_sizes_; - std::vector features_; - std::vector pairwise_matches_; - std::vector seam_est_imgs_; - std::vector indices_; - std::vector cameras_; - double work_scale_; - double seam_scale_; - double seam_work_aspect_; - double warped_image_scale_; -}; - -CV_EXPORTS_W Ptr createStitcher(bool try_use_gpu = false); -CV_EXPORTS_W Ptr createStitcherScans(bool try_use_gpu = false); - -//! @} stitching - -} // namespace cv - -#endif // OPENCV_STITCHING_STITCHER_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/autocalib.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/autocalib.hpp deleted file mode 100644 index 19705e2..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/autocalib.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/*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 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 calibrateRotatingCamera(const std::vector &Hs, Mat &K); - -//! @} stitching_autocalib - -} // namespace detail -} // namespace cv - -#endif // OPENCV_STITCHING_AUTOCALIB_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/blenders.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/blenders.hpp deleted file mode 100644 index c89e003..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/blenders.hpp +++ /dev/null @@ -1,171 +0,0 @@ -/*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" - -namespace cv { -namespace detail { - -//! @addtogroup stitching_blend -//! @{ - -/** @brief Base class for all blenders. - -Simple blender which puts one image over another -*/ -class CV_EXPORTS Blender -{ -public: - virtual ~Blender() {} - - enum { NO, FEATHER, MULTI_BAND }; - 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 - */ - void prepare(const std::vector &corners, const std::vector &sizes); - /** @overload */ - 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 - */ - 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 - */ - virtual void blend(InputOutputArray dst, InputOutputArray dst_mask); - -protected: - UMat dst_, dst_mask_; - Rect dst_roi_; -}; - -/** @brief Simple blender which mixes images at its borders. - */ -class CV_EXPORTS FeatherBlender : public Blender -{ -public: - FeatherBlender(float sharpness = 0.02f); - - float sharpness() const { return sharpness_; } - void setSharpness(float val) { sharpness_ = val; } - - void prepare(Rect dst_roi); - void feed(InputArray img, InputArray mask, Point tl); - void blend(InputOutputArray dst, InputOutputArray dst_mask); - - //! 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. - Rect createWeightMaps(const std::vector &masks, const std::vector &corners, - 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 MultiBandBlender : public Blender -{ -public: - MultiBandBlender(int try_gpu = false, int num_bands = 5, int weight_type = CV_32F); - - int numBands() const { return actual_num_bands_; } - void setNumBands(int val) { actual_num_bands_ = val; } - - void prepare(Rect dst_roi); - void feed(InputArray img, InputArray mask, Point tl); - void blend(InputOutputArray dst, InputOutputArray dst_mask); - -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_; -#endif -}; - - -////////////////////////////////////////////////////////////////////////////// -// Auxiliary functions - -void CV_EXPORTS normalizeUsingWeightMap(InputArray weight, InputOutputArray src); - -void CV_EXPORTS createWeightMap(InputArray mask, float sharpness, InputOutputArray weight); - -void CV_EXPORTS createLaplacePyr(InputArray img, int num_levels, std::vector& pyr); -void CV_EXPORTS createLaplacePyrGpu(InputArray img, int num_levels, std::vector& pyr); - -// Restores source image -void CV_EXPORTS restoreImageFromLaplacePyr(std::vector& pyr); -void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector& pyr); - -//! @} - -} // namespace detail -} // namespace cv - -#endif // OPENCV_STITCHING_BLENDERS_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/camera.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/camera.hpp deleted file mode 100644 index 07c6b5b..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/camera.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/*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 CameraParams -{ - CameraParams(); - CameraParams(const CameraParams& other); - CameraParams& operator =(const CameraParams& other); - Mat K() const; - - double focal; // Focal length - double aspect; // Aspect ratio - double ppx; // Principal point X - double ppy; // Principal point Y - Mat R; // Rotation - Mat t; // Translation -}; - -//! @} - -} // namespace detail -} // namespace cv - -#endif // #ifndef OPENCV_STITCHING_CAMERA_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/exposure_compensate.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/exposure_compensate.hpp deleted file mode 100644 index f5a8122..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/exposure_compensate.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/*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 ExposureCompensator -{ -public: - virtual ~ExposureCompensator() {} - - enum { NO, GAIN, GAIN_BLOCKS }; - 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) - */ - 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 - */ - virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0; -}; - -/** @brief Stub exposure compensator which does nothing. - */ -class CV_EXPORTS NoExposureCompensator : public ExposureCompensator -{ -public: - void feed(const std::vector &/*corners*/, const std::vector &/*images*/, - const std::vector > &/*masks*/) { } - void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) { } -}; - -/** @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 GainCompensator : public ExposureCompensator -{ -public: - void feed(const std::vector &corners, const std::vector &images, - const std::vector > &masks); - void apply(int index, Point corner, InputOutputArray image, InputArray mask); - std::vector gains() const; - -private: - Mat_ gains_; -}; - -/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block -intensities, see @cite UES01 for details. - */ -class CV_EXPORTS BlocksGainCompensator : public ExposureCompensator -{ -public: - BlocksGainCompensator(int bl_width = 32, int bl_height = 32) - : bl_width_(bl_width), bl_height_(bl_height) {} - void feed(const std::vector &corners, const std::vector &images, - const std::vector > &masks); - void apply(int index, Point corner, InputOutputArray image, InputArray mask); - -private: - int bl_width_, bl_height_; - std::vector gain_maps_; -}; - -//! @} - -} // namespace detail -} // namespace cv - -#endif // OPENCV_STITCHING_EXPOSURE_COMPENSATE_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/matchers.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/matchers.hpp deleted file mode 100644 index 009bdd9..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/matchers.hpp +++ /dev/null @@ -1,355 +0,0 @@ -/*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" - -#ifdef HAVE_OPENCV_XFEATURES2D -# include "opencv2/xfeatures2d/cuda.hpp" -#endif - -namespace cv { -namespace detail { - -//! @addtogroup stitching_match -//! @{ - -/** @brief Structure containing image keypoints and descriptors. */ -struct CV_EXPORTS ImageFeatures -{ - int img_idx; - Size img_size; - std::vector keypoints; - UMat descriptors; -}; - -/** @brief Feature finders base class */ -class CV_EXPORTS FeaturesFinder -{ -public: - virtual ~FeaturesFinder() {} - /** @overload */ - void operator ()(InputArray image, ImageFeatures &features); - /** @brief Finds features in the given image. - - @param image Source image - @param features Found features - @param rois Regions of interest - - @sa detail::ImageFeatures, Rect_ - */ - void operator ()(InputArray image, ImageFeatures &features, const std::vector &rois); - /** @brief Finds features in the given images in parallel. - - @param images Source images - @param features Found features for each image - @param rois Regions of interest for each image - - @sa detail::ImageFeatures, Rect_ - */ - void operator ()(InputArrayOfArrays images, std::vector &features, - const std::vector > &rois); - /** @overload */ - void operator ()(InputArrayOfArrays images, std::vector &features); - /** @brief Frees unused memory allocated before if there is any. */ - virtual void collectGarbage() {} - - /* TODO OpenCV ABI 4.x - reimplement this as public method similar to FeaturesMatcher and remove private function hack - @return True, if it's possible to use the same finder instance in parallel, false otherwise - bool isThreadSafe() const { return is_thread_safe_; } - */ - -protected: - /** @brief This method must implement features finding logic in order to make the wrappers - detail::FeaturesFinder::operator()_ work. - - @param image Source image - @param features Found features - - @sa detail::ImageFeatures */ - virtual void find(InputArray image, ImageFeatures &features) = 0; - /** @brief uses dynamic_cast to determine thread-safety - @return True, if it's possible to use the same finder instance in parallel, false otherwise - */ - bool isThreadSafe() const; -}; - -/** @brief SURF features finder. - -@sa detail::FeaturesFinder, SURF -*/ -class CV_EXPORTS SurfFeaturesFinder : public FeaturesFinder -{ -public: - SurfFeaturesFinder(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4, - int num_octaves_descr = /*4*/3, int num_layers_descr = /*2*/4); - -private: - void find(InputArray image, ImageFeatures &features); - - Ptr detector_; - Ptr extractor_; - Ptr surf; -}; - -/** @brief ORB features finder. : - -@sa detail::FeaturesFinder, ORB -*/ -class CV_EXPORTS OrbFeaturesFinder : public FeaturesFinder -{ -public: - OrbFeaturesFinder(Size _grid_size = Size(3,1), int nfeatures=1500, float scaleFactor=1.3f, int nlevels=5); - -private: - void find(InputArray image, ImageFeatures &features); - - Ptr orb; - Size grid_size; -}; - -/** @brief AKAZE features finder. : - -@sa detail::FeaturesFinder, AKAZE -*/ -class CV_EXPORTS AKAZEFeaturesFinder : public detail::FeaturesFinder -{ -public: - AKAZEFeaturesFinder(int descriptor_type = AKAZE::DESCRIPTOR_MLDB, - int descriptor_size = 0, - int descriptor_channels = 3, - float threshold = 0.001f, - int nOctaves = 4, - int nOctaveLayers = 4, - int diffusivity = KAZE::DIFF_PM_G2); - -private: - void find(InputArray image, detail::ImageFeatures &features); - - Ptr akaze; -}; - -#ifdef HAVE_OPENCV_XFEATURES2D -class CV_EXPORTS SurfFeaturesFinderGpu : public FeaturesFinder -{ -public: - SurfFeaturesFinderGpu(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4, - int num_octaves_descr = 4, int num_layers_descr = 2); - - void collectGarbage(); - -private: - void find(InputArray image, ImageFeatures &features); - - cuda::GpuMat image_; - cuda::GpuMat gray_image_; - cuda::SURF_CUDA surf_; - cuda::GpuMat keypoints_; - cuda::GpuMat descriptors_; - int num_octaves_, num_layers_; - int num_octaves_descr_, num_layers_descr_; -}; -#endif - -/** @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 MatchesInfo -{ - MatchesInfo(); - MatchesInfo(const MatchesInfo &other); - MatchesInfo& operator =(const MatchesInfo &other); - - int src_img_idx, dst_img_idx; //!< Images indices (optional) - std::vector matches; - std::vector inliers_mask; //!< Geometrically consistent matches mask - int num_inliers; //!< Number of geometrically consistent matches - Mat H; //!< Estimated transformation - double confidence; //!< Confidence two images are from the same panorama -}; - -/** @brief Feature matchers base class. */ -class CV_EXPORTS FeaturesMatcher -{ -public: - virtual ~FeaturesMatcher() {} - - /** @overload - @param features1 First image features - @param features2 Second image features - @param matches_info Found matches - */ - void operator ()(const ImageFeatures &features1, const ImageFeatures &features2, - 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 - */ - void operator ()(const std::vector &features, 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 - */ - bool isThreadSafe() const { return is_thread_safe_; } - - /** @brief Frees unused memory allocated before if there is any. - */ - 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 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 - */ - BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6, - int num_matches_thresh2 = 6); - - void collectGarbage(); - -protected: - void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info); - - int num_matches_thresh1_; - int num_matches_thresh2_; - Ptr impl_; -}; - -class CV_EXPORTS BestOf2NearestRangeMatcher : public BestOf2NearestMatcher -{ -public: - 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 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 - */ - 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); - - bool full_affine_; -}; - -//! @} stitching_match - -} // namespace detail -} // namespace cv - -#endif // OPENCV_STITCHING_MATCHERS_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/motion_estimators.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/motion_estimators.hpp deleted file mode 100644 index 68d4b8c..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/motion_estimators.hpp +++ /dev/null @@ -1,359 +0,0 @@ -/*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 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 - */ - bool operator ()(const std::vector &features, - const std::vector &pairwise_matches, - 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, - std::vector &cameras) = 0; -}; - -/** @brief Homography based rotation estimator. - */ -class CV_EXPORTS HomographyBasedEstimator : public Estimator -{ -public: - 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); - - 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 AffineBasedEstimator : public Estimator -{ -private: - virtual bool estimate(const std::vector &features, - const std::vector &pairwise_matches, - std::vector &cameras); -}; - -/** @brief Base class for all camera parameters refinement methods. - */ -class CV_EXPORTS BundleAdjusterBase : public Estimator -{ -public: - const Mat refinementMask() const { return refinement_mask_.clone(); } - void setRefinementMask(const Mat &mask) - { - CV_Assert(mask.type() == CV_8U && mask.size() == Size(3, 3)); - refinement_mask_ = mask.clone(); - } - - double confThresh() const { return conf_thresh_; } - void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; } - - TermCriteria termCriteria() { return term_criteria_; } - 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); - - /** @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 NoBundleAdjuster : public BundleAdjusterBase -{ -public: - NoBundleAdjuster() : BundleAdjusterBase(0, 0) {} - -private: - bool estimate(const std::vector &, const std::vector &, - std::vector &) - { - return true; - } - void setUpInitialCameraParams(const std::vector &) {} - void obtainRefinedCameraParams(std::vector &) const {} - void calcError(Mat &) {} - void calcJacobian(Mat &) {} -}; - - -/** @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 BundleAdjusterReproj : public BundleAdjusterBase -{ -public: - BundleAdjusterReproj() : BundleAdjusterBase(7, 2) {} - -private: - void setUpInitialCameraParams(const std::vector &cameras); - void obtainRefinedCameraParams(std::vector &cameras) const; - void calcError(Mat &err); - void calcJacobian(Mat &jac); - - 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 BundleAdjusterRay : public BundleAdjusterBase -{ -public: - BundleAdjusterRay() : BundleAdjusterBase(4, 3) {} - -private: - void setUpInitialCameraParams(const std::vector &cameras); - void obtainRefinedCameraParams(std::vector &cameras) const; - void calcError(Mat &err); - void calcJacobian(Mat &jac); - - 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 BundleAdjusterAffine : public BundleAdjusterBase -{ -public: - BundleAdjusterAffine() : BundleAdjusterBase(6, 2) {} - -private: - void setUpInitialCameraParams(const std::vector &cameras); - void obtainRefinedCameraParams(std::vector &cameras) const; - void calcError(Mat &err); - void calcJacobian(Mat &jac); - - 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 BundleAdjusterAffinePartial : public BundleAdjusterBase -{ -public: - BundleAdjusterAffinePartial() : BundleAdjusterBase(4, 2) {} - -private: - void setUpInitialCameraParams(const std::vector &cameras); - void obtainRefinedCameraParams(std::vector &cameras) const; - void calcError(Mat &err); - void calcJacobian(Mat &jac); - - 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 waveCorrect(std::vector &rmats, WaveCorrectKind kind); - - -////////////////////////////////////////////////////////////////////////////// -// Auxiliary functions - -// Returns matches graph representation in DOT language -String CV_EXPORTS matchesGraphAsString(std::vector &pathes, std::vector &pairwise_matches, - float conf_threshold); - -std::vector CV_EXPORTS 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/3rdparty/libopencv/include/opencv2/stitching/detail/seam_finders.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/seam_finders.hpp deleted file mode 100644 index a251f48..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/seam_finders.hpp +++ /dev/null @@ -1,285 +0,0 @@ -/*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 SeamFinder -{ -public: - virtual ~SeamFinder() {} - /** @brief Estimates seams. - - @param src Source images - @param corners Source image top-left corners - @param masks Source image masks to update - */ - virtual void find(const std::vector &src, const std::vector &corners, - std::vector &masks) = 0; -}; - -/** @brief Stub seam estimator which does nothing. - */ -class CV_EXPORTS NoSeamFinder : public SeamFinder -{ -public: - void find(const std::vector&, const std::vector&, std::vector&) {} -}; - -/** @brief Base class for all pairwise seam estimators. - */ -class CV_EXPORTS PairwiseSeamFinder : public SeamFinder -{ -public: - virtual void find(const std::vector &src, const std::vector &corners, - std::vector &masks); - -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 VoronoiSeamFinder : public PairwiseSeamFinder -{ -public: - virtual void find(const std::vector &src, const std::vector &corners, - std::vector &masks); - 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); -}; - - -class CV_EXPORTS DpSeamFinder : public SeamFinder -{ -public: - enum CostFunction { COLOR, COLOR_GRAD }; - - DpSeamFinder(CostFunction costFunc = COLOR); - - CostFunction costFunction() const { return costFunc_; } - void setCostFunction(CostFunction val) { costFunc_ = val; } - - virtual void find(const std::vector &src, const std::vector &corners, - std::vector &masks); - -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 GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder -{ -public: - GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f, - float bad_region_penalty = 1000.f); - - ~GraphCutSeamFinder(); - - void find(const std::vector &src, const std::vector &corners, - std::vector &masks); - -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); - void findInPair(size_t first, size_t second, Rect roi); - -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/3rdparty/libopencv/include/opencv2/stitching/detail/timelapsers.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/timelapsers.hpp deleted file mode 100644 index ae37b03..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/timelapsers.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/*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 Timelapser -{ -public: - - enum {AS_IS, CROP}; - - virtual ~Timelapser() {} - - static Ptr createDefault(int type); - - virtual void initialize(const std::vector &corners, const std::vector &sizes); - virtual void process(InputArray img, InputArray mask, Point tl); - virtual const UMat& getDst() {return dst_;} - -protected: - - virtual bool test_point(Point pt); - - UMat dst_; - Rect dst_roi_; -}; - - -class CV_EXPORTS TimelapserCrop : public Timelapser -{ -public: - virtual void initialize(const std::vector &corners, const std::vector &sizes); -}; - -//! @} - -} // namespace detail -} // namespace cv - -#endif // OPENCV_STITCHING_TIMELAPSERS_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/util.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/util.hpp deleted file mode 100644 index 78301b8..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/util.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/*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 bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi); -CV_EXPORTS Rect resultRoi(const std::vector &corners, const std::vector &images); -CV_EXPORTS Rect resultRoi(const std::vector &corners, const std::vector &sizes); -CV_EXPORTS Rect resultRoiIntersection(const std::vector &corners, const std::vector &sizes); -CV_EXPORTS Point resultTl(const std::vector &corners); - -// Returns random 'count' element subset of the {0,1,...,size-1} set -CV_EXPORTS void selectRandomSubset(int count, int size, std::vector &subset); - -CV_EXPORTS int& stitchingLogLevel(); - -//! @} - -} // namespace detail -} // namespace cv - -#include "util_inl.hpp" - -#endif // OPENCV_STITCHING_UTIL_HPP diff --git a/3rdparty/libopencv/include/opencv2/stitching/detail/util_inl.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/util_inl.hpp deleted file mode 100644 index dafab8b..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/util_inl.hpp +++ /dev/null @@ -1,131 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/stitching/detail/warpers.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/warpers.hpp deleted file mode 100644 index ddb2fb5..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/warpers.hpp +++ /dev/null @@ -1,616 +0,0 @@ - /*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, - 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, 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 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); - - Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); - - Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, - OutputArray dst); - - void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, - Size dst_size, OutputArray dst); - - Rect warpRoi(Size src_size, InputArray K, InputArray R); - - float getScale() const { return projector_.scale; } - void setScale(float val) { 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); - Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T); - - virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap); - Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); - - Point warp(InputArray src, InputArray K, InputArray R, - int interp_mode, int border_mode, OutputArray dst); - virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, - OutputArray dst); - - Rect warpRoi(Size src_size, InputArray K, InputArray R); - Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T); - -protected: - void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br); -}; - - -/** @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); - Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap); - Point warp(InputArray src, InputArray K, InputArray R, - int interp_mode, int border_mode, OutputArray dst); - Rect warpRoi(Size src_size, InputArray K, InputArray R); - -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 SphericalProjector : 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 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); - Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst); -protected: - void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br); -}; - - -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); - Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst); -protected: - void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) - { - 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) - { - 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) - { - 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) - { - 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) - { - 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) - { - 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) - { - 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) - { - 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) - { - 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); -}; - -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) - { - 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) - { - 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/3rdparty/libopencv/include/opencv2/stitching/detail/warpers_inl.hpp b/3rdparty/libopencv/include/opencv2/stitching/detail/warpers_inl.hpp deleted file mode 100644 index f4a19d9..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/detail/warpers_inl.hpp +++ /dev/null @@ -1,774 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/stitching/warpers.hpp b/3rdparty/libopencv/include/opencv2/stitching/warpers.hpp deleted file mode 100644 index 139e052..0000000 --- a/3rdparty/libopencv/include/opencv2/stitching/warpers.hpp +++ /dev/null @@ -1,192 +0,0 @@ -/*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" - -namespace cv { - -//! @addtogroup stitching_warp -//! @{ - -/** @brief Image warper factories base class. - */ -class WarperCreator -{ -public: - virtual ~WarperCreator() {} - virtual Ptr create(float scale) const = 0; -}; - -/** @brief Plane warper factory class. - @sa detail::PlaneWarper - */ -class PlaneWarper : public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - -/** @brief Affine warper factory class. - @sa detail::AffineWarper - */ -class AffineWarper : public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - -/** @brief Cylindrical warper factory class. -@sa detail::CylindricalWarper -*/ -class CylindricalWarper: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - -/** @brief Spherical warper factory class */ -class SphericalWarper: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - -class FisheyeWarper : public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - -class StereographicWarper: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - -class CompressedRectilinearWarper: public WarperCreator -{ - float a, b; -public: - CompressedRectilinearWarper(float A = 1, float B = 1) - { - a = A; b = B; - } - Ptr create(float scale) const { return makePtr(scale, a, b); } -}; - -class CompressedRectilinearPortraitWarper: public WarperCreator -{ - float a, b; -public: - CompressedRectilinearPortraitWarper(float A = 1, float B = 1) - { - a = A; b = B; - } - Ptr create(float scale) const { return makePtr(scale, a, b); } -}; - -class PaniniWarper: public WarperCreator -{ - float a, b; -public: - PaniniWarper(float A = 1, float B = 1) - { - a = A; b = B; - } - Ptr create(float scale) const { return makePtr(scale, a, b); } -}; - -class PaniniPortraitWarper: public WarperCreator -{ - float a, b; -public: - PaniniPortraitWarper(float A = 1, float B = 1) - { - a = A; b = B; - } - Ptr create(float scale) const { return makePtr(scale, a, b); } -}; - -class MercatorWarper: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - -class TransverseMercatorWarper: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - - - -#ifdef HAVE_OPENCV_CUDAWARPING -class PlaneWarperGpu: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - - -class CylindricalWarperGpu: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; - - -class SphericalWarperGpu: public WarperCreator -{ -public: - Ptr create(float scale) const { return makePtr(scale); } -}; -#endif - -//! @} stitching_warp - -} // namespace cv - -#endif // OPENCV_STITCHING_WARPER_CREATORS_HPP diff --git a/3rdparty/libopencv/include/opencv2/superres.hpp b/3rdparty/libopencv/include/opencv2/superres.hpp deleted file mode 100644 index e8bb5e5..0000000 --- a/3rdparty/libopencv/include/opencv2/superres.hpp +++ /dev/null @@ -1,207 +0,0 @@ -/*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_SUPERRES_HPP -#define OPENCV_SUPERRES_HPP - -#include "opencv2/core.hpp" -#include "opencv2/superres/optical_flow.hpp" - -/** - @defgroup superres Super Resolution - -The Super Resolution module contains a set of functions and classes that can be used to solve the -problem of resolution enhancement. There are a few methods implemented, most of them are described in -the papers @cite Farsiu03 and @cite Mitzel09 . - - */ - -namespace cv -{ - namespace superres - { - -//! @addtogroup superres -//! @{ - - class CV_EXPORTS FrameSource - { - public: - virtual ~FrameSource(); - - virtual void nextFrame(OutputArray frame) = 0; - virtual void reset() = 0; - }; - - CV_EXPORTS Ptr createFrameSource_Empty(); - - CV_EXPORTS Ptr createFrameSource_Video(const String& fileName); - CV_EXPORTS Ptr createFrameSource_Video_CUDA(const String& fileName); - - CV_EXPORTS Ptr createFrameSource_Camera(int deviceId = 0); - - /** @brief Base class for Super Resolution algorithms. - - The class is only used to define the common interface for the whole family of Super Resolution - algorithms. - */ - class CV_EXPORTS SuperResolution : public cv::Algorithm, public FrameSource - { - public: - /** @brief Set input frame source for Super Resolution algorithm. - - @param frameSource Input frame source - */ - void setInput(const Ptr& frameSource); - - /** @brief Process next frame from input and return output result. - - @param frame Output result - */ - void nextFrame(OutputArray frame); - void reset(); - - /** @brief Clear all inner buffers. - */ - virtual void collectGarbage(); - - //! @brief Scale factor - /** @see setScale */ - virtual int getScale() const = 0; - /** @copybrief getScale @see getScale */ - virtual void setScale(int val) = 0; - - //! @brief Iterations count - /** @see setIterations */ - virtual int getIterations() const = 0; - /** @copybrief getIterations @see getIterations */ - virtual void setIterations(int val) = 0; - - //! @brief Asymptotic value of steepest descent method - /** @see setTau */ - virtual double getTau() const = 0; - /** @copybrief getTau @see getTau */ - virtual void setTau(double val) = 0; - - //! @brief Weight parameter to balance data term and smoothness term - /** @see setLabmda */ - virtual double getLabmda() const = 0; - /** @copybrief getLabmda @see getLabmda */ - virtual void setLabmda(double val) = 0; - - //! @brief Parameter of spacial distribution in Bilateral-TV - /** @see setAlpha */ - virtual double getAlpha() const = 0; - /** @copybrief getAlpha @see getAlpha */ - virtual void setAlpha(double val) = 0; - - //! @brief Kernel size of Bilateral-TV filter - /** @see setKernelSize */ - virtual int getKernelSize() const = 0; - /** @copybrief getKernelSize @see getKernelSize */ - virtual void setKernelSize(int val) = 0; - - //! @brief Gaussian blur kernel size - /** @see setBlurKernelSize */ - virtual int getBlurKernelSize() const = 0; - /** @copybrief getBlurKernelSize @see getBlurKernelSize */ - virtual void setBlurKernelSize(int val) = 0; - - //! @brief Gaussian blur sigma - /** @see setBlurSigma */ - virtual double getBlurSigma() const = 0; - /** @copybrief getBlurSigma @see getBlurSigma */ - virtual void setBlurSigma(double val) = 0; - - //! @brief Radius of the temporal search area - /** @see setTemporalAreaRadius */ - virtual int getTemporalAreaRadius() const = 0; - /** @copybrief getTemporalAreaRadius @see getTemporalAreaRadius */ - virtual void setTemporalAreaRadius(int val) = 0; - - //! @brief Dense optical flow algorithm - /** @see setOpticalFlow */ - virtual Ptr getOpticalFlow() const = 0; - /** @copybrief getOpticalFlow @see getOpticalFlow */ - virtual void setOpticalFlow(const Ptr &val) = 0; - - protected: - SuperResolution(); - - virtual void initImpl(Ptr& frameSource) = 0; - virtual void processImpl(Ptr& frameSource, OutputArray output) = 0; - - bool isUmat_; - - private: - Ptr frameSource_; - bool firstCall_; - }; - - /** @brief Create Bilateral TV-L1 Super Resolution. - - This class implements Super Resolution algorithm described in the papers @cite Farsiu03 and - @cite Mitzel09 . - - Here are important members of the class that control the algorithm, which you can set after - constructing the class instance: - - - **int scale** Scale factor. - - **int iterations** Iteration count. - - **double tau** Asymptotic value of steepest descent method. - - **double lambda** Weight parameter to balance data term and smoothness term. - - **double alpha** Parameter of spacial distribution in Bilateral-TV. - - **int btvKernelSize** Kernel size of Bilateral-TV filter. - - **int blurKernelSize** Gaussian blur kernel size. - - **double blurSigma** Gaussian blur sigma. - - **int temporalAreaRadius** Radius of the temporal search area. - - **Ptr\ opticalFlow** Dense optical flow algorithm. - */ - CV_EXPORTS Ptr createSuperResolution_BTVL1(); - CV_EXPORTS Ptr createSuperResolution_BTVL1_CUDA(); - -//! @} superres - - } -} - -#endif // OPENCV_SUPERRES_HPP diff --git a/3rdparty/libopencv/include/opencv2/superres/optical_flow.hpp b/3rdparty/libopencv/include/opencv2/superres/optical_flow.hpp deleted file mode 100644 index 07e7ca9..0000000 --- a/3rdparty/libopencv/include/opencv2/superres/optical_flow.hpp +++ /dev/null @@ -1,203 +0,0 @@ -/*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_SUPERRES_OPTICAL_FLOW_HPP -#define OPENCV_SUPERRES_OPTICAL_FLOW_HPP - -#include "opencv2/core.hpp" - -namespace cv -{ - namespace superres - { - -//! @addtogroup superres -//! @{ - - class CV_EXPORTS DenseOpticalFlowExt : public cv::Algorithm - { - public: - virtual void calc(InputArray frame0, InputArray frame1, OutputArray flow1, OutputArray flow2 = noArray()) = 0; - virtual void collectGarbage() = 0; - }; - - - class CV_EXPORTS FarnebackOpticalFlow : public virtual DenseOpticalFlowExt - { - public: - /** @see setPyrScale */ - virtual double getPyrScale() const = 0; - /** @copybrief getPyrScale @see getPyrScale */ - virtual void setPyrScale(double val) = 0; - /** @see setLevelsNumber */ - virtual int getLevelsNumber() const = 0; - /** @copybrief getLevelsNumber @see getLevelsNumber */ - virtual void setLevelsNumber(int val) = 0; - /** @see setWindowSize */ - virtual int getWindowSize() const = 0; - /** @copybrief getWindowSize @see getWindowSize */ - virtual void setWindowSize(int val) = 0; - /** @see setIterations */ - virtual int getIterations() const = 0; - /** @copybrief getIterations @see getIterations */ - virtual void setIterations(int val) = 0; - /** @see setPolyN */ - virtual int getPolyN() const = 0; - /** @copybrief getPolyN @see getPolyN */ - virtual void setPolyN(int val) = 0; - /** @see setPolySigma */ - virtual double getPolySigma() const = 0; - /** @copybrief getPolySigma @see getPolySigma */ - virtual void setPolySigma(double val) = 0; - /** @see setFlags */ - virtual int getFlags() const = 0; - /** @copybrief getFlags @see getFlags */ - virtual void setFlags(int val) = 0; - }; - CV_EXPORTS Ptr createOptFlow_Farneback(); - CV_EXPORTS Ptr createOptFlow_Farneback_CUDA(); - - -// CV_EXPORTS Ptr createOptFlow_Simple(); - - - class CV_EXPORTS DualTVL1OpticalFlow : public virtual DenseOpticalFlowExt - { - public: - /** @see setTau */ - virtual double getTau() const = 0; - /** @copybrief getTau @see getTau */ - virtual void setTau(double val) = 0; - /** @see setLambda */ - virtual double getLambda() const = 0; - /** @copybrief getLambda @see getLambda */ - virtual void setLambda(double val) = 0; - /** @see setTheta */ - virtual double getTheta() const = 0; - /** @copybrief getTheta @see getTheta */ - virtual void setTheta(double val) = 0; - /** @see setScalesNumber */ - virtual int getScalesNumber() const = 0; - /** @copybrief getScalesNumber @see getScalesNumber */ - virtual void setScalesNumber(int val) = 0; - /** @see setWarpingsNumber */ - virtual int getWarpingsNumber() const = 0; - /** @copybrief getWarpingsNumber @see getWarpingsNumber */ - virtual void setWarpingsNumber(int val) = 0; - /** @see setEpsilon */ - virtual double getEpsilon() const = 0; - /** @copybrief getEpsilon @see getEpsilon */ - virtual void setEpsilon(double val) = 0; - /** @see setIterations */ - virtual int getIterations() const = 0; - /** @copybrief getIterations @see getIterations */ - virtual void setIterations(int val) = 0; - /** @see setUseInitialFlow */ - virtual bool getUseInitialFlow() const = 0; - /** @copybrief getUseInitialFlow @see getUseInitialFlow */ - virtual void setUseInitialFlow(bool val) = 0; - }; - CV_EXPORTS Ptr createOptFlow_DualTVL1(); - CV_EXPORTS Ptr createOptFlow_DualTVL1_CUDA(); - - - class CV_EXPORTS BroxOpticalFlow : public virtual DenseOpticalFlowExt - { - public: - //! @brief Flow smoothness - /** @see setAlpha */ - virtual double getAlpha() const = 0; - /** @copybrief getAlpha @see getAlpha */ - virtual void setAlpha(double val) = 0; - //! @brief Gradient constancy importance - /** @see setGamma */ - virtual double getGamma() const = 0; - /** @copybrief getGamma @see getGamma */ - virtual void setGamma(double val) = 0; - //! @brief Pyramid scale factor - /** @see setScaleFactor */ - virtual double getScaleFactor() const = 0; - /** @copybrief getScaleFactor @see getScaleFactor */ - virtual void setScaleFactor(double val) = 0; - //! @brief Number of lagged non-linearity iterations (inner loop) - /** @see setInnerIterations */ - virtual int getInnerIterations() const = 0; - /** @copybrief getInnerIterations @see getInnerIterations */ - virtual void setInnerIterations(int val) = 0; - //! @brief Number of warping iterations (number of pyramid levels) - /** @see setOuterIterations */ - virtual int getOuterIterations() const = 0; - /** @copybrief getOuterIterations @see getOuterIterations */ - virtual void setOuterIterations(int val) = 0; - //! @brief Number of linear system solver iterations - /** @see setSolverIterations */ - virtual int getSolverIterations() const = 0; - /** @copybrief getSolverIterations @see getSolverIterations */ - virtual void setSolverIterations(int val) = 0; - }; - CV_EXPORTS Ptr createOptFlow_Brox_CUDA(); - - - class PyrLKOpticalFlow : public virtual DenseOpticalFlowExt - { - public: - /** @see setWindowSize */ - virtual int getWindowSize() const = 0; - /** @copybrief getWindowSize @see getWindowSize */ - virtual void setWindowSize(int val) = 0; - /** @see setMaxLevel */ - virtual int getMaxLevel() const = 0; - /** @copybrief getMaxLevel @see getMaxLevel */ - virtual void setMaxLevel(int val) = 0; - /** @see setIterations */ - virtual int getIterations() const = 0; - /** @copybrief getIterations @see getIterations */ - virtual void setIterations(int val) = 0; - }; - CV_EXPORTS Ptr createOptFlow_PyrLK_CUDA(); - -//! @} - - } -} - -#endif // OPENCV_SUPERRES_OPTICAL_FLOW_HPP diff --git a/3rdparty/libopencv/include/opencv2/video.hpp b/3rdparty/libopencv/include/opencv2/video.hpp deleted file mode 100644 index aa644a9..0000000 --- a/3rdparty/libopencv/include/opencv2/video.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/*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" - -#ifndef DISABLE_OPENCV_24_COMPATIBILITY -#include "opencv2/video/tracking_c.h" -#endif - -#endif //OPENCV_VIDEO_HPP diff --git a/3rdparty/libopencv/include/opencv2/video/background_segm.hpp b/3rdparty/libopencv/include/opencv2/video/background_segm.hpp deleted file mode 100644 index ea7a897..0000000 --- a/3rdparty/libopencv/include/opencv2/video/background_segm.hpp +++ /dev/null @@ -1,317 +0,0 @@ -/*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) = 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/3rdparty/libopencv/include/opencv2/video/tracking.hpp b/3rdparty/libopencv/include/opencv2/video/tracking.hpp deleted file mode 100644 index d397ac7..0000000 --- a/3rdparty/libopencv/include/opencv2/video/tracking.hpp +++ /dev/null @@ -1,628 +0,0 @@ -/*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 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 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. - -@sa -estimateAffine2D, estimateAffinePartial2D, getAffineTransform, getPerspectiveTransform, findHomography - */ -CV_EXPORTS_W Mat estimateRigidTransform( InputArray src, InputArray dst, bool fullAffine ); - - -enum -{ - MOTION_TRANSLATION = 0, - MOTION_EUCLIDEAN = 1, - MOTION_AFFINE = 2, - MOTION_HOMOGRAPHY = 3 -}; - -/** @example 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 temlateImage. -@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. - -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 -estimateAffine2D, estimateAffinePartial2D, findHomography - */ -CV_EXPORTS_W 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 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; -}; - - -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 "Dual TV L1" Optical Flow Algorithm. - -The class implements the "Dual TV L1" optical flow algorithm described in @cite Zach2007 and -@cite Javier2012 . -Here are important members of the class that control the algorithm, which you can set after -constructing the class instance: - -- member double tau - Time step of the numerical scheme. - -- member double lambda - Weight parameter for the data term, attachment parameter. This is the most relevant - parameter, which determines the smoothness of the output. The smaller this parameter is, - the smoother the solutions we obtain. It depends on the range of motions of the images, so - its value should be adapted to each image sequence. - -- member double theta - Weight parameter for (u - v)\^2, tightness parameter. It serves as a link between the - attachment and the regularization terms. In theory, it should have a small value in order - to maintain both parts in correspondence. The method is stable for a large range of values - of this parameter. - -- member int nscales - Number of scales used to create the pyramid of images. - -- member int warps - Number of warpings per scale. Represents the number of times that I1(x+u0) and grad( - I1(x+u0) ) are computed per scale. This is a parameter that assures the stability of the - method. It also affects the running time, so it is a compromise between speed and - accuracy. - -- member double epsilon - Stopping criterion threshold used in the numerical scheme, which is a trade-off between - precision and running time. A small value will yield more accurate solutions at the - expense of a slower convergence. - -- member int iterations - Stopping criterion iterations number used in the numerical scheme. - -C. Zach, T. Pock and H. Bischof, "A Duality Based Approach for Realtime TV-L1 Optical Flow". -Javier Sanchez, Enric Meinhardt-Llopis and Gabriele Facciolo. "TV-L1 Optical Flow Estimation". -*/ -class CV_EXPORTS_W DualTVL1OpticalFlow : public DenseOpticalFlow -{ -public: - //! @brief Time step of the numerical scheme - /** @see setTau */ - CV_WRAP virtual double getTau() const = 0; - /** @copybrief getTau @see getTau */ - CV_WRAP virtual void setTau(double val) = 0; - //! @brief Weight parameter for the data term, attachment parameter - /** @see setLambda */ - CV_WRAP virtual double getLambda() const = 0; - /** @copybrief getLambda @see getLambda */ - CV_WRAP virtual void setLambda(double val) = 0; - //! @brief Weight parameter for (u - v)^2, tightness parameter - /** @see setTheta */ - CV_WRAP virtual double getTheta() const = 0; - /** @copybrief getTheta @see getTheta */ - CV_WRAP virtual void setTheta(double val) = 0; - //! @brief coefficient for additional illumination variation term - /** @see setGamma */ - CV_WRAP virtual double getGamma() const = 0; - /** @copybrief getGamma @see getGamma */ - CV_WRAP virtual void setGamma(double val) = 0; - //! @brief Number of scales used to create the pyramid of images - /** @see setScalesNumber */ - CV_WRAP virtual int getScalesNumber() const = 0; - /** @copybrief getScalesNumber @see getScalesNumber */ - CV_WRAP virtual void setScalesNumber(int val) = 0; - //! @brief Number of warpings per scale - /** @see setWarpingsNumber */ - CV_WRAP virtual int getWarpingsNumber() const = 0; - /** @copybrief getWarpingsNumber @see getWarpingsNumber */ - CV_WRAP virtual void setWarpingsNumber(int val) = 0; - //! @brief Stopping criterion threshold used in the numerical scheme, which is a trade-off between precision and running time - /** @see setEpsilon */ - CV_WRAP virtual double getEpsilon() const = 0; - /** @copybrief getEpsilon @see getEpsilon */ - CV_WRAP virtual void setEpsilon(double val) = 0; - //! @brief Inner iterations (between outlier filtering) used in the numerical scheme - /** @see setInnerIterations */ - CV_WRAP virtual int getInnerIterations() const = 0; - /** @copybrief getInnerIterations @see getInnerIterations */ - CV_WRAP virtual void setInnerIterations(int val) = 0; - //! @brief Outer iterations (number of inner loops) used in the numerical scheme - /** @see setOuterIterations */ - CV_WRAP virtual int getOuterIterations() const = 0; - /** @copybrief getOuterIterations @see getOuterIterations */ - CV_WRAP virtual void setOuterIterations(int val) = 0; - //! @brief Use initial flow - /** @see setUseInitialFlow */ - CV_WRAP virtual bool getUseInitialFlow() const = 0; - /** @copybrief getUseInitialFlow @see getUseInitialFlow */ - CV_WRAP virtual void setUseInitialFlow(bool val) = 0; - //! @brief Step between scales (<1) - /** @see setScaleStep */ - CV_WRAP virtual double getScaleStep() const = 0; - /** @copybrief getScaleStep @see getScaleStep */ - CV_WRAP virtual void setScaleStep(double val) = 0; - //! @brief Median filter kernel size (1 = no filter) (3 or 5) - /** @see setMedianFiltering */ - CV_WRAP virtual int getMedianFiltering() const = 0; - /** @copybrief getMedianFiltering @see getMedianFiltering */ - CV_WRAP virtual void setMedianFiltering(int val) = 0; - - /** @brief Creates instance of cv::DualTVL1OpticalFlow*/ - CV_WRAP static Ptr create( - double tau = 0.25, - double lambda = 0.15, - double theta = 0.3, - int nscales = 5, - int warps = 5, - double epsilon = 0.01, - int innnerIterations = 30, - int outerIterations = 10, - double scaleStep = 0.8, - double gamma = 0.0, - int medianFiltering = 5, - bool useInitialFlow = false); -}; - -/** @brief Creates instance of cv::DenseOpticalFlow -*/ -CV_EXPORTS_W Ptr createOptFlow_DualTVL1(); - -/** @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 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/3rdparty/libopencv/include/opencv2/video/tracking_c.h b/3rdparty/libopencv/include/opencv2/video/tracking_c.h deleted file mode 100644 index 3e32fbd..0000000 --- a/3rdparty/libopencv/include/opencv2/video/tracking_c.h +++ /dev/null @@ -1,232 +0,0 @@ -/*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_C_H -#define OPENCV_TRACKING_C_H - -#include "opencv2/imgproc/types_c.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @addtogroup video_c - @{ -*/ - -/****************************************************************************************\ -* Motion Analysis * -\****************************************************************************************/ - -/************************************ optical flow ***************************************/ - -#define CV_LKFLOW_PYR_A_READY 1 -#define CV_LKFLOW_PYR_B_READY 2 -#define CV_LKFLOW_INITIAL_GUESSES 4 -#define CV_LKFLOW_GET_MIN_EIGENVALS 8 - -/* It is Lucas & Kanade method, modified to use pyramids. - Also it does several iterations to get optical flow for - every point at every pyramid level. - Calculates optical flow between two images for certain set of points (i.e. - it is a "sparse" optical flow, which is opposite to the previous 3 methods) */ -CVAPI(void) cvCalcOpticalFlowPyrLK( const CvArr* prev, const CvArr* curr, - CvArr* prev_pyr, CvArr* curr_pyr, - const CvPoint2D32f* prev_features, - CvPoint2D32f* curr_features, - int count, - CvSize win_size, - int level, - char* status, - float* track_error, - CvTermCriteria criteria, - int flags ); - - -/* Modification of a previous sparse optical flow algorithm to calculate - affine flow */ -CVAPI(void) cvCalcAffineFlowPyrLK( const CvArr* prev, const CvArr* curr, - CvArr* prev_pyr, CvArr* curr_pyr, - const CvPoint2D32f* prev_features, - CvPoint2D32f* curr_features, - float* matrices, int count, - CvSize win_size, int level, - char* status, float* track_error, - CvTermCriteria criteria, int flags ); - -/* Estimate rigid transformation between 2 images or 2 point sets */ -CVAPI(int) cvEstimateRigidTransform( const CvArr* A, const CvArr* B, - CvMat* M, int full_affine ); - -/* Estimate optical flow for each pixel using the two-frame G. Farneback algorithm */ -CVAPI(void) cvCalcOpticalFlowFarneback( const CvArr* prev, const CvArr* next, - CvArr* flow, double pyr_scale, int levels, - int winsize, int iterations, int poly_n, - double poly_sigma, int flags ); - -/********************************* motion templates *************************************/ - -/****************************************************************************************\ -* All the motion template functions work only with single channel images. * -* Silhouette image must have depth IPL_DEPTH_8U or IPL_DEPTH_8S * -* Motion history image must have depth IPL_DEPTH_32F, * -* Gradient mask - IPL_DEPTH_8U or IPL_DEPTH_8S, * -* Motion orientation image - IPL_DEPTH_32F * -* Segmentation mask - IPL_DEPTH_32F * -* All the angles are in degrees, all the times are in milliseconds * -\****************************************************************************************/ - -/* Updates motion history image given motion silhouette */ -CVAPI(void) cvUpdateMotionHistory( const CvArr* silhouette, CvArr* mhi, - double timestamp, double duration ); - -/* Calculates gradient of the motion history image and fills - a mask indicating where the gradient is valid */ -CVAPI(void) cvCalcMotionGradient( const CvArr* mhi, CvArr* mask, CvArr* orientation, - double delta1, double delta2, - int aperture_size CV_DEFAULT(3)); - -/* Calculates average motion direction within a selected motion region - (region can be selected by setting ROIs and/or by composing a valid gradient mask - with the region mask) */ -CVAPI(double) cvCalcGlobalOrientation( const CvArr* orientation, const CvArr* mask, - const CvArr* mhi, double timestamp, - double duration ); - -/* Splits a motion history image into a few parts corresponding to separate independent motions - (e.g. left hand, right hand) */ -CVAPI(CvSeq*) cvSegmentMotion( const CvArr* mhi, CvArr* seg_mask, - CvMemStorage* storage, - double timestamp, double seg_thresh ); - -/****************************************************************************************\ -* Tracking * -\****************************************************************************************/ - -/* Implements CAMSHIFT algorithm - determines object position, size and orientation - from the object histogram back project (extension of meanshift) */ -CVAPI(int) cvCamShift( const CvArr* prob_image, CvRect window, - CvTermCriteria criteria, CvConnectedComp* comp, - CvBox2D* box CV_DEFAULT(NULL) ); - -/* Implements MeanShift algorithm - determines object position - from the object histogram back project */ -CVAPI(int) cvMeanShift( const CvArr* prob_image, CvRect window, - CvTermCriteria criteria, CvConnectedComp* comp ); - -/* -standard Kalman filter (in G. Welch' and G. Bishop's notation): - - x(k)=A*x(k-1)+B*u(k)+w(k) p(w)~N(0,Q) - z(k)=H*x(k)+v(k), p(v)~N(0,R) -*/ -typedef struct CvKalman -{ - int MP; /* number of measurement vector dimensions */ - int DP; /* number of state vector dimensions */ - int CP; /* number of control vector dimensions */ - - /* backward compatibility fields */ -#if 1 - float* PosterState; /* =state_pre->data.fl */ - float* PriorState; /* =state_post->data.fl */ - float* DynamMatr; /* =transition_matrix->data.fl */ - float* MeasurementMatr; /* =measurement_matrix->data.fl */ - float* MNCovariance; /* =measurement_noise_cov->data.fl */ - float* PNCovariance; /* =process_noise_cov->data.fl */ - float* KalmGainMatr; /* =gain->data.fl */ - float* PriorErrorCovariance;/* =error_cov_pre->data.fl */ - float* PosterErrorCovariance;/* =error_cov_post->data.fl */ - float* Temp1; /* temp1->data.fl */ - float* Temp2; /* temp2->data.fl */ -#endif - - CvMat* state_pre; /* predicted state (x'(k)): - x(k)=A*x(k-1)+B*u(k) */ - CvMat* state_post; /* corrected state (x(k)): - x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) */ - CvMat* transition_matrix; /* state transition matrix (A) */ - CvMat* control_matrix; /* control matrix (B) - (it is not used if there is no control)*/ - CvMat* measurement_matrix; /* measurement matrix (H) */ - CvMat* process_noise_cov; /* process noise covariance matrix (Q) */ - CvMat* measurement_noise_cov; /* measurement noise covariance matrix (R) */ - CvMat* error_cov_pre; /* priori error estimate covariance matrix (P'(k)): - P'(k)=A*P(k-1)*At + Q)*/ - CvMat* gain; /* Kalman gain matrix (K(k)): - K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)*/ - CvMat* error_cov_post; /* posteriori error estimate covariance matrix (P(k)): - P(k)=(I-K(k)*H)*P'(k) */ - CvMat* temp1; /* temporary matrices */ - CvMat* temp2; - CvMat* temp3; - CvMat* temp4; - CvMat* temp5; -} CvKalman; - -/* Creates Kalman filter and sets A, B, Q, R and state to some initial values */ -CVAPI(CvKalman*) cvCreateKalman( int dynam_params, int measure_params, - int control_params CV_DEFAULT(0)); - -/* Releases Kalman filter state */ -CVAPI(void) cvReleaseKalman( CvKalman** kalman); - -/* Updates Kalman filter by time (predicts future state of the system) */ -CVAPI(const CvMat*) cvKalmanPredict( CvKalman* kalman, - const CvMat* control CV_DEFAULT(NULL)); - -/* Updates Kalman filter by measurement - (corrects state of the system and internal matrices) */ -CVAPI(const CvMat*) cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement ); - -#define cvKalmanUpdateByTime cvKalmanPredict -#define cvKalmanUpdateByMeasurement cvKalmanCorrect - -/** @} video_c */ - -#ifdef __cplusplus -} // extern "C" -#endif - - -#endif // OPENCV_TRACKING_C_H diff --git a/3rdparty/libopencv/include/opencv2/video/video.hpp b/3rdparty/libopencv/include/opencv2/video/video.hpp deleted file mode 100644 index 8267b85..0000000 --- a/3rdparty/libopencv/include/opencv2/video/video.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/videoio.hpp b/3rdparty/libopencv/include/opencv2/videoio.hpp deleted file mode 100644 index a921300..0000000 --- a/3rdparty/libopencv/include/opencv2/videoio.hpp +++ /dev/null @@ -1,957 +0,0 @@ -/*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 - @} -*/ - -////////////////////////////////// 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 (platform native) - CAP_V4L = 200, //!< V4L/V4L2 capturing support via libv4l - CAP_V4L2 = CAP_V4L, //!< Same as CAP_V4L - CAP_FIREWIRE = 300, //!< IEEE 1394 drivers - CAP_FIREWARE = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE - CAP_IEEE1394 = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE - CAP_DC1394 = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE - CAP_CMU1394 = CAP_FIREWIRE, //!< Same as CAP_FIREWIRE - CAP_QT = 500, //!< QuickTime - CAP_UNICAP = 600, //!< Unicap drivers - 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, //!< Intel Perceptual Computing SDK - 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 - }; - -/** @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) -#ifndef CV_DOXYGEN - CV__CAP_PROP_LATEST -#endif - }; - - -/** @brief Generic camera output modes identifier. -@note Currently, these are supported through the libv4l backend only. -*/ -enum VideoCaptureModes { - CAP_MODE_BGR = 0, //!< BGR24 (default) - CAP_MODE_RGB = 1, //!< RGB24 - CAP_MODE_GRAY = 2, //!< Y8 - CAP_MODE_YUYV = 3 //!< YUYV - }; - -/** @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_GENERATORS_MASK = CAP_INTELPERC_DEPTH_GENERATOR + CAP_INTELPERC_IMAGE_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 Open video file or a capturing device or a IP video stream for video capturing - - Same as VideoCapture(const String& filename, int apiPreference) but using default Capture API backends - */ - CV_WRAP VideoCapture(const String& filename); - - /** @overload - @brief Open video file or a capturing device or a 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); - - /** @overload - @brief Open a camera for video capturing - - @param index camera_id + domain_offset (CAP_*) id of the video capturing device to open. To open default camera using default backend just pass 0. - Use a `domain_offset` to enforce a specific reader implementation if multiple are available like cv::CAP_FFMPEG or cv::CAP_IMAGES or cv::CAP_DSHOW. - e.g. to open Camera 1 using the MS Media Foundation API use `index = 1 + cv::CAP_MSMF` - - @sa The list of supported API backends cv::VideoCaptureAPIs - */ - CV_WRAP VideoCapture(int index); - - /** @brief Default destructor - - The method first calls VideoCapture::release to close the already opened file or camera. - */ - virtual ~VideoCapture(); - - /** @brief Open video file or a capturing device or a IP video stream for video capturing - - @overload - - Parameters are same as the constructor VideoCapture(const String& filename) - @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); - - /** @brief Open a camera for video capturing - - @overload - - Parameters are same as the constructor VideoCapture(int index) - @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); - - /** @brief Open a camera for video capturing - - @overload - - Parameters are similar as the constructor VideoCapture(int index),except it takes an additional argument apiPreference. - Definitely, is same as open(int index) where `index=cameraNum + apiPreference` - @return `true` if the camera has been successfully opened. - */ - CV_WRAP bool open(int cameraNum, int apiPreference); - - /** @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 - :ocvcvCloneImage 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 - :ocvcvCloneImage 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 Open video file or a capturing device or a IP video stream for video capturing with API Preference - - @overload - - Parameters are same as the constructor VideoCapture(const String& filename, int apiPreference) - @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); - -protected: - Ptr cap; - Ptr icap; -}; - -class IVideoWriter; - -/** @example 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 VFW is used; - - On MacOSX QTKit 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); - - /** @brief Writes the next video frame - - @param image The written frame - - 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(const Mat& 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); - -protected: - Ptr writer; - Ptr iwriter; - - static Ptr create(const String& filename, int fourcc, double fps, - Size frameSize, bool isColor = true); -}; - -template<> CV_EXPORTS void DefaultDeleter::operator ()(CvCapture* obj) const; -template<> CV_EXPORTS void DefaultDeleter::operator ()(CvVideoWriter* obj) const; - -//! @} videoio - -} // cv - -#endif //OPENCV_VIDEOIO_HPP diff --git a/3rdparty/libopencv/include/opencv2/videoio/cap_ios.h b/3rdparty/libopencv/include/opencv2/videoio/cap_ios.h deleted file mode 100644 index 0691420..0000000 --- a/3rdparty/libopencv/include/opencv2/videoio/cap_ios.h +++ /dev/null @@ -1,150 +0,0 @@ -/* 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; - -- (void)start; -- (void)stop; -- (void)switchCameras; - -- (id)initWithParentView:(UIView*)parent; - -- (void)createCaptureOutput; -- (void)createVideoPreviewLayer; -- (void)updateOrientation; - -- (void)lockFocus; -- (void)unlockFocus; -- (void)lockExposure; -- (void)unlockExposure; -- (void)lockBalance; -- (void)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; -- (void)layoutPreviewLayer; -- (void)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; - -- (void)takePicture; - -@end - -//! @} videoio_ios diff --git a/3rdparty/libopencv/include/opencv2/videoio/videoio.hpp b/3rdparty/libopencv/include/opencv2/videoio/videoio.hpp deleted file mode 100644 index ec84cf7..0000000 --- a/3rdparty/libopencv/include/opencv2/videoio/videoio.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/*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/3rdparty/libopencv/include/opencv2/videoio/videoio_c.h b/3rdparty/libopencv/include/opencv2/videoio/videoio_c.h deleted file mode 100644 index 32f6ec7..0000000 --- a/3rdparty/libopencv/include/opencv2/videoio/videoio_c.h +++ /dev/null @@ -1,587 +0,0 @@ -/*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" - -#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); - -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 -}; - -/** @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 ); - -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 -}; - -// Generic camera output modes. -// Currently, these are supported through the libv4l interface only. -enum -{ - CV_CAP_MODE_BGR = 0, // BGR24 (default) - CV_CAP_MODE_RGB = 1, // RGB24 - CV_CAP_MODE_GRAY = 2, // Y8 - CV_CAP_MODE_YUYV = 3 // YUYV -}; - -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. -}; - -/** @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; - -//! 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') - -/** @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/3rdparty/libopencv/include/opencv2/videostab.hpp b/3rdparty/libopencv/include/opencv2/videostab.hpp deleted file mode 100644 index ca3f5ad..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_HPP -#define OPENCV_VIDEOSTAB_HPP - -/** - @defgroup videostab Video Stabilization - -The video stabilization module contains a set of functions and classes that can be used to solve the -problem of video stabilization. There are a few methods implemented, most of them are described in -the papers @cite OF06 and @cite G11 . However, there are some extensions and deviations from the original -paper methods. - -### References - - 1. "Full-Frame Video Stabilization with Motion Inpainting" - Yasuyuki Matsushita, Eyal Ofek, Weina Ge, Xiaoou Tang, Senior Member, and Heung-Yeung Shum - 2. "Auto-Directed Video Stabilization with Robust L1 Optimal Camera Paths" - Matthias Grundmann, Vivek Kwatra, Irfan Essa - - @{ - @defgroup videostab_motion Global Motion Estimation - -The video stabilization module contains a set of functions and classes for global motion estimation -between point clouds or between images. In the last case features are extracted and matched -internally. For the sake of convenience the motion estimation functions are wrapped into classes. -Both the functions and the classes are available. - - @defgroup videostab_marching Fast Marching Method - -The Fast Marching Method @cite Telea04 is used in of the video stabilization routines to do motion and -color inpainting. The method is implemented is a flexible way and it's made public for other users. - - @} - -*/ - -#include "opencv2/videostab/stabilizer.hpp" -#include "opencv2/videostab/ring_buffer.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/deblurring.hpp b/3rdparty/libopencv/include/opencv2/videostab/deblurring.hpp deleted file mode 100644 index b383f0d..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/deblurring.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_DEBLURRING_HPP -#define OPENCV_VIDEOSTAB_DEBLURRING_HPP - -#include -#include "opencv2/core.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -CV_EXPORTS float calcBlurriness(const Mat &frame); - -class CV_EXPORTS DeblurerBase -{ -public: - DeblurerBase() : radius_(0), frames_(0), motions_(0), blurrinessRates_(0) {} - - virtual ~DeblurerBase() {} - - virtual void setRadius(int val) { radius_ = val; } - virtual int radius() const { return radius_; } - - virtual void deblur(int idx, Mat &frame) = 0; - - - // data from stabilizer - - virtual void setFrames(const std::vector &val) { frames_ = &val; } - virtual const std::vector& frames() const { return *frames_; } - - virtual void setMotions(const std::vector &val) { motions_ = &val; } - virtual const std::vector& motions() const { return *motions_; } - - virtual void setBlurrinessRates(const std::vector &val) { blurrinessRates_ = &val; } - virtual const std::vector& blurrinessRates() const { return *blurrinessRates_; } - -protected: - int radius_; - const std::vector *frames_; - const std::vector *motions_; - const std::vector *blurrinessRates_; -}; - -class CV_EXPORTS NullDeblurer : public DeblurerBase -{ -public: - virtual void deblur(int /*idx*/, Mat &/*frame*/) {} -}; - -class CV_EXPORTS WeightingDeblurer : public DeblurerBase -{ -public: - WeightingDeblurer(); - - void setSensitivity(float val) { sensitivity_ = val; } - float sensitivity() const { return sensitivity_; } - - virtual void deblur(int idx, Mat &frame); - -private: - float sensitivity_; - Mat_ bSum_, gSum_, rSum_, wSum_; -}; - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/fast_marching.hpp b/3rdparty/libopencv/include/opencv2/videostab/fast_marching.hpp deleted file mode 100644 index 43f8e4a..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/fast_marching.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_FAST_MARCHING_HPP -#define OPENCV_VIDEOSTAB_FAST_MARCHING_HPP - -#include -#include -#include -#include "opencv2/core.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab_marching -//! @{ - -/** @brief Describes the Fast Marching Method implementation. - - See http://iwi.eldoc.ub.rug.nl/FILES/root/2004/JGraphToolsTelea/2004JGraphToolsTelea.pdf - */ -class CV_EXPORTS FastMarchingMethod -{ -public: - FastMarchingMethod() : inf_(1e6f), size_(0) {} - - /** @brief Template method that runs the Fast Marching Method. - - @param mask Image mask. 0 value indicates that the pixel value must be inpainted, 255 indicates - that the pixel value is known, other values aren't acceptable. - @param inpaint Inpainting functor that overloads void operator ()(int x, int y). - @return Inpainting functor. - */ - template - Inpaint run(const Mat &mask, Inpaint inpaint); - - /** - @return Distance map that's created during working of the method. - */ - Mat distanceMap() const { return dist_; } - -private: - enum { INSIDE = 0, BAND = 1, KNOWN = 255 }; - - struct DXY - { - float dist; - int x, y; - - DXY() : dist(0), x(0), y(0) {} - DXY(float _dist, int _x, int _y) : dist(_dist), x(_x), y(_y) {} - bool operator <(const DXY &dxy) const { return dist < dxy.dist; } - }; - - float solve(int x1, int y1, int x2, int y2) const; - int& indexOf(const DXY &dxy) { return index_(dxy.y, dxy.x); } - - void heapUp(int idx); - void heapDown(int idx); - void heapAdd(const DXY &dxy); - void heapRemoveMin(); - - float inf_; - - cv::Mat_ flag_; // flag map - cv::Mat_ dist_; // distance map - - cv::Mat_ index_; // index of point in the narrow band - std::vector narrowBand_; // narrow band heap - int size_; // narrow band size -}; - -//! @} - -} // namespace videostab -} // namespace cv - -#include "fast_marching_inl.hpp" - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/fast_marching_inl.hpp b/3rdparty/libopencv/include/opencv2/videostab/fast_marching_inl.hpp deleted file mode 100644 index fdd488a..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/fast_marching_inl.hpp +++ /dev/null @@ -1,165 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_FAST_MARCHING_INL_HPP -#define OPENCV_VIDEOSTAB_FAST_MARCHING_INL_HPP - -#include "opencv2/videostab/fast_marching.hpp" - -namespace cv -{ -namespace videostab -{ - -template -Inpaint FastMarchingMethod::run(const cv::Mat &mask, Inpaint inpaint) -{ - using namespace cv; - - CV_Assert(mask.type() == CV_8U); - - static const int lut[4][2] = {{-1,0}, {0,-1}, {1,0}, {0,1}}; - - mask.copyTo(flag_); - flag_.create(mask.size()); - dist_.create(mask.size()); - index_.create(mask.size()); - narrowBand_.clear(); - size_ = 0; - - // init - for (int y = 0; y < flag_.rows; ++y) - { - for (int x = 0; x < flag_.cols; ++x) - { - if (flag_(y,x) == KNOWN) - dist_(y,x) = 0.f; - else - { - int n = 0; - int nunknown = 0; - - for (int i = 0; i < 4; ++i) - { - int xn = x + lut[i][0]; - int yn = y + lut[i][1]; - - if (xn >= 0 && xn < flag_.cols && yn >= 0 && yn < flag_.rows) - { - n++; - if (flag_(yn,xn) != KNOWN) - nunknown++; - } - } - - if (n>0 && nunknown == n) - { - dist_(y,x) = inf_; - flag_(y,x) = INSIDE; - } - else - { - dist_(y,x) = 0.f; - flag_(y,x) = BAND; - inpaint(x, y); - - narrowBand_.push_back(DXY(0.f,x,y)); - index_(y,x) = size_++; - } - } - } - } - - // make heap - for (int i = size_/2-1; i >= 0; --i) - heapDown(i); - - // main cycle - while (size_ > 0) - { - int x = narrowBand_[0].x; - int y = narrowBand_[0].y; - heapRemoveMin(); - - flag_(y,x) = KNOWN; - for (int n = 0; n < 4; ++n) - { - int xn = x + lut[n][0]; - int yn = y + lut[n][1]; - - if (xn >= 0 && xn < flag_.cols && yn >= 0 && yn < flag_.rows && flag_(yn,xn) != KNOWN) - { - dist_(yn,xn) = std::min(std::min(solve(xn-1, yn, xn, yn-1), solve(xn+1, yn, xn, yn-1)), - std::min(solve(xn-1, yn, xn, yn+1), solve(xn+1, yn, xn, yn+1))); - - if (flag_(yn,xn) == INSIDE) - { - flag_(yn,xn) = BAND; - inpaint(xn, yn); - heapAdd(DXY(dist_(yn,xn),xn,yn)); - } - else - { - int i = index_(yn,xn); - if (dist_(yn,xn) < narrowBand_[i].dist) - { - narrowBand_[i].dist = dist_(yn,xn); - heapUp(i); - } - // works better if it's commented out - /*else if (dist(yn,xn) > narrowBand[i].dist) - { - narrowBand[i].dist = dist(yn,xn); - heapDown(i); - }*/ - } - } - } - } - - return inpaint; -} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/frame_source.hpp b/3rdparty/libopencv/include/opencv2/videostab/frame_source.hpp deleted file mode 100644 index e4e00b5..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/frame_source.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_FRAME_SOURCE_HPP -#define OPENCV_VIDEOSTAB_FRAME_SOURCE_HPP - -#include -#include "opencv2/core.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -class CV_EXPORTS IFrameSource -{ -public: - virtual ~IFrameSource() {} - virtual void reset() = 0; - virtual Mat nextFrame() = 0; -}; - -class CV_EXPORTS NullFrameSource : public IFrameSource -{ -public: - virtual void reset() {} - virtual Mat nextFrame() { return Mat(); } -}; - -class CV_EXPORTS VideoFileSource : public IFrameSource -{ -public: - VideoFileSource(const String &path, bool volatileFrame = false); - - virtual void reset(); - virtual Mat nextFrame(); - - int width(); - int height(); - int count(); - double fps(); - -private: - Ptr impl; -}; - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/global_motion.hpp b/3rdparty/libopencv/include/opencv2/videostab/global_motion.hpp deleted file mode 100644 index 1fbe0c8..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/global_motion.hpp +++ /dev/null @@ -1,300 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_GLOBAL_MOTION_HPP -#define OPENCV_VIDEOSTAB_GLOBAL_MOTION_HPP - -#include -#include -#include "opencv2/core.hpp" -#include "opencv2/features2d.hpp" -#include "opencv2/opencv_modules.hpp" -#include "opencv2/videostab/optical_flow.hpp" -#include "opencv2/videostab/motion_core.hpp" -#include "opencv2/videostab/outlier_rejection.hpp" - -#ifdef HAVE_OPENCV_CUDAIMGPROC -# include "opencv2/cudaimgproc.hpp" -#endif - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab_motion -//! @{ - -/** @brief Estimates best global motion between two 2D point clouds in the least-squares sense. - -@note Works in-place and changes input point arrays. - -@param points0 Source set of 2D points (32F). -@param points1 Destination set of 2D points (32F). -@param model Motion model (up to MM_AFFINE). -@param rmse Final root-mean-square error. -@return 3x3 2D transformation matrix (32F). - */ -CV_EXPORTS Mat estimateGlobalMotionLeastSquares( - InputOutputArray points0, InputOutputArray points1, int model = MM_AFFINE, - float *rmse = 0); - -/** @brief Estimates best global motion between two 2D point clouds robustly (using RANSAC method). - -@param points0 Source set of 2D points (32F). -@param points1 Destination set of 2D points (32F). -@param model Motion model. See cv::videostab::MotionModel. -@param params RANSAC method parameters. See videostab::RansacParams. -@param rmse Final root-mean-square error. -@param ninliers Final number of inliers. - */ -CV_EXPORTS Mat estimateGlobalMotionRansac( - InputArray points0, InputArray points1, int model = MM_AFFINE, - const RansacParams ¶ms = RansacParams::default2dMotion(MM_AFFINE), - float *rmse = 0, int *ninliers = 0); - -/** @brief Base class for all global motion estimation methods. - */ -class CV_EXPORTS MotionEstimatorBase -{ -public: - virtual ~MotionEstimatorBase() {} - - /** @brief Sets motion model. - - @param val Motion model. See cv::videostab::MotionModel. - */ - virtual void setMotionModel(MotionModel val) { motionModel_ = val; } - - /** - @return Motion model. See cv::videostab::MotionModel. - */ - virtual MotionModel motionModel() const { return motionModel_; } - - /** @brief Estimates global motion between two 2D point clouds. - - @param points0 Source set of 2D points (32F). - @param points1 Destination set of 2D points (32F). - @param ok Indicates whether motion was estimated successfully. - @return 3x3 2D transformation matrix (32F). - */ - virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0) = 0; - -protected: - MotionEstimatorBase(MotionModel model) { setMotionModel(model); } - -private: - MotionModel motionModel_; -}; - -/** @brief Describes a robust RANSAC-based global 2D motion estimation method which minimizes L2 error. - */ -class CV_EXPORTS MotionEstimatorRansacL2 : public MotionEstimatorBase -{ -public: - MotionEstimatorRansacL2(MotionModel model = MM_AFFINE); - - void setRansacParams(const RansacParams &val) { ransacParams_ = val; } - RansacParams ransacParams() const { return ransacParams_; } - - void setMinInlierRatio(float val) { minInlierRatio_ = val; } - float minInlierRatio() const { return minInlierRatio_; } - - virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0); - -private: - RansacParams ransacParams_; - float minInlierRatio_; -}; - -/** @brief Describes a global 2D motion estimation method which minimizes L1 error. - -@note To be able to use this method you must build OpenCV with CLP library support. : - */ -class CV_EXPORTS MotionEstimatorL1 : public MotionEstimatorBase -{ -public: - MotionEstimatorL1(MotionModel model = MM_AFFINE); - - virtual Mat estimate(InputArray points0, InputArray points1, bool *ok = 0); - -private: - std::vector obj_, collb_, colub_; - std::vector elems_, rowlb_, rowub_; - std::vector rows_, cols_; - - void set(int row, int col, double coef) - { - rows_.push_back(row); - cols_.push_back(col); - elems_.push_back(coef); - } -}; - -/** @brief Base class for global 2D motion estimation methods which take frames as input. - */ -class CV_EXPORTS ImageMotionEstimatorBase -{ -public: - virtual ~ImageMotionEstimatorBase() {} - - virtual void setMotionModel(MotionModel val) { motionModel_ = val; } - virtual MotionModel motionModel() const { return motionModel_; } - - virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0) = 0; - -protected: - ImageMotionEstimatorBase(MotionModel model) { setMotionModel(model); } - -private: - MotionModel motionModel_; -}; - -class CV_EXPORTS FromFileMotionReader : public ImageMotionEstimatorBase -{ -public: - FromFileMotionReader(const String &path); - - virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); - -private: - std::ifstream file_; -}; - -class CV_EXPORTS ToFileMotionWriter : public ImageMotionEstimatorBase -{ -public: - ToFileMotionWriter(const String &path, Ptr estimator); - - virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); } - virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); } - - virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); - -private: - std::ofstream file_; - Ptr motionEstimator_; -}; - -/** @brief Describes a global 2D motion estimation method which uses keypoints detection and optical flow for -matching. - */ -class CV_EXPORTS KeypointBasedMotionEstimator : public ImageMotionEstimatorBase -{ -public: - KeypointBasedMotionEstimator(Ptr estimator); - - virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); } - virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); } - - void setDetector(Ptr val) { detector_ = val; } - Ptr detector() const { return detector_; } - - void setOpticalFlowEstimator(Ptr val) { optFlowEstimator_ = val; } - Ptr opticalFlowEstimator() const { return optFlowEstimator_; } - - void setOutlierRejector(Ptr val) { outlierRejector_ = val; } - Ptr outlierRejector() const { return outlierRejector_; } - - virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); - Mat estimate(InputArray frame0, InputArray frame1, bool *ok = 0); - -private: - Ptr motionEstimator_; - Ptr detector_; - Ptr optFlowEstimator_; - Ptr outlierRejector_; - - std::vector status_; - std::vector keypointsPrev_; - std::vector pointsPrev_, points_; - std::vector pointsPrevGood_, pointsGood_; -}; - -#if defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW) - -class CV_EXPORTS KeypointBasedMotionEstimatorGpu : public ImageMotionEstimatorBase -{ -public: - KeypointBasedMotionEstimatorGpu(Ptr estimator); - - virtual void setMotionModel(MotionModel val) { motionEstimator_->setMotionModel(val); } - virtual MotionModel motionModel() const { return motionEstimator_->motionModel(); } - - void setOutlierRejector(Ptr val) { outlierRejector_ = val; } - Ptr outlierRejector() const { return outlierRejector_; } - - virtual Mat estimate(const Mat &frame0, const Mat &frame1, bool *ok = 0); - Mat estimate(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, bool *ok = 0); - -private: - Ptr motionEstimator_; - Ptr detector_; - SparsePyrLkOptFlowEstimatorGpu optFlowEstimator_; - Ptr outlierRejector_; - - cuda::GpuMat frame0_, grayFrame0_, frame1_; - cuda::GpuMat pointsPrev_, points_; - cuda::GpuMat status_; - - Mat hostPointsPrev_, hostPoints_; - std::vector hostPointsPrevTmp_, hostPointsTmp_; - std::vector rejectionStatus_; -}; - -#endif // defined(HAVE_OPENCV_CUDAIMGPROC) && defined(HAVE_OPENCV_CUDAOPTFLOW) - -/** @brief Computes motion between two frames assuming that all the intermediate motions are known. - -@param from Source frame index. -@param to Destination frame index. -@param motions Pair-wise motions. motions[i] denotes motion from the frame i to the frame i+1 -@return Motion from the Source frame to the Destination frame. - */ -CV_EXPORTS Mat getMotion(int from, int to, const std::vector &motions); - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/inpainting.hpp b/3rdparty/libopencv/include/opencv2/videostab/inpainting.hpp deleted file mode 100644 index 61eeec3..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/inpainting.hpp +++ /dev/null @@ -1,212 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_INPAINTINT_HPP -#define OPENCV_VIDEOSTAB_INPAINTINT_HPP - -#include -#include "opencv2/core.hpp" -#include "opencv2/videostab/optical_flow.hpp" -#include "opencv2/videostab/fast_marching.hpp" -#include "opencv2/videostab/global_motion.hpp" -#include "opencv2/photo.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -class CV_EXPORTS InpainterBase -{ -public: - InpainterBase() - : radius_(0), motionModel_(MM_UNKNOWN), frames_(0), motions_(0), - stabilizedFrames_(0), stabilizationMotions_(0) {} - - virtual ~InpainterBase() {} - - virtual void setRadius(int val) { radius_ = val; } - virtual int radius() const { return radius_; } - - virtual void setMotionModel(MotionModel val) { motionModel_ = val; } - virtual MotionModel motionModel() const { return motionModel_; } - - virtual void inpaint(int idx, Mat &frame, Mat &mask) = 0; - - - // data from stabilizer - - virtual void setFrames(const std::vector &val) { frames_ = &val; } - virtual const std::vector& frames() const { return *frames_; } - - virtual void setMotions(const std::vector &val) { motions_ = &val; } - virtual const std::vector& motions() const { return *motions_; } - - virtual void setStabilizedFrames(const std::vector &val) { stabilizedFrames_ = &val; } - virtual const std::vector& stabilizedFrames() const { return *stabilizedFrames_; } - - virtual void setStabilizationMotions(const std::vector &val) { stabilizationMotions_ = &val; } - virtual const std::vector& stabilizationMotions() const { return *stabilizationMotions_; } - -protected: - int radius_; - MotionModel motionModel_; - const std::vector *frames_; - const std::vector *motions_; - const std::vector *stabilizedFrames_; - const std::vector *stabilizationMotions_; -}; - -class CV_EXPORTS NullInpainter : public InpainterBase -{ -public: - virtual void inpaint(int /*idx*/, Mat &/*frame*/, Mat &/*mask*/) {} -}; - -class CV_EXPORTS InpaintingPipeline : public InpainterBase -{ -public: - void pushBack(Ptr inpainter) { inpainters_.push_back(inpainter); } - bool empty() const { return inpainters_.empty(); } - - virtual void setRadius(int val); - virtual void setMotionModel(MotionModel val); - virtual void setFrames(const std::vector &val); - virtual void setMotions(const std::vector &val); - virtual void setStabilizedFrames(const std::vector &val); - virtual void setStabilizationMotions(const std::vector &val); - - virtual void inpaint(int idx, Mat &frame, Mat &mask); - -private: - std::vector > inpainters_; -}; - -class CV_EXPORTS ConsistentMosaicInpainter : public InpainterBase -{ -public: - ConsistentMosaicInpainter(); - - void setStdevThresh(float val) { stdevThresh_ = val; } - float stdevThresh() const { return stdevThresh_; } - - virtual void inpaint(int idx, Mat &frame, Mat &mask); - -private: - float stdevThresh_; -}; - -class CV_EXPORTS MotionInpainter : public InpainterBase -{ -public: - MotionInpainter(); - - void setOptFlowEstimator(Ptr val) { optFlowEstimator_ = val; } - Ptr optFlowEstimator() const { return optFlowEstimator_; } - - void setFlowErrorThreshold(float val) { flowErrorThreshold_ = val; } - float flowErrorThreshold() const { return flowErrorThreshold_; } - - void setDistThreshold(float val) { distThresh_ = val; } - float distThresh() const { return distThresh_; } - - void setBorderMode(int val) { borderMode_ = val; } - int borderMode() const { return borderMode_; } - - virtual void inpaint(int idx, Mat &frame, Mat &mask); - -private: - FastMarchingMethod fmm_; - Ptr optFlowEstimator_; - float flowErrorThreshold_; - float distThresh_; - int borderMode_; - - Mat frame1_, transformedFrame1_; - Mat_ grayFrame_, transformedGrayFrame1_; - Mat_ mask1_, transformedMask1_; - Mat_ flowX_, flowY_, flowErrors_; - Mat_ flowMask_; -}; - -class CV_EXPORTS ColorAverageInpainter : public InpainterBase -{ -public: - virtual void inpaint(int idx, Mat &frame, Mat &mask); - -private: - FastMarchingMethod fmm_; -}; - -class CV_EXPORTS ColorInpainter : public InpainterBase -{ -public: - ColorInpainter(int method = INPAINT_TELEA, double radius = 2.); - - virtual void inpaint(int idx, Mat &frame, Mat &mask); - -private: - int method_; - double radius_; - Mat invMask_; -}; - -inline ColorInpainter::ColorInpainter(int _method, double _radius) - : method_(_method), radius_(_radius) {} - -CV_EXPORTS void calcFlowMask( - const Mat &flowX, const Mat &flowY, const Mat &errors, float maxError, - const Mat &mask0, const Mat &mask1, Mat &flowMask); - -CV_EXPORTS void completeFrameAccordingToFlow( - const Mat &flowMask, const Mat &flowX, const Mat &flowY, const Mat &frame1, const Mat &mask1, - float distThresh, Mat& frame0, Mat &mask0); - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/log.hpp b/3rdparty/libopencv/include/opencv2/videostab/log.hpp deleted file mode 100644 index 81c634a..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/log.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_LOG_HPP -#define OPENCV_VIDEOSTAB_LOG_HPP - -#include "opencv2/core.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -class CV_EXPORTS ILog -{ -public: - virtual ~ILog() {} - virtual void print(const char *format, ...) = 0; -}; - -class CV_EXPORTS NullLog : public ILog -{ -public: - virtual void print(const char * /*format*/, ...) {} -}; - -class CV_EXPORTS LogToStdout : public ILog -{ -public: - virtual void print(const char *format, ...); -}; - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/motion_core.hpp b/3rdparty/libopencv/include/opencv2/videostab/motion_core.hpp deleted file mode 100644 index 4525cc7..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/motion_core.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_MOTION_CORE_HPP -#define OPENCV_VIDEOSTAB_MOTION_CORE_HPP - -#include -#include "opencv2/core.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab_motion -//! @{ - -/** @brief Describes motion model between two point clouds. - */ -enum MotionModel -{ - MM_TRANSLATION = 0, - MM_TRANSLATION_AND_SCALE = 1, - MM_ROTATION = 2, - MM_RIGID = 3, - MM_SIMILARITY = 4, - MM_AFFINE = 5, - MM_HOMOGRAPHY = 6, - MM_UNKNOWN = 7 -}; - -/** @brief Describes RANSAC method parameters. - */ -struct CV_EXPORTS RansacParams -{ - int size; //!< subset size - float thresh; //!< max error to classify as inlier - float eps; //!< max outliers ratio - float prob; //!< probability of success - - RansacParams() : size(0), thresh(0), eps(0), prob(0) {} - /** @brief Constructor - @param size Subset size. - @param thresh Maximum re-projection error value to classify as inlier. - @param eps Maximum ratio of incorrect correspondences. - @param prob Required success probability. - */ - RansacParams(int size, float thresh, float eps, float prob); - - /** - @return Number of iterations that'll be performed by RANSAC method. - */ - int niters() const - { - return static_cast( - std::ceil(std::log(1 - prob) / std::log(1 - std::pow(1 - eps, size)))); - } - - /** - @param model Motion model. See cv::videostab::MotionModel. - @return Default RANSAC method parameters for the given motion model. - */ - static RansacParams default2dMotion(MotionModel model) - { - CV_Assert(model < MM_UNKNOWN); - if (model == MM_TRANSLATION) - return RansacParams(1, 0.5f, 0.5f, 0.99f); - if (model == MM_TRANSLATION_AND_SCALE) - return RansacParams(2, 0.5f, 0.5f, 0.99f); - if (model == MM_ROTATION) - return RansacParams(1, 0.5f, 0.5f, 0.99f); - if (model == MM_RIGID) - return RansacParams(2, 0.5f, 0.5f, 0.99f); - if (model == MM_SIMILARITY) - return RansacParams(2, 0.5f, 0.5f, 0.99f); - if (model == MM_AFFINE) - return RansacParams(3, 0.5f, 0.5f, 0.99f); - return RansacParams(4, 0.5f, 0.5f, 0.99f); - } -}; - -inline RansacParams::RansacParams(int _size, float _thresh, float _eps, float _prob) - : size(_size), thresh(_thresh), eps(_eps), prob(_prob) {} - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/motion_stabilizing.hpp b/3rdparty/libopencv/include/opencv2/videostab/motion_stabilizing.hpp deleted file mode 100644 index 5ea5a65..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/motion_stabilizing.hpp +++ /dev/null @@ -1,174 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_MOTION_STABILIZING_HPP -#define OPENCV_VIDEOSTAB_MOTION_STABILIZING_HPP - -#include -#include -#include "opencv2/core.hpp" -#include "opencv2/videostab/global_motion.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab_motion -//! @{ - -class CV_EXPORTS IMotionStabilizer -{ -public: - virtual ~IMotionStabilizer() {} - - //! assumes that [0, size-1) is in or equals to [range.first, range.second) - virtual void stabilize( - int size, const std::vector &motions, std::pair range, - Mat *stabilizationMotions) = 0; -}; - -class CV_EXPORTS MotionStabilizationPipeline : public IMotionStabilizer -{ -public: - void pushBack(Ptr stabilizer) { stabilizers_.push_back(stabilizer); } - bool empty() const { return stabilizers_.empty(); } - - virtual void stabilize( - int size, const std::vector &motions, std::pair range, - Mat *stabilizationMotions); - -private: - std::vector > stabilizers_; -}; - -class CV_EXPORTS MotionFilterBase : public IMotionStabilizer -{ -public: - virtual ~MotionFilterBase() {} - - virtual Mat stabilize( - int idx, const std::vector &motions, std::pair range) = 0; - - virtual void stabilize( - int size, const std::vector &motions, std::pair range, - Mat *stabilizationMotions); -}; - -class CV_EXPORTS GaussianMotionFilter : public MotionFilterBase -{ -public: - GaussianMotionFilter(int radius = 15, float stdev = -1.f); - - void setParams(int radius, float stdev = -1.f); - int radius() const { return radius_; } - float stdev() const { return stdev_; } - - virtual Mat stabilize( - int idx, const std::vector &motions, std::pair range); - -private: - int radius_; - float stdev_; - std::vector weight_; -}; - -inline GaussianMotionFilter::GaussianMotionFilter(int _radius, float _stdev) { setParams(_radius, _stdev); } - -class CV_EXPORTS LpMotionStabilizer : public IMotionStabilizer -{ -public: - LpMotionStabilizer(MotionModel model = MM_SIMILARITY); - - void setMotionModel(MotionModel val) { model_ = val; } - MotionModel motionModel() const { return model_; } - - void setFrameSize(Size val) { frameSize_ = val; } - Size frameSize() const { return frameSize_; } - - void setTrimRatio(float val) { trimRatio_ = val; } - float trimRatio() const { return trimRatio_; } - - void setWeight1(float val) { w1_ = val; } - float weight1() const { return w1_; } - - void setWeight2(float val) { w2_ = val; } - float weight2() const { return w2_; } - - void setWeight3(float val) { w3_ = val; } - float weight3() const { return w3_; } - - void setWeight4(float val) { w4_ = val; } - float weight4() const { return w4_; } - - virtual void stabilize( - int size, const std::vector &motions, std::pair range, - Mat *stabilizationMotions); - -private: - MotionModel model_; - Size frameSize_; - float trimRatio_; - float w1_, w2_, w3_, w4_; - - std::vector obj_, collb_, colub_; - std::vector rows_, cols_; - std::vector elems_, rowlb_, rowub_; - - void set(int row, int col, double coef) - { - rows_.push_back(row); - cols_.push_back(col); - elems_.push_back(coef); - } -}; - -CV_EXPORTS Mat ensureInclusionConstraint(const Mat &M, Size size, float trimRatio); - -CV_EXPORTS float estimateOptimalTrimRatio(const Mat &M, Size size); - -//! @} - -} // namespace videostab -} // namespace - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/optical_flow.hpp b/3rdparty/libopencv/include/opencv2/videostab/optical_flow.hpp deleted file mode 100644 index d631488..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/optical_flow.hpp +++ /dev/null @@ -1,150 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_OPTICAL_FLOW_HPP -#define OPENCV_VIDEOSTAB_OPTICAL_FLOW_HPP - -#include "opencv2/core.hpp" -#include "opencv2/opencv_modules.hpp" - -#ifdef HAVE_OPENCV_CUDAOPTFLOW - #include "opencv2/cudaoptflow.hpp" -#endif - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -class CV_EXPORTS ISparseOptFlowEstimator -{ -public: - virtual ~ISparseOptFlowEstimator() {} - virtual void run( - InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1, - OutputArray status, OutputArray errors) = 0; -}; - -class CV_EXPORTS IDenseOptFlowEstimator -{ -public: - virtual ~IDenseOptFlowEstimator() {} - virtual void run( - InputArray frame0, InputArray frame1, InputOutputArray flowX, InputOutputArray flowY, - OutputArray errors) = 0; -}; - -class CV_EXPORTS PyrLkOptFlowEstimatorBase -{ -public: - PyrLkOptFlowEstimatorBase() { setWinSize(Size(21, 21)); setMaxLevel(3); } - - virtual void setWinSize(Size val) { winSize_ = val; } - virtual Size winSize() const { return winSize_; } - - virtual void setMaxLevel(int val) { maxLevel_ = val; } - virtual int maxLevel() const { return maxLevel_; } - virtual ~PyrLkOptFlowEstimatorBase() {} - -protected: - Size winSize_; - int maxLevel_; -}; - -class CV_EXPORTS SparsePyrLkOptFlowEstimator - : public PyrLkOptFlowEstimatorBase, public ISparseOptFlowEstimator -{ -public: - virtual void run( - InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1, - OutputArray status, OutputArray errors); -}; - -#ifdef HAVE_OPENCV_CUDAOPTFLOW - -class CV_EXPORTS SparsePyrLkOptFlowEstimatorGpu - : public PyrLkOptFlowEstimatorBase, public ISparseOptFlowEstimator -{ -public: - SparsePyrLkOptFlowEstimatorGpu(); - - virtual void run( - InputArray frame0, InputArray frame1, InputArray points0, InputOutputArray points1, - OutputArray status, OutputArray errors); - - void run(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, const cuda::GpuMat &points0, cuda::GpuMat &points1, - cuda::GpuMat &status, cuda::GpuMat &errors); - - void run(const cuda::GpuMat &frame0, const cuda::GpuMat &frame1, const cuda::GpuMat &points0, cuda::GpuMat &points1, - cuda::GpuMat &status); - -private: - Ptr optFlowEstimator_; - cuda::GpuMat frame0_, frame1_, points0_, points1_, status_, errors_; -}; - -class CV_EXPORTS DensePyrLkOptFlowEstimatorGpu - : public PyrLkOptFlowEstimatorBase, public IDenseOptFlowEstimator -{ -public: - DensePyrLkOptFlowEstimatorGpu(); - - virtual void run( - InputArray frame0, InputArray frame1, InputOutputArray flowX, InputOutputArray flowY, - OutputArray errors); - -private: - Ptr optFlowEstimator_; - cuda::GpuMat frame0_, frame1_, flowX_, flowY_, errors_; -}; - -#endif - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/outlier_rejection.hpp b/3rdparty/libopencv/include/opencv2/videostab/outlier_rejection.hpp deleted file mode 100644 index 9b9b384..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/outlier_rejection.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_OUTLIER_REJECTION_HPP -#define OPENCV_VIDEOSTAB_OUTLIER_REJECTION_HPP - -#include -#include "opencv2/core.hpp" -#include "opencv2/videostab/motion_core.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -class CV_EXPORTS IOutlierRejector -{ -public: - virtual ~IOutlierRejector() {} - - virtual void process( - Size frameSize, InputArray points0, InputArray points1, OutputArray mask) = 0; -}; - -class CV_EXPORTS NullOutlierRejector : public IOutlierRejector -{ -public: - virtual void process( - Size frameSize, InputArray points0, InputArray points1, OutputArray mask); -}; - -class CV_EXPORTS TranslationBasedLocalOutlierRejector : public IOutlierRejector -{ -public: - TranslationBasedLocalOutlierRejector(); - - void setCellSize(Size val) { cellSize_ = val; } - Size cellSize() const { return cellSize_; } - - void setRansacParams(RansacParams val) { ransacParams_ = val; } - RansacParams ransacParams() const { return ransacParams_; } - - virtual void process( - Size frameSize, InputArray points0, InputArray points1, OutputArray mask); - -private: - Size cellSize_; - RansacParams ransacParams_; - - typedef std::vector Cell; - std::vector grid_; -}; - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/ring_buffer.hpp b/3rdparty/libopencv/include/opencv2/videostab/ring_buffer.hpp deleted file mode 100644 index 55d5244..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/ring_buffer.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_RING_BUFFER_HPP -#define OPENCV_VIDEOSTAB_RING_BUFFER_HPP - -#include -#include "opencv2/imgproc.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -template inline T& at(int idx, std::vector &items) -{ - return items[cv::borderInterpolate(idx, static_cast(items.size()), cv::BORDER_WRAP)]; -} - -template inline const T& at(int idx, const std::vector &items) -{ - return items[cv::borderInterpolate(idx, static_cast(items.size()), cv::BORDER_WRAP)]; -} - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/stabilizer.hpp b/3rdparty/libopencv/include/opencv2/videostab/stabilizer.hpp deleted file mode 100644 index b78b4ea..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/stabilizer.hpp +++ /dev/null @@ -1,200 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_STABILIZER_HPP -#define OPENCV_VIDEOSTAB_STABILIZER_HPP - -#include -#include -#include "opencv2/core.hpp" -#include "opencv2/imgproc.hpp" -#include "opencv2/videostab/global_motion.hpp" -#include "opencv2/videostab/motion_stabilizing.hpp" -#include "opencv2/videostab/frame_source.hpp" -#include "opencv2/videostab/log.hpp" -#include "opencv2/videostab/inpainting.hpp" -#include "opencv2/videostab/deblurring.hpp" -#include "opencv2/videostab/wobble_suppression.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -class CV_EXPORTS StabilizerBase -{ -public: - virtual ~StabilizerBase() {} - - void setLog(Ptr ilog) { log_ = ilog; } - Ptr log() const { return log_; } - - void setRadius(int val) { radius_ = val; } - int radius() const { return radius_; } - - void setFrameSource(Ptr val) { frameSource_ = val; } - Ptr frameSource() const { return frameSource_; } - - void setMotionEstimator(Ptr val) { motionEstimator_ = val; } - Ptr motionEstimator() const { return motionEstimator_; } - - void setDeblurer(Ptr val) { deblurer_ = val; } - Ptr deblurrer() const { return deblurer_; } - - void setTrimRatio(float val) { trimRatio_ = val; } - float trimRatio() const { return trimRatio_; } - - void setCorrectionForInclusion(bool val) { doCorrectionForInclusion_ = val; } - bool doCorrectionForInclusion() const { return doCorrectionForInclusion_; } - - void setBorderMode(int val) { borderMode_ = val; } - int borderMode() const { return borderMode_; } - - void setInpainter(Ptr val) { inpainter_ = val; } - Ptr inpainter() const { return inpainter_; } - -protected: - StabilizerBase(); - - void reset(); - Mat nextStabilizedFrame(); - bool doOneIteration(); - virtual void setUp(const Mat &firstFrame); - virtual Mat estimateMotion() = 0; - virtual Mat estimateStabilizationMotion() = 0; - void stabilizeFrame(); - virtual Mat postProcessFrame(const Mat &frame); - void logProcessingTime(); - - Ptr log_; - Ptr frameSource_; - Ptr motionEstimator_; - Ptr deblurer_; - Ptr inpainter_; - int radius_; - float trimRatio_; - bool doCorrectionForInclusion_; - int borderMode_; - - Size frameSize_; - Mat frameMask_; - int curPos_; - int curStabilizedPos_; - bool doDeblurring_; - Mat preProcessedFrame_; - bool doInpainting_; - Mat inpaintingMask_; - Mat finalFrame_; - std::vector frames_; - std::vector motions_; // motions_[i] is the motion from i-th to i+1-th frame - std::vector blurrinessRates_; - std::vector stabilizedFrames_; - std::vector stabilizedMasks_; - std::vector stabilizationMotions_; - clock_t processingStartTime_; -}; - -class CV_EXPORTS OnePassStabilizer : public StabilizerBase, public IFrameSource -{ -public: - OnePassStabilizer(); - - void setMotionFilter(Ptr val) { motionFilter_ = val; } - Ptr motionFilter() const { return motionFilter_; } - - virtual void reset(); - virtual Mat nextFrame() { return nextStabilizedFrame(); } - -protected: - virtual void setUp(const Mat &firstFrame); - virtual Mat estimateMotion(); - virtual Mat estimateStabilizationMotion(); - virtual Mat postProcessFrame(const Mat &frame); - - Ptr motionFilter_; -}; - -class CV_EXPORTS TwoPassStabilizer : public StabilizerBase, public IFrameSource -{ -public: - TwoPassStabilizer(); - - void setMotionStabilizer(Ptr val) { motionStabilizer_ = val; } - Ptr motionStabilizer() const { return motionStabilizer_; } - - void setWobbleSuppressor(Ptr val) { wobbleSuppressor_ = val; } - Ptr wobbleSuppressor() const { return wobbleSuppressor_; } - - void setEstimateTrimRatio(bool val) { mustEstTrimRatio_ = val; } - bool mustEstimateTrimaRatio() const { return mustEstTrimRatio_; } - - virtual void reset(); - virtual Mat nextFrame(); - -protected: - void runPrePassIfNecessary(); - - virtual void setUp(const Mat &firstFrame); - virtual Mat estimateMotion(); - virtual Mat estimateStabilizationMotion(); - virtual Mat postProcessFrame(const Mat &frame); - - Ptr motionStabilizer_; - Ptr wobbleSuppressor_; - bool mustEstTrimRatio_; - - int frameCount_; - bool isPrePassDone_; - bool doWobbleSuppression_; - std::vector motions2_; - Mat suppressedFrame_; -}; - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/include/opencv2/videostab/wobble_suppression.hpp b/3rdparty/libopencv/include/opencv2/videostab/wobble_suppression.hpp deleted file mode 100644 index a44410b..0000000 --- a/3rdparty/libopencv/include/opencv2/videostab/wobble_suppression.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/*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-2011, 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_VIDEOSTAB_WOBBLE_SUPPRESSION_HPP -#define OPENCV_VIDEOSTAB_WOBBLE_SUPPRESSION_HPP - -#include -#include "opencv2/core.hpp" -#include "opencv2/core/cuda.hpp" -#include "opencv2/videostab/global_motion.hpp" -#include "opencv2/videostab/log.hpp" - -namespace cv -{ -namespace videostab -{ - -//! @addtogroup videostab -//! @{ - -class CV_EXPORTS WobbleSuppressorBase -{ -public: - WobbleSuppressorBase(); - - virtual ~WobbleSuppressorBase() {} - - void setMotionEstimator(Ptr val) { motionEstimator_ = val; } - Ptr motionEstimator() const { return motionEstimator_; } - - virtual void suppress(int idx, const Mat &frame, Mat &result) = 0; - - - // data from stabilizer - - virtual void setFrameCount(int val) { frameCount_ = val; } - virtual int frameCount() const { return frameCount_; } - - virtual void setMotions(const std::vector &val) { motions_ = &val; } - virtual const std::vector& motions() const { return *motions_; } - - virtual void setMotions2(const std::vector &val) { motions2_ = &val; } - virtual const std::vector& motions2() const { return *motions2_; } - - virtual void setStabilizationMotions(const std::vector &val) { stabilizationMotions_ = &val; } - virtual const std::vector& stabilizationMotions() const { return *stabilizationMotions_; } - -protected: - Ptr motionEstimator_; - int frameCount_; - const std::vector *motions_; - const std::vector *motions2_; - const std::vector *stabilizationMotions_; -}; - -class CV_EXPORTS NullWobbleSuppressor : public WobbleSuppressorBase -{ -public: - virtual void suppress(int idx, const Mat &frame, Mat &result); -}; - -class CV_EXPORTS MoreAccurateMotionWobbleSuppressorBase : public WobbleSuppressorBase -{ -public: - virtual void setPeriod(int val) { period_ = val; } - virtual int period() const { return period_; } - -protected: - MoreAccurateMotionWobbleSuppressorBase() { setPeriod(30); } - - int period_; -}; - -class CV_EXPORTS MoreAccurateMotionWobbleSuppressor : public MoreAccurateMotionWobbleSuppressorBase -{ -public: - virtual void suppress(int idx, const Mat &frame, Mat &result); - -private: - Mat_ mapx_, mapy_; -}; - -#if defined(HAVE_OPENCV_CUDAWARPING) -class CV_EXPORTS MoreAccurateMotionWobbleSuppressorGpu : public MoreAccurateMotionWobbleSuppressorBase -{ -public: - void suppress(int idx, const cuda::GpuMat &frame, cuda::GpuMat &result); - virtual void suppress(int idx, const Mat &frame, Mat &result); - -private: - cuda::GpuMat frameDevice_, resultDevice_; - cuda::GpuMat mapx_, mapy_; -}; -#endif - -//! @} - -} // namespace videostab -} // namespace cv - -#endif diff --git a/3rdparty/libopencv/libs/libopencv_core.so b/3rdparty/libopencv/libs/libopencv_core.so deleted file mode 120000 index 9e41d35..0000000 --- a/3rdparty/libopencv/libs/libopencv_core.so +++ /dev/null @@ -1 +0,0 @@ -libopencv_core.so.3.4 \ No newline at end of file diff --git a/3rdparty/libopencv/libs/libopencv_core.so.3.4 b/3rdparty/libopencv/libs/libopencv_core.so.3.4 deleted file mode 100644 index ed138511231934126b9a641cfeb493e49419e382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3155120 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 z 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 yu2a?H+A0f#cX&96ts;C9 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 #wcsZtX;nh5w|s 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 R1i_ip{O2U8oUR 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

Wa;sV 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

r4spK3 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

1b8INGvscI;uWc`k4__T|CvNxm4qx58C~$Ql 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%0AP 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�B;NyRzDLqQFaZydo8VLYwKL++0d*q%LhcCTF)7hhXuC{{4LQf7 zK-2Mc=oGBWYyK$J*DK+M4r<*C(uS06F!Jnk?|SR@!zoz6a@_S^Zv6{r_#?`t*0v|B*kG9q00SBtL40pK#Bs>hUxLyum-!_HN)w*&cQD z9@p<7>oXg8dq*4@ftL+{JEEdo^V!jqFG}FC@9zQb2yjJz`Q@8Aw>fPqx;)!0YUft< z=Dq(V3Svh?$k69|^K9y81xbr^PE-VJYh zW?k=pl!D(6(sr)^(ij0OkpY_oY$yXZ2iRx^Y#FeL44Cl-tX}~u1aE$rMgd@RfKit7 zLs$u5tAOnlh=%P2EI5k#^T6r>+Y6Yh>yx$#ur|Qp5k)?nlTQM+_(LaM=d1*AI{;q> zd{m>#dEi07;(vxQ=#l4go(QW~saQQpye}=H*<1u_S+WTFlm96t*WLY;lwTN`6GSdZ z+i3gO%~=1ArETfVTPa`xz>YY1WBsrkM*v$ySiSg0wz=@f{rHqEmwjUZc*TE?JfI9} zLhwYU$(>&uh?dPAT@E?_t%Kt6Q3pK}5a-nu@EiQkPP(x)Kg=6)mFIM=;1x(Der0Jj;qvy>ST!Ik+*&b-UrXy@3HM}MvWT?goj z{|juzEbrTd&Xt?_2Pij>y!b-;5V$)i?&H9VzK9D6oJ(fG~q&M14Y5*{roBzJ~* zO1qNBw0Ry{u1xV7QU8U;tCQeUbPM#6|8{2M7|Re8J~Q%uO{n{_uELPL^TGHfJ(ouM zcJ&rKD`ILNgp_-V3%PL(Sel5>-SFKTzIbErgvV!jYZ?qfWPmgEWF}$OLmX)@PeN|7 z3_mVs{}{k}j53bbj(F=xE+RQMk1n`T#ql->0d;f=wr<`3)8`m7&Tlob8oe8epk+N4 zfxh8KXEs{1k%wl5m;f!?8zIaW=^)gP7bi%1{CN1*Bat>#U(;lJ*4V ziket;S5<5$Jfdj{Kb~4JdlQiMm z0eNi674;D8lvTyIVg3J;&9aJlIstwwfMbDEcO9uG3{AJAi!UVV zIxXP6{0j6Ogx&cf1YfB%JcWC#`cvWbKu#HHiTWoLzX30{^<5ndrd;yj%>e_Btd=pe7U2&!fQ1sAq3H<&*C`D#ld zzcA$-C*Cx61Zd#-3m5IZ+K^D_7;lzmC? zI&wq3!)D*N%}D3>&Di&Fe0jv|{!=q-519|gzhm}%*9;}TY4(51wB7+}KaV&0#Coo; z1Vj)GB*X&e!>8s>&+kje=6B?3mYSnR)oE!0CPA9YoJ|SQd08f4({G$7L0Km6fd0Os z^(6KFO=V8qV-x!sy`MAtK5O>3 zn~Beu_NPtjQ<;(y@7$*55a*Tz`&c9RH?29g3H^o6CWx)?XXX1kx`DuEFs+eusB#IA;s>T4)k@fqy+C?>VTy+Jq+)D)Y)bE(31~ zcuNSY|FH>=mTnO*Y_kI7apd1nhfMcJf|r&pTt-u*c-pKUG&P{9GtO=VE(gu8gk~it z)blMf{!I*|VY3^@OoMNd zeeREhPTR9+m6G)WR>OLm$z3tXICOuo{$g*&dNFub`?JAsj^PFH9R;kN`SE9zG3~2I z!C!}^eZFZ*0rYssx8J$-IcRGCg-FYNW#o^|bZGJjWl?o;U}MRgsX zKst@UZDO98z;C8s0N8QBMkzygNcs!ek)Afwe%=gswwtlfz$gEw&F)W` z)>Ao@1CG28g0}FFkpA^&H=PTsg`XZrR7&663!LB$XI(q5^bg#ZaE~GhP9t#k0;dK% zUD>-Y1E&=@M}fnB=i+$%%S8bm0!}M%+B`TBxG?Rqs#5DS$-r-UQ-Jlf0zT8=BjXUi z2~&4No@T%b0aGPsQ}zyy`%=Kl06T&(@+spUvxD5@4+2z&_~VH8mIL*Xsx!6;%h3*; z7WRqm+fs8u#B=W(rpLzg4W23l^_vvK;6HQY+0>mG=6wRNWx&c1=7+FZz_M@JjJE_> zF<`7qeu%dYSR-Hz^TYpvw?N)yz={ED08C_)gI5mNA;36h_$kF-9bm@+TPFZdZdjcq zu^TGw-J-d2@~ZB-{ywL*SQn#6zvA_0Hx>|9U%oX}7h-cq2k?wjQD5Eh!M0lg?ILIs zr2Rme7N%X>_ox<1Wr!{nndEjId2OqX`6JT?IO%dS8!2LKv(v=1G2JQkg z8dh}F8{4#TVc7SK`o6qWV=YJtQ-ToqWA`T$-%i_EtaJZjAX2Ir{Cd-@v->u;fa6SFro)DDSn)we~AApMnN0=_io?yyzd+_7$Kn z2mLbWWj^|jq%XRX=qR?5+rql(J=>)oZRH4fG=oP;6?9bg*%sm9$k?7he0!7*5vuH* zNcWDeoz?WV(1Z({`e-G+4WTDEPm&Xx$PR9Zxa^3 zcUJphcKtgIjF2@AYpRd#Hx2YUZvR=I$PoNwWyt-viq8!=Pu&>^8 zcHsV4u8G(|T@HGzupU53aM&3P*qvXkD2Z$A;Bnf`?qg}fq`aR$_qioT zN+P>kk#@5F?8cmyUm_{8DuBbeLiwaaSnK=`!KO;Yea`=g^Pe&_fdf$^ zk2-zSwOergCC?>mF-94-j`G$tVa`w}@AXn%uWiP4j{sYb)17pE8bQz+`>@_Wde+^4 zb=Q}v`HK9HARkHK%+W@V|R9CXSum806U9ioAvM zCrYB7ZT{Hve)~E9<4{+`JrQvyfg5}hb3Jj_BptUe*uKZX+>zXMz#T)ri{A%*R`(e# zcWqUjvUNwei+xl&Dy+zQ;&yD}-c4*9bruA_>{{?U?&$ljK&rBLx{DdkEv3Mz01n4} zN@zv8cG^4A3(#7fOX=4!cpQ3wZ4`gg zpgZ~0*^MFALy6RblrO}>g=ol!RrO((?`zWhXvBFnCZ$nMZyXo<5tp z+eX+5V0kAp)<63pUo&8ZfJFgge)u76DPS#t6$wPcDgbNGpgjcG5MVOD0+;v$NOu;n zLWI@P8(9~yt?7FWI5pJ91`TgWlD zw}fL(Z$C!3{}|>5WVpA$-etXO)1afR-8%$DFD*hEbIq`wP$!BCFB!k0=g7O6Fv*CO z-j#Tp9FYo-M(`;981xJ@klG_WCVZXcvAd#OcXr=V*|R5pd+%+1xAvDMZn1B+zMfen zvJMyo591S_rQ~GC&_>#rsQna0%-TNVxD6eN+o^0cNcN|p4dC+VbfKN zKjI1VjGzmbzOs4%_J-%qZp3k34E5TwHPq8?#y?$5#r zNt>B?-o#t2*13z=H@Sw0-UI#lGiWR1jqN1UdX%$VR8QCTb>iRD+c50k&7d3jEY_yF zf2Zwam3EeAw@1d$0`ffjIgAC+sfrsm`OR(t%mA-~&+GoG$`FtBx7k@3yDZXmY4;^z zJHI-#-;Um$5qZ)=Z>`}8qoAik@2XWx$gKw`U{|F~R!aDU&YkDFJL zUx@rdYNHoAOARJ&5=P#E;Mi@(kip_ggAEkH_BE^!4Iz2w49G?;QfIwyc&IERq{WbaiecSxCdH(&mKEnjJl)%7=+x_WcNn6M2 zA^*Sc$ZeUk?A&{tb6m{xDB|b#yt2`#`&)VpRnkc<9`u2R@Tqi$L7{D^%b;rn-&Nh; z+__csEQ?c^qYtug79PZS8--qQFTEIIF@Q z4jxV5G4PjI)8>Ik5IiuSUlZz#t5}b!>F-d9&#S7gZq?nTdSWWxsd~St`n~`c-k(#x zn>KZ0%~E)dfoIV)Wb;<=ED@d~;MuKW@B!WxQ{C_Z-t$Ej|AMOO?NEK6SN)$;iO+&* zyYhYYf*uV!6Y`mNAMAB6!2ZX2ze>uQzPl4~{Al)Vfy8aj;R`VjTheJ&r7wEfTX-@nJ$z){Is&@YmmNFD(r(HE zk38>zPIU}KuGnV2+_2uKTOs{v=#?n18W(ykKkaOBdBrLYB5vV+tgq*xOCgLjTpYR+ z}=u-0i<0~9QCa^{Z9HwY7H0Zdd}bdNfe>g-;}=2ij%pi z-6TC;S&k$BG63@vbe*ShXr8OOh6UAI7fTh{bG z&PCRBL8Pe~Fy8`){RwI6c>#Xm+_hf|z>VM&1CET7YH8b+kK>ruX9HcI3v_k_VxJF$ z;-3lhv>50=8${+QuUL6+XrI%R3DFbzn`uN95WYa6xpAOr1F^0K7fGYumLZcVtM*Fqx(`MP)0BbEm9xtSS>kHONrTJYb@>j3id4)98qhIujGiuLRDYua}|ezG1404pz96W`>h zV@VX}MXax-DD{1jy}+Be3H88q4(WZ1T3QRk)WhIK!5q643Bd+ zfxHd8if>*MU$JX+N^J&^6;P=iHjz% zTKV_+{WVz!v-aVdNGj6kK$=Yt!+vzz+QzDuVS0SQZqmIYOr z_tZWi9OONnjw6uwYi?@#M`$Ou8_M=hctLBf^ z+_^glr9h-p0pey5H+}corgJo0n+5@&1l*wR^j}|R8rFNYvVe_H##bPIutM`xKV8BLa8rB>;$x9D@x!aW#P~;3@nzsYfcQg|Yx-Qw7Z9J`KNY(+3m`8n zIdYbHngva;TFY(qe)4=c#gj6374Z`_Ya8>B>*}2@Puu^bvj_aN^IyvUHtcuQLQWF* z0C~MF#f$l?KzwoCn%3h(F0U9Sb|va4vqk%^I}ecO3D6k#tZkIAPOl-)XHq!`VW}?I_v4I z16g%OGs}spYSI#q#g}iRG`GxBLfATmE}qw*2?LWchyT^QvRW#=Ti}NY=Ad zXFuHAi1G1$=rjl;?UX%}b<=>j7~(jeFphVz+%sa-KSxkEgNWxiQ-3dcPp>(uY$XQ+ z9RbK{*Fos(z+VP!_EQe+H(on!6tpGC*D=seu+5rsndV3}j$VKziPk{@3gWLGIC&?Xd^GK`33*#)1cS0{1hAqnt;yMEqOx8l z0ZRfl?xCFnY|utqJAF*rAFzclgO>V?>_0gT|B!C@I;Z{Fu7&Rc{Z}F1*r%)?rP?)! zpL-Cu^bKdtVTs^>0R8A;B2^+loCe^;zJ+qLuY8m-Pax(H1Ce~=6{8j4QRJuoJJ30h zhI;HW&R^O-T4fi==>_)9NcWXpMUnXBJy(Rpu9>(5rqce@auW9!^cn!lv2#adzGkz@ zG;zrX+?a4?jO10l8}0kOHNDqmeVlo$O_c|kWgV9Q=g{by>_6bAr*{~h_ycwypjI{z6ly8V&29dSg_Eo8Jg}QflUC#$`x~}iu z&9}qDxsmvFJ;kBEYkIE@C9dudT7Tm$C5*_-!*Qf{WFno1BY?F6HU(Icea(4G>40lL zwYR*VQ=_{xSKFKY?wpsxx%a;0wUo8;r#JgPV%5CFzPt$jNB;`zdh)k^E`1Q~ zEB?-n$8mn;M_6xgFUA3y2+S6~td=y367hTS6U-aUA?8RZ} z#c$1MU#46C1lo7*;`w4*A4mK##1B(pfvrjW!`9L@EIq^0PptM1>zqwV+w^3A#=Fb> zVYY%7AaAhDfdBZy+D4o1OWLNs-@V_+mm&Btgq`=nOlmpa{XAwBrMXzX^hx6X>ez`~V z8RxWy_URV|Udt~rzh8!N|IALxvkBQl75h4j@bO)hc77H2Jj1ew`Y&=lF`aD}|H3U) z-|ZGnFd{wNx_Q>!QT6#H@}T?sUZURT{yM^KEIyHjBSWX>_o6(@$mdBTsr})d+QEG4 zwFB+zl{7$c_28PXX-;v&7+;_-JqCFL`fMnNYDnl?#LsUfUHn3LS5sX3vdx^7#K!5U z@27tF?lon#FL&qAW*00|o~4&yYgSA)*4t0b9pvx&Q*-yre*xcfYOb2U=q!_Enn0eS z1x}fYe!nu2-gqzOThPy-U#fq?&Vjd1#Bm4=HR+1r#!aeHNM8Z^;zB3=A7;@1jyffM z3+PXPz8K?9J?Eikb6{WA_I=Eg?1^q38Q8 zUom5UVn(|L%MDl3CT8F#Gz={ysC&Yua(sn)EJpDb=9{xpF|8s_VhN5&Q>( z$&DtK?^oM1#zs{SkD^e7xRojF!eg2 z4z%SZ$&KTf_f(~)tTkQOe|}FYLF$wzf!ll|#u9NW1Xr(XYj`e^{z ze^27}D*HBn&8^nIcsaRexP#zz;{DK{%ai(CnzKf(vMqf^5Am$mIB?V(9URA(jm+=R z+i6R2?>9t&yNq`#(V5+g#&qY2_q}g#d#vsf1 zwD1wdO18`^sb1l+9(#+$(VM2+%!hT=4nA|y7NJXHToI2l;m^W z2jR_>|LggH9sXNM?n5EKH0z$i{L+xzm|~irkTi9lj?hLd#^_p_*6kc|<>u*g7o>?d z@hnLbwrfcf|0PZQ*J&a!h%_gV=IlF@8ZWN(j6s3X`rgjvCi*O78TmR%9V-l%nf{u~t-pt%9{=yns(}gY@@KPZstElDN#kep zr>(!%5y&I+dGu+X*Gq29F`v)mu|2d7C;5z|^11KdDW5;PNIq$A3!H#{`?;jp9@ME^ z=2K)QOp7V~iMkl&Wj+2XfZqiCMTK(xso;;~Mmzt^jQtQN;YQ8wADBJgH{;(kdq>Q^ zKgFrI@0yA4nD($~{cYxS0d88pANc^3>&|5A-YwT6#{tW8VIG@l0CDYz3m^_vD<8rJ z04vIXjRIBzSh0f_~TqWGHyYznXr0#Y_ev#QIgPTgpd zjQy6olI%l=z$Xw(iY-w6d@IY7-fxCKL^){V7^azi-7_dZ@bj21K5Xwsz}f*LKjsBT zw587xzZr1@h;#GK{~drO0CUS-2G~6E5eF=RuzHW=L$VLMYHB&|eVd1EIR`$fD>cVR zTf1lIm`)P$#fZ;Fm>|_S)C}1Z%Fs9iI*m1y?XkUO&dd}-^8?ihI#8>nuHx>}4-V+RUwyM}CRK)&c z#XT-LM}a7oWeT{fz%3&$_x`(${)?ZBh|B)c=6ojsQyH+l4?$jKz=D9SC(`vsetQ5* z0v1G=pCJBf03*L61h{*99MiajLk+MD;6auLI86wv-(;m^G7jR&CN8xtSv_mDOKjT% z;M)wE8qHVg$n~S>+B>BDz#9Z!G4aH9{`YHjezyo8NdjSgoCjCd!6w|ltQFS0q;!mT)sjH=|T5kzaWxQXxW82Ao-WpnyNfDHoX_Fv|69I$~5ycxg}8F-6;#WP?@z+xWSAo%4qLw*4k zLl|x7%9uuHnv}XJ15VyoH|H%1STlVCzV8uTE3i*PXLi z#sS0^W$+mVtS|#M1y})KZXTLITL4&qcsyJBW5xcqqC)icFK++&2ms#zh-laUKK}*B zNiTG$_H5>4UygK|kImZ>f&BQ6qhCn>!=4M^d4Qh;e4g_8Tf$T8ua!K10j>3k z)DemhUu~{&tr;oj>z?Bpn~w&ItT_h$$&sXfv+SMVzmI*z_OU(dKZ^aB@1}+)&r|&2Bg|>iw?S_Z_pcbJUFe zzzp|{m~m=j!)D^!aKiE}^TU}91b#>H7eu~dKfrpJJpYG}ZRDPwhg_;$4`4_6E1JSWI_wYaNNebaNx4(4z9MPOh`+t`-IWOMt~{C1 zrmT}G&@TU3a$|t`Y!_PnW_h@`yzee~xI7{cm-pY9xC4&7p9YVN<*J;g3Ve+Af5#s5 zZsDVCp&{Br!+fVDY;ThnTv%GI#T@F}-W#ZT`K3qsAO80v{2%Ji$9eOd{`~sfy8isy z)6xF?2eD{^;!Hj4B+?lkPi{bc#+x^ij$Z49Qa(iOJS)Onx^_RK0dymvTm3K2x_rMk zf8D#f3PSRZubtn-3><#>r9)^Gc251E?E#u`57I1{d%(%$+i(DjxMEA1g;9Ixzv?lS zYUhji+LKk$=B2*S*MUC%-_XBVrhm5BSG4Sw6B}A|_igRxQkdQlHrcYa)*n>b0}ECYvap+20( zaecxPr|9F5&wu6Q=izi(-uzSmrvNyTpEsv*-24=SPZMy0z^Oo3T`4#+N5EA@EgFYQ zDd`jKz$*uy_;)A7eh8`or3tb6(yjF#r81xv@;!zT@al?y`sJLqOg^$7w07l6_BS)o}6X zuDvhf6wg*bvugBNKo{?#=XABl#S}{JVcz@)fBZu>iZL(Dqg+eV$&FRocajF{Q=gCI z;Yd9BVf%T!7Q1Vh;UDVXwfiae#W zPfJ!eSzHSiaE)Xql_+v2{IuLvt+1#5U2>zGbLq3FC+7mYoV|yV$%h6UNk>zy6V!dS z0<@EVk2w={t{#*+cJv?Z`kX2$^hA%t4oCih?%0o$+Q(bPCc4zxOw;i+q*iPx=SM(S zJPUo9dA(WabYG89KNRCuSWb%3D225q^~6j$Pu(^NK6_tC%Gn9Ev60ff-TUJn|G+Xf zOFoJ9DDanA&YudtTh3R_FZHmJ=P;kV=&WP$n{)kMz#0Lge9Dwflt(e7bsX`MR_|+1 zD+azLr_#C{`40hB3|JG>O6#U6yMk-WVSFBNj{>)iALn&vsE=ZbXVm*Hh&lMu%W~&W>hc8A>6nK;%QlQiI(l5XJJDe~o0l@Za*p+O z;(3f`>lN|kg|f)p@ODS;v#w)^ulY&3{Dchw7R`W-16Bc8Hsbjq-V9)SJ+L5PMSzt9 zMj5WY`ERVh3+AH=hkqGyK9$CC<$nR-rENH`0Y1{+j=o9!X3!o5T*lq~LhJ5N=vM)# zq`2k);FEp?G$&qxOhZ`h7aH9UdAgm7k=`~C+j-WWy-5jU}vTT7*!JYy-&L65eou*qhIcw|Kt}1|ELHwU#ZYTch)A;Z)CV7nX zSaMR~f{gOI5a`*ab)Sa5vX~TKHt1v8kIOxFP%bl5^f`l+W8frkWB=&%C8s~SZ)mU| z#}Pk>_&kL9AVeesW*J%4P56CdgSXr%9By)CBI?JkcF=(wnW1p{~A-AHUWF}*gV zH@^(q2=_iBlAhN6<;r@LPP6ru*lPOTuE$i(O3_LvtH>I=5QM`eQDR5%AQx}f;y94} z=UO9)^xFRgdld+)dnG+R_Pl)_Lqw(?dESd>IrO_sdp-kw?$@y6k@k9_oyZP#wwbZ# z&1g@nX@3H9-zmq=6zcw@+4Y<$%Oe-Y^5U-NO^nyH>~4og%DNr3WuyA_+o`eR_mK?U8W!X8`yfG3s(+n5-b7g(Z zv}3#^Av@VA+14T5$W?#Q|QY1<{`G0Txe+$_iP(s}07 z=@W`ufYKFG0pN39r~u92za{nCS{@pB+DPdI9OFlUw+uYqp;j}(TWlTjCOc2cJF=Mh zhyi!PIH%?7bUGh6Q!mH6+22!}F~BFy6ljJ`hvxr!Z8YnkiCYfM)N7+D`yA}MK8NP7 ze>V+fap~uw&!}@73%c#~UI3RfwOrWHR~C8;tvsoPK`6HcbP1$Yn00QWmHUb9l9uCt zK1~1fcG8FqXp+S zI2tC&i`xE=I<_dr2N8el@^ktvB`5wVC%y*p z6^y^)+=fEcx$6x$iHrNR12OAiB&O9$k2fvG+tx?fQ(TpkvTG9gEh{>w*S~k3V>@XZ z6>S$)cDC3n^qlQEzM=OoS&lJhgWaRmtT6U1Kvd8+|T^v{kY%XNYN zIl=q`hcZANPvf}yC;1G6cO!6ESDrqcIyb@eXMocT9O^*)kRQtt2Mk;dRfum#TY?-) z`FToRng!4TJWT#vSteV7*ASd zvK8MkMaXyZx^v=ZMSVV6bKG5$W_s^bn}FnirQ846m)gOnqvYI1kbImz;@Y|xKkUSF9&+Pd zossRW5I+EVt*RN%(~m(P#9s|y3BXR0-+vMw(pL{VW1jQC zG2kSDBX7g@2#(hAD&4nH>;mg3Q*%qF>*-h*#`n$0A9(Onj=wSR+6$Q28o!Z|X9z1R zoX#~}%)13R4%$`F9xp>%Q19vlZ8*Qh*I5?3rLybh?l<(5#$UhRF7ek~@87pO+;?N| zO+121|IN&m<8s9zaPfO@>bub;fy*9F9?S;UWS@=$e{VU)5%u9FDc{Q0P^WFizJzmm3A4N3tnBGC89JwRq632Ou2FF^if5R# z;=+Db2i%g#IlVTm1nv{5YkjgNJBIk|=sEqi&l`o8$mvSgu^J8|iNA$(^NW3Q5Oj@| z=Qf6z=S$Lgmi~!-B4mW)(OoHTI#80p{h`XE=WK z8WJYgEByN|kI;Q#g#HVoc9A?A>g~$8DN~Ew)@X*tgz0$CFx9T z3H3Y`e}B01gRu`px=wUI9qm1Czwd21`k0&UhmUOfW&L2&PtFCc;2S)APTTZ8FMOT4 zWEEBRzyT}$6S(c`J(#@7#|Gz|8SvWkR@4vYl|~OQIer!;FPhL@UYrfwu&kBmdO`m% z^cwKe^PTN?&lXVblp($e@q^@lnef*-R~7e%?45Gg^&+}P5VXfYJ9h+g9>U5G+6d=7 zdkd}+rF?;R04Ms$IoWep|9drs)8N4w1YeWBCt~2X2|?l zl)(B8{1j;U;kYdWY#gv`foQu=Gx&}HCUfT7g|Ccx_kH>XXW9ya<~Zo{9zC~FLHe{E zm#zn8|A=YCfKvjTW5mH{Fa8#gMk`?B2&;{MA+4l=vt_9xBh`E~>cQ0Ztww+$js1NI zJk?{6*$C@4iovYzPis-o#L{-V8fObw&(TLf+W=bhK0`g9P8a_AMOgR5*sbO(SndyU%S*pyR17kxetGv)b6cNLNjFb+|vA z2!-v6%DzZ%G!n1usj|K+tKfRr(Hx~Ae?}3X=si{O%HC*Sgj9CLer_Pu=a4Eyden`J z@U-4ra${uYE9^$H4>h4Lb@ZX1Qx-iS`EqR^-F_(3o=qib2e%^xL3{Me*zaEc$tM5z zSbsm{_WJ_hv;$|P-&u3i(59p3#d!qg0H;3}^&9j;XZ%;%TSU#!OAGi$^`2dLuqXSS zr@R2ZJn9~7z$;+yI`wEz_EV=Sd$KD}MSHUMApI!PZ~QXWX)NEgq$4_eHO(89a9H1y z^}s2QpFH?c5?!nrbPWSqzN#UibLJAeK+u^%$MzdVI>W#p0)C9?v;ZGx>4TB3Ppj@v z;i=Mg75fZ)zO^a)dG#^RvmAAvu(pk_f{*bP%wgcE_Di~HosO$7t=k4gA|eBUqM;7dKT4ZPO} zojk3iWucsJrPa&HNf~fQf!p#mEeqAlf~(iX&K&8UiE-bf41#6}H0_{iLs)&w&g2Q%r`Dh&&6@dfYbE#b9&#fHI0L3o>F`c0cQd@lGgDwj+@p1@^BJ3rQbNW zu?G`^dPHz=#;Wt4*nzMe<)hbfNb%nIzMk4hUv+Oyq@+fOFkfb92K&CnTL*lJG8=^$ahANlb__p%-2xAW9A);tLe{8^T}FS8yKV zyU>MhKpt>mYA%?p3H>@NlV6zIq3H#Aq|m}8Hu+Vmc# z9j>Ga()!N)X-rbyCD}ecm05jy-g-a~zL&!`se#)r!r{oPK1Xbqxu8x&-bG>W{FeWb z+z5X@h$|P)?=XMMJUxZHE&mky1;^%1uU*C#qi&`LVXsuYLN z#y|8R+sC*X#I3t=OX)c3S51g({0E0_J{^ZBv6t0-4dVsz%!~VJM4$=qIl>{oUEKrz zw6t-BZuN0>1+p2QpPcFXVLb+1Y0c*{w7YqXaBW`VYFk?o!IC=D6w(;{N5@u&-zE5) z2W$Ya5riRQU7K%eJ1$D^Sg&aM?5|@z_H%82Bl;fv6#-TO*b)JbzUA&8ig|+*TqKvi zJs6Tt6TT0DE(tn_s#JO91SDnhOIkglVd?OTFYM!gd0OCYQUhs>2U)~Al-w=qJ}npc zv-ZUoj)V0$(kc5T<{h1m%vIVqASW!`dFq39#^dLnMX%&Ly#^LLYWk> zuxI=V@(y#CTPM&#@1yF8X8}_B*ZtHDk>wVkHG!sP8TLogRO$wlHGdRpH`^bT(+Jrj z52K6HkZxq#biHzCv^-CgHl*B};ayHqMOZtw`4GECuSGHX5|U)Tmyn0af70_3@-2M< z@2u8zSqD>_&jRFHp!x-EHyuLz|8MjuT~>+Sv{ne^^15DXZlzvY51OKX#`<5=c=RLP zUFA(9*DfNjo47x;9lHbc^DCH_JoOua{}|TqLojl(H95~k2tfC6G+eFgYkmCT7haTJ zTFrNq>yW2K@XY=f=(^tiDA_S{p%x!_oK7DB#o(mi;XsfwJ68co^OKR zYHGbE^@4YwtUIQy$cNlUokilEp)}GUPG6RKnGRtSfq~O61`b z>vRx2PM*QK&cj1Wh>8&-vsN@4$WsR&NDavV=odkM^ep5(!u)V8m;|g~?VRgp(&-O) z2hFKpIXA?@0Cy38CEvn&BMBSwRrukq!NqeOc7$jrLR)BmZz$px3T|t$$5Fh7BW-xFo-~z!i$`!sMGUL5Ti;Es0hhfgn8s^;u@3%=igBloiE7}HrBd#Rg&b0ok#blSUI_A zy+hc4^re^I%44?oi4hpaHa3S9l7E%>4(CQCtiSafQa23$LN}dH*#_A68Ub7Oz{&wT z0oW2?6Ic@)wOSUTD_ajr-?QGMApj%PBj>3y9_(n^~0XcQNx-ow$p-K<3~gl8+#zw6L09pHWJ-t!wvRK}e4 zz%&`=y6gZSudwjCk>j+QO_B8@J7+(wxbLWoD;9t;xEMM~b}F$v8bTd7+#(1j;h*{T}Q!?{&(9--Oiz zHvQyzIsb*9Mi75ZfX$sazfnZ_B>vf~zoM(Hs@#+K)^u&anLT-4Y>WWOzHI`qiD%Dm zM78`Dn{OTWnCvXyR+G0*EG#RvLtj1bAK=B5cSw0)=sLz<@P5jCErHkMADR%pziq7VQgzbkFcAPimFWN1^Z&7;7N3zY6^uYLrb2khRBb+E)FOP{ z(wN0T{4Z1JgAHm78;B(c0T16pmYPQ{9K5^AfLEhhm2pyyDx=+0@HI7N7B2XVMN_RH zA&c-)OO5!9n6D7wd7n;VTMhmnRmY7MCzs4=;CMUgFrKXv*~W0TM*JId?-Uf+0iS9q zF@}A}gVC1NFnyyjw?&QPJ6lcSd#jo+F~)M+)G&VRI*IR=OBkKFL;-c|5=PHnLe!;8 zCed~yg=!WAm#bKbF?mIFvcyPS)nYFjer#4OBL5RUwR)$qu7*(9 zfo*F2E@L2Ht>SyTTE5Ge-x2c<-eoLa(E-%O*Ue?)$Mp4Juyj46TW>&c;0EH4-$2?q z0!Chsuc=Z(7fJ~odIOOs-cW=4G&dK5#mFsF$m-;+v_3B0rpC+Rn^}#P8}Zxs&fIB? z?`bFe4%G_y9pDweQzgoc;X4tWzEic|WvnpRb{D<|?n1ARmm@U7FSJ`epPXn=U@_>l z=4*nmKORzTrZM1B5mH*xYO;rF&KHL?lwf0Q%8T>+L-rtrBPwnhBQBo{A(DEjH;3%; zdrCV@W5}ht5W?ChEA`e!1t4{$Vq;BI#(_3Hiq&T9^IxEb{nzn(aB(pC!*gN15hw=r?KLU^P|qKgT~Q-A3zfUBpQ#Vomw_nCV=4du!XS3D(VPkb`9>U4o6QhTXrEL?|K!Y)`Lk%1@CU+`? zCw8g!!^TL#;5GO$`$kePzmc34-$bsh59|T;#Djz{Jg5f2<3SR%Jj4_R9#Z3njiHCg zZUWy8#==8tsKHp3aI8VKzSU?stP65AdqGq!D4c?vQxvO1%2+oG5S~>U<*vQ>-=Jo< zLJ-Eb8q=o2!!FCFN^CV2EQV)&YJRJ+q!@06u-aktTSAl>^@7?#y^Kh` zAdGrh$u?U2gb!siJiobKeow01l%9vwaF%gG4Q5dYCbEnPQ!V<9X^Y`_md;eEu8Iy! zil$0#VSy&M7~>Yh7*y+9jHN7wSGQ>V>!bMJsHUhcV3VX}!W zEKoAbXh%^bv%_1A6{rJSjJT7{;34on&J+`-!a@`^4sI&iX_@~yMlS}>#QS}J*ZjZ4_xH`mA6h>4Gt|o^q@UQPmbMuS z+tkW7qa**dM2u}$3)_vk?P_Ve(H8JfylTYC4i(>NbYRxmX-w?&P)zJlOFN8(9cpC< zqtm%sxU6|A72QZAc&a|3Tki?`~EzCKtLo&;Onf zj=2+R!ZhaG)c*tW?^7F`Od1qc#n6&;yZ?JanviC*f)N3$3Q2u?^e84ZD0n7SUICS@ zFwlloBF^a3@&bEG5=R*r(a`8CWh%mv$vVQ+x; zhZQ`OApun!qrC+xJIq01UyAu?B^n|F7(#}zh+=TrM>A3j`Na4&#IJFFf$i0MVV7-# z7V8)WMxos~>;HKtnfy|08E&e{U^}CrsLqrf^#!Fv9AZQfe71WT)}!2be3g0N#-w zU_TqP6kLs9Ap%pZrD9l7GqENj3oxw`PD&AgZvtEc;+|ZM>9t)+E;QD zT-=Vp`gS!EFk%4&hXZOdU`#ML%P-_Oh-D&pz@CCdA%lxs)%sQ=$zXeq#yNf*!@-zQ zYG8}8%+y-_>>F{`+=yRIZP81Uc|X@SZhK)-lVHtZSv9}Km|_rJ3bst?Qf;iY1iwc3 zHOa3zel7D0`MPb~gh7d8nM*bwO@vr?jXDcJ^nv*-W0Fkg__fS0mS#!evqYA((pn)}c#umy-U4ru#IL%g8V$E-q(N?2=r#w??k zvB2|jNrrySFB!F<3Dhls28fd|-#dH)hcM8{8VR_(gHhO-DLf!puzbcyg6Y#|q@@ST zQ8)8DaRN0MxfD<^1&e@U9xCPm8^MwiCjL|&FoCm!jbl5)g&iRtejyoDv97y1@`D6j zRP3#&d&LEujPN$rCHP-+2on%13^;M$D8d&(3e+VtK{{hZU^ZBe_PB!H%sek!uXHZ;o$OLwVX@w6s-C<{ImS z#&T3ko-xFJJCUR2a%mz&i@{EqYqaDd7|&JXdB!k<6a1Rx*AlgPnr}=qxVTM?Y&Vh&wsRo}n>t1$zoz&#JwNg^V`8CY134S5d zW%cYQ=+lXG=f}2%D@rGQ*nJ>6zhue+&DC7{U{FA`xsnT_EiJi#5-i88#omB!ihd$J z7QI+{tlO2#_F&9#0!N)E$bS^JEg$Dwsoi$;Oa`TT6HXnsST(IU$k?8%CU@w18_QM8 zJ7^-7DxBMqs=}6?sVW={=qg-7#RiOZ)@BS<7%+xdZ&*yP28>w-m$#|J4x@$j70*{~ zJB(olC-c?F4r9)#%Ggd_mx=9ae5WzOdYsy>hIShB46bfhGduMPdmy030>&uC@D#u1 z`L)8Y)*bkY^J|!2SWu&K`L)Eab$-dhdXTH@F@8<+Yr$D;AFo(I#i6!f4{~b@ZoH+o zFnbTVv@rpr8iR{U!2l#Cp$cSW7bZ&dB7Q-xBj=7xZJcFW zP+x(tB}*g$i%c@=L&GlOnbKIAWlEwWqgbu08}lXE+i4M4DnIK@;X^AB(;;-naXr4<8$LFf^y*equd6B4!_6D;v4bW}&*o#*cr zeo3am;~H8fVaG`Z40N*@>1GH|2UN=rW0idjNZaf1AIxbP^k)lb(xlzxh?=^UiecMr z9Feixpm3a+xfR;ioH=+KRh`9KVf`*bcrdTkjNfVuUP+3vD~UUOCFvHftOvz(k!me7 z+FzFk)V8bD*lkAa8Z}*JEbk_M+w}_Y#T!YLypdGxHz`ofyq@rZHxPgR4TOx{tmbYr zW^QJ9lLYMgi+T6Qr8Hhu3Pe0 z*9fDoJEX1=MqLj`UC%mojok$VSF=?|E|pf2ZY5+gMKY^<^vz-*4- zXg23wC@YAJqsBR@lL$J>e4e>3;n5s5u+5y#2?CC(s$-iuluMlXTops}VancSw2BFL za&uj8n0q+4PGM+53&PqUmm(K6v7#n@__30$MsujOBYHST&F2{FR3k9f?=HdrJ;CKH z$j`hXOa`#+LsiE<5#%*CAG3@x`G&Ly1U(3l0j#sKw0aE=wH#S{8>Y9gw_<^W`s%=n z%&!1}z75Edgh7ii^mD+m&V%Z|Bw;B0Sa`|W3EY^cx3Mg3X2awzqa7OXF3t#HIP=etLa^kWP3rpvZD~Ov7L1YukTceUB>t>UFt_@ zwWx2J*vW;}@=ne{>pMBeAdK2s6AqjR= z014CW)J|i`nQBFh79f#1Z0_I^9c3^|cBRzStZy2U6}y{$V_2yL7zsE9BKmgD0u`&~ zAosL_ZP>x_okVz8w#tbd9<(!{eqr-k== zPa`}f`sAFfu9n?86Vyo)rUw`zFtwqZ4LEZhtMs)*PnlRcV1Q#$({8CjoIrYQ%yW($ z@fZpM1Lhtmql2VH9;NOJPU8QvbrS0#F@9jo2>i)*t8_jeT55UgcI^3;E^gO)(d?Ge zSb$rh6Wci@Ol>#Da?0b|vD_$K$v0;6N{4}-uaeu1W$KMB)D2_&8sgVDzZUofeG%G2 z0AGXrLPg}1(2yiL0)Oq{dS8qV_{Dhl?}`p83^C>(-LeDgO9mk{gv)!IPJp>=91mDj zTd*44sx3`e=67Ic7>1s$P|u1G#=u6TC}h)Fb<@~!-lFi0A!=~-f*oWO6hnC{gJMn? z?Hwkcaxtt!h^a+RuD)vc;hRjI1n zuif41*Y55@;um-(Uii)U4g3=@WWH#+?cCPh4IM%HkLOJ_L!FH0&$~0A%zL}WN0(f zpYl>*mC4aeK=Oan`^ykC{~!6khNr5!Fr3_>3o{Xw@i2=*%@Lb*Jlux%xNt_#W&nrd zaAnd@!6KvMs*Xt`)`Dq91!LNmj%I96R9??W>KR)7-~QbHoab~IG~CTp7#z=_887P% zRhkMzo2Uk}Qq7X_uqg;hxPuTq9nKreVpK!D2K>tJ{IPy$)z!hJ)jN8FXk0- zgNR7ARftKqm5WKYm5G7$U7C$C?UFHVvttO%w5UxRWdTHG+I68qGupH8Lrpf%j7Uxm z(UL8P7U6=|rzYwRBkDgl>&h48epI~R)n{D+(t@xEiJH~ML-vNIOE{!|)^_;`^VITpJJTo{)+q<$o5N{1j&(}L zYwI(==kFdn4*NP~I>1tk&mT%6d(1t}aow4o+D2jsZXvYa)$#Vw#;cBPRBbPFk`Jav zOa4zv;m!0LoYQs6^zSBkj(Z7CM0>0j8_1w2FR+xS<~SMrAH@%-e0?+7fv>ss4hZNt%LZ$mYy z_uSF8oFaAS_jPq|({;AJ{SO3peki#AL&4Q8wMl&F7+wBDSNqtjd`QQw4_%YtTJ_#X zF2SuIsbT#iw?_vCCq8!hkG<;0H1De5WnU97u;PxEM>HB_nY$@;-CTxaS_K|1k9MvT z|HlpA`B#jXuK$PndorF^pQpw9`;6ne+J9I5tIzwc-#dTgI8NT<wT4+T45@7ZnsR^s6zc{v z>m;g#{h}VVb8XgZ1uO952RxE-9!JEe_am|*bR*L89x@0gnDpi2p z5)molP0P+3ya#?mIA`2_WM6cLvm##YS#h1fuzrGZ@kMum&Ks@y?84~C1Y2xJTXDx7 zFjamef&D7<46o9?@mfsgC#^8)NAxZ4`bT)(Od`CxM_W{$K4Xw~J=VA#w z8^<;^@#9Y^u~JdOXRrtm8XLu5ukjb1HY7b4+M>)L3nOn%M1V_E_aXR&nFZDJiRkla z+yz7AVG62qg7?guYM)Z#raY^_%P<9KeCY?3ukJlBHF7-=J(pH_WYvEL8eEuMl zWX816Hl&2FL%!uI@Ex$Z7i50Q!S3nflVi1L{kYUB58rWzoU&W7Zu4OAcb6{FzPk_93oip$NLn z2F4dyBxZZwOQL6(7Yj*!1_o_jauhXv$Kno_(ZiP~5;tYWrK%crTu$R?x6E!y`;foH;u9_m zuIfT<$tdJCUGCiwaZJQrFYaaIy4sDq(z4fB<|+MUHDNmbb9*M5EA17eT7;8hPTJU0 zVB|bX108XNraw87{I$MtGC>(@k_C6ew<+MDGUH~!xX!cPWy*kQ& z@YAfLhuC1g9=-0Xzb7Lu>S=;`=pO^mJ<(XrtHsV1x6MYW`r3UX6M*#-i7{Kd?g1or z^m}PT*4MRk z*s0kKJvB_2BSJ=(84E54Re?}gq?X{G78U{eeRnRDSbbJXDyUy_e9taw82{k=CTVO{8ZK51`Q}M@LaP)#-BjOfca(9ZeO15KAINFY>nS#{Rj{RVj7!vm(4A)NG-{Luqt&E;0aQT9K z9r@z^Bn47vraJC9Yi$~RGusy6gHZHKz&s43%y`Y+V-KOf9~o?<37}YOzT7 ze61>o2i_PQYQ|=4);8?C##%lZ@K%ZF_Qd#EPoVl)PayjJ`GKD&#VqXI(AYaVHj>?) zq@!bW1Jhncco)r33T|H@YRVEy6oE;pMY1X|p)l`(mgKc>YRepho9^J2H@wM(^exx8 z<&|y$9;)c5;OTb}ZGckdK6l~)bu|75JfJicyM*dU_0*C1ireAEhcl9WsGY&~=nVuW zBNSN`+;e>m^}9F`w{-6kufb$;udPi*F&uxz!zJ^dW1eRt_}bDo z^f(8BS2s^i_z-#xi-kg`$zD*w1l-tuV#gQVJ-g`l8rUTGiP0%QRgQHIp$60_wJtLe+2QXQ zRQgBIs%u-^@<6tPCjcxzh%uvg*$-am_hG`h6&4Cid>zEJ6CI5Gap&EfHX zn!o4P88;ZVavD#oSw8#!hF+1?&f&wSC1#HTvPoIPV0->&>V-W*);l&}`5YAXYhdh~ zaK;>UHnMhAGa{>cFQRrSoVaiVK-xOz9T*?oFnEAQ84JF+Y4hM>Fnf3q@NZa^a(F>ZUuuetJ@-tcw7 z#qYV~ZLj)0!Kqc(xb5Xu1$S3n@wRtlaPz3nyMQ2p=?*M8I6f0Lmws9!wfZz@#w z(MZG46lS~>W)Uw3bmr*gHeKoB>O+oekuJ(nC#$3Vkf9+g%`M*z$E`8IeK%oil+M> zOikM7#~xn1G`i-JKk^#aUG7I-<_ndHAB`SxPE)cgU(mh}*=H1igp!|vJBu`?#9X50 zheQ(_nwxOcl(4rUvmo0}%BBa5R+)N)J<7I)x!QWs+pPNE1a~EaLmosSX2yBbG{!2> z9Wj)!g!qSt1Vf~495-|h?kh_8YjJAei=wH~fKRxG<>PRLM$l$9L~beuTYwiN-VIaV zKqZ1*5ZysGltmT`@(FMBYt8hQlvj{9R82r&M?=$Ve$2V9-X_^M*Zp`J3$ z*S_hz4ot&!WF;CdR8oV0yw0xC^)@V2I(XrCBoGjqKVdxhgn5!oh`q%RVmR`i7#9qF z#?v8rf|`XW&WJkyDcPFc5@Tl#u_=CeAMojRaomU2568n$x5juFYMPn|bL_xn2#we< ztwbJ&Oc=LW9w+a}h~30wH?mb)pZKz9UqHAC;mw8~rPzYuEy^SKdG5fWX;PH2AiZ0{ z=Lhn=?Wc1Kil^Jfq-7XT=WT^6Y`u>EB8Xv5t5-Au#n=a0ol~o)t{t$+)Ko%`Rh9Bn z_vA>^`9d7Y(HA;+HDFfro+xtmp4XVn`21l1^uF+hGtYqWvhClK5x;#;*1YaL+3^Nn zqTH+a`}Zud#ur|5VfE-suXx2J?s?rSF8`(1UUd6kdWCB)zr#5$jBz>hrb~S8HSfAA zx4q-28NTCM^!I~@!24UOX>GX@S3eZo`Oqc4^wJ+YhF$wuBWiuDp%%6^?1OE+NPF8I zGE##xpSTi(_(W|EKXHjKyxu2jlls){ed(1x72NpLHF)l)>c9M%tA6P*&ibE6{xVrKS7i}Mev`QLmk*MZ;k>kD!SXf5bO4Hl$*t1h6% zulo%y%sNVJsbJc3+kj|LY2U-caX|s6odvIaK0-}bI@08Y9W{xmx*AiL9ZGC|24^n1 zBd%W5L&yh_yW({&s++_mm%8F*E~(@4C3kSet6$O(dY4@Big#>q?y@_);*~F}ee<%D zVRB*g_P-L6T$j^!66qUK0$rY!w=^)~VgtQcI1VS!!K(nrZsP=wuyCVOn~3A}eP9mX z(0|%P|M4C(lci=_i0=Nk^Mb4-PMtyih0P+o=@4Zxx*r^kP0x$16jd_k5&Jb#mt6!Hb^dW2V}07^2e`bjj8nY*;CK#ic)7U;Tu4P-e%Z@iE~!;|Q8#86 z)k$Gdx0e_5x=>$o3Ce3x;LP<^%G!0+bg$b}Z@5<6%aIRc**hRBPTXr4Jh&k>YcW0= z_xudJ423;*R z@H&*>FuWOXW9MFU{CNg8CzyDEBd*RVo*SQ}4*krjX99{+<{?KtEGH^MmEVv(ZSg?PPVtRKwDG~b-_x)HY*#kcgnuHs5hdka{~<3Jyk13mYm z!f!>T_O|~2yO6faju_H|P^9ywtWMoGWC6z4;MjdF?}Kq&MULVs1{+w~#-vNYwBjuK zCcap%ML8oDxDizw>?|;GEqsMmz1js=d(+Ft)?tdP7hUn?NKE5B|dA#u@dr7vPUsqeWa zjQ02Rbn+MF*2tBl_5+ylH7|+B*KMz`>dI?gWmWa9Ro5r0(i@}ch>xbbPU;C%Sr#Kk zd0=WWaH&n%zYUG}&!f*pG#j5mt|RFkxhO#mI#YE&`>7lsxxlj0XdfrY9oe9IpA&1a z%GJ&Vcl?=GAbS5(uYTEeKJyN)mO`b^z2tS*`rPZsb)mcLDxZ6aTL zL+ap?c@nPObe>*|G`R4V+vh%=hN`M%m0 z-e01(&ii^!_4^{C&F|;Kbhr0Im;T(#Z|RxUEtmaFB$L~YFoAvM?R_Y?^r5Tlc=eAR z?fW0ACcW*lUwHX#4X(QFDo|{LA)Es^fKSv0!r9{LC%UTx5rs?|5zTz+_CNJ9fiw`X z!_|NtM!A4m3L%7&%?Ou#62|bCVng;q6o@W$Y$Rp{+aHS{^T9Nx=j7XjQ#j}hn`dnX z4;OSl5)LD3o{Mm2$)v@)RkW=_o-N3V&=yX!r3aT4TqVwU`?bsE8U zfvfUF z9R!E_`*r;q*Cv zzyut;<5eN^?|8|}rBID4OO7&kO;y<&DnaTr1*uc!;yE>{-cq9?XZ;;z9it?f8D;tQ z5@q#{)vqrA_tyod@2afbU86j{8=<4}JB+OI&H^Cg)Bk#a#UUMt6bUF1GT;rFn+7*T zwFhzUU?SGxDw0uLK5Y58sPTSWlLO^~yJ^Ig;SHjMTT%*wc-aWif_kehsE6hi)%0LQ z<6eDH^<}~}=;5lX-0%`hu6x7FFS*7IuWWFWgjmP4$|~ z-tZb$Gq~mo*S-Ap(S+-T{z8*)V&9W((;eb4*z*Nqhz1Oy{2gM68uOAuQoL>h>$N}- z`M|vhG-Ywc10Y{;tBS4)910}jfl0g>1`PMwfTIt1vEW5Dzyi35XxEq(dd--fkI zQO)fCiZ0huzmS?D3k zy}`S#@Jp}po~!@LYl9en?G-m&>DON616TgFSO0-a|JrN*&}Dw@wYLQKK6Hg&d+8rD z1%)4L3MxNdqs!wT-{XCAKcRa6C#!(NpXg%hr+QxTr+Rkfry5P|ry5!MXX+*UGxb~e znVwYonVx;H>juB@+Pg0Q3$L^5=%>HynBilCb3b=`f9{okuKMQBUH{L$&d)Wqy+7x% ztZCL?D)}ritP(tT2z4oPSrZ0(j8#1#pnL(ohFX+pgUc`zE7VSMYj<)XiLW2doUr86 zvCd^|mMYUQ7qIFPG4*><)xf$Yt|-I~_P+>!wcs@_#<&Y+zjj$nJ?wm24txpm^am;$ z0e3(36mw!W*inlsF7JCAJ0rCzI`EP%9R5*PBM|BY=In8_(t7LY1DT-E!Jg5fPHwob zOf}2(FST7WK2ammC!?q;p<+X@Kw2FT%<7&2V}AzbY{+#6d-$wZoKQ_=qB6#h-0X@y z>dU&nx{r$NZmu zUB@ns0`5I2`1jw_c}~11pWXI*65UeodkMmHxr!_1`|^&hy(d*$={@fN=l2a^E{^wk zfyv9R{+^dXsG>QEDBttS3$FCOSGscOAHC}x#T{k-wUSR;RF!+&@jW*HRdZ%Gyz-hJ zLzc(d`(E$PIz5%{LO6SOUHe@xC1kq~6S3jd1d{2ovf;Jf1stjd}kRejxjXrQR{h7<*XvzSgE>>i8;;JzOH9Wx7rE_|y(>KZP5 zsaM&4hV~UUqo`%x_xaHZCw+q9j?gC(r?o%6iGy5YDoUBaA#6rM0+(^X5$;AiLAw@*}_Gq)Y&(0TbxbD5xJnj#(0QGHJJ z$R^YyI8mPt9DEY~j-IxayefhGco9Fkwc{)Du`mr;EY|EoA{;4jiw6*oXl z>5`*mA3~J+o(>NKz*rQjU zm7}0qMpS0-xW)i9YjD7!|5NnoY24FLpU=zQnFq#IiTA|8iGA(_Gq8SCXc?GI!49We z)la%=RKBagL=_?_vv9x!pVJR=I(H$~(dIyyme&c~qVkA|NChM$39HQUA~;F~sP2zy zBa(Dq_YN(=-`+_N?Lddav(D-8J(XWVN`!)%k98M5;so=A5@F(U;Oc5IsVb;~f>8ta z1({%^Wa3_CPgWuor*D?vO zyJLbh1LSZ{cWw}+M26VWy=D+vb3G^ZnDrjiz-A9lYJ>{zIk=Y-#^v|u88>M2lIC$% zGjY~3^6d(Z`>e6(Th^ohFct1Q=I_Nk>)kZ(!Qc4|b}>?NYEm(X0djGklSKr#WeRD5 z5ofG2Z(%=B4;Yx)AVO!pjjwzu-j)~4D+a<7e64 z2=7$W?wZbabu2U8dWulBH_jhq(#}(_@K;=*!Eb$py#A7WMmtxfQ3OUdPEbM{mK5cc zUh>LlG?t{pEG~J;OD=s)YO5CH`jTs0^}3f_bIB_r6)%asr=Pnb#%mnn~Sb+)yrQ!86OzDMJ;adSLK`v3}x$I6*CQt zuhG#}F-O2%G_6bC5Ie+@>TiMhT2QJAo{|D7d=l_O5#AV0=*w&dAr6n+29@wD-T`jKm&t{izZcRWY=m z=BM~m)&F0=I}tHm zz{!gW8OvT&$7IPzbUdV7@cI{Bfrn!u;vtvZ(1b={RxEc#Od>Fprb2935CQft?HzZ- zC8BoCEyC?a*e;1Nqy|_<;!+kRrd1b_4xUkivWpr-RBlMkYiH%=bsIW1>WMn19ybPR z_Alrvf$rRu;B8<`*-48!iqvTG$)2KeDe_4H?Y`c7Hw{V})^MIR~eU|`IbpUp{q%|)mgjuriERL*$( zz#EUII0I0V;%u8#KvVRc)K|f5CIetyfbU70_7IVR8MR&hHzzBBRKhbQ$&mcQ(kBp7 z;><08>;RH!RG){RKz1HmC4vP@BsFk_)PUe6@R%DxciLs)?+nf&?;vrTyo1*Y0(ZyY z1RI#(&z!N`z=Ov8x-C)q18@#DbkoBTymk`~4Tqg0hb7GLW&4DslYj8FfKJt6}}9d zNv=BVza$wqTL3&4@SY{EJFx{U>QRs653`4>f`uxSPZQ{`joy?X0_1pt2(TBBUp?ox zfsu{~(XCjFLl4O!NjJ^sB%_B)nB`?}q9zdX@;^U3TR+__mnaf5U4n zy9^P*%Q8=8Zq?OA?X@LJT+AqQuj{KJMJ!*d`g#Y}G#CmxI(}W2yY%-|j{_P`YFNR5 z+rZ!R4g&%;IyaBpFlOGW7d6Mn#Bt-%8ABcOB*V#YN->SJ1k6mc_YuX077q?A>`I%c zau0x4iTT|JuU^zy;VvSVXvtZjC1-^w^6Uj&tz2*=PLjd>3$8;PI{22S#}wK=h>a%s zZ|qP%QiK*8poC}&mXUBP6KX#E6tOljCV`f10GuPx9W#gdrKLcT)Xd2wgGU2bYv?FB z>LRe?bOU%cs+)Q-Wnl~U8`i_^r zq^A4uRCh3;yCgTmoA5NW-qgc`@PI3-7eB(ii+W6bQIEvZP+#M_GOP4+#0NDnuHH~h zjd0^TUM21l+`AkF?qN$@^NP1rUtV$hYhK|sH&~PMkAB!Dlok9G*R)L-TY6RP3#*&7 z@2;xl@v7tHF_YHsc=#;RzVn9b@LYqlZ_2n@#P^1N-qgK~H|?$8bcNeq;|h4Nxu8Xa`g1R8(!AkyVDLIyCK2dX{u^;>=p_c1 zKzd!jO9~CtqxP=%KG%Fy#grEiB{HPmwB$usOOxVQ%CQW_Qp(v!4*9Ekik?rnKeniFV(IXxW>cKu!s zAjA0^C!iA$8nz#N%>iVA&ZjU=ZAHbQ3LYEX!qr($Wyk&~+=jY%*2fDKwFi#mrr3Z+ zR)XX|tOECu>*JR_zs5`D$71Oz<%&9<2xru15z8wr zriPH%GvTz$ESXum(X{2lP$s##7ny%`WmM49eEo&L%NAjr%w$CVuvM{L1KzF)4;1my zaOET6J>>9+kAk{96NUw&O>Y_#UO?T&6W?GHFc)?cN{qF1#)!|xaq&d**N$3t z$d!eKg}hl9`bpt}PYS7xwdhsjmD&OmlN8)FU-1(Rj;A%kqa31CMw9-EZGMbI4fRUh zxh3}CQ#bUb*tVMcHiPh4mFZD1>oGZ6h-uOI()fPiX+5DJm(Ijf_%Vn*2T(;4h5z)K zfS0;FvGr6=sySJAPR*#%$D9Mb_z_z_n32COs~x|HmWFxOo|o%pQ6P#vKp5yY*Tw~d znGW&m)Ql%aLD+hIWT5_}IdEBgHAkVZ>g1$8zyp=y5U7AP9KC8@ySooPgDFDD=Cd{9 z29qh)VlBzXgC7_$j3s%Ey9RUjo<;spUz{TSjW*ZlRpT7xz_WM|OeY_>ih43H9}=Pp zMYjY>l*lTK7o$axinJR{!>?_+IRAZCS9SYND*TS7;Rw<&so)K+RZYv^)dU=K6ei(N zSjisRqDjRUb3pWxoFY~{c-^mU^LFuXHNzdFB2ysF(HbesOK?y_^8sVdIVh=T9J?{- zu*Q_6VWOH>rQJ|3O!z;}_^8gA)oFJ~l+iQ}WAcPJbPW@7xyE>qA!ss4l{*1qIA(UQKs;@xoa|&(+(93 z_h3We{+`tgQEpt9T7ySkaTU{QaMKa$r6q9@yx5}4a?hgr>Mpu67xBkJVRO|D&_GGe zad_1wuakfh5am(sx|dl}3mh5_m*mmMWUI(X0k^NBuYyl}v8;jn!sa?Zb|V!Se%uSd ze&(i-adBX#`iKBIkgh3nsX>PgTCHoLIW`|I@E4?;=cwagK+FyrAt4>X91S}ZfVMH% z5`dhE)Wi#ians~J6p3BIFWe7QmXK zi~}TXB$h%jGFypg9IPoMVY6g9XfuI}5w*vwik9d(Xw#3V9{p~Ht9T|MRT3hCU!%dt z=t}1#JnCMuA`k{27@$nivmu*0HJ)b>-v@yCceg8gcJ66`3z5FY>8+`1tLoD%&7WeQ+$o;*4 z;kdeWCM09#z~4G10bei*vIK0w9(IFnkuSDj10W$bs`;G11yaq0g^i7x_* zZW*sLQ~WT@#M?$Hq4s1JGqsQuzvmvV+i}BdghjV1Gjr_7kA!~y_!=$E&Qplp(aU!o zoJQRSJwt|1j#N+s9|n!EXIAMDgP+w`%8pyu&jde8x zRm5a;GP|$-Oj#@;J95-GjlSXZdy+G73(VHZ{LMX7kmNUtlFkHMV(u$3+s_r{&PYdn zB+;gv#%*8YZk)-Q9B;B#ht>{_{Vkt{(|opFIB$M+sw;@dFATgqg$TB0Y5yMrR{Cs&RLANhYie`$5W0euw(AoapwSJ}Bm)~J7&P|+x=IMzu!}AlxupRgj${s6b zal7n=gA1{?ZdbZ$y*}fa(YLz^vchd zXZw|v24B9^)u`v%Nms8th~*&t!$=4vXX+{sOxQXVpz?g6nv+j?vRXBy@>9%wo|aJa zY^WFpF&GNb1a8vDVtZ-CL1FjqvP+HZj>LDZ?6cCIkO@$&F^E$ z°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 J8izsPSAf5!Ei$A0Vl}G# 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

i&2_%J-QAIT25i*C;t_HYgBOo%v=q8@|#miG{S= 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%0AbJSiAfCMbzB;K%g8;TyGqAyj zT^sWPFHpw1RbTX33NJ&bn}hK}DWP`z{1RO=Ml)4%6)FW8Qke;Cyy|~co|@g~r*;W= zb)cD_XKZYq8fSRWfO-9xO$T0Y~ukz z7t!sT6rqIag07!NlW>e#PYTf$OIQ-42Y1c;-c)g=EddFB&G&$OlYQ|W#sa9elC7?!YOdT1tg0U{{L->ztWF;9? zQWl-K;TB%ghnss7w_{FCEgA9jhB1TZXGS=vp1AZUZd z3F$$RW$%zUP_ae-hSvzm}p08>H3 zTfGr#{=Xk0KYWCGKLC)Wjb>+lXu@^NNH_!V17v=pH*hzg(d?oU>tv1wt5hT>@WY?h zo}=~z5CJw6GR9OtT^bQsyfN#PnU|$9@9-t(Iy-hH5BS8$n%rABv(MS)>CI@lJXv77 zVN2Y+0y3FgZ}a~3YN3MS$@u7^+1i1!Zs+VQrR@4$pG~NG=RkPEHj2L@YtdCO33b%6 zrBqC>!%v1Pv?52O?5_|t$1Cbf7w#iy(s`8O zE_$eW$cO_%4nZ$?xVVlDE%`vssl|AuxS_k7h2ROqI)Qz_k@4c{h>49nnpsa0``m9j zJb(9Y$nNP2XjpJ;4R1C}!u5E@$t^(5Y>^#a0^cHiVH#p>vWsyJEEGQn&cfidiYrN@q$8kB#F!7+*;dTYecmcm zgkE|CCbH;>75~=Tv`a%5(DNWV=u3icBSN1F*GAqBm@Nk^>C~WHuH-BNxbp@-!e;Yb zC&U+u9$WSX#woC$v;&prGigXuvpEyGkxD%p#8UIX>o9Iwb+elA%>0t;75f61KPfz4rp3FOzp zUsScw*jm&p62l%g8LGxxQr;EKiUknR|i(Nj)5AW7t z&OEN0!7ch0e1fY*kqtsg#6G#x3MC~snSNO`*QRr~>LnnQvxRyW9gT6_QZ_WVEGwN_NUKm}O+f9s@z) z%*ET}TJNP=&mi|^^AheBfyXe5&y`Cc19HIvo2)`%#8lO&1FE&FaJia&7Q$}I6!}1M zokDSNqx5PrtLSK7y^?K|qvluySs zQ3nD&+Dt^k4#QjRfk+b;i8YI8!UoCALP}NuKrDJ7&lWRaiWgSk*2I8C1fV^U$+FOk zKE%uUTf86QETpP@`uN~rxOFcfvZ%6wjYgI213hvuvxCoDoyKqt&5rt|D+MdHv;!$}eU<{YG&SeNV&!;k z9|zfuY0D+IbD}PHnZc{eLw!eXUm+w_lQ1>$;>M?xDY=evFtfQ{bC=Q8h%#ej;@YPut`F56cQiWX|7ee(oeV2jZqR@~3f@I^@3!nqu zyzkT$`)V`~Z!Ro~byz%6gU_!~=wdiJ{mwOvx2O&)U2=1Gy@=2^lE)Yhl<|~bmJyzhbf$?J_MdKjIS*F)d_<!vc=ZR zH5OdDE^6+s0ygD_;ob^Sh%=Ig5(BoBS`=zHb-#O zwVEs8>Sc%bRyDr67QltWD?YfPy2LR^VE^=V$eG5y=<$h1Zp^5Ic1c6B7-f@ONj7qT z1*!Oo^zN)%rS)`P!_F!tn7WmzK)L-Ui%zQR+xE2aI$fd`D6r-N4_TMDHk%OQ5vR2( z(2|R|qryf3J|C|qHQPCBVTj~*XiFCs;PfmaXkZH7dL|_1<7G%Pi-lnWDuMtPxlfMf$8$*YwNd{Kdpk1L1V@+YLjJwybVIib_T~;fDrqc8f>yYNn zS@Y!mCFQ)?1zJ5XAx2GJ~c~6Z+V*yXl65*(3MU* z6~B3Qs&f&A;|MwN;5dzDBcw$O}jz5SHXmvo%J@pJuBGkd3HA zN-fdVprtTfur@?oAig-iVsjvOP!~jBThLe7T*yrI_<~5=Tpi4BYCuy&p5PQ}G0(Hp z`Knshqp&sl&~r|#H)3fQWo@HrLKsoQR1=Ij^}U!=pL8FQdLb^( zOnZ3IaqP<4=NCpI;bhzqH5Q#Q1KfWld+jJL2EeMLgkR!KU~8f9@@r6_PdCqOwr?Q7F3Dlx@kZvL|0r9C{z_H<@ICn< zBD<+7Xx2hfjSkPhD(W-9)!WMMaNR{7;cEl6@0dQTpc`x=DW#!I17aXC5bU+|XqKYg z>`G3cr)ZDBgbt-xG7DfHFkR4exa1;M#-nbhrjHce<@+aR^vDyHnAhZV;Q`!M;7Lf5 zQdre0NrTx!hXrY@ur+)&m~mU@TnW(UR93nL?l@Zm?oe4kQMZGHzcpoBu`T2|ny6y* zHgkaHu_zA9tZ{H7VbmJmcU1{`gV_EPEO+UT)KPpmgg~t@cx7~(fV zQF(&ByPT~y?y+FW#y#ZH;x7xNs#XAdonxI3Lx@_~)M7U+?wm>T2WOsZ|8IH=ew@KF37}I>-0= z5vn<_qCdTQwVd4eCpyyoJtoNCf|&fRU1{TM|NASr!k@(df84J0-9M&p{Pq9-ZTrdJ1U&8DE{_&3&>HJ22_^!SF^KJdyKHpB?_yxTAY5ec!Z=UHd{`$=y=x5%K z*YNxQMg4l?Z`t>L{-?j758$tV^PBcSc6|A1W22Ane;md?>+6;L^$-56p6KKE`}pev z{QUpI`ClIDFaCOIH{|&FzmH$9y0P)g_Pt;4KR(iT>2*^t;P?0Q{rUf%ozHRb-*?~Y zk^cJGGyR_5{ssKsK7WGmc!xiQ|M~Af|E`|zuYMo>RiDA%^YvHpe?0#W?R#zObFQ;SqrhWc*TIc`p-+#ixHvIKx+k*B z^8UVle!YLzI{&AB>95OA{`$-R!;jS0_Wl1AzWy`#UuPZk@pHc@2Y%z{{)W8%OZl7s z`2GF$-{B{25kLQXcK-M5d_T^w;Gg~VxA6n#&(HrYJO8)r{L6pnXX|B}o({PS`9SN{`lcrAbaU;BZc|LzBR{*R9Q zNPYdZ{J8Ol_{`_uY<=(NAGE&bvHa(+e-z%!5BBGWcK=_EU*dgx{NKQZ{95tQPkyN5 z=laHf?PGst&H4Y!&i@zjWV~;m|MP3k|0ln#_y0Go6IvfP?%Db6`TIM+qv!wY7XA47 z{qw&J*d8;vK_Vd;k^n)G48dwD zy=0VXiftM2(j*p5TWEu)tpl_@Iko4UskS!u^fC#y%_+S^1Cpqi_q(3Gp2^NK(_(+; zuXozVdDiFId+oLNUiMPgHP;F| zF8<`BH|crjTG0Mhtew&rkE^9nKW{1ggcZ*I?#j1B75$O^w&OVM4*(&tXZqx8=9CIK4#qEBEMt_P1T; zl--};D!?@#S1T_1P;q<(*Dbgn$3>s@xcqb@K8slP8N7(^!}z`**Gssz;L5~helCab z1g_npEQK=TZo}aD@z5 zg8T2Y{B?sj;l2ac=MDBH+-I;{Y;d{_vfP627jfN#>ub#R;`@uZ=HPmS*-HMVuZMA! zu7swR}%s&l>mpaPMXLQGD0q zx{~E<`Ma9G+wpxX-+vX~hj3kw>$A*`^0)o92RHwM>&v(f;<^FXBwPVp2XIZsMW0!? zK85QWB;d1Lf2lk1eGRTMTz1=`N4dB@LpS)mfa`m>W{|+2tNA;dzn{VPg}AD4EyeXD zuI;$!)2P3!|NblfyA#(|TzBJo0M}Ev=u?5~UR-yO@PF{J+w}jdstcfC94_uM##DD1 z(;trc^dCdJ&$&tj?PA#@_!1#UAb$tfO}Nr={Rb}lb1rT^X$!{p6yx5!b+T|6-^Xy> zi0eLP^mV&&|83k~f@>A7G=u+$?_cKcAMp2Dd{5d`VKW zO7^<<(KG5Fs6Qb;p%0Y<)iJegs-Flh`cR$QeoSReK1lv_k(&5s&b>dpd28Fe8^Z7W z(cK<719_-~`|$Ko{!@>`W4zcUkXPXfRCQi5`( zaWlzJe|3WVemOzA8%oeF{tJ`DvFy1wL4JRp zpk9t8uyZIu{RR@~pM>@}mOpeS&_5wT`1S<-WK)9v=hg(_uTNm-S5R(a*?C!ldbu(| zKYSPbVJtms5~TY`f`0F=1nK^4{MhxoFF`*rAwfH>Phe+x0y|$!(67>Be60MQft_RV z?;&y)b^?2{6O7A63EIn+1m$p90{yoqXcuV-?EGQ^|H(^GFWm{sZFK^B-b;|* zfduvFOfWvaogiOB3G7*tpkJMkz(0Kn%I9Q)e(41`$yk2!L4tZbH-Y_8gdeNl+nT`s zdlK}YzfMrjLka9Wkf8iK5|l%Bf^wUjpx+B7@P|7R==oj(JFiUO|G5du^OXes>IDhf z?{Cl_j#d7zCGe}l1nuRD1mny41a_`TFz@vyNcX-3dKM-Ke-->>tb8RUsIPkx)O&4$ z{_y++^*b$rJ zmIU?ql?3IVl)z3;g8Y6zft{`d{+5$K|3zp=WBE@kLBE7z7_;15&_9-*ngs1-X@YXN zDuMoQCg>k-Pte{!mq7o2Cg_)z!f(g2|G5P7nNtb$d@8}Xwk1LN{{{XtR=Nul_}i8Q z{;&=9q+tiv_haqR1?MW)MCP z>o4_|HU3Ug;R0<>DQ%YGQ^x6f`n24qAFCG<=$T~aYoZPqMt?+~pw*5hsmR~7yomL@ z2|uLriMcemm3a-uWs66(;VI0YWP99y(t4;Lq|aBOpTeuRwXD#d>GPcB=P2iKI^eTh zKI_=d=w!`leny{V9A2H$GSw@6p5pvUe^7;m>o!zZ71q`j)zlRhs>0Rzw-uI_)s(HP zsI4oj$-gb9vbw4)zo@vfOg|g@NnuHSQQ_K(s-nt@2N3Yy+ZU8u6A|F%9W%yuWm_YbxBcW*^Tp8Zsvp*t*xvGthADuKfiEwRbW$HR!vRO zRz?d7@7PoqXOuKqw+wo#Y6I1^WoH{x+iJy+Tam+7lFd0Vx2|mUhN5-0wevGd zHW$^@CtG4p07os_@v^^rT zu53eKZAB$q0Qp|KrKY0J3U*6g-QtqEt${N19rG6!-d4D!qO`0E)qz$=zM^ZXuDqst z3mPtEwzkgpq0EX6rDY}6rDK|F=VnLjlUG!xy@>>KZuRN-C^d(56OpSc}%9)mpZF^x4vNWpyaz!j)%{I*ftuRd3a* zkP0=4%#!NBRw_|gmY0E^UbmmWn^9^36n7=+Ik#xDc7Qc#>F5&-at{?bkz1>aN^K{J z-`|D@H(G^hwl`9{AY)UY6zwplx~i_CY7=^Pa2rg`&qr-7;{J54ZdhYF zHie}D$Dpnc~GK}XQZ1yo6w7>M=t8-@gF2*W^3VbN^tLG~;Q)ChhSY1*M_WU1Id zvW148va4 zCiKqr2v}HEU9+L6vXK0=h_v|-49#=p${PcB}%wR1eKcNAn)n})BQSH{M5p_U$&_VgZ5fX=RcmAi#L7zILiXXMJ4OkVmf5^ z;b&Kh$QtH#*2wv>YBm$|LY+10So5usV%f_2lCl7`6PmlA;ZPTAPfb=?Qz>xVtgNY_ znc1e=kzjeWzN9XT*01=!3Cm0CDb_5sblDK#DRN*_Ox#!VG9)+7L3n(h-8EKArY zWLH;LQkPK7mTDz6dKy296%|+4)FJ70suBxyyVJ=m*^J(%63h3qG(JAf*QPCnLad0^ z&7ThwZ>?T;YuVd#?Yx=p+3GQcp1V z8%f%;vwC3ag`Z7nSn zZpX-%881O=9zuOyyadnEl4URi!$8HlDjMb%S<`<*%g3q*W8yZ_%&aweMQv>WS!D;a z7ygB1c3Y(W8krx7g;oFP{UOZB@PD*p%lGwE3x0u(2p~+ws;UdEod+~*Ym*}07O??Q zW+YS_Aa7nv3DR_FB*jHr%CVlY*Lh3U(!7us{3Q<{ELM!xj>uRwO5?me`>tkJjW5>K zTKIV_OsuG_E?Ks$u(r0OsA?_kiqr?zs>)J)Da=1%Ix(vm8>Rm->W~-KYc}ZFDvj?W zD_AQ5UfN>%%hTBEb(qkP%wpj^6^pFdwjM$-8pNa^;l- zmQbJ#@w;^;*i0p9K5tAe6$YoSediS7)eIx3134DO_;%f@SgB`AhX} zK>Ei-cWW8a(F*x(ATg{{_i;Jd6E@Qhot{f zIEp>N;`B6$Eg&sq2mQ|lp3IW1fxam;ofe%Kzo*bTgtm<&twrZc$Do+>Tx+-OrLg0z z(Ao+LlY~oKOE!|`N%(KF6uX$>Y`Rc=#mMYv|L@oyPO=>fiV|rBF0TZ!#vT zOIhD%8?JzSj#|X>)}Orudt54;<=0j zKzd8gn(<`Ka=n0E>8XM4H@Z>`3QPkds6 zd+4AzK7E3_>993E{elM;^9w1z)@SE8!unl;yIH?maO*HP^rr~!W&P=bceDNs!L5Vt z(32^6Kd0*z+|BxZg7>rj0?GM@0e-<_tiN1xe(_f?xGSK`D=2u3^*0F~W&O>9cd-7j z;2zfBDtMIjcL*L~{hfjbS$~({nXEr5c!c$L3*N!{V}kowf4}6ce^Bra)~||2`&*dx zy9D>J{uIH>S-(f{FzZhjyqWc92;NUG+VSxU9%TKwf;Y2%pWs2(Um$pd^_L6Y!ukV( z2U&l;-~rYj6ug=BHw)gu`db7Ku>P>%e%9YAIqUBfyo>cm1oyN4F2Q}QKPq?z>yHT@ zWBq-C`&fU!;9k~0D7a$%s(7@&MGk7&C3woO@S+_bx8P0xrMXA&F4mJSxS#c82yW}~ z3La%Wxq^4SsnhidZtL+2-pzW-1#e+J0l{rOLBV6Jr%7->>uDC;))N-IkM*<)-rueB z)gid8r%UjTO}f6Kg2!Iw^ALjfGmicWWMzoa?ts@aRiA zd{pq}cFns5cXK(%B)9!ja4+X;Q1IxBTEAL9+Hd`wUzgx^zTA@Aek-`0FOT4MzS0G^ z^OYev=gTX20p}}M@aO@ZFQ4Fw^Hm_YoiD%SoUd}h?R*6UxARpmxSg+{a^xz!84e*3hraxA$UFWPQhE4M+EO=-X(Z9^QhozP}|upxQBU6@J!}?g8P{F z3trBAQ1Djfs&ceHcQbbhKFHiHxMxV)pCWhxbC2N7%+m#LWu75;7xPTP2bp^X&wWqZ zlPh>RbD!WX%nJnXWbPL{#=Kl`*ZVr%fZ!R->jlqc9u(Zqyh-qS=FNgPGj9>RlX+P1 zDDzgq`AD5aWu78cQNl4ypMTIaMuKFPoLoF%=-n;Wj-i)GjqlJvi3f6l(|cAmrJMX z7Tn7`MeqXV9>D|5(*xl|(hmQ#!;P8Ed z+u;WV@8s}`_YrM>v%|XuS8r&0QUtfdrwg9T;WGrc!+Qm9=J2_K+u;iY@8^{_cLRHchqU#C%A{Xsu^8AG1l)A+|A+Lg8R2<{V9TbIefa{VYb67xR1l<3Lazq zKEc&iovvSSKkF$MJjgsCcz}7m;NHzzf0N*uzti>DEVx}?VZnVIzEyC$96ALLvK$fI zy=NAfwB}L4> zf_vx>pV6l-fqx1fZqec0f=8LBNWNExPZzv}?Z^<^&E=LUxR1G4@Cc`yD|p;L1&{lu z;O>3ePQT!B{}ep#pMtBeX+8CV$Nf|AF55o^kNc8{lE{GQXEug1q^!Q=g>;PL)baNl>d{&c}x z*p3XreOzvtf;Thw3Lfu21&{lu;Bo&HJmYz7r(f{6e+nM=Pr(D<)q3g$kNc_4Pv^H!aJ#?l7u@#eLBVZ* zR+~rnleRy*1dl~@x^BTc-1#xq|z++W+x{FB-1g@t!87J+J4Mw- zpCP#I|Cxf@{_hps_WxYLV+(bO?%d`?55MA5E_eq0p*MU2g8MgV9u&Nv%dJW94%X8wct7(N!4>nc z;Bo&HJno-@yUVqmor1^xQ}DQd3f^3=^+W}a`={XQ1pBApasL!Ng~Ka8k7mygi6BRt}pMrP(S^MXp;N8q!e7?!{!+z#&$vM79aMxe7{&d0ZbBURPdpLZq;F-*Q zg4^fi{DS*9e7WHEIkbAgyV?Gr;C?>3o@SH(X_ zd1!R_rYE)R61=}!hj$Ae{j&Z8Vkv@W&>v*S$0K;;I&Dve;JJK0FH`Wy^E$j&@Mu8W zlPh?Hd4b?T=6=Eblktb%@F|!49L)oQE7nslc*b9}ok7849KK2LKF)8m;BGGG7Qs7s ze>*I=m+P@r@W?!EPlw?CPR%2N`#9Y$!6O&x_k&TvJ8sr`VuJh9H188UgUg{`aL;@l zeo%1r-1os@&dOd>s|EAMT7d*UF^9;fL)3u*uO8yDW zy@Gq#&RoHRf71GWf@ktMzXHKCzNhUk7d)^?>j?<%<@^Q(_a|vPn*{f4)a|QTaCN8F z-y(Q3*GpLN{)M_9XcgRlM%&*ZxVlg4?-V@D7!GuF`s9 zl5_Yz$ytBD;04d>d<_cjAE(P%HR$K@ac!l}uUqiIceOn!l5f}H(*^fFruAk>&h0K! z@cuPgPp;rm&X-Sc&lhy~0>QoPCw{>LoNl?`Vb&iI+{5o#>IJ`^^A!|4;{%=FCc!(J zG;bAL{Y95&hv31>biO(TALQRT*#8cTU0=5BdUSL>w(xlD7Tou?)}JD{|3l3)1b2J% z9|+A9JcEB9>J_}>lRA8^;K55Y_X!@oK=T5@Rhs7Yf`{j89uz!sx#mrhv;JnmeHZEQ zVZmc_G;b9=m-E{pxbo`ooq~5P)jT4&m&>zD@Ysbqe7E3HwkIZest(^LxQBVa-~mo| zP;d`(#eQo0RfO$v3m#;9QUuTB^6?1nyI0$pE_nZ)nr8?e2<|^$ z^G?A#m`4P6Gw%{SdY;zPEqLaYdVb=1YIJ|%Wu78<#tyB=Be?Hw&C>-BFVj3z@Lbkk zF1U|*i{J&!!-7W_Y5lE&d$w!dA$agJns*A`k*Rr?;C@awD!7-^?UsDK))Nyvqh9kq z!JDtud{FRmPFJ;zu9uAEI=oBpScT?p!8zyj z59==wyq@*@1&?rfmJ8l|tJWV7JesR{z2L#6nm0+#={5`A!RfXL?k?4O!jji$-YR%( ziRPVxH*vZV!NZ(xm*5?RT2EAPca`Sdf-6q9Pw-|=cTjLQ`u%2|m zZ9N%++j?>Z53?Sh;LV(Ff#ANIbbkGU$GAT!7rf(o9ll=hR!%o4c#zX=61;hp*3&Gw zJ6rP>!817BR>3^$G4?sd<6mf$KCc7d*=81_bwWy7hwF{uvb9_Rl84 zW2~n|@YbvK_}D6V2lGzBJDJA>cYjvrYf$juE1J8X9$k-~mo!foy!l1Vy@IPHZ#wf7!84hs3!ck7Q}6=j zxq_E7FA%(*dAZ#+{3(H@DBE?Cc!(Iw+bF%-YIw&^De=o z%)15eX5J@wjJap;=yL13PUqJzct7)?;DJ=V|KB9Ie~#v1!3SASL~zeE9llHO@MO(n zf-C-a=sn@l_PdyS1@~N}_2dd3NzvRdxSRFV3+_FGf0zWHpx_au^)v|{8`j~&f~TM>*Y~;Oab`Zj<01m*&la`#IgP z;F+9mOmHuA&;HTnoXgxVxQ}^Q@B&-E;C@^GGo$sFGtU&f!!Ccpz4Q+mQuzxWOVZpg zc)+$(@Os-$!Gp}pdEeUJS7~86Ab2OsO$m6j;I^Jt!Mj=Rko-AaUR{C@vK*D1!}kfE z!n|Mbmglv87eBZ2o5`|U@J(3Ruo@Jlp9KKxe7M25&zo7Lu3Es(a zv*aAURq*ZuT2F`IE#J_*OYlJs9~Hcl!}kfE!sXU4_#n$JejYD>mfeDPbNF<@3s}w& zyxT5+!RuM}2|j3-zu+w_2L!kEHwoU!aCK3DL1mVJT`a`cJcFg`Lpa6yqm+P3tqr-hTwMiT*2#E z_6cs=Q!aQ5%K^ddd^HK)$#S#cnJl*o-pz7{-~}vq2|mbjRPcJ1`vgzndg&Lug=H5% zkC#8oZoxY_e7fMaA7%*N&EazexBbv3_#lTb7rce#fZ%q%ngs7;xmoZ`mRkkyX1POf zTYs0}gDgh{xApf4p3<({X}{nFEW7x5y!=^q3trFR(*-YJIYaOk4xcM{J-2V$+z_N><$IG8(x8U_0K3(tvmNNuz;qbYF*R$*sypzM13*N$VK=5u3 z-z0b^%gurha`;xkyIJlKJcZ>h!3SB63ZBVwpWrDkarp~gz_N><$IG8(x8U_0K3(tv zmNNuz;qbYF*R$*sypzM13*N$VK=5u3-z0b^%gurha`;xkZT%gBr?A{5xUD}bcqYqz zf_JmrpMbkMbp6=nKgi+S3AlY;)ei43(EC5>e6G{x{neUh2=4i&PA^k(PR~9cYU>Gp zjrW~I_>P}y?i1YeZLPmR@^5Kw{|+??KYP3u`&smFH_*raJ&NS^?@lD|->UUVZlA}O z+&-5ld298Ep7pT9wkMK+cPHTe3Al^@?hB=B>h~nznF+Wr0WVL$g9&&`0^X5;cO~Gl z1l;~RH!{EW-yM4Sr*sV&B`~4;kEN@a+aKFnFuM{RY3);N=Ft+u#9%&op?w!F37h zhe3niYlLqyc&5So4gQ?L2NUoDJ|9ixX@+mzJW`L`%AB7ugWs{_P|BZ#Q_o!Sf96Y8VOMU~rGY zn+)zX_?HacZ1DXCZ!!2Y1`iwjd4op`{(`}~4E_y+M-AR#@NR>D%ivz49=~XC71ZV6 zK)vW+X6c76gX>>*Xzn&R{$Zo|C&l3Uq`H3OF}Oa#t9iP?^@$P9GYqcZ7;2traQ>5L z)&sA>^&4;3(c*KBb7vsCdJtp-ntYr(%aVenZ7?=<)Y29Fs0LW6f1 z{33%#4Sun~yA3|a;4y=H4Blt(RD<^$Jk8*P2A^wiwPVEpFEO~w;FlWQZSczso?`IJ z4el{`y1~;8eucp^3_j1`nFhbo;9i4YW$;{sf70MSgI{g%0)t;;aKFLLez@G=^NsKU zgD)_6y}^$eJZSKR25&O>VuLpu+#Fw848GI|A2zr-p0*l%nGwFj;MWY=aLPJjdXwam4>`G`P#)D-G^8_)P{+ zG59Kjdkmgy@N|Q(Hh6}?BL>ej_;(EMHTca2&o%ge7~E&@TMS-caC5%rH~4Kv_;Q2a zVeo*#eFm>L_?-q18hnkxn+%?B@MeSGW$+e*-)-=)!S6A6tHBEl-eK^6F?grJ&G~A? z;GZ(WcNzTC29Fy2Uk%=E@cRrNGkBrF`wZ?kc)!7m3_fV^VuP!lBmQ4vaF@YL4emC0 znZZ*GzSiI#gRe7qy1~m0o?-9`gJ&B2euH}rUTN@LgKsdn&)`)CFEDt(;C_Q|Gm8rLn~m@V1`iqBZ}7(r zUT*Lw3?4A}ZiCkw{7Hic4gQqDn+)D!@MeR5+2Ab(-(&Ew!JjsGtHHlw@D782)!>~5 z|C+%g2H$J&E`#qgc+}wg4c=|=XAK@R_;UvDGx*mH-f!?$gAW?K&ESgH#kBryH@M5- z2Mq2u_=^TlG5AXc_Za+}2A|_`{^HDoue6ZmnI(^hoMy-qA!i%%d60_@c?#r4L!JS7zah_t zeAJLHhTLn&X^hP(vwenY+%@=-&+0dlV)XG3;4 zM$*3ta+)FE3_077Z--oL$ZH@s8uHzc_Z#xPkdGSjeUN(%xfrs;IgHRN8%jtO@9 z9h3h6In9v&1UcJ~{|dR-kl%saXvptE-fzh7K|X58A42XmWJea#ca5Y!9&(x?PlTLp z$mc;WHsmRg8x45|3!L%tevu^}&j+-S&4 zAn!NiYat&sd@tmqhI}97 zUPCU1?3gr?{#wXshI~KdY(uVsTx`fSkQ)toGvxh-`~c*mhP)keuOT-=cAPts{v(jn z4EZt0*@pZD$i;^IIOIk{eiHJ2L*4`Vs3Ct1a<3uphwS*oNczu1PBY|o$k~ScBIII2 z{ubm$L;eor{f7K9Jjlg{JOy&2AhP(vwenY+%@=-&+0dlV)XG3;O8A<;p$Z3XrGvsVTz8!M0A+Lel zXvlX%-fzhFLOyE9_d)J8#a%T9cqVWoU zIWYKIs()T6G(7wiJ*(#L4g9^Hzbo)PkoSYOClIF=-3|G;Q?)lDPLd;R@to@&Ln=Hu zbO)a8B)brnp7|F!hP<9Bq19#_)v9%cr-X7c9Yfi8wgYiIUdIsG^@S9*+qUDwN!}sM zw>t*%j)8A+J&g z{lmjEiP`xH(zD>?5S2wLzOnawBBE42)pKfi)e!c|4)!~f+7;Fr6iev>%F*9==Q3}ST5Q?)>zjsx zWFwVfOZL!1@V9Q17kqDxzj5-i0o2Qx2aj6oA>006BR}>%eaD~$Tzvixm9&e>1N$ZU#pim5Rw%~_>|tQrHTZZE+5qYC zApb=!HDt@B2=@+bDs_2>`bAljeP-JKe~_vD??gSRhde*0{3Im@Uwit@NS%=Ul#rhg z@)w1?OURE38R^CAob)#c`9UFX5pu1NtA)H?$mRVc3|+|Mlz)e=xhRt~l#gBR$BpvoHOl8w#5MD4)Y+6LD4+0;;hb}RW|ckaJV|*E z59Fz~p$DC9S?2|oj7#<&K3(Eyn}xmue@NtyY+lsa$ETQ;irbrPZ~P<_^P2E zXHrNdt2^j_PO$Drx=DJ&>Krp=C4o z&Yq)^PGD@v@7d`cN=5z~;bXCCuQguuYym?*{17puu@1T@FJ$K%use14O+#-KtI)f! z(aINWehm5Ajq;%K*`2LIC((xfg816MXU!YP^R`(&T#}9Y$!SBqg{Gqpoyl2Olx#~y z*{hAWo*d2}aL#If4tyE4OZ(euQzJU;_~Y=r2mJ!sNNs*O?99ekO?DoEo!PK673JCk zJF}>MV5c8;QoWI#mhG_f80T{(${2k^KlL?Mol$&_w+8WO9HM7`#5eg4T?2XFZTk@Y zL?7yXMY4MPv*=?y=c|K9#s$}qUp7JaDa7%grw&d-IZuV(kx#x~o7{%2&}p^fRj9$? zc-xD3!TSd?Pdlg1y8vlg&(jUhi3s0Iaof*!LIcLwqpE?W`I%k|n{ct#c+A+_rIcnzmBOeUs2OW`RZy~Jz1D!X8y!B03 z)uu4UUkJN{6WDIFQOj=Rtpj$&{bqd*%I!v!H}Z2G^~e8V^~W)UdmiDCC#$?-C=Unn z(2H`T@*-a@bniIv%)7%Vvz#`HJ7=4U`{P(TPr`?OPWAkd`bc_YkF7)6LiP7J`w7_< zgk9vHFTxMBzr5Ub(&=g^-`E6u-$j{|KXhV_J`?4=4{Iw2%HhKc;7^zz(Y%R#Ce=N4 z7x{|Eu3Pj^R7S%Nbt36}Z`LUrvqR~;NipY<;Kp?fB%Lw5LHw2kAiITh*Niuy9!*g?p#%f0CL#v(d4e*mse~-fK{IDBGS%$!(Oc zOoZQ$JjcdUAEi$8pijaaa9R&!%5SQ2AWu6^6gyS^roY0+kw&(fzRQbpaKOj2)4iC7 zuXv*u`K5l)i@ekGK8(Q>#%c#w>9WGPwP`)b8`*g+(xrSRB?s4ho$@pndIpCNy@I;i zyIr+Wn8{Y%O+#H_>_xxz;RPde0Lt?dgTn`DEkXIYjPeZ~y^!A@8h+~g&_goipUNQ{ zWk6}f&{t6T#W1fp$Z1i3V)r>G$rhyjj`cmY-NSYDKEi1K`F`8!2OVuQ(XWvYk^h`R zSxrS7YH&+lxA%e!_z^r2dH?M?cb^4%?2f{?iX; zqm52~mCAV_?^x^a-W#52l{q-c5$DMIirVcChdM~>U@Ehd==ZTkX+QN~Qrpi^?$p;} zTsw5?LDHqyHhK)2+Wvjyp%?k-LEi1>%|oNtZv%PXZ-ZYQrgb&^apQj?uO(=wC5y6$ z8X{>Yj=3<0z`SAwo_%s0Kg*fj`sO!?Mo4s`p7c0 zA)75=M&q^3KFRD;21{plx54HzyOS8N9g4Ue_;=`b;72>4bp!cUk<}hBhk#6N!d{3e8bdPk3R^nL)Bw+eGD21pEJ&+dbK0*^}4a)_}g;>&kwB+CPmQ zG!LNp1kFP{3snAlShK^oI>@d;%=c2CJ-Yn;XB?r^$DE;)PG|cmr(+)V8-3`vhKI+u z^*F~Jh&jg}c)#$xw%Cf`@_VfLtFP_#3)Mjn`mfkJb+~Y@+W5H(ktdYZ2T#yC=R&l* zsqNX*bpK17`euuvFQPu#F4xo)?q|?HduFSAl);(4<208}X^-txXXav0!U{V)+^@Ws zho}zFzD^XSBfTl!!`CLIEPZ*dYpK_B(G<+x*WkVT(ml$(WRB;dcc|R5y=wCBr`~bJ zD-T>;6Pu~>Z*pCnmzw?XYxt9rQ+Bw%`Hufwb!X}&Ki)(AU+TFR<&`#N;m8TC0g@Jk zw|T#veO1ouMQX?F;5Prau@;y-0p(6*lZ-GfDiQ6(%x6_wZeK&r$YVr;2H8})qiYK?tz|LBFkfw#vSOH zkaakAM`U@=!r<~4=HIcU!R44YS#$I)@C$lw)z8;aHdxDCHAnj$)iaHQy$`A(s^^}Z zaUloBz1{|e`f#CM&w)QCS^iZxtJUAMAcsmv-X)4}CDr#dlnSaSGwB`FHQCA?k0_k}#K2D?-~b zRvbY&6k)6YkEUXth$XMEjf#`4=v=7;Sl8%$YpzHKaYJ4`ZEj0?(+P@J~#{`!n+4S!`GM{1G3f ze(WFC&sqBMk4}HokN=GEl*-_2{aF2JIRD$wb35{T@A&kkd;VwX5|yOO;7#n`raH;D zXT|I3(+Ef9n{$<#G6(GjXPxqc6RCYBulHiS?w#vEKQyg93+4FM%*j_Yq3&q>U5a=y z^pp7Wvs2!JUMio7V1HQWJ)HEGx`z6jbWixT%e~>(deB#Ry#9-OosQ6R=l*zh3_72I zzP{I8Z4W~pzC#WDG0)vLyh{!JeyaP5mypJx-w!W7iFL@;WFOaI8`8nQe-%28`dJL# z^9=Q==e13>Y{6U*ZM7F`u9v&#Ed3ta^d!YUkMc8a{k|buV|foN%sP0z^K330R3p2QEHo6*f;w;xV08VyX#3-{dU`Y3h7yG zb0YSx@hp$(1kbHD>0J@(MVtHr*bb{rj?822Hn|GV9*6GdkRG*_EAjnvpDTKFw+E!+e<1N`XveZ{;Ga0*8t`pG}m~a z<{0P;?fD1IJ&vHS8^rv=iTN?vGKBWifHwD^Si6;>Kcn%~gNyX+uYb1lVT^}ro8##Q zv_;x?!w&FRnWeNHA2hTV{{)t&vyoWgw^+z->D#CaQ`z{!6I43?w`e41D zBSGiJ4d_2;4u<`|=r6IhJ$lo~IyT}}`O}eC@;}ONwtJejX0_I%yms#$?`?YpYv@B* zyYHs8J=VH=rv$C_`*4H1ZPPjG;Ayl)y?&Y5PVI%(FG*OlzV|Neckn#p2CO?^dk^+4 zOE9NQ{i$bH_O|2;VmrM_BCE||Z-B=^>LXUcE;;T$!g2i9=>Gkm zANOZlt(sFM`Lqk6H%Osta&d5_@?@*IXt4pG_CK0&s7 zWWJ@QV~j-@%O8ySaVmU@%Kvrrp?3K%6-l;m>YMr%t1ixRzP^?8pgySFtn%Xd`qT^6lvD7LU%*H9@w&F1 z^W?pF#77j`@K`>w3U%eVSS`+*susODMbGP3Oi&xC{!&!S9)&ujGF50pRKC>4Z$}(@ zSAaeszOVOrq)Ci?zV}ho?WA+sZbZ0V!!IenXmf9;dL7o@V?UnL+Ebkv#(Qb+Vd^8P zFSXXock4dPgZ`@s{n(-Hjte~H{=q}ry-yt4uAcUzjUUGvlls6^#JdZ&%|U-g`(;N` zF`qzrDUVug`5A1s%8b{dmm*KpZc_05|GGYGNaS-^A5LSR+u-9!}-5~o>FSR&**t)5$-?I-*f-t z`StK2YL_%#kl$>l`6SxbBIN&J+!Gtb{B{FztchNOZdwx^MEz&}&+x&dIq3V~pZ0#r zd)suIEW#K={d^kqko{@`$_npf)lR*ya@(83`Hs2hm&k9BzP(;dLbw%NZj|=zNY~mQ z_$~H>u|LpHcAzaKBmH6;!_W^Yb$KWYYlm#~zbNw)LFlG1v?flvP)+SZ9DC2`wp56u1UNYI8Me7J>(&67vNIJa9YQHJ%Zj>YSJ2bbZaUExGW>Ok7mp?{! zp$*Y^MPr!%C&PzkgYC1%*^%|;B*dMH@r}aOW-kkU31Py4h%kSBSE!l!9pJf;0Lge4okj`&9tlz9a2g(!?&=Do-#)xmz$(-Pdz;5@&9Jkvau zo;{6ck3%<&t5nyo)Ffys8O*GALZ z6`tJ!-S@!;ynk8q7G!FpraiCYIhFOL_@*?>^fM5i(m#T>OV9p{F!bD9uUw8Wl;8Py zM&rS&kSVP^q=T^5n&oZix9|T8_f&pl1NmnMWV*NJq$pE*_9Ap00N;npE+^zE|AT?C z%V|8@xexC%$df&fwTKHo=D9B3)TF|4V70 zY-lY<&z>XMUbphPF$P9u^C!eV1HBK^1>JU8&|1#Ee+~C9qc|o8t(DCwdR;n@D??jsxNIuy1)maQQy$bK&el8?BdObArov z&|Crg%nhKQu+HZzMpnN7v?r;m=8G=_AlvuU9uXAq0Gu?UW5L> z6#L^zScjEONp7QelGtO${ua&8gKLT$>VV&obih9&xcpwsFKK?Dum&wfI(w1MC$P6v zl%~guG#)SJ)`zWqSXvA1E&FfS*2VDI5!yl2N) z7vI06_MXK0=kPv%FT!DNtH*KVu?J;l@54G#_jrGN*yF%l1$m-AjNX9_a{-Wljz93$r_OJS_HU6*B?QiOV3kRtbJ0o`Qh^q@5yQ_ z-ILTtd&foC8~)4;?@-wcHT3Xogqy8~iXF*q4co`H?K9d~8}d%}kR9KE?j6XxAD7H` z5BAfKa6AQHdK&S_$31A5R2H%C!pFD3$MH^R4$o72AJpy0o^SOa%nEy++CcmBGpu#` zt?(CG|C#!Cvi=C>NtXV5pnnzVcaG>szX@AL-jg6qTtDir2fkpppM~U;w|Ea@t}@bo z_*~II-p{NyRB(#g&@}kj%=Rtl!|i%{mf8aO1LhodTlzNiJ!G|o>Fsr-+ipujXTx}P zSnHhHejohxMZ{_3HnxlP>UUr`BX*BEd>6v3v-HkvufqKi>wZ@IdfZdnqxM7lq)sbM zv}?|nZfn!q?_^u%AiUky2J*hwM(?^$;mqN1gR?DydZcG0PeyoaKh>cQ_2K<8wXst4 zAM{P_dBB;CvqS3blN0vNHuo1U;Q9$-&44yOPrn=gp;eCdyy35iZ=dHr_BPhsu)m1r zbSNuhFKAR;vWwDwh4b+j^c`fsWiRqT_J@t=4xtZ5e=?)p3H=z8)_e|oth$_Lv~S`xXgv53 zXFUh<%sQCS{&~aRV(9!!+`bv@YdP-jf5N_<3GBmKV@;`H-);ZEzB0qUYlVF`aNNp| z*!LZr!%9Ma)ldZcomjIUZagQj1Y^*=8(nkq#wFi)1-+kj-n{pgV{U&S?vt>$*LLxy=;V-HW*g z#%0vsbgTZBV}4Kb1*$)@zgxw=7~``6a?U{O{^LAnXh<+$n4_jy{pn!;NPnb#LeCM% zhJS%g)DCe5Ce(vD6OGTQDmio-Wq&+bMSH=h9a(FiaB}F`?Lq5(%{ufaG~bKIi6w{r zq~r9*~CNr?d7{x|0U}> z$EfRMuIq;{IkpGy2y|UL9U-Sx*FT*77V4Vnm+HFbxC-5f`hE-N<$9eHu4q7AA3s0Y z>K}Dok85*Sb&Ycl*b_WCJfV%o9;)jS<=B;qdZs+}PH?sPsjg=Rm*b!(?YqV6*@3i< z;=K!y`iqRjaAo?@u6oMbiMr-+#opet8g7zH?Rt=?LUm%svmLqNt;!Q=E9y}vE>aBY^!+1e^Blg0&VGHdS#de{r zvG*TwB<(6jzYH7J{2pOH*hy!9=$y}m?Z4PeXV5Qfe`32ngC53utM54NgIw62g)`{0 zw%`o_S0GA?BQj-&@+ZlwI9 z?5JE1S>-*e{a5#=4j#(J{0ilI3OZhg4%*LxFN{9NZk#=VAB2hquy*%&52vb&7wm!F zL-3h}D7Pqon>tQoZb@f{DPA7pQF+t57OF#A$7iAAhls1&BF2Bp3;gkEaANz|UMs(_ zvyGoW!Oy9DZpA(M2IcQp_j@c~p*@Bd5w;A^4#)Lh*uDYf`UjS2KT5Y>nyn~m}?*X_4rZfCFC%g~lzp*0l7O+VT? z`rX&&a=)28#_u#VC54EdlYkU20V;2ZPcIOoqIdZ_O&ll zGhR)aws+5BrC#X8d!kFFmF&=wkSz8`&C{t(KG z&Q+%(+%ohH)CW^PD%YG1&RHjd==VL&$Z}fm&c$9jt#ec7V2$bsE>C;Zd%$x(p7FZ2 z_z|*kw0&=HcI>8j);b&gxn7UWqITK-9{i8er?e?8`n>_&4^jW^oOWUdd<1_-a#|Mb zycgj-Y_GI)uLJK?V5fJI_dpuTFl$m|xd&y4wef)*r0s=`Y0l)fEZDsQWtloDxZESk z@!w%5g|+R(yEUvEXT#1}?NQiC>65LL7TGy~GW;FJ#mE@r;z8)5wK>Lze5xCBT!c?p z<07>c8Y3*93Dk#X@m@PQs{OhkKzZ#BS|r#q+bvd`5GuElR9CZaE- zeJWZLqu;ZC3-^k{abo}DjeD|_9lP%8d+>E?qHUi z_8qXTkXsb}4&lP~tMxtJL(uQ>Qrd6E^Z&&~R0E$2C_2? z-?Udn<1^VneS;t2Xb$7Ce(R!jO$DR#`4rd9aqkBEEwQ|p+USgWD$XPx#~wzia`8SG z&fp%ynOr`o z#ZzLB()X+>v08Q5kF@Bl&k8mBL=XCfO*oVLG=5`@bE=0U(`a9C`n*FE)fBu7K3p^v z@8%!%9^QfdLVEw!gZK61m+;*)eW(|zi`X6N%wdJxare=F4cZ(l_j(_Dng!YT)TKTc;fJm{NZwb&!VSqRSr>gQ*) ze+j?u`ck7lbA#Vw<;SjxEZ>j5i1x$6+4v0$`k~$lHywyw2abN|73{C=M?VxsKZN|m z_p<+c6MoC_UENP!^$F}5Hz58P`)tASG^Qtog5wqXIFz9Wc47^&0`D64!9KYUcNlu9 ztp_LbJ{i*Z`1^4Bob3I7vChY}QCb7o?}@GO4n>fMB#%C``!zc)*dKcV@9@sG_R=uM zkF;^S{o8wLRK^~>w?3}bbyC@@e|jGgXP)sc`dZj;l^Oe;AIwf4 z^N)Fcv@OihCf|>5YU5PD)Rq-|f_^_3PP=Fd&K9is6z*|m`7rfM|;v2-QGusuSxA^e;V_=h)|kuOc5z=JUe*UTGcJ z4$CJ$dN$F6XX}y1cBDNH7rhtzGTF1rJ9HN~^7!}b0QG2{8A7>GUEpsprUtM&4oD?-zcD@bhpjhfP03IP#|(koGxXGOcNx z))B1R=vh>!)nTQ@@6;wC4Ee@%JWGepmmpKQ=0K-iSJc;2oK`%eeOS7G4);I6{RxzZ zO!r;rqWZSe{gzHw=P{zsW&Q<>(mjp%6OnER`Y12-uHH=7zNhs7rTZwteU0xQ#{JW{ zx5jStlLL9rTfgU^c^;J)jR)Is-iOYb_3j+smJOR|9*Oydb@o!>-B~ftuchMM8OtQy@XK33=0jsDJ>JO24f z{q7<5)JNxzJ;(9h3;TIAcTp~Nr%K6spnNg20)sHQX?xEfwdl zPvW=M!woYrSH`Ue z1?J(mdMGbhx?FKSvFG2B*FT~^L)qf2&`>Yl)5tk&@1r*#h!sYb_dYt|0M*m4C#Xf2 zc=X>ppnTfpXyx^ogU(8>dF$Kwdk2NcYYFxjjC|h;-n0C1A8&f$5us_ zH)5<0in0FZwHWJ>A6gUrbO!7|xd+D>>*@U>jrEw@3{iO-S)8HdfhN`q}5=`b~dB zp5~|vP6YA(@6*tqg5PgvIWcF#y0sYV);BO;#u?C8^_tZ2^c*LC_lt8?)W)b?^er3H|Gs~FD{3GS8Qcg6z zKAcbQ3aKBn--)e2Uo=55nlE|5>@dUVBNl@_OJ{rHai_Oa+owK&_B{?E4|gHXUTc1Y zb06Hl(%AzFL*xI=cpk(34YgP+flp@Eeb;yJH%m~Kbk2vury~3lxF=hBFvqgWHas!(3hc)C(A*2A z-)*?8vPu3Iz2{BylXuaNpQbSm^PN!= zEqF=--V&vyimhqSIRvmsiztG%7d{hxA znHO!yRQH;6F=VP}{|@%o{F<=pK4jS2iTf?(@1>86j9th(nRb%=LYM1_lXds&c#D6W zgi9ZkxQPOPip;}m>mZR&kju}owj%94k8&iPq(?W^%M&_C8%kSB+$i$Pet9dMwFYXH zpGCZ-#~baBou7O|2!Ee^5@zA^XZ~*kM^pCeq|rTsqe&x6{=1AY={u6wrDFUo^r=OX z4!rN7jEBKJ!KBAK^l{SS=bq~qxzqX#$|Dc;Tx5K+^@Z0>eRR@Zcy{&=pib&Q^6Tp_AA4t zHIQ)-uAh6;g6*IkyG6%L)jo{+oHcgb+umUz*%TCj;3HjL!P ze01|5{X%#@Jbr5nd_eZ~=P~cR4}K?#u7Ss=w4qn(_5`tUZYQ1PKm6$uQ|?0c^YmdS z`=|IkI;`-er#=yTPl~>NbO!nNH^7wnPWrb?rR>=XZnDQ96qh$lT##=KJ@|R#Kx9a3 z&#OKkFYPhklg65FWdCn)r@hnP7Q@YZoiX$NE=Hz_fk#^wj<$hH&FH}NjDm~=0wNVKql>jtkTN1>BXNPePXsgKT!S_V9S{rC+S!9oIfb=#c%8Tl%?~{ zx|nW!Q+S~8%1C&n@b=wVZoXARzPCT$d35kd;AnV&7j6Vkypm+X&y;;)O-uhv1U2K zzeH}go*-*d;sYW!1M!=aajU7Ls|Um&`=D>gIWBi|wgtC-?aAaVXQq^iyax@%-lsvU z2f)>?l6K?}v>4BF+cciT!sQZCjVQW?h|4y(sq8Ol-OEfn#mhM1wq1 zrs#80X0vU8Zwcj!ZuevqYlrmJBGQf`Pl`jm`id>d_f(W>KfwEmg08c0j5AIQ*v>Ftu*n9p1HQ$=q` zjX<^>3Ll%oUOw#j8aDhuv}3cvb|3tXcaoMtygddPynjRB((ZcfU+%E2RS}E<>d_^`gtZfPNQXUFqXe&A*H}S#)N1wy_UP?4zQC zicV|kp~cADl1Av+Q%4P4OdRwPJ=KOit#y;#Z%5zFGIiE7=<#Qn&w`r_e>Po@D_2ct z@pBL#)mC)(mgvaMtwo6qE!TS|ZHC4{bcbq_Z#sebH1!P@b?0AC5+*#r&0ZoUcDx7R zU+9K`RSw;!VK3)E1WOJ6HQC&^a)>n0!SHuQ#}_;D2B9JHx}`tuWgW{{10C4-6WU93 zFVVXMrC0anY%_LFdU9o#~T7`ncs6`S}s*ScpwN z3Y#}=Yv~@wn0{BEBlNz^c$WE{K9_hGbdkOEXXr!JVZZo9rpcJ1-ZGALTAAw$Vq0mZ z4Zn_7GJp4^)!i{_oalN1WFql}2qL=|!HcZ(sLJV=VrQ&NP+RlC8@%?9)W`LJ#JpWkbh+Uxs0-8KDYj5ev^4s=DI)geY<>{<1R}N zPi=gM@XO3JZ}HuqZ=GMjQ-r6xobmqKs9UJclCR>B>rxw^`7v_{bL$7twp$)|tiPy_ zJdUMCp0|7ELEoB9o}JjuTWEV@FOC7nahH*2M^_&F3go=RIRDjs*WztRfo5%#==s)t7I((PDelNt;4bl4GSGb``8!^k+apZtHp`;W{mBCE*1^%h;oO5Z{mABFsX z$bW0d|KIozhWx+B|6fD?_wz6MkyYMX{2$=|MB$6w^b>q4bsa_K;ug*evUHP2nIq6m z_J!&uIv+zn`2%rxnfi&Po6JHtIWt9c4`Yu*Pu=6cq4!Ujx9Uv&!Hqpf&aOi~!8RP$ z(1HEh(rF~@E$AgYrI~Z-oY+1CCsfm!D(1yis(o!g(M#|HM1F1EiORo1PaK@Ph5;Jgn%;zg=w1xe6Pek~#ND=DGz6*j?x3w3h2~LU%tx z(pmm*f!pEP$OG1Vuux#@@{+NpXUqeC3i0bsZL9znYu>w#^g<(xUP7yPPj`%4yK<%O zE33=y&}^xm$2em=Sta`d$QvgKpG5wX$Q>`zPgsB1zk_!jdPVc`j;(d3UQvvVCjbv< zZACVto)^%J?ZQ*>0D>+b?8Co>j-aw&I$_1q9#19-~U$i>XG3VotjD3{&v(FwudkFuTNk3h{w=q|x zGz$L{+sH|1-=(9)H5`Mc=xC4cGIcbIfA^`QdEz^Dw5;mxI@%0)nZOuYjiBa!tu@xzj}wq{%E z9_{?pHIq4;N^IvMH*mIEqZ8k(N_#3gpY~!t_F~nKJq_5@kn*1KtIP@`L=C32aq?a>#7tTRoMpW=SIFJV=r3xCG)pR-LnY#T0R8dy;(I(i0<8oNY3_Bk3YFC zg)?lWy?#KxbI>|PrTCKE%D1N2Mr4|<8V6+Eox|Mm8B|1aBb z%s<(FS^tan`x4sz-?U#F`Mz!YP3+Nr3VwH@@OP#?Mb3HC8r08?Gm}Ne@Z4WLQO-%* zPd>3nq-LnK3R~=3{L6fwiC=I&eLcnO@1nzOwBh#@rJ8b4z-~eEc41q~ELW%J{_|ZoKHPx!qfmHtUk~s0koq|byWoY^ zZ@vl7JKCtYq$e1s3G_+8jH3mJ@!GdYDVX8jn|7yW>8ZetonAj9%hnq0B znlJ^PlknFv@gHQq6Brhs5tzF|;5Ac+-r)V03D1d-rquC2On7;e`|0-#x<2(S;WdW9 zbK>LE8@zfGo|`jR1zxoYuNZi5neZx2c<=R6zh9etROF~On4q_Mk>R* zf1X+Py)%uv74t7V9G?AneslLevjbSzv6}t_tkX9;8t$a5>W2*k?rG5z}ywXVqJ^P2ktNVI*Lqh7;EIz{K9B7OOqkaP{ zc*uU;ZHd3vb;#|=iekU8_W$;lre06e2<&FMA1-_3oba_)afj`GobP)4%l+c1JH^vYysr7u$YP;|$hE&kSY#@o${1 z1J4l|W%I2DkJSFgnu|_n)+8eh`}7`gw(?$S=DqoYuDm}t^VYwAVP5g)u=0*F^Pc&i zuDp+#dGr3~!n{I1EAK_*Jq^xJ9PHS--Ne~z<_+RM)RQj9L-NXfCz5yIn_YRAn0br$ zT$oqRR5IWuH$KK$Ad>gjd%Nak z-Y3Ybx9^Ws+wCVY*KqaO6A@J&#^L1Ky>?i+}eH9zNht)=Khd0tN6aEmozIv z(k$nDyqPAHzIW+q*l)%Al3wC(GvjaNeQ_@^=IZeVU5fcm?+dl)Jr>XWi|Fs z<-k6PZN8axJ=vG2u;c4{_E*{)#P0b2*FMn&Wqt1xy@Rp&|H?kmN#NPnKGAEy^Pkx# zI+C(;Z@jrrG)R8&WBL*OUwqfZhdXqis0$kGC9V{_1uxk*yo&zFyS;cAXJ8R0 zdq_X$Eqzez!6PVB_G+Fs@eVRCl?Np(sqvT|#@=AU<`X7s0J0Z!6XB;Q!}{OAzvTn= zw4N@hv4t?%SNarh_Ly$9_LXi0ULk2@p7!f-jD4c-kxuG^E;7d|_aVZ>=SkKl?l;SQ zfwwjG<$a>?71j^+{i2V%R6l*MsNBybJWBY!;SXxl{WirO`Wf&=Kd{z7m6YesThdG& z#kW)9{z00I=KLkq_)b`1vWD{?qz&4yHteAA3*!t^@$XBP^KEATkDTvOc(t6{F|sfJ z`bQR+{f@P-zWSZCpJuM7S?8bh)$csWEYcUgYtm27?KsJLkM3X3`l--T{OfO$dUFO? zfVEuap^@En&%K@gkm6TfEO%j2hOCYQ2X&QEv8_E7^ZKm9hy}j)u%ywb>ctoiw?UyVl^nv+#YDG6g^J zQ5re|zgl?k&{4vR)%C2;?UVL(u@6Pgt`EYS#b=AN$YfoZwL|uQ9qpLY`k`^pgY>5y z=-e0mgjOH#)cjH=?U%TawEKi^?3--`heHOf=$H0JXS{dPp}6RV4~ai(<}vo~CO7UO zU-0Jc>)l_?H~LM0_7>dPH`gS1O8vOMWHYvT$_l-ue`#X(@*nwz^oM$+_kKhAS<||gf7dspf9=NZ z>C3(${bxPW|L_~qKQg3y`8Rw+`h7jpPyL4Ua|d-VpYigw^na>H`cdDIepF)j@}1w1 z-qRy}@;9V^`kLuogYNP)rH|{XU#!<$B^i%8E#<;$Z`$48NAAFMZ;JW7> z>c$5gswpyI!@7$dYTW(oZCC^@k9^{t{hgOiiKN+aC~rIoQsQ_3#Rd6sj9q|AdVto%0SVu8IgGJGa? zWk%<#{yq!7Y98wQhe+R^w7FJ;OiqU8+@Oesm7fs+}iLG z`2GYKmd^m^7c|z_#->^KvRzSGwT63qMv9!ilJ8AC+gMw4WvMy4maJIqa;SHzkkzw* zaUJr}-@??5yEyx08hgTuE4B59@pst;-QVV!NL{aFU&nsO&Pnr0|MaH&*GXLMR%EL! z8`kZM**WPN!tZ^>2><;Gd*S!v?Cal%-#KZR=I~ABIfTE?>*P6%PmSc=-A^Unm%4LO zmZtggc;p`0WBqnc3bLQXk)>U~IZXL?CGVW{SMd7Fl8X}W|D1a`3pwYC_4@mctvIlj zwz{0QIy6DG&!xSB_%~{#{TLsa;Cj`hx1Xk#e2$DEej5==^A)Lxw%~?q@Riqm5h}u$ z`S^9`WMAONPi`12aSw?w9@GaUu@IdE0UL$R*omGg#XqU z_XAS6LrUx@7l?@uY1Dk6k=yfO|!Ac;e!- zsqPiUq#ZcOz2b86*AO;=bRNgR#rBKbE9yymD&4(e9O;gza9?J`z{QbTxKBk4UR+Gt z%ZYOlz9W3_;=1r5i-X|<7neAOEVeh#A6-qDYM#G%ig&^2V&dH11&d44Hx)R&^A=}% z=Z#ji&lKeGD92^jyLd836vx^|6c^NlRZrZY#kILOr(O2e2;C2AspaCU5?t?Y`eKb+ z_hD*a|0Qc!BR}K$`0kaf$J6dE`rpyJha|?>VxljDmJt`(*W_X4v9n%SXqozN0me~)x7W%m^mUbx(#?MC9p z5jPZCSMyy0z0@=Dmli{J_4Ka_^7(f0xYxd1;9R? ziu8R!zDN40grJ!(eq~bH(Y)j|m%A$;eS6tKEvEcBe6&9!pTIgo`bU5QdhkCr97cE8u=O~X&G5V@5;d<6MojI#Lz z-p9bR@DrGkW5Lha1v7ZDs_4+-+v?$W;^X-RyhrjQ!|jhju9tNMY3o;c3-5Uy-1fnT zgaw+^?dmi7# zFY}GR+je-$WiM}7m+%|^y4}FL3|{5Z5`1$0qQp(pytD7;85_BCQl5mv-z5B9!u|p; z8Uqh=X^A=?%9A(zMB;@Py-+z~{cw0$u)XR)u*e91zH<2b_o>4$cvQXcCgey-|6Jv; z^&h~m9wqD${OXy?aqER&T@0^V2hY+X)Q!3Dt+TJFrV8O(zfnyG;Zv8$eslcLV(7a? zDyA*?$~2u%#i$scTAg<;2#@(~?4 zc>;c9jj1z)3%@FHL@gfA81gcHRxMmmDP!y;=`JrTs}z3qvxW03g-E%vAEc;Qv)BaiW1|KpXbuP}L4;g5$T zF0mycOjoz7}0y4dGR< z{7ZP%73Yg=Njk4u9p+wk>B_1#)e9F^tXT;E0JqsI2c@~D4^F#`yWWe#Q$u*wr4_?DER!CMmGBejHyOeSqFexp+Ewy%*V!@fbDyreIA zGX9^FCx;?W_LL>VxL>ZPEZG~rFPieC$iL6p4f$7>m%8L#UH%P6-bI#8h(PAeM+Tg> zFC*ugKt@iu$iLuw&C!e;OU``>zW*>X>+kOxQuu}nn|U!0b71sLc%;a#s`+AHe)DkO zr@hF#A|Jm1P7ji9UJrbv?;(Hd_(ZUgNAQURFOk2)j~3-jcc|QHkt+9^ajFxSH^Jor z!37#+tFY*KJRh6otLAL*xY#$m4_XNw1RqOAzc^lvyAL@#5}o4@;2~$rK1W%b@3<%t zIoAJ+N_*jpkzq4kDmr?XBivWYyJ1Dc`nOiRuzm}&z#riiqmaGJd49zl|8jqo@X7#{ zuyv41_$B4Y8MXhNpc1Th+RQ%sJpA=tk?NhvThy_@L)R={h(E9Fqiv;s@6wbnYwE#S z+tZ&b*qHuo!K(CU3W}$0m~~KTZF%fxu*28$c($qj!=vZ2$}GUqJP-Jq6nR{&>wM){6F zN73gL^IpD+_H{Va*!olO3;jG}<34sN<0Ru(-a+Un^o~^SWt`LEAJAM>VGk5lSo9e> zS5;)F@HP#49x=ziq_-Z?&3+He`+zyj9Pj1mVUG%u?LdLsRF|T51 zrLAyS{6&SO@fRh!DkBPAypd+pcEJdRbqz=QVgT1*Z=VIzHRI|_ART)7&BGO8E4mF1~a(s&B$ha5^uatu#m$+%T6CCv%9yMiZMHF2pL376e)%VvY7XUYxu()l7#8WBjlE;bar6TT zi${;xrJh}X3_ai@)>_t}PaJ}$*Q$fF>Ys_cwC2`Des}pcaFC4xSH=o2fuUi z>x8YUSvtD9X6fRMyx*1deAjrFj9yiOn^i>|w z(dVMKW}&0!@z!{IN4R30BU}Y__@Qrr-_>&l`Lx?AR}X`K-3K2NyUG#H^2om}JuzBE z_^y??w`@Vqtzqum1^wK)GggGBMP`Sk9YGH~f_{4h{dV~D%$zFv(jxplN3K}8W;%QB zBH&k1Ww++E(N9U2TTZ?imymBnNWR_Kt5s)9p1Qao6msPA2~*cm-B7&8SrFo?+1l5Ow+nXih-6J#AAgZ;Sy z-ZtcWjXHsEd4RHkZ<=m0D#s%=bk1O}CkNh(40P~=~<6U)ZAv~kRp%o1Oa_WJ4-k_hiB?VsRcV6{T3JV)bVU|L=zWHT=e1{ zjyS^O2#+H?f$#*v69^wb_yEEO5S~JK3gIb)rxBh;cpBjs5q=Tj7cCZAxgBbAezWpF zPUu~FJTYIdagZhe|aKw@Nqv4-du5JP60JiE5)vt}SnC3)k5qqSb85gT#yyxt2 zXt8xX#XJsZ7KUkchJzlVpI(m4v z^OR7>W}bSUjnvV@vz@19;qdcXwOUjZrjB{(3xc!lK5da2puQY_Y{lv?CISz*BF|0M zBHBFYE^(p*Dm5w0p(fcQ)g-;`-~n;S^x-jt#}l4xgnvR^;<5-&B|M#QrxBhl;bRET zB76klqm1x{$XRg{2_HlFIKp$x@)`4S(+QtQxSQ~)X8H8+q- zUPbR=ye6ztiuLKR@>|J!kTEyw6Y>9uYm~7g?+E0phtXrcQ1gE-ek;aaw{ZLy^gE;) zxpz+Y@wkOCau1JwZ-_l?pv?GxZ-CcE`@xRQ#J*KBneuSs|reH)u(t_!)P zL}|XcWyLvD;3;|V90$D04zJR%TUfkM$}bW=1#KOs9C~rt+?;u3^K!zKOOx{Pd{@1g{!*#%m=N^IogDBjYtm`!Rft z_RP&AUT~ZTjtju?IdH58#|P@Lscgx}sfM>ode-lCo|+%C@&MBPam=`Wh(378-mmd6a;M<=d%+W%<@4bAY^5V<-tKuh_W^GnvfX`@ zY2j&8k$cd+-pN0ocK}(JbL4Hl>@c~%$eo)>zLMSG5|s4)I`MQ-W-;{%rLoZKu;9cv z_&s>djd5plmv37sb-RN3K=gQ_9b*AnFFXE#S~a*xEk7RN9rBv-eedyzE!KDC@rZ!+ zz2bO8e1@5301AR^+Uiwp{86RQAn{%MlNo)r~Z>v2V zF6EyG-1)Sh(D+);IuaUx${A((S?Zlu?mU@!e#(J`@ZU?2Co;7DZ4v$Z`7*~$JLh)J zIQIu^_(dOR$F61X%*c-_S3eu06>R6hN4;_2A=~vcusshrq+OqUSY4m=k-C2MA$9$Y zJY#qS54U6cL|gh51%uKrE3l`JD@aWrQ{YG+UyzbMwjd(?@`C)QoCUe-odu=5Q+e0& zKC{kQaD=yd(7CuNy?F6!Jip<2o@XP^CZ1<_>Uh4NGpL|4C$(UGPD(*|PDDXzMQTBQ z#h`-Pij)FX5mE4OSEd*IB`2+5+P&!oDLIaUT@`7BI|`=e*hyzEuwOZ-Aobos1%D;) zF47eo7TCUmlWb;%FQpXyQDQ$;rasERp&T&}9L6f+Mk5rufkQSH6x3jF|JoJp!`rCXX znQv_AnXw7!V`H^+SF9sFD>goTOl(B@@K}5L&{$|O8d}AUUFVD)#v3}t(hjll{6ni) z=oee6qQE7}_p9{c(OY<+(`e{58d{BpcB7%!==${MMqiVY5Sw3-5W6NPKDM?ZJ~k{T zBKFQ4Ef#vk7FTGo@8l%K-jL&neLg2Kc2h+nX&tei)-P0Z zm}h24ob-z#N5-82cyk_$?~~)1pYO&0`tL{fJCXnJD@>NN%Wa$ww+VcvD0`F^^YQ*F z@hu_V6;m=K!+Fu2p83pM;Zw8oofmPhNBE*W;3+ojzysGT5+A@Ibxf2xZg97!4&~e% z?g*J|Pc3);2pNYuoQX<_ZsyGy#R)qGPR-^l!>E*ql;~CLEqR@%*?z|r&sN&fI__6X z0xzpMqkh2IJXdg^>|EX})snnlsyY4D3$wTXm^%sV{YQ$8=~|v4;J=e|9Cq+%oMWo{ z6g7|XyPO03wbyaKAAUGT!7I?}@IMF6BA3XWStkmO^OGM9=d3dx9qt=y&P(GBxN5fn zxB5jjrx1N-`%*Q|g4uGZ8ds0qY4ZyA8mCgx3K@&JWXUC$a%L`R>v=w0oSukm3QJ!_ILPZ zO}m)y;15)LHSfP&PFN{v`Tk%6-{s)7(!J)LD^#gtKZMXMX#1lWO{qG;NosWS^UhoEN)Y@Bz_x!`p0^6`VUfLB4Hm&10vY!xtv1dENEPTXf$a ze0&%$LHtaAXt(>0AV(iYPHwTsH*R+yoOJ__6FZy>+uVTXA}>vTF7kF;^Mb`gn-`3B z@EnzR{-3E?Iyx_XV}bb2c(K{ZdQH99?g*EB@#Nc7Gkelh|O_+BEEVigQfRf&AjLX2UL_v4(e~GA1oQJ(@L!sLpkU z;bB5xTSO7T_Vn z_6iT5i*EUTXV#B1#cXqdcUvFu@I~&HZ<~?tbNmx*cK{Dvu~&GdJ@V}_@?C;Wj=M>7 z!)yD1SKcGvL9>1$KRpP%$NPY{v`4;wnDt|>x2*-<(|y3Zw@1DXvwrB`wmRUw&6_5tsK9{Juk>xUkoz2?qsrZ4ZHFT3dbnj<>R?TAVX`tVOM?Qxzm zSI*LKbz>=O2=TT=-&^>oe1X4EE&emy4L7#+%3jLk#sS&t3h`f+ zd5`&f_FeC?zmLZ~;_MZh*h8|B$C`(jllC3rympz7WG=dnbk_Z6vOm3B`oJZANiS(% zFJSJnc@y(UFLRfb=M?`v=dh0F)DrI+=Br<*CEAaT`KtOVW4@Zk99eR%V_ZFJKpT}d z6aR~u*Qx%|8uPX++d;o}2WItmYShHE(X;$zTvw$0|V zVP8M&BMe)x_Hl(SvM^%&1udbDrEj}a<0jF=8q3;(Z0j>DCQ0a`&^FDLMHda|SI%gQ`cH)CP zjCH&Y8+;Ca^&^Q#j!jQ?=U#=4c49nsTGC`DtK7-(_CMmk^dV_%@ZR(+(xj3mUF8ao zALdlKMWktjf9d78Ndv#VDvLBD%yLGl+$z#M%vyq8&JCoQN}4gG8E2N0qjEQZ&#mw? zy&U*p`W(_sB#qlFXR6BGMw%JuW_meykOtm&)pXL#GRwI^ z%k=X0k?wWUJx;o{W_eFh-g*;1c$Z#YfOPMY?rGB1ndLo0c`usyVb9UaJ4(7kqsFd^31zu`LQ8 zbA60Wj=4s7*-7RgIk!UR8<_^*$eTmi$k$q$8uz(f>GHMk4mnR@GCU$Mc*^qT`i?o@ z`%A=xgK|#_`a}p1+<*E0jwf$DfNoQGc0wq>`U7D-`BgWbhpcY#yk|^#-9a8HW&=gwSMm9ddtv_^0sA&2M+ise^}#|J7pRK8J_?lJ(YC`1fePSidDkB|Ze-`ywpP zCwBHa=7r5+{e85PKXJ}AU&?di-^ki*{11)q2#@g&pKH9s%C7lR+PMxN zzt7-98<2xb#$0>OlYPzdeym?s<*FqMr?bBczLW{C6IoZ%E9^vCdR>8y$Ijz&ZsH~h`6@ovMZDsfLU=Wgm#0)k#JW^MEbC3N#bvJZ ztu<=VL0f8h0GoX^w#O;(aZM@KjCdm9Ey`XlYkAeXOLL~c-?bRR<9U*exJwv^dK`RT zOC>y=$7#gLTAm)qT%ctUK7wZyd=GwbE8|U%WA4$$5I&A4$B28FF(z^O%v0J#!reSm z;i=@~fG6TgaHfY<0_5$iTNv=^^**I8?_T1b53(^gQh;%uc225`+s~~ zbnVgfGZ|Z%^cCy{Bd0UIB6w06W1`cBhW8_UzMS7+PZ}xvJ>@NX!Q_6RiOOhOn*+PC z%*VnHu+?N@1F^vmWGyc9sMu=K+k)6z&QU&l`89%>Z%tV^9$D^-y%=r!DMdt0($Qj$&5U^vQO4v16CHxKlRdmoM7qZG5 zL-=M-Ngm&OGF8IAi5@II-J<6XQwi@!5s$7LWbl`fz+R?Wq--lNahAu36@&50sgwJOV${wDwbJEWQCOWYT9htFv zWBUXnz39fvXAJV9Gmjjc#O|aXb$6Wre=H8ok$#-n$At`CXBN(38=fM=Rd7#7(KWWAs|$^J?x` zoXNM7_bM-YQoQrgo9B=A{x5Xo06MbBSjD=Ioazgw?;ASut?0<;vAT}jpS~@6vZaq+ zfet&k{87=7lhH|>qLbW;j=a#+k^7?~ho%=DIjy`uzAUyZbdfQli`E(}#jy#U?-MyDD=h=7RgpQ2-BRcY4(UGSD=Z4qJMM3%on}fY*nP{HW;2cLC4a2fRLXqAEtzZLDI=*YLCBQG>{Im~;hE{8cx{n^P~ z0xR})>Ce7%dis6n+xtTF?JaY;Yb^_0WKa27c(9H6R%8Cz%RJ^nzLhyj<|pRZ*)np6+C_mzJD6N;x8hjjSWxm{Q{XzVSC(+Ei%%O>Gs91tY445 z>W{chm(%u*WuH@dShR1z9mfBDWQ1Q*RB~%#y@yK{y%KeP_ zwpi(Y0knuYvI@vYibXPh>rZySx9m$afjoKt;Z*!N0heM`Sz?4d=-O1rXidr? zY!z>j3#an7^Tw1ATdW4ema3#!ksC#RbQ3<8Cyz%VQ(}{${A6TD=lQwFjvXqcyqU2! zHQrs(jO;j#wb)um^Y^oqS~gslA65BY#?(}N<(rWor^T4@V^qa(U4|qc8FK0!~j0m}CxOHSQKeq_mMW6XH`>W3pw>hX** zH@^0}kSC{3#7_$RoJUnf7BVGk*X4VWDcxi8D)OhBaroS4B3I(aa$_xHOzcvVktvJ6 z;0(5ZbfjEv%JurX4gG}u8o3WJ&T8-<5TAGz89P(!%1{}$fGHZ|^A`e@COj`7ogGo9}UWT~2`I>t}o-yARdXOQnP#*wUv&_BnE zT>1e2BCkrEe9L`%tbuS&0_SWvFZIuTyW>g5wLVTe_kFuB^}jv`e=x@MEyRob7rOUb z{__c!wXr)G^TJQ8M{)OKsJ}-G^=AFQNhQ0R@{)}`*H&72bLM?x#tPM7<(Vw{Y|4hg z)<3l9=8x7hy>b3RWTWPFH)xt_sFpK3;?+A&^8NcwwzYzzoWo$1CwF-N&$r7qIW!)Uh}&OMR3dt;j?l>nm{7@nH@C+aqV5L#4o*2$`$^Pxiyqq zV&~pN(!6JrbN09s(Jpt2I2!(IuXzRt?I~xB$e4JEa^(&*xjV0#cx!BwddB(lJ>xk; zB)Ksw(L39TJ;P6085dT0r(~?knKHmq;JSqTEmr->ceh^u0gX%bcT!_LbkJ!-ofey6 zPn%(KK9SH!_CQG=gw~I1&^+HAZ_pwOdPTE#&0JCqpR+OU6n$RkC_3MRv^8ze&R9QM zIuMzZdzt7z$DGQ$u8Oxyty=d7@RL3zH9nMapF{y-;;6snc%L&=YCK2PRW?q zX4Bg0C|lOlr7hgxT`X`y#zfWkI9r!654cn_E@Vu|{-6y5X%ld?;B?im@A60VQvQNo z%CG*eyL}DgZoA;Y7=spx|4up?PhRMw7*AD{(@A?eBi#+BXq#f{D|5Y@G3a!_ z7fSGHt+F);-Ht>1AY&|)Zezh$!gOAeV(^jxXLKAP?J3%a{yFliIBBPydOPWThxmiU z3r_vP347h+nJR*Qsv4#5O1&M*I4>x(Ry(_qu#6b`4fxodHh+HE&Pf^PZ4H`t)kK@u zJ5hOSdG6!6f1=}&hz8|-aAJnXmTU1(z5HgmkC$_uYt>oktCy8=UTermroPSCJI{0X zt?B>Vu`1~ufjOma60ojsI#H69>jodsP-|_}v7SDi|N1qI2Xy*E)+)GLO!Bxn40$aU39^JUqU_>st%Wq#&;eM0V1kv`EXxdkA~6?l2>x1W{yGL&Z@Ei`zxhrS`a zt2dtAAD-=jXVdrh_jS%;b*8QJo~#XfSo_$h{67U}FEm)gJ9NI2dVD1`hsHAB^@aam zr+zd3%_jch+x4%)|8^7qc_#j)I_;AiHO}s}>hUo2mwLQOJw)cP+Oxyn{~axW`~=@M z=O*q*;qIe*;jx@mo5eo84akPqp{vci%8)Ca&~;PAMqRFy^F}wAa^(hO1xKp;TpqgW zT{Sj;F|-t!X#wpjJXhLG{__|E>-2NPk{j=suGV@!bu>x%BEIFU!3@f|WGMb|kKpe{ zo{TYSi3j_UCzi9{5|LX)Ci(M*!JZaJ6EwV3F_&9qc*50}(b5i#x6ZMDZ+-*y)W^Fs zGA~>3RF#?Q1=nVL3a`@ro;lx5aN*7Y!DWVg#~R<$_+~yEDdDcl_@v^)j;4Hx|GT59 znz~5%e6v0i39nzxUUDEHTjkLbH8btbM#pcopp( zzc^|EO7ihP^2I?s1$cwV**I+Z}DDrh9QUq?H-G&NqzssjFM z%CYLlzUetq=Qjv*qnip{b~A>DLKi!9@jw^1rmiS*;_m=nlPS+h`?{W~{(cK}D*j5# zE}_g?@=IJOzQW6eMzVihXavqWje^(?q;8?Kkuoj%ERlSPYDpb;X-od?ysMBEt9fs; zIhK6P{CrOheBEo@w=Cyx4`3W_vyp~!HvV`>;T6vJ1`Dm^PNDqxCkAIrU!d(J?K;lZ zETKQkxCkKsc?i$&f*-bU9WR@A_TRukz6Gz&_M@)Se%BILDm38X4o1Bl$2oTlmUBr< zc*g?kKKfY6YVOk`%mc1hPrulgrQG^{uc6o-Wc?|V{k;zSg~h+##v0T%WEGiDi@{Cc zP6mEYI*$Z)>$#5c0s6j&Hh!0X>2I=*B=x-)*jE3q;G26}^s#d{-_o{HZ_z0_YT}kS zBHhcIX=~+uY&Ntj_n-?~wD7`nr2ZPTkorp>EV*CHmT_;B`a`phnv5ly+AzD$mbY9V zAJ9!6@mW@26 z9%L&|j;_y5jq&QXj*EyFeNO0Y+SlYa!D!!ovcooq1Rb*rZ{WB)3C9fhU z-xGx&aFTcMHsrQC#!?_WCAyON;JiI1TljPE9{09Hfk5=ojE#z+&j8kBy1gfLNc3fxlb*#fm$vBm zr7>4-hW9OF{C_}wr0#0Aob@ZRYYH;r;6^(-Q3>^LwGYyHm5hh`;ZK2Ix|`P8(tW}U zXqSWl<-rfi<@^i5&7cM67RI~JL5n%>=zTP=J%}uyfes_#9?qWIL-=;;Bkf!a>`>gW z>(3FKoY$a_f#2QWDSbH1n1<&w>t3~*eia25qKVh-wR(2!tX=j_GjJ~ zcmmrynfq;a+WpXeb`)(j8Jc=7p$+x=Us(Pn)F~9dSHRE7I8ylfYtTt-X+i2WADSM5 z_qKqq@cb~!xAVvtJG^vA_LrY`JgM(Xa?}5>?SUU>ru@~y?+P{NH294tUntz40(YJc zV_+u?tNf2{9+G{@7gie%x`0M+g5P7%=#1ED7#~;4H~m-o>s-F^8Su-Tu`zSU;7yd1 zLs&QZagMOiu6eZ4ZlQSHZnl@zR%>mXdB?u9e8%L~-3CrQ`&0~lO70m5h4J}kT{H-c z=%PW-{vq`dEB=_{ zYo*LX4@|?JlH3^4>TYVm-s?MR>}QcS61t_UK{Lr;{v!Eh-qrC$4-M=DPw><61m8|P z>8pA@D7zC^{5PcC1mEG%%?7@M!1wGA-0eY;>7tR*nC}DNtSSekN&PbHs;!m%J(=vo z2t?$y=T~Y;`HZjpij2gJ=FGN-E|;}5gNN-$=5MhN(&Y@je#pYDtbI%TJ+z7Fm||%{pHXD(;E)McNerkSLiLY7kXdXgWkep-=yBpBOA2p^oU7v#kp7K z#;HUXy4t)yI(;SVw`rZ?Zm-$F9?spK9MAIN*GhLU%c&30o~!J+tq<69gZ3fWMJlyz zH{(dB33|feH|+k8_Sp4#UfRRS*#|DAX1C&(@OqgirRyhIOA~i3H=Re8kUDEBZ}|*-A%xxm=BGOPkkl9d z?I!lV&O~oa+r{BYyHt9#>|uD6dzo~80?n-cD0C9~9D)A`ZLR(&^y&X*#~c|8Zt#)0 z!QwUf_(}_(S@%ZAlaE6`;k%FVt@lTnqv3DNUny2w9I;Q$4Q-33X^a1$%)m^sI}IEu zxJ2x($g$F_B|evUp}oM2H2c;J!p>snQQ)*8LLFnRN!OpWJ)Rr|eX9qGuT^r}gN*aZ zr0ooc#uj~LzqIgK86#g!LFc6HxgUW(H@Go}zS>S0d!JKU!A)Sl3N9u5%iIvkm*VKF zU&jwGXWscbe%KHC$lTMjT!C-QXgbD=RvvWS)VsA2q~ zUiuCA{tsnZeMZ_-+D-aeHuSj@`sn@Zw?=>2O5NIf&}(OBy#{s8qdn_&xXr59h4O&Z z>p#IkXm*~me+<74ZI2fz-;iIh`7zFxoQr08SQsrJw@)Tk@hpo68;fd z&n3N-7xN9}EvCGacJ3W#51@=OmowM@2ICby>~Zw4$MrR5(Z!rs`VS2<^r_zwudk~? z>&|?EEBzP{I`irJ8+j!EGn2ft(Pa}ioB3p%8u_@V+H96W@QO{WZ?SH_XJ> zuG1F#YjT(Ub>tf|R+AcU1Mij)n(O$RcRqyLK<+4^jHI*|?uoq;qUY?bzno4)5+!N%HKG71!UE9sdKhSCTEYxtWh^%XDEl>@} z4NYsJRJ#LuOBnNFqGr;*nLaLSoLznd#(HHnYr;AY0G^XI=HAi>TnEC3yoH|lzdWhw zcdsQizGK$w0QK+IpL?P2I?@V#pOQE9eL~OMwO;YxyNq#RjRm2jtZ{ES3+*t;ngzn8&u1;#*Oy zs@L89dt-f;xoEbA&sNDzvL5W6U8Dwt`eSS9g`|kG9;8sN$QXeZ^zU59F3m19!#qWMiei@HjUCqj zll~#|-BRA6eOK!7A#Eh{o%FxH@R$DaP59TD`2Q>Czw1r>uQu_YB6z@`H15l^>TxUd zmwLQJJwoR{xj#k5ejQ_4v7UQq6TT?n?k{zpCho8jp5}_Ii#@$cV;`-p;mlB3>loO0 z3fqI+SGEb;bRPXo?m`O=S6^}`6h3Q?&4+G|Y6x8Fosjf=&17o8Rs&-Wt__xU#-)@7~>V@ z7)N%Ob5HjF4tq>7<6LMWWBXBatjqUp*dZoBC-IXIy8MAYDD?j>?YNh334dMsC2c6- z`*i%08jk}{#%*u%Nh{?^`ctPv<&*eM`Q#PirT^q1pX}pXmrt4}>GFxpXO?U-h4ZW} z*<>i^S??unr(D8$MAkgln_TkY%&vLveZITqxqppZ@-X*TTXM;ZW_>n8ldk#0kSCso z2G)4y-jlOc$P6M!Y``Z@WQjZUyaO7y(@u|Cv~XXg(?V!81>ad{uxzMOO~`1==9;kb zH1B@t-}U-jd6j=7<76nlGsqt8F3uR&I9puikP=ysrClw#BUIkFQ7?=81GzICknUdK5kNO>n6juO>81^SFsD8CwvZBxQTVs zMp?f*yUONwvbG>+{{`(~@VD^Itv`ru2u$`)(rwAC_iNZiCnKv>r@>>gSTjrUPU^T^ zwMT;gV6VeZ!z2617!7MUN4TtWRO4GEcP)BqesngIz7guLTVzjaLx!2-<&IdHkE^5b z0p<=)=dsdXw)t;R|83r=%5sg3Z{DtMCsN zeO%}g3ta@Zz>)R;P0qU6nef&2q4@hv(dgfU8s$E}bMVzx_7R@IF5V%2bJ!Wr&g2{Z z*+AXoeoDEU61wX4wx0e%hh~`bHU54c!G(Kj^*d_u^~`|3iGSzZOw(70_Ss48q2_oCw4B6zRf(RDAX+%5So@?P+AQ-8rW`U~NMo3Ldwk7Oj{>n46IlwZeq zl=;S(Lk2afS?(`oY>NM0Ye?O8kiS1|WYI*%pU@<<{=)A%iMQ+_qnguq<=H%mCSw5Gxyytb6?nIi~gJ)AaY|j|Joqw zn177bbo;Fzw%vA+XSGot4{fcLH||IN#>qX?___zm;G79Iq>b4eGh|)H*8Rv zPETncSKU?q)L!!?H@+Tke`yx=nami#H)hUu;w=7gT(4(pK%?=bgKo{^t^LjI%X|KH8`CzKz62GUPmO6_6a!Bz)hhl!WI zDUYS+SpT$3xBV3g{l<>}auI#(kH`s}LpifVaW+V$YG5CBljP4=+MZ(kRnf&7GR&~9 z^6))~%Q)+zTvccDXHhRJPTn0mhw1(cBL7KUR6yyzzrqvS@3l7|H&Hie1li7&^ z_CRSr|8Ck+{9`o;ZF9v#xABOl}wC=R)>vye%?xtVc zo)}zb^A2u(!_GOh+Md&U>`j5U`97b&CVz<9I)(GKoMV(m@a6z*3f#74`sQ8CMKUg5q^%`9K)arxT~G2|g`dWB*24nOQTWj3l({VyK1~_h z@cZ&Yi<7O~y9|8B>i#RhLHeh(k*qJsJcjR5yM2VaUF5XVMEm+y=BTsMXDCz7iC_;` z`6JLn>M);hy-xJaz`?v+@%t)f%(on2JZ@sWlr(O!c`-Im$e1VWA{pn5fo6w#RpPTL z;{c=l^Ur z?^XuiU(v>ol1`r=2p5@4+F%o5(hjV7r?7^PxM}L(y&(p{yXMxuq0`F$ZmHzONJ!Rw(;0as{W;pN!uE0BTb3(S@<{50j zt?GoE3fw_D+*^CVodsN3yOObMjajL8kTK9g`%AxIempicKJT1|zAj_)n6xkLZ?(Of ze(;Ed(f*{_D(}~62WgLop{?L_qVU;Hyy z9`Tqbj=LJ<8pdua`^y9GNUXfOC?78X3Wd^Sc{GRKis{2d{o8t_&;}dAt50^o(LpJb`um5 zq@n~Rg0czt1QM0dYPE$8K?R~HVwLA?ASxPAR%oeUn;@cQH5EmxTiX)E`T)`@_|%WK z>?YwM2@gV0vY_VsKKI@Y%Ni(rU;X}GpV#k?ea+sv=bSrp=FFLyGiS~`HpVsVc49to zmMs3!F~!3;(;T}&>l(X6=n>Ola=wZ$S3P1Mf$qIpOzgwZmFK6y8>~ggJ_H?kUIVUQ zb&mZFc;y&(tJs(JjG3kX7k^KewP$Sc)k2GRPp(S++8U3avaMtbYx>dn>PnqwDO)V| zhwNhJ;)|eT;e2!{I-rO-m0%t&pr=Hu5cqwt5b?r)glvv`U#Mo7Cmwv=88K82bE>sfBAh#3oPx^3PHH~;D zJ)J67e6ob58m&D4++?)LfTKnnv`y$^zqRt#@beHxJk2llxl?BMi}iBdt;b^^9#047 zCRz#&SlMT+=L}3>TlcI(Z}rGJurWTX`Nf2+#&wBVd)Fjo?Z!vt?n!E8J@%Hswi~jL zzu=*_ZUpWo;Kl=22;2nV&^4`Xuj{rgc=tzST;wwJi=2-HSgVC>n&JB;&mn(eKYUhF z)+^7Dp2mLIA^vYn{FNsDlcds5WDPHL{#1L4{cwXrC3+IE8_OD!d4ax1)}oI$te0mP zb7F0Ud&f)Asr(r_44ba>!3Nr-k~O|w5A>5_UqsgWve)KjE$(oh+-D1|r8Zt;tYO@& zAry1yj?O&DI>r^Yjyaoi4@Hzk_StTxjAD2EDQWmxR_b4i{-_UY6Vv{9#`?b%R{y&q z>i_J?`Y&%e%lgkU>tFj{uD`>qe~MZEWKx+gXgyEbEl1Gq!iR)tmEub_GISc;(z029wTGD%n8H~R`v}NfwAM;>+Gt0dEBEV zHc;%LIiYb}#&4O2${3v~<73q5YA5BNWnmowULJUE_DotSmoa9G9if-^S;`~4l5cfd zVT{3{F`qFQ9QJ0I)8;XrHZacbxw(7Rd-ZLrWZzrr?clos=49^*|Dhv$L4MlFd9>}d zr$p}IhaWv%2W%d&E`BYHe|hl42~XYvM&<@5%O8LG@_*NsbL^Dzr+Du-%P(_>-A~G# zC9!?Z(q4Y%+){p#wYTwYl6IKfN4Vf8f%$r^K3(EhK`;mXs}^>`7`CW! z*h4htjJ6TFjO%uXMYGqw>EN8anr~SXvip>>F3`_2@x7zaa$^rL?I#<=uD%GH$|UAs zVqgCg^jQnRMOhBew%?Fev39f{Z+lH-P1XvmZL=Ssd~)Voo;UY&`abEYe6Kwm zoi$}H>m2yK_Hz0zcA=`Po!^gSZ8qywcdFF6mh(+J;iaq}0-QyWa;;z=F*Nr4BCKuV zI%u2GX4?e7leQ5aVmA!hMR!0y{A|5)vIZ0#GT*UA;)Cs@F4%OJV=wqx+DjG1dmObr zJ=_Zul>hllt`5GdQaqio1u&j}UG7ZrXuY&*iIZl@vjpq-rtJz#P`kCn??<`1pm-3pV*(#&my1Su;(rN-TyFT z#QOohMy9{Rav7h?9=5cKKCk4xq(zkD&-`CRJLbDBx(!|Qmy$gNrSB!=_LIGN=3m9K zFTXIR`c2?P?%(bN4)%&O?J0b4)yX}Dclj^2w_1H}{@>YC=zWYm1?n#S|2JlxeoGrm zzYYC5+HZLTSm|$1h4ZI2seQlYW|LL`d-whP*ZD(TMc=gZ2mRfTz4g%EOa8ritr_=f zt>O=I4>;{Sa$3*GBX<~&7W_Zp(S^bz(;sAi!$ZN%*`;_$F;6dif>UU*P{w%rZoN zKPU8k+9Txe(DD~UUZp*HguYLE=-;Outm2Ck@_C>gG}_@z{tkQ1GKfBq?_>&foGC+IjTi!N>pFE&suQ@_V_9Le<=UmU6 zwpiKlp|LH0z%Z@qcFG69`hr zA5W^6)m;C~HS45*{~Y`S%SW60FK3v$pX+(;A+)8eTe2vln>zO=4ex(a?k8zSSyP^C zd2cbxTlHToZAbKHy>=mdqLXs=7pv z_T8@NB>u0ps7u`!Ovtr!zpKo_#{O1YDf2HE^Ma1x%S?DB@W2eO0G>IS;ZtPzc6Fm1 zF4hh*=h0-0RGmBv;4``{TfSX(K~nAl>LF#d0_%=|y)OdxK44`Xd6al0qEDs%4p%47 zhvdt6Blgt%+D@Kz=03@lZHy@qu$v=b7stExy_g}uiawWeO#nvtxP$LYo<9DYdE3d8 zxH+Nxr_B8K$Pe`|89(KH$lvcZ&JM|(C*PIgS;YA8jg*PKb(yzGtd*D zmap%j7P0PNZ17cDlAGP=Bq_r}-~x%K#&h}0DCP^~74=j>e+oL8d9u)*1+2_H!rQ}` zdnbGEGRxfa8$*VEOWEb!3F;+v2$la_=>02?MRABE(_2^{kBQKY=Q`a`?Cw8IXKfDOqD=W5#J<$b;*@^Uq0 z3duzxc#@Y#Ubwu(nfb%XkCYebo8K@;4E0NFs$U0U)uk)xmq~WkF3@8=DQCWA9r2O5 zj#w`1hmeoXRV%fXF8Zyri+at%+ymYu%!k*qUaE>#uW5`~MRxVNW@EjbL27sUVh86{ zmt3Oh@dcJ~o>unfvRN;K&w84D9%MuCVy@4w$Q8v6cDu8>f3Lji%%uEkM~>4+4Cu7=_ReWq7d5mtP7S>_K@DwV zjvJ6O^|D6gyiciSEh%FEs8Z`xlE)cUV&TPCs+i^?_V~H`F2`x-eE;k|_ig6Pt$j}4 z1eqf{@L8DDk26KAck=n=iN4veC^fLLES30qGgXhWR9QbF1KHtyLU=0n@lo(K^4-5_ zEBjGhf3?flIP${faU5;`TT>@(X09bNCVhG%`HaIKt#?Ivgn!7}23_7b5B^*qXEkT- zsuw4-He)X4W-hkgmDl=^OKX*V;T|D545L>GJ?=pGsN5gr38z)x(>?xSliox4v5FnV z2E9)BuL`a2zc*xhZ5XYk?Pcq7+OmyG2`k%;lg(p@Vd@!rx$%%de(4yVRik~ zq!-Zjp~1T;p}M+aPO0l+Xgq`*;?o=~zt`DnyI1M_dZ&Xj6^6>>KYf`pPgAB19q?>q zJH6BMtT>!r7|)(I>1mde@-Z+}$Eq05?g;si_IwWcSO-06!=)xZV??`N>JEOm9IP{a z3d$m3@iDhWz!vv1=spk$>+j?V{^?Y@nMnq0NhGX0)^jidcCkqp9UdBYjq+A?_S8qf zjxy=~6j;%jqVpaAM*8DX${W(7o6WpKVR?Tx^P0l)-Z1lahvmI$=J~_&YRtSZ!}4A* z^F9m9TW98d9G3TcGw;K&yr;~(_rmg4nt5-BKNv6`vKcS=h3_B{r+Ezh?M%1+AU4^;l<&8Q)nuWxMJVJ+iMR_T@Ux*~&am#uLY8 zW1gperRAub(LMF~eKqubD*ejw#jjcw^Ny^qoYlmM&B}D;S2wbsi49n{Lmwlqxu5uG zz54Y^JF(E3mQPt_9MU%Af3JEK^}Up5<`LO)??yUfL*qziaNu9ChR)Pv&*7&2=-Fg` zd+oKUdsXjPW$iN7KMy+;u!C;r{4VD}oy1Ys&n-)Aj~F#`4{4>o+RjV$yvnnlJhnD!!3>%eqWa@!vLEd_C_Xe}(czPX&(qW)>3@wlS9X_ky3O`8vCR z8>RVv!?%Jh7GLlCxqE$pijN(v;uD6c_`WxaZw7djWA{$w`}Rxa`wj2vTa?ery>P*? zn(ry@-U-$#Up#eb+G+9iplr=wT72F4){%OPuN&`wuv&d_{rF~-)%UQZCzP-2g_JGP z>RZD1_GN0m*c{51V)Z>re&ayRcd?w+9HRMpa@Sn_3e9KbzPWE->bLNm$@7;y zbEjMnU=I-|`S1KBUUGd4@3~*@+gNzOJ$EtOxzk3B;ibGQ;dgkk3U=nMyTjYuzAnVs zsL!VuF(HT;$6~u7bni3;f$ttoh34FIdqyPm_F4eIeiBF1y_&7T>q`@Iw~9 zy-o9di(RmOvBg(hYAZZ^gBJYyHZ6GQPAzzFofh2xq82>xGU=C#e9doY!RC6>_q5e0M~=VqRF@(d4}|G{$$&-md~Ah*q5QcmQ%*}B-*+^hw+N#0&yP5^U^bcNg3+(H_~ zd#feb99!mVZsR$T=k7d@;yIQyh38e|kL7uV7L295&5vLoMF#f2McJ_P?=8$D=1NL- z(`|Y9cqU~ZWiPc!#l-BzU$6-oY=RGaxnHK~8ZD^*-^l+$^FQ~=G)*%9Z{hzM^Z%Fp zf8P9G&;O0){}%plGXJ08|28eyP|CTiz?_{r?aVx1)92*P!>0800wZrAdG)kYYpL-( zgy%yhjp6)1p#}F!8KW%0{-vZ(fd5Eb^;+sWXaD@2fftEU$os&{O26YF@P?#3zr{W$ zZ4uZaDbMer+rSC@L(&B+6!II`se;GxiQo`Vw*Kx*^BpoB*k!`+HS>_~K(m?GV&)<1 zfn#P~o0*5)OMDoeUaX{iOYT(cZsw(!dB}et&CJU*^W>hz{$}1qW}e))IK<2wZssAY zfssa@lDb+GtCi@(b+kP^@;}dd+&^b$tF=$|clexqBfd|MXhDey<6ptM(gi#Ht62X% zh#wn!W9$u%t-r<@)Vgm@Rr8b6ru4x^CbB=u8GQVUqE?A3S191N>z+x9&I1a zzFj4I9Oz=l&sEOdgLs}Lwl(gpya!tVaJw|syqUX+Cts3xyf*una~q$K`>0dKx+&|T zxafj_wVU?|zN2-GF7VG|>>#ftD(Z#?#`a6td#=@#9v?nuw6kV#pS+q2lJaZ%bsbfM zAE0OD!*vB0^XtKHZ+Tt8yZqMkE9Y0tZ{^kgf{Xd};J0_Qzu;Yd>-m-QE9STI>HzNp zybtg`!21C20|md%UfXSG_FCWqzy%88c|JT~ZNY1gRTaFEUDWNe?4p9#FWorfy#Z^x zJx~5%@-OE3A)asNdC!ung8BhP-PR2#DwxnWr{LRcN4EzCI0~L6|Hi(93$E^aLBaZ* zjWb5~?N_jubQLsHp!pFv%fYD!-kR+w*u(R4Ja6FrVBSx8(>{azZd;(WxX%MKrf{$1 z?flB!a(5VUv^YEA-${EOk}*{)@!PQlJaR*I?KD^G6!tZ-4OFNBpRZQ-uU2c^?@nCQ znU7+Bl`%E2v+`C4dHzSRQ{o#^G~GVTzfEu3k{a%+_Fu!f;jwwabE0)a-bq@Cc_Jqz z7eDRC?9Q-fOj6XoWzbg#iI?CXm_(|4-zxT}eKayQ; z189)_P{;)_q}6O?6zQI?{J{w;lbn%TGg^le4ow$rZztMY=b>5gII57C`@Q@rXG zD>jju!O&ab^i>U3IrkA$W}?K4#J(rGeY@COE>|-@Aidp^RH3jHxu*L^R86fKq3|D? zMBJP*e9lU(y-TnuqTds;ccn3>XWtti_H29(vt46~zAMUiR4l&tyadLDSo_qR?@IA! z!zMgotwqI7+3Ff*Wu7)=s{}Ku z8S|Wd?weuf?j|`C65#$(ku%jqTRe~d1!Eg$Qi4;sJDU6L6GkHU`$nk=Ze-nGV(5Sx z;%fO{Hep{p6*l@R6SmkKpY{U#mI?dDsjve=u=C9EXE(6#nXp?5Acze$R?@I%(W*2zJ zOuUw}z-uw^4*Ux|Yo5^tZKvW*4b?x^XoF>60o&b#jV0z=SbIh1o4m?2$B!?8O*3Ir zPKA9TM0dEU-~S10e-k$IRM_`JbPEmGyT1T-hzWbqsj&Nq$*1%39s@S+b6`iBu)|M< z?XV3N8+hYB6~C!MeaW-rFiER(y*igTr}M^tZb@%m|_hr^C&sLCOWfRB~`S5BYN}h z&)O#ZT}!Gsj6NGj9IgMP!x}$7!x}+!TL)`|{|)Pd4XgwHh>p7y9T&bnxFBME(13od zN6)Q8&&hh=6LjDG=(=^}%i18cE*RA}Q(q_agyv_!hSmWOgL?-XKMW(VVz=uB6w$mWDIt_POLoEp6;^C)T0?SB=VpPmtCs^FkMLpX!}0?y)} zoe}3+Vzl|uqamDSZ^?IVIU~*h_HF#=(-6)9pM2-%XT*t?@1R#hIOE=w@7#7qoFC0A z(XZ|Jf0S?j;@t4jv+ek=$@eFo8$SBB9sgDN{-iVFM@xI4cSATe8_;Fw-T->{OzXF6 zW!-`f4&fd619<4+06O?gcuUw@^P`VLc!O%dLnjB&$7jORzlUxP;obcrcbc5%3pAe4qWYQ}Dlvc&?A2_qzys=SP%JVuy0> ze(YZ6rm_#3#+`aqj7|P4^?lC`#{9LDr#pGF?vc z&t9|Vgyy?|Go1SpExu@Ma*YEmzUz2?=I1@rb{AWG5An?dTPPRhS**p$ykh2&G|jhT zVM^K$>~Z{iVc)bP><>J-p>lOT_?+kReX+22S}<1g{c~ZbwBw1I?|&AirX9gXxdYp8 z=LMbD{7@)(*0jetE42-o8sFErKW7ooTNh@pIke@xtYhp+$eu&%aLu=YZyz74`BD$e z-xMkIdH7}(?0Xm+bBPLWrA$Y#X|K|{#~xvP zdx*1KO*d=7nE3z4QTNe&oGk)QM6-Tgj`^P%JZ-P%-t14GNSwClIAHLOeo4^iQ zb7UTN>3g)`W7g%zfnn(kDTt4C}Tdltf{1J?-MpR75+oNzldn>MN7 z=K`Nu=6idgC9MfNcAxndt!Wxq=Bwg62TBC~qBRGKRq%YNFZS)M1=^aXA!R6-e`zTM-6P$T|rE)d<3&HHQm8*}*UI6yy z7;M$8);wL7nl?foyL>P<&nGh6^cL@F1Ak(kPu8wYTi7FD?b<|M(>C5=*KXPgJxRYb zX!)@PUWPtts#n2b>>pTd(FM8e35ZRceZOE8skF8Km+ty%-T#fq0zLX zH>Rtc?Tn}U3-f~4VK+Z~b6)TU)wQDKHsZ)~kLXKU*9y)NR{TUutZ37^HvfV9#IM(S zY|FP796yL0etkn;aH-a9TLG|RfN^t=v%q-y)_(T1+O%%X`Svl#o4({c%%i`Y+eBWa z7Bjt;we7*o7|)3kq@oYKl1R$wOV~2j~iWmG|K8bIFC8_BU=!aGw==i)Gk1Qn&n5aiJc;?V-?U$d-QtxIugq}wu@^i) z;`tdr1D3gX!K>34~#b#mVx%=KRqmNCSm}aw1Otp2I z*xMF0v6rpO#1WdhBE=Rvarm?WBYN86CSE@6@)60l?h|vTWsFF&#ZMeIEptSoEpg&y z(=Hm3U`w8O>9oNk;%zAthfcd>L=Rib|JkP)42=S{q1S`Jser%$|i z+Rzb$r;QlVf7d`kZ{5mwe$F>;f&R_V{uy+C3e5@7D}>f~ z=-dR28=-LxG_Hn*6B=WnQHktmhubDJ7U%n#(4i+vIEQ8(s>pYck zou+b^GWO*Y2cQ5M9)p~JFzupYrPi+c9RPJ=vs9fcW-xy4w|4j5sA6L$iR}^^7UmV= zeF2b{Z;MczIsJ4t2Wnyu^9dX70|FHN5D95@<%+3u7s}VK0m=x$xhd zt6?q`2hBt12&u;yc*P!V#Ta-s23}nceT}lSA#@o8E zOIl2Aw!U8`b-x~djzNdWd$G?751NScFLe{UW20$X?2@f=29e)5WPJ5?^y4w;n3qUJ zXEZ+H3|>c@jYQWpqBBHy*dHyJn{^9qjQy<%J<%2Z3QXf=D%gn5xJGl<4AFX3+|)a- zh66bjUt=%qL4O;prBoEg*Iv<|e#+iifit=G3R&BJOP?9vyY`AFcz@G*wO8E1`_8;i zqJNG-f3(maH;mXopIY0^PXFG)^T+hPc<@&C$tn1hzBV-5Q4ml5iata1zAXJ!Y?4(Y zs%HF#Z#+PMeQv~aGY*b*1`Bz{7FqBycr(FE;Q0u&LjCzC=*v+5?f)nHjHwn}6^Ay1whrJTs8hCrp0#Dz+q<+{g>4OH|p;Pge zT&pG+ZDxF95Vp(4V>ztumcU)IP8~=*aLLf^iyH4W&WVUjxu0tb^wbFK!+W8Dr`uHog$mJ z8F&Xi0&fj>X^Ko&GKWH@Cz*R$lUQrlq4)B!b!H&X^RZ3JSS0!<2K`@feO8BKOc%x@ z(e0x5+P^t1dsvsL*~3JqPg32Q?c4{@(fD*NYfjPsj{-0FA)H;BrJ42jgxe^?xNVgA z9CT-6_UU!!1m;hoJI6DJ65V+t^C;1qS2LFq{U|;Uq7(oBIG+;T9MZv&b1KoDk@Kqm z4LW%ebD|>l2`eVlZ^v!IX8Utbvr)x$;N>{KR0~zb~`?{%Ep1W zo*O>;yB!~!W#hox&J7@X_b(_+G*PJ-R$YD;eAi~-3RPjNxvJ@$ruM@yjsfqxYQa`GU#{c{|<1Lp#KFv z9QH!?(*A{AQP#)I)puM!ds=HH^ru0;68g-&Ju*KJ&A+8z4_e(eAq2Ni#uQ+}-|vU! z`_L5oXziS$AK6B$p)Iy!+4t3LqWXTDRL_;(2_;a~{u=;8SQU z-iysN{P~NB=MN&D|HQM{pv6CY?om18*TYj3cE)e#A2|0EI^(ChdaQ$ta|u^*cTV_s zK7menJ*1p1w5iywCqhHc7ku^d$@2x(X5Q!I$=;{@S_;>3zT0N{+H+5$>1%(Cby2Ie zbGF2>I?j2%Ab$2v=!)OH?rVPy@mW?WpN6k}3-9ypRF}FqyXE{)}ejGlX>8z>6UsJ#T zD~0%b+_6+gI&zd#_qDeui|%XBy>34LD%o4seB%3RonN}bPrO$D&73V*q4ZdKn~S&y z4BsMRYJ7a>edi@`*Y07hR4Wv`=fDwL_;>i@9LI;}1pYb!>{CtT9mEId2>w3lnQG== z@ga&QURGD)a>c3C*zPJVwug#|?WwxOrl_b`@#Ei(&3XNNYoVPxpZxDB%GAqS)i780 zd99t7Ug*c}?Os6nW?>_gv_u8{lEPd2Lef#3iz_9)N9=#4E9NY;7W#){6Xbs@KK8fF zFWuQ7XA(xLAot>WVzKFo@2!3B+@0lO6U7edXI#vO*1OnLZ)eZ?@Ox1=^x%0gHqFmS zA0dA~JhIUS2Y9}L?>i37-x*K+zQYdp9WwL-HuHaz---4)fqnmYv+^}y_qI{D25j&C zjqn@Z{Yj~@Rb4+#y|vVmR(G>Acq{F7+ZXu8u%CacRc#Y{q_U+}5c_FnRXXuyWUYk# ze)2^sr-remjyb@j9CX(k{9h&afTwvS9`G$HO}8g3j&|0Rsl1wUrFn|W_Y~ywbMRCA zibwA)$mi$ar}!0*-p%uFo_F)SyI>0I|Iw`H@iFRVA$?NT>8#(y&!{}-l^LUW&L>Ui zdr5(nJ#RPfoV?3pU0y`$c+)k*-e=YfOP{I&E5EvjE3Z$t+M0{7votXF*D-#}ozTRz zoDdw6#~oId>?vQ)ZoLfO1`D?0W@1miL(G8V@VJ*sttcPx!Rm7R`>R)tPzjYPwnWCB zO7!3{bnCGzRYE`fyHe`YXQx=zoKj**)(~TEp4Cz@I#Cg0(^et$rbH3jj{pCO*3HCi z=!Y+UN|Zrs96odp#yW$eGf&cbN2Qz{9emPLx*K%j@N0aqJ9LKpU(ms4Jtf7Uv%M2^ z5}`Bd|AG!a?QE9mJX(ew?ZFi26rP#R3zw@2I#2L(Pw8*q)-VoDNpl8oE>@ltcu{Az zSBSULwo`M}gmT)e!J_8aE>d&;Wa$+9CVF8L@*Ky0cins3JC&hwcCS&sJ%uW`J8fKb z-8QH11U9bVEN3u9Su1ReeIoPQu@|bT4I}*1pB+)|B=)(|4F5$-REeK@*rwh!+ctI3 z>{3fi$=&+%Jvb6HKlJ4BlCICwS;AU* zH2u&9Z-i%KxCd1FB7M}8O8*mCd62$nz*|b92b%EoVS(Rzuubo8^uc!c5bS^~6P9yE z0z3Txu=J^ZX+MU&HUvvw7M&2s9f#6y`q7U=57I~a(cgQS^=`9RN*XUX^;7D(PW@>+@I>5Mj> zw?n^`xSqszGv3QH@jabA%=eV>7_mN`N%EXhGLC0wFSS7Uzl{I$XtQI?+5QGkq>t5G zW4!_TSu^X0x^>QAZ@yo*0zWwMf2JMdqz^L|%JVAX@vNGiF}oa}gptUz*wv-qaz3Ua z7k@nIyLT~1PK5S>|2f&uKA3;9pS42kL1g%U!MUOUV+!rLTr?$9??c{`%wb(Nc0PD*j^5%no8K?ZFVG&JkH3;X8BL02RNNywr`As|Q{v z?@L$Q^b2d&#S43;9cN8&IcIFgEa;h54$L0*|2w0V4iFcSj;p?oa*$t~yu%F;=0iO4JK3Bmzc(-RKFu=;)!-CULp@J9kt~*rI=TZR1=~ z&Y8vlYoij4@-gn+jlYmX#p&y#S_l3Y=K82>UzIZsAJYBsr-Xgc{dYQpcgg-}r>@%$ zQ0Jvu+_nQH&S0e$*Sx=&_@9s7Ft_m%;GucIYV#ia628oH1}i$nRy>Zc#C~G5t?S~f zS*zvM)M&DnVy(o_!B6ok9?jZ{pM#&`S3J6b=LVh|cy8dl#9GcvoLoyCVgA*^Tuatc z{jYppUrS|N`Aqv-%FnyVwUn!G(TpUUWn!YO^TY&O%)}^Lw~1C;!o>SEwZLNQIdRss z?D?84b>e+dO5j%j`y_CW0J9jF zMZlB+;|69aFq^QCm$fqQV1B+olR2o?wWOAHT63v0xc?FOGPR_25dJMMs@RH>tPfU~ zINo1<*A@7(Yn}D^P$_mIeXpCm<_c%x5DVGFz77fELHQyo6n8Tdtr1|8Fa?6 z-f7rr_Zkf ztcPS>v==>&f9OpP&S3RdQLzEmL?cyH$%X74zr`4GH+ytKAG*Ppkh7)8*ivL{8S+$V z%2*{bc7XA+hP=luvG`NOmejER`fy=v+J*02sM|lJOv|XtQqIuIdztr1*{0*OQEvKE zG@EOzfhpKjMCQ>4rM;OCV?#T*@w)0}^uYn@+p-DWOj$%99K?QfC;k#X=oWX$tJ%mN zU%*^*ZP3yxo*@5m@U4_Vk^2;jVq<^I+z#kpXKzm zY!VshTH?q5XB)nQ%khnS{ENFj-}UYZt*69Kj98 zt5k7%T&-@DqlU9)?edMkVn_1*cg?2DcQNCg$afKAp2)Y1c_P~~?umTM*e5bB3X~$>Xw#@7|XN^z) zX~$>nw#@89XN^x^YR6{{x6JHMXNxa=%fRni631FD)VE}8lKyqlhS<4eAO1@NkX^ao zq&L3@@wt=#S20dV`pXk-DP2k5XT5RM8YO#58$xjauY5t@Q!?VRIlFpB4K?>qG|$B(KY_4E;UE*8dE)z zJJj~04=OF{FzealF6L+4Lo>8!2r>EjzTG8jw&=u>#K;eDZ^35b`W42gp~NNe%6f3{ zTy3SFeXbGwcgMC~=4Xx_9Hzx zR=2lPB_<%>%f12n?8SNg-?hCaynl%G%M^YA$|Uu)QWx=8t$sjT=|0gm)IWspa;HOj zwDX96IQ&M(B-*H7p)>f}S=4VAcUZrV%n9v0%DQWgwi5ZvcJN>FTHxpZkSFoBgvXM1 zl>NO=$@9OZe1)p@vQOe$Fa0LdYRY`F*J1DODMNPIM_nF(XZiNwp89M<=35%uR{ed1 zQAgq=zQ&r|n_<%Zg!bb*URRQOO}pkzV?2~^l$hUG%R4<^_Gr<&5^vcKA3Ct&R{Y3{koNt zJB0Q7+Q)N$$M-hT7o6LW{v&&k(uZ^&(HHG4?8VcM>~8%|>=Nlejy-KTzk`qG+pEU+ zb5@PtOFS8u;?Q4Dy-h62L>)I}zDQ(F&ZiLP=@}D|s(htIA z%GJ%Y9~$8@m6?T3fTt6YsZ(Ixah^Z~?3N4zwh-8(i$k)SUS${%~+ae@nf80gUMC|A7~hXG8Z$Dm2&2JL>%MdeSiY zs2^m=U`O&HwB9pm35}J|I0U~!G?(+-9QM4F=e_OEN!}&$O=$cP8X~_EUtMse&q;jw zKY!7-s!Hw@xA$(pUv{2}6CkGKZ~0%uxaM$mZ@*vG@wKy6`&zYz$Fw%eljOaBm+`&T z?caN|TE-$5yfNYnYWO^`PdyNu4!#UBmTm50#0?CMXY8T-+_5U>^YMAQF5Sspv&1*e zKE@umZN9ehIAwPegI09xcGkQy{ymMo?`d@OEbbwE3f(!6vx85!ERg#I^>gQ&FOWSw zd}U&sLGA_&CR!8M2tT-6Et|eGvxa%_WD9djV6IN*P6yiUovE%?MIX**Px}$ZvP$BX zxUlVCh2Fo00J)oN>TrPh?>o@bVW!%3c!87rW0YYJvC|qjLtl?SfwUiEs;&BNv|!qYft(f5owOl^11;%kgPQo2w7 zhF88JcL;>qO>YO0ZR9PrU1pQKd(FIL$>VOKaC!I^e36AZ>~tY{&|(aE@IR=0e&j%G zjiM)o{)7p6Sx2$i6*B%Y&Sbmi!6VkhCyv?A#owOUS*iSTxQ82onGu=nt68Dq#s>)zALMzSdfD=14y zU%1S?$H_DF(<|sF%`3X%TiWzf^g|VLCikd>ROSXRv3FAxlQ#|7+0oW!tL9GM>bgfdS063yp0y=P<+PPX)6cqa=V=UiJ+n$V z8&t&@-PRThY*%38$UiU3g$*i@sd+No?(rM$Gv+b1QR=m-p3>g#9U1(rHfOcS&y;>D zn88o(k4Pt#xscpDUzx$VJ@z}D#DY#_ZrMVt=~`lKKS2NbEI(KHygXfEZ96TVT8n%2 zbjCu_(X2UNV7wJLH>+ck{b6A z8+YdXL)RI4JzVbb3(b1Cp|4m&NqMEL%qxRZ?ogS_&__=YGg`{L6M2z2c}H}!X+KxX zsk-PX+E#Rtw4dmrr=D$F^&~Wo!pm@7(?Wi`EV;P{)@jJn?Z}ec!6f)C^u33G6WwAB zlb?^wydU_M$WPmrXg!{-j4N)D8*`iyowGSv={|Gl@Era9+r}LQ@{U;Gm%1{NJQ9OR zbS!lAm`joCtbOtwWNR7zuC0r0o;Sdid%kw8BX+#^>R@1Tv_~w(vX?O+-oj({rXohw`xdIZgQn>K=WJH zGXkHi@~fZW9qSkR2m2ZpOGQ0;bIbIM)}H`-4A`}NSHAt-7ON*?|JA`0of(^)%tJ?9 z6TE%##8zvS1})8Fa}gJYyHi}#&u=|8%I5J;ilQ&{@itJNKx}MvTWME*as0Yf*HgZ4 zp)Yi;R`zb{EuMOO2`&4sK~8#kkCpbQmT%NCUu+v?%Z&y0L47PiPM_)FnarK{TWP1j zEY@bDES{j=?<}6SQI=f#@@oy<$FUByHNU_dyj)qgS*WYj_X_C9K9LKVdzJsPeoI%q z^?SZ$&h22HKOeeME{*z0DrM?N-7=}CgL+E2q&@*`lu|eUVrNk5BXe~(eLYZN(3x(~ z*`UEQ;e$i)s80j=Met4P*-&wH^*Z=JdAg$&K5tmWe`yB?ZTk*wCv7Qsb7>E0#{l2C z3%Rh$91uBxC(DcAg~)JQX-svV@WkX#PvGbSteq0Q`BjOYdhR`T6QBFpJ#DKBsk^gD z?_0~^i@pc?w%~@%wciF`?0we)Tie){Q@~oS2zh=6p5$|PPiEO`N|&9jL2Yx!RX&qWVSg6~zrFZeEZ(FpI)177N~1z6EP=ke{M;0SMy zfg`+j&>kUPN*hG-y(=_mw;%ESVe(z@eJwn$V~sm`y1iBUh45SE18>s?!tc4{3$Jw= zw1c#h{ylgfrUz@<&l%f{VG)n@+ZhwK6SbO;wblm2@M(3K0&uC?#y}@Sg`>_qw^GY8EH@X z9__b0UqyL(+Lgyn+pqYUst%z4HR;P*T3o`m-Y#jq(`dbF%kYvkuQuhje}Y@Rw>Sd+2VnXQlky!Sfrlyf1tzbxrh& z3^-U*ls&BUJI?OV=_Gk&O|h8&BJ26ADTH5A-}ZaESX*SUwh;Lfp6T_kI$8fk)LZKR z8h0bPss9Sv&&`HW3tH)bkh!r%_qE(U*!EuIv;A&(7Ei# zKSTS^+f*H%CwzYI8KWO*vBtei*Q_I^h)FL4yRM?$CvoRRHErr(e9lm{xs#mQOefFs z?F<{wUvcj_wg|bK$sS#s`v5fcc>!zw(A`aX`_21n^L`EB0kCUo>WSm={>S0C0* zN#3f?G4zdO?<1*7pR*k%6+Nc7YggiAx*oQ+7U2)SIm}-5Mb>}+zN$yoGA2BuJPW9U z-2XI>)VRmQkOQgL9^}43*I&l{bZ4qhp;@25oJD<}HS1G_Z=Yh`)Y09+;!o$wz@A25 zJDYoh3(fjmXV&K$y=}NRH=TPKxm!){RGUHjNWC^tuR7`#>ThztsMtlg4IpP1GF--a zDC;|!6|CuIRsowN`g6CzyZEE7=eL*NB;YqwZf)wF zv&(yNCsS4WYz;r(vRX-RpRI`NQsz&eU8+>GobNGgDSy-F=x2-5BITwW8Q`DKJ(%JT zB;S{BJ1Cpf$@o_1iZYv;Qx?r{iqgOND0YX_y_*WXub_Rp_tmTkPWMi5w}We~HF&16 z=8-a5uu)%y?~ar$kFsS@UJEf7Xmh!TC3g{b6)wtA!vyvjViTO{eJ0;{jc>HWs7@8( zG=!&*a_;?1?*~9*9Wu)UN*{(k*2}%f&wp$X z?REG%ojA0rc?oovN!iW@Ps$yJR|+0?uj*?-8J8W-T+d6$axr7&WPNU!3ci#f zKpHCRTFxLWN>W27Q`eEy!%uw43=VM^{7duxoH`1S=883v~4Nhszx6vbo=P}mcqr@ z2HewK->F{qZtm&!?<&!$b{QjWPVUOFcSBCUuLMWtbFOGJFIs)?yuWXPL#fzF$e#Gp z+ld#KiEYb5pUFoLmlMPKq3M%{J+#$6tbBULur`ZT_ocTOK2!0dfI}An2h8+h;4*;A z1WqfFFE zD-8a`RTSHn!7q)oCCZI$0iHQ*z3x%`G6py}GvX-7&|^GXbX&V0-U;8FoXMzgRm(3vZ-#24xGRLR}=`Z#i&xn+EJ7;+@@ZRvZ`-=zOZp9^3|5Z(~maaATT z=~1*ZZJFL(&D8kzF>Esybb*`;a*+05p53lr_-0S?L=MCI=8I`+rS$iDa6)-H+}f=?~-w(%tyZYIEd!I!)1E#EA)~`|A$qzJD6Jy`ig^-<8dE&6fTC zvgyY8VrkR6=o?4bN0j#(<(C+V$neZ%62Dq>B>GYzb9LxN$G&+xThV>eS5{;Dm%c18 zQbxHCiZ!E0_DKWyBIMDx>d>D7bY^(D@1)$)hnEqLUTjXRleP){^x5d-dC2jS{JGP3 zr}u4ib{%_pGLIMDJ%de7_?zM0b^WP*+|n%Ts5VQll3Mnx>K2dB3ec|U^n*tFHg=0_ zDf1}$_e1pWXT$n<6@9$a?Bi8tA9vHoMK4GnuQL0%+w9}m_hQpUrq9sF*CS)ko<$#D zk6b@XA0NrNn3&V_@paI8hCcoyd0`H=j&@r|J4o9JU-C}?{4*_^!_pTK|V*Qum+v%K$q+D4fOd)#!6d{yyGr-A#;e&8AD`F zG6(&y`4u+Z=X5`rAY;EB8-2)rBXbCuC-@l$`!TN*op~UKIX${YzLUXko#{`IKi|5h z(%kPSojDqRg1j;8_0u06tZ(IeKkcPf%J^v~U!GrQ{gci*y@<0s^8AWCvrZ2@U_95z z^8hu|)@$6{vWM6k;0*SOYaiP&e87uGBwlK&d)%CP)89Wbd`aVxHugT-Hfp)YGqpKw znO)v&yNI;dk}GuAKu6AU&-p#;x3;#Sn;ysh!x+0MTg_}`Phiufj8&w)fZ-g}&~Has zJeN_owz1TmJ+u<=@XHvwnf*_pHo@j_CHv z48}IA$Y@%#YsAU_wZ?y+T7KhA>e};W79oFbzGZJwzPzR-I|L_h--|~aOFlTF#Wd=) zH0BU0(K#pGrp;W7Z)}wb{}?h|*^_k}G`Zs?S6ykeljw4>cj;xLu1VBg?1UNAmAx8Y z`V!_-0~zNBs-b>tv&^ZQ?L6DT^S`X+4&AGKvxGMH-H9K4WjExHF_Qaca$UD{{EZW| zfqbJ&*f-$Ogj(jRp>Mc(mTwI0&OGgTE%#QwAu@Xl>CMQ)vHUb_dp*7W1m(F1I_dNo zC+|fbS0=bq^>^cyXMp+6#XIrgl6SolpElkfeFRfOc>5T~+%# zlWv0MN#LEpe24t{$7`N$Jb#6ZOF5288947JJgvhfATp#uV>|VhKJ#qqxVg15rlPN; zKWyo(RtlZ9yqErU40wqp(S^D7cNV4h!9M}>I%B24Nx#|jgLS48KkmwbYG!%bxVh4Q zlD7=4;9U2|Lbu9No4ZWtDV4M7+w@_Z*z=X~LF9C^+*R>nUaozJ8Y*=##`9j@Uz_c+ z4jBlweHHU1t$zu=Dp2MpT_tp{K=O!MOQ7>k;q+u z@WFma`I6y{zSg4rdnvc{-`#qe?5)?+Ufx&qG|4-Jw23+iUzANA4q8zR#a!g%Lo9Ionol6Nkiht|V4&IfH` z-f=zmFi1NRBWA+LW~HAW$fJ)B-D%CWOWDxJPs88Z^Hk34&)agCr=*A;8A<;S*CQfl zAziZhU(7ROoj!leqvP$5dhZ*_nBpK$rJ)m&w3(Z~GR|g;4ylK>lkeF1w%Fb>R9=>h zJ^A=j$@pXEZiH9hvr=C_$sDDEwt3}R%J=JF+v_16{oT_)*3qlrMWl{?lDs@!j~hDr zah@Y}^!b+>I(il~BX#r);H8c4($i$`bkdG=v|H!@spb9EzfP9-qYlbj0A_+80EdDgYxDBFXeUWX|nf9(vHe&$jhna{q&QQ<$bn;@{WX7WO*+qFTA{$ z@*G*-tMCzaAp2<@l(#4FQr;vzP4*^`c2wR09q@PPu9M}R-9dR1p%q!)ZsdiRH-_iP z^4^|fl=sk@AIn1%-;wg})6-<{9@37=`yF(L$hb>C|9Ma5L(HEX#3VEN{+au`K9167 z%C@vk(EAB}rZ;_N?Y@c~DvEJ@Nj2l{2S*&yetqm+`*zy|m-Hv#5`a6(|5DP>94yb* zHenUdpOF6?v3?x&PM^d*dWl$yW#l=)dz<&6{Qdag=b8C`mVEQSkN=_m*QW!1zd>Fk zzh5O!=4IhLuOTmz=bcO$d9nkZF9Tk9UZJPS-bYD0;&~-J7u~!ztei)n7de*`dXeQ^ zLSA?o%XyA0!Y&2^rfM;emP`%m(O`Wkci?$C_nNep?We75tY6M2z**=@>a)9N4dWjEgvzSQd} z>t)i8_;L)op*H`*#QDs``GoW^eKWkRL-lPo^My}aO}zI_ymv|KPlNX_@~*8Qvxlf8c%Y>YJ%!uYrrUjXS( zH|S;S=^dx1Dc-T9C;5o4wz)nmf{&r{{jr1c-2`4_`K~8V=5OKUyN0~T@?B+?@4^ns z*B^MP@A-O~;>{%OsC>EY?cB?oYU1=VaeC@$vbO>HLrng+n*CaM(9MMJYQo2miZ4z_ z{p6sT-_(xZ)B6K-MHau)(`4^)(v;J*b9`7kPXR8no!iKZkpyCeFJi&O4-kI1OK3F!P@ym9>cc+O{Nq ze2jgl)?y1WU@YF2LWTbhXL3#YVoMU+V)!|%Ln&&d8(sfv?4)ITSUtUC?B`2-0_OWO zw=+ktQ|>3-7hoUw&{5HIYEkPSi3t&~IICB&cg20k+thdYE2=W^&E!6n419me@#89I zk3w;#iM^g3o!F~zc2yO!2RTVuW^RV2>`m(X1xc(CdYr%J*1@Y+JHX|e&AR;tf7L*$ zdQJFpL839&lD!_or?Z#$Fl#sFVcDnMYuS?M5q}dqF)L<4OZM8-cTt|SuVz2#cC@}x zjBk-kFTZsgarK+`ab~-$v(qPa9>f{1dg`p~?(vJLcMqANHec>6;FBipQFx-W*K( zCS#8md#>cW-X2=vs7>)?lm9yRhAv_sqCH>r^5o+$oR7^vgZJgU%U}<05qo$7n@PJ0 zYp|WYRs3kA}eHb4JW4PcKiL`L62yM|ZfRtB<&^ z-Fn2S`H#4^4sDe>jH6Cs*B75ZX_LD}Zp?iWdje~1?2#I=_C^v+Q0N-wr;nxeQ)+~nSvd>mV`^dM8@goX! zwytUYZQH6{*t)l48}pZ7Pr9FbTltp22(Ii`oodHU*6kFNtZ5~7*313}*$a@fbNH%{ zQrg(bltJv$vR@^8EwW!#%-)G>dXc_gMU2t2-ml7Ize?FO_Nz4gjtC9f#asQuWFKbA z*1)hS*qw{Hb9EPcG24-2jdq{1wQiV|y_eg0e>=A8Df)YBiS#*E%G}#pKWs8ICbQ>K z1b!W7|3dsn)^wZaNNY;TQevJ-o7^RR;vRUV`!1@({dzc$7ePz>kA|QpBppsW59WUn zzB7XJM1s+`oa~2`neu-jdoOoAlWl za*jcltqY!G%rjEAqwfOk`Dl;$Nx6&nL`B@g87=&a`bZ zek6MJ`8qyWnk}YvK$2Q1&y?q*40u0zvL)B?)iuG=BlNGAHeVsWr1Y~LMdMYlbcZ$9 zb-DYB+n^`o%Oc&kwo|)r=AsUK6YsKHR*DUec1@VZf3c(0B0n;xiS*4Z(|t4HBYPBf z_ToE&k?#s$jPWhe`{$3@in?xZTHnY zL7NC22leg+th8l*Z7*GRMJEbBMkhI|`z5LB(Qaq%)qV1+FX*FH_j9Y<;TYoGYYZ)VD9GCh#sCN;vp-kCu zA{)AoUYJ~j{0F6v%lBHCCrse`^8YjQn{xh6+D^VHer8|sUHOKB|8CP)c1;-n-{gOu zd>{UceD;IyHu#`U5m~~Cf&$n zxbLcr*|KL84l6ik=a1^l&3{MTB=;^%VlFZjyLQMg^`lkBUVuNsFEv!2tEj8MHsF`K zuC|Y7D)kqA5qdAO+L1qJ0dOw#@AZ;qD9;$uP(!8uELT z_LO?vhb)BqbDpU_ySf|ox$Z3LGuW(86*hDAU-IYN^&6u;pGv)`&rVX&PulNK`g0y% zW%zTBpkAyAP8koRze!u&M1Q8=Wvg0s6K9-eHZpdW%3djDg(ulrLYH%4A}2!sDic0a zzRSLk>um!M+tP$Y=BMAxbH3UcT|6r$u|npn+`m;(YDsSXkhzcG4+X#dTj0nyjCL@5 z@df5WU_$oCGWv<+^*6s8`rbbLEv2oF;;WYzCAut$^COn(S11?#WyAW~z8-x}z<(KQ z^WA+tFZ9c+j_#*bFOJ2Q*~eMkxsR%T?q27d7y9K_FX?BguH|gWdg97F)QcEy_o_L} z7dRu04+Ul12Mvi!z?jGweV!*B`9TM^(;gM$9&cwnO9n^un3QLR-X@9Or-2RSO*8XW zkr(QN#(um{*SRt#$$q@7uYO2lE)=#8KMwzj+ply6E$A!0#XkHqZ&C)2()Zyl`nmf` zbd-&KkTTBo-;Xb!G5<>P&O%Pbj_e{|%C=MHW9-AP#otbz{~^y`sF_Q8vSxy|wTpj8 zp1pSUNM&tW%RG3o&A&tb`^CrOLwxTfUft*H9LxNm&gLt6CNY=&a-Yybx2(A%wE0*Q`O+z??#IlUQ2u`dJzd9=veuX`-&N+`muruW{WID7 zO7glotMA*o>HV*L@9T#&IRpHjzUO6+Hui+n{ERiii&}hVg%^VRkjaMtc?P}Y4r%Ch zlyhBDN6t}(>i8ZqCv@=nS>>W0j49a?KUaK9_RIPN+xQ^-++6rzD*Jf}_;SPxU)}+4 zl*Qnoi?xK%7v2f|5bX^nZADv1ebJX4mQDO&#hx?<9U$jH84Ix;$y_tVvzxqcMrpF% zS}yul>`8v|jxE;nfWz*@81f}~4g9YMrVd=OA*@d{>o}Toew*alNG$vfRplBI=Oea>NxjQo9^ifjQsD(yDRvA zFF)xY+;vJhQoL3AH0H`UW5?_H!F@oEwE_JKdxtba&fEH|I0 zlghZXlr&V2?H$x(D)b}kQA}QBJtmSDS&vRVje3mgpdMEOFKs?TPm{ctlXg^(8_n{D z+HbIl_Y)KELek}7?ZUy%_BIlG-O8|MX@9$k-`B+NL&{jwjuVMr&byE;wvffxLM(mVJBs_&uGZ+o#a+)U^cP#Pg;}$)+4$Ppx>lFM&o<6CI~Ygb zJviD|i(MqW)jD&@bTwfMYxd22qao8OK49ZTFW&x(UWMzGb!=TqW$NC<%3J>rdG8({ zWp(ZU@0m$LG=e|^;Z`z}#0%6rw?wf#6A&-p4QOq(r%V!P(bTpSyl|M04RHL;%BikDce16XUt(<+|Y%jv0;1c5fTM+Jo-kl*{WpXW&?BSHBdU%%J)_51zt zyyltx?7jBdYp=cb+H0@9cIdblMwtVlAsr@k(W(NS0m!y@FDh>c*_$dEz*){!qyGDu z?zNkC%&={F0eo2xwmx&yn9+hSAL|PIkK1JzSsBVNzH#)>`)bYT`-;qv`-tm0Kg{_J zWRYN2E->@{3{9@g!`HdW%=`WNx#jO&Y9?)lRv%OsCO+613d13DmYt-qV-K4Hk=^^Qi)Mo1^fgMR2W zJ$lDUUjA&QXXqWZo6*bBom1CLD#PC-q59{WVKpy%aU_apU-*1%ZP*R`wf`@k?Oq%C zH1|3{pCoM<5eirz?b|MM@qZ1TO82YomY;d3*XP=vhhBA3!qpwoJv6WQerul2!u=ao zxAJwCT;_$}16Oev+CpQ-`*gkTbHheA;;S!xNxoGkTz8M9^Mx**XM1$EI)qQ>3-Hsx zFFt_1i@EciM(kkQ@r!>BAFg)h6nr%nKk&l3QT4i4M1G)mnb!5(RlNbf(9{*2lgu#< z>Km2g&JAl5b7nW)Tg@YzY$N`n*wN;^c?&)l_=RrZUTxjA!hOB1wqLQ;gwgY`#dx-& zf|kE}{8!|_SHy1(6Ay~{Z>V_j*YwFW_^l0ln!{KU&oxHKGuBKxfqJ%g;CF;vm%Iz{ zU*l?LVd1z7Tit%be<-b=3TsZqUo8obngjUu(bj=cXa(;VQAg_2X5N0_h|kVD2#+%U zpli*A#6D1*sOU-N#`)M{1N4({Y@-}_elwhV+43gz%G6!pI1L}9&*1w=AGo$K);+%8 zHSuZ==XVXCTfghJTaYdIa5EliQs^00M<9(mR9)Y7{IC_@y#v4Y8Teoula*JET`+b{ zM~@G7?4rm4#fneiFDf7GEM!KN=Yw5^jqW*Ogb(CfC3eIRItJ%@%Bx-~B_03tJ+2RS z(Axe=NDJ0H!Z{xKV9O4;02`q44OChwe%aUn7hwBSzH9NtEAf1=t8G5R{Yb74wrqn9 z@UH{?L`TuEjk+>vScgCRPsyh~j-5h3<>OBTZ&%}wQ)}`&zYDxTmT3rL#}6>>YJ-8! z*cqSS@7z6e|KGUVVt$!<=QrnY4&<$scWN)B3jbmCK{#vE)Btyv_;;ApIqPOmGeLV! zAd9?J!K{Xxp<@$q>jbyRWOas#eF=TH=1|ugBY=y4pmpLwu8YsA--USYBucE;R1Q4<*C7&EBC z3?B66qL~MOoR!@WF#{SRz%xA4DO1N2=czUW21QKHAmVio3e=Py*b+C_BG)?&KI%F@ zo>kzKl^RoC%Gs|{&VJRxPvfwW&d74g9ejd`wOw91n5V$~b|Jp;GjjRHS*+3#q>teV zyWg%R-sKE4e>6W5l(sd0#hEI&2yP4myi09#_zYDI{f%Oh5Jl*@2u#mRgAm*x%=yo1?loN zUG}EST4EqgIx$0DoX7tjnK8O>+`PxpC$ZRU;28;Sux9{R(!wN&$l+tBwfolE9b|+CmWFSoQt`TvqqXPv>&7R`6=a ziO{#wGlNTe_1B%$TUEN5eLLq)cYecXeC2?9%kS)7TM8^+HzDrF_;n?N7hlL76Vmy{ z@m)G!A6-OyWAMjbbUxJ=!^V)V7yOa6x^y!4ERDObw-x*jr+>}HCX_B0pwYbd(7n>- z!H;N{`hERftZ}>;U^@GDH|Z{Jqg#Y4Jh1pJ{O0~ndot&!%3pNPyA1sWx@@cT&ev34 z!`Tb^LcD_C>bzI9r;m*4wleC9{pPfMVDoKA}$ z9EKJz9)T9mB45?kuTbYNdCzR$Z06smNca1&q|~`Fgq%SqSQc7fZq)o(Oi;^v$!AbyC_85paNjE_?6palNa7dpQ8B)?Iwz=DgVkf>b7X%zZ$E3<^t|y% z;?az}TTY2vTie;>-P4m7`$s&Sc%Ub*8^f@Aj0^X4!9|Wa%-_4HQ#L%=^`Oc4Q=n}H z=@u94guX4Wm@?vX`8K5BgCg|o1^Lc?=KFae%BWvtTSU)!N9z{s9gqGhVeK7vRIndp z?H#E|;uUbx`=9w1pxi_r*(Tb7>BFCIVOQ*rA?u_IbW%q9i~e`5!>=SwdyRJNQSayY zFC4^=>G>`r{XfZ)(0upGg@Q2`)Pp|bh{zxz8`H3rZvWS#-;EAF&@VM5PRA=ynm73kvxs; z2NPcu9o@ADcHk4y#NK@D<#0ooxN_2`!z<0`6nPwCibags8o?K2(-(+Y%A6i#9xMS~ zgt;A``-Y(WKjQEq{S?Ii1KKX`V0~!FH;p-4dVdEp#moYKd<0Ut=%)?LDe!J;9&dfEFu7rQ_E7mo%CnWvujd|1}vuW>B<(d-HT;8@myva@QfvC3&} z!gpZ=d6TovMC%uDJ8O-VfzjxsL$uywjh`5auZa1=z9&PRjWKyV>?7mf(5X1&qwv|i z((ZYWYFT!f_Pj^782T}km$B!4IX2q4=J9*Do9|z_`zx!)G>>F2O*q7{-#7U_C$l`C zlfm&h>phW?Vb2#_=d)@k6+wnZCT@oW5W&Fu>WdRURD! ztjDY`4(Wri0l=gE`{IO#+x2)YcN&OiULShjC__6V+!YgvyXVWpo*#|w!D(Mb+@vS* zKax+)blUd|)3x{x*Vi#cx@|A*470Wr4L0RKGaiSh!qknbBx^a@%yNb zogf}t9Mw8uaC}rGb%OPO*o*Dx5@>==YJ3D6QXMv=DW!k7rwy8>24O$q942zao>?x2 z7L_W`U7``EC}FltZh)4Te}?j}^VGqd?WNrTYyzA&y5mZo zIOXvw`D+@+nS#m;R1M8G_*7B0w@vpADvx0Nap#hRZZX_x7976?pPF`T1yzi16GFekPs72c(18#5blC?Q#*U*Ox4k*vbQNKTGqI+7 ztALBF=!)T^ld9Hl?Omy>i04L~JO04f!`~xL+0^f-tJ}2JQ-AwwI_Ki?9yH+`*E~Bu z;XSp%Ft%i4NS;KxbV1s_DR}oi?TjtahP?($lX4qBbY#u7>?1VF*GJ>g`eLDf)|z`K z8`IE^{Xl*?^Qk8#zbfE=fZi`2a)@VV=e8d^tx4JTsYiA!`Qh)o;+W=r=mL9n{)Rr? zbCuIIMz$E*jjppyzA3U(?+xbXy#h~d&T*E-xD!ulFYAAh|J+lh|10L2#OuL=h8IX* z*-=!sa(5BuriayRWiHUUs(n{n*jyo-A8o5bXI7c2(1=+lX0-Dy?#ob~)w07pi7vQG zy0z<{6FJfK&pC}T_9i@{c7CN3w^HP7{9p9*Noat)2!ReBpkJ>MNJY5%;O-uSk>Xt8!lO4uk4@fqVR5xpi-TnJW zg;>Lz8rMgP6G2DqBZcl$lR}0D;8(nN%65P|I?s@-t!-slTf=3ct@ufi$M=)U+S+dY zq_X**y|tJ;5p<)RnwOYIi>H zF}h{*iO!8HY`+(_TtffWh6?PO@dLigmSV>(_K-0>JTO{Z|2p9^+2yP9Sc%71=ZLSyG@L>DQuu0VAHGsOE^l289^&^%F?u_FJ)icp zmGVxT<{NBatho&G1AAWs<9;h^uXj?fF%G{obNO$G1*EmuG2|)U5xCSySL7F)T37O# z)KqhK_!4JK<=0G2qmA)6&08~zUTwb=gw~V3xz!S6mOphS<(oJFVMfBTHUX zeE`_U1NZnS_A>Cu1MZ;JPNV_Yr}Y+yW1F$%;Wzsoe(CcayN&(M`d8l- zV^N?*S8{qD6R z=*t6-b+3Jze1dWDUm16l{ZH1nn}<7PF8_>bSpmu6F{QiqQ;_6Kid&W@fm*T{A^hvQ@7kPRUXGg$qX!rZXy95{M zrT+p9tKPaUb!#K{@uws>{?oO1qJDUUpvbE0@H zp>+7{2F<0cf6j!z{4$5AOKGR1rFD5}CwXb|vsC`SdB3uEz3t^0n^vw=%V%JC*h0v1!AqpCrNaC-O{C?<&U&g zbnqYFckPAbhueNLZD+k@+a96qJ^qGXTMccG(RR_n_iaPBu=_~zH7uuo)%}aKI(N@~ z#*6nKz`r8UJS=Q%EbU)XzpX1=oQUD~u=FC+su%%=Ib#>{Y$EF@(d9@ zi-#l06MOCgD89^DR_gg7Mh3H<8O$9p*i$v`*bB6=>)rUH&s%>L#UF@LhhSHFu$$=P zn|#>elYt#=4jvb1W}k;&(;Rsvx-albU|%OZrE+tmzQZG(nr`5-a^>S-} zxCoY$2J2sZSm6^Bib3`M7VZ(T@`|%c#A3UU@254)W@?_go(A^~)XJ zGM>ERYxPHZ+{seXWB9NY^Q-#9_P3zr60grRUNkloBi7)1s6JDi*w2u!@*<}d9jOIf z%EpK-Crx?b{Z}gD(|Y`D4;Lf$qG7$fe?ITMy#Id~BUXNqmiLCWjJ9paZ~2tQ_1vfI z`54bWl9-HrLVgE2Q>XS$nH?P`U#}DM%$j=WqxG-SD^5P&#;I;EF}lBe4f)5*wqVe6 z+&;j+Cpj)r4_}o~R<55yl>6@%INxPo2HGbOb%ZrA#@&C`H zD^26<58iu#_y0_Lf0cLap^G13u4G+q_w!e2ZN-^^I(v>{m_0{P$vKKctl^iiAKx9! zuX)S*`VDLOmw|2_|HYh+&XVEZJ8yIO=nnlB zo5c6|^<~1xDPQlEk9*~B;#a&XUunU4@HSt5|FYSY&!q|ZE4#dDuzMZ5@87aLdG)eu z8#-LP(w`K3^8T$?-HPm5ZxWY-bDXhsDZlBy&uYih(9!pA?GOKJKL-9QJ^VjOf7VZX z_(weai!AN&XI;nH4D<}eC!GoX)sFAbj&^S@Rljzx8u)4;MqD1`!ti*I*ha?63;Ct_ zev}g!KLv~(^hD%rK_45EdVDi@lp=*DJR% z&%```$WwX05gWT1z`AIqS^N;VN6;w)gCBi2jPFr6U?#`@j&B2Vw&G>U=TLU4Fz+@d z3BM-Ie^Pb})f>Zq@~2s9U;lI{Dq%gym@R_7v47&fc@n-j)MN54SiVPoCdh!c&7WPK zdXl&?_-ZEcwYjlAlnBP%y#lRAN&CZfGB! zJa=JzR)Tfu>}k?nh*hb)U#^!uGI?%{r=5G-(C24ceI9>TeP39glZfW>ou|Ddc`iE7 z>}lASlI(N2m+KQIw3y|%05j}tDD0;6(HczVo!t^2$%-J3Qx>ACibpU(r5-+0=uaLZ<6BW!1lAwRen{zC!A-T;$5E5f6=hQ9%?HokW-j;l?eq2r>3 z2Notv8>*AxhU&2M>H|DkS?2giiu;GKAvDHsIvCk=(`%Ld>MUM`$;k_rg$9`$LxW1n zvIa$N%o;R<{}ucXl?6x-3|hcBy{cQywXx&O!EV;LVR&Jc3FcM4RNS!0m{~hm*PqAw zb|-7yj+YjdofHq1m#hwzpZJ|n`LtU@<O!v`NKgU#YdWfY(E zLuIgI9I4De=Xq(!@8KsM zVclqTn$)<&j~a*%$$#|KN2_Dw6BYPIYtOHgJp%1L-pO~JtGVv=?n%|2EYq340CF>r zZyo4sl8b7y!6p#1{_ewD)*P;W;t@4uZ8xH1zS8s``1)KhYtEe|8-wVF?Kk`aZLT#X}u3yb|o;GkB7*I zQuE(i+UwnkjSIU9_1JT?b;y(y_fGYD-h5S|)l;-K*F9Crr~K)D5U#(Jo3AL&KIo*r z?a_VS^51KtO$GRlY2I|$V;P1Yl46&Z(SPpVxO*;O5p5G~E9q&Hv9sD}eX+My?#dO-o=$lO1JBOkD zgpWb{Ch8rc@$oU}tv+fKufcbmX(>#{@gLaleg132ZoZVgF8LZvfhIWn6|{wBHm?hs z&iXs!_lPfI-#s#Yu2l@+H2%u<=r5W#LA!v>VUSo z!?FsVkHNP(n?Lr^?zL0-7Ov$URlcpkp4`S=Uu|~<6K&JErwG2>!`|I;@~6N*h2QU* z;FwvWcQ)-<6D*wd*l<%uTNXcJ&kYT4*~GYF{lmN*TpZ9I598q((zI5MAL^bc968Ig zbvHVobVkYk9$GQ>)Xom>d~?Urn3m5X>vrFiKl;8c6B>#_uB;s~zmT=+@RkR?y8QC8 z+c}JvsShKAwoYhR$oSem;DTnw5BN&E)4C%h89IhDE+fZJ|5^81;t;lI3~D@T{GE!g ze(doWmaI5w&8n83#KJPuy zG?O>~6?mC)VWQ@;kB|%dk>iJhck^N3J@ql*?Es$og8TjEr1!@_wHscMENsFb*yp>B zS+pJ69Ruw9#7`~YOqysbI*Yd3r@MJhdT~jaXe=MRR_Od7`D5^?cuX;cE8(Y6Wo8I+ z|I90=6OR&J6E0WQhVsR8qmpMg?B)OGLxrSK6mA9 zDKudIvplC59_qIu(j==Lcy90J2@SWwXZez~d>bK}F(#*n3b$(CaX$W)$4Sm2&-T){ z1&qh;;Hb`!M09dE~Tt&#f8XN z$%b_KIvD&US2d<%`L2B3f#0RZ^$zt75f>ZC)>R`za>660`Ka~#VqmehG4?iwd8MP^)39oNrElH% zo$j@#GnZ>Vo2s(l8?kzu&a{;$&LE!;%ZDSFS*N?ON-{RzrbFEY+s_=POm+GQ@eZa%gwiEi2wLB_BNf@kCi6k_WquNmbD>t za;0GlmR^1xwyDV7GZ{;Yr{?ZgJZNDKldWXi7T(q8;k(Z}7}>gJPV|wVe=}fAYb`dF zT5Kb+>w^c=&ufcDnv+~xe}VPU`=yahBfn*;-9ss8`6alj4{iTpM@qkA?5ETxyYYW` zcH@Wnul}@l<5Z}J?uWA*KXZI9-CKF@rThP(-5A_l{u|bEo25y9%k3WSF8+P*Ctl;z z8-9z~_z3webG>rnw{P$+T1McvV)%=_?yjDF1NbZepZPX5onP{K{~~Yi=^JTv+xoqD z5Jq>35Ywl!IIi=&ipkV~ZLG_;vBpS`+yXD;AoKglBY5xyu_MO2_kZ2O*aLogn(+BG zaMYIp&bbQy`QJ$!k3K%!(HR4umE^4*&f1~aDX(oe<)lrjy(!SlI;saZ)$2dL?bw8! z@;I@EW7w@7;Cvst)fTf)pHa3aKkZk()yj9sG}l4{zwJJ3{r2PsKDbQu^Tf`IxBltd z>{;+zjBKx>F5=QR#Bu`7tYdp%Db|D5Xxs6*5`VX|4%GS-8Te>*>XgJT+AF!~*Xh>> z4IeeoB$7HYQHi{u?v0Z&Xw&GmSKox!<z#Dgz@VcOH zI)3rA{vGa(kwC7?Q$L6I();Uh^n3FN@PZlee)KWmy?O+A|AZEn=RN$s=fkt{Q3BWk z@H;iSyL1|{HB3thdyCqCz^|lp6E=xp(kZW^y%BgIOst$3@yOKA8@)O!iKSxoQ zKDcW!++fD%G193$S(;chJPq~9U=HZyde54@c3aJ{LqGdL$V+aUK73cSJMtF zACZ$)^n0B6=9V8!c7ir_wn4-6wg%YewQWt7+qQnqYb$#3#@J+HqN}aQ&MIVA?PSwh z*>1`k;Xm<%`rhZm%>Uv`@qteppDsQwzWfzVQS^Ap%?9YupWKu$yXte`wO4qLr}HFj zE2gcseXJE?v^}-2dy@9ed*q$Hf7J5V9d>*{SH(sVT_ezRn#LElD$z3rJyYP4E@M*M zTdlp%2xDgze%7_@UtBA@XmM|>4%KykPrQz-dl|DfUPmo!7R8~kF*{^uQp^W?AD$H#v9 z%Owr z$52?PGAgTbnR)iCvOWcONMDX{N3r;oarUVFpE@wqky5XB)&PcSAwiiE%y{;XabYg#?Km3JsHx7hi$+~x@ z|BAbn!Exv&;pXXQ%n9&KVaqe*7tE*aZ$Zmb{7U{PpY-{PICk#XNr~UmFYA-V4Zb{x zeLLE$HgS%oPn-7i;6s0#)7`s+!Se~=_Vjz~^h9u2e9p6+-|mw?d0J2Ymh}A2X^Hm2 z_?(|*=8yH}|4~N%&E$U|Gr#H0e`iMidh!zoxM%%%J>SKL_tS343ejq@O&i|wb$<8e zOAZqM!=?>uQD2mMW!8FS{MaS$Ge!hMzv+GbD*ch!*MgVX*I%*qeYmeHN&iq^4|Mx_ z=3)9eYVl)_#r_twoXhXc9&T!jkN;PC+FZ~w(dNx>sY**b-AntIp0vW2@iuLE%gOxu zv^jxy$p^K)%llOfX8nJRUyW~#>tv`mKAY%)&A!~QPgs;P<&lju55kL&O79IA)+KTC zNMM9H=$8pmetRe~zINq|Ym&&=EaZ4L>!R(%R>~SNb6knW`Rc6E_%hB4OmxS22%oKK zCZ~q^Y@X%>&1G*RLrt*gb-`^)MjGVTRYZRM*BVoJiJv9Uq?d_a0os?z)46Fp^d@~E z9?FMKYO5aK-^t1|;ILF#?!0hbH_qK%fEYVlf3cMn!U6? zq@~^OrEMe4Z@=glp*_LD#B1VA3ArX@lBXHP_mFYr}Hbcu=c^ZCKc(~jw{J5W2^MZWH;DyBv=y8qcv+RGO7vh%$4Yhwq ztmg5G%e-ok(Ie1$bLHt^!B)&bQWbui27U){d&hUjGktrWm7UA%eRJM7H(r;UuGmJ5kvlA3 z#?G{NoKA4t@1`}LnFwMxJUgxZgZ=Qo3H}%t9V+YHzCur!S3qB}&ui!A3xTKgxL~Od)qn9~gD;WWhZBvB zufctrlKW};uLqC22IlqAb2xbW~;3d)aLiFZ|9;NMtf#=qx{L54z4A7=JX;xKf-8@gxayX7$XzJHi}-#Sdb)rZNqVx8DxS7Zpe53-Q3XbiN?2mUv5XCo=i&aC~75 z>#vW&7kSVybKDL+Og{z=lP~u$`S#X-7~UbypJ(#fKMs>`k9SU8^7B=`i!ZvV*XN6u zy|n#lX}|W;-b+i{?4`X;TDrVYJBwBlm(ta>OjzQ_zE4 z`SOfAAF&qOlx;R@ouYZk9LJt2b5Pbp&VEB5RbhWXk8Qc1wUBhIs+=h(3f%!^jqI6Hj&2`;tm2ZumuL>KCDQswD z&865tG3Kg02f4crJ>Bk?*mc+QcCL~R-i9q*G!<^$wV~#Fpie2ZSe-gEAzz@L{*RrN z*nCcW&bNsv`ekB@-i&U!FxPag{zi1)f^P)&-I~@vS9>&Gn?_@QKV{<73tr30b#;j8 zb`Hz3b6B(#?=xWH_iuHJ81s^=1GzT15a}lnSNJ@`Iz7vkr5iHzk4onJFfe1Z9ivZq zEXQ4&ZGi^$;j350{?KAHMt$?$Sdheetr_v5i7Q9Uje=`{c75D7ahA8dl722?{BNP{ew%!L!Kbz>08Fj7haE-Uf;3uf zU>)njO~*TvUj2RZY4#y{K_^Qu=;qVwYUmZoOC|Lbv~~(#$`vW0K4}*jSg+ zmxs_>)&v7v9oa^Z1=VAnu6o9O2lkf*hI`S`ONN=Otq%l)5AT?=?w;q&u+E3j^B%;0 zx7uXe*kBHPvLMTJt&Fo5h|G_j=(GxcfhounpDe}R?aphiOpxtHcC-k#oDGa)#TsoR zR)_rb+L3jWNsEDpU>L?tJMx72q(N~wBu^r~j>}q1_$@~^^`tePl?ZZnrjGaszTEy2 z-zCd$1+LFK`qh39>s>2{W%F150PEfgY_E?iE-iS|n?D5aKV0PyQ&a?Uh z{1elDiPsl%57U-7ec|g(U#AWJyXH~BkiSSefBlGdf0(}t8dBs-=gkA;`wMA4&-n7@ zqv%n<+7J0@&&>PdX_ZF{e>|OMhPmSjdQ|sAkB6W~`glUWw&N+C9>;$KJwBa5k90bG z@vw9l)}S*X>2!FSeA-9)f4lvQK1Tb0N1n{Fna&TL@xJ_!-u^Kkv;C4U>Fp0N7Bmi` z=v_hN6EfqDh=U(AI+gV1CdNR3J#Oh~hvNlwo<6cQofpto4m&nZ=rcA74m&n(^=Kg( zr7@s=Nq>FmupXC9G`(MEsQo?Tt(Ui~&sCZ{-Ug3-c)Sd2NZ(7d@~-FpiCpW?BD+b7 zvxY_AGR^hKiU>3z&SS$U;OT$6F^{k3w<2I3mwZn5ONpVU*75AT30pXMg5BL4tNGu= z6X$;nn}3RLndM|xP@2xHrl5!32hmO!zbBg2Z}Kx~WXvg#&iQaIXdZgB-5UtlGnuld zm)W_c0~qgN*K=cj4QqLW|CF=-?z@03y%rzbwIRv{d8*CiM1`4R^Dkg8Ak1FCZz&@` zgWaJZ=a6+zBQ_0ZO5$bG{c?iumt8S>mcH$}wYwKTA2;QH-mBwo$_Te~nhW20($&UC>F3OE zE4**beA9fZd#?4{>x1O>-C~<>Sj*S#Z$ZnoUb%ZSV1C8Rx6sR1?d3~&@O@jj{k8j( z+}D6^4R4NrpEZ>9#pyZtaG-lEnBhF7KCE!cEWIL)<>=hbyA@{DJvYN^jalq*u@@K% z=1z%)22bhXl~h^cTlyZ_XVZuUKVIiJT{~QP;(ER%gZri!Y=-GNt>!1@wP$Pj6boE#gKmZ#CpQ%N4|TayFmQ1Hr}3%l7%0(Zd@{=)t9k%=y&uMHf5@Kc+s8Qf<96%pg3cwd=Gkc84;^1CzcJ!%#GJqZ@rJv{g>8&|#6Lmj zcs_f$TQ-#!-O6}EZv9|@dHnagzPs&n58k}(7jHFe`)o_|yPrGdk$129=TF|9^qrU9 z{oy~izI)YAUVfK*qUJpQl^ySX?)(3E_bTozlYh7HONYNn@Y&C^@O9n_KU39{(%v&N zpa?y*PVdNqA~U>GXY8~uSY$?bUYWmkl+IYEehqF1xO4qjXMgyEZeke^YiWe0*iVV! zV9s*RH&3bFSa5j5UixcvZnFFw_6UgWG5%cj8U9aK)l4qqyl>)-&zN`QBddH*Zl2Q6 zJ=B!{fwo>nTd$y#u6JI|`E#*94+IIWGN%(K#O zTzZY}jIv&BqK`zgDE$+qU!wGd)_s+fKO5W?`!3btEK@x080#qUmP2|Zc6Q>CL-1Bl z9Yt;(!_Bk5rp(#shUtBI2{?yYPpCZp&DQ>HWnkkuiQjoR52URI*cu<1XE1ip{hhTX zh}V_p`_$co3%;=5OaGrbC-H6myZo-ZKx`bnw`DI8-@m^hkl4Ed8$NWEJ>~DGXI*Os z?bY5xCOkHm=T@F^txY%O^4!Yvw+(@Fcl|hU?pqHB&i#V;<%90WMT0OjxR^Hj zb)>@=?Cu)VdNKJM4|Q);8;)bW-9y_I70tU&nttuyPoF_M&%4&Y>mwcwkA0cGQ@i~~ zwx&~Qr`C;YY@9jnoXVPbuPZ;;W9@L`J?ttp2Xi?SsJ#&3w5X!!K<(zDr)q-*owBiH z;`jba$x3+tfAAZ`&)f|D+E^0~UjF%SK|kox(czrizSB9ktRq#Z3s&m6* zD|jM2)yJA=@y9q-^{JjVcvfxPRp=b-m9g%6Q|XemqFpz8hJO2Y&waFcM%Y}A>>sav z9c1D7_CvSNkqm5`Yr59qTcUlYU~Oo$cv9zqcF%p~p=+R%_Jd6AO?OFl{`*bvqt1d{ zYPz~ecRqz5g5tqHhWv#71G%5laA#ubNyB&?k(VMKoOtfjKMCTSAFC#VM;HjWH9bZMt`FM=0^ul-z5NgHJ_&$?7)FPV71<=h_*L;=Tu#>CDvj zb|1_|6S-qynYe99to6>H9QqO5%O`aVJNYThPG`9m8X6kDsSH!D(~Q|NE304l0j3h zzTOfHZIwK(T69v`f<-5mJ!f(|qwsfXF6W9kXCnWU6nz(`&r=VZR>cD=3XQ4x2e$Iv zp)uoi_HRirJCFY1JOpP~;Lr6hEh%f{40I@zKTGj62f)WGxX++A6sk$l|MWqkwmYym z=I(EmV+XG>*ivhcXFejXUlHRZD>Qex&g8tw+>s7n`*`9%Kab!mhQo8n>Dz!E<6O{l z>^rA8ue^@)881=CaOPL>=t91!FQ4N~kk&0vzw*OT>SOi6{*F-jJZMk3jY^Bce~p`` zHYookq=!krFElEzHaMo{WpEI#|G^os2WV?7B$-rTkyTzhwl$iOc$LxR0=gd22ZtCQ$Ch}V`gm;}Z6B%IamjCs+)m+k&o(zqlBlRb~A?~Kto-Mfij$QW~wNtOIQ_|nR<2do@*+pabW?>E7F z2RIJ}=SFmv1EKu!YUgdl&3}P%z_PM3$e0%ni@?E8JILN(ur{CbPzC5e)0^Aip8=Hd zWrKcq&wbp=2YXgCZ_qf&2FZk7#HZ8vPjRM1<6nLI2r;zXv!8*MHsV^v8NXIet_miK zIb$OE5?_eVdU&Z8+)~GzjqR%{%ICwk--Y)a`mPd~(~{xNt>|%W z7GCgjVB&K%rscj+upyhi5zJNOUlJ^A7%_lYKIm+UW3IX7%_WzO+h=he-I9Z>$^}>Q zBo+nDLE7CanIQR46w2w0p&JE5___oOw{8hK_=a=VcZ``3T(q*xELvDrIcCI!=$OG1 z0%LL~w86{CgS~Umj>4Q~!F`-|v^`vLZkFbw4Hf4Ke*2Fr&JAlG^5&!+g)^H?Zt2)+ zo~VAAlaMQRP7)q%!k;rsDdUEG2V?4{! z^wZ!G!*;}2ZrA{SYAg(dF*BaGk1J#eW+q(X!IbR zS%Y>D0ZaKE<&U46m`eWCPb8j0>PvOXxAF1u3OU4C>(N;-pO^p%y>hc4O zqfERtcKo_DmR0`yss}zb)Kfwo{`?*zUGx-PMbk`r_Mv4Sv>aegmHkaHmwC9OH;#`q zPE8C1t{pdg`zGI1*MDb>-|$%0b@(*8b31-fj8%>0k=RE5G?M)^Zyr6H|7Q<38?WMb zG;5lr{O*B=xnsNQ_s5xyPxAXDy83Q@??N_S&+qlovuw4fy7_z`XkU8 zN3L%gFMEecbb{MvYwsSebC%f%U|@r zyZiAN@GF6TeH#2q5B_W9VGY^k0Jjpj5%&ImYhl`T+P1B{zYk1}^=+1xZu+lCzaH2r zV7CE#cN*+A5B4*Ht1X17?_ZhG8<9V>y}*hV;y&wA4B&q{PZ_2&)biLoDH>0RW~Tl}YZkb?bn z5B3MZ{+fmDreE#Bc7PoP_S`hsQ4hAphvUJHda$puut!$fYJqPbX);(y6jq;WgEk@KId?KHN1 zyG3e14tweGZN~yncWK!6`2>YKM8-3xIm%K#m%UE#oMkf+qV&UqKnpn`=JZra9~?{$Iy; z!(496XAi=Nx|5^ODQWnO8^Ejt zrp^-z=AVI=dA88P!(TPjgkIXc&You&UTG3Kn=6@Ub)6FE#okNNz(6x&sH><6|Dx|^ zS(+7GSPk$tNxg+BB&^b-HxKwF7V&{@fMDOfXyLl4ENfZ&PM#)Izr)=1;jvEVz>)?lzHbEcr?ykQ>(Z)?D1d-|LIVJ zvnYJP&O^)>^0f})Gt0WRd>Zq6T(+JZr@Zl4{4j}AuCx?=vi?}o29ZW=a-}&+8${Yr z(uhZ{v_|S$Ka{lLq_HQWG^4cPq>UntxZ_HT(T9zr@bM(p_-6R4?IhL)@XGu}kuuGj zJv_Q%db7`;Z6$$(`cU6H;W3rb`OPGBX06@zFg(`8nppf*Lw}*$jQ=5N8c*uyI>qK* z6t;IRiB_Ut8{ai{Wj9hjbOObz-gbNj&pbwbKF{o)+uC#YjCe#kl=KA25?{x9jPk@G zN`!}1!Rk^IGm=_;p{Ljxd=oF@T zL%m7d$DAkMK?Bdld5@7VOukr_({(@ou(inl{l(lN#a?!p`950aJnMv=gIcEq&N0mU z=3wJ^=5%zQ#?$yk|GA61W7L)^WYEH)(dIX}hw<<9$D7OxyOD3{>CkcB0xQF^TI7Fp zD*OU{=FGgFBytI9r2dN05H!tSpWm_v73nG(Za4Bg!F%ZjY#0C8d>2d3XO z%@lNMj~zMkj`m!_1?%ql0KQy~eI{be!|jairY!ULNMuq0ZIG@MLw8DEbN0U4U}2}j zINQ$H(7k7>d*Nzl-_7UXvhejjmJK~gJTYCNa?zK-s zJI&M5^&-flY-pzS#s@2AG(YiW)4Y*!CfZ5=^T(y|j@+^4o{4XN>ow7O4}8GAGcEYF zHH>6#Kz0`HL8sQ2>JYY87eC}>3oTumya=BH=wKh9zK^0-iI70 zOqwAh>6aIn2VRH`$oo||JC8dy^Q0>rgM6L2=<2eC+$$O5{>Uw3a_3esk5oF@d1326 z9?aVwI%Ztm_Z)i;ASD@yED1xaCB@v`fE8f^NqP4U#DbO*=q22Qm(oRNpNG@Ww$vj_HAdX|x>t9-i}D&*KcGM1 z&uxF8ubC5H@#n-9UizyU>DQ62eJ%CRZstXIj^s>AesA9lrf--p;2AT11H6+3t)8H- zB=a<<*CM|zWN#;GOhYp?JO6@MS*}Mn_A(MDLbDT~*)(XDLeA}^zjip#4Z65}8tSZP z{dwM^MP()QX#~1GK%SY4Vr7lc&7cEReqZx(4*fb{+%yyFY}ERz$nDcg`cvy!hn`!>CJE$kPsBx}!1UaN%{e#80Mqroe#IA)o6Rk(Pq;n&9t`*IInqSg5q zEG-kCWzx&Qi-*JO7}}qSS4A4V;AKmzN^cA#ku5%6;uFzK{FNRzzArC_I@{4-)E}xx zec}LrLzuXso(`tIP`{`@6zi*Oa zKFq6tDcDEC*}`WI$%Nk@&YQSb$A>@N!+8xjS24ya;d70%^flYl9uChi)-=WrUDtPv zt@qORWu)Inx-Sd$yL-hin@dk|$D4FxUk3WTQH*>$f$=CGu>t7FGtrO3C#xS8l<9uu zZt2L#nbpX~)v=tsI5IC_vN<=CohLaazF!ZF^C&-)v3LRHPGTHN=WS#xzQEYJpYfP< zOkP$vD{r;Q&8sy7Ixl2y;_kMxM*4gM{T;D#^($pz@`dOl@XKqjcKcX!?DpeBX+Rs+%?|wz>AYV5X;Ux30y2(cu%-oa6u(J{*@kF9t4+0@W_eena zNXb|W_ow{dqw$tjUb?tnzP~Z;^LGR7l5N5Ne+&N)H=g>V-v?g)gV1sJ+y|NqSYvPZ z*4x8adzYZ2Y0l6bV)^;Afo5Wux@+x3R&&mM@VU3v-f42SiZ6=KHS@MCsxEt;zRrcu zuO2gEZaq(Fpfs<-l;mlST|Je(a6N-pkE&YF-NG+sEjG+GC&T~q7iBF@a<@}6a%z4f z@7x(R|M{%N0r+j#^z1}EG;7QIZ1el8vN@+Bnh)=cpN3BR7&bkvrOspw(HHW~um8Sj zj-81e=wZ{f{V}w{pGq$`caECnzcB>KIyLMtoNB)Q-#TMyKA$XWAJV)7$<%=_Dt-P zl0jAIV=462h%sC5Q6GGowG`j=A6;uQO{SBo|mWG!wY&S|)mbC}4L zZg}r%+P(?7A{r-=>yoP_&_2i$GvU0biR2mR9^o;A>qf;MG|SW$cfRoIxGZ;Z8+GiO z9!lJzy=CHxch?T=ZO0PYv81;hjeFg8EE3K&w1e+zN9uiiT1opY{5k(X)?(J1^XAXU zT^wPq*tI2?_@iJG^Srw@uNQVTu<;e~X_VaK!oFOvxjV0o?}BYepH146f?Wnp&@<*w zh5p!_cTLYqbbTNmxf~wJ>fsT^`R%yN<&k(vUmkHv;E@J+bU0bpe_t-Yfr47B~GezHbY;fBUqp#B25FSPw?xhVIXu~?M4fncjND_Os zjdE(kE7V&|y+*MDkr~=!*@fTmUy%nXV()j?9@E>NxwL0)Z+qhHZhM|nduGudzFYdY zb#Hu{v=cJgv+K?7c>~p+={bon+xC0`Uh3_W6g=GVn%5q5$v*9oU*}fZ^BV2>o!6eN zZhM@+(jLmGJ@--X0JQ;ssEchKmqN2%ehnkP@&9h6fYtEl7m?2oszKAg|}!(sGT&0`lX!4`|`Y`>lJP?G11ip#iftSbsWeqKlR zG4g)K&-=TyytL;x>3P9Vc_;XJYt!-cR{? zf0~x}VW&%RRDHOO&`WuT`gzx-<%OTF2ChFRyw8}?7?Vxvtn_r|3C$}?zYf?v`QcCT zv(m3f&rcty&y@b7^mO`P{G#;Q^mJs5WRlW%0KYBtEBrSM@ssEa@YP;Q+p6b#)99bO zZCYABXz-lULND~@gN8q~X=!C^vA5W=Y5C~G+e!Nz^5C;PZRo<1|MDXpyq~eb`+j)F z>a%knY0kInd(MqzF^8d}$iIL)7nn~N4rD2roj?8uwl+>tl589nCN)O_b) zTYli#)a~Zr^XgA46Gm8{4PPeQ1m5^IyZePVxN>lr(q8+ zk9<4qPvJkoSFGg->(9T#uWI|;ect{gc18JB$p&%-dE3t6KQwGZ77{NR8Vze1@=f$v zo6a66<(V_K$)+qEh2Nie_i;D|-`X(z8G%pJc~s-vSi9F}60ZX9GQre%sSYL1>w+He z%yj#k-*PH=v_n&UZ?iNFZVhs#M|*C?(C9s2>6`W-#S?lIk40(zp4N!CcQ;X^Vt6su zicHslz3!e_z&MJl*u}m;S0w(WeF69!Ahyv^Ao2dX2j1-(O^mGW zH{R_k2`IKa_QqZBiY67jUkWbLM>U?OF>bG=Pud1V%OfT*1UuN!Y5UCL7g@iw6>qu+ zz54H(=d@p|vQ9?X+Zg9KKOQPk)+QY%W3t6!EKNuhI?5oAtQ?K&Mtmj>ANXLDe z30{MIofrAw_{pM2*J$>uus`9y&^m3kX%-D42LjCo-}+YQAX%k+iq%42b!}pwQfc+* z`910EJ1RX;2!Eqv*XIPA``Fxy=p%36Y+BZ$cbiyGM-LqTg!U-Z#sL{^yq526w6C3Z zYR_sCZPYz7k1!^ykX4V5GOsQ`pRWe*I^@=K!9XYXAk16O*r_nX8t|v=ba=1IBDO9x z*rfjW2%2nS9+NE8KEw}z+YaAJ-rR@YCfYprx=WkK4+WaT&_;c`_!FX!`ruF+jdW(Y zDHzy#jED2@;NQ%CjQr#H$qCZKwC$&ht?lH|An)3f|2EGpJm2B@F3EqsTdOz+#D2~kt(oG%uW-(R*rH>Oy9B=2XzmYl z2P?c3k55%!Rqe2Sgszj1uc>gJ_Byf)8&E#6-_0cTHRoxDsLUjMLTnl8SjQe;h`qH+ za8h2$J=NcX;|JXnb%t8sD*ukWME>b}CF8{AAMF0uyL)bY^F!N?HwD69_01=aN-p-; ze&O%yo+$fLU?O)WpAlt@1Zp~IydCm5pdVjRx>}Lt-)G=o(~=KN>8r+xw(dn2sT_)YLFbyr+NXlKn>ng=A3o~RYdM44Ld>JZ zS7S3Q3UgN?`c^%%;JSL9xz@Qk`JTJ-APMbbqwoC$~53+J#72#wIWT=d_vmkT$+svJf96Xw<3b6r?!+n;TJc=7fI zF^7SV#=go|Lu=WTW5VmN%s=p5dw2KS70%iCi7*esYil(2FX1k&)0nT}tw-=#v1>te zW>BRli;o59!&8`{aEhcsShMpBO9u}@u|5LJa!BKC%JsmKJJJ~Of$o3W^+DC zc)K=FH$I)@uliqUf>pwpm2A^kd0Rdv#PbXmI9-}27O)VSg z@sdBTqMj^fF1PYM#5~dmHvVru?8ExM;ZGMrhFEz?-NI)Eb(d22bm}gq?h5KIrtW%U z9*_9-!9UWIHfP0$imzqE4^gI=GLj|2H$a&t;t~WXBb>tY#nIp?dim{1p9AQ}9+~gT z`=FKgo;)4j)V&USdcdALv~vhNnqFRbqdR^G@1WP#Ab78*t?78RC-eP*CrrpoK9kK4A` zv6Q2XWOos=`!?3flHJJdIm3~G(&2Pp*DB@{je{e}wPMDRFV~X9D-hrNWhVQ2C-9V3 zKQuZ{I#vDPV4h^OT+Ju{Tl_=|;yKjJ<_@*P%{%x)+L$TMTjw8C zUEunWHd?h{4pO0i$>u(HH_Q?BTb}mi9t4%%l>-;G5u*a{0 zTmKPr^U=bqWG#jt=HeSTTfKK^-6+WiU#24C`pkt#3p*Xwl>a5HHAD09Y3ao+bH2cC zxN#ow*hU~H)*O3&7eQap_e?>P9pf$?r!%&hm%6_25o25Qm*0hGU*^%in^+2A?3?jm zymbwJ7=KzGyKw^NV+FssHg~S_ONR6(KQ74vi-1!_H zuy<-&dj)b$IBWgC1o?Iv>tD`5MN5g9znw~OKpZ?iC>siSu(MEUi z^hck1)2sja`e^${%$-e?aq)B4wbDngL(a+fe*N;L`|!iFc30#ddp>64KiTtLHh6m4DFf^P!(Vh=JGUFzm@F7xs+4=DDQ&G+w| zJv`6-PCge7cjgXcPO#s9-V4W>Cf zEN4ctZl#>stg&K_Gef3(`cLS_^Y4NO%L|CV5@wB#P43k&YxG8M%&5<0*D=H0y3^%h zrrwoVFR|||zE#w#avzspQ}|p6*QLeT$fx+WVUmgT=_Blks{L!1U(en(dz-BN`hywG z;N@h-y3gMqsif~K^W1({|F>b|jC^&>T=5D2C#JAlMvTdG`-{00x`m9j)AiAZKW=?$ zm*S-0H(K)(&KC)86*wFXeK;rN(iI$!rd&+6Vd|@Hq0J9QTZ7QBa&RE8zcvMeePv+$ zF!I34bk;k)GU0_@JCv`N*!9p0c0Ck8=HVFAuMGI(5x#9X!Z-G2`-M6G2;XKM;oF2G zd>hL*mnV*_>tv1zXPnyy6-POS8&7o0slR=_2RYY=2Q%vmm%3%@q50A9N$Lc*+)`wg z${meOD*Q3*dA&NAD_c_D*gTvqIA-OhY2C^J|TS9*E{7$>YvE_eerC3uNP0BuEpTu<0~2m@RyTq z;BTxU>zJo}z47b#GW+_?DXsYN@?CmO>}hmt<~QYoSLZAw-*3Hd#mAaS8aMG>-IFQ` z;;kA#rp6sRshz|!(AXi}rZILdR+`3+pT^jEWCuO~8ap;EQg-GMHGPW{j6d9axqV?`EtL+ z(+!I==H;WB?~rZnp(D=)M+;AKrx@IV=&hML!_mSD;^%ZEId-)0DzKq_lJGWT!~P`U z75`t3-zV9(Rd>!f;v99feOvXzPZ-`kpDetkb1IgJen--8kG9R}{gJsoK3Z5yKlgt( ze(7!f-^!IE!HT?=p&M;;b)&g{$zI~iE+tKz@aq$0MdA%9m7}55VnwyG0 zVfk7wf8tLNzjp4M{v_d5e8Tvx|AgTkY1|wwAAiz)@k!$L{|8uAb6lSsjaAOQEly(F zm|tKPH(`6OU_BtaW2SCd*V0!unwDPKC|y?Th7#7z(y8UM?E8obR;J93JkUxuR-w!dE>-t}6T~ZCK7&hV9-;HAXzKxIVD?3eD;sx&crp(*h`TsyNH?caNoxtbz zZPpd9R43UdiRUKpJ9{OP3?&APFwNP61I?k_U~_=jg~U5+J)Hky_m=Um?w)I!3*L73 zr0w}Td^B{1a2)!0^>RE%p|K|H`I z(bi40x$Wzw_4i}(3&tkTc|J=6bH}{pZvkuFA+z`={BoYJ^||q8aq#YomjA}9!*9nF z4;Pg+g=W%!VjCB(ncvmMYw=$eEXAHS`1q!3Sz|%h)H$XrxxDqM(WJKnM`!NLUv7Nu zY-1YO!<-mi6np9_&PFB8zR9aS*f&Fmwbb1RztyU3jD=J!_(KQP5yLOcV0)UeVuhvW z_MClFR5rcbXIGr_6n7O6XK{4ROYEbS^IjAhS@RQODaGLt_E(3zey42m`85|2cU&|R z&x8kacB6znJo#X7-meyZ_y_$=|IK+KJ3gn$`kswx35+t6L<`yC9*0-dcfMbl;Bfaw z%}=Oz_guyPa%2B1b}GD`NQUOWez>-#<9sZ8imx#i)6>3(ADG{cuVM%KE#HwBlN{(! zgk7|g{!8+F6m0H=>49^~|HIq6$46CO`~T10lN%&pAR)v+$xMh!Qng+JPAr<830^AR zfM`9o-)1I3sz#{@Xt+owAzs>G4^cc?@Ff8+H94inQ=w&g&Zz@fO11VVSbICangqO3 zTT!ctxBT9pJ+s3kg7)kAp7Y1N_MW|;{an^s&sytQ&systPLf>O69rfD&Nco$-~Tgh zd$6DN@t}*hRM^Y+TlBSqzVuSB=%>h7<(F~(({Db7hAyHng1zR7&e{3>@~tj@H!WYb zeFwDS%@fgl>RkEh^2+U+0~dkE)Nfkwbx>LF{Tk-TNZeoBJ6MZ9*F^FSFABUiSbGWg zskk3QPN1I0p?|A?hT4A!8t~}9G-;c3@tuJ!jC>D0kK>>5S!Fqo;3DEzdmayccGdU%-2EDD*sjPRwNUzlitl|8rx}QT(66d(NNedHlT3 zZmR^|NA8E7$It)lvd3df0$x3jeYxi7!A0~g7>aEv1aF^)ANf3e+WYR$c(0hGPy2o| z?4faCfY*J%cvJS_x6l0I}enatS{hXVq z?a+p`q5@f_t-YX`jnldev z>A^=SdU7J3Bzp3ve-pcOdt}Gn`ocwbszPH}#G^)$l^(_>C5Fl-OZn^CYXA*gsZ` zzRt6epU5_?g;w0$|E_Oh`PAI%vJ>vBDO<8KZBm$aDx#TXeObGT*aQFQR?fbOXFXZu zcYGg)ION6Lmo}-6dPBLZi%Mo0cq4r#=aBz=;%KMQ9=uJqLg`wfac^%~`yHZ#i||DV z-^hNe;%=Vuw-+o)^i#eE1x;3rSfWL5AlC|3a?c#UQ}BMb?|^x>b$z(V8WyW#GiFcksnI<#kh9Qv!qDWM z)Nk;?0C$g7=fuzAy4H?Yf9Uf&G3UN>KC1t*`N+;e?**=wvwCJEYiChljXg@}Y(PJ5mmU#5*K+a1=3Q-dniET7 z-PLe1^ChQrL*xBG4W!g@qEAcUv67(4gX)? z_sPCT-W^dUIlc(v^~R!pMCezv+;N|Y{sNte_(ymA#A#~$sW9>4BzwR`ls?}}pH=3} zWWOJ!-&;~>z~i@eW@7y&KKO2G3>|*%VPGx4_Xc{EJYLeyDr_%iNvZ?SS^-E>_oR_57lJEoOqbHcFTgWY?buYP~%OyLI8*{H< z9kzNjIxFLXZ;qRfjM^v}MPJ*-I?KEK1}g_2NU_ z@82S>bp~>cIrT1e$I(%oPpRuj^@vs^o77Ku{4o20==E~u(i6$PMe*^Mf0E!(42~{( z75}X>6ZgO3{_K>pT8~-eX81R*)xb!wk~|$5KWD+es*Twe_Z^P;EGcE&z(=$ihG&c4 zMUh`&>2Ab(s;t2uUjLh)GVU1&dR7cSRehd}jKHS@(-J(396-wbGW5O5>gS`pa^<&@ z<3fDKv+aDGS>0b8H8HQ=k>%~FM<}0feWH9aK9Jl{tKtuRi(X?cZUToscdieQk%{tr=_<~g zB!)+MP|PgTF*&R@(Y^hWDS5NEovYl=6WU!K3x0l(eDC_R;%{5bm^`0W!QgN_s#R{6 zDkeS=GgOz%K_EHW2H%(}o|Bcx1@Z6<>_Frvc^NvJPk(mD)8Vc75ieV__l}(C-d6_y zac{gSvVAJ>H!IUN6hCPWNsp86xF1_oT5jn5XW%gpHU*jj*aoYNb%^zBt>QeN07r*& z5lrY_15956zMV73>jv$aJ&Z4F&-!9=YMN(nU+*Jl<6n60;q!Bi=d_XI8TCIlo-4fZ zoc8yRNBYh?$@~iw7PTr?(>+I0v4hGLaXql)>|Ok@C%8V`PtZo{e=mOaR^U|iq*=5E zT&SLHV|Nt2#j|^uix1k??4|IgR9JfSq5J`g@wcE4SKs=S{1kW3<;lDV%@|mm->bj&gIhJ#{&gZ8# z)c17yZqfHN`fky8+i$u3x9Gn`|HIL{W)=rogRrLcXupLytu@Fjmk*FLo%weh^G~+d zFnqKXo?QnWT!_zY931u{VWc-8TA&H_EyQzu>%qpR4}wh|eGqJ{ z6uf${P<^WBZtC#xr#kXXVjRMuSJsmi)=YFPtwG2!@k`bORqQ*&!Q(aj0)=J{x%3v@ z!F>cBUUNwLnshPoI?2vdT`YAxeVOJ*8c+SswEi&TiO{EJU|hqvM9bc|e93XyM;cdB z=DF(@)>m4$#L+=4baTl=(P@e1D(kNZ{n9h}=SJw?RF@u7_CR>&?SW{1YApB!CUPk; zmeg^$GCWx(PQ7-Lx2Klz#tNPPNMjVdHAan9!v*%T=Jjcn;;qe7(0$7#S9d-d22bG-{Ub(Z z3Gp(1{54fxc}+O$YAtYG+Yrv{2s!B;ZxCanzB})GW%3V~iRMx!t>XY?G%n)r+V z`)sHlKlQMV`J?KgOthc)INqzhp)&C?l<{@!rHpJN4T2Hx?WW=SPWWUq@Br@<^7AnM z@-9r!)X{J#9`B&ri%;Ikb!kRk_BMQXqaV{B^tBc{gzaELBa6OT?Zt$^^=kUCd2?$~ zo4dy1JQHxy04=uKb}Y2Abc6U?^kXw{5BP|J3$Y5Xjmtt$GYY*|2jpE79WoFi^EUgyR*nK{kq zC(uI2t!dG{s?XJ5ay z8%QrkLyuhseu{yyVQ*mRO;hG=BNvElUI*wCb-I4G8c!5ByZyyBDY#C}GG!s)>Ibd? z7p`_=1h@*v^X<|N_fyB+SC?#mA`KlMT|l;^2eY_GALxM>In>#i!+&59;eS~Fb4^Te zWF>S~Cv|pG_fym}@>wT)N8)YhiR$B8!OuqaJq+ITEHF8KmYzQZ4)lKk^q?{iQm_8k zPm7;bs&y8yngu1`_qu+R`gEZeRpPB{Fr_-D|(i1EwMFDe!t_~J=2NaGc0$U?~j*oaiSVLAKaCjop#K zc(VDO$ZuNHBip|d*u8#K)2mI>ZYjDLb{OqcqV+OGFZ{nOdN(q*;pKDj@U%V6UD*zAa> z(|T?Ye8`@pJ@NOkNoilc<%=e^j%z3K8Tt2^;TMRX*(u6c%C2^0P=2@iBRUrE7tim!+_*WhU3i&EF1(t6t6&lkTxqkl3R!PTI|4sAZy=Bx zUEjjGyZ+lK1AB_Zp*I-^x);K7vn;Mot&G}bcM3VSly69?}BIbyBRw8JNB`&EBw!|UuT={s^Y}@=|pg=`!VQ{pJvF(fbQi%$(nkHsifLk!9#vvTrRZG0B{! zPrCS2y@j-89rNjJ8TN_QmdQ-C^-KzE6Z0#vA10XojWuh*`3`n9<(ek$A9(jM24Fwn zV;|KUhi6}<4>9J*^cU<2+3b_wC0yK7@|*RF=g#*{AKhyg%w9(hUg6xGl&MXqJ7Oqs~91MLQTQAsWKyQXk|0J^Mh^7lWV_#W{`?1Q?V0GPec7liA%-m6|{|E4k--jyO4S0Osb}Bz$9tn@@Z09b^H)#le&B=LG z58iY?avrVtjCs^aPL%&w^T@MtkDN#9mp6~zV;;Si#M{l_O);-8+Q%LYOIHDw+H3J} zDceTD^I;avHXs zb#D(=L>7|cG8wZ!m1o*F5#1CqhpUe=hrMw+$vNyK=kO2t_C4RE@?Uaw{etMX&W%sZ zXXPhlJwUyA{ffJAx?}^Y&+v7rfAeWu*FN}oFF8I9|Dy%k!)N@^cr&nyh|d`_5P=WE z?}ls~iTV@q@1msw>i-z}(K!GYQ;+t+-LqoYf2&IB6v#1mAFcwqD86#Do!%ju8~_&Y z6HD1g-T~R;FUya{wuelIvtsFXNAWProBDe=D^fb_&ao4aPrw#hpNU-hhZWPet1abu zk)2ZeeDbYPU2$yWvULkC!f)b?*@O%XKLURywrT5JcsONSph?yJ4*l@zFQxu4bxY2* zET6tz`$f;-s}t#FU!8ATmM`7ji>+UKWn=XGhlii!b)lbRk^t(*HVDuBWe>ZDRyZ!U}_ECpfr+%q_>YK*-C(%OcH`sYo z;q~SbzWFWRsLqqftuOe7mk0a5pL{lL=vhU7EctBe(6cl8|10@yO3E|Yc~#%BL(eMu zf59`49uxLZLqaZ~?KkpX>=S63dei)KfV1zSyg*}C$bMUn~YN}fcXTitc=+FyaI zxyXYn;r-H^^z0;bVJoR4NyidwH=t*Umq5?YX?ziEKrX%p6MB_bexyznr<_-}%Bz0) zmTrT$Yh0{#UAepzp4Ch~gFESu#wcFDgE(5vE9t-%c|q(+)v*Tp;Afv_v-XaG54uE! z!RCz3DCTEgd3+;ruKX{CWWZ$6!4Y`$)TB-)T{xQQbP4{_t%dtZd=vSMZ^FrM9^;$8 zp>s<&i`=IDN4p$YjSFO%@sZn1O!GDIJg@si_^e>@9iAoVVaK$ zM;Q9v55Ep%okyPDW4mu>U+SgRc1K`ONjqon#0D-w1^@&9FZ}KA)LqckQ^PsG=>5^f z__lIB^z&29)&k(GJQ{=T*a+I4*m^tuhb!~qf9R{x`k*K~kXh7TJQLegy!!oK{B&E6 z|HJxT)&jk{>Uuw{zz?&9Z}l#KtS*V~s|>_zVrR=HN4Xx>s4pNx*3EWeH-%=ndQk+u z=zH4hhF=F*cWh>T5%BL^f2KLSz6ho0vr%-$n!!u=eXTCBzDT2gZRow|yp>nJ*t9Ro zzA}A&E{cBL36F11&I5fXzST-u&4tu*e%2TC&!wvd=t?vf*S;*ze9+;1eoLpJ^YJ{4 zz7VAj=xac2RHf)e>zF&_iyglnxxJ2cqSlnncELgayZECre(6Q3Q)`Pf+EIO8J886W zJHLBqNBB0$c1*Gz>9ggCY4 zOBW^JyLUG9!#GQrGcCa0Lg#4#H}Io@ko*>z2O4|J?Zf9}%kAuE!8f9-6MSQs9tpom z@Q>fP{6loMf3b;W(4OeN6&UYlURdOK5j|?2*P}Oxp0z)3L(@)Eq+c}cGzI#5D6=1U z(YNucYbL%7!qfhCWGHfTKlAmb(A4%wK|HAU6}%TdTd?J6u6c7}$$`Ob(i>Zo?YRBo zz4TR`cQ1Xl6@7Ij->dFE%I;^Krt@YJuq0`KNDWmnBYa?)A;*W z*zlqceRf9_UUYzQR>O;4+K>JSe7=c{4(vI;T{QVO=D)@^0o^W)&K=J;BC0!q-M)%}=m*HP#IABs&ZIJsDjuzNB{7jWy$^=Ebl42cK_t)fW?b zPA_BG1^jg0wd@1lx>{{l9cWsDYX5BIOXLnn9YZhw)!(IW z4{p<$VftQhR+&`Z{9DQi)^FhJ@8QLg{z&ZYzX-q*YG+$yh5k>@|)xyoDM>mO8yTZTO# zbhirl#LKLo_7kg6lPvchb!i?ZLj0um3>!Ovw3= z&({?JpAP(t{kw`Ny3;@HOLue77iwOhA6}1bM)mJpzHK|U9PF1%`<-mNz3mvgeJc8& zeT5Tidx+SeX}>M1M_=$=VPapy)*CXDE|_N~HFh!&mW+>IskxT#%b&gRWMnYUT96T< z@dL>4R2n}3-*1JctG`H}u#48fmv*3!MKs5n>RtZlZz}00N#=C*S9x6&bCaW(8T7dp z^tq7aB{Um?XL~fOF?PaFMYGPQ^5=wp*W)X~?wMa6@#S4`7I02&>j&=*)+z=qMBiH6 z`B(Ib_5CS)BmFGo%80{wu0}?@$n$FVc~SSz!1ZSSd;8t?u}6q!dmsA`d+@!AQHvhm z0nZ;mCmJx(JJ?tFHox!iYajCYP0&NqzqUtfcr&mAJZpWj8kncTJB)9f*7zGk8U4|E zd=l`VGx(20;RQqc72yBvdD~exCwz(usB{0MF=dY7ThL)+rn`3fG3Y{%Q~yR^USlJ+s~+|iPWK^0p=sH#?~sh=zj&1RkgfBx_}|C- zD*Sv~;Y$zw1-``lN2q7l0w;F5F|%(?a|U)B-|W8Aoq-prNAX+x*4|xofV{_n3pJl7 zbay87l9(}gmiX`=E4r|Z``IgP&T+mmr_3P_YNy*b(+K~mec1J-ozPuM`!+D^rS6Am zXFqa8b-lR2#MF26q;aRKzIyhw$>HOT<(K$#bYASlwx8@sXLIv}%jdtB?+cD0)~Fa> z-gI-nVvqK%%A0iM;xEj5VU;xr8Qu64^J9hl$bkEP#=xG|+?QAfEVk3Kp-J|jC*dE& z9`osD9r-L9d$B>QE&MJ!3RmL;gCD)@aO&RyXloPis_29K`qc;3+rxOao<=|DgYcm? zHxM(p-#0ngUVi!gKDAerY_F*M7qq9cYEN|vmuj;r>9_x1;Nx}L+Xrm4cJbCtT5Cx@ zB=ny>3H^t0>%HFjfuG)cdlhfbOO#PRz2DpOe&YIzyK9!2)v=rU66;;&MfPvmD^Jjw z?b4ZO@@07DOPQHn`+d1(2hL-i08RV`8bw!ywoLwf=*SprwrJ@2g-%Q~w9bZxz|Tf} zN!Q&KbgyRWe2zho{bJ?efohh)n#i837X2EeSeas)TZiIn;VJ! za^))HRt(#>p?}eK&+0^7tD!m35OQz2;HdBP%>}?Z0<7coy@&Z#2>ygit*1RaE_LzP z1RnE`fX4}+z~f~u9`jv1s&2JaNbF&iDRkp6JUqJn2bb#qRqlMq>)wg(Gc*^@OUwn$ zxBc)lKjpy3IKMHmovjy^$;X%b>|*0$(XaU+9kUSn)ER^U#-s0w>A&JAHKr7UDZUba z&fzxQAzl2JE-fk!MSZ!Mavq$Y|6-po*NNS|pS76HzB0DZmPui|S zUv6=2kgdebs*T%5qtD<2-A22imA(zDt5~~dasTEm`$9Rp*GFkvb%#^Vi1{}jo7*< z(>I$q@OjMre})(Qi@_&|^Gd(K+6w%107s2s?Wkz%AA#M0(=)q5E5~hk37UQxJB9kR ze}jqrbrgKTq_>B1o?YK#x#ya7_p#Oy|CRmW#RZ_jTm-_N%V1NuP=CWiGXwtNUg~uiiY<&o$09;oi;hK-}#>W!|B7+ ztm-n^&L$yyzJB8u=2@p8`^WBb{R);Gv$H6?YVxG(SLIKVO!?t07iItY7AsFan8N<;(i}IQv!c(ryY*&W@Kk8(jW1tR)=Vt;pXs;c z;%3GTJuJGDc#xHxm4XwU%1jqaX8yH77))qjee*`C8Z_?9)kUE_b*ms5Vgmn&bTy~w{sZ=h@G zc`N)Y#2jqaGi+zYmBf`Wzrp(@;=MIywEMl4wqs@qzVQL_pwGfLKJ-xTx2AFpa5cFP zkpumqg(i11*UelX&!YM;>AK8F;@y&p7|qmwULJ^7USk%d`B$ z&&KFkKF?A$o{AOS2;b(UupReFNXWz8L&&12G zn8vdc4?nv|&ramoDTkkJK^ME?6rNQaex@~3O@&iwf_ml?K3rMt1UcImShc}xHk!C0yb~Jw6SVe517p^Q| zuFriiMFuAJqluA#pW|249bkTlmhlbfK9;#4z8u7MRp>i*w&wF0#Fi98_hT4e5p$-F zdyQ)VJ4Io$b2n>AcRqKr-=;aBeL7=~b?JXmt_!qniSz|1;15 zw%k*nh7RB#<3tN9poPnj^wSCpaTO^3BPsj=erAI-b3^ zm<_F&m7^!khNq6sb;eaeBV$U~W14N|9Gfj$(Xriy$Cx>Rm1*6o;Or(@eY zCnxRVseIpaOimeRZ$|%^2W}U2|_A za(}-svrGL=`)+fW-RgAx1wT^qOH>LUZvmrG+^z8Fbc7nUjG1*sr$qBBpMrD7+eV>&*jpus*bILBDj)zqqzJ9)2-!a*@{`|Oh zubyj&6Z#gp#~)sqz2V#m$8S(y|Li-a`z7nx_T7G`<9yzScy>G2-5*|h_igZmHvVVu zzskxvC>h=vt$F{o+cy?%w6YF%o)UWhRrfxV`&sW#v$96N;{MOzzw`b}+!ue@EPBPH zkA4ZgCDY0r{e;Q9wx@s?5noPsCiHnLuv);cHR@dW3b6k%*L40Daczro=DL}2vf;Xw z|L5?0zL~M`)bU?Fc@_T~c>Z5pPaR)za$D|~7hb`Ah-Y)n8T_wU7&2#2_Uw~;eKSv1 zy=}Q?^Z%@q=Z-(~@E?k{^7BZ%CVd?lF|EDjUGk*HXf!rC?aRzc{ z#=_~3tf2*@cyBHdiY{z-NP3LxHj->YkTBk!!N+Ep5N-UQ!X+50{lY!=1+@^ zEu9v*xSFfQH99RY);}$9u}N>4IcTg#ANwxa1DRz{Z14M~6FZLUw=L7&)8NE*TNB&A z=@SpP8y#en)@fhjo#=5V^bv=K_VZ)^F1wHan*V#?2diD4U}x_<(Fxw~zV~HkS$6hn z%Cz$AW8UBI^T9jq?EU=T%>OKF3T1rR4^qbFc_-ifjCWbkVw63bkeQP0qki-A68w&` zH#pYR4F;Ms(3u}P8?;6pjIg%dWsRZFW7>CKbA9j}drbS)jn@ZDxr(;6FWbX47kwXH zBfEiiL(u!9TwihTO*Xcd$_C!)`E5LFfXBD-EX3SuFzQD}wsYpWd_ijq z@xuBi=^M{N>fb1QtCRhUUUOzJ>dKdb#$SXa(xUUwjG`3HH`{tw!PslUNm1n1n;N9Zqh3K^6+mh!WtU%9& zkAD{5zC49*$4BsOc7N`DF@_0(`J6rye+@Kd0!4V65l=v9ghs=bAD99 z*_~re$G?^+Cu~CA&0b#LU&DPl*GKuyvYg7B_>D~`#}(J}(xD&hVhh}>$xi2*Hrcsr zH}vr*#WX?#aUX4(Deb>-X(AI|i5+=m&W27aZNqEuNsk`r*! zJ#!|@%5DEEKk;JUDEeu9Pv34b*`H!<<@U!nM4LUM*ynX=({B9p$o1I@`R^w56wP`4 z4xjIAbxSWtkDn`>NguLkKDLnrZhhT8o_{>i3_O3bS+@=w!cCM}2kzJ5lPSIbB=juz zY#6>7>UY`i(>{~dV4bY9WP{XN%dp0>n2YJ)dJsFL^fjFYqj{wBScb=^{+nyR zv&S5c_t!dHv?sfQd>my<(0*Y3Sk8YYKU?@MgDvH_jvnrfb6iKSZMp`>n^+&V?1;_2 z7=8oVFG;m$H(cz*-mNzsvKuL`QgQ3e(jU?9-L)5W{hqyzD|emH@d0}32mD{*3%cj9 zg^6Qt8I8V~W;MnsZ|CeNa-!CxC}*WBu3Yr%@XXv{P3pmBgDr0EAF$sD{^$N`L6^f0c}@8z4Xdi71A&$xRr zI_n#q`r2xEzSe~DP4swHs(+$j4&pAA4n z0@gF#zIpwUKcU;_c#-@3=ls8-+N{IJs2mwkVbaZGs$cLhThANNxD=yQPe0}pld3+d zKhm>BmtNo1=ULNCtOnbw==n`(Re6`rqV6#JYhJzP!bF|&MN>P8K32GW5r5OOKhow# z?gcabynIB`;T6Az-Z@a!Pdp4`whi%t#K1q98GoyW`&s$e;7(!h1Nz(8H|mg|GJ@fQ z#GCmpiNEE+aw_F2DCbblzJ&F=_UahVQpzqFi*LuA!Fxs1OXA1N`hO{bZ4 z#K*XMIBtAeLE>Gwm6*}iJNbQ=-#^auN7wS}n5o$LX*p({zTcZ>)-^y!hPZlrTuQ9h z@g}DC>T`I!HBh|LbQP~;oGWd9K7MKZ()nfZLsxaoKx&N8^scX}(3^saDtPShLjmeQum>U8!$THFGFZQtiSa zz<2rvAJlSiu}Jf4BQZnO)cv>Qd~P5cR%p2;xZn$`IVS$_3VCr|xby9~ z^z*#j^s<`#jIua=4JYf>nUm`Gt6VppZ!PK}4mxa{N6XeUsZ zpc{?lROr=Df4rO+P7(bDuZq#vetG?egVU`w)cdGxdRF63=-8s|2F8<0`;qaC$R~JAh@N@xvul7{O$Zx}ZTTCAuWS{yaUXj|j^I1m- zCYpnRBus{2lpM1+PL18qS(j>GxQKj1aB|%J3Hgi#DtzN2;Kb{fxBo79R>8|Up^d5& z;cd{XU>gTVHf@MjQt3qf6P^_p=^KOGy3+L@ogVh!4*xTLXdgK#xV9+w3H9hZKk)Ks z$-|kSa`GYXp?#IN1_!sArYYmaGXucIe}~g$&>#KCGuD3x+of0F=g!)!y(G&FXpV$` zNP9m{$OrXpDbIT8j|&HlnP+j|Nc+6bOHZ6najs_a(<3;X1_s!BGNdc4G;1 zs)7Fc$O&uAHy_aWR918(8VW-{8n66CMFWFhGT8AaboV`;h;#PnCnCD~l4MXdv0NrQ z0vLd zJz3@QBl4Z8ZtVlge_T4rJ;?RT%!Gs0&{z~6l1Dqb_HuQ^XOeAcTpIIK#;P_|ua_$z zRVJ>czuKo(-~U~GrfvuN@aj<=seRrLU8rwf|I{}-**EQZ>}3AeAP@7=S6l2%^jhnn zU|`XQ{mg^Zy6WloI?7n?{-$zsWp)^6R7Y)^)#cRMU8()_fe)L!U*K@A>TXElrH}T* z1!mwc^vfi0FxNVteRXJ+b>boUFC_FjYY2wQ*%JkhidVoUe()mZjmFc8KDOAlp4J|b z1I}A0)5DmmOy0pSvQ7~m@&9;Q{W{&`wcpL!!o!!^)6avA2Os#63tQ2LaM{pGY$fz@ z>cxq82|wr3g)d;Qp174(>Q8fN)s2fEMyufx`Q}E)@8oQlYH;Plr&rJHG*em6RkY*L zk>YN=eyPtjZf@7%v?pIAPae4VbJy{fo6Bf3aSexYIQBDfh;R4Wb@o{NB*5Vv=MJrq`>`Ylj^8b`9D>6fZU&UTUOcMo%^#dCHLonME^9$ z3SK4e54!mq@TG!3bB{iIr|#e69-a0i-M_=Vm;1AydoTCrhujm>sr{+~V;|1_nZ~`B z`!maqxw$`qNf`LZhiEAGCw=-4@g>G{{RF`()V1VK=oaP73&n>}Ub65R>R-}_Jmq-+ zpI*t#ll1K6#Is&KL(f#~$CB3*-*=8OTO;Me>45W3;S1>f(2!qr!hgr(+wE%xX)nYgFFTFKe(fXGb(r@C-8zo+eI!}0czl5N_EE<@)X_Ym4)R9)-Tl}} z9ik!iW$}o5;>o`JJ>z*SrJe=UBRai?>(TJ7+|I-0$-j4r4@`t-x%xPGR$TQ9__bQ4 z)h<8tbX>-tSTi#>UEL6xMy{2MKGkk&%yCb7!oQ^#Juk}oEezi?*n3SQT;3!pg z%RlNe7k5Xmvj>^h18pMz-MpF&t`0O@pU^z|p<)4!(l_a)ksmWZjA^`6v5@GfiVcb2 zQx_#4r=FLQTP(ty*-0J^)#r@JeaQU%?3|lggHI#AA0Gz4@@cXb4gcDF^aS%}3qGZ+ zx#udM<`w8LZXQeiuO6LP&#+hcf0s{_wj>jDR_^K}<|Djx&Un?`ib7<10o_jeo=kdOt^-;9M z#OCu|XwQuH$odw=y^X7zOq>+<-Uj@iYi2x-Q1e=G0ZpWUj^mEkC0!Ja`ntFt!ocLr?RPbDn=5XTI@Hm zLE4%F&RrhMn62b9{D&qA@1L3nQ0Dn$NOdCu5|Tm#i~_R?MDh#U3AWRo-D@OM$lsZ39~6&qR3xh&ns*B~o8{z++2F z+kVzwDnGJr|G1;necC7Mjvte(8+>_nyY*7G1zjq2Y++(j^XZ4?V;^*|cna}w1x|3O zJ-vM~F>$wIN3LPr&~qm1+9@IQhv;1AMDBsjHujAU(8jD&OzZ&Tm{q|QS~&+C%?c*g zhdoI?*n_RHm-=g5J~%wSMlkS`L!pPddWeVUqmDYwPkeQqG&}o=o&JOH(OP}q0L_hz z&r$gS=JYahq3JvAIcN{!$Mk)AritxK(twB0_$bDFiPObi%AqK+gz|x5{r?G=N3rdB z%0)Br=lwRH8B z+XcVUU0i`*sqbssFHeOZV^f^PukdT{1D2{=@`p85xyuXSFZq`k&dfCVdTw|>QZ}XH z+h8{ny^Hp0n5*lcW#PVsd%@S|%9r8z5quS+qx#jR{0;Y`f209ljYWM@-Z5`pv&ib! zH$Cgkfb28F_yP8_2B)N5>jvzU1By+P54hHIbrojOx4|&XZWU=Z(4NE{&aDn<=SnqD_5%hs<5?a6KnG5SpIV_ zJ6Uu*d-OWTpnzwy(Cv^>#TQ~bmJgo8f5|a&K1RWZ#;88DQnqzXdYR(`gV-f=Sf?L5~We2C}vhxW26bnz&#>cigLiY|ORG-R>1 z-OnClr}XK*b1E0SA6i!bacJ3m@VZ|yI?$Y8{R;U(!!MsxsXj#uGhEoV22D)g*1vvE z-g-BR4O_Z@ zoU44uJGn|O4X3xm`E&}fA4pd0fOfUc46v^G4P&T)@Bf7P-4E}JqwBFZ*rBmqMSp(6 z{8c~Z!~4`P&Dre>X-I!$E_v&l9oS7&&QBS5UBz$aI$c_i>$#qV;h(=DCxLA8+V4ABJ+en6?98TH zxsTpkVRv;>*YoheO>P?nZX4{6ROq?pA^h*TFymDIc;+c5cSz zAIjpKZQ2q%)ZTN9S$xff+ltVTy`!GGc7dl`-948A*ETsH{AkbR<|N&zUUJyRemljE z`Kd$o$KPMUoP^N{PG9VF`Iw)bj7#4w=lgeFu{wlv(V@-wd{>JfChTh?>u_=tb?Dm& z-?kK(V4=^-e$mc9xCuCKrrurD|MDx<2dgWqsrTStt1I6**F5+7+trn?y;oiN z>Ic=8uMAdK))c0fz3dBBov^Hd*CvK4U!4@He5E*)sBh|#>r-9DzO+TxF?TlZ3?6))>n8e}?#lc`F7M;u zF%IQEsIfZ=@k>SK&gnhR?jU}+8-=u8@F+>bRORBxWWiMM5H6y?V-Q&E02V%cAZM`otb0FWqOQF!Z#=InV>0sC!HRzZj z2DzDp?=IJ$BiR>dOK_{bIWf-N)Fu4>JXuDz6xm+Fl##tiG}Qbm;~N17_{e}@;o6jv zb4~M2{{G@Q`IAGgZ;bk^c|>llijC~oM$z3`Y~LLD4D4Zj)`^{l%#I!AibzugBdGsT zf4ecoFGT3mYII3=J$-3HKTyA$ndfT9U4N5P&rco|_zZb%S&NeE=Uw3he*ZgQ>E~Ox4`m8Zn`BQ0-u{r;x+4j1@KiY+UGuBZ?harsx#r0`r+=^l zIoy>Gtf4i03n#YM<(fl1lv6(wb7i>AV-x&UvL&@1^X_29j)ZJEBz;ir6|(*s*<$jQOhMvzL@p;!xsQ zm}im~D}hA|vZCb-vo(sG2ta!_eY;F^I0&t~yec90d;UtE6LQeVU+O++?@Zt^!8f6O zJGut`M~B8>H~a%*PW{IJ7rtq9x=I*}^t>zKbNBMC`Y7B;-+OmeTHfD?iEkyR(Kmq z;S5tTvM=%15`785qnIz1#{&D#Gfb`4S5f+OrREaxXOZ)w+dG#Bng;Dj2jxScen(fb z&OxXB^Vz1>WLnQ*^H@}vX+Kw(7hSKhUx=?%KfF`)aFr_$^19Vu$piIwU88a1Smi$| zJTX@$iU(-!%MSN9@XdH#8``cT*y2P>sdK7xKkK94XJI+D$DN?i*gN0N=bF zCk^K*PH&=&@cL8WAeuYiuALG%@@Q@ryf@5PoMX&5<8R&v3=Z~8Kl&Vik6jWb@AmQ^ zSuqpcKrH(GGv8N!4E8wWFVDldqQM^I^vLmr|LbtS|1CK_&6CuzIe#1~^PKEZ+v)pC z*4f3Zv9(7*E`eCH&uTPZG_|dYe+GXJ_bvEJD-P7J=RRMDY^T_|YFldbA9}v@k;zRn`tj-+-?G{+ z>&I8}Ypgjuy1#9r6FV1Lzikq^44{#7SzC+lZ(?sX{3mB%qt6`lpMb8**^bE9+Hhau znWJaf2|t zx}eBbK8ELJF@Eu``Qt;bO=f-pSH?ZRC^XC_BN^d`HX=V%EKyBY9kxLD(zwVE(dm$1 znmEY4S$*xx)pqq3xsvh-~fxo*^#hv0c0zEk_6 zG7fbeX$)#Z-^dPqi2QirClmboosSZHUGFV^uk$XtEAfsz^AnfCM>>&dPEJC9bK`En zq2!G8u{isSe%VsoI78D-tmkviL?F#RfS}(ZLVHsg(Sa>~r=E)*|m+cuCGl-lfXAU-7;TJnu+>iTMfg z9X)~gv5CXr@Z-UXO*|iolNRF8Q_J;i9jp+31hac3AGAODUxV8|#0K>$ZHdS0{k`1x zrnK8RMtNIny6&UhkuuN!qlCWuVZV|ZR; zu)BYv|M0B9Zxa6>*Z)*JCwb|vqdebvl;^CKj#y8e=YrijuA-$yFAd(SwQ-#(Fnr?%aJ_f~#ipRXzUj-r z_PF!W0R5HyaTB&iozbDS^(JhMRsU`+s@6TRuT^(o8$`d^M9gc|I&72NKk9cXzfGMF z63ePOx`|8OT2BgH54E|C@Z5ZJ&>9GZO*D&hkY&%JuQI`ig&9| z;nu{N8FAlXpBd$6myN=+b!lJZdH9z6{I`<7bsw-t-*9ae6PSmrpIuvp=w5n=*2p^l zst}%4d_23!09wk!GW|Ei)A-sIXJHnHAr z_Dyit+wz+)^c6kb%NnLC>RZ%F-BsIti&#h3_R+64)+MfO9Nc*O_50AfPiMU9!$tT= z_Q8kAw}oA5Vv0>IZ^)*md7ALa-|en*Q~QRTcl)NXYMdHx>R6va$NW9IrN$^kEQLc zsr2jl*G>+_dX;kvnQG(b=s3P{#q9lIkE?BPVPv~Lob{~TTt39uJ-J^^`2hP&0rFW^ zBl|sn979{){a+;iSZ}KS2>42E!-9?*z}GoRT_D1Dp4}}9EF^#B8*DBWYA?v8P&bPP8+pFXVIE*+~8$!H#z4 z7}^tTHrjS$C+%^*z_^XB3X~m4T@1&*)>!z;9?j)qd9Q*iT$dgEOupe7rT_#`5G4(;q*!1AM%h z#-8fK(Gxn_qNN>HzH$Ay0_F=HX<3H!&t||xtt}>M^Yigb+fw|PiOJurj`)T;;v4FS zZ?Fp4TfG!t5Ol?6_IET!^my0CN-V@M->y`Cn~#4qdm-e!;(Kh*c2It1I&%+wniw3> zX#JFgPf&I8x%({Xx19PcGMe=?dOZ6#v4$&IHyYL#HxhG&f3Y7OF@!FwSV}*8V>P0C z_P|5fmit)$DgRp?>}ZBP@bI9 z(VHCB7_2d8j3|HF@c-e3_$pF={h5j9f{Wmg3WL==izMODOn(Ep8;erm;lWPN6!R0N zZRy@&#;3ZYA>_lE)_~|J3Vi=lWmY+?m3en|;+^b8(hqjIzKz4}E4#e;D|!PSdEl>= zZ!PdPG;UySfOYuB!#qU(pgQA=H8<--`=G`ADRF=~Yrt8BmoC>@%i;VmZ1RhyabLRD zi9P5u&o)4#hQ8KcQNMko;%j*q_tm|iXS%9fonu@%t7jWoJL02VTXG-kd;a5V8EdAE z2=jZ^)vWnAS9v4rQOVzP_OLfi?w=?4AJP9D{8T8LqkG1t=bM<*=lm*hU(J1>lYDm2 zjQlBf$p1ZgubA2>_l&JkXYQ(RqI2)(=@%AdlwVsu?cn2xKJ1b2oL|;(8oU^Pjvk+{ zyox$sJJ!_BA`e`ZNo%|Y`FI<2TxBvEUz==d&sj2s=jn}KnPO@mcAuv=UQ=XhpJ)74 zX&H@QDK@p|Qr9nxJ-fzVhuTzp3RJ^<*}dvBs`SOK(C|0x^q_MPg0#_ zrT9WnW*yI}veMl4wsJqqeV^uj$G+t3=k=bpUSlm&Lwvq+531jHlrY9WuiR%5-{lzd z^mqOErF_S@zAf%E-Z3YizJuqz)bX13%)V=4k6`GG_-H0=5o1`hjD{C0KaFyH3m2m=E#IJP06HjhCU37YqYrL^UK;W9kq`NTTSiUN z`>HP_{FO4HpTI4dlLEkgC$War_gRy6aCSphj`ClPD!&Tf8;fs_yCvN%vsq==S=!G9_%Gp^|vd*5w{F&asyJqCiozN-#w!=r?$N_Os zG&X_p+0>;zu0Edmzvv6|T1Put+m8#2PS}@lbL`-Ysyzw^KcWg?6K$Qmy*2dp?JYa6 z+}y zLvI$Fb*?`qZcz%`q9-X88#gsbqz3S2P-}8J^vJQ`S zzu|qyUiNcG`i|#M^IT&{rTI&}?>HB27w?D76`uV}&*-!I==HgVZ)%x4;gwrAs9)Pg ze#i62lHZZPq$ax^Xz6l12z_ZgdS`@WUZ(9EdDFK zr^NYEhhjZ+A8=-LOhA4~2i?s6Jn@0CCl;F6Jdi3Zm;iklW!%DAQ_Lll+vRs>2E@w;lj%2wtUb!(_>enXAt@Fx_ z-4ecU$5}1*F;4=2 zC7m~+uft28_&BpmzF&&t3iG~sXJ&u%ZM;Lb>VbDe&{OswK~D+a1uuhVMX|quo3;8z z@tOv|?(oh`_pHec6QCD#te1U^z@gFJX^e^C0=damlP=;q50 zn01QB)&FVtn{_*r_mNZ0x+jwNXRb}aYksa-_b)t??i?j1&CmDYR`7`K*~!^FF8tpa z+^V{cosz^$DB&k29Tqqu()b2EzD+&u{VEgtF87+>)+xYY4e|<`kN;BR#wh8z_tX4; z$A^Cy_OJ(y6HBK&x^--Ij<5aUoP@on6P-C~Yc1l!dR)||fBZMnWx4m_epIL8+4`^* zpOEi#m4Yj^Kjsc6mf<+DKa&^vhqqYs9_HG{uMr)7+T>7I*|eH2>v?D3#c5_yXPK$J z1K;Ww{p>TG%C!_-6MM%Gp^5#z?CwM4HtF+?Eg#Q1Sm*q$y?SA=!EZYLh3l`$5p~k> zPVn?)H}s#o>|6c0%Wl}do0zG;HhpXR6njjzatgg|jmh3(Wn`bdXH{@jXL0bPJ=X`X zU#sil;Puhs;Ej)Q|5jZvm-3HL?yrwAiW$M0DXT=1-}-wG~>Q})f`V4WFz zuoqoKV?@Vn*BP8^((QH*7Hr>Qn;F2gGM&D*agCA(B($ud|M+F|`_q=q->!Uh`%SwoK(!V@#!IZ+Nkg{S|cC?*bRW<7Hs; z7O*)6m*LEpeOBuCR1VZ z^hpnH5M0K*pXtIR6&}Y8!6W_X@L>GI-~oJwV1XZ`!N+F=G5OipH5HCC-EE2r_-4~`xw9Ak(f`b{-4gL6Y2N= z7#>B_;*W0slXSlJD0B`@e}c}R{S5y2`~LetLwEe2&JXW=?sM|PBgltkj9vb$vWL8a3_iZp>ADpeJqyXLO8dG~U_7wKL z7y0LKMJ7k^{eFwMfR}vZ%ReU1m}Ji(-wN(+yw8JOe}TfVL`iZS;O{wO|B~sZ{nKE`8Q|mxjA^o=HlQf$e2^^()Fg` zDXqo9iXRmRAA74VsPYAryMe1)wy!uigEBMrCcoK9*|&;=&z|6XqU=|xS7k4E>%Ad( zDfQM;@3U{$1>304rrrjwrO4!2)LXKrJ{Y3j669WpdTXio31YP^{MTfEeh~Z1X4Zm& zvvN$4*Q=fUgXGilwf~ym77P7=Uv8S2aUiK1?Bd#oZmsxMJ>Lv|AKa@So1ym-bdt^Rw1=4wJE=o9DTi_mT%|{}Cg~)a)FaR_D{rN2YTm0l zbcs#)n9NP$^KEb`oTlOvT<#Sv4_v(@cxsXGxJ3IwE*=;2|Nk0~z}UqjFgzj-fw7B2 zVD91_I3EdrH*ZdqyUDHZhTsj@1@jxB%IFLo1Bk*37pnaZ-{z7&wN~q zPVu?tqdO0okM6u&5PTT?Z9dw3bmw6>7D^ zF#fvvQ}`=z9>!n$K83$h?=b#Ky+`G*)H{s7Qt#*Hujm$^8=u4GDf|^&9hJWxVXlh5 zK8h@^L!ZRIwf3$*4Z3ntYu7iCk?)YpF(D_%x^gnXR~H9!UA~%-j}IUp#b=MqSEnT9 zcI^Oerh8NSs%ko#ZTRRTX^jaPiM~P25$eWdIjTi>7MZp@v*y(!p9h!3lqkwZ(KgM z_b7afdR6vvx85WlquwL(G3s^cJ_$pYk5TXE;bWKX_;1iXbnD8eR6Yj3@?_L7y@ImR zzlZTL%D#>-(f^7bu``J`;Oy!V!1;)>2iT_K>=fX7B)M}l^{L#D9zlIa!qt506O4xR z2QLe@;EZ#gC`|p+~@jj))^y#(*PN<}?JQ`?Z1}>Eqr{_CML{j!&`IjbqL} zi+!$(-!#?;-{DF=@PQLg40WAcQPX8(tCL>>=QUKk3@>}dm)ni4!nHfqTys@$cdqFu z<@zxGiXWFc!M*55o#;osZ<5;?{hp&B+viJHLO)t!tnAa!ds?_IhNr~I8(gzzN$>&g z=kB>NSiL6_oFzLLzVS7zrRS0Z*5pnYKM$T{a;nSc7EBr+;awa1cGO$GI)Bpm0Pn+& zDG%h#D>ud}kHMNoA z#)9|5*xt)opFM0Qb!0s1#7GoyImTV7@qxc=0{LPGeIe3~%F6X#yvbPzl zJ^$$?!T0Qf?4OZec=1!qgVxgx!5O}S><6E^Ik@f{h4cRObU3&ed_~7k7{3@iZGGw{ z7iZ+NDi_ZFMDBgzYS%cjE`BrcAuXlrJ88Idd$p+`p{Uon!uG$2A%H zlShAUrfqU7WwT$9UGJ`=^Rn-;^Rg?b?{wOi{5Tt4Dq4~5u#P$#L@%^^I{j*JVeKmq zfrnkRt@)*AA?CGc1zUM}Pg7|V`!yY+k)EdGnjYr9*~&O*C38{N4>WTYQ>ZKaw^jSr zSlQ?t+01*poqY1`W#mME#hCUVu@-*_I$6yx#P7J}^ZN~Od^x$EgBNUnl5uDb5LBIA z!?>jTl8pY7 zT%QBR6^3uPJOjG_I3?EEkhK^>bza#p4h1|9+KoYHx6`s`K(nim1MiLz&&lcbXmb>_*>mkR!TejY=4Ccs6CC@6ta*`ZuL}O!%J06&RJ7l4 zEpur_xc})dRPS4};+y@mO?La2R)n{Y=6{39X+LkpH@9bf!MW=K&gjuzL=W?DI=r^m zva&BUS?zaB$(q;s%WyCsKD6nVk>DHHV;XA}Ce zwCP-6niaU%<%Ry`$2INtU(_wS7rnn|k2+}K6TjpA=6&&ZSMB?=FQXg2++OG_XeYPe z|IgmLheugmi~sw5XL1ji8xRsoW|E*JUaE3S6wR9nUV~AA*4FwnlT4tZEh-b=X4T+Rcrr!>=QF-nu@Q$Kw1S~b-*D-ZiW02Cq>GUgs*;;MJ?bc8w{kWFBbdJm}?(gE_)P9grmu2%K0I&kUuHt{Lf>+iOCPZhT-UQ-iM)VEiSt6VgX zZ|q$MBKx1Lg?@qYGxV2eY=V2p&%U33C+AwP!=F#?{G3DmSAD}ZcnCkWBk=a$KGK$R z2p^$$@!NATX9bRmdU!Xncy?2F{~qod;Y@{xz1Kfu8<08<5!d9mkNha7g?jp^BcD2J zfz_37gd}EfoXmIl!ajaSc}CQ~4laB^{9o;qaWRKQesfZ{_-)iYz#cw#wz}5QXOGP% zzEI0A)k5?=WXE?({7svyl?WPDrNV1;#KHkVh73|{w~ftO1f_36Z7?&P>qAS z(poloh%YX9H`s4#&sQOr_>Xwb_>U~d*HhpTSYp3PnkPerWZ!%En`%A~g`acjU;HiS z%s0!M^{{j@4$mO#9*;Kbf7=)fpvWk|LeN*|NP*A>!1CX0|}4(>wz_K9mnfZ zI*xDc-+8?A-JQpwhXd!Uj^o8VMSpm7-BgQr-M7bg9KRa=w0EVwXA$qmdAF^!4?5sy zaolz8f`8drkK33>+=Jt-R@`%i-&(BvSNlD~yfXk?9kZ)Td@3;0R}KDDTC<6(=NLPM z-!X1&CVqcIys8-d9@7owvjwmI9DeQ4QM7I;Z#S-_?t~F_3w{NkEzAWIkI;kQ*2B1n z|ANqrc2lA+e1}%}zVp(=rXrbF1!+c+tQ*-=%gwV9rJ2MIC2o@VnZ)B)B=t^V%+9Tg zE6PueFDfhvpD~dbb`6mjlJ^pKLi+Ln=Mv=1fV5{2PqL=g2#vGi@36Xl{pGC3-^54I zw%FODw85FR)Gu{29%gLPuXElO`oqvU|tH2(O`S=PtgPg~x zq26YETm1ORYYM+5BhjZN&==Z~*pp^oEt+pU@q)!>?pU>aFarNP2j~612CV(B<$H+* z<@0&*=b#OZyQ;NmDs-qJ41=^U_W(M-Cow)F_swz#0cR@xdHBfY74SY^`Bj zK}~p|nwQE2kn0^(smy4jq~6`oMm4ieXH#=LR--5@}`CT zM+L9t^h+>UH7ASNn9!rrgr-Sq?>vQ-Q7beQctquz4SJH1z(iJ;y>^ z@^)iC#% zG9OON-_Clb@W;`*^}E9{UdLr~{v)E(<)k^xJIuz*JVY+51=d|xa@Q|^uA({{I;9K@Jz_zS5LyLTS*2gLa+g z?cU_n)J&%ySjoM&OEmaY?{^L67(Q4wR+9pr4*XzQ>!trv-vB<{wpGvf5WB-CKF-e| zw{$EC*4sE=BlCGKb5ml71X4+MH5e$UW!zVSa+2{qz>*qqOl9yu#7AdVSz$$|tmWZwbDE zlbQR>$wS4&J_Dbgk2u2s?)aWz2XBHi!H?jp7aUsQhjOR0;OY=-s0QEZtz>-%o+v)0 zzh2_U1}+8OGGgd}$CKc2h;hs$et_7JKVZ%6qWZE9|N5K02umQ+;?oo{t3r=E{-F9K@on2+!x!& z8FcCQ7-D!u$1P78$AgTO%Jk$&eKNjTjH~2(6&@bVC*x~qUp~ITV2-bhsVxrwI-wij zs%dz>=Uwgq<&N88J7e9Ath!}MZ+$OwoEVokmnEo6E=D?<`nwR z?;cbe4Ez+|<-T^IpZ6m4BXU$UzlC~UC7*&fN*dK{ zz$0|u1w0i(mPKK5!>^Ggyaq!#ncv(^i}( zb_Cjcb~fbKdxnN)DC$1D+#Ti@g41^+u=I02F9^M^1r~{!5`{(1&xHAzKN15<>(=0B zI=pNq<%OSdFHd)9m8I*={M|Vd;b%3#V=puOvi?|zoo4MX_vaTF{zcd(k8ZSf+3|%R zBsN1k^e6G3PZnrC&Kk1i8Rj(wg}XPkDmAl}bFzDMOK~earCnvZpMuVwjoiB{wEHCV zBxeZ)hu;8hc+YfcOXfiDSB;RwnLWC3PM5%7BTpePE#mxFEBwsP`kT-CTfo{ojH6W* ztifTOWCZSF(uEHd(3dacLuJ$}a!n9C>d%biLpJ0I;X?~%5!WUU*=AX}zYH0`4jdhS z8=6s;Nvtv8J~992!}rfiY<$7_c-9QD2Tla{S&?-^aNW!r!P-7u&V?~Q<(!lF$KKow zZ?Hap z=O;z>A*QR}11!6^YhG*>qK7!4>qdBN3vI=v8C^%#Cv-KlHl4Upg?u~Sk>!7XD9nL->s}kCG;s9T6tbgN~u;BcM9h=II~=7E!dOOMxPe(*r1^{rIH!P zjQE1RIm)&tN5M}#=&ho=Rs8Y!9&4a2r;Yj3X8Zl7x>W`B@U(Pk^L*+Po*;3@g;(1O z1DiUMNAhZsQH4(nzm9`fTj15r_>bpBDK59ky>hw0TXK z=Ul-0Cp<^yS3mKjB=0BWv+0AgqWNTgN_s!*P&?mbeEZ?$(eL7u+|0N)9~+t>^$32u zNE3NM;_2?s`n_z%D4XBy~z%Qm6F2-x60GWXz5L``yxi;wT-7fnDO! z2@IT7fZm@m`HS53E3|IvDA2j|=M?;9TnxQ$fxfo@PY3<>Aiv9h8}&qGq%9E{>5P2z zs!8)g+gtw*ZSRcGHahF{mQi!JBSPB?XCgx|cbl2JJE3i9uY+@ta=yX?ui4V6e4RgZ zbRDhGeQV%HM-vjew&1(ocTQ4QC+%A~gV4K`n6VEhcb)pS3T=Vzcf!x)Uc!@Gb@Vpf zjK}cf^$9+?XI{qjvQ@wA`Ax&BLC-lkUiByZx3fHcg}?Mq8k~bdt8zbelvY)e&1*rf zs6(!361jqUg;rhA>K^<`M2EVQvtu%67Ry`#ch~^uS(zg;f1-2eC$@b#&W47bIOb5E zW_54nyNfy0imj}Uxnp7f#FH?{QRSyIl%^_0mq5W=&}Lx`y<8!Gi#|E2yN|W``^Zqu zQ;D_NguWwk3Tt$K6LaBmbXS>!;E6aMK4p7rldIvf9&8ry{9L!hKN8wK{P6W%f?F#w zk%JZB7&?`C)X8`qo^V~)wnz0Yl?EN8DSspM6rFePu+F^kfcWS$_x2e6cV>m>UT?J# zdJwtd%=}9<=O5VJ&~H)2PML$`mwc`8WfypOlX~gvyl7uv0k$_HZS~W~=V+$`e%vqe zN2Kf%d>8nm^DsIu!@M|5m*MqQ{P#I~6S=R@4(?pw?6Zh{2bj8>MeoPn&;l(f!|qeW zK`JCqYq1t`aL1)nVdpV%p4BZfuT$wyd02;<$?vIEp)zPp)=;U7_15G&oWJbWZJqrx=L0e)m51cKoQFE){G7o#IXml+CNNQd zKJNm?+yI6qhdvnf^R7u|{H*F(W!gtB^f|FV#eUcB1n<=2VqR#X3##*cHRS0(J+vbZ z*;~fU#XLgSnJ0B^=ge(~X-6RT9{85D8qP_Z^&3T>t6yPbRMhjicFzL0++ldO{s>== z;vzhL5^psQpAcpGg!~PiX0dMg$AKg6Uapk=z#-Q7CxH9N3FZ4f?GJHAbsK#Y`{vO{ z*5=5(Xfw}7XLTco`h_pFk*}6|c8}G$a~xXp4Cuj*C-vkjjyaR%Z@8X&lLUhfPL;vujCha`+?Vm{k0z$rL2>B^H{ULFXtQ2 z6~3)foS#{-O@;3k2$`~0xG%$Fojj)~cAN$N!}QGw4>%YZ2Z@KCMPE%hfqqG!2N{Dk z`R5Txl_EYv@dZS`+)J89~%B`^k=WGS1!{nm940gkt?3<+o>0c{tc_>Hul=Z9&O~g)UrJv1_etKg1 z8M`ke{j@^Mt@N`whMvXdD)39}+u{3mBJt!SV_H1SC!irG@W_}uCu^Jy$MzV=_qDIq zy5OZD^Xxrq=DiOv2J09TY{RwilUDfWo2ymsJ)8-fgDx$$74Awi>y`cq3^F!hyLkA% z9VfWzg>JrdmjYLZPWj}|mlyh!y)B*dOzJVt>n2Vp3Rp&; zC-BBKqCD17f^sgfNj}y^8~KF4pKXsrl^Fibk#pM@qVsGd zKAeo9$U7ecqv$_^m$w_1^@uDu#e_Y#dpG)yz_YCwAJ)dWT=BVH)vEc#?&wHOFnNOT zYvI*$hpUX${lF<>(Edx#dq(C*Eo(z8j+;jPw}RtDV34z1?W_|L_eS8US-E)7@_l04 z*DoGCPg%U2r5|WPc0dkz<1nxce-*f9?m3>yQV##eYodt+no&ZA|K{D(CTd+UGW@_<=*08@;r&MVjcU}!CZQwd+Uzmq>bQIQ<8V%?rdcs^QF4T^i|G;q;f0 z_g^5kQ4KOzT{h{H!s$tpPMo8fsifOTFO1X=oG%dDsODnQr;>g_q<-jS7qN~=FRhub zN=>}eH~b;oPhz{2G1{7CloS-Il7eG-B?7C&c^{od+^z*5GPeDU!BOxE|2XjT$XE-0 zrQXHSvE+Q&d2Q;(1oB+X`)=aT-M~Jum2(2`;m3FcK3Or&DA`JzE~_QwaqhI1yU$&m zpL8|qnXTZgXsY2qKM7myc#$7cinq-<-^+L3PR59{WZuFt>gLXiD?af|y}IEJ&TX~h z&-^m>zjLosH}_kTyWbDPIB##Gb-wIzJ5}I{Hr}r6~UG{Uh%YF*)INoi| z?Q=!Pdk0(i3&d*J%Ts}G$#=B)$|s>K{0iI#_d%S?|CdwM&3hBEPfa8i7GwXv$=7j5 zn7&@U`@VHgLt`)B{gsTqbmNpujq&!{jZ+WCjqwK4Y!|(zB~?~zOZ@7tH2X!h3({|N zw7Gz<7C39G1TGUkV6yY*B^vapjqQXsRlGWVNF}*#*!Ak5%|-a@{J?5W*{hOL1UGxZ z`C5Fu>Yz{dpipKFPO5l>J;ee8uXZ-x1~T@jJxWb)X~2w?&lw zT)A}0LEj_FjicNc#vFZCzAd8c=gLi_9P~e;+*c@8l5Dr8cq{Pnc$>Y9IUiP+Y=!1!F1XNf;C1Fa*b4u!Ft3_eV^WWX=W4&jS}e3J zbKza+oU>vke=A@Oqmgh5v}Jp{ylOL3e)zwlwmMq3!*^gueRh8^BZtF3!WJU=cj0jX5wi z-Y7kS?+W+SGZ*4h`l0BxgV8Rxf=4P7$Vs1Ln3#VU2v zj?}L+KGm!x5>sa$ak3ta!|#zYwZx@a8-ZspbxGb9=ICyDGk?c$4qWh-Moh2&C|ADM zOx&fp-^Zs(aCcz@7q6Zi+VKW>lbGTCz;V=)P%LpkWE`W9_zM+UJ${Y)!ZNPv7ClDf zBL$CI1+GOFvUF6GiY}VHuR>xhE`61CPUYQquo2&vu*|3<2j_OPr^&tOmaZUj6Km|v zL1ZUs>kru8P9P)tdC#|GdaEs&0}kd@5S>;*J9gr129a0#(CcrtO!DSmI<&D#&l$Lu zwOeA!zE9p>P7zS$}Mj^OBO^1VY_Ypn6!YW&+ozHw{u z`<=AW6p?R&ix-{Ri+s~UzJz1A459wO(*hAC-RM?i+rP} zla74TiG0&p7^$Ce*2j^KeA9`1(}{dz){lInCYtG`9mqF=Z@EiDc&OaLTnOFW%s4Jf zR=y6#QRLP;*-II%V;n&ST7x{Y1{p}?z?Y$&(P<(B$vhGH99sRMRj-VTxV>q;W;gJ8u&6P>hy?R9l0z3 zd}1pMz?(e8h|(Vk$B62a*iw%Xe+vHu!S9~4-1+AuUWml0vkeZ-sM*wP#$u^OkNrBj z>odeI5xuq#eKc$b%j^!IgE}oLv;(>rBDQ(~usGAMY0!W>tRttHxU?}g9>!PbX~>GN z1h)JQjG^s(bSrFJiO4d0h$DrLHyya2R@<%#$r#9bExKs~?|b-fY_*g+_FGEDRv24; zAM@oo%6CwwS$=uA{43-$@vJU0;n*ktu~AChFY@~rv1M%GGNRL&up63L=9m0`l6->e zT>=|)qZ^q%+rF#0gS};w)D`WY+;1R!UgCRXLi3t7IIDKG>=|qB^BMCR>j1Ys3R2pV<3kPhIi_;i)#}jC@zDqfUn!j)SPEJC8Y$XN2`msYmWZzLs>o zD7;54dw-gbI?}d|QsyC9Z!}j;k zRYlexU0oFazpg2IH%0lyPMUa?$Uw^f#>GP$#aD~GK3QkA8;npnYq4dE*sgT<`@nDA zF7i!Sf3HxMO8Z-`!J1P;J4_e^#tZQ$09Un4w(3{3rRC6z{_o27i;JW9`&pMxz7xz_ z){kySYB-LejBOwP;TKQaJ-I&h$~D+xzz;B;SoPYljc)k8V39@VmzlrxVdzMBoYE4M4JU8()j7aMu|@!7WzCiooW6WdgtigQ=8 z_S){V*R+-z)^@QJ6GQ(kzP=s#WHF&W%T*_Y4}w(-1! zFQoieq-%`HPRiT>?pqc+OZL<|2NgK1I|pq%`_R1wo&x9 zvVg+|9OoEDS2}P=yaa*eA!s2iGiMcFI@j<|2A*gfgzM^84_2*iSdVTt??P>y*V(Xo z@PZ4j>MFk22>k~5_r6@{jRV$1bnQ0iP+)H34ugB|Sk$wTCjqz=OGjSg*AU3cbZ%}7yGiB?0$uH%3Och z2Z%je9*b+io9toiA&yvdPv#i3ApBjv$rJSzmHDnQ?^`mc58qDxCia7w!}?>&Uxpmx zfd*s^=wR)(LqAflg?oWM!>6(U9wYUOA7iwBD|Dy9n_7__^3{dDcJ_(nzdaD=Yp)W& z!j?_V@%R(7=6kSlD)d6BE9whb3!O`TS<~#Sch!_v0gI2Ai<>-@i_Ocvn7P*>Jjh%h zRiWv7+rCcuJJ}Dq=K*3$qKoaozrHL&&yVibO#jY6!*bT0adMZN@8uNss?GU@|0Z;8 z%BC?e?I3=h@CT{mLcWVWCiSeK{&7Mhw81?G2VKY|!c+U$zZc%_g0DIwJTlNQV^HGm zm&qNM(5dJ{Z^?Q?yVWue%yTbV*GKHjNuBqyHzDo31uy-bLksT@v&Q7Cx~GT1eRkKC zl;chkXCXQX{^~ZyX_q4=jXTwwS@!~0OPX>k@(Fyp=Zp_`R0fv474EXRIZmbd>=hUI z9E~g17eLEv<1LkY8td1)0_P4K#(w5X-Mxu*$6o-A$9^j$UX%IF$~SCAvES;V-xB$T zT`2b3w&=H1zG3@`{dPF|Esby3cVfR4W<=V{;v4p#*l%^wZ`pjq{uBFcTlCu`zS%~8 zI~@IH<6Gg#Z-v}*XZEj#iz@Z1LNAUn(pyk_%Sr*ePJ`$Ibp4O_tn~ ztZN};9|v}f$3AU3n2oP1cO(`Yb8TL+b%`I9v>8Odl(@-N$;5bMF2EB_+2gO+o_-B4 zpG!HBM++_Z5wcIxrV_mUl-bR?m?l2j$cSw!lfB`woJE}Ey`KG)B%WUqvr?yTB4c*q zD_d0mn!~NwByCcB2 zSY>$yK7mc}+hGl?JZecV#(09QK9z0KG~zmi;j?9UQvMy-Y?EVQOG|Mgw+U>Q=&JJK z25bg8a3Nnx+0H^$pT=89Cd$(+0|Fm3bU@ZjX;1F|5IIihL1sI*R^Bg zEJyayIM=DjpMX!D$bgF}_ck)~RlJLkf!2z>>#e$;7m)cZ;Qw*tW;2!(=j+6V-MQFS z0?ndxj5p;}_AAqcK9CbL)Q#dh5T=VLO^mdc?ltvDk&guqY2QV=0=t~U{7J)|g9+Tn zR)pM~$liwFNBezUkHA#R7zj)vo4V9QuLA|e&bdF%#;0&MLW$TEqjGb*CDpX^pAEKM z_)f*%c`x=hJu@szh+Qo#H!E|mUgQdy*HPP>$Uq&JX`yY<74pL)qT9Muvd>{8;Twyb z=SlLB9@4E^7kXg;J?O|w{+UN}0R z=kxitIFNCvr@|t^C*Msi zI)#n>oA4a&)9P+V-g*_;iup2+F-<29`DU?AZ$UP6Fvevnd*CT#yfSE~mwcV@5vzGm z*tqTr;E&$4+0=Iw@66fOvF-83afKeE1K02WVCz}7dSb4IZv@0}MOy)Rl0S=s=1Qm&8nLfUkwHDB1~lbo4~w%GzL z;s3nU0C!Se;`^C>1s^Zf*Y>;(+(I*f2F_9s_Zb-I^PT7f`x?#*!_JtbLQ_(Q*fu|6 z4`VBI)dB6+GXLZpla2j}Aooo<=Z5bTH|GrVWLrcp*-G9%_FE)f>^dI4eSqx0h4jBt zpYWIC=pWG8QsJM!Zn%>(9%GAN8}sX&A&oTXikP%F@8iKf>U#s5&C&a`%wxO*r(piP z#eO5UAH|#Xbl!hxKQr$qcp>riO?}vOhE%3I8C)EqzE`1>HtYvM_Aapjc3W6)wy(T% zaNA;g3G~lAvJ5oKoMN92*KTh$W%q-Fy{9a`x7FAbx0dcbq=?hV7)u{S_b)^DpNoy; zgA5gtex4{+{;NJE{`U9a6{5$|cC5@h+J3zZndwFI9@}xg}-KBwTl4ms%X z)!5jPz3Py^g$If6^)nA(Tc>^YIMSD)2j+>~g8lI4@Dw>q_$Knj)?wXH?iwFAtQ!j4 zfrjaWqKB5TXC}Jgm%%q3m`*T;;AO%zek-0he#<>G$*hOhMC?5>rm`a1^K%H9@w8ukgF2fNCe*Q?q4tl$j2KHtGU)OPuu)Uo*paRWLRJL{p( zbmW2W8N$mJ+v@SP7|?)I&c`?5*KjBJ4_MCF7G?cOea!F=Fs2H)hAN8Qn8IH3)s2?S zZ}Z;1ICuVDp0{~U%vW8{z-JV2{|3Ia{cijr>N!`E|8C)k@^)cJ9;p>rYF@e?m1bJgx#{X2ikw* zH6Cn+Zxn#j!>f#+*|1sbDzlRKft3#K#ZWvBc$R9kZQgZo;*UBy>s zHznuV8M%iBMAxA3We0qdl(IG>2 z`(6ETjyo?3NyZIWL$Z+ zGp=n$iR{_oJ3LF)^+&cdo-)2|yrphC?^6{Pp9}ghb&mRlJ=v`7pThSh*4Oo1$#^=6 z=@QIK=qe;;iSgY@^ZP1Qs1La9O%rp2UgcL!*|~k+QXxlEPVN+ZjO@_w;fFadh%ffl zJjyw7zJsS2-sggjgcsh-)6CP!GoD9LZ+`{8i{7NJ-dmvIJ?IAC;*1~rfJZ9C|9P_a zsGNbM&jr{F-(w%J4q5(*#dRe|60YfbLQklCyD>Z0&i|kAH0xUB;fD?XVoPG>k@?`Y zabj-beL1-oXBBQfya(UoTO`fCS&N&x`5ZmjTcw@jJ;Jvew6Wf|t>#`O^IqNR6l9Il@|>&$G@@daO|$Dc`OA3Jjr_1n<*H0=zW>}6{<@)wS(pZ)F3Lei&>s-HdX zOk~mI3r5w?zIWyY)Q{bF7xfSK7ymx(V)9QPRX=;;nbS!x8C8D?>Bzasvq#lGoAlY# zZ-^~%%$fQP>Nm(gCtUw99_EmL4(ZoQJ=QaLyO#88NuO(k4#whbF6ncr|0bzF^-TRY zQ9ridc5-x5HSE z4`$w8;w`wn#6lhSPrF^>N~O0|++Kn#lpep>UeA73`UCTCmp!obAGmHWiKm_KFT1^@ zjsH&)n~VLL^q(fGm8|9IPo%1q$aU%Wx87b72Q1dbGwZFu^TYMw@(*pjy#!U#>wV^S zxw9dC3FTP})9;|Xw6j>s1NQ@a1fDc+!r~eAKR9@MiL`NlKV`@-?Yv5UfoDJY*Pgh& zBzf`l`Yyf+>`(CRangTasV=!cv$|w$L3N3gSu?HL?8CoQRGWQFT0E^DU#|3r=U10x zV;B0NtGeW&Wz}+LLb`W-wF%z?TdPY1z8^eOT_W(^AL;M?d%|_DrLDCG!}YGA&9>HX z-D~=(bMdA1f}@Ay)JkdRhe>MXLu1rR>*7o5+fG!Mq>!FWn&e3$Jz??1^^2%~A$8VK zS9O~Du$j05C*~WbohMeGM;|V}Zy6vet?m z@EPgVr0+*=7Fj~pY+0}WgLGN%W9#T8ExJxiS;-S!=cP;^|3$8$%)BYs>11uZ5jj%U zeR)K`w<1rpAE8i^FyR4WBc;TVyryV+mFj zcqho6r`Y5EptH6ycb?^a8?lX=b)$5{SbY2Ys!MFhoy4t~?+{-2qjZD!5{Rl<33(@#(AYdggEjE6hF26jdKR7AcP+>4zpd20U2>*#bX_%~PsHFRjGuq&l6!Qm@KM=Q>|LcoYgsRkat?0oBbK?m>49ovO(q0f$=@@~#2 z2tEbxQF}^Xs|s}@qxasA>`R$GFYkx3b9$?~%C9y2^}x`-jJS0+WQy;qkoXBUXR7JF z_Z#>VdDfj8GW-|u&bDaYyLk6LOzbh?<=ux3bsZ;J5ax8tj#NWvNB0EKkTGrr5ZYPHS9>Jz=86 z?@ED3ru>%kg1?DZE5DYKlX5VbI914O(^4j;JewGo(n(CJ0{-vN6H_+mNh!uUyS2>mM0>7MVUCEh!16#tLC4a4damfeu{7?DAlDF%z)uv0_w_7b*%64q5 zrA^k%TO|!&PfLnXdMp3+1f%qkw^sIO7Na!Vl8S9OE#;B77WS-ps{tEQT8h}%eoSn| z525!>`)f*Oh{64d zU59T}p(D9jMem$9uIT-|l&%jhPwg6TtI&I&a<=T$(8l2YYr6!;M{*aC=W9jpeM$^U z${$9Cd_S*}{Bz0Anh5>&GWN%jGqGWWc3i14H}EXuu_q>MmhtXSsOrjx_FO!@QojlKf zFf;@I%z06|=^Z`4@Kk+m^9q`_v`7(37>Ej*GNo8Jyp=R_Vv`e66SH7r&(*r_%P@l;;Y&p?uon z$7ffgKh>b)M9)r29(hLV*P>V3!Jmd5LcWQAgPa8uexdF*{6E6>@JtT;CKLV(uQbT( z`5v}6_A@zm< zcU*=|g!9#-+Zs{+^{YqNf}`c_;QLYRF}vtfM?ShdHkmh9Z`o|HXD;^C*DPv7N3juN zpX1q`*DLe>W)pt&M!EZ|HC}YF@z`jxO#4rC55FT{g^uxE(!a@_)lyb`{-Wa}{#2Z^ zEtdPZs^%C)H_a|Dx+cw0BzL1;$r^A-OLup(UJf7&CgDeN0eaS6>}5wR@x^)iIqvuK z)q;Ji7I8i&tvC@qtk;s*jn9(%Njo||b~6k7vmO2ZeE#Pb8nR}kw-8rnA?Faw^f>p0 zHbrdQ6z{pKjr9YOIxpa!)H8J^4cGZTccRAD>E?fIoqvTle#pFa$Fp|^Y{+j5-UIGL z;64I;0{3;q;4Ra~y4|$93%Kq00tvhi(q?SkDg2MEdttKj4{34k4~RYVE_*D*z%AZK zeU)00S>I2&Z*|wI#nhK#*7pi$nPTg!ZSb$fK~AO4)BT(nZQ~c zf%Saa3;?Ux5{I-jcO`B0(jUQXnL5WUZRyHb$y`pCJ@8t=Zw9s{73Y2^oBPeE6Cd&7 zmtyLyuN06tWs^84VAyyITjy1#%n+R13~N%8PLf*huxcn&utR2@oV%cOP{_uBP+vu{(YAD z#Y^v7H;*;yf~8-{DBuhku_%2T`0xIp@!<8uW_?IYNYUWq(R*kGp97r#+q>#JgS*ik z_M#`q+`u=lTm1OYF&5-;2d$hD)Y!kMV0^`&RN*(T{>544oaC(1x22t4MSLN-t5)uht;xW@ zc7FJ-ZkYow!Ecz0>4}==8^Xu#fnIFkoLktb;@x)zx&I2f${LmDSARD1PQW**KJ$@mo0mdsJP!%Jvsbf2TV zRo)UGN5`Md4qq2vLRsf5$OR%FJv!C!x1|}Tztry4`I|*nb|EW>{_!bmqUbADY#Smw z$Ql{61P-td(p__TdB~GYy3Dz{J=|~Vxx!h2|0@1ohuC9!YPwpmf^YZmoNOue?btoj zx4u*PBp!{d1EOyoiqCfMzgR7>@LK~0*|QLTX=|!^7V1OC>z++6Y@w<{^pebhUg)?b zUOnru8h0(CUL(;sy_fl4K^#SqTWaIgU1FqU#hfOzS&(ygUn4QssLM z#Lgndz%^;a4Q1{d#K>!d7d+Lls3#uY@Z=ws^!&8J-Lsc(ZH;4cw>PHd?rluTEiP6w zcETg?ynyqX(2Se6O(mwVSHq)a8tnDSxv;#s|6|^P$v>~s;B9ZN{r4(;LBWj$+tR+O+McMgZ%g~GgLl(5 z+gI<~X8Z2)z~f_A1Uko_+8nG}9oWImKm|8$=l99Uja8SCN6KvA_h0fFt7-$CRrP_# zt6YH{RkxAn@Y=&w>(`#Bnic36JDqy|c>kwWW%mzNIVLTvDy8o1yoFT@`CUN0j<&;9 z+4rBQDhzZ~t*1U4<*%f!?QNe{{U6Fmd#*{1Rd(ubgBLGfJ6Lt={imxA<~ghS*7jAo z+KyD&NH4wrld871zN%$wKdQ=Y>#r(P>`4}w9I1^ZZXimUDEs^A^YQ!a4F`tem4ILicg?y73OaaqRU^>qI?fB2h)%h%5-d_oSDV$Cg&iD>z87#HAmK8+ohi_Uti81LJ+=S zPu;g^D>fA2k3sl{fi0H(UUX^F_;xK%&Emq6E#$Go?`{0<tZ5e3fhMI5$T}c>w7=fEN!EdK z^r_Y4k$Sj$1sh<(nR@W0FzZ3~{8uxN)&1%L)=JtJc!TiUZKSLFY`=-Fkx~6mkHm|X z^-!mRT&{ zT+}0VMg1HC87d??;=y8YOYD=;x}|(OL>>c~--G`60%c8@nP*0%E=S`w_BipIK#!I- zqz|GC2f&&9mpV_(-}93?ev&15X^GyPuql9~@;*9=~s$ zLD`R1BOk&)lIWYAc`IeaUTauKmTN*rlX@l39!=)@#4wHG|6(vUKYwkSH!xFTMX4Rv zLW|P=7S07oA2oPKnVK-*VjhZpX_}g_|0MfomPF$?`&8IOEc+ccMa-7+u5x00oA%@L zjL?KvRF{o?B(W)>4bGj%sZ^9|DHPdP*J&iU%}wEAU(A`@x!tDHVzd*3g6Pl?ET z(;ivBNnqWiXQGqmbg%l1`xUUW1U0pz>4(~f`yzdc_GfCu-|YmvY;?KRlyiPI^lWF9 z#K4;1wL$|9mE&b~3vvFdOZH%U;M<=T7{FzmRu&Z!JtF!)FjIy0@Lyn69?h3c`Dh<9 z>BE_Lpc3y&5${Ti*!cD0zd?6mn?8wuF0q%2CC1c5a4F|T0+I2SaWVPEP2n+-_1%ma zgzw;Yv7_X(pN2jZ%Dzo28lR^8;|j4k;Ddut88Uu2MwAWS9vderJRko1;o;2K#(d<} zzYEVbXM^YeMB^D2%lteEuCgMyxC8zrv^R{4Z-jC2=xZ~*zr7OM(3RXPfIUk3g)dQ; zoJ*1Y{~hpd!NHtH#5$5mASu}@#S2~j^9GxhZw_uq&zTvuKZ}8P{aPm z`m1R-0#EHlhQFpy_I4(8w_r!CJ(u<~dvb z_Unli2+f)0iSZ_OHTgY_{>Zmq@IQK9Qg}E%RvU$8g#SFw?;7~LNkij22X@mZ_<;Fe zY^Hy)sH`*e5#~w4ql72P`X}^CY_#GDjE%$zYZ}d)Qb+QbWf9)AEW(@W;Z5QnD7oHAMGd$`gSh+ zM6}UI8^X`F&<1qXCH3!&)E$j8C-K&-SN!f0PHXKM^ZC^sx^^|BI{D_yM7-nFk-uxwljK9o)YwdjfZ$TZ#;^5_-$GWL8Sv zL-;>R-Z$5^6vKJa%t0M9gG5EmAcyKZSoJ{PVaBySJa}k`dKWpNn2Yd*A1YX_5%lKl} zR`4>h`=p7N2_{~UEjJ>3PCxu5c**-ac#-jzF_t+a>$vc=XW$F(DfXh>b{m*97)wbvbXJHQ>O$4qVCbPqY6P!k4KxkfVx~oY6vO5t=AqZE%Slcx+hqmA3vL#&1if z;fE)LYH~Omuv;5!LT)wj3(SI>Xqys`RMJm`hW_C;_n^0oZZq)<+LXALCTxvaxi!Ek z@X2~m+t|5z1vpv3THqSby@Owp&%t=yNnXh(`TNM5gyYcY zM`M4JiW_jfz6LwBKG61h%cdq}9jJS~jsNPy8#o&{2#(o5KX48-)z?x{beK9SIKRI>^T>rO7Qe5~FM)}i2| zj-pZv@$}Th0g3G)a<24oC%!2^z_!rDJBgUw_ofr0;|uV}T3pQ(+6G$ z!PgF5ugqc}za9IT1DZ3Gf|q9%@4yFO!|MAE?$A|=jd{S^yW{wM2W6ZEW`R*HUOu=X zAGwD;?wt|+Me4m*VstRyg3JfWi+ofm^H-&2nlkyPtL7k=zi8?=66Z(a{m3040{d2z z?~bGa8CMx!p#>S&=osgJI5hnijlb9|F@t2BB}R#if$Z`1GLFRa+E1J>#=rv3TQ|wR zxSerqhp!Ef0r-m@$0Lz(lse9_Iue_6l=cs)tl{|_h|K5RXPM6@ zfGIlG%lcLxjLzqF_DQ~IJ~uF*^>P3C`Fz)Z!+gGBcs^(Tm*#Uj^SOxm{OFg?=d9uR zj8E=}`JBmo&hB4%u!%XHKRl;1%{jg7EOT0DCOn_R_K3f77GtL#wtt;%K5rPF&sk@g z&sogptS_C~K>&f{%XI8*p2S`G_~DN89pyLn z&trQ78NThFV&7qYBXd5|7MSiMW}^?8;+WVq9mWKo-80EI7uh0(wwLIt3mNih6)5xF zk*{@qJ4f$Yn8E&FvbC#bW?a{utK++xRwwWzb~Rm;)U_U6vNw;rI*{S4#NWZT^K^eZ zx>&Hx*SA&q4!08is`kV~AQv0i?YfH66&1*-WVXfLE z-y~g;rbu&Mq=@q_F)zY)IKj`w;HH^z#Mbq?{5J|m>J-m{<0$Vm*GX(x8}rVjiA`(P z&SUAS<_^0u z9>GHg=gIHM{Ris0m$5?^(rw{*JIfjDfEEt#dY{<_Fs%rYqqg&A$KXeGK|nR?q_5^?{{H~ubyPM4fb23wg!=ruP06i z=WH_YnZDkpRB3HXc~>@Z`D!jRd+8w5}TV6q>p3?rW#! zuiyEZ<-;-fqqwd#{Cl|f!HNFlv8o-O@kYqS{*BNm_IP}wRj7bAH0BERyrIF@wkWkj zOO^4>>b60?h2tl-liYwU5;ywb#{D7YsW&v zz$0hDUzK=H5j$tB4W}7cqz$2=3Sa?_P&KgR1B(M#fG?Dfz1R*c0ta+CquHdpaG8>+ zVH=(FO_ATpehf6QL;Adz@xcFWfeANr4ZHJuq*%kHP>)-|-ztg9UYb1b|D@Y;mW(7p|L4cZrYqqqwYKlW@e2dVe}tNu%$W&Z`8 zHbfjauWOywb*Hpgr%k~*d}N2v z>)HBy%m2lApRJz%E4rb-CfzX3woiw4h#ddlR`)2H6kBi~^R@{c>V3}G#Lo8z;HR-; zC3AoKscSK}gy+Aatl&@hOXn#5;)w7U3;bnHy=$-*{?ZD65#6~K{xXzjxXVZI7k%J{ zVg6$MCx7`TfB8@I*C>Bk2!H8Ry0`X+|Ku-c<*on2{N)Jzr5ZcgNdBS^JOqD<9V_84 zZ6<#S&;MBd(!w2|r)jvLTzhR+CiHgUhDdGCB)+QQ=j^p0KegR?xyRUYgXB0r5o zCla|x^w1h`5i6JfJ$bOkl!e3k>x_sVA$1EZo`@bHI!iP1v6H&djnegqo`Ow=^MfO0 z;~M0Muxy-Z>P$g&6=}nAmU!x(h|I0*#6n^XZCT4b*z~`BExPjTdyXr7Dw~0&`G2sV z0*69x9F51(`i(OpFA2^?C;QTVQm3|f{=u?SmJb8ir}HM=b9@&uHe=6Lp<^uVjaM@w zxc3R}MGrB~QO`k)WO zx{2r!LN|iXhmhNUN}MF=2X>obn*E=k*Ds@0?c=B(7al{oEBuRS)!bJ)3%>s|c>1FG z^&t2WJXP?Pu~4Tf*T>G`|0?aNYby`tL3_=d<&-)6Wx8$6z(||~-#dd7p;s9*@e39B z#HJaw75?3N|1*36T*w?z=!egPlfPHD{VyY7?)dW=n4|L}>dPv4K8ioB@XP2U`edxX z+c@~L*sLCvvk>4*XTAx}3b2I;&&wah^R}pwJkQ2GtWs`+!!p9YH2v?C^Khqj*rtcC zC;JcgVxJT{We>K==dex6e!1BB^oSjB4>rng;~-X%6l=HCowmdD>QR(aKQ@Hoo; zn1}6gsNszL(U~2|yW9vpo=tya?1oRWM=W+j=Iqlu#qNr&Rep=@ifE3fw_t1S!1fxp zx4vNR!$$3oa{uoa%_Z?k{Gx9^78$cX4X3gJ!5mcz0^5w8|jHT-rwtimCuj&_>K7<|F<|7lb<@tJI#{oz6IQ# zWG~y!UR~I4B&+*4``6X;@n@#(U*xbSmB9T(w2y5uE67)34@EseVhae|C)iULyIT1Q_Qc~eQ>F!` z;ai&7%^~cK!C8#WThI0Uk@|B})eP>MPd~|-8!1`&rVSqn#nn*IX#^qdub? z{p|(6G9L8T*UMPsDb0N+_uvV=$ljI2Yp~Hbp|NnhhW+8aeA@fel3N*Vvkh3JO%L=K zZL^8Ap@jMFU?k?0etu@FwbKt;ZK$E$w5x?vi~%%GOe^2e=Gq zC#zJ3BZZ3z>Kc}UzGm(phZV2GzcsX_<_WRm;$UnB#)<}qEy<7 zZD$PoD8_uluds6q%3ro|0j>ph$t&X{@DZTO_gSP5E5N__kw$Tx23~4)?kcz}Oz(dR4Q>1e-*?21 zOOcp9TbK_o^1r;!@XHx)kMQ|LhQFCTB!zrSocavsBIW09#)!Sq&-#ELd4v~5ZI)49 z5b&L@n}qOIlrdys`yHa-)aX*&d865pK-R`q(_Ps{ys zhpi`>J4N=Li*L8ea$&1~6B_WqyENtTb1vwOEe*Z(>}yvROno6o8ycGF;NADx(DV(I zJBd%B>xpu|=T|emiIlfb-IG&J9a0W@HqUrSJ<&SC<@e<1%==~S+yn!qhE z5f{QQ_2$5jvN?;8-D)x81vJ8cRDuzDEMZd0q`++aFDJN(FGS2w&i2tR=R{{bc8>D> z8{^s1@C-aJvsn7q%$SJ}3v}Sy+R#ToER~CZzxA_lKWgd6P=dp4P?tkuEu<*lU5wo{ z&L#?MH!%MNhjMrCh2#<5A-qKRN0gt$#(n9vOfvnS9s~}FXFHT|wVU;F!R|=iU#D*I zc@wzY(2{wdEbw{A-yca|7?WPh??00+b5izbd%+WZ;eIuI58%V4uh>i<9Xq^-yQREe zC;#7rQE2cZXz&p6X*|$iP3{>Q^gx67%})@zILWh--zNW$iT@yX%nDtK&!)&NTUZ;n z)Z$;r9;?vamRi;$c<_$SIN!$Zaz6|ae@5abvM01Va{sLOpv#yzRA8lJ>hE#{_ve5c zDaZLGGfw4jKVr_5YysYX2ks8uv2&*bxY?f{ma$IE?>X!Ik#$(^>`GZ ztYgu+<6-WsW!&$L&YczExg%?g(CHdzYY_Yhtv3HEJa_7#d(O0)cO?M3pEGW6$eN3v zLZx-;i#gc(m^&|;bLU6U{!Y%fJ}7*ccBM|4+ZuG=%bf0A5uOJVnFF3Zc5kpOybeFZ z*gpr&%XrK92cfsV| z%!NPjZeT7*o);Mhp)<)V>+df9&!=CEZ)7c;)cqUk#?Ov(>DlhPSPxBKFYvXKd2$yz z^zhg*PtL?Z-Dj?~Pf?%L8*O73bxHj;czc+iPU_x99$9P8tiO}G+ewo%pmx^PS@eHl z%v#&Q`l~vc&9!z7GOet&Lbuz8*IVKrE>r$bSQCYxKS*7Iha=1IV;f#?Cw1S#dfNbR ze+-y%L$Z$LnCtDW!|Uy&?uCOx8*gPD3&?zA?8M(N$ao2_zucUUle%kw&mNfJ{T}Un z87`u8@szB?Lerz>;y`!ZU@8kmlc__cM(rPxw)o5uV$&arxXlC9ol#k+GfWZa3!vGZo$h4lTKaN1vdenLTyPkcvsgEV<(Hi9w@*T+jC*XKALMMZ ztOZfIGAd`rt_jXja*VY36zhtL$T0%H@UCcok1(#Y@V^&1#_SvG+UUM<8(Bn-3FGK3 z%1EErL#HCUcY@Dv-b6X%80nAn!<5H}gD>rfEVG|7(w`H2`#J3kZ@m>d6y91MLx)lN z5FWcCLT3_>M)oT7i#UVI9z1w8{W-)x%ZY7Dbldfxs8Dcd=ym#r-&HO?8`(amj&B0z zKb)PKPq&4AOQwutj*Rupb9Tm+hW(bpF)5<7Ebpklk18qmFCXhLeY1rwg|6={=01n> z&|#AC@yT%DFYfTyIt)xg)|O`q+|?kVWm=W>25 zKQ+FnutedfUG}E5;ryAbMaWCg+seLp^X%FR;Iyr(AFQcGU$Ywij@9++FH_39obwR2 z#m*j^HaN4Ey2S>dp~F{zn_KYFslHhG1utg3z$iX41IWx9B6^Zz)$$%GBd|-kYT9*l zwCAvA?GDHuHFZYoS`ewrNgoY#Ytt_$Qs=LjKT+6Oi}1x^jll<`hI-qXKlo3J-_z3? zkHaHAPsPK2G-H_G&k7D{YYsk1v3;0>{YBsxoJd)_5pVi830{VI1$g?y&$xGzxc1LQ ze41)5EB9Z%YWd(UWP}=U+Kc~@z|xGoCgbo$eoeDt{hErwXTsV2n#8u?q>Vu07yC7h zsA~!Oq4kVk)7mWLaQYPGVS+31SL)R~8BS!8sGN7`Gp$Q}zjoo17^n)zsfzl0Ri7fZ z{Ob!E+}yKb(hTPlHGaGB0j*`eIO(tRWBj8SFPpq&tOnK6CyB+fo$szM@{3xcLgGs@ z{C%`vR53EaC|is8dPQ;KIXN`l3C{6EnC_>Z;c*Y(?`C{uc-$Z6Tl;k6Gvcm@k7szk zh3!*XVK^3w%r(wLgvL!}u3@LLK?}hzv9k*v?u9mbpoiz6hbWDRZePcEMd!ZQleR${ zb->A8(lhG7755C8_9Vp}u^kQ0!O?vjwkJ^!{A7mMlhopH-i%S>DfT28M;T8U%bhZg z*pjv|jvd3}7_lP(Lx=dW0sFBC9t0Ord~i0kJCptkE(Y1}6@RkYV#9Bq^OJb`*wD-Iy!e31M&YH-31O9QcR@99ZomXXbOg88J0mT_CNi)!Ios=uI zS-b1-=kln*S#mZ*+7vsNqYytYzVDX!n50SFqE|dOp1A@&!83OBQjeTVld)3FYe`q^ zvGfXmif0V5kp$t#c6{X6Cs=BOA4z}g#DkW*Dz}g?AKnZT67nK!U2>h}55Ic+Dt2Yms;`k80 zr=9~HlXd?iq{|qJ&!W(PJSXNqXUb!o4ei$ME;rBqh&+}h^C=>aHCKWAabbCkbCP}! zb>r)N3HvV#jQ;Ri^bo&2;HrFmf@!Cf^VDLe6ZxzcS*h89{C2qt1+jgN=No%7&;Goj zeo)qYkyWSF_w|Dcz+@OJLvCRQnWK4ZwZ{F!gq ze~O*pVv>vlI?=g|^&I49kGiTf5M!5H!km=x6T94OV3YDv5BETraMciVRcwiur)|!e z4O~IuwbwAt0&~!Ed9ljcoI|XL6g69AI5}Il8W>kn)}&Qy**1O)dRvErm>z}{lJNkNv_%jdkjrh?YXWS-qqfz$WjO!lbTjd)w zOnd;DW%sTd%G|8vDeq;xwt+kq`yLx(qHY!I%sk7;PxhK$rHvsbRCP#YKbk1^tnz#I z>OM-@ze@a+KL5&YUfM%^r50}*{Av2z;7!YCuaB2({J9bS+=(AIS$rJSyUgTI=3a8N z?wM7|^hMTTW8NUMQ)U&s*)iGU@1}bBy9s~(Tzqg*@o5W@CAqY(%n$hB<3a3vO=h2Lsk8D7Hv`ia@Jm%=}wQ9khz^d!GH>^7&%SM`|e z$7S+mQYU;f=#*<*&XSbEBMUOcHvoTLE8jy$N1`UDd0qa6LMO={Pn^c3o?hCGxtfKN zx8z#^|Fz6V#y-h1hamLWk9-4P)ertm`Vl!L?|Si0@~?hDTNv2K9!DxDf5u*{m4}BDBjJ6w}lJxIt@{|4$yR0dF82g_ZdoLI=T|k%UJ5(CBvR{|EM>5Fb`R=oJ0* zu&y(@SM0@;Hmp&jvUS#2Ba%gS%iCEayhGK2BnOlVINn+w_#nzQowkUkJSC;#ka{x6Sz8~^OJ zU?l&Xh>j9Ju)!DID`rp!A2#lM^vjLN%^Mr^i|`HWY{3gnX{H?SmatBj<5E`*eqLHv zKUn4+;z=hoDsd5_FH(`U2Wk5}T=TiV-hGW&+w{aO|s+kIPB+0k`VgUdb< z{*nHWGH?Id@IzJWc2U;~#$`I)dYwt>NziqtgonFji2V_!%x^+xDGfZ=HKhF}Wwy)u zP~{%a|Ail9d@gj`;Lo}=v_H$2?x=+?Kg!oGEfwFE%N=MdHhOC+DcQvk;`?k;aZ>2rH?Q^*Qh0E{%|Nh(cU%2)R#{avw zZ*cj7%OCDJ_@z4}O;YqBC+pr8<#ep1f!1v2Z(-6PL9#U5PnoGkEwn?j9BIoUrJ~N*E2+2qCle~6f z)8$>Q>9MGawaCgJQ|iU-$}iBu`}Z5zc{xv8VvKIYI=X%_7;qa(hM3{|?>gN?E%uV%(#XZJGXrhkR1Swp;7u7f>u zv5OZ)W~Gf(-3q^tjqoF4njUpVl-BT%J6N0Vn=`8FYu457K#$JA4!CQXD*a#f0g$oVUBoe!1kGi-d`tF4XQ+>HLKK92d zW}lSE_(*;KULS3)IL9ehzLC9lUhB;`%USA8pw9HGM!(KVRJBpa@m%`UkNEA1`uOyjW!@-AVHNMa+{tA{ud>Bp(LF7}~koG*TJFa5UkIBkNB zf?uyHH-fgN4j$5ZdO+8jqefsEgEi=7{OX@hGsc6G#~r7gX)WP>nWL(DB`|+Tzbtza z-chP>8Fkd48OdM9gBr9f@Ovh08v6YYjrJ&fCw8R70f^nHpi!Y!r{7T;h>I!r{Q#fd z1MIIe5ZYxdB=j%<`VqPopPJ;CbrEqqQ4`8#j{M#z>}l$x)9iwu*9gs8^eVpKJlZ7i zfbO#@JObV2@U0f7Ro&2&_xN|_$N9U>|3GzL!u*V!v((A|a5u(Lx6Xr}7BEioE?Iam z@1BJZ2cn|N6?P=H)&a$yN8;m?`F``@`KeiXY^bBugT{x<*~3UKb9hjD=T4=y=_9n1I|e=Q+hhZab@qKEmd6nFFjV(Ikr z5v~7;Z(U-W*q2o9e_Hd{R=+onrC!mwa~-Q+ylBPIByoZaIj4QC-$^^M*oZB$r68E&8tr!QXku$OlD z@7D&G3}FvBr_1@5uC&n+i2@@WxPw~T@AO=9nF7+;;{NhI% zDf}!j^>@PWBA@1C>*o`jDQ(k>_Q*BcqZnFO>~lBYnZ(}0N&2}GdudlGD>ik9yYzF} z@x$N`k$D({9-q_We}xWvK!3U~0lL)Z>kCG4mULE{(54=z!nmUP33v%wpO~t0mUBki zGWG)y87r{|Lc5&XRCV;nsy06*qVy>7oFkbxT+Z1M5+@{kFbB36_P)g0vhUN>ddA>F z*RK-Ka)dEyH8G4C3ue?DSx%cgA@z3_PGIe7x1m~9BJ=g~-f<0m!#-WoHuG4=D&xz* zO2)eEhc0x?x`7S>_(to5uXhVH@i1@~)j?tjkuT|iM^zPLru47jnOgm9r=$wvG1%MF zL9CHV7yp!xe?VUyzH~a`uID@?nZK-*b?>haEy?S|9#sh%b?aRC0z5BuTRMsQxl|lw zDjdK*I7_2^Rmb^<_Y1A|J@#@r#(#F9KV-}$ydZO$Li}FtT;o4CKqGoO zT6lww3W+BRjeo%W9vK|+`-cs>oP$q5sV>d)f7HaoUrz9z?#u~Mhpbhj%JV5h7G;!n zna4b%#VInesjD9rF86&F}j*|6b^19{$)PPG_9G-}HQJ zZ6*CGeYu~t?n3`Uhjr+jTKZpnBG9@%Zy|iR_Dp@w40Mw8RrQZ$J)5DER2*|yCVh&2 z2|)8wzZsk#;X{^+&tpRu#^&Iv;hB09e}Vt+|6+$D)$d?1BOd1g#aoV5}?U7OCF534AX@6`0FXbDP$o^pRj13TA zo^?zT>yxZBVh6~(9%dS`11R$t^hiS*YypqFOEuGA3zV_{`IvsTG}r@5-t{-rc(6y` ztIx?ABsPkFp;!KoO%ULmj7;J~uniWbB9FR_)2gDlbN*I?uWBjnDDAnlyD`@t+z!G| zzvUaRO&`w)p^qy`W9j1xVCj3gWc`C4KaymOw?+QRzNsS9lIaH-FU!2D7h6R3y7e6w zn+6+Li_qsR@4%1eWBmT*E;;woci`d6G+myxLkCL!d9l8#`O6%o-d#6rUlys=PN)4x z(pP!A)@_$PC%w)aw_n5aG33royRP3Z|2#@8tJtGXVC6zakbhv&kQ%W`Mdrvk)RtXh zpI4NzzW!aAxo-*dD&joOcj0 z7#wE;IEt&YkF|GHD$Yfae;$c+Rx#wVQ9kM)TW#Qm*Nt~mLAf=4Sq#=ffK_%0tlmwFCZII||6 z>kNCrq!nxWd3dQ2+OW%GIIEmF?|x&njAHEcXh(EuRQ%;77sb0v5=h%VKDxxc;MSVx z1qC%y*JAAbV&P;Y3)>LYISZ#pO14h zF8@nzhSW>yw1@j1#u!qkXzFIvD^jmlcdPSP`>YL%FK2one4fQf`#j^!x)N4;e zy$sw;a3}P7MHTKvUrN1Ln_$$7_>us6B8G9*;SA&(XQCV)&KQ@z9A8sEv^Q~TQdg_r z!q&6HziB=DBXiOBhX?6vD{~4yt{*yvz2UxfKT7@RzdrQkVgUlX< z|H+cs)<31}t^IdTyefU^quh+$Z{+I#j*9PFV*UGs8jsFs{_j!dzeidBMy|@d+ywkg zB3C`ky^36Q;AiOfH8jn<%Q=;YHrSK!9h3+8r=iny`A0uQe_22Dy)PQe&}w_g{{ys# z|Nqb)BA@vG_)pO(pPu7?zhys+bi|(t?uWe})(_qM;ko@!r?7TKeKXc1YQtU`&pkmKR>8feiYZ);?YyQR`LvTX zX&Gx$B@K6vq)F5Bk@H2?WRMSMZ|V6AHuD+On2*SxHRH*rvzgCmGas!npETsbn(5@z z)yyZy%;&nsd}8pqtt`-nMSo9qm_>P3&O|m-j+I_**cQD!(fZj4D;H?PW>N2zw+p^s zM)A+IVVk%wQSpVz9~k2_`(772u&Z}ot8#9}uGX-t+bwoa>o9lmL!A9IMd*@yX)5c? zKY#{1#jB2&M|LQwgcc8s@s!+-kL@DpIALy&j>U7wvi97d&xwf!eTr@^hX#8?r~Mr5 zOC~bLcn;d!p`y?9CEvZ^QZE1DSEIolhZc80pKjnx-bFd0_MI``IVBD018HLy4RN^l z?Nf2FZtlmSL7`LMs_d`!@J{HnK11j;GFEW-^yhf5Q#tj+)U9dv8fU&+^tn?zJb4uK znZo7b68hZXaO?E>6yvv^DxuJW?)rlDk{jgw!R3mxHxts2yQ0!}-}b$Z-?-crd)(Of zZgqT-$`xVdig{n|XgJNiFnaBbxByOWA$aBbvL%H2MTE1AnV$Z?r> zkh&~+kn6Ine(JK6e$LBOKgVVH{alx2COI$5n$Wk-!{y{U?7FzH47$D9p$)qi-XA+5 zHREQ+Xno|)I4zQUPZgol?W}g%uoax2HEu%hj9DGDVSVM^85-o?ld+Z1?X0fkL!898 z34JnVeNWPGPnI-&^n8SFXZ0o@&YRQoNi*{q(3p?V?X1hmhx1wWe1@3$3~S6s==SCj zj3YU#bu9nCd6bly`xq&+l*g^p?M)N3VPmMnP2bms^_Ke-ZCC_%q1!yx3{1sGvICv2 z-m1?jM~?20vC@s)MW-|Nz4;XMd#Zl0(4*+}Pv4-Wbay4b?WaMi5l9SM=Ay?ZY zS0{h}^}b*_WnV4XDGDJ*HfJ+?1;p-Hvv2Dmh`w)wH=Hj}y}`nb@!7bI$Rc?6{;P3fU@h zRhxZJ-Ew4VaVVLJEY)QyvNd%=KV)h@WNN>%=d^dxlGe?of3TIB2g@!b1MnsjI(TBpsm$kEf# zot_W!RnKR5V?IKgYmuWTp*uYv~o2HrFCYPeXTlKFC)+pBo$V5!zgZ96iB# z!Tl)DD&*^4%CTy$Hf*b2o+zC*S0PLLQSVjA*1hP5;>99U`$C&>g`<$E?8Vw;2lib6 z|LhLNw@abV<8Rgv^}ku)M9<#`U4AP)-=k5Eik=raDti6|@DB8RxvA%cE=A8DGxfa4 zQPKHF(CeS0*Uv(e@=o;rUQ^GXYNqGoV_$AX&zJQz^!%xx2wg=q(eqyDu^L+36{P1k z+4TIWA2-$WTb(ftdVU*vz6?EoE;K26K7fwjDS95A9%0k-r=T;@{i5$h7V3H)oo?v) z-nyPYJ)S$X`3m=u4(3Qj&!f{LY|SW|J?dKwZSLm2M77iPe5BAMHoqU5T;Z=D>h-s%+aDBpcuA0MKS;cE zux=N-PVCRt^!u~T^m|SS{hkw~-$`TY_e4{_r<(eGLm2(8E;aP~smyPw-YE{2WJ}F`JyX4~x zqu)1><_L3=;q*K4x?M!aorHf2W~XMHbR%myWA-HehppU;kym0XL=)%teKW1l<2Y=f ziTDKj^36DWf-jMF9DbTDwr@`28~6qMAo)Lu%-GDhb}Z?iWK7*h?u`E;xm*8`^heBp zY?btkzokrD87rP7->rNnWwWPG!9E$gxqhf;bL)I|E;h8qXUu8o1 zh8?{_MV;9KuZ@LoqIu4|eB4*5;4GV2?C2EUi9I5+-wE8;5s57_c2OjE%T^XU+>aen zhz%k(_llP6Xy%&5jy~0|IiF=A|HY1Wa2eygb}ib`r?Az++0n<;B@K4;F6?KoX-DtE ze)gJnwAj#MON$*n13NkyJ6d5!_riwG#Fp0W=p^iDo}1Xw&PxnF!)9(~M`K$zv7@n> zo7vIW)=lhaZ02TmG`4jUI~tq0nH`O7ZRMle(b&w*>}YIjD<9pC#%6A2M`K$zv7@n@ zo7mCV)pk4DS7-78e5UgNe5UgNeiu6r2%milO$*NmJ)SGy5Qp0(^1k|^fwkvvi#O1} z>F4-&vB$m4$%s8J=WU*t^V)6NlrQT7zDYew@WWPT~(ZhR-X8_v|Ca-asl{(n>nwob>#j zf!`$k5B2XPeT1I=TAuCy`6cP>-ybKxW90AVz1+Vdz1$CwukeR;MKB*6kKeHj9f7XB zbpY`i@$7jh`$9adTydX_^iBOZ*EjW}CBCU2ZtzV#vBNj@gTub5@7GJLVPib1oa6UR zPv2DCzO(dB(x`Ic;totgzoc`;aEZ@G<_p9p{uch|zoHZ0L?7;UT|DV;=+PUTohM!G zOq|qZcJGX?&Wk72I66;qADUV7rAnOC{m@-CU#N>Gbvv|(`Gf8ye+BofBXLqO=O)X% z@l3vPA6i(GbZ9|MmqT}wCaI)Yb;D{(3 zug|Y`Dr9e-hL{9>KPub#bTXgZ(0;UCOa}2W(sryNjv$t1B(a$rfw$lb`yF;MbGK7u z>?U)#ALB=0f2}FM#piY6?Bat@<13TAG;qbmE`&DYdUB{wUw-v5RKoyJ38P zYZ~(piZ=BZ1cv(x%7!caPWU9xEJfb>nM2>9+836=b0?v}k=Uhae0R##KHWclc3mv~ z(YRaherT*ChGjl+B|gSLxsK>U54KzkcFJD!(L`QzJ_rDL z*lMxJea>0qos4aw3n$1sWXa2nx2<&L#LmVtZraQE+Da$q?#3WH_As7at>=dy3A>K{ z(}wx@r;IzQiN}(*mHO>1@G_qEWGLD~?8H^n?@M?|@QfdcCyCVg;1%8-r+#wA$*0qP zN8D&c`abw4hdo~Ab3MZ)bow0aE%AI^S!chcqv{~>f4>1otW&L@d%wH2hbx_laldt5 z68Ae|x+KF_lwf;>(`bMyU6=0{mz;z_V?6duJk+c zPh}VLydFGviQD-DbVS_e6p3m4GxU;lch~jDiNlgu&|?yB=ujV@AYQP`-96UJ-jijQ zs1Bz$sH*NyY*=^pkE$x^_Z!x||2pYESbXq<6RPS@(BFsksw)2DyAK9_&wofCAjYw* z5BGgM%RQgx%eWuqnR`2Y>g{Wn9J~mB7wfTV%dP_VH8{E7rHFabYDLdRLcgOONhO-2 zdx_BSOT>8AD|`nY?JKP$cTpO1i6`j0(T?bnzc?dVdmUTR6Z%(58{sS{8ordv=hoUK z7R(#|Fqh_zDC$^HIJ}fApU^d^+ z9EH*qO16%5ZfQ7Gq*;?se*PqX$ds-Pglr{mHyP7u>2 zI5;ckG;wz;!5QCyBmPTpX~a68Cf2dZcf>jhZUS=mH0!pTe7D}f&4%Ys6A#?vyA1|z zHT->gTF`gDH*n?X=hMXbHTmw32JU5K#Od6i@Aerud^C2?%(^sV?c87VJp_nltlh1YJ`b&7lTU=!{D~^#Fmxz#Qr3$~ zUUGdpt+M=#%bhNJLMBcoE)U*lhfEil@j1Q-cdPXh53VG}_fA!%-{E;h zjIWdUUWxM+*u`9c?6WHS6jZZrTKHNK^Xn#-w3;~NYRV?D$MS9}@+-pCF-~|`5sO-V zgW%oi5Ar_Rl@J%$K{|PlEUHF6?%{omD>6=aToHR(jclrRMW@ffzbi84R`7qu@6EY+ zRlfs1`rk^{uunPm4^{OjvL|qu{P^y@Pxbeu)yTAJ=HE_sa#U?V7F9p2YFFOVcm1hL z9aRtAbH)18107Wl-ZN-@U_SqIb%+am$@g+!BF`7at+=Pp`al;)Rp~vKub1Zs?islL z>&G{&d+fu-2fut~!@3e=&Y#emYmh&ykXfsdMV}+5Xsg=5EUi{-jLwUVb7)_<>!zA& zXGF;i)=YajA2+|?jvCqfl$gwtnaH9I%5i3fDT~Vc6Kky^O0Zd2?-*Zlzspr($e}sI zlMCh`XG9Lo9)2a4A%|uSzr0`;a;RWrI!!T@sU$WYb;6x@`dC}&nRjx0KILlAC< zfqNNQbOf2w*T2S3j&Fr*6vd79?kg{Lt-2)(KBW zCb5@7)qKuAt{!N_K#MMwxa(@-m#sKyiT4%RWyq_8y1YUr4V}l_X*oRiJLE+gwEkbr zIdLzQxu_4J_bbrmQ4e)i~wZg;BaeKLLpe7A>u1H9YNRo3ZPbFXTS*4MCkU&iNi9Qmxx(=9MyZ`JRG5qBZix zM%VKlZRR`P%y)8QzN_JvsOt>deGBD^%8|NppDuOd&bWM>Uf#&UH2BBi)rM`Pu8x`7 zu%&V@(1zu4S97&tnzVtF7%zCj(&2Vq5Z#@LOwP0PH*J~;-+9sBOOV~7zk8v-tKX|1 z`s#c2gSWynzlCR_;S1KQe8jy}=MVU2HN5j$MEjCx_~r*=29yx2Jmo3UZG&&z#2f66 z(sbV01Lp{JXnW8sgoL0Mn|EP!g;~kE8eIDWy#`ZGaJB4rQ1mh2hGZ+J{=RoTcXRz5F zQF0Y=2K=w&UgjbC5NGh>cNAx^93Jp;WpZtBcGUf&k@VX}cwq(eQ<3n(&2onq#&RF2 z+UfHU!V^!z13E3i4>~Qu3qnhWNh9-SQSih@XkX_g_(JC;Pa`i)KnFy@6Hh|(dOq-l zo)3H>`Rs5&lhAq;d_nw_kq>;K=L26f@FX-I34d&6e7b_~A~h*9clctgo==26m+OE( zmQn`?{E^39!513$9nP4-rNkMm#=jzRioGv~B{NTOFJsu=_&08nJN}I^)|i&LLzyS| z1X`B#eIz|Tktf0T!6&jp?tFK%-1%;-?YpgfH<0f>k?|#T5{0c<%=3Hn`{UeYJj`BJ z_=6hpJ59fj-FIQwzyG7Jmy>lGF4i}&U(tbl#&Xtvqq3GH?^>jY$9aVf`1XiBdO{}4Zr?5QPn3{YmtgFQ-&a#D}h z$|>!}zur(X_t`^ML?q_dD{hi-kD$mkhQh!g9n$j~>-I}^8bJ0fr8K|#+T4~9p zzDUL&)Jf_geP^XRMH;<~_?;?QXJ)l)9&6I1U-fnjQ$A@&2mc+(f8Fw5+Hv%U?Aysc zD_+jzR5Qob%Ks@#7yV!4H;Q#;56Cm$A_EIG+QMr4;J)U&kCb*%vpRg6K9>J|ApaA( zkUlVJt3|pXjTc^SQZIB;N9yGxZdtF_8)Nl)iLbW0zWzbV`CzhtXsOWlQqCRU#QUDq zRpN%g(SI3w9e&f8{tZ37cBP*FS5iJ`DUUKrn=HkTwX-oTXI7K9)=5t*`vmFz?{gXb zFZA>gc8kynG^x`B|6clGea_RQm2xDr&P~>PNx!;@={O24tr(w|aj$Zf9OK%foKwas zRrMrtR)^id$XXqa21d^6a6B+_R)-USk+nLU2#lQ7;UrbH89B?k_9+oP;^4H-ERaH#>5j{qg7xRzN!&TKL>af}R zkH$ZFUSZW`w5nQR)nz=eRhP-YR$Z~$0{huJlYi;(ZeaeU!+U}Gmk#d-=3hGe z1~C89;WvS)iw++Gw(@_QaXf9MzYnM?ua*BXU@QNVz*hcefvx;M0=Dx14A{!Q2H48K zPF2};UYc^VW-h+eh0Yaz;(X!lkqh&;_vPN3`yL;A9I~fuv5JT*Uc6;}aq6CR?ghOT z;L9w<{``0;x>xce9&eI`Kjv~zvZt}uFG&6}kD@*^)}bdS`1G~qKc1Xg;)r*Yh_6WI zO}aAo((UZ1@(k8ec24E&Cibdj9ov+jv)_eE@J;;;pUtQEDBhZ0w!WIVpd;*;8ekt# zjkT1rcj_bfr#(8{sX}n`oz7C(zs<|L!_H3nx(dtI4xY z`CNaV$us|NNMFD+|8IDn%QOFPc>WpB{J-J(cAoivv?<3V&j{)+`b1lxo@ZU7t`GcD zmc{D%NZLZ=nf~mfA1O=2b1~0$x>&`toi5h$Y^RF{dA8HVBRt#b;#Wa*@mLUDl+kwf zzSzXGy)U-%Z10P0Jlp%?X`cCiR8m$$zXz!I3sU!I!P)y|dr-gpIjCR!>Up=lUv~3s z@0Yzi+xuld&-Q+KgJ*lcyvZ~FZ|J8(>Um|#G9`WSwtC)g%1iw@pq{s6rv7}4XZ|np zRDV9nGyiXRKFc%zZ+QNQXa3*t{29;uzu~!tXZ!!__&@SbWSd;Quv<=E)U&S7by}r& zm4C!|L{UcK2Gb}-In(p9Hv<=Q<#T0nMJ1`qhy+Ka)X^2~tUMVtsxBpAY~_^4##WAb%_!HPq;Zv5 z!~G*tUNh?I-``8Gmz2>>xfJ&&D1-c4>bDHo3G5~RQC!OHspM=wutd-kl;hHDRHE_O`2H`>3h>_O&OIHQt191lvm zUW{$g>r>cYBE7egaiOECmvUD1Q7+v!(0U|IE0*yu|7Sdaot<)~fH4FyjvZuAN7=I; zdtoZut{ynf7*qB?x_PnjfBCn3bJXSQs7RAS{v*jhh5UP&`HPQO_I)?(fvx6#Nvc9I z-y}9bEqg3{#=a`DpI1-DbMIfRauzZEVm~5%?s^D3_FQIM>5sk~TPyo+o$MPi@ASaP zd1r@4&HG?v^t{gO@8Z2um43>e{s*1v+3Jf&RgI*L{rEj(ysF`wWZXNrnlZ8~QpV(6 znvBT<*~Z>5!}NWHk_rc0#eVPX<#7%BSISsDjWv-+__o;mHj8ofXm>=KS8;9y|CRsA zzvZ9oi<+~ZJwFS&Xtm>qsApsF8Q`Bdkml%u&7~6SmGfg_$a1`MW-V~~de<3ew8~`K{ifJam9qazUboCjX`h+xvnsbHWoCQ3j?3OWJu|!TC*!hHlE!AQ zOv=hmo<26aczRZLm+9lP$4(!Yo!@l~_%YeNlSYFZon6yyY<6bSxNMa)KKt&jqq5s? zNf?;4CE=EtNn^6hfu9HNLEc|pKQ=pmx_mn-Tk((o+Tt15o$L86o?DW*-hVP-;Mz?I z1LtrRY)%;X3%*SRe*PbM*-2bqKACV!;pT)}4sP}ge1@y$&Zx?j+{bdIa7A!!c+xX) zJJ-Oq{t?vkX|*ZgmY?yymUs2!G5_y**;Bbr974WvWpZuiD%|Y3<;y222WhT-(D-)q z+qV?WfA^N6saz+3_i$x$75*<}A&;cPw-kNI)pL_);8l+p-@GRI42-Lke+~VW@hw5l`Og@)WrUb6Lcpk>}2=#f6OWN=9cke7p;JThN zJkOQ<_MJs{aUaH2N!f-zW|Va;@IpV8)aKaehZ7f9_kzM_1lF-x^r%}*{|mUBeapL?vA3* zDO)@8y{PUM>Mw0kSoHZo--y?Em&PUKm3DfBYbsYU&q7CQ!Tq8zul<+58(n$wO8qRYuIs%}=%m)yJ47Jn^- zM)*$}Y2)e&i>i1|;9oD0ue3oq_ek3FEz-N|W)>A?Feyfw_`118`3qKOCzHR__ovtV zBKrhzC;Iq@cl{!J4rvnWZZC=^-;Q;+6%}$%g8qpF&Q2h&i3{(|UPhXB8TV)Zr64c+ z>T8x|r`)wHdlm4QYkr;mDF5xVXjS%vj9+Ab0X%uw^6b>BS7qnTp}Y(3&;H?pUt~WB zJaOUj?4REC>+EsBu0_AhX7(ogvW%74$qQCy&lvV-ws+y9*>P9@GW!AkQ_Od-Wh~7e zmr;_vbHUQ=$c*LLYQggCC$3qQ{rp|4vNIQyWIvs8U-sq&_hnx?Y;Csdc1PvWj0dt$ zEO;P0AyHLsy?Radn2h4=w1wb$xGOUk6lXuTXifHR@{UV&R_-DHi0Ft)7ypRPaaAh* z;ZBOIbg8IH(POd~R{vLwxh2{2@MPaH=*qF^%5mt*@$;;CSUGd((`kovpXyP4pP?=l zqL0M)Eqd)Fes6CV&UeLcZpVwC+)8u8Op|L*<1zOtGV}2g>%loFws;fse6Nlz?1%h? zs$GgcJ%aBvQw=M1Ds&V7(e*k0S<&ZS{LsmqJF~PwpC>la=kmRzpTK;)q<3InUBRAf zVq1*j9AbQ$_+`77Cf_)&7N5kryvtPWRPf|GSOYKLFQZN5TlK4Pwcab(lZ$%GUQD9< zol-|^3tj(@WnRFoejq+-@3LjXy~~z!t>9WY-11qsR8IMa=9O*N?-dweDrn00H<`L)!IGU|0xpN(ZNP2yG1_j)_{IXf*<)qX)90V~bVsB^5U zm3_GMG`=hJG@p}3!-p(wq_&e!I{SZGY0P|1lBSHkWjtTd`isr-AF^{n+T zmA3sKp7r#HjQ>7pJ%42UW3Bc4rjZ}9kT!bSUfxO03?&Yr20Brk8!E9&VpmG+Qnf3x z{2=@OD`Hf&i?9K)ZxlAOCqq>UEhx?zbaFOfXGNcKRz`JP6zP3ahhbAmo4yLINlcLJ zZGV(+6Bj(UJwWW+#S8AJQ5Pka+#a1+;@G6szQq2GtNL)Jc5&wHfQl~6BrY}iI?jA# z@54J6F;tWYYw%GNrCzp)u&%dzw9WJ4XB%PkG?5Fho{x#n9 z;5*sRjD=51WQDmfceBc5WzNcNiKpVhmvYL{iH zDK`>}%YREViKk3f&XVd~F5TX~n!ME}-}P$vsDnQ9901vi)hb`^r7f53`c6IKqzqEN z>*eh4MT=^rjDba0*GQR`5>F`Y<)FP}zq7^o_5$#2GW*8q>739veXz8TLUwg7+%NmR z5+mXvKfBM)m?Ph-%PU1(fXoNzdDy-^%RW#NhwdE5KEBd-w5RO7DSM+!yECIx>Z$$a zQRZpV<-8eVJW{Fe7w6)f35QQB{|1@InN=UhFt4+Wa>{*?J=c~^9eC<`ai}9bYn^xNepK3K{MtP9wjE4pXNGJID&dz5xB4ebDrLDj0#Q3X= z=maAs$6oIvlp~ciQqFCRDarhM1^5>KRRcmFc8 z{Kx~b<;Nb4EB|yB=Rv~v{;Qee%#RrC-^KhC=e2pJI)-=;M3f3o*F5Yjl~}|;ma8;C z45FL^(cSHvIuhDxm(3<*$dJ>-k_rvI$2kw3Ip^W%k2!y=qbl{b?_3ghSKf97?>mxw zRVvX}l{|mM)2a4)gTbkcKpm+tNHmnjMm6={e-HF?>D~cXD=J>MKpk;(O99{*Y2d z{n8z=arvH?*D2+yuu$8ht)T#ZAmtad8u&i-{fl*UxdqPMRcrp8U$XwZu_MTwE`QD|YpQ!tEvW{m8}0 zB4mDl$vowJPZ(kNq|gXmt*zID)WMLvBvN`HQ39dtg`tJv3A=-%UBIGefk zUeNrd)HmJXnwaKrQD0X>eX|_#afQ^kkh)4fh0r~5OeM>ipGpf;Xa5UrUuU(`sI!z! zL8DT)Wa?T-8(4Kl2UNJEzM6kw+AEGB`RMxcRR6-5T_zmuUs$d=hLp$q7Ygp>alriy z_*6FVXakP<5wO>Q(|!u_Xu22E6(<;Qj_&z7ROUfM50jCmQgnmB51x zIOYN1$^M0NDFeR64l%!U=zSyoa%phCbcm1JFbexwZ0bK7GN%`G7tE91g9c9u-G$>N zp}TOrlmgv_&8IAUKFR(@`ki6%*Fn~e8! zH}QUz@qYi`c|X^9-~R`Ed!6yV|0&)NHr}tD!TTiR{n{^`LnQBQJ@{8&-e(x^&qlb0 zY|An8xyn7{sh=6|CndUuOp^3#{R`Jt@!ze;2zgF%4PK6%SOYDt4Wh-7tRa2BC?e++ zeWcSOaa5uDp)4XoeAuPEv=DUaHgU9nFb#WLCeGI!7jT%kvgWulW#EL?T*ykhuJYEq z^|C1Z%Ej=#uM2u%c z8oMmF^tkX;*nG;u=hK9z%(8e#MHqVAUeEX*)AG@G7Eck=-M~|6j`&!S?Q?BB6{-!G z75q-yz^>1%cJx&lHpo-Ek&n7e*ssfX;VFa1URftHUU;eyntvkTUnqR_!qkW%PaQL8 z`zh#lE_6HF5kIjIT}J&TrJ>7byJ99S84le}jmSA0hHkwvCXLbG&1f^)#L>^exIm%y0TY)6tv1qbe1+6S&N8udLApmxiN)rbhz&APGt;UbbIDn{-_IwZgqR84diXvPuiYt13xn9_QvpZdueav?E*vIzI+jM`^dS;+xIVO zO1GiptrvSm=qQxD^=vnB&~32X4E({wLASxUvfrCH=r$PVH*ullZNS8xkGw7Wz<1))OFH1MdUU9ZL-HP8${BUC5ir=jw2D*L2q}y-sKRoMSDE@{0{S1G?YSW*9 z-?4FAhJ9Pf`20+mahd0OgH}S)?Q|0tif(^w;zH4Fj)@CFw>}dWif+qHTvNJ@)5m24 zSVw00MFx1-&mr~Ib(M_EzR$R9hm6Zi`(uFC9B0`d1H8>~o*hP62l$%f0*udvj|P-A z$Cdrrz)3yYVW->6;{9&}*EsHqtH`YiKep8Nez$bjmSal|zjRaHi>nA8TZ&Jl>DV$p zw$SDi3FYJ0Ty5{~_9?^Pz3o>P@9oolB6;vz@Yr(yY1fb^7W)_C+n@TvoABOa*g9c& zPaj+U!<}WepClZeLe5QU2#e15m-$L=8GWA<1-t%uT$`gwBe9SvpV~t?m(|&E>EZ)=W5X5_- zd>X#W@77jnOMj$)i(&Ivb!4lB?}Ya}@44E1e$9KtrO&Tz+a8|x&K`vK-Zb>y6MusD zJ~}tO_v)X*>%B6Q-b3-8cbGv#y+ZJwC&R>r;Jv_ACN2c;c{>=mP`u|!FmUIi_q_KS z--hBnPqB%k9>MxDfDcdCZPX(eSGLr|QIBAp*Jt2D={?U91J_8G=cf0(4_!EV&wC$r zY+`eMH+s*vx9xe)|DwrzpM~eW`2U9Y4jFnce;vH{=X2A01AZA^@A7#4aWHs4O}SR^K~+CcD*O^^j!3wHp}=n6z{2TnKv&-3#ONALOWY#Y5-w!7_lFR;_(y|=^j zUjJXahLqPB{|Z=IgO|a zv7zmDXDFLZ%QR^IQoaqIUsj_`oVPj7Z`#(E`kLc>rfq#`S#z8=qLKgN81vcV(v)d; zH}YRp#gaca9rK0q(|dl}7*|oqShHas+>GbQBc83$7FUsv?rBJ4n{&)(K5>c6IZ~&v z`B1lT`AA<`u~7~28I1X7P)2(lv)GfVR|i*IALbJG;Ioi5?lRB(B6}dMVEk9ioZ<_r zF|MnRhjVIKf4_&Ax3Sdmu*AHrb>)mDUx@{H$<_wDY;C~4TBV1Hc}wxCDaUPTj@Z&1 zCrv$R?EV%j5ASMM&Mv+yrfkad!n$H&V)B$Du8e2#vn)4b^8!C6zMB10PfgQmS-Up4 zju`3dRgW`@*!TeZ=jFO$&iv%z)$8O;=OeDJ6_2^PmTY~W_}eWLh*j-clIG~TFF^d} z1Y%VK>|^MVSXK6O?H$h=G~!i#?TFVV=GjA>r=+`{cw*UGpqg0B=OhM`c+N+NDV8{3 z$6Z6V_f(06YoGasxXr9`D~34lVy*TFWl2d@<$2v$SMb0@;zb?hN3yiqW8;VojvrON zEZ$MR(~K1@yVyP0A@SjiVRv3_oKdZxjeM!Z#=fJ+A4`1b0Ll@_Cw`RjN<68=l1luj zzNdl2i`(K#6Nu9eP>*WL@w0d9AFZbT4&~UF=5Xlsm%2!uq%Kk?dwnWpFC5}ekC^eN zR_v+EiaqsZ&Q2!gR1teBai=fJIz-}4SFy%0Fl$_SHSIo)e|A+}&-f;|bENI1pGML* z*EIA^clxG#$*6|D=}zBt*UJ`T_DwhXW(<4iNx%4ME3L25C&OIb^*G|!iQTowYd4=j0x(;Uuy(ub#}DPqzS3ny>-Cg*?|?M(@jP^u7Xm-(d2@Zd)3Q=0$eww)n=Uri9I> zOic-wk6kWUWl{6cZT#PeFL`m@M)=ALe+{6n{Tt#UbPKf_jOslK!S ztL^HmA+Osy*4MWpsJ^3HukVD4HmvXRe?fhHLG|^vUf;AQ+OEFpuC}kQ|K~yV^|fB# zn8(_#zS^B_Utjfup!&{iy}qX&X}kJ*e%AK&^^6Ou@A%g1`|^ElS6}rn&_~+MLG|t5 zdVR}Rv|W9*pR|4d`hFBt--OodyLw66)z^1J+t=4WJ*d8kt=D($@(f zzJpq??}S^weSKxEgRE~@9%kNA^=^ z;#tcJjM%D|>FWVvOFP<4On0=4D|ED*R7ebVp({?0!G85iS3}%#FUAuSu*ZY_pfVnq zz<3~6#tfPYzfQ$_4(n8W=a5gC_!7)@dgl1W+s&o>5@b9Pysp60)$j=|XD(9KLsr*y*!nq??@M)YeW!6*c3*=P+o2^=e*82Q#m)P9 zwI18CkM$C9dR^8GWPM1P;p>|`=bOQ+>EjYd4C_N;=;N3seO!64X&(pouNV5tqTi)& z!>%v#oEn34kF&z`u{XW#``9ZqDt+t^ z-^b~%8|#pSpU>XVdLQ5Sa_fDp5-yxRR&lNO@zF$;*jD3ZcC={o@uRA7>T}tK-y`(8 zN%0SeJm3CteV2IlLCfNKK5$#r+Y{gRdQ5$M?)AQty7r^aa-PYZAJun}^>1?&>xh*2 zf*RMz%KF4Zq!oOqc(z_0;^LMtCos>pK1cLiunhE_bvDSruzql4U^qW`Tl&*|C!D$t z6d5S7LYAHrf4XMsIa#A~K5eIk zblc0<9Ou8n%(JXH&Z5mwHn%p&_)cVzC5L1$hjUpI>A&^Dp<6Y#ZRpm!v+e2D_eYa% z9}G{oaStGGZ#U#^%qr-1`nk#5`xZB)+fedWOEG9Al)P2RCJwp{mbd<%CJwp{#`zcz zNIY6PbQ_FQ-3?qQdFwaFisvJ5HGDc3ioEsxkTz%od8@XyJ>6>MCfyDXPq&j6A#ZOq zV?O6Ww+qfq-VV62Dcy#Ww;E$7p|Mc%R$XM`pxa=Z(%;U+LASv;ANIDMCv+Q((-{8< zE|k1gu?FtEe&W#>wTo{={E47Nw<%Lr`wX7khf18^7iHF(Cz+nl(+xU zlx{=GTXocF$VRQXZ1h)~IOsN5Zu$Zy4!RA-X@^Z5bQ_FQ?;5y}^7d^5cV6=LvI~c9 zef`>oZq<^ur(12YNw+7%)9t?Nkhf?33;Q!hKbi&IzTscEhV?CC-{vzGpUv8`LiVb$ zuPu{t*?kjTVb{0#A2Vnrl)Uw=H*wHyGr76W#6h>gIQ5?<4!RA-`F>&GLdjbVc_FfR zc@z8g+~R!w5r(V|73b@7n>gyxEMC`T;;2V3PB~2+^$5oKm4TCb1g~%L)f@F_w9#WL zHU!1_hFVt@!1nqs{Q=?^xevK+`Sq9CVi6nmV54qf_h6%rR-B=ghlja=WleNO^YtzE zv8C);B72vF+ds}fvF&{#+BnlE@~p*sE&D{y4uSW6W!O5dWcHF;Y^-lN3-7h$2NNII z0Br1V>pII!dJn~W-iJ*d@;2uo&qF4T{tf1@!2KqUehtQ{2Mk;&-t(Barnb&GuIt1{ zCVU%;_q@kV9Q6q1Asx#;8~+T&d)i(T zM?HdhNWEm@s7El)|DuVb9>F-@ZUYxe?`ba>IE(l6It1yxP-_IrkP(xRA2KHzc7HhP z^8a$5xd8V1j3&I-T<@LFT!6Rhzkv7RP2T$`Jn!|7f%iT$^xn~9%#9v8H@){NeHm8o z-D1#5DBklHnK=46n1?*`Oq{PdE>LLV%9`UmvkhD*-V4k!aOb1wcu&RXbBdEca143kZF61c9(b>YZ%n->u_tTH*prFGo>==e zi>|nDk2B{ebClK|9BCdkB_{Rdb!qIuF@cy4)@R(RO*QBwO>2(B%Gc>R&D$L3|AC3~ zHOKj~OcwKF;_X6)4ycazGEqkku($|f=vQA<^JlI?h65o&oj}@xeiF4UI7QaeEeAiJ| zT*Lm%_PDlm>M8My+iWpUp?urwAC88&hql_ESv%w~_Gczu&DcA(aew9sL2+%%%Z+`Q z)2aK}EC1PIT$|X`^PY7!#4d)CE1nM>ITFt(He5O~+VVN1*nAG@tbdgK?o;5)3AQwu zwlov0eOckpu=&8J;qnoFwR{&=S<2pX`(#(XIFK``AXU^|5cu zh118r$J?%tRax8jvG!}Tk9)M-$FirH*dAG&5hUjp2p`Y=s;*UiTsgD#KKB0p!s%o0 zZ`-bq15dSmAA8EpKF$f>$GtKg`WY0`$8l%tT8*oGAAg6%$D!t&{c9WzWB17|*i(}& zdkUM2Il~6K%o>;GvEF12Y4r1Wu(`tKgUuB#AG^(E*>?VW9s1Z^Y_8VgXwPTPNL$|a z<9DCW9KWw^K7P-#?*+=b^Zic7@5I}t(Z?@Lb`Ftq9eOc-FWGFw(atf?Xt1xd*L}S= zI-A7Nh8ja?|4Tb!XNU5gDQtfoM_&i~&irqgIQlpk=fj@SzoT!1ab+e>`ZRbAkl*^Q z$@sl_JYpzY(wF9JurmhO=+d&$g)Rr!#tY@PG>_ZH3+1HQVeY9CHXrI2E+0GXT4nL~ za_ZxS#__!sN85O|h|sNdUXL;MJ%>2jUpl^1zqj4*G{bBo^$4GIw>i## z!o>NS<9x?W9Q_&`AEPnG6PlL(437U+jGqK|KJhWC(}m+N)!N~gqVJp2?f>m;5r6T& zfNqzWbi1uN-8PH=PDkE8XwFsihi-2-;t^Y;TRmoaKvTL6DQ^!Lv=UO@{>8*Wx508# z#&5bzg>Hj!zSm3~blVK~Uj{Ceyw#pIa82hbn#p2BvC!>}=O%9}J2s`;Q2p)4{ulZSC2xJtm^kRR zncOt#FCDrK#wnBj(xKa6oNtqnXDE5AJz?O^N8XCBYa;a!zv90;-Fopew*}q$hPFN3 z`UjhIyC6K>PI4e`A2Hhq>6dYZ#YJV$Np*TgwxtNE~fk!+xC`uy5Z#>1Yzu5Gr<4jWuYc zKXNMgOkDqH69?S}<9t~r4!RA-X_|?HZi8`N6DM>V&%CPr3|^m!YbtM>$MS`&hsi4; z>+x7C^;q9ZJ=V2c5A~l0E>u1Ij~ci}`;|KQnx0!3st#WNck2&m%Q)JyKN)@ndmZg( zG+b()|5wQQe}(4xe{E>Jj{1V3C27dIZPOmMt`JjdXc#dsS=r>%U976W$9;ztk-({ZdD39@ydmAM$KQ z6TSD{#PazMsWy)%Qg10Eo@lYfdo9PX@81RQJ!aZ#&%k@zjaa_ccyEd5J$&ckV)+z0 zUgsgLIiL7FCeGU&=ROrDfjJ-e{Tk)axztp8wUBc~9*#aG`k5|FVIz>phA8K9}_)TAIlx zA$U*qGjSn!&)>(yh2TA3Zxa`S_q0?47mD{(F9X-ed*>Fz?w@)A`C7(M$0j!Cccb^b zkGDPVm2EJ2uO>Y2iH~L5-|F%)~j^4)%Q|CGNQY znU?omJL-x_fA?(5Z7FhK9)2dPEkn(7c^_5{vB|S(Q!9RVhV3ka+3ZWY#5~J@c!q{F zRvpEs(94>$r!B+gLtBQ+$KIA!S-kh-cc6?S?^=uBJ)eCk110J^_1oJ0CYdHJcvd5? zX}^jLD_*E^kJ;5hG1?V9)sSsDhR?G9D_^%56DEE9Dn7{8`q=--h118r2ivZXwfow> zkNs93|E%Rcw&MQQbW%g`^G$u{okkfjH-rq3_zhx;4xATV-_iDU_RKfwdR5DHw)WJm z=nGxXHR<}lTBqy#y0%W&+MO2;U2C_sPS^dEN|f~{li1T^GJARiuRnSIbAv`M1>axC zH|{?ydg5x%bFuVDC>pBz##rAnoAoWMacQz=i0F|^zG(gX{|gQJZ)kfOR0SptUKgGQ z*CarLgAE$o|LfLia6m-sH0a5>aA?q*-8v2aU;5ZHsqOpNGr{cRq?Y^GlC5)G#vbj9 z-ZtpICBAZf+B*Jy@U8LHh*Pbv8~YLVU2A-OW0?Hc!`CxR`>WkQ$jjU#{_x-HyG%0S zO~5nEIi3B$`N)w_djkodE9^-ZM(|LMD}<6Vba&%YeJly9~<_6qJlU!e8z#E+|6$8WD~J^yzyp{A2-{trSG3VQr~46yee_` zk5QLp@UWZ{_p4*|T_&6S{0y*_W-stq^ZkaS^<8!WA13{Cz*hR}D6^IRW*fYRwzkq# z*x(iPk(K^2U@J`mb+g|00k+;>N}F2mM*&;!|4d!2_XmKj_kV-NtoQE&Tko%icC7c; z0bBCxhxGXjQ+^c!Tj`HO%U1e2VC(%5X*aVCV`SZ~**^V%Em?Ujuyvls?oaBwq>z3j zZGINmO0ST;R{D#9Cz|HnlyTI1_t4=n)-}%3d?~edm<*5N4ZI=J<(1!J1<6A4A|ForF zzS(3^1F)6;A2#~`7}#o0pRM1w0$cBE;ms7zpOlBb7N5+0z*hQP;7qff{|IcQPqC$svz6x^Xv|7K#72kj+xXpu9I*Ik zC1tSwdl=Yyf0K>B?z8dNMqn%bA8qe%B2Vl6eZW>ZHv(Jb`J?Uq6lAvbeipFx-yhoA z=WbiOl>%G&ZvnRY>pkR#1#hs`_bMCzP6oEVeGz`K+P2&V-vn%>xewUN(`Vzmi8guu z2iyDoHo4u;Cg<1K-XFK6uLHKqFqXPo|1AQx+O5*okA7SGY^NVnOnM90M&0cV=>`I*{Ac&iQm4`hXvCdURZK?hmy z@36rS*}h$6gYU7yx7*+hTb`HM;8Yvj&4l~oD-~T590ypvv<%m401hg<)<$p+tGgQu8qOaI&X z)Yq;4Z=;Eq|K0FTfQ!k+I@g6-_ABT&IUVd@NrvPylsQ;#}=^KtJs8F zD&Nw{t(Py)#7p_|usy7NC)nVTHh72){@ezivBA|g_-{7&3T#v>|9&?39viLMX>*S4 zz1If+$Occg!SS{{oi@0}mgWN+?6bA$&u#Er8$81XKW)qNNgMo_4SvW5ud>1S*x&?P z|3%v1I@`ZKG2xcv%hI~9n&^vQy_{#_rC+OUyzsIO-eH5Ev%za^a!1B*R-Y}f!9_MW zz}U%3^Og^+t5pT^ou%{MtbbG+sRjprpw&8*ucMQ>@gqM_z-m}v znpUga>Mwz5s@69`J*%eyUk(0|U1~}qX-<(QEkga}6lr1{>bbxytu`@Ht6kb&tM#an zZ+VBS!M;9Pd0KR&g=r)==y|Bt z2}emZd%LSV&Ft=75>7=?TcKt5pppY8iPi%iGKkFkz3#aO0z%bi_wzjO=l#5Ytk1gd zb-32)x3242*S+qwdOiQK*Yl8G&xyUB&Apy`ddaK5^?E+m>v?3a=i$Ac`}cZ|>-GFO z{ll)ha!}v9Mqv>~x3^3A9^rL!(H}s-^FVE5R zufa>B>3`F!|4;Bdm$Jm(vzu{@_SO1c&$olgXx=4)AERzR<~f=-4L%ml`#0oyH2e?n z#%TC5!${Ks--xDpp64jd$+Ro_9D)x-=^qrHVB{Udb2P8;ff}Qp*Yg~$r-^5g$3LYV zB5MaDhc`v#uu|g{a<-DVhFGn!19{!|Jm1;4i}YWxJB#1HC*nW(NqDI9{)cCbx&L9? z^!p#a@IR~ETk2nSOQ0kG6 zoRs%;)_d~)8t+1P@#o64+4AXMp*xnk&Y-T*GmQ(#w~+CohjPh7{grubh)*0c#jtP=sTvykGo8PPfE>= zKPu&{qD(E=Qmi$Gyq3n0MKzW6(?X?bs{e@*d5xY2^BT{OQK7o_%ES9dm>TO+v|qMA z7}vP#yyg8q+{N5!Nof+ku_{e1n`KtT;YlhKu2sR1w}5AWzN~KWABH z3Wtm5z>h_Ll5}sM4;MFBRL_Fn)lR)SErXiwwhZ#O zzIc8^3jR*>pzaR#5l1J5!_@ z&sfaP4=t7^>3`|_9{O7PT*gKExZ@rboRg@Qy+|ER&?$)Z&DQD7ipdsw?e}Owt)I$K zzq`q=G}>^J3i1BJkInG%Wc5PmCN1>g9#h~Z_HhoOzNseP>}E6@3+(66THh^(qGGCS-X*DlCmyaLjRg*my~~t(H^1m$!Fp5 zlCOmLjW6BoI@c8w7)V*eaiKkJxf3Y+tYw%p$kq_WkV@m!@n;fYiIOBv%@v&FC2 zYbw~Ru_=G$pjOwX7UfjL6}6_fP>24K&(3(aXZ+=h)7zgLx?4?{iz}Hz_+>ZnQ5lY{UK4=HY%xw<1mj@>}P$INqD%+FUiE z#iWvRS6K#jSA(T9McM_t%bXC*%e(*+0l|H=jeWscv@O2`Gx`{RGcv~N{qRnygWw@r zk4ys-GWOqkFTB$d7pbGU!FR|(Ka?_V9x(F}81tD`s1lkN`N6NjqH2m@(BvEnPdIj^QCsnYo*{q8&#s73IY*NscrKxy?UsT1*xhY1(vdEfptTr7M>@AFLh zA~i2~{#yDy3I3F!g6$8)WeX2FQ?yU#KV6j9X&K^_I+iL^K>Bb%IJ}{YvO6t>0?;q^XYvfVUiA7)LrDQ zza(#ro_7;@cUjd9J`4LU;R_A8vZ}c~3n+U_)!dd2T%C&ZmsMr-z(4x0sao2u+BbBX^geHt1#AaI8MIcxRJ{*hS= zE+3!*KQgJDa1H-D82lzW*P?U2^`#%VXnX(GmnOJYnTK`fQTJniH3jxte241ewcG>5 zowUR{W8g6|*L+MO&8Eh;)2H&@1)sxyb_X)2u9#1(N4gY6(xyZ)x z?HlkV{0YN)=NjqqB-UuF0!4F5-lzufTeG4gq#Bl#EP<=TaQX zv}CRiW)9j{+}E=co;GBVFE}to3)UnJ@q1SMuw^+i{O3sn{mP`q=V@BVVNoya&R6iK zK~0^^oe$54H&m>+xkX#CyhYMfv*znCs~6_ZzL=()G|eR*D2cH=I7w~ z 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 z

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

yKeEUIbz2?MHv!a!`pxR%~ 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 diff --git a/3rdparty/libopencv/libs/libopencv_imgproc.so b/3rdparty/libopencv/libs/libopencv_imgproc.so deleted file mode 120000 index 15421ed..0000000 --- a/3rdparty/libopencv/libs/libopencv_imgproc.so +++ /dev/null @@ -1 +0,0 @@ -libopencv_imgproc.so.3.4 \ No newline at end of file diff --git a/3rdparty/libopencv/libs/libopencv_imgproc.so.3.4 b/3rdparty/libopencv/libs/libopencv_imgproc.so.3.4 deleted file mode 100644 index 67117f358bf457c626c577aed13b0273471f1ad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3529368 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 zν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

-=r>FkbmHY;B=<18L{A%1xAqiTGA$?~JN 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

E_p^$@4r!pi#4rV z(!0ud{xbg$64QO>pZqy-3(q{WeCABfPA`^qmRU3TT`bpwc^AuSkJe7LXQRUt zFY;w)ZZu~4i(p%r-U@H5G?^_rn_2z~HMerw&l znE%92v$;xEJ;YT!^a<{zd&(c+pSXAB*zh05EwT9Ro+pY8_mz8ofev{_ai9YoGR$6@ zbVz(^EFDt1;|27g5dBel<365;(buMcjVVi)ZZQj4m(i&zz&r6y=#3k5!WJ(+du*V` z1D4J>N#EJy8!Wd|P6c@@$yW-FSCelzI-|-^{*~mP5|RzGwG6H8^@|FRP2&8-i_uF~ zdCEB8lp$S_IICkt5n`F0a@v#z5O9qsz_bB(0_aw6=%YxET zy>eiS3`m}KG9Yy0l>sIHsZ6g7D4LQScq%gBE-)<_Fv1$->QLg@TJLQcFg^Y!Yn|_6 z=~45O^r+pmK{DXaxSBg#Wx%~)@E>{Rl>zte;@prJ zf`!LQ46!QUA-HEqj=iRwIX1NGT=@KioKU49PC5Nh5P9i0l&^JRC464>G$L#0%9%!B zbU<0{{mrx9?1F6(UVj=G9S$~kFg}||&r|*ZlQw+_yj1c;8S;f>377YCzFtqs6XI2( zJIND=GP5imFPZ6W^5;7`i|{P|{|L{7SLq+pS;Y5Lwx#16Grb%+Lo$i#5nd&as18dv z;eIydNlv*Po!|Z*ZpNYrzJk*6Z-gCOF8~YTbuT*@k$im{b1MuE&+ZbBE|`m6HP4c( zg}JcB3vJoj##)y{jbQB}u%&XePHZ6mQLZXuNOme^%m>4Ztup3-<0xflJX9WQQ|tP$ z>l_EasfVJJxrsIv5r11Wh4>2W4*}>va??igasGs5KRD`OT`K?Juz8x4^D5Tk5N!zNZ}e@S|tm?u@~R>lM*jkDUIGTi(cLpN`THpmX-=JR0(`IL1-`TSsKwNv-d>@>!XaiZP` z^QL;E$d2rhIC=3iCa=x~xAS(?ZpPkfw>{o=yVtd}J0DqC?cPBdZO)>^ZWzAF-d`=l zekd74$=zSIV|sKRCFdKlZ_;`mrN6dD{$qhjRrdaC%BVA!9edzjdirq*0hh#H97*1y`&A7!sv%!zu z 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

Fobg!AWDV6(D;XzWamVtkj>od@ypzYt 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%0A*vXCLvVXj4fzGg|t;{{4N# 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[?6OS(-num^woy4W3i75*+A!1l^s=ul2bi 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%0D&nUlY)h=c=Ag^(+rQ7RTQd@Uyo^5HcilSc z+dakW$p19!)PjRqkpN{5!)unX&#R1b!*3_2B2}98KIXhk%HyGIS(Hb{eKut^WrV9phx~O@4(na(Loai!pIS8& z{Krlj(q=m2=l`#EI*l(6h3@r>U^1tXRZk(?b|9bn?kU?_fNmp35FN&$+A>r2Y2(^o zhtVthG*o6n1NJl{tFphf_}>!v&a2|fggoYsl=DNjsxCQ)#A50i1?L%&@E_6w&hwI| z>+Q?V<2%o6)m=ogi3GfBzvV+4^qBNZ)R|;62#(RwEPZ*!8x9_e`~^*)QpW_gLrUvL03N z>w#Pa^Ldgm0DE66w3l&O3bxb0noach2M9s*^>={R_|fA(%i3%?xXmWw+X;*1eMt2D z?A^iEyAk{OguZ_dHt4&IVBuq|)f(9g`WW#$x!=KcyW!oKakV1Usk+WW%^sUAXivduX&_^va^mEtd_LqdkLp1xl)z`Tz3*AKQj+Wzc7)$i7}AAhdtQ6 zc)^?f@q)ig;sxk1MRzVb@K41HK1}!ze(UPg>bJk_sDAf`vf6ZMBKSc;N&-LFrMfP_4-O{qgH>`~ z#MN@Pygr^Y9rk@q><;lCBltnQMJ4QU#V?5Pj6U|bX;E}~FF~s$hA{5g1cuN!h&~Pd zV*DGkUXj2M3a+S+JqdQuX6X`N!oTmh5I>lHP?`9_clh7L5BN5|155+o1FTg{f5J`s zdocv>-c1bLQo zBm_rzm3R|JIEWrwd`$nVi6dF!2c-f%Y0rn+`0e?RMBdi6i_di6fvF zjB%!!M{tBr@}zI$!}mfQ;j3E0KQL|6DmVhVMd4j0j=*_gv4=^gGl3(#?N8zeJonn+ zN_z>8AU-ZG@EMFBmGeG>TksjYLUsMUv^C=^mH8Izq^k`aLGXh!=#vCLNMlYB{GbEu z;0ElR6LDr3gcx`E|{lso_T`#hHdu@4b zFJ92f`vhKKb2h&|e(!kn!jit=1ts`@*E#RR!}_f+UJ&?30xt+)vo3yt)gvF{1vh9{ zd@5cLKM|-sb)up+c4ASj%(d+&%4=n<&~_qN+kdW&u1eqqVvB3y1Fp?eiuePn~2$`W&BU$8;$sG10^`k9q3Vo`w zMB=1%-EDePJ3MK5zTV_yj>@X^HKor%R-WW*y0+ZkR6fq%G_-tcC#th@NVe<{=u$zrN!*t`{Gj7BW#6qKS zzR##zSY!-e_%)+r{@2;7Iok-&pJ9C6TAJ&#mey<@US#;^&otVv3tfNw>zT8?#hJ4w z4EGxwGo~2s;a@ZA)~>1f$F*y6S1i26cSeXFr$ z#4X0Y1yhY_3#S>G3;jmXEk%Y>_tw0=V7jrH^8e;wzSYYHVoMK#;G1s`p zx+?b{u}}Lpbo)ov1i!0WlWU8r`dfz;8Fz7ZrlQVHU8^54US z8L_%GHJgX5$Q{AjXZHLl#y!}w%^glTSXX$-&&K*^vUOFBbCarX8aCC~JmiktEu?Xo zdqs`yW%OEFP40N=`?H1AgEfyv-kV8d%*~mz)8}aQ%ZA)hb0=jOKkRFUa}#T?jA_PZ z{`b18b8W0?Qpn%UT1U#biT}=OH8tr0WE%I9+-3Z?k+yR-u(qPTHu2w#1x1D}CTAp8 z*J#)-2109c>-ewzYvdQuh+k5J4t~~y!)EXwYbAGCZXN%Xht|~CV&pfSyxdE3H}Fr` zT~?F6j6KMF@7$y6H}IY9J>;`=&Led%tqJi>`ZBFPV7}MtL*{$Zq|I&7k^95EFXvsD zc(MB{<$R3>N1eobi91tS*4@gOI$gQ6`#~LhMZ5k{dKAAL|EyO#=P;%=`Knto zbQjvm>cjJOS74<6k$qT!>+KA`%dw!q^-zY-6`t>NH4oEW9rOLJdxuSNy|_Sk?a7$w zdM#tR>-)oIxvCaSaWxF{xjxJ&bPXCd&9ybda5c`K>Dstpmg|XIZgn*+@VTrDb=P+m z-t2M@*In@iC9WHf=+&zi%yboK!Q4M!&$u8a`A>H(OxHhhESTn+f&a;l`Gu~VD9`r! zvnYe%`ugyNu9^`yy5>+G-+ z*MA~|TKG;aD0B_J>nXc`dpJv>C9RxUY zc9?%wEc}|QaoBWM(7i0z>%NmdKG$_PW17qFuF4I`x5MU<-%YOIJrnnP-4(e7^aWYt z57A$lqjGZ#l@YA2x z%D>XL`BvvU56=zAK--bSpA~r=xjYU(kK@BB%e|)Bb3eX1DYH`Lxl(@5W^8@j!CdM4 zQS2gQj;O}&$*QaR?bsB>;nQ*aC;jPvcjSu=>Vsh2LjT4|@-O_I{`jZ=-A=yt#JN3D z;5r03`%UDYA=;3lO2(n!xZ+Q| z7t1{io-8;neyiA#ZU%XLvpP9%u@(kL>_kMNP#a&6=kxNJpBc0|s9TSt7k$UF1EX|cnYi(J*QW8iK% z*XuO6?J3sFr+&`)V_8@1?l{Od&#A5;_OxmIC$fn61nt-{Yxn8l0nF`zzlRUa!)F*Y)j6N~UHnvErG~V;U>VX9XT4v=eZZO6TQPxq**_umlKmG4 z>2tCN!(y||&a_z~8vV$?=dH+mQ^YQCNj$%lYk;e)1??tA$$F5!m@W5Qw{6~Gtmm5$ z*KqQ?MzJBJU&-2Zr^InD|0mX}+Y@V5TOJr=9vEW+BP|4DJc;eNX=9CE--2ET-dh!7 zKh#ixNj9hj_N z4^ihJ-vYIjsY|mZEy9^&vjtBG5-TlHLG90{imV)XEa{HUrrQQszOAxdh!$W!c`t1SwY|SFjRim}}X2y_R5$qT5QQ z;ZQ4MtQ+F8MilIebp`9ms*V2w_VuLR6>GZ?`&x#6C%%h!Ef->6OL&)#zTi^Wm-u{t z>*{If1*W4HxbeLIcMm%7zVh$gXZy&%|4CVpjX4YLrjzJvb{8b&Vd&C=p2iA(btJ52 zXVN|@IzBRkwBm=nk++zWWt@1?cZ#e#LsKnNlxp!3sr;lDbQ^v`}a;&E~*VvE__@#v(fLap$u<*2R&F~ z@61ZUd~D7*A=593huy7YBtbm^GA+tJ;6JfG}m1N-!|cd(5Ix9Q4( z?^;=BIiXR&>5RzUlr{9bC0DBAa`w=0=EsCJvgW#470Vhch;8^$`rjb%6fsuspZd*yT0wuU;CUI(%jmbu zd0t+V1s0Q)lx?hQ)vO)JEcPha2iVI2;!|jk?Z`6rIjTOBciJ-A8kwhA-t9pKly@(i z^3g2qJ?4aL!8o+~DDNARGLXpF8a7^K$kG6xB{L%X z)Mb3w8IR~Mk=X~}=binNjEz$0FMU zw*xu5ow4UtHMucs`V;BMgN_A!i_EqjJ@7BhaaNrxv|pc5$er+x+|qll-0wqnY=%zAmtat8ze>_g=UK+-QpS_Wji;&O zv&?~=m4Vu3#@P#u#RH7Z+w4x~l`>8kJAO6L`2yp2BmJ<7uom3JOWe^=No^^%ek~0p zwSLClQ5lazWh^_vg3_G_mU{Mz4rLp7a*t&|RTKV0oY0p!Y4B;~jJ(ZwmONi1zXRm^ zkUiabmE=iYe&uq$NZ$CypC|cx<(d4pllKecQ%Al>&3s)>$y3TG#XxkU6U z%&Sh?GYGybdB(|8>iA3Ym3n@hA9We6p){fd=GEt6cDvFiV${aeA{DhCm+$;RBi2SCKpUm}s zlb-2LneXKvnQNPuPGHWpI2*u=#m;cN9X@ns}NnZ7K3ZigW2meI@5ZPJJiowmYvSFj?Dsb@GkoP;A-aDDSIyM1dq3VA^#?Gs9#7ZkfeFm4F1a`AnY43{ zuI0Y}-l*&2{V}tVPwY%b{(a%GSdGahL?fMUSIze+B(t4K8cs@jQ#h;%l^Ybf0n-b7vg2l^Z)-e zye!>Gop)S_mvQp>1$Y_Q{mXyD%l_x$W%UDS>%Tf))(T#BiuG8$A70kp2QNFtTqv^Q z|1G>M23~dwyzF!mFKb6m5xlJJuY#A2==@lg`hNf~bAgu`p8+p3z{^~hz{_0VWk%uu zdAtl<;8XE3qaR-8>W7!P`r&0RTlAuMnc!*t@iH*56|O&lmw|Pi$IDzvyvz_R0KClA z4=;1|!^@0I;AO5PUS{;e%Zzl^9^hrJKY^DSNxaMj-q05>Gy36Wt~%-rUIxx~9xrnx z@iOC6@G>Jrx_`sVJ`-N%`U~;0K}o#K^=IN`uFr^<4FWG4l*G$i;AO7Qh?foOgO|C$ z%jo0h@iJ`TFTl%O{qQo^I?-FW7tzQ6Bwi-{_pgDM4FWGS@xCNpCOQ?@XT-}c@$U{3 zYkTNoc-hCe*Cqb_lX%%B{%gqp8(#J|yi9yQn6{mN!^{4kz{_@`+qo28_Ak8qYv5&D zv3c#)B~JXmkC(Z?%S;S8iI=&+%g}$rv)$!fgIt3~FJ88WbHo0d;AJlKk%OenNxaOQ zS9?U4@AGP`% zzL}67UAbYBsy}40MFcaGGz9;We?-^Y!2hQzPqVg?bnQ;j-}d5Ve({eXa9}yG8cH60bb?;FEcKJm$|^p4Dd1+c$ooShOLnF z(+b+Zg6CyCb8feLInT?Dzu{${2`_W?!^;Ns!OL9z@G^7ET?8+4CGj#>qAki@e;HmD z1G|cXmqo#mPWHjeqTm36mz}%_UUo8xmz_-FWsFD0%4f&RI?X&^B)$I)ax)lXzL8u7U|B@Ukd)*~uhc zCVBlic-dRvWhcSQqTprF$HdDLG%A9o3B2rNKfEjoUdB6kli#H0Uyhf}J^k?|_!zgI-`d7vg0nYuN{##LI-Xy?9v^yiDpY zcv2}S&8DTLH2B2h?hmd%T9uqMZwFMGfccJK?5f=NZ@5B z`{8BO?L1y4-wIw9{cnSp%}Y6tm+cW>g1@zxSO&hsK6ys<^4BlK%TCylzb=87U7vbs z+3ZWa6KrfcGFmTQ_AF^hTmfHPJI6P333*U zwODTwdkgUeSBEdSoD3b?e63#RKAZE^ErcN7ijP3~CrlWsPUc@nxHi4iaHj_h@pC6W z@5C3O_$h4UUVIXY|2*-3CqDCb-~(@(>kcEuwah5zek~!GUSV{k-(hf;oZ(Mr&g2^~Z3|5wezvL!*d*G)t;HXf>>-CX}t&v*WO^lkmmM<@N!e1{*W;141+tLMwm2D^?j>V>_)?k~xi z=9ESD3jO?-Uow4X$DdOBnxVDWO@}UD{cZ8921e5oyKms`5I%ZhzrvoH{?~@jfVN*y z{;_(OtWnyrxfZ)2+GFskK^f!a40HB4o9CDNoLtGXV6}CNV$W3!n`Mv98jDc0m%^Ux|!WjhS-Y_{M`+o)1z6^Zh$vN5JQ|5W)3jc(ct=X}q4c}#ob9q;AUipfY z%bb^4FDqJsPr22U{koRxB5zpFJz7fH$k$nB=C55w-!aR9U&1Xy6YMY}H^@21h2(!X zHsenT?X;?^Zs2(u{!K`0w@Qud;5+f1@Hkg#2dV$I%0S+jC4s!1oCBUIHc4Vr$$D#p z#pcA0Y@X~1E5m18>FZb*#_E9_>L(3ifDPk&pl6oATEu?CnvUzl;s% zNz2fxcd)0873p1dlwp@rEwS0`Un76^fxja8H&mA9ohIO0CXc-U&K;}7#|(Ls{sH!r zi)~5RVs)0ip0yWWobv*dxeVhq`!DC*Lix^L~Pm5a(`V*ZseWoBwl~y40|}mhCRRK>d0?@K6v+8 z;<_JIT?S`C#3{o&*XgEBaCNpSK9x0Nw~hWJ@pD;&zNpzE->2T03ZGHVA(0uZlZz~t z$R6ygc5{Cv_Io$r+cj{_jpt@6SLA*CRAf0_kyQS>%9)OD3wP)H^tB)3Un=vOndi7{cU$xn{B5L`jpOIGOa$#k(hV!Mdh;NV@l@U z#oSNh-osp5z_X9*2I5kPE91Wv(|zoxD|KNbZ}_-sTxFhb!(Z0{{80oZl)7}&|JQOO zx|w+t9~P#cjif&>IUmkX5MN(%W?axVe72w9B`8AqIIpV^|6Z9~EnKsgH0HNfHs&`n zM?Hfd5jhvK`L>a!f7p|Zx9I0oF=u)g9e}67rjZ7a+6 zim%}H_(52N4+P;2+Zf|ACQZIT8NDGj*iZ1TPPt5b-jnD1!qj74uHr|x8ed&y%(*fK zw_!`ap{i`};-!gn#BQ(q4+fyuOF*vl;qBV@OH`)K)Fnw{im3=W{qaK<*wp;d@ zH$dO4s3-C!|2yc@i!00W7FUkRyFqhQy#Q9V<49#*D*bcak#WRvW(RR&qhljh`Wkx= z^Uj#xT1~$Y-e^|DO5e#OJ~J7Q{dw{BBf&h4zOeR47HMczBG+s`Qko}iy7q{dIQ&Xb zzHLVWd3DfS{GW-93bM`n*>3%u&bzbB@v`S!e4zD>f0Ou2?fpP5trs5?GQV$NzIhy4 z_RjCjv!9sX)B4Qsvj0GQ-#l=^{65~C-``|@$7VY()12GWoXqP*%IGpQuexc?`V}`o1UG;`21%GTNbbA6vaY2GE$~Sohy9K8LdKo0f^+ zG%s_6wT}-@1_&-3j2v-jF-ul3n` zuMNr;Fd6deZ*pCz;J=>4PSq;m+sMos?IU*3?u36od3MGAm8Pq(t(ZE?AbZ&n>-mF_ldqL7F-49{uJW*@ko9@~EMFJAs77?!2mgU-f2Sg(BcbWhn&*wc%A+$MV9 z+}E;n8Ws7|&Oc8UJJKN?z@|)HlNtA4k?$IN%GQ$p(EVE5VcYbkqjRu3!d)kpC{8iSGq*n9K2q0N9O;kx$G)>?E2tal6_PR&xc4qu6FIL?Lzz*ibMCpM4s8>7+Xi+N5Fot`#&YSdGkyvS&@ zcbx%w%`|13GkVJN+&zDwV3m1K!7HN2a|i2G{7MKj;eQwY3O_sdA2-T9(%A1&ggJQH zpG-@vkaLkd9ry_zQNg?D`VOAu==K`Uu%Ll^0D}A8g%`DBqYB=i9BJEUJ$i_YF(YeG z#nhLxG0BXdS#oxB3eGrXi!*8p_2XU6VLB*Ra0n%Svc^n#QXj*D>Ue<$u7Gaa-h&_GsdF{9jkk)0V+M97<@vC!4rUhK*fg9h5|pQMeM z&&)NPE$?I4_rYrueE)#X8~7aDU`5U2JvVUXcouDgj!#`uz){-T?+`4(>}yB=?*yyS zafBPd5gxrNPjq!1NBBGfM-Z$5J{`sp$}hzc(9Lulp@MSmlK+Tu|4gui|Df*BM&JN- z#(y5V>=bm_0J<6TS8}J+<3k+JxO1>eJV)A+rV0FOZks z4xl?cr26>QFb|48zm});leEK1)=;7N|pt|V>+Sc1qFJ;n?-0Bu=$gxn$iv2=l_9;R~h#`R(xYonQ)rF9^;M*vdEkpyLZ*4ALJv=?}pc4$&uqIdEs!jFbE~ z`gQkF><6vJ{<-v@*g%&#Zs&@q^bOcI{}J~SE}?J4&iSLSUgwj3Jo-4c!1tvzonju^ z0KNc5=RV2#_d~uJO&0i^A%-)s*q=6&ZZ_?K{^m0n4f{ktEgGdh*48>6hyjNXT{Q+7 zyq$8Jzzm)Si>Sc84xfL<7{6~JZm6Y?F9(~Nd6pR8+wjfpIv4L-;qiOm{p!chW25`|-nC`LTp;J+ zD|9{#59TSnxWat>EC){E?6~>pzEjbCvw0eMMlIMvb5?#G`oYu4R9n!^k1(FWn)q*QlgJZy5ZUesZ6ar|M9veNBro&tFLSO+Qbn&v(on%pX!;z24MS;U-twFLco78qZzSEsOJe zat~h=eTwUJ!8=RC~9HQ4w=*EF;Q=y`*qJLN59LP3C&cn|wyYcaC zp0d|rJ^!~F8G8t4vfvBJ4)nsq=!n0;eSKa-LU|1#FXbM=_^Qp4{kF*L*p%+Xj`T}7 z8B;E$tgEP-$XhbjMc$HniM*w#i$iI9xLu@Yfae%o)F*X)(zE))a1z;J0BGEO>&BirqmPHx% z1<*T0UmFUY2;bB74i&Y};GdhI{Mbw9JiDQCyDkf5Vf(m88H4w;oDv;FxwHNgePh5K zd1ABS7`iohJom(?e9T_ zuKxhLobR_+tuY#`hpB%K<3Af35*f(#!H`xLJaY)Nb$~XV`3LTcU=DB@jlR`Jumxyi z73-T}xt>046I>{syAM~f=DCtQgJJeo;fb8B@8yd#xkK$=k!9z`qVq83h5uhF&lj1% zgOPtD`KjEU_A}BQW(?@g9KRQ5fTlEP>Pj+vebwNqENIHllQ~Min@;R)Rw9cX zV!o1kAdi-`@Gbbozw#9MG>WH-`B~=7oDhDI%b2Uc$((Fit~ON&eu3Pwh&yeKG0b(? zT7#zd&4FL4wKqL*jB(nr!c;nh_8SZjl(HPi7hlCKj5=;{82O_oR{KO9=MG8iiT#%L z7h6YJinHpKomGa)T*g+6JDz(vG{)#|`eAEjplWqx7XI`Tc9k^fayL3%r2qOO_+#66 zH!^Ib{~L$#XN>Mfhl})&7ysO#UHAs_U#aIG?VfpvwXjj>Pn8{2-pcH%t7)Il&~ZdR z2_WmON8i%*9AwEK@b1FK0=N&n-RR5W{|&T@S+Pe8zrp;=9Hn$Ur!V=OVeTvEUiYwW zoYw6kLoj&XUF|_)@K^e|Lyge$H?=4 z^cmJg{~PKvbr=2~`iu*G#&rdK#&rdK#`Sm9XUfrM%F$=a|3{xeZu=j7CbZu8|E@l> z|8J50^Z9W1@1LMpHbL65q&18 z7X|ehWbePA&%om^S)cej=`;KPd+Re5SI}o%SI}oJ`hQiQx#<5@edeP7SM?d!W%QZ3 z{{?+U`%C)FTVZ|X`pm(523dhWo%!f<$_a{A0&q!WGS zQ=X?wpKUsAGStah!l$gYer7V|@9v}6$7`vRwS}|fc}~`;DCf&`)jfqYew?Bh4D z^0T}Vzrj`Sbt%_YHA52_zT-}yoK$Vf_KC=_0(9K0z+B5 zRO&_hZ0r-E8$Pt#urUw~KEs^zvsAE)tF`VktI6v&>}-M?vo65-smrEpq>G2TyJ?$YpJL19i}AeoZQs$P;^V6=&SYqF7>Vt)%$J` zlm_Z8*wdwTmUTyEQQv1hv&@F=!Fuo?`BxX^+xn_|{osg#3mM2`YfsN}6`HBeie7po zeP$l}+LB+v9a%Qb`pU8!tw+GsU%|aZ|Lv8yUX!f3mXOWA+=_AYNA1Wh@^*z0eyC_4}IaZtWGDgV$Oz?gwL-3j2a){Sk4*lH@{e;U| zPdR}Z?A0`?>ps0>GHYFqrZ3ZFFYG(p^}P!8xP;%?{VN zx{9BAOR`v>efrIwCxn*4JKzrkn(cw>>aOjLJ3x$Qc3jmU>Hnh281Wp9{Ze z79MeCFZiuy3Goj0D#JS@kF!gKZy1{=!ha5M$8S0JT*Otg*TzDkIpY<LvWa73L4@ zAL+TDv1^Lp4`90`P4mJm@ycm?mXJ@CR8t zyp%r>ueTifw;g&3^M^H*!x}&v?G)q>OC3$8OWzLhhE#Y!Kb;2*pdX(JjX$BoqqK$a zhGhJ!@E4kWnDLL+u&l z34NQV>iiX0eFfcn4R!E_$GBgn+3xS7^9JDy>~+Z( zc|!Iu$bN&P*QhT>!_)p{XpsL%f2^l`T?WwCW%@SXOSsMNxHqf6@Q>8yMe+^*u){z8 zE920;>*6?kJu5g4&(p4#8;jYD8KI8`qmetwy(J-;0$ak~l6LANVbs0k1L`hqWK(Hf ze)bc#GsYr$mXk7tS47U4H{&PcE-N!QCS34_noQO0TBU;X@*wteW(V(L!h$0AhOwq3 z`~w|D=4IKJUv5;o+;j_LSN51m`<-C@r_*{{p2z{NAE`VSe1=t|woCa;N1q$vQGR%r zf_Hffcd<@!l0A#;ZA|=ptD){fg|Ti7|296WzGQ+{Um|lrIqMhl&p+jV<-QhZKFIUg zL(su^J~~5v@dROVXGte=NeB0g$vH6W%GMnnuf909NwpnhpTp7H)E6^}w}d?_yNs#s z>EP_rW|8e<2(^z3`BLW@{NI0tFI9g^e=TJnMVMb8PjtJBp~)%GByw&*LJwxH?D(UvQXHCNW+%44BtrLL1TP*)myF?Dy5Z{QxD{Z+Tn zoa~*wl;&=;*Oz=}a(zjd-W;^SmFVpT!oCT;Jx`lQ(p!MOeE&?4CcLM5kb|yjw$PW= z^sDrLke{dN{QRfL0AH}aC~1Dj`#(tEGyb5ZwrrgaQk#E^e**7e8d*S_>oQ;{p0ww) zp}d1UJWZGFeo4F_zfWs+WR0&|{mUQ^AM$!g_oK|?p?U^+^Ht4%5?Y21EtDDL&1ubR z$VYf{_`88Lr$gT#^OW&>y0oPUo#-9mUuWRer{T*YD+?|5>VU;2_S<<&zD%X>bUF;q znc;L2SHizb82swq2KbHa!_@bDqj%YHGH16#D+hh-U4VaN!9UuIRa+0dzoV1&`a2Z# zVW^X{SL}nWTTOmvhO&=LX&)%6eQRU-_!xtWs zeEM9}XDF9(a8aKjPOlvCsK^l)<&`D0lbm0OETbb-hJrTrGVZ4g_G}^dUDRjpxQx6) zyxwx=h+Jgql~=w?Il?EtOcfnwe@IU0+k69kc!d6uId}r^`*{D9w&|VcUE}Mn?WGas zd2K>n&aNPhJh?AOBY!@>Bm0m>^1MT6hd!3_g=Uu0Z$b;={#ttYBl1RAhPsp<{++PD zH$C)~zPf}S?*ALp!>QAMP7mMvJJ7?wQ_kh+;TQBzm>yo_{c`m1EPN`+GoS}A^xzND z!@$2l56ej-^zeJi6?%~Jg&xk*Zx`v|*G*q0G7gREMbQHl_=}f$+|Uf<@~dYx07-wf69bm{X=M~6l)vS_Z%5WmV7oj_zu zUH(MxG*Z8?oY~2~AmMcfYgF5zhd6`AKi@a-+<3vY__wyc(>K3ku-Hlmat2q`a3aY|^8XY07)UQ`yUH>pFNZwFkcZ4KYMC*8 z&{#NPV6Q|`cWfeYCS%n3`tpKI8&!(G?x z`C9(?A@&&NaL<8}@WI^4p2HcQTJ{KUU1myO^13;Fj_T(=0Und>E^p1@u3WIGXYWTg;aS9+OnCh=m7e;#Aw4zz-1zqrH1_7I?$bra;>G_Y!H*#z{dAJ@_=SaV#YmMp0vND)y(Qe**htDq%F%xmwc9!j|&=;yNCosIlq+tmGY7C9Lv(v-`m4| zxSTHv7}Rz2Me;!Ex+I&kcAO)PMc%xu%*Guk0d&{XrN7hZ*7aZw*dO^JW5`{#;eWWA zZz=mIeqPhuOf~o>+X&{W3+%aag}(Fn{+#dM5vM;i^CD0A$4=_r!GBDkjl%z{skxb* z)L&>&@=7DEj6XR$%3k9(7vbXH7ynN3WUpG=F5^JA{Oj0debXO*Q>7p0pZ4r zL>X(>*KH+D?>O^MtSkNv;|!cBo^f^tnhwr05_e+VPcDhuxi=Ws7%?W@#F4%}MjHfW zjlRuyhWrlV7v?4MjDv;W>f9~k=x-K(OsHXmcB5}NuFJ}?IiQugE?RNf7% zhYegiLBpM0Nar1Ow3w|{F*Z_Ew9k@5yFPe#e$pg01 znIA3RpU=M5M8C1_BlcoRJ+cgQGYxlZU#uekgHg=emh#LS;ccb@!I!Ht*Te+(jTOh6 zH%+Fkld{S)58k#pjXj(*<|wOs%3Hp)TJoyx8@;I~39JO%=@#nMgM92oAMF9xEoc1M z4C>yQjA`K!Qf|~dts7fVbx&1pX?3voYK@BaJy?0?ggf7|O?ZlXuI~)kCNy$4_xz7+ z6XZUomFzo{bYo~6?p{is&UqAR11o1kzl67*F5RQkWe>9bO62%MoEwp{4sdVj8;t2_ z%4=l*)Vu7d+An3&{trfb+a9l6GC|7SL3vM6)-K9wpsWs4O1{ltbgyS`tE8PuTb8mu z_6qlW>h*jzdjj{_yVr9D!brG7rTQFZZ`&%)t<8OP$b|Qxx1KC`8ai*!DB3_UE81WL z^-U#yxE=0%fV!Z+RK5K9t`KlzO_((Rd?3gs>rYUPQR^+{Ho^%Y*pd>WbdBjv*^>W)@yz^A898Q zvMwoJQ+@ZI+#A{Ev@Yb#$?}}MlWlD@bOQ2${wU|!~gqo)!f$k zRoVJKOI+Dg33kLe!z5pgv2U09xTkChcPM-m%D3gCVEbQ8zok{LODGTd4@v((DE^33 zmyKUVnN`xx;rRDReCR3cPM1EV+n5N?m*II*{$Zv^l?~_o@ksV_ueGb>bwgD0Px`6k zhx1hOKV8K>;=QWP;?MOxIzlB|{S$nf2I1%CE(PvPdTccBOXWS^*JZt`$?BiztGiAm zccJTB{WtjJ9J|GTjqmY^DtQBR{ZsDW*vS1EKjx0QH=*$noY(BSLv;^ZW-dLtN#c(3 z9eqZgqkSFwwC;ZXYkdR!lYD9ZvAzudIG>F77MykVFyE;hLtCO|_kC1sXdAU`#r}^g z3~ihxy7lNTNk7JS`XNJGs(-leSf^?`&VA6a@S>x?LARw{m{ae40~~cTcjBz2Z;YdE zI-iyAeBkDJs_dxA+21AR*U|{T8yX?@Ps}S!DqUAOqP0k+==Zxch5TZo z6#7G^J06|tSlBN{{Q9~Vp-7!xq6ijy)3*Hkz=CVAy(i+p%2{Vb>A%P%up9 zj$^-x2%D(dYO!Yk?@ZpMV%_bGt%}$4eI38kx)1QZ=r&b04m!UU8mVMH9s}+Dp7ReS z%q`%U`Paec4_OE7le~XK8?IzUFc_O)xuT;zq%ou$B?@V6W}#MdnZS!vYSj%z83b6TiE{_ z51nkr7C@uw>s!nD&nV)l(KF9W+GE&D*sP+u_Kd#iyx2t8%k=d7FkjS18I4GEL|4bGeV^$D84-Z|CZ=p0si!FeXPAz^H8gY!oJwuC8u&MD+I za9*Op`7B{Myl>_G-zIf=+}C~TNnLZn`5N&b#xI`mPjD001)N>hsFrNP&J2rgXE`_pyq_VDF}Uf({XNgm_>ca?f0XxgiBnrPW?t_+n|ZBsN#+FSxk35PBR>gv?6|p< z^C)@TLmsDjrjq6ycNm{Zys_m-#`R8n#sp_A@fvZKe+qaM&pe*5@a&t}<@q7$ErV`w z<_#)zHfD@;s*DlNS2C`3KAe&7Jjg!}rrm6r|K*32hc&w!oe%DQ z%K3{)pLu>g>5Qj@@HvF-BJ2j&Fa(gFZ9vLVcx=)N#{LRk;hL+_gS&Ga3k?gveveUJl>$aKfA_Xc+$4m zvujefX9;xRrd>;jbBaFfVGV!Rq;sBu<3IH*#odnU8SgDD;(2bGx3HT&ngC6_FZqCh zzfV42j`0^R$sFhWY`i>w;T%BSpP=r4AfC{O#Ouyn>^TcfNdLPBjdT96_F3p+tn*05 zSZ77XIOq=>-Gjz?en48riE~6k$sp`WWVCORkcfAy4Gmf`m7X{v{=u5}7csf=r! z-^(a;PUqh{iu{G0#oVhs=vwE`@mCp~HO<)K%qFeSTrqX(gic;2AECc|=q8prIx=o> z-T)1@51rbgh%0pJ$bg=R_sKMWp=D4Jw0S-G6*)i9Y5H2{VcM#Pc2XIfv(0FtoLxGd z-^0Hi!`(>UPmy;=#%Sk!+HWd-UQ3L{DnmsSCjsF=bP*5JuSF_zIx9@Tye(tJ?R+>Jig2?J#R9GS{R$r zwyT}j+pc#OXKwfWJfp|6z;@8{W~SS7SH?-t=|P7*;|HDhJe#3fcKm~(rIEAyHbYX^ z%HQ{t$$W~QS+)roSN0Voux6H_o=Yh*sEm>Z(_INlKVLwuMYJ&{Bv5f(c8sl zMh|<^)(^xsj>vL6^O)oEnV*IrujL}2jYRfpL@&4j*=`atT@Lb@%rD#-?;C?WHV#>A zB68jcG+wD6ZQPCqfn$c2aD_{_w-gEE9(B-izhOn$bFrx-SqlrVLy&F zj3Q-ni`>_VOxPPXSkh$bHUhyaF8b$^Mwb<_cY@5<$^N3=G{Xr?71_J}o2~=SO3V8*9gwr%y*l7Dc^4fp;i3-68jr36 zvL8%zz$@y1H-z**)>(A@Z;m|C|CW4>{H^*_eHuK%H@>iXYZl75U&*Zo$b`#r9L zy5BweS<%bteND*Y|Ig`t<0EvVNWJfd2!GN0_RAO#>3u~JVWRh~4u;A2KL$S9t1pV) z_joW&*ZXEggo)m_H5jJreXOzdrW3tS=P5C|J)~o-mGy>=CTwpoov!!Y6%i(S-|vHA zy54tBMA&8Yz7E!@Mfa2O5TAo~4&N8OE(u*P0iEq+P-ja?LdQ!+ce@2WZTPad^f>SW znMdD19*{98vVb)t3#`v#jyFVE8&%A7?nFlxuc-wqrfguJpcAY-g z57{)#kl>U1D{Bn#Ixi@SLMCW(FI` zBwaSBKqr*{x*M$Ra_8zs67@Jw+25IF$b8ePVfe_J`A2EAQypua{A zsNu}+Ykx~Q032xMmE-_;MDP3@DF?tKdi_NX(0N2i4uD7WhDFK&#S#7@2l!;XhU9=5 z5n&<+Yzl_yazLakB67ep!7yD8xFaH+$N|3$hUs!Zq^$B+$pOJNp0ASwWc*)g{yoUt z+6WwKWL(Nzn;Dva#b4&z!4Y$BaQ^)lef|~OPlCao#Ri@1heJ2Gcf>70{*;fM4B=0s z7cbusJ3HSeIF;}xS?{<8`x9}@@4}lzew&k~?#;WIz17I9N5Corx||xsal&}yWNZgG zyqs$n`_9M=>yV?1RHEApZ|g86<{!c3D&q_*>nAla*d{~nn#s9xu~U(7--->^`!Z9G zDDF_MTy!BXCczi97cgp;w{lB?&0uwF@Hy-IN2-n@dv$Qe#*LgZ%%JFVi+d4y$@%Uh ztTEn%O#lmFxjM$#$Gsj|$bmfo2QqGUj9_+2zDJPHcY%}2{p1y|4~K8ZxknVUUnxpG zHjZ`}Mcceb+f1NsM0P2#sFZ2v_7tw_!@e{yx<}yc(O`7%(N=xI=#oBMwtpZt)W(u_ z3~hG|VM zvi134#4uI127M=p#Z5i$&38P|bRBrI^b59ztH9x64C%gVaJVD%QLH%zOwaqyz&>Uj zhntMulHvu2bQ_>Uz+D7Wp2w4W%V&+*+n6w9Z=>_ty$uQWy$#OF2ah;^ReMCo5`Hau zJKs0(?F3sG$#?v90Z(kf1y4-DQO}d(1D+o~9B}SLhfm(SEg={E`X+S$q`g}c%zLqw zwRfxYmazekwV=Z@px|>)HhHWfkENs&{A_1tfpa?PYe?4vZjnbmR^qscv*e$Hc-Eiz z{x`y|ryfsGkLiPkgJa#`?9caod@mxO#*6}I3GoFhdlOxJyX{WTKayu5b-5*Txbp?x zUm(xeg7eh-tS7$UQ!tSmoT&w$d0x%ir&mJ8=p4-Ocy+GKYD7oskR1F^sZu zJ)^1Lli&q{(=D})cP8--hU2W@`;kG{IrrGIoeeg-bH$*s&Ox~A!2+MOH9Mck81Gza zYjXAnGrBM1I_D#UTAXvhI;6ec9JIr^p7%xI9@8Iu(fQIHS)RA4@AHI}Y_E4V)xPL_ zi+_2H`fnv{2!0RKJ|(o7V{N@>LB_|P#*9%;JMSAZ7E;#{&iUXRcKqfJ`o707XuhWd zJ@W|TdY4M-+I_O8>|u0e(H+@Whpdp1-xG_C++0~BOl6Fx=35L=zC7GqXt9y8ZRxJr zpNE?djeehTzKC&ds;s>5w4smHP`Tj3^q3T1Be*fND0G=P#lJPd;os`q3NG9LF8nZk zJQcSNOy_3$WCm^fBitgsNANuxdWuF&Wf zXrLB)kiHX|%NsPzxgL8t6&b_9sD|k@IyGa2XBBQceF;4$3?t9!gPwzSpViB+rEe@? zQssl5aSCPz_UfEU|46^A%&4T?9OC6T&4bE4TL#VZtipybGMc*{J-!lo?-+b#D*Ui< zS?;E1z$=cLqLB9zdNH6^_y6?vVXBXH>ib<)H^C}f5%nq^f}PNQTpWw z^!HE%-Vx7wxX?l@{W*<#9)bS4bo%SlOY@SS(7fOzL#q!}iJo(0*)Tnx(7WIr$B}~s z?+_hp7x9N}3m5;2IyS(P{7GyHyG~_kbMxiZPhs*;Hj)k90Cv2gNdu$Ou z3~gB$^CH7l>SHs-$J#yeT0%%(8;QJ@;C>@HD964T(zD}{txjB`XV0kev<_QlO}D-@ zOqZh~^=zRf!Q5wpzup|uv#0BNcI?;c*$b+VR^=@pvMJvXuj|=!3~_&^XD@{QVncfN zfh2c)0?znGh`$J*xhBM4gtw%at-e#o zmhP9m3c_Cmn-c!Aj9ZL(ksv$6hkoGbUrO zg)u0)d_MaprJqLg&tZM(&5xJwAN|Sl{nx;2lgLlT-+K7-9Au((e>VQISoh9i|AveG z8?IU5@mFLB>Pzd~YB#(3K-_-&6--LgLc9gne-QyJ^Xa*i8!wo4)cUpNx;2mb-S$-EhnKJlb+Iw#K}iiEN^M)=`d|K9F{hvD{3V z%nRL9`QPc}DdkKj<+0?>=taw&sH|%e4)8lw~2j@d8i6^Oi?#n!h4ylY}i4`Hko z>+^kMYvVH4e&%~dZ7SnZ{;jL}?$%+;t?AGFmU)eTJIS~dIb<+n@_@&bgZ>Vl)wG+lZR>G89)-38tS6^MZ`o;=#x*dAEk8u(U55<;i zN*eYhv)G%R4Q{-a{>x#_C%}4PJ#plokU(O;ePYMl&)m0Ug*Dw0W7;J5UUB9we>!%7 z&m)&TVTzv-m#A)KUuM3X?f4j7tHsdYy4e)3-zidredm1kW82YfkoDgg#W|Fb(0UK+ z+S8#Cv3Dvqs;^<)NZRO~D78tRhpO*t-E53<-$MV`s)wFCz&VXY$Z2|hJd59Cufaie zjR~7TPbupR&OYg9;A-UjBK<9CrQhXjR1{-fv3FsQQr68zqgycQ@+#K_+9MfTy_uwO z$HD(=`95GYyS;>0AP;P2jejM3_?0#{)2^~J)j)fu^7E`7df^CdS!3$sejQ%a4kmxr z*ndVxvDVF4@`;^gIoB$81&G~sxl=`vx11Z0v%>A4UDWx)y7QN`Pw>3!K3ztGjuW%A ztW22?cwcWrq~cK^;U zcGP^E8J8`LlPq^I+{nB;jWJ}TeH^?;_th4d<0dcQY;bc{)twgxSIxhWQ#J2Gc2&g% zl{+s} z#l)OB1zsN+Hj{oT7G94X)GW#hrct_#ro~BI`igw)mid{6>T52XVji1gN_3wO4~zCDyC%nvV(fBtyzOq(GT-x(Pn{&;Ep4=;)Dh>Q=vyfl8tCGp2a#)p4i z8vngZ;^&9rf0<}Ix0Sg?Ezf#ac>L+oe`zu!-^sjhe3ko5Uf0@w#JRcP*;wqpAm0^% zL5pnn?PZ4aiiACBhX!m;n}eUoeInm=@cjqmy)E2_gjkA~GTOy0nQb7(j;U!Pb-H)f27m4e-E$@IS z%{`N~4S$NdH5)lm^pP{jdLomihh)To$cP&F)d_3geY$M82fHlnFO&Q0m!4X-|Ac8^ z{vQ+6tuvX2&(YV($Pz`&#WJVMTrBhONo2?mnTy{(M4wXjhs?v7{NG9BzS}up*}{A- zb$LT(Y?mZU!H0U#+!W zgUkxnQc}*|o-O%WH#_h-8%LTb<0d&Tn(fc_Njo6%>Fp9gCY{4t`68YYU$DdHNi&-? zFL<=>kCrFta;W10x7e#sl>ackmhH=Cf9z)dPv*sjh5R33Ina5fO4sG63f_kf)D{d$ z;wB8v0%}!v{c1|poxdusn*S?D)x2M++`-6DIk;@(sH{xxvD4+KcJOYw_f+Jlt>inH ze!UtwYX18Ttr}@1uE?e%D3^O7e1nmr<|9W%hDn>xLyoc|M`@H5OoRR-@-A|eR#mS1 z8Di|2hN@w|5?oM`RO^@U-n}?PaFK!5Hln9frYI#MoUl*ugY(=Azup~ zvz0bO4oGZ#O>2ub44AQvwi7JhP5T|tSoXlvUYM0_>hX(@Bxv_Cx>P7s{CI~ z=U?O>9zhw|byL5f-y-_A`6|8#scON{%?2}f>8QF|_)iPifZW;g z5_gVs=E{9CN0sfTem7ymV2Lqm#*|lw_)an2qHn(OizO?JrNVE20G_+?fo0&qeSN-M zZNa*%$qQ;3pKdVt>9`c?oP_=(Ywm)}_XjKP2PTqP>8?tyTv%nTTu@aKtyRZVR#qkP zd=0l9H%X~#FyZRa7F9hePE`*}Qq}o=RdwD#Rh^rmsso%&%u)VA!vwF>SmkxPl4`z*9t&ZOK_K2qTt3@h*61y(fHF2LwxJO({P{YkLOTtxVFY=k?X9!}Up|KFxZ4zG0rw zzU1+9>ZI3)yuNXL7&B6znP7@}@mkxWfwXgmRxSM%OMhADuPJ(6zG0g)?iP^8P1I!y zZBs#B($}l8Q4#Lz8v43|zOJCJE9mPQ`nrO?Ud?#j&3GN6qGrgx`$xd~1jj$fSe*=( zFZZ?^!QV{Wo9ck?lxGYqt-xuxkp*gugJ(iP(iq`2n*~Dz4{T>_bC2*0^vu#MnGdR# z?Z@tk&l?5bF({qyyaFA+Vlh|+cbv(*NF9<*j7=kBvq<%E!-LA?&J{3+Y9r&chx!ZO zd4;|+F=ma7SxGB=$Hdq*GIoQufL_-1)WhugcoTlgxy}4A-?{sbJ!L1r!>`3(aC*U= z_OQM!^3b2~!v@Jj`0YEwU%6v(;&A@W8mCPR^VlC1YCC4aYwyMh?@cINyu-~imw3+> zx_11iaP|&=yv4Z-djfBaS7j~SW7D$SQ2I0YFYS`NGAS;C{~GjmXra$5;^N@H@%sNM z!(Bg>xE0tp$Ql&w)CR>mU4s&wS+(kd{KqbX*}ZVAD*IiKe?E805D)(x!TPMBIcnyO zUz~#9e?rXO|=#_TQIKvZpGc*8hWq(R=PsNZRv5o$r>V)jG$d zt#tNDTkYHf|DAGst)`(zo@knzP!c&&!SHrjnb-{SmzYk!r~w1 zv%cz{U{2O1Ho{kh2eMzs-T2sQ__7JUyc)hdB*d48z?WC2vF=eF#Tb8-{LKA0_(gt= zq!YgUwP_hwQScN!?NxteTE?Iiz9Ro&9;8iNtCuTvwtRiLj9r-zT4bJLj(#jgt9~?| z_R!aLwYG3uMD?~sa6b6j|A7bSZ9#r|Taf2BZVPya-WHNp+TyQC3$M}Jg0vReqE=7) z4ch`9C2cV?iS-rcAq)*CuSwRbYx}|fLo|^{J6Ls^_=f$OrK%I53CYI_O-NqfxE%(Q z7Mjr0(hh%B+T2h(P_Et%db!`Q9fk+nAzt>7G5`6l(yAXG#QdkXL7p#)`S0Smi2ZsR z8x^F5hsj51VI6rjA{W%M4*j)sG&V>JdRp4xuSz?Cw2X^&Qm%{(y|C zVDS#cT-3Y(lR>rQ*y z1l!v=iE|a7bGPq@%Qnb8(qpV(W1OK3SPk8(reFG!k;VH3s|(t=(;gQbu>CgHZL*9X zHoi`*MR#8M==0tyt@weW3dZ$y02Zje~w9FV@TI_kHxPFfE)AEC%fJo7W#Vj2tO4qKo{Tjs_6M+6ip}_ve-D6*f-A}$3r$XJ;hEKA z-UN$tO9Hm^YK)~h=G}#cC^ahz8z{w3ZgrY@&i6JX%=0!l4?S*a5qr5_#*u_i#x9J6 z=UmuRC~+^wi)pceoodMcUx}yoUJ@_1Me3oD|26V5nfDet$j3yU8s!yJZs%%ii{bvv z6k8wdlK}Z;E$f%wQEaXgEN=CiS-#@;?dLXQ&nK2J)|0I{jH@;HPkn#zxf=YZlehQ_ z{#J|sl=pMaiT$64;eq1s#ZMy-v2B{g8QL4bU>~R%n4b3P^}ZTYru#LplX~p-{qTpG zr9Z%K+EOsp`&d_g!kB6ea851@8@SkM?G8|<0B3RSthcI~?^x9`Luzi-QtmYdmvpe- z#K4`v^lcvY^>WZfj?*7UOat-{oBHOTWxvE3^qGU~w>=HtwSx5>GWEmeY&!d^v449? zYhzu%`9pBsQ^nDBpYlA0-RRFvvCS8Zsl$ZlOhG^Up&`{LXV&lL-wK#-eoS5E9%)s- zG0nz5A4e}O-Dw!9=k&XwNdwQ%m%2-RrJhmnFsYB& z`I99ISC#`s5L!>rPE|j2OKqJG0nYJR*tb5%wFrf@{Rp;wo?s+{rPwHrZ*%<3mfD zOh)fJM{T7|V6N{R9#GaKeLp(d;!MIFFAed&3+#Vf z?AgJ$;`xGnzq!O&%6HbA-*=Yq-TwL#=NP^NuYccpE#JHOPUYLrcM9JPe4noDD5&TA zlgiG5m3;5#+spSme3$dRgKrn#FYrB?Z;f{Y=hbvqrTk{r(>%45S7v3UygW=aC*(&!liw% zfp1dDx9^+aJHS4WyZ?i+aToUmStpCV*{;uMGoBy6l%_r4f)9u+Gps|_owcuE@?o3r z%!hR%8_F0Jz93_G!~rmF?mR#KXmr!T0f~7ZrYGecWuHl$u=P^yn zJLg>Me`0%lz%1g-&O0)+B=7j6H#QxergfkC`OQs7kSDL*Iwx=Oy@N^v>~(s3`SQoF z?$X*$8IpbZ)H!LzipLAsJCk5am=Q<6i+vO1P_eSK~xYqeW6Ooa5EvCXKggOjvhU)^`|2pPLVC&lkCxS+j1 z?}AyS&IpfhhovI(*7sc(3>GMlumz+O8q0dbF~ZDo_sQlPZL>+2ouU0&)&_+3rs;VM zunG;@qo=Ypu)kHxxDo%Ul2`N;TfnT@{HoYiuN<~ORnCP9Fgn(q+$WIbyoRV52U(YZ zC)XWfZg_Hl(sBIh$Z}2mODF##dx@T8U&rL?1+5L(wzaTs!V%C1s5Q{=iJ^_WZ< zn@y%JFSNzpxBLT)<)gATq0WsHeyvpMFwT>d9l#FxaQyk6A@6VCccr{`Bfo+tCbw7R zUDyV{79HnFQ_{WzoSAq8Iqh;h^^t$?DKpSNAJNzHUq2?@TUCoM$Q=GW&-bbqUr4en z&fLj!lw*o*BhOOYwYX&5TaIGea}I~?F~?-vV#hSwY{!kZQI4s$q^eODq^}?59L!sl z6&Gav?RlQ>EvN|Q$MZ4mR@+9NrMPQx$+*SZw{5evZ`np^WwwvBQrlZviS0S!B~|9= z`NeW~bFn5mh)R}x|EqZl-(1+qK5Cb$d%JS(h39bZE|_~kS?EYgI*$i zEUw3t`nGWuYy8Noy55G&B5N@+?(e!58?)ClKO)phvN0+F! zovcB(ms&XXjI8k|?C!FMYge}A<0Ed)mo3rSZvK`k`xH4haB9U1yWlZvZ&zjia=vE& z&RF%f*wcREkKIq~idN5yjO$?hNBE} z=Pc&FwJNOx`_$t1@N8MD#P$pIpPzP1o{Rg2=4NyDo%K)trCS+_-t!x^wsh`zkbJMB zEcwSX>@S-GKaA%DgNbqUZRFtl8DoC*#{O!6Pu4yq{#j&=aQqJ1qddi-w^g|rySEp5 zuq`~G`G9eNu7is0Vcagnz$ElC}IJhpIskPnD zeIq}#s^kj~RJWex9`^(6C-n0D-j*kk)eLU+)=Hk(E<%oakG3DkKe!&$n#{}lq{~0c z|JEW4`;ob%E#%*8Um5HR|NjO4U(SF_Svy&Cle~?l{#MCb>MQxnKXUJVO0eEWcN}Az zdmL}=!M?<1>>)Xp+Dg4!SEh-*BYXX(G;B>-cd{NXvW%qL`R)I8d-+JMn|{5wfq6t@ zJRd~n%X;5c6&Pcvo~ruI2vivB)JubX^m&QwM;2Sb+x&xl=V({Cm)(wzJ__3S@hcO2 zuJ1YY_8D&)uu1kLs0-i-lhn8XdpYGjP@u;B2kp7klw0TOIbiW#uf`qRr2X1Zq;9R{ z3~rH}U*SCYgMt-Po?yu@6aP?@x(AH?qdhoj|HszuDO4Kz19xg|1Z&t0=I|cRirU3a z2hNUDxaVv46y7yqvUBzX%~?@38QfcQo+0le`;>!Iqba`|X_e?N5qe;z(!X05h1w8&%>7Vv7ldEg_-h=A_ zOF1}xa`mcfr=34M9=XnF?ApV72k*NksC)M)W9%VhuwCqtLB}l1iZeP_;nt*REuZx1 zGpnzE{>W7Sypd7<`5v=>o~JJJMdw|aJDksPM)^VH8Gp3aa;w)h@?4upF2fIj)EG_vEdbVR(QYmLx+>XcAq&YYj5XIQ&00Xj_ zSSLqU*%Pf*ufaJ;+ejXI`VoI2J#$+JIFX(n8DUQ>>2Z{kX&vBbdivv}&nG=DGQE+repf6X%&h~gO;3-! zv}YvgagpiwuA~eXz~l7v$VYpwB|R=O{VLXiu9zO|t^>?YPk#^_KjRobxXAJ2 zz$U{L(}VAIfa~e$u^+eUdeY+}(;GQ=bfxry0d|1>39maDz;^m1t$G#C%=pt7e_o}A zIoNlm7{7v(DaNlp53{z8u9y-4AB^M;!WY6ag2)t;(T7~jwJYHr!dLfkHbC&DKFrq& zUaG)Zl;V6)nfG?JtWWyJSF(HoWF3*;f@cwsQUXA8UBBbL zi01zUA9TG8&VA54i}~^`@zWkzRand%ed%2L`b(lScuN)|hsqrNreKSENxKc6Eot%d zu3c3)mb57nhdKRa;&^ux2fohS{FeCD*RCoYMx1Ekm}o1JXIvY!rV834EbGX>yOep8 z$b6A<-p}F1Hz4QrqaM-^w>;ldb{;)d`buQ6*LR4$(DeNC$c{fDuE?loXq!8ck-=t4 zUZYHT-b9!@$AzA9rdGaFLQfTXei(}X$IvsJ{wJaDJ45lxLQhBN=?#Vdl&7?r(9_+7 zwbNH3lLx31{r9msY4Uj&{Uv9WZlurT4vFv3X8U=UHV`NHw6XT0JRjW08dDdZvt+GB zvS=gnw%vI!<7ww7 zI6LnO_c8Au;kNZ1HLC=-)r`G-+-TmDaL75cka1@H0GXu>ndN_teaf@H;02G!MkV8( z@(jU03jYrZp7%VFZ%_CI^2})bUoLpg^G}3T=a)N^`2OMAdS@AK4DLI_$`e{iW9EIx zFndDOFgtd^uXAq1hIhqJ>OEp}#=&z*=4j{p`Q-^eA&&}d_}KAtV5eB|{6790$m3Av z0*{$IrsUg^vqmFljdCug+}VV!5}Vt+n|RO0CXb?iF6y^sP`xKx-?ON?j$$sk1zlk!m`@RRTr2?3VGS}Ldou}(arfcu>_J?@^J&get-p6ric;~`#)ah< z0*`2m8f$-+a4=5$Lh-D?)#A38M}a4I|g^ z{WxK_7Ctw!|G4InC51ajp3R(?u#@+J#Q6bk3bM5>U;m_jKu0LS{epCkjEM=f>&WMcmy|g!LG>BvDZw@3XQzE=+k{Uu$0XG9 z4rchhjii%uN@!yvc{XMc#`kEx6>(m~Z!%8y;SA;}GQI=<#|Ym_8TMQ|dD->6l*A)! zWrk-Y`*;)P67C;VKGMN^V9=J4>gK^0HjCX0@G=8@H;#RVL!tSG2g+OR%!&48NvYUB zOCFq|Qf*(D?iCxY@T+@Ydh5a44am0JDu+&xF+7v=symHwzIp5|YvBH(aN41yWglj0 z&xMO=UnOlHin7S)i( zeTbZG4c9Z9baVK(b<=|FxtlZ%m01(=*jE(hmtlSupv{G!$-ZjgX~M6BN5u)go9Jk} z1I(c>c0^>}i=T;IH86%J(E9}gFfCo$I?$Sq4rg+^X!EmMR`=ozJ*O@( z4wb5CY$gE}0}KkZZgF>+Bp#BCjJ3R56AmVUP=SF;#Oki;ZDK+d?{7cvAJ6BRd7k^ZkJtIW?&}&Mc7`V3 zB!l->HDa!BySYm3ztqmq3XhXmAHwIXW|QamUgaHjr1NRvYsdGJzlQlFellm@%wq(e zon@-}8sI-_p$czmME|i|}>Z zcXw6`-;fx1?GiVjtXzLC<&CE7#uj+Ushbxx4jyLLc}a0|W859hFX9i^h%Mno#|-Wl zdA5sdBG+;L@8DWi+2YVBrzmp_ANJ$$A!4PuKOY>?sIBum{=hq5^q|HTas`zC*ys3e zEc>v@R`hw>TV$? zK?`y39qUdw&Qu>Esl=xv&h&49F-9p}hH&Xu1aRc>?;JRb1&5<+0x!@de z8{m4&Fb+pp2mzP-FyNR1;9Gm9Ykv!G?@BFUh{xWU1(yvz9JiYF$ z;{(d&Qf4ppcM~)2N&Y{J&VQ0N-{#qN+WCNQe#7sR!<`GdALIMEBr~fVURwi4|6U^qU+5?(&iZI-kx=l90A1kBsnC$B97o!?yjtI@+8c3{As7p@lWGsI`*yi zxxbw8mAe3Y%94}`j(^QM?!NUIpZoc&kKGCMqnkQ*kcZ(oeSMPHh?~CsmAjk#?)zzf zI_(uCH}KsKhneBI|vg_s4!Yr*Q?b=AI$`-`|XDaNjWQd3SNW&#^tL z-R;^yJjJYI?qS3W{G9ju=tlzIe89CMIo)xD>waR_nQ3z^{gpnA8221J^Et<{rOmfQ zGk2BreMpa7g^`sIrMLP))(&QnAZN+gLcx%e&_se;E4@?&rq-$lb=b=CP@c9Qu<_-|nWr zuVtNdr!jYX`M)E1GWc+7V+$}QxY`PCv_3>V^y3`YZSIV2kT# zDc2Iu@fyeRao3WERE+s`M1cYU$T}* zc-IANiwr8yGkNaiSuQy^J{UL2ahlv5=f{nAeD;XU`$Wf0>wWaq<`~0Wa?2d#y~MMW z7?u)~au)MM3`56h*7!|+AEmEW%KZ>|No3nb${Xo7^M_n}4KN&-gA3Jj8V|Cb)5m2w z5@@$`dGjq|V{9Bd(eWg46MvWdlH)eMyPxk~OnyDY6iThDiq6=VOb85_e%^dI3nJ69AnJyufGw3E1W zzg=~0wbBNA@K<^JxKeMYXoF9_smDke=22bFt%H@J3K{MUXM7f87a3|Vw27=zB{9+8 zW&a>tW)VB8$R)BLExLIv@?95s?mtBLw({-1z<$-CT4YSIyI^w}iXTCuk#`|^F9n{w z7n#UdWWCYKUX93@o3L>-@vRERMPb{fPv7pqU%|)N{(yeX_h;*H1Cw+E}i`gkjKpP{~WnwhW5jrUFJ9jG50#1=z8#D5aMsWbdusA|iX zNRCYQaMLfM>x#`N5BV9{!}ZP-u^EjBvl$ut*oAA=I>AB%LZpgMIa*)`Rj6s=l{&@CtsCySWfW|c&xrdxc9^!Z6Q>k^FLhoHO z-F~qg-S-ZBq-xN8BPWLIzA?J)EAaJy_1`P&zbVL;;ree4GP3Bu^U;6nu0sEP4*mB< zUH^^K_21^8{`=j(Hb&Qf z$8!e#!RE=H(04x$e)myO{|$XN2>rKFZ!-|zX*}^e?r*-P=eq&hL;nr6C;Bh;;j3#8 z{WsK}=)dEK^=)r6{oKU(c887cW5y@??=F3O0sYrHs;~Z=#&>0mjaWsxJ;Bd6qW^~I zoZ`H*T~oR~DL$K=d4&h4hv$6=ZAG8-$BRzcYv=Anw;RaL-6sxi)*Z`2eoexQ#P?7O z@`tbEN3Ha6Z9je_KJ#MNHF1sLx7_9bqA#z;raiomP5Uuy#A3(H#I`B>17gd3_xobk zj!Yla)jd*du^~I`ImW;1B6eivLboIHKdYY|`Cpk6u_N#Mu=D9`Y_#2L@dsJo&wjkt zaEbj`+7bJ)?gx?X zyu?;LWFTJtzEzRc_iBSYWx!i3``J!-p!hY{6VD!AiH&z8HeOT1nmbeV^9vg13KTwI zR`hMf6_T0L&=HKtYH9j;3`2*U4|fvltITBoOab??w4F~oG0>4Y`z@Zq_*VMyX|v)> zM~u0x*(DiGoJZ5oY_}K&>oL>t?IQM1;Jv2D8x6!wvzzgi;JL_Zig=?ts53NX8E-Q< zBxBsinXO7L8QVPk%6tWO?<(v^qZs=a#Oq7J=R@L92>&j{j)ec9S8P0KD_1oQhi1); zPDTz0*pgljvnApC<7!|`;xClMe9QOFOZ--bjj0W@CmlW5YfnnUo+SHQ(w5{S7kg5U zarhzGS@zjth=N>Z}s&W{E_^d>*M$PYz_lWOG4nF&>+hc6j80<+8DR22< z@{MnwXFL87=iZQ`PBOnsiR)F4Eon1$>l0~n>Rp_ZJ#{dhcogM_a6@^5c!-DC=QuMV z7+=&x%uk6cDseuaC%)j1xg@^m4&nz&%+E^hQFKZp23m@i=(1pEwGzu-;3KazRnMWk zl(>ZlfK%U!{0k}20F79L3B)F}P*(!6OeJ37zpPT#r&np!KBubwjQF8-{9c$d-7}qd ziS{*ikHj`yux5d0I={sSvs)X{k-Fu37j4*Bvozv8Xq!H)E6u-Ud&ReD$7H3Dv)I##ghS`NS4}znt?ekHlkqiF$`qwr)+fXCc3>Y6$x&BRULE zeDC5MU~npN5M^wqBOd?I&wN?XKc=eqx4SiU(t@mSy|eto%Z+&x{tO`)7dS@WNcX-O4^?bV)y5gs;7C9SrXPQn|@U_?DP7Fj>WX`&=Kd3nWtpNlX9enUT$sZSy z{swjGycB+Qp8nBO&3d0gN0K-i8{iXBCiec}A9?J>*tyIT8ua)!7IIdIFR|=3 z*5Ql0bJfbjb*ok#u4Fz7(7_}=Ld0!_qmk9}Zu*)#JXy5UQk8u%ax8o&IEMJK)Xf;$!|Fc6 zx6=0%>W+tQnx&ugUFz1`;C;fQ@zum_s219Enz+o}ng*T8zG%ZoB#XM8_}Zj12Jv4m z=FCcgUE&?bx=!(aPRX*SBF1Cp+^Y0{8vReF?nGi*M+Vz66GKPFFqOHT9-Q0h%}FPE#wC2zhaJb_==$a!~_2(VQb=XY+%I7mND2OHhg#kv;qA1rL>zHvGKzNTBPTM z7Wp=3oZeolMV>rCob1zgZTL`fMuvY!jGe3cu7+}VP`|9Xw6~W3z_R{d;{8U^p1|N7 z;&R_XyTr{sIfpiL?^^$1I9xtR9NRt6jZi#~%3*$ zJ>Ip@pKSg+EA2XMN)y_|CG<$>k{)XVx-B&5m>M)!=#bD_p=%1-UJfm)gchZ!K`#2f zSk8fj&x6F$y_)$u2VISV-(HaN+$H9c+<(DcVln?4_Xye*+BWYG_@vUl#QOLx&m%4N zA`7%sBaT)CeU?}nChqz;xeHy*;M`W7@X-Y9Q2Z93gPoj*&Lh8b6}wfL9{tu-gs zSIgda9alM*w4>A8W>uA{YRJ{4byNt=ElC-o8Hrz;SXV9al7yc|vL`zsK`l!&tFLxr z@09o^k;FTguti&zHZ1T=_-Q2P|0g6Em!(+(&tiFI=HSYNEv98@ljRvXzu>EBH>$5D zBn(<6?d*iUKbufjT>y=jIarpa7Viq9@3G90$c)HDI(@I#Hh&lo{(Y0Q@s1#EY{rjK zXyc|nv@ymN3tgF0@?d~AMwp|&Y1;T!kT%NL65uJ{B=4#Z(ncqCHJ!HnH_*mNh#4P zq%ZrFiZ+4wqQ?r2X@=&mgT}0d#&l!j5E|2rY`zW}vlbd7&xFP_WB*$Rjadtgk!M0< z_F>yw2aQ<^jS0n2S__R?2aOTBEp&F5tPA&_1n|zRH#9dE`+&%@856dt)aAh&8ga_cE*h|slDl(vkCOC!6X{HX5 zo23qso9_zBoC(OB6KPN6W|28{*^@R!ZZ`MG&2x~Oqmi5EUJS@(Q7*+8(ivMrgmxhv zxvY?}WFyx~9VxVNCv`}k5gD5m-TE%%V(GKk1Vne2apkVos;!S|)$(pSdUO_T7SaDX!McS`-^I5g$4WcWMo4B3&t)QWBl%3C7+WBhNnmc~aITNKkXb^x zL^OSUhy@zVC!(FS>iI+}J`7*8P59~eky#SL@KNHA?YDXqxG4CR4enXFhu}-#Hv^a! zxDvTUi9hMbs}6%pRpo_snI8f3>x1%$RhQ??E~}~HLy^l^H{`h}J)c69rg^gIr_c{z z@?^FyTUC50a#^-6mj%8PxlHim^Wa_Nj*vXE34i;LJn|mT(Mi2JJ_KctMrg7wd!WN_ z;J3&ff(sVT`L4e+fDfX}>G)7m_Jqh56)~FUR!v0j<&L)AibYM;JC>xj(7%S4@hP)NPiVN5i{msR5U2j8Yvtk$Rg}>Ming5)s`4>0f z^IoO}U@&*kszMfAfHjqz;`X^!|3Wq@%*X3X^G;YcN zAhw}CFxbNrYMN9@0QR&XtzQO@^@Y=VvB>~~Lg$6H%X(Ja3C!wt+(2BNY}Rt0(xNL_ zPqBfpSE1AJ3f8n67?m~M2mP*KO?7_4{|eSr=&{U|!0gLGn0tr2(BdOO*jvXvM2mmK zZ-GI%qD;-D+1j<^BF)XEnrbdhTRbh^%71fAbE!pLJ1&*~8vn_{5>I~H_}yZ6fbKd? zG42q(4$*46X_(t$N)F1wed%@qFjpD0H%QK<7lZPs8Jm`$TxH}eTX+w2o4l|?mI5pD zDRWYbiJqs$9QSaR;(ns14yY1Ga(v z%ayIF(qq5A9e9Y>HnzDmkUPyxZYZr|1AA^gx!bVeZqTBlC2!j%t{N?>IGy>j-L-Lv z?qC*bDk00#G=S=BN?6DQxbsdtsj*sY&+vtBDS2@=jaHx*U$t7)C z#D0go*GHekE?c4X>XYTrnxHU0evz9 zeNulW@}HTU?&y;l=#@MR>X@_D>l3yN&XBeRpGC(M{W6xbR*m5E$I!J%@VOm)jsu@_ zg7_?ap%I$l*P^2*k>?aUJop@4Jc<04);m2*D!}J#@R``sUMqPjr?QtMc_zCxvyRX5 z{X6gfM91fB;Lo~hs$NFki=HI7CS@eP_<(JI&zq(b;{crgx^}Xm8G>)tRpcq8FH32s z2iIsP7Tq#W$2E;yv084K;F>;`jZ4J-QqhBJv99^7O*S?_y-oB6E4gZ;po3bWzvOGj z3S9^v>rP@`on~HM1RhUH3oNhoB?G-hemV0j&|EWA_rr0`9l4fD9?X>rk_)5!h%!TS%mhxq3NeuwCR8G0c2uQ7jy;9P3l zcS8e~g~@Vn@!QTkh2*(_EEm&SgDcpCbX<8* z@)&xp$n=6M5Z55Cd`%y~YwN1sKC~mNNzT0etd-maSHf|mk3KK@!<$x*b|k=q?7_7Z zT#&UCm}#VMeQ*JJ?gX$UYZ{X2M4q!i!$k%XxlZ6*@4Te7BW zSkn+}ioc=2=0@%sFe!FUxyxQu2qqulx4@*xaDvamKLrLiv&K3fqQ8=7S$L3qqtS1H zL1e~W{hGXsI|V1rnrAorej*u7kQnZ<*fh1m zc4+66>M1Hlhslq$=pLACfB*3%b-?X1oqlIjXHaH0?H`NobW&t^e~GNQ z%$=;m=F6=4Tg-{jKB0FqhqC7Syoby2%%LvFGmqhNd^z(NzTV}`V`#n0nMYagkbEM! zGNs;-46kYN(M@6NEw&bUkNiF}D8J8S?PrF`?=uAsE+@YWFaB%f_l&EM-($Z**E4h(q*q>#0>(99{7UVMogo|i4X4;FgvyKK|i2bvaqxNSg-Qw1ZFRzdFncEl2;I*s+xBd0~u*MVg70Gxkw^7((z|Gz*!*X6R1d_F%+ zK0m?l%gN_Gdf_)9pU?jq`F!(VAfGq(lh1>)Iq+~r*?eYy*?dk=HgD+<2jQ}LVL;9Z z$>t&h_1DJ&_VvE9x%Lgq<&%jmA@Cz|xts|Tx%}7MLp0}S{Fe8jt9w>h{O`TJ@xLX0 z;>*PUzAhO5TVkx-7|mI%hg7F;sMhIxboiK2Q)e9(e|bMKp-16|s?e)aET%J&w=#Cl zyZecuB0Ab+3xZzuV=B=&cOX@J<@Ly74f7W-S{O!{SGe-9<5 zH+ribIFs1lJ>~kx{vI0L6Z>1~=i4t6``Z}PnD-<6FzNA< zdSZX`T#x;YZ~A;>)}GkkJeSztW%z(^MhDhofAdU_{e6$UGj%y}pvmQJTs3q|&i*t{ z3uh5nC)dU_;s6kXR@Sk_#ky{_clyYw-SRZ$iKD5Yb~%ynw<65{T4u}(J=AH0ot*%yfM zO5CD`FO5m*#IHOgakR-Vkp9WqK~=Ny)Bj(_;gb|RRnCXp%UMi;-DlKrPZqIxCI0se z?AXuXgD){8RqazrDQc)5|698x{`WAK4>=kcA{hUBs2>0O70zr}fy*qubAq>PuC;d# ziXQGMkG6OIUK{C=JdWb0|103>--GeL?M6ejZ%qom;UfaJ7y2vxJPW^&{s-cJk8p7= zfcW1}C5bPt^h@G@<8Q0S|1J-8AiBvL65$D z*6zIkj%VSgJrDm*@#Eb#4&Utui2I3MW#V{yMl$>2;=e30zYP&4N19wJxf;Lm&Q@}0 z){ay!i*K#O)f!6wH1-%JHj~Wn@>G?m1kDVZ+e4x+o=xgPOGC_ z?sJIG!f(YrPtR9ja81HDdpkKjC8y#>a6^2doxs&m>P~(0I**_B*a!AtZ(x6MPv-I= zvJbo`Q|h-+XQ)1n7%v)o;@RYllDb}?-db{f$~?w`?@|vqzqNo^zE0NvX8ND03?7LG zR)7uU3-T77?|yvYO*~U`(mc|SmC?%6TEqDm`XS@A54LBlnPktfL|VpK$xEp;LrPRc zRLZz_I-fRho=wYCLzl89Vp9~F;NSN25_`5~T!lfE4!=^F!P(TCol!AJmG-ZD@Rh!k zx}(Sg_V&Q-|7;dE{5Vy*g!_}J;`^W6u?LyOS7Z0eTrQ7N(T^}6GXBpQe;G03b6JP8 z9kNm-I_%T1x8xZB=aJ+{lU>N+d??Zo^2|Jm%jI{qO-(Ex;Rir1J+W z`i0O5r8vK`|2mzXU`um-{1JV6h*;c1vpXfeb`5c~$+zqjdjx!5hIS3!mS2#yl{nm=42`P)kA0m_x2=Sh zFfX4B&8;5{?`vdlt&AHH(l5BjKqF=d{Q@5S#)JlF-J!ju4_>%;#e)}~<9<7L`9|!GhEit} z=Mgg^jD~0{cF5u*EhR-q+Dg`Ot>O19jX2y~wTd|XTvqdhaTO+GisD|b3@Lj`EU)>v zWbLTawTW}=S-{6e_=m(u)=F!e^06~ka7lhs3s?9zyE*gpF>oNVH+$ZCzEkPj>DBhF z4=|n+!aIUv*i-t@g=e|seJp*K@fqp=ER+59K}KVAPNn^|2}fE>(vBP}siPeymolf( zrXi&~td9@Uo{w|i-D){KW%U?L2=fcZE{Oeo5qO`OAPkrU3%6|XL`~A=S&%Whv?Dv00 zzyFpaeak2J`#-ARf613FG4Mh$?{>>R&TUAY@W2e>?j(S#(;r;*#EcjPXckN zr*r)j-Zhmn*R3i$JcZa}L+n-$aJLXVefSi#v_=i-Sg(e94AbUZ^x1A(5ouS8yJr%M zEJrPF$CivwW`oR!h1{YVdFsdu`jB<;s0E5k(^R9mf-@XiY=_4DZ%~Qw<~Wzc#XZS6 zv)xGn8LZtHNB)nvbTy~2OKj!edwBH|b2-cXh&D1>@{HOdMtG#Y^1_{&OSNbhveM$H z{g2$(&e=H0Rmj?xqHE|mC!_Wk-q;=$d``YjdA=Fmtv`;QUI+OqEAcx54-$9dd$R|7 zO2Pig>@mc+<`Yke{H%9LO;tQluc?>E_3lYg?|fj8}l*yV@znG6o;kG<$brXdIiZO!>pjy5}| zv^3|tea%kyjtA@9m0USoifcQuI%W~8V-0tSLA>3p8l8M^!?(l~tmA!RCBH`)Z)kQjgRzf%r1(_}0YT#C=C)fuo$9R%GsQ8#43V+ml-zhU6B#?j7auD=o6a zPwe1zY8>;#IUalfI*Hfa4J@8WSDY`7C$CI=dd?jyx-KAh7BIfd<*T0<#o9O-a}NEw zdHL8OJ50%*A|qCP#(gj2EMSb%rvfe+Pri(+uqm^EdL+N2skvZ^YA)#M_gcyrDdVKC z(ogB5l+QAb(fylCl)dyO6&XGEt)d%e0!yydqsElsE9I(MpHy;-8q%ax>D;$g+_=I- ze!bO6J@2B8(a|e-pOQAowPfr1q+e4mOO1AIhQG~ytMta3)aYobdnP`1m(*#x$~q}0 zb)MpUpwu}tSm#anXk1dKS?Vmku~hHp=sx`{4fb;;{q#~Ui8L)Dd$>!g|SmkV#h3l z?#O!I$hsG?Mn&YgWpCSMW6f>MRsAScn)_DCjRn*>YqfDq88ob5%lf1=%@|!w-rFo| znk$#G4V0_oT&eKlR%2X)(4Keyvzz#(vp6$9yIykON*=ycVx8nbGh{C>gSFIYKKoP> zr)>&!$B2A99U7H`9joY08??jVIS76J7Bq^)A9qb-pL;U2X)1I|8BCrsjXZPZ_KUK| zSPQSPv6j1qSFqpJLQW!`J|NFu!Y33y7U1Sm6{+)yt9$VTYjPQ zM#)FKro>VrG8${;dQfB<=h#SObU~Gt^l z_ec&ck$b)qCileBhR9G-r;ZCf^3S*)`DX(pc3fc*3J0P@e<1IR!7uR{L8 zpA7jYHYopOcm%fPZ0P~`?G)y{5t&E)J3EkRgr>~H*KG2tm@zTz3CrAz%qH-Vi2ubp zV2pjT(p*i=uqku&256*hbri514Q=!!2`r}vVfj}6OZgB?W`K+Lfg5dKbqA9rDkxg3q0AEc47+$UUyM&5Vlge%fWfh(bt zoH<9n>ZOz78=%uk>b*KT8F2}nY!A{&@e}S(C!>I;NZ={;GIUbtfxwf{r8#}*WI&#F zBG=9dqmwCGh)(jn51kCi(|Y+nbkZE8la%j6C#hejlZAgVoea-Q`gQc^?^s`@6|;9Pa*)`j&60zfXNCBx1Z5fMNsLRwo>lN}K%Y8=jZ*Zf(7b$ydGWQW zhlGY-Z&pKey^6VMJhkfZf1ZEzu<(Q#s~$Z(mAR5U1L(Y4MPL3syg>ZD62o+>T+yqr zqok8-`5tIh)SKx#U24QXXr1U(yemUzS~JaYQKjds*Z@CB5qfTg-eAWlF%I|Kzu!Jz zctoUWl!tw`Lp$)h$|-8gv~umRtE$<|R}Slu#@)*O!{%qF9BJN$uJf$h+q`|s8_nC? zuQb<9+1|X}UDsUa9zNr!J8?#fd&G>3?!hzs?qM@J-9u-zx`)iT;7*uv-hEfH(``&X z>;7Jf)BRI^&)`0U>(g;g_qF_&xQ@>fCvgpTiHRvOAJh1sQ~9hzO6-c_;eBGVtSXv{9ZF)Frx)85oWjY%l%(A4;j~*S&QC&**2~nPtDO&Z4fF zdR?Ofb?LAkpp6mH_ELOVMc?tx`9mRfH1*a2{3GvsjjOj;m(j-p`nW?GCvB%cX}!47 zBj?ZKoK{GV443!kA@2)+6`T-xvk_l0;j{g< zi_kBT!6T99TY%?QV`76-m*e}=lWgSp9FgNSV^H3S_k0AuXlA}zpq=O<=@XP;?oQfB zfu4v@;v5y@k=WFY>=D0!|Do7_3RHBoEi%@l3Jbe>Y09=t;oHdYi`VT*^W?*;B1-Nn z*^!yBD6lTb*VMOWPpYQ?eq|`hFUjFuD)U^1Y>&XXcrD)@2=& zBI6?S9x}o={*C_^gL1FX3Sy2Qf|o6v&U1-pB799`=UVuJ;M83_56Qp}9tp_6;#XT0 z)($by7O&!&tk>CR7f8ELs5xsbwf4s zXb18r_!$X~Zx%VUDI|x+0-MO8-U)w34lOM#nGgmuAG2nn2Z}r#@F9+K#juwrGU#0J zcG9ZoF|HuqN^B*4jkr$*Z>NB_VlNzGiuRm7vGVXi`koPnw^^*?2J~pb+cwSQX*CYf z_3$glidi;&9C168H~Y)B63N-0%Oye*ewr z7y*AR^04DWDn37<^AwHv@zt?L65nbAzyH5HPa%Ho;xqXP>n~?15`b?Rqr~?So#(+! zyG?we%<#r&tu4--dOV!A19o8)ypW%F7$EK={&sbH=Bh%M_s1C~&lmnLYfaQq;lv{&--3!a{`aWkkEMLwqwl^+O0H!6Uq}W!) zr&}w`*WsMKh5zm6*d+eO|E_avqECx2;)*bwk~3_*I2G@je44z=L7a+Wz5?e*z$b94 z_xuQW2JO{-_xqjyUIy*`YtE0zen$vi{tB|_!4-PcxggQW1yu`&{9vL zy>!EHdubK4bRlrMezd)`7`WXGjrEMRm&$qQP0-rhs)}bMKH9=3DxS&JhD^!@Zr|2Y znu@^#8{efrD)I&Az@;2_DR0xFCfO+W7Vup(5ju_xQop*sI)(RU-iOMYwa5S-0N+Ix zyG`iyh5^bMkp1@W37xr)cf}wVhr@Sezq1qr!8Ue)cmuEvTxa3J4vC1>rP zgjVg_P0U~NJ|C}^c)zAI^|$uR3rB7}@n@MchnT;}*P)odqy8-r^Y;t(%hw>=Yrwk1 z{QU*>eL;Ppew-6OoZ|Vm24em$#Si2Ak{6DgKuZo+B+38cZ2X&ygUI_lV!(L64PiOq zX3&m|?+bG5Wf`Mfr?S*y8D9?ar0e>edPV%jb;yxFK|V2%2W}IxMG+}D&izbV*9BpzptW^!4uG5WEa ziEVPd(&ie`3CfU%#P_uoJt%v&)f0(6P=GF|u;(@xw`NMcQm5qkau!*;QnW}tKG2>I zolOP5v3TOq0Slp{R{XIdiB(R1u0?r;sUY` zu~o>+tEkxuOc4g#66tNB(BP;*E^riACyyn^bxza?Qw7gSUOfS z-4QFWW@5*aIBqz~|qMiuABfTSms393#jLhzVY0YV{bg?zWBzDDQ$1;aQ`snRmc0}gSj*1 z*N*3jd$)!%d$=T~=%F>+ro6vqoBO>rbyI%3rp`V4$LAbrTm~+G>VW4w_WrZUNm2%__CsSgf_F7$Vqqf_&1GKat$uXtGA+`x zXN9Zjz=~x}8Zt>N@{3i)zOXHoc-fp$<+tZlcg-P*i-ewre7^Y^D|>z}Y$)@Ay57JJdZoVU zb>Szl2Yi#hZAOpP>x#X!u9h)ZQ5XIJd+^(lx-#HhdR>W^)|E5*D(b>7U=O}NQr7`+ zRamtSd&^O>()`~m9l52{fCTX*`NbkBy-cJH1Q#Z6{-ud+zIGjm4{^iP3X zIecSh-=3VhiIOWO%b4V<LpTZ+Pp}tMn)H{ILO5%u3#IE3{exnxSX)&4`gkRjj zH$u~_J#m{a&nF~q^HOEh`9zsESmzTh#^`iER~xp%?X=a)C&;%lJJs_XdW`T1s~U6( zpRg3Ac74P+eb@=#_%N?2?Kf7>HOvXj$&&-Ep8%hbyyW?X<4bfqD093QKdE5sXRnlz z_btGBH*~WRyI~%DBE&!Zz^&x;sZ>$q2a4j1c9PC3#OFALGkc-9&i~kasn4qTUWkpc z9UoWZ5#4tcd*DKm1%AUC3hj&Hx8k=v6S(*`Yp>@4W*&s^hw=f-+y-(1k7y7+5}prO zavzIrP;w`Tf4T6p2b=N#;Ee2C>I?ageU7a11^sRf`Z|85!&&*lTY~M2jYIk|FL+N3 z-n%H*le3ravlw@HeCY2pcFDEidZY8{WBiuBo?Y}>z1T?n-Kt9LB!7-qo!0i1Pv|xh z&SGS+uWn&qpguv}Wm|1nBzs0Dj8P49N>?3Tk1SmdoYa6X5|>~+GIqf*=3bHa61?8P z`m&exy2P1~J;e?1NBD>S{{ZW^fqhCXGWeeVTC94#p7|WFndVmFOJR;Qc?yVQPrl~6 zYJi>1;P+wrK@5Q{%MB58XYZfjnUJ{mmgSre!EYe(6JY$P>@!8H&dn=U9$p3=-Za@> zv~hfPQ6>92o1ni!gA-MZCthd)zinK@fthhC(ley+!IFeRS4m7^amjS_*r>vylGEr1 zFYx;<_7T2?&lWbl(rNfaO~r?4GCoI>@DWOfKG>2~X&yLL03S?KXL{%pHL{cM{fZFZa6z*UiqKYp@>eVx`oJ_dM@;@YECJXi+L$i`;8gZ)}_;xNy- zXnW@l^U!F)AF)}@I>awU2e#XV#*HP8|TQ zX^XQL5_^Fhv+`fyoLCH5YOw2V;Ci3HxgL8a5Q{^LQLq0wUVMq()a|07m<;&lq=#Vr z-S+Oqr|`{^7*b;Emz*u>{O0^sLkoB5lU&`#;g{-9ocRgqEtlv|ob@?5b?~xE^d>#u zw%B=s`L>UdhxFXwctrp5g+F`^eaeH*6wI}K?3Z@$TMzWpsU8pJQ7P=JQ|8I+X|72W>r&_m}BZa`stxWYORC>QtA}rxr-A>&xm>!0lh5 zPc8Th^r@j=qfZSTK%W}gU!Tej)2Cu@56qXYOQmsc?2)U}rBd+oKNY4+30z8EmH#$< ziuLWUPjx>gJ{f7-On$$FZZ#Ucs@bTvh|ZOZz9l;ULG-N{Q}Znfed}PcFY~z~U*^ue zFUGyY{ddi;#kFx4|IO$3z7ThGUAv=d?~b?^_rB=Z*Zi8}g}pC0*6rQlNd56~$KG|v z92=7}9Cei)j=Q-RapivB;-0~sypwKs@)Wm={JHCsC%SXjb&|{U8giFf-8RZdZdl1< zyJhSyM?1MC_a#puhvy{6o#cY8tn75yC||(+{Es^wPjb~z?s2ZITtDIRaE&8x>0RWV zts&>@RK8oz{S)%Adbs|BoS(NRU+W%|`KkLnIZ-7a?X~3h%%M&z*SVz;jb`$le!g;0 z(At}e0kh8j)l}covV_3p&yK!=qTWxOCHni z8+`61d}HJHpJ}t5+?-2NUUux}cTw`o?opYaxOeFF{>riZdY}8Lg^5KF(3JbMg6G8y8Z~`Ed=7 z>D<$ki`=79{?)NKd4>CS%KeCZpilgx&rM!f$Aobc9EsF%2A`0pY2$9%D8jGamQK!l z$~5r%B){*X>tL z`C~6_Oh7j-BVXx4=I7wp?>JIv6Wzhq}p`dvNUYy!!>u zo^u#@HhXNndoQ^^TN!f%-?q`;?Bsjh+xS-e?~Tuz7UU&wbL+99Wd91^h>D<|T~3@3 z3;2?O9Fu^Y76tGB-3n)u0~zhT6+dW-Cw9-Y)zhkdoSjHe32(=fgD1rhf3gz)AL4+Z zi^Y3R2XwKm2^M=5?>gql8B)##vZtKrESiGu9q*b?tdIkSSkL2org|Kas_G#4^t%-g zHT@htd@5}u(1tR^dlC%l?bGBNl{Vhwn}OQciJy(oJ-r?Hf2bXa?N?44FQJn=5(DkL z$9VdWBh-c|ao{%0*k<(lktcfU$M&t)kDl%reQEvr7{cc1Uivf87}hiQdi}^ZJ@un6 z${hV1-Q8jBohO+enWszU2%E-0^_zzV>&M@)r+#Ely?*q0hwba@AJ2FPs((E;8tK0k z|L#EjnjQnLVvp6c3mrd~{i__-xtW}>8I0g zH47YRTE|;l)JhbeMGB>;~;qoqNIN6z_RALxO} z4a9_(dL+)s*Oe_I?!A;PzKXJu?8Qh~iQo2h_13e`E@dmPqU;^Sc9ODHS5fu^_I)Y) z&%v@1lUL?Jw~?ST$~=VTv>m*aH4{HhJr6DCUln<1hxhwGso(#se*YKs`~N_{|10_5 z-xkBctE;ocAg6|GF$chh%h_ULdH$E$Vk9Q@W$ZA0fq&kpz4VK{Sqa_a5NKE7ejvQH!zrg3;5o6H-mrRXR>3fe`G ze-=)_R`M6yV~`^^P*=D;X45|h>@hb}pTO{7-uKvL(09l`*m;ONmwvwGd~<`3|NZSO z-LD4hEQ#zbZDO3l7eZI}-qG)iAM82#miQe~_pd%H_x}2#-TMLYJ0yk$_JMqyk=4j=DK^MCv%xEJ0Xkpl zd|K+37#=q;PZA5{n~32-&TKt~M^0I943D;^&Zq5z@gc-+RCELW62TZAZ^W4#_Od_> z5A>1+5yak@g*`-Kblg{77k6)YoujQ^3=coD@72Wc=qY!F7#<==8%>vw;gOBM>(arY z7#<_Ww1i@K91O(psNqam6t)P-eN8On#C1H^V|ehKa}WA+EBv^U=Muw1&Y*2X=a=&3 zJd+q6ElW8^{zLL9nC&*=ba?%ofxmfG(wH&(Z^npIJ1wg-s*D^lVfGM_kWSg z)OQ{69^Noi)fIE*nK&IS*KwCv9uKHad)boc&Vq&Y605^ToR0JNEUK6F5FZtrrsg)J zs;YM5=mzYH4H@iNoFr%8dE)V%Fpg@tU>x2s2sr26JiC#5Z9wdOV;ChSg$4LU-U4KCEDKk z6BXxyR(3v#pS_%oUKEV$@d0~tACQZqMjIZC>yex;{p~Wwq)T4|aXp5+I6pvKkDn$D zW$ePw0B*oy(krEkN3OS%aa%a=a|>i z#xa}~if%Xy|Nj!Zjly>SIdjXJdM_FWr@!!--P?)n<~(b1fwS?%eROR?UhowV6T@iF zC>WZZVI=-XPIKxwA8W0+7jRW_J^LMdXCApRb4Z8x;3R-Wv5t5EM3q{uis_&8d(2w_S0Ixhm}U9$2N^ZM)Wg& zEB0SMIH1!R`rBgE8ZNS?f)4`!A=sDq4`M5m`TZD}-37gtbro0=INXfv@~0UlD(zdI4pKKk@i&_3h8ksXzJB z9rZ_F$*o^Py{|p9)b=noZXdBBK3lzdYyC;PcZ(Y0*?GUcb2@QN8r=5I$F=ym2f%|N zJjb8$ka30k!g2P1ZsjgEyc%qR*lHJdV|TT%$MzAna@lKJ15Nh>8y1s2LzU(?rJ1uc z#t|pQ%KDqQ9ysFcdcdHf??3Wrm%s(?uF+QJ-(r4X+s+gu<{oGN2E3~}3T);kDv$K10bKZJ+SiV%sqA|k(n=p~veLGX z{eOH_$QgxiWNH3uQkT@vyJ&&WY?D1@X@WW$l96UtPFf;7F;V zla7MhS@=kZzcv5o%I^a_>!6(Y*5+!7?{sT%u3en9%;cH$QR4CmdcGs z&-KZ{37!L7lfm66t`p$wey)3=19__kR~JNQX9(VhXn@cJ!TnRfjo^L_y2$KAaGw6N zJ{=~0pXGOs8XA>iFcgi_m>A{hIx&YYg_Ue#2dGx{iB!5T^ysEQR0d5_~?+ItU(% z-Fp{%=i(DKkNMPLYGpp_n9n-q2iGybt0K6L+4?#LV6}`q!Lp9xdoA$Oy>|HfA`^-H zau)ul$oCqMpR@*%fnxC8)-3kUO&PNeKgQnFHPBs=i_T(a{@Lh3W6JTb2*f!voUvV} z7K;oeGLpz$ALAe4L#ET^rEkNJke7zN-1+p!_(OZ^9hG=sA1QL6Ad6rN6@F5{a~aRfwEF7t)bTgQC=c@K z;m^q}(~c~0AA7VXfb&m~T@JGET1>v)*5#_Rm9dHJaH>OjPr)0%ga-OfD{nLX6dA^u z1HUR$?76D1r2b^B+$+3LMcQAF#|HB=@>83E`=6?0PnpaaGFS_ASN1Pu&Q6otx|JA4 zAKwsfJDO&$KRGh8{>05u^~bT%&SEZ)lGpm=$UAtJTYvf?c*70Qb!@Vs#OE|i7+ zNgs3D4W2e*yXi(|ZN^U2%^a7blcMK8ycs+?!+cBsQt|t;MA=`rgU9!iTiFAgYxM62 z*hIFV+ou=?b(D{uy`mnSG7Vhwu;(T8D<2zdbD=NO`EI_WImk1Kht!b`{i`tycCo*- z*a9uj<`OvF_F-O^6B=hxIVsK+maggF5}$*_4h>nOTN~+8$P6+cvR~y}PP{PWtz$0u zCGr91Bs$-KK3KrvW~EquLr4A^`^94&cJHS*)FkbOS3@5=bL5OG|34DnA7mwEP*HD= zvak4*^-eJ$A25DHgxMkeuchyH`ke>=xBe;LUDq>)qz)@%@O>oyPMqTsnb&Clsu_PU zyG|zx$0?)w>O5y;e1Eii8^KL8_LmgJIbQ4ze){gC@5GTq#xyp_-a9UukT#JLjr1G_u)eulu(ljtl1()+amy|WISk+yU=C~CN&c!6lIo5-h4}TU@j!f5rV>&#rKFMYI0S;vaM=r>dG|vVXP4 zoQ?dIosz%enl5MYv@Uy0_Okq9SC>Ja7dyN18GqI_uo&hpuKrg9SHk=DpC%M}S%Bi(K7n zNB8hY-`YSt(5J8`NI%4$@U++!uqSL4djfP9x(?n2>9&NQ*T$J0VoUG^~k_61EaI z6#gKz+DBcNwI!^LZuAomw7VxBD7J)Ifq0=rK%;Y?TpWOC0mW>=UYX6PMT*Ups<|1~4n~)nSf_8&)YzV%4SocTojuv@o zV#$i8FX@-)PhZ@9SG~;rDfnN6$U5k*#P>u$9oAsRj?lqcY(Osk*f^5-F3}C+!N)Fs ze~v%Gaqj1h=JYu13&*e%binVA;^!vzgHH6@Q?mwDoj^WlN6tBi9`Pl*o9N{ijfNf@ z!fbfh2meL;K`lH0TCe(*VS{xN*;9P`#`G!frm5IUOOdmg(1wjb{o*bO$I--zEw%pqCdO|-^_~T+~`E+s$5n5W=%jY zz?Z5+P5a)(ZT$B?CUM0K{QvI7v_$+7`CkUCTa=3OBVS5fPUwGeIr35~a?Lx)ZELs} zGWR>=H#Ak~w8&&akLpBD;GM_~A}{RYzv6x$a!}s8_dA^L-sh-*|A|Z?eUkVz1@H?e z-zf68rQj=8jND~J7BcWmL*A-gQP8!AtK94y=Y!9bm!x$OlgO2hoRDTAcP)0g+G5IZ z^^_?Llo8uqs`L>XU2SnbW%9$yq;^SrCy`yOPE}P~oX7jTu=mz3e}Ua=$3`LhJflRn z!RJ2;pE!ICs|0r>F9|lCbRFNoF~KXrF?si38)x!aH|%fea?V)n5(1-QmpA}lbh5wM zdflMlmi_iA4lsj#$*WFg%mW96} z_KA*H?%+K#9rfF_n7LwadK~%PW61V4YVn>pWZj2UyywT*D7IjqaAH3aUGg>LR*7f% z8F$VvANr2i?O4C|U@XY(#IdYg`QU}Ne(@~#lsKCVnmr@mppkpbzSYe4IoyTMik^C3 zNnTf8Nq$!)*IIsy&Mx|$GT%GSj$NV-{_P9#aCG)f@K?#3nJcu_IIdw&No|vp?`kPi z&OKBX8B6E)5EwJs}Xsa&UwAFGf*^%#ZZXPQS{7V~~D52rm~q zMh!NM&8^*wB{!6r^BdyZ+X4-gvxxT%+gUB&!^@W$&Guy#%!|OP-!v=5hb)Qz@3L%_ zy)36(RT<6M%LF$rEu$?HKl$CrwR@Pi>uARc&b|X4XMwX3v?;!8GokT%s?pV=E6Dg|9)wQd|F>Aqz?U)JTyQWC+`E^0wt*9SxeVs~ zarwxMIfd4)njrp7WG?Ro|F#tuQl>Dh%tXD6;NN&V=cmEHZN>Le=H9R}~H6y12JlMW5>CO-opLN>@oJB9cOsMKcmO@m+QsH z7kNpy;Xtz%wjrBIEG&_A&Qa%qpucS*&xKcxMURyEUaI0c_K02ujckQJE>+PT7U-wY z&OD_>b!%F2Gvk~9U7XEWP28b}dOU&c$hYM6PLy*F1%JBN{agO$aDR^f+uwb_u??Cy ztFSI}4VT`QW^@%o4_l21>9T)%6!>X{XNn*9THt0vg1}F~I9ZFdm|Ig)&9hSq%#xEk zds!uYosf{N!^ov&v}NL(ng#6_*lDM3fyeH>Bj5K8j;Z&Zz11sr7O|~_WZ2LilgOMC z?apz>Qetc^@xyILN5WH{mwC0LbDzN?k!(-U+>Gx_DUb5y%b`%tJ)`%e9W`-A=JK{85bQuH7~m0 zgLi?O^fxg6^J^JX{>%4}A_61?HeJYz|()hT@wWHV5~F%>nBq zZG_K3Y|k8wY&g3dKV-%yq3+#deooz0j z?dAU;xfWrk+p4cYr|%WsVS{e_EzdtP%w~cscFM zIG02J&r;_U#^^hZeu@0Zdi9)-xRZJ6Pd9t^<>h?D-jO=}6nc?@t&F|TUVJaVp%>rF zd-2@_t?@H1iw@H&U102bef|S$A#nOV=DvloIl)!`FYTR4@N)Zpi$`$AKj^}*pfO&H zs$J-(jHToz9XB48dYQxXz*leGBO6kB>K@73j%dh|x|z#R-6KME&r+QgT3Fqbv6Nh| z*L{uD&D{6}_s?>%|D<>(Fm0tD0#^~V<0~*#`T5?TpgLZYI)JM^-QAyB z)y=*0uZH!|+h^ftL7Mz?tNohZGR>BrGS$6hwpi`yy=CmZ>-Yp^@_-}VHVzz1KmEW` zHGRAsEWNJd)6jQSh7CdY|#Ouje<&vd1~U*b+Yyo)f3@9EELsGPGHE zPI-{$SSJI6uiCxX`aZRmPtp6{%x`7CDKI|l9<2rN9C*pOz3?1kMAa8To)h9X!{9xV zW5M?-Jg0SV)#v9`XCyLrEAn(hUf_pI<9cuG6p z%eNQ*g?$gft?m8T)p4Pb<8Kwk{N0 zhW8X)%6r}s-UE&4nFCkY9I#gSgZG((KD-D1t8_dL<2_HSPNU#~=xc&6jB$)!CXDxN zRh=XB@sDcQ$@q2N^T1`s56npWq45jvY30B0oTJQ(@S5)UaW-daQdR5o$TQ%m@CTh2 zfp5Y?+JI-B_q?D5cn<5`=79$RpCSIz_Bi|pe$t9w2|jeTEvL*o{BPxgCLZ0cuS2JA zH}CL|Z~Gn3j{{%GJ3036T@b$38a=kY6l{Lb(5)YVO5-4Z0KH8zNH$_|H?|S7<$i|NIJkT_L=O z@hvGU+e)3}JV_$=3FCtQC=2KHIQu2Sg}U17qR*r>v*$0RO3>Zk_i~ z=LljO`j}VzgLGLkFTj6FrG7upErr+Xbx)AGnH#_0KlDK7J$p@68s&s%+)o?6?U(YN zN_o!vam=rQGpKrbc<)m95B8K&ay86VJXh0t`Hz%YsP|c9!~p;Kp{3uT~R@Sv#PGOBl-o(`7L^fDuQ%ar$)`HAo#V5x@( z-N5_^UI9~`f@hb3sWCck4Q|H2Jg6JlQS_hlYvDz~@9*aO z9v$fEFdYavvM!_pA-i5cF4c7)+7wAtmLG?;OPbRgm{ z=sHj@4aPqWU!ofN>%T$h?I>OTJCAI?4IC7oIKTcZx#8DR=4L4~j54De&Oe6yughG+ z8g2)UbQ)YHG_U4_hyt2b~u|OMB*_I&26r)71BW$SctLe8*XLnGLqupEp1#aH058&hsO>&_(C>v`Z>_|tCq(U<&&FM|^SeMopw zHy1k2(Zl+hbozeJJNR82yolH(L4D}13oV1S&KBr)i|ki1rsecO#;WT=)Yl>OAwIiP z=x;bLie;{@$cy#{c@g6iUbKhv0fO&!x*VF-i|@+NgYUX7#F}0-MuhQFW5xxE5UhoI{Aaa(O^%FmmZH%Ff`N@ZerJ+w0C^eT2 z}mI09S`{ce*V|+ zkbQjr*YJ>kdjYum{}B&~6S(fjLj)hgd5BHQ^y4Ap!4tt3kthEr@Q`;|x4=B~@{r%@ z`b#elIWA@NdFbUKExPI?P(WF<`qYP~eST%a79b!hDnzin z-|NhoFvKKnpVz$a=lA)%f83w5-RC~{x$foKudC`&9~{0<9J0LU|5Y3^k@dcaKKSF1 zY5ZqfIAkfX`k&wsbuYUi%lJ@n-dOML;gEdBp*0S1$~gGpkRQodwZb8fb5C$c4FB+b z;E)k&d*8(&Kcz2i;gG?;KKbF0$y%Szv*x}p9Fnif$Rd0=1f2vpSldJWa0vWK+>JW! zne}32l?6mMIPl%#(EKb@W(HE0aZO0});;+6eE zhqdq~^hJ0R`g5DFKYn>}RRLHzR0jihh+^eLOZ zNxwE9HD3vAgGce)#G~}MfjgAmEx3bR$SNNL+&{E9hu)~;9MV!}vwt01?2WN;-WZ!- z36H|uXpLWnwKG3{qOOPT%^Bw1KV)3c*!wSatb2*54F8L%bU{8UM zVax=bQZ$~JZ^W%DlDJ}APn}83!wJL|93R7dV)@DaHHtEI0y#d%-@-kMQnZzQyHp9w zZNjDz-=wmYMq-Ht8(rf90$lHyC7xKAV*qw>V(V};RhiVo5SIH6Fc6#A9{8&E#NO*k z;DArdf&hFkQkN|K_%r;o0)P>+wX&JStrJ^`dk^$;iJe6B45h3-uzt9Cs%4^5T4DF- zoz_I9cjAQw&f1G_jh_=sEVB2I%f(}h6{keHx)N{9G<$x=on|GIJXx;sLAK1_@vMJW zC3Ae3Epu9wEz@-1iHu(23jA6k_=55hR<{Nyce-9<|6~29EUnO&BeJN{wWlrWD;(BM^#?eBov!V1&`f*pV zk~utF$sESFhwvYR`SuU!|3Lon)>I{vSfZJ$X!ExIO6CCikwzbgx170(HV4p$H2N@u z{3R*0IWl9pJ-cwZys&M??5g$8?RVX1veVDJMufju6;ckzMAF9#32 zm+Q$~XK=iOqr5waXVE;1<6boP%81AI$(}`#zm|9Q6fjSFJRo^&yK-&h{Kp*493^hs zu04g3(R&_`l;^SBm%4l7U$B?D7e;dnp)UQLUl1KIU!fS5zcgIQ-ZZ?Jm~8dLm2ePyQ)ghE zh4ctZ?^m(0b>5j{%>BdIjy{adoW$}I-ExGMe_$f{mB^V{Rz^&~)!4K>Pt3N90a0O* z?t!j=0}C?tGFID`#+VA0Mw@n{Q`q)=NqjNK0*(ddUSS337K+Wi90lf*_>_vI!Vekm zm9+Iij4g8oZEfSdf~8Ua{N4Jb!Vj1m^6rs1-@8$~8`t%Y1l+xFN!GoW}REmiy?@pVcv8$S>E8T35# zeZ$4#-zDLCG7hFZN)8UH1XgYIG2?!;{6zBg_`H_g|edssR5 zByNG|Oqb(pV8++Lu(X>g`<)bguyl^OHf8D;_znoJ?8!Kak3qu|PptJk6;`S0d!WBA zlh4M3UaDN*MfKBE!fh{ztWxZx-A~-B+DWGt7S+gjTp)MD%4ErjE4~K-Rj1HZTtSrhX-GhE;MvwS7*|d5qz_ncd&6# z`}s9K5z>Eee1Zf=SN=!(B=)G%FNse;O#1W_tVMt^l#z&VYT{)&tP~#JPDS98)_$A;*tOwOM<1#Roz2p$%C^CC}kh|zf?9`3;5KIc! z+nx9k>>sX7G8o)NUH021$bY07j2p$*z&%9SbshcIgel6@(co2yO?fxCb=w|nPq`NT zaVpm`4v#=PZT^oZs?qVplq<)Er~JrPZMi3_+M?*n3P!$e&!$)?3T3D9o#6#z@*_XF zn|mDBaRhHh?&1iJj9kR=lX2Xq?4m592woH%D)?0J;@-d>^Ghh3DS4Dfxi^?{FC~sr z08U-E=b=c!?}A?ir+>0%R^%e??c%uZ$>^w0DC_u-PbiBx-$hx(`7TO<`@zU;_smEO zM}=cSX>?RJGEb0?SkQ*a|Ew^g34sa8%4nj5!!sI?2NV?6w&9 z3>O%x@B~%@TY;ItPv9eP75L=SCmSW1a|6W(gKYOhkp=Eqk@7FDSoeycp@jt8aAzFzaY(BZKo+5VeZ|VOz za9RV$Ib+jZ&qDX6@vNGB0B0$?bpcKK68kq7RA1GQretzBp5=TKw&|6+kWle=Ca2k4 zcLx5S1Bfw0&V;eF`v|e$V)4B7dyKHIsiHL(G9*%$FwSNF`-; zNO0JRxu=Hb1-Py9kDED{|Fy{Vi(C1(t@e?;C;x7tNZ-|e;=Vip}%yAbC;MhOlg*0SQ5hn!5uJPu;c1`v<% zxBN!~CAg&>J^x}bwQi^6fH~tB<1`QdwhHLbVE(akF7Hy(TKemKw{?F@4)o#OV8W{g$?C?=}KIfng)?lkYYzjgD=w`NOa;?~+3U8gUywx-ZY2#W!cwysN#pS$mH- z>akfjy=Tr4n>X>Z5SmMe@0rutp5M*N-3^@+E`FO5!bLae?lLp>$*8E zyun(6PIQdz<9ddEjMIg=`Vkjp8|NW9Z0?{Xg0tX#*?VOFaj^dp%b(np(Xn%~R*@4@ ziQzi7(w&si&o;d#Bx`!jKdt*Ab)D2L`4{SXs0(i$QvWa1{VXYCH}XKqXDqxYFrB;$ zzpV4@9XifOa8Kr#%&(37v*hma`EL~xmrv@{aTMM}CayQ{|gVV)EQDX9?vUi9NzQpD8#^W>M_m_ZAy$PN-K=qxMczj=o zttfHM&S4*R6@Tzct>W>m@6ew|1AqE>m52C7<9E$`Ctr)lC*Ki%SN!F%doO#j zjd*991AAsy_$X2R_pBvr7%g-rC zEq3t%ws35u?4v0E-D|#u@;tns=TNGBVS+c$NImD#f3?_eqe$H+;RDS_QtS_tu6lTkXkDbsV9>b)pC@ySGDNykDc9lK{;H33&2ZlH&8Hl{Q294wQ}&>HzIg{; z?;_XJ4FOHdc`m%)H(Vd%on)>j>Z3wG zN16KUGUJqm#KOOa(uZ;y9_H11ZgmBW)J;4Y6f`k~y-oJ`$?(PaQCFkGE1Ue%8}M*% zz}LJ1-}8q3v8lG|N5^MX7x3((^{?AEQ%Wd#l-qeWgl8g~_-Orho^9vZcAjmwujko1 zo|UT4Ugp`$JbRgEFWVcRD63Afwt=x2%S-p^wHdBRZpqX|RoixLLgC*Qtxe)f>9^N;dg z4g93SxrOozu7A#TEbr`0x7eq0J(YH5{LwuB2ec_Xr!(CWY2%qK;qm$9@RI`TEMyKP z^Aft??+QN|?kI;=UJXCFobjDb4uUlNDE8Sbt{D-=$Vrswk-8`u^FHL(>%~|bDJK}a zJruJe|Jv!Gpr~!7wt3Gkyrm0yZ6b}_Tf5peZyVFBsl+47=YA=5QuxlIr)~3W>$gO{K)tMWTOyB#8zX0NJtf%o?MUkXjQf))1&CU^|pnQRb#$Yc;^DSm$2nlWlryF63@U)JX9lVP7j~i zd&$h20LqEQGi&N84=xKdjp`X-N{KU=8p3rZi!vrAWofrq%cJ*xTzt*2a1}VOn0=<< z<4w~n2}&3A1u?ogsTsTRC7*|#Miz8nZ%2Mj0OcgSBrz^p+Dwfzni`_LZKi5%ZqnL> zCT(fc2oI}!FNHRZj>F8AEO^sE+UrF*p|yE8{hamh^b_2zd(Yd?0oYDw4Z6{$ub;j) z|K)zdzx(|(BwoF*pJEe~b0 z88v$-`O9>stN{3$0LI-2&(FA97^4x4&m6{lgx~n+-h+pS)_D;gUgA9q5ATGBU$TFg z%ER}63*G|T_%CCIr8s|5~z?=vz>CeLp&#&_FIa=(5IlVLX!7J_71v=(| zb5oW)Sfi&jEPk-YO(}rC$c~`DAv%-CsF)P`tfmdL-P#ltSa}kD@sx@9t;G5>BU7{-U3}$iKX2^TF9wHJ?kmTh!!$9i zDe7+OB3B^(-`Rd+E58^#uJQx;huwU00J#<;+wi@MOC# zw}yJjsfUQbeXQ^SYzDUUFqi^7#|l@32buOp1(euKEi<0ECh=zFT;k1sO1;~lAy?}X zh&LPK=nqc3w&3o{V&;eRPxPKbll@7H12UX(@Q?Lcrtz15;V68A@B>|0D?Z**j@MTV z{_}A|N}1?G<34k$KF+()i^g6-FN&_T2HmJPY#B|@7)BGjx$TvI&b6L{TJBh_M zoMNTiMHxX+C_0LsVxSl)0hB;W5G9xrLJ6%bMkgnE4rYjsbnh)?4N1<)^DFRS)O4h2 z@2dRe^TJ>1qo8yDnU3^giS^{A606t{df+2Oj|%VjdYgLE%hbI}UHD8V`{GS?Tl1OM zscTqn6`t43Jb~AIy{*`6p0MTC6G6+Z`RGiGTXd#9Ovm>omZbvc6&k;}i8vb)uSQXN zcw@b5{AMxt$I-sr_vbf9aQ_*V-|P|Q^zob9bDEDc9-=eNe#F*nSQ=}(SJRu0TTdH| zuV<5?*+ZQ-A4{Af^XM)3OkMF4YsChyM&CVmDY=71e&N|cJ^JW*jrp?E(0oSA-6nb4 zBxjqnaePxwvu?JnIq!)nnoe~_jf`IeIJ$x7jf|i0L)YMc8VxkTvoGEzC6MN0*RlA{&jZ6Ph-&57Cihfe!wsq6>1g~^e^{PYA ztFA{LmV};FDgQNk)mW9!Ecp(f+125E4j2G)3p9z;lXW~4nQ#~Q%<1}AmCwwF|63l` z)0Kx__2){Q%4dpfdKmJJslGVu#C`t*dd}(aeO|q4tjcFzGIUY<>eZ{pYjNLy9glt$ zy=tt=XJQAZ>Q(c!@8oOW5kB)6{~+Jm_u;SOZ~7i_+tlwFVl_U~sPg4k@Eg6#o_38G zV3)C-n63|W9D0#8yCbK$fw3W8raIQiOZ6KK!)?vVXXJ5J^sa^tjBQR(Epf>vdHMv^ z3Qnx9RHmMh@y;1d%v@d7*_)CjAd= z-vko_c*t1d8LRh#n#Mxw@8N!mIA6|vgU%4z zm-h=4eW|`&37-BdY%o$oyAwpwp^L|PN=)c4zIU2(p{u8 zJ16hy;x6(qCrjY>j>J`LtncP7k{D(0$GeLf4N+D50^LO?u`g{13a!qkj(eYN!h4DC zq7OMgfxP9kA*QOKpVRsSc*dly(Gwf)cUrS}b{zYH&k9Pc*Y^fiH#`+kjqKRofX%`e zBb?TTr^2eUsQ<+RIS;SaZHlBq&v(_+VW!gp|z;IW}HVjAiRX zY~#KgcRyI8G4f|Qz zyGNekJ9)mK-ujsOEU+qrXJa@I)#=M5msumc6EQf zb%V5n>|_eZ_vvS_&R8~Y!<+UY)H!PiD*KEaVrTf?5T3tBpU-Y^TldkY$n|yh@bx?G zVZW)gpMBG9{c5}0`k7-~_2m_AYx+wS_7LtztbfyfulkQ&%KE;v%Pz3Gmv)*Av1L~l zxvkIey{~fWtqawAF=dm;6K>zI%RYWXjr|V!eolOuW5YK4W8@KEuwkoxIQ7ovn9Ays z-nM^Bzf!qgMW0UXC(jvuYTW3y{+9Zu=JF~AR&A)`zKo@z>e+Q~**Eh2^M>fMsP(_IuU_}2J&b?d$oI}0BFmQ0 zp7&f|^$+r_UE5G^{ebtcrPNywbNq??b54&k&+dBbeY`W5|J=X6-2T;5cUOBhxviJ! zSBCtbA*$^7OIz$IFP7Uq3%Do$#~6M2xZC9gmha{J5F{c14ZGt^uEBk>RRR~e7T z_->OSqD-A{Io->C$-i74=(c_xTW>Ao`%Uac7Z}@%>;IsQU3i&{**N~;>q~CyE8HKd z_C2g@DEG(m?QFjLHE_IgN4-_@&b`0B#(rgEz4e=i##Qf-^FH;~&pvirE9Klp9mei} zoafeC%lVJbPq?kU8S^VU>#dvR{{8jV(Q>`F-nv44$88-Y*Nf_{C0u{Ggt6c7d;6u2 zbE^yK|Fg(+KHKZIE?EDDeI0!}pVO^u9`}6f>zDNN9!fg@@I`^!`uR@AJgD9}p8A92 zUzlf)uwFm^U{v+o^>5j)cCWX3=UUIQYnK^=6XU991Cwia@=sIT)<7BSiS~g*daHTEAMN`${LXIV zUXeO3!DXNFUq$rwn}?|Lc)hjxKi$@e(&iSobppp})H}x>FpWA_*Sf9eH@syZF8{z< z_4YZw?Az9rFI0z@O`H8%I@N4Xd}l!5TWl{ocHPbws`OixFz!;{= zyKC#MmllzuQqEVnt+GE{;-4dd%`a)|vnBP`iHzSD{M+31yX^mX%Wch-vD@ypemmH0 z9V_P>+*TQ**_>bc8+%Grz4dNsrwLfg^Xb?N)0cl-cUyzxK6Cf;B<9hEKiTuw@3t2( zrk@|Ay{FvPFORvc0bIu*H_T=&e0h;^=i3I(FY%9G?r>XWf1Jy>%>wR6R=#1sNU5f* zro^zPUI8xh4_|&jo2_2D!`}#HDveRiD0)9wdUuz$?@^!m|l12%pJP&*y0tOZI?=pS9&i{QidSZ1Wd%-lG zon&8?G5%^3`Kswd7XR#I41Rzt^*>gzH&GJl!#MisprlcPDW{nCUq9!zK2AUHqn}d~ zhuD9ZIMn`2>eo_^)4$t!){STTO8;d4jDCMezZ*G!3t8DlJ3Np5%$UUVW zwVeNo^Z9qZI)7n5OXQ?}7W;y`UYj4!`7qAs-BmsR;k#a$U%Y}DE-XlT%o+m z^|M@Gpr427=N~w(=XeO2ZBN?xuQZGOBImEBSt5_{Prv7U4W)qoiOg4IzasY?H*_aC zH+RlYqdZ2R?xjz`oZrEDch1Kr_O~BRw?tl{jfsf^?T_)@d-?8!!~yDmq;nn0^}ZoH z=O3hAF5ex?cfRKSdhXBVyg%hR`u7^w!JHqa-UaG4^3FC&DP?S8ntfbiy8R;G{XqNf z81j0)%=MF8SJ#^7pX6WO>5JZh`ghZQZ`v#1+(KE&bpY22=llCwBDYg->n)4t4@KU5 zgm)Wjct6)^_1QNi)2^O&zu4)vI;n4?{)e~hnD0p_od3JT=J}q9PU{yr!PREwU%776 z_#`E=DSsDop3$Rg%?~GZ2~uMK>l_MpWS$N1H}Ff1$V3N|CnXq~))tFx!4jp}#Dc3Q#hSEbA6~>|3ww?HJEL6?rSNts}Q6T_Qu2OrLB{ zazKb|E*l<4m2*WXnVvqQYsaC3--bLgjbkInVC>7HqIVaKL}z~x zIyi-+d8uOB2Q7SoXXSdM>47CPYTkh+F3=fF{W*6-5AO|+Fp=M*c13uisT#T8-=U2S z;o+uN!fmy;VrMX5X$1B{;ilD#XVmPC3OAi!LcSDo44vPi)Q%_DM)mF7TcO<}f5!L_ zTkWgExVJ^Sx0ie57kx7@+|-}?4LfYj^M;0-EaV;|K0<8+-|WvjU+pA@>JXi&fxgVo zq%QC5;+tQcP->54aDNMRKDO1ap-%o!X`lWz?X=ZK42d)SoO*Xq>W$prYpZ=WBg}LV zIzBQZ&h*s@TWuiE4&Tw;RKoL-oS&!vI%Ay4^AjnYz{@cg9EY)!ISFqU&V1g>Sc{y$ zp0R!=)mHg*LRRHr#`|?t`9R0Ed8TQCobnSA7uQW5jZh+uAt{@@6GK1_cP(a(W%@@wv)#88ebi!xoDonP~6X0+)reO#RxWBN1K zN9f<{9ACRF$|QX|M4ygWV@%I+4||rHYU&@MZ>#B7{cT?TgKz!#%eK#J{fb2YQ1V_s ztzVH2vEdgT#9{h%h@$Xl))~_`~qfLkCmt&~6Ux&4RJvSiAbclWltg8L`wVL{e z>6e3kR}5&sUrk!SB(8Y=d$(%+QXFfLt!58W%A`-SrlnsK=gg?Nl@dWYH+x3S)AVgW zeR_}czGlXVKFzj7nD)`19o%a)hnn7{Ur%$Mnh;_t;3(s`CpyfuIXD=*A#5la$7D@k zGhNfyOlL0pbU?@HUlw+VA|q-*CZ);-kw;iqtDo!}>_P@pCUPi6QDS6%zA_K}z?&jR z9N8@Le$fwzji2PmI@2m2XKQ^y4zfspeStU5@?bSio5)&3z9X`s3y-kRzn0T{6913m zJCTuzZ0G2rE2r3V#OAM&eda9t$vO6m)0dQ5_>S5W?CodR*N^-f`96C^BYVSH_K1J_TNMVh7!i#Kh}w545K7Ht~DUWuQe$<0`nc8M`9r0xTS z(WcMXAMYycX{x2YCki7?G0`!mk?fTd?=qTFx%Wb?Ep6It_B8g#L9?SxzvkH^ww|Wv zvm;Hna{j{NE~Y5%i~+W^E@OI{9;Hqs{WZ|$$x%jA z4A%`~b*570jy|}n$&+a?J51DR*<;NRDgzESi$ z$a6Dww58CF=%+*{$-HX8p;^>%V~cC1j_83xkh3Q7T=r7Ik#1~n{c$5o{Ib;)2PK%Y zk3DF*F19J3Jj9jA<>kG9<(*jQHKC|R`+ zaNX~WtycUn%s;zj%1(4C17}Jc+Tyi?9wx>VbJlW=cmn8GL=Kd^#+bYIHAo z`tV%jW2#=}ydfezx(oRL`Hyq>%sr**WumK${982g$A+SZYIFu2eO9`TQuQ%$sy=3G zv|>uq8=CSMPc>g4zGMbux;OMOaccg*;ud{OT&|ppKBld98qfpccNp_dQJvE5R2HRwuqH+$^>gQ(}T18gljfB7Y^ z-saMjS~cc*!){%f_&SS@M&9{HAEh}I|L1Y|G4D>m-(|2e6~*HuTZG<@t@)IG^zkhA zSF?Y<^y8<=Y3;<$0-cuX$DF$GmMH~Y!(8H*e3)EstH7zD_%UPG@0fu8V->h86rX0f zJ`CJefkQ%7|7M=cH9G82{F~M1=p9y}e-6dhS$$uw(H)1Xe$TwmI$M>%HNMa4bFM@2 zfv!X*pQ1T7>NJy9rzCq!+-d8{D;LyTKtFc*Us#Z?{GhShg}KI+Hl&5;5+^CBhJTXIGnb2 z;BVR=U*bO4VD!VExR?0)@GQ@Wtblug6!G=N9^-*5e0#;eH%061x5lZfsw#U>Is|#Mgl7zoCHP! ztG3}ZV%`XJxB2AZWUr42j!Sf1O|dm^i|!J(H$ji5blR*JB|!E8&7aqdKX14`O#E{Xv+nm$SEq=-u3p^- z_J~c5Q7M{^ugLqX`#oY06RbU#Yq4bs_g)`n-R}`QlxXd_T#F4!SM53LejodQu7_L) zIwo+fOHhjZeZT*KzU$JI{i;uJeJePO|LXeGKe3_szpa+>?1I^L!v{J%ZB2 zdAd=_3?+VoarVp%b>1`Q2Q%k?z?{F0IX{RwKae?pD|3B7Dsz>&+mE@M%G@nr-H&8` zqkD0sGLJ2~zYjOgF38B?UMh21)_V%`TGqd;d$aD?a9Q`V=4I`FpX*+yD|uMv>LGIZ z$Q(M2ovzFunLDlL&BLF1{i}%;TD257pF;2I+mB!Q`1;hd=om(DU;HTr=Sn_VnNQaZ z-CFX+E98R{{B#+4yx^#w(4{)FjHyzYIWXtrODh7(`VhBb7__L^6kLLC9_ENQ*;;a- zVo!k2oamgzR$Y8=Jj4W5{jRgn%VJmX9~-=WHqhGz}LKiw?(Pq!j_;7< zJxxzVr%J!az;k7zA3lpNG0>*`c{(-$#~YQ}WNf@&z`sF!b3YH$)eZ!Px_i8NP|q16 zDiwp?CHYH}R8|LGt(S$|LY6utc6P$lLn`sMQ{UkinO#a2| zGaXM3&7SEOu|X#$k~g>NOffs=rWrx{?@= z0qiy6gC%i=Wjro2FHWottZc&n>eD-7(#{MHschUr9@k$=%&)t-Kf3bF;IWk#@q_vF zj!9{aTd)zww!@qP4aj(17u$_gMa`*N-iITxQN`X==>2MFWEs10skXEn@-*H9O!MDQ zbM-PryUH13r=qyb3bBEJx6PHacn)&F8Q4;+%-o)#WKV$){R3-O$Y;|C?tB3ClNx-c-k|7}Pq& zhIlpKQ<^R!Y#b#GTDan`b7^Nz9k#>dh)k;!9)G&hy{R5r`8xULoZtn4Wi>d481>D| znY*X32hS!i>)FR`%@qo=OZr;Q|4Gi~8RTU>3lDqh4mA&Jli21ZYk65mAX_}!h`f&= zr)F}>o?@QtCI_2`7-YHtqnel1t-_&vc-~wO`PD4*-5M;4!95meYtIJ~>#K*uj6A|q zY-?`Vz&cTEZ<}W)*EJyjGjpzByRIn8+nzAudy#`uXi<-gx*PrKu4q*^%3F6H_($yB z8#YN@ovUH3R*&{Q&w1Yurv1LOf6YJ+*n_rO{KB*xu#t|{#3>OteWTi>7^+qPFR?|u zNSg(~Y&x)vz|O=2U*DiJsPYQg z^Fy!ZfpxMTHyLeT*!a(r$Rz^6$IIC}F0$U0B{S&!*xzIZ=&4uPV z1)3vC30LRw9Pj|+v2Y&wU_H56wa#eCBkLXae8xLZoBw%!W1i(V=H>879>!S57|Ynp zxGOpx%kRcmuen4W##XJvnBP>#H^%VVGL~u`##id#Lyc*c@;3QPy?JTR!0WM|due%B z)5yD84opLV-;Bkx>NbalxVExxLV#QT+_`lM>xP`PZ!Zs4$l zGv>~zOP2d{fr~twn^u=M*IYM(b*6((Q**Mgzj*lG2=_7Z_h0&1YWG|YrIGJa?T3}EC3?yfn^d+C~OJ8JM{rfPUK1l8W!SRxp zMDV-hGn03eCEmU(%r%+MjN#OY)Rnba%(dg4>r->NE++@=7WPgZcrOYZW5zB@*5oZb z6I}A2$l?TsQd;}d$#?%iJeWFckUzohQD_s%Kf6=%&n^Hz5xdb@+)a%KBeaafgOPn& z<+-6*8o*&<_xPTbweROs7krnOK6&LA%^Rfc7TZTPPPF8p?Lyw!SnLpU4%$tu zH<2kXFUIB(A1twXybW5&srl5smx<54L22=+bAsbjjMyIhi#~M~|DsP_OTE^%j($FM zuY_V}n&}-LJ64lf3hdk`n>hjMy=r!e35u&wqoBaTB(Trww}54~_Mp+A;o5^Us>e znaeu*PX5^l>=<{qm46mq$-+7kdDbtmqix9tiyfongWcWYFPEU&Ffes(JKbmM-# z!R35<%r|oH1m{9$Z&3{Dvpnvnu-`Ot?-(>|sn{^0XaLfx-l5BcIl3A}$vK3nDWX(#v zplJt(yL9k}dH9BaLmh|6SL)IHLPX~y`kvPMorBQ*{`#GpXdBHZM8Bkv8@$d=^^#Ji=Y# z<6$8`Zd3QrO3@L03g48wj$F9-dYpgm?n|@06b4edUS)=drP4=27 zJ^i#4&8oTK9}((U&K$@unxVEO?Tep;v_Cys`Md!*;0+~KO65;88RL3nMJ%OX_5f|87uX*W<$#(9kGI;Rz zm&~bn?#ur00LS;4Ln^(1JmWZW3dsW_@(iI5zC@lO{t^M2JVR)KKjI64KYNU4ky1O9 z`6_gU$TWU3*~E@H(b?Z86w9xafhw> zDR}bb$TM~_7nT}gU3ooh%@01GRe2hDMu6B0^tIJ4M~?9&eDQ3emLlrs&zOQzZzMJD@j;;9_>Ph^F zMaV8j@n6NrE-JtS=h=rsfx`&o6~a4{gS~1CehQy)pI94{l2b>1EHrBcJ{GyXY|RnS z&*i))v=eipOz5$Pgim4LkoanzwZ<~yd!;|fxUbYjhkiLfq01Te%z)Ly(>~xB_@X|| zc5?B@9^?*Y_A`-pIFT>R(h*Z-qSCz55alA*X{|F7*f(+PqQsm+t}!Zv=ebJrEP0Mx z#o3ML$RM2YJl`nq1-l-iea|uOC30`O)D3od{>F7O*IT4ckc%8Gwa(sLyX1M0>(q1P z0uvbtdS7QcZ6f1v-pUbqky9TT=Go2hcCPnw9L8}!GAn!yKDqtXjUrc(95&csgR>H< zehDopzVY~wRmnKWd=r>ItsuK%eJbE6p=o<+G;Q!QWn(IRlySTOZznloBv!G^*)y@h zm2a@moQWM%=~)CXEqgV36ZIVYAhFfebH>evjz>L5&LLyS|EaQ$2xx@Q`b@0+YK2n! zIc@wScUsydmr{H2&im6Y4E#yjxul<_UAphbY3CW=6(Iy;M=o=EPqHhZKE-7*1h^#b z*WF=(F5AImd@TZ-dT~!bXw)~(e)h%hk%K%Lyc&QmM*h=G+|cH?XTxops1;HyU--@bqQ7 z6{RVQy=jv^#-U)plF!~|qsW>oIgmfx20uZ251943B-;{m-6lg<$6*N*MLRI%to$r|1{*l?duZbWktC zv4(hC`S>i`DDD3Tb|~n0^OY#-MRiaw$`Ju=k&k(ejnaO5T^xtOHTg;+^%6U%m*`l7 z94%joqh4GG_2L{8kfG$OI3c!!da;fOaNQ|#0Ol(Jv>DJrUG#_0ET^!;_*d#q5INC) zTWtZfkB#E}_kxzWa~pGK5_4xYvBHk&!<*_Gp-ETRYA?Cq7ui3H^@_vIzseeofPQQ+ zjIEr*`tJ!Y92}r*%v(}am$V+-f=$63)^HMZrq~nY&CSfP@l55>mt@w7PtR_BPnDjO zJ>e2<3;vP)K#m^vHsNz6-)6%Ij>t5RzeVgE_FMMZm-B z(4qU4z7nqrJSR9>)}v+ijN#axwX6@N(2MU!;DaObxp%;o@=w*^cagv4b-y9wX+SQM z1x=hsv9Uh$9ObH<6M9XR4-p3**oVE%36|4|FrhmBY)`MKKdYmm9+1Z|Mb@6KP#0$m+&qk1Ip$bPtJaD_%^<=6?p8U z{Ve2-+c?^Qhrn(RG9jNlD4TC)IZ{-(9MkKXEPVG4`R+tp^P{YZYv96lPbeE@UJYO$ zxm=KqkE-okPp*x;7S4~lDqUU9C5!5&K%2;VImNv3Q_7l4DJ

syavFMAMsVc{QqeU$(7^;7=$FY@dTTk{ZP1Z}Nx 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%0D%LywMN=tE%WW51Z#{3v~2e=ziNF!a1d z_pLC4p;N(H$FzQ4E7+O6o+a~){k-YOz|COjG9J?XT~DI!`JR9U*yJq z>mt00`vk(*apxb4gL@)4+KnIF2A(U;%H|~AWlnb?XP#KZ<}K+su!)VxDlU}&-J~bD zdbO#)P0|&7t-#RbDhb@2XtOUEwo&Gk%D~2go13(xlKoNKd;lK!+aTqYatUtkpd9E4 zI&S{k62Z+i8&-GWX6S&M*9dNgj^O6K#)LTBZ0>=ZZE?6+o+G%q_jCj|vwyLlW5FmL zH^0U{tG^l3chspg9XH=b`$@hVxeG4~hK|R~%$Mny`G2_I0Ix}Z5W6~y2mYagGm}HP zCZCh@j2x}GzVe}2rGf!Z7aR5QF0x-fTi>t#9&?Ui{4Ex0GYz8LIvWkp#N3k~x z<~}?+3BUN}Ie`(L@eg4yvWp+35v}9%*pH6hF=;RUIdkC|!=Bdhc3W2I-u}uj^K3F7 z#~Q=}@wE|5N?spGN?G5If7(+o;$z|0DtzUwG9TyS93C(f{u`X|m!z%XliEPKZEF*J zM$!~I;#2p;)}?MAF`ybZ=00e9QuxD{9hOsgTKeN z7w3QE=Na1L!NzmTHiiw-9k^~^-6 z^Q;!Vz3`pkq8@GV(EI50C%nWX-xq^1?bruf`#WEfx>4-c^33=NJ_<%y?fA-6_^&o_ zzJ}DL?q3|AaLS4AxBlv-_U)@kr;fc3{Bn|C=J)@}5sw>a$9JnqZ6FJmk>pg(sS3^jt2Ih!Fx(O=KPUtaa> z@{Rck*!}Uz?!XVavo%M2Fc#);7eD37?6jHjE4+@j-`|*-A6hve|KN-4M_gfPW}jmC z3Cg*@aVp_oCmf#=D@q7wK34W#wN_YL@v$Ur#(djLLca;Tp6)2Ln#9gYSv0N&Y;09_ zu{jtD#4lAUb6sMa+Rbwc&-;0PjptE3AK+R11NPy+eZ)V;b6W}gjL+xto38fWw)1Ll zr5fa|tiA^uyYnUS<1T*Uhhcju#_yD!YYp%9Tu$-d@2S$u=R$vRkOz38V>Nb(_mO{% z`7QS6wTO?Q+MDz<4Zt+S{p57ne=TtT~zVc=pM^*f*TCeLH{upnuB`!XKXd?^{uYU&Oia z$u{0wbe=JJD-9{$O6peVZG(5N<5}qD@+`Ec&#u@g`EhfmMfL328>=|SVFr9QZT7T{ z>&A?PuQ>)ttED2izD651D&18a0iAI4~t+vf1 z0~#0+k+z~xG9kE*Z5_4cUgLcTBHE;;+Nw2ki}HwZAX8$FONFjqV6=_ALN>DF!`ER)@+uuzKmv@<^GlK&0DE+ zNIQFI=i(IJ-9RZQqB-5v@C${1TW8P zTv@x>$v=v=${8RMtINA`(PlgSxYlO3JcaFNgQsS*EqN;Py3rQFan0qU}*u@9k}Jq|DF;M+%hODt#Y^Q~6@X5?E^v5jvbzTM8d`K0?ulSo;l58>TE zf+vlSSp&A&ZOAhpBDoByz8V8DHy)hC`nkwb{)@@hTNmHD*}#0&rA)HexfVS*(XwFi zlFe7AOtCmq3M>^V6D@Yequ{|*^n+Q};0xg1p@kOk|Ir26j#J|wv|HwKzQ9$_Pqt2e zb+R=zdAucsvjzm`KgXI+ zozyY`DZfK^wDV?r|Hgs<@{$#SMdiOrHsy@FHJpt@+kY~aUOo!`4aor*g5 zr>TIn?>}SpUQWHDPYFQ-*63}>Y0cx`0=bXT`DE^+JXB8Wl~+dT>E&{TKDi_=BDm$- zI-SjKT>!r%c~3Gv(SPz=w`R8^FGTC+er$dvyO91qMGRV5lPUC9*E6gvYw0uQ=rmgN51VOUS8NlisjgL~+My^g$1L=9% zCEtf|m6&%m@IrdbJH|0+Gz^G&r$uAl<;7#(C876BZVBd}8&fWav1ASF{NPp4{ThiW z$KDftmeAq|upZG&=xGaiPyZjHeWB^+@~Fnxd<3C|O6Fra^D$lK!*F&!(4nY-^Ff~e z`Ox>eXXj(3jO92-z^18bCm8=@^Z%yH-lX4$wqcXOn540O#g|#e?mpJ`zN*-C~ecRIaFb8{OZOfWI#yP7J zw@u<{$vPMPx7f*?;LOnio@Jk+`&4g#-hIW=u1B!PiVO_5S&u3`-Um}!({x*9!9=H{QST0@8zVP>fd~Fv+DTd3et)j zu*XAJeyA}WJt^lWxYPUzM(^JGRi+jbvBZy;r}^twCA3Ig^{WzFx_CYWZ+6R2)pBrK zn!m=Rwd}hpdPZuvSBo4vqD2lI<4n_&TI6@MNA^L5vAxg9#$@WqgNMy+-Aenr3Jrnd z=urCdwa9w#$x!s_oC`NMOgl6=gVI=Q*=eY?9G+5kX3kW{62*Br4{^R$#mKTH;pt^( zHVkrs|6P`{gsZGJ?J8?mtnW3+>JHhDd1lmDt|DG{?>Ozuhtst)9oV_cc!cgzRXvP{ z4g6xKZNYc60CC|Woc+=oI;I7>%9H$koDUi<H!?j%3`S&D9XUXU1M zBMshpJ?ICI9a9lS46>d+6*xgVAtsnobmwN6yx1O|EJsriddfs#rTTSZ8J6n(M0`-tD z-k;zvsfSp%@&4Q+^;~~$J;&2yV>UWg&z;nBz0{L)ww{|VP!IX~>#3IhnEUJTP|rXe zvB>cU?zs+^es>9Qt>bjr*Owh8Ha27C2ByN)?r!Qye#sCyDV~O zBlT=6i)>*}I{{raeBvXaUkYwa@ZW*Yg^4w;+j}AF#+G}o$SH2Z*5&dPl{s2zMZ}gU z_NrRT6=~S2dIUcv7JpaHq*yBVNyT%9sLa{uz=(aq^Pu9ZhVu>CK@i!{)fSa`4e;=N z%C>P0Hp=_d;+DlaC_1{*R7tQ=m(ShewU?H|5J-sTRB@H#d|G5fCe3=i- zTHwQUE%4D8EwDt+uiYr+WELMqW^(!#E%5Q3THtnM#lhX`%*hut;#Zi9gU?Bx5ye6H zl@S74%aKKF;oY5Fw{d-e>pm6nA{Pt3sUpaK=LU}uOWl~^3;sn#I*fU~;0`Gxp?G2L zsz*-rh(0}`RqRAuqtG=x!}!0f1&;5|Z?Ur8z2KEFb`o*?@w1{D%M(Q|%Ld~LO95m5 zd?B$2uU|jhhCdGQGuMi|-hf}4m+uF!m-B6FEf14N&I;r_!3rmN@IUs1k;&V~F16Ul zdMJmpxX3rrR%_`dpPW0;O`XxaCeIph5wemq=s}6uax41t6`Ze83-4dkpI`Fsr|u&3 zp;l~>2IDJp>}5F{B)L`g=?2nN_zO7$M5~}~lV&#kt-#mOVfVfM*P5A{viOXtj#-8b z$E=LEvA@l6%*ru2W{Dg!A=xoYe7;X)VhOcgfX$v9%yT%mE_d?|Z> z*6}Oj7F!xFWegqsx60D=#JEM4?d;X$e6vJk4kly|W7scg?9sN1-j-CKz&X0?Wn`TG z92=*BZBnsuFfuL$+{+k6Ww(qM|4aXSh8pRU!D{ccZk9f1a(>4z9T8&LWF~9aau>?k zmLohHu(^%vGLP@RspUkEBeGKG$+KH0Lmzj>`16aoU#0Wsj>vfKAJO0EwiaSIJ35Zd7au@sE=-GMGaH?+)`k$&j5=q@|_Qm#Afv41-eMU$=gEX38kb!^xa& z$r*z(x20Ob8d;Cpj&5B*pz0@_gr+jEir2I^*Kc$jch2>>)pL|H>K9WGn@KDp?zq^PbLF zdikRFXBL$y|BQF+mBaaGANhfi%I)OuqdfP!mvDyHCAYoD_o4DH_lmTV=N{_n+BKun zv1@weUDUOg{Gnansk~A0l9p3`?e6K7eUg{@wv)eX_q0kQN$LYOE5qCecTTI+>m-kT z_tZ-FuBnwyQpe7zm7RlC+g43$+ofrK@c|5-?5nCaAO}HKCbn^DDua2;(EW@$7A=@* ztXnX%fFx_bjOY0Jr|-bPDE7;l=qm)aO;*Q>k(*`i@%fxvk3CK*dqL!anF8NOw87}! z2J7)Tt;SSOvn>kiq90ffjqHBT5qPk9{qQ-grP-{LG<*sNu~x))x0Lyx#Pe3xkgSJl zW$G=MeEF$v?qv<&=c})QQhazFc2)HZ^V`jw-y55A+v4|UZjH@Le6Hs*FZggRoyZs( z2h8;p#(f^o;4scyvsX@H%w@i1ex2macyBcGH~KaiYw%vBn|no)@s@Q^gRS{QQaQ=7 zb4+D}L$x(3t!=G}j`s$1IWpc3#{DVeOYf^JvyJi9Vq+W~*O8WHY_8Qmi#FH8zJ7E9 zp2OpaEHa9(RtoVwzb=2iX9;qk?xl{%1K%kB2+v2vkM3UXh#W?@CguN4OS)j21b;`{ zl;*h_`;6|D{DWTc>;5_0k2Fsk`o``?{^5+LZ~D(*;kSJJlU^1OpVRkM+6CJ-u%0F0 z+U|AyGv=HB^BO)B-A(+%8Pngio(cHhcO&yZ%sJxU^q-#-e~YyqIgI?}oBs0=@ngDQ z<{$JR-}IlWyZL7e|G-0i(|_8+{IiXJ;J3c%KXTS`_dd?j0M6quE zfqz@wV%GR#9goNw7aYAQL$fCQbL3{h2OIVi^R3SjkaJ(G;Dg|NWB|>-eq3}EZr-JU zlZr^P@5LwY9K2+|0A8{gjIe8lbMTVYVCuDllis1c?m;O#1_6I2+IoK5gtp6i@~$Y} zJO_PdwKk|X#DA~xU(L_7{13N|@tOWM#+Nz>dt9N7O7r0(;XAm)5&3V<5c+S*-G!gl z!M|YRX-I}X>mLdWL4H|@3z(l+XN2>NGucbZPqgl@f#f6ZR#+Cu7$fM4;g zT{?-pZ&O|e|DFWL?%8!|<WY|yS`od$Szx@&`W8D zpK{kgFQp#A)3;O39n`msvTAn~R(||l)pm4{)^-GXw|)Sm@&cKw>&8n5d`{W+)g4P<2k$09otS=jG*|4FPoJ?=f< zL|&|)A4i|&P_D%3mv6$S#nZ9*zegTw)MZ{0EC0|K;}Ve<7hxN4B}wFC1tgKP={{-5 zlm%Z%tol*3;r)%KCGa?$-ju&H zg`lHq=OkZ2o$IqHnd-$8`08wt@91H!;T*^-K3w(4!Ih4{#|diB;px{F%`vGxA6`7S z=zU{SYiNoiBKp&%(PGJFF$@sN;dlPqhH2)ic!5MeOC`>%xW&t!r`fOyxix ziH@)Vdu5klkgr+|>h+>u{lu8wY8|eQewTj_U<+icTX=f*CqH|Hy^wDs$+dXY>1uES zbybbR7jpr1CMY!nJG0(3$iGM7ySV`0|5ljJ=B(vqI`M4plRj8w|dVRn}~=sdjS^Wi!dm zIfn}R4K6ev#E%zy4qs>rI%O@_6Jj4GGOf@6TY(kksJutfcbOZ7yf}Wohs=>Kzk)A{ zk6*w1ioB)B_jG#(=5OHn9*E3jtrm;TrNq=fG^QNCrQN#BI9^U6ex2^cwi4>|SI6c- z&U^R-o>Jt>te3qTcDrN)BT%g>u~uzaQVCrm+Cvf<&f63 zmwM+pjNYu@@Lk|htB3V5?d2L{>?nGW%+M( zuyw;7MPl0`dN9U&?so7{^GN)~v;s?~;w*DuMqt8>Tt@8i9A2YUWY0xU8Le?x{TzBB zvgi-7lQF6ii};F<)=DhRBh`d(V@gXc<#aX484U%NgV=D1Zt}qO>xWOo7GQx&s5n4u zvHSUUhvT1?k@>==qB+V%t&7y=_pjMb2#u(YrHp#`mNsG#iy!&X zRYUT(qMyDt-BdZ!V5|rl3ybf)bwt)G>L1JdGS=2MWi*fBdm`xoeq*MQrfckK1au


7)z|EpQAS?P%BmKH3Q}xo5GGsDm0wh0!LbHsaS*GdU z44K%Q&ku>d*zAnBgKI^_on5OYbf3J;UEx zOaa%PIVGHYBEAN6EihBXI5DJ)N**&@BU$n_W_X~W@|B)o`0Wt-Y(0(|8mKk=mPBq+ zv?jZIQY<9#$=~GntmT1rE@XmrTKd9=4Q)r0ny&gd=Da@@ePJduj%u<0`0 zLas7Z0%od&vOQ(sMaFp}SHUxTLav&L6YV>qp;R0qcb2raPW{EU+W9DAS zDiBIDN)KlX+z==+iKBBxP3Ibx&J_Y4VpI*N1#F(#@Y@9j{f@6u#CJgTn=Ub8;Cb`J zK*%`W!?cHVWwU@lYpFeXiuo%=xInklwZIf1d1}Ux+=xy zwUPgOtd{f<(I8WGz!L9Wgs|W}fs=Ji596Tab?U4mdVnoO|8;LGW53p0t?p$5R5E4% zpMAUYc>Rc0NO|5JeAvxoSOpKt@ z_(gd4_^myQN;98Fm|K|ndy8K+V>Q&GVA#+iKADUR_*65k(kDh!)*B{0RdusS$S8WT zPxNA*BR)Ou6Z@kHo$G~0QZ9Hh(r77^d6*RXFEjx9IH%Q5+fp*f~wD}?8tI>C49Y*4J3dBBV?Gg``!>W%phgBj4mk77qQ$O4kG{T0RmE0i}(JRvshrphf@x?SFe7>87Hl>2@_9)wn(v11*0qsXg$S~Sv9L?>AE>r^`z^GHENjEy)~?k!e)*U z+N>!+j-{TW3J8MLXb^FO5Ub}nX4xEB&ZQXTK{00R)pc|V1J~{1_oQY&2o@_W)H7xh zf?hb3DT0K%#~TOz{AvW%Q?BY3mmaq#OMUg zK&~FSMa}EBZrzdX4?xN$s>xBkWY%j6o>#3X7Y`&hkS+!iJBe$rD>vRw4 zDIkHp*eP#O!v&Je2|-}8l@w#Ry+w^|6fVqpV#K#e58bS0Fl7?QX5DwQG2h;-28)Dd zx=8ojta`TU$jxdJ3@#yze&wJM>jxOq9<-rBPDwJCe?JK zp4g#ApDQ#o&((2C$H37YdiEAIutV_UJ9N{{s_!OSzJ;emTW&_`vBtu(H=~EM3#pZC zm$@gQLnz`iOT#o(a(5}eXvYIN@*$SPlB^zL`OPOS6LG=SJ=0p+U<)Rc9MywzxJI$u z#k1dQfd9?nzsur^?cxkgYsA%4xvB-5IUX!p&*X|)g8&@CdYLD7yaiT{n0K(S#EJ@V zjyzd={O{KJpU};u|08t8vxt!aUmzT9@Et-A&5`xzpAB8pAZcz`v@V9L5JB^?*A7iTv- zyfOh7a0Z~8$toyDF!A*gkO?|njqwtX8q8sN;=seYcR&y1$$}~ciBdtXM8B9@BW1cM zAo_(Y_ll6ms5pV^S?)0+_Htc%a^Q9}(A~P_4mG+PnyKC5<1;T{^BsEV4srT{Kpvy= zKvVgVThG8GO2gc{Sap>IVe+2b9)L*_YV zo>S&YY2GGE=7jbKB9)}!A;cb$Rlb-z=lV3|062=2wl{~|AGvhG{&^m(pFSU&K3Ls8} z=5zhtaR4M!*ti~2%eYLjmSLm~qBK(t2{@S{9*VO9HfM?_hlxFg49b+17`mrCu+PI^ z~_2~r?-nKVPZQ5jFGKP+tt7gG{xZ(-S}J;FVXYc)nbW` zK37F=)XmRT12<|&#&6Uu+tu`qdThID+^&bVtI_S2^VZ$FNsuEeMm^GnVwjUT5?eqc zoryg66lFcYw4I}I1P>}u#qV)_g2}mgf0uKF1tAqF)e~hZerFSlXOX*fZ&3B$1;O-P zdZtV*2sn7R9tx__y8#>a>cuh@*$X(dSC0kNn1GFCx+SOv$^gg9^i)ty3%DSU<{*zA zc?`;9R3348u)1ebk+*k<)*fcW_G~9$yI$(-l4)LjVWaCbIt(&n_$av6^wEG%6~-1f zW5gBzDsnFm%mGVY5DB(lIRj1zOzqKToF088Q#d#3u)9zow%SHK7a4L2u=*DBnGvM7 z0Fz|^%xqxM;RokKKJ@11jTSf~x%psP)@yhStrz^*dI`)zKe@;kFmfFrOJ-0sT`!2f z>vede8ogekYS^G>H>mIi2|2hy_krIaG&39Y5bl%(1f49%m?=;cgZ-nfjE~js9eD0g zho+pi$uPzobsV#XFA6P<7nmt8cC2Lg*V%H-|fg*|EdX5$4UUR z2G%2(HOMMLosmO5Yw%oyHj-HY)(97tCx&nd6~QuYmSv^|#7T~2gdtHfCQ&kEMF9{? zK|hNg(p-k+F)okkz#dwtw1QE2ko_G4Zl5C!5Z^u;X7*uVGK09^D66E*`~f#v+S{Z? z@yx+f!wGOJHg$>ZZ3cr-noPXGW6t0?>K6=}wTa=jJ^Y4rFP1qc!0H?YydZSy^#g6hQLiTE7^kF$N!96p_-k+^EbeoJqO zVRl7w8h7z^T!{Txd||JKKnTHhyXCP-S;?tS;qxW zhksmJaL;4nw@KKZ9HD8+)6?+Dm#;n7>xsw3V~Vesm*!usqR-s}KDE-T;>w2UhvFA%f5H;AlY z7-1U?vV$NKR6vewfBr){ zj<}(I++?WbER1f)2aN|Xm|2`#vc%U8*e-GoW(kJroyo#ob^IQ!V-o5i}j z06u-v8Kl2tiswgv*3l?VB-x=sI$pje7`D{LLN!SvV>H;HM>dNCC@jY4S)0{Nfre?% zM!^r#zrZsxz|@od+eKSCD(frQBS%>EV3fp5fJ$Mp3&(zzIJ}X3tCbDNo-=yfh=x8{ zJTb5*8h+$Rao{VkS1mZT17+9=#+;eGVw`9~iNi#&SDZ=sfVKmEAfsSvuhc1Ugo@m& z=C=tvdxMUYDO|On$1Dq``9=wa$rbv!n{?!E72l~R%T&Yjg>s}+Xog>;XQA1xo8Y!b zFavw^?A@yIr2D@fCxaW+e{;q?Uz&DJ>gx<}ll?k(EIxo6Ld%&2*BjKgn%6>|QVv1UPRL zNpn;L_!(I~8bya%UXsjf6vYww-s6fX89HS17M-0nF3;11)f7XKQ^oHoaW8K6FhwO`j?2O%hI0grPfwuP2}tdj zFk2-I6Mm*5!%{XA*qj_YAzAdw$~f6aGIWI9BPds>G+xnU9~tqb)JkS4(-bB+HnnhL zSHryT2wUBH{Q0<(HKaAVydeAx#cs(@m0n~Zb@#B0NRa|#hvJF<8JICds9C}SrjjCb zK(Au+L?Vniy>6eD1scQ8_yf^HQ`*GN5T9ygwYteY*5_A^X62g32!=`kgWJ&nQG0C7 zax>~da#lk-+<6oh$3%1Lb5G6D)oC(_0Q01ofuZLvuwLoaTJACEsq#@*RxC`yo@Y}r z#?C=B4-_uiktkM+4liN6P-qM0+30zUt{q9EYQ=QM!q|um2P9-$Ex-Lvh@_*FHBlD2 zU@05uaE9op)F!3@7Vn(=0T%LHJ-Oje5=d^4%9A@XH87_P-R=(9Vo^T7IulkFT48Cb$CXN zqB|N8cveO#$&Zu@%F_tzu-M{ptYTHzbgvmS7_W8Kh$6-4jE9TcEY3NMlRO7A&7RN9 z5?}@lJ~QM1qpk2{7Q)cNECd*19)40N+9uA;BCh)J9l)KyJX>()a;22aXVZe{#x3}9 zrJ`0gsu$Xd&@-sWZf(rCv|%5jYXf5?LV;-t&|qxhN$G*de1Sa!mnXCb{F|~&Mc7hLP3lXrDop0n^?R~<@>#Fw zbNOM8$8%zx9$zn>tH5l5>dRMy>jh>`9LrbHe4G8Z+Z0Z271P8N+Z~wfu#>{q!@eZ{J zX18j2f#CaIpeJ^#VFS;-K#%NJjkgJY=r%pQTa6ib`Zm3AyIL@C%L{e?ooeibLNonB zJ$#2+FmTH*y?BS}-6iBY!=Ha$CW%+^N_F-=PI85#&6Yy?Ez5mP?83}bQ(i~=qEjdK**ta&<4mcD$H$^olS6QHV*Tc7Dz~}z?eD3 zfP&XNY&|o=E@`vFX)T()mMnttb~j$l#JZr%;)aGXk&Anoo2;9ABDlPT|n!H2N8qS*2X&fTV1|MJ>s}OGBRY z)gfoVKg2Y4RfJ?>j75j()A)6puD)Ymq6O< zR-x6RVk@-%V}R&FXuExBg}`(Vlb7w%bLO3@LE}!yqJy!sMVKUN*(LzmFrZrhA5%(> zqHfg)^EAm(i~ks4i&54iX@$Tzto^n*`p@9`8<*!Non0gtVa4v)DZ1zu@s$K#G*3)3 z!1HMCYbP|x}`|< z7wF+FER*P|EwZJSP$Qe=YkaftL;w&=L!r<_3WdWWTZ;L*#g?d8SM)&hFuP;f`OZUYsx$J zz;oE$%VPA11a3)-I>6{COnKwRZ&B8&*nN*FHPdX3!W8IrE z%8m|WFJu7~d*KL+pUebUxAX!Vqkgkn#T?Yk=tq*%(Luk=KtQ(`v%)}fYHC_%G8BTa z$Jhb1IN)NN>^D3~w1N>{ytn)9Cqq|cMDKJsPOh`~@m$Qp9@e~`9k7uWytR}m?*^TGR#H~JA-y9P$K z^JIeD^MKd_fRSvm!(xI1ZeSkHlg%sl%N_}y>@wszyhcwwpqe=Ho9Rg3^B$UIq=%$BM(@ueVpD$ngZq+SE zRQy)m_n;bQ!gRmtzfDiwr=w-I9eVzV8oE>9zL!XhlP?i?XpcO5FdH6L6EBrmM(+~Lz}>=)#pj{>WZik< zh%78qO5^6qf->Ct%k=>Gkd#A=K2P~nnt1mK|Gs^?nY8Vb)K2Xa{tZ=nDh*dY&?=m6XiaN-PZr zgj@3g;U765+=dTG`r`+5)~p5cSSCvr&lJSa*Ct|<6uz<=hDj@_pg zfge!OIz2@R)al6w)Oej9d_YaHO7(zhz&Yaq6@HntkinPf!H3ky%cN$fU#8 za}8OkS@W`q0ApvB)z$*Sdqla2)i5>Dk z4QXLCgDt4i%VMV%+E@&u(SMa=_@}Jd^`E*+3CDa#}E~ zZuddKl!wck*4ojDtz!8OS2D;Ru4-oC%St&pLL9?fFqOV)Y~w-?m~b?MW^l8KsJ~gj znJv2!?`#qOIWRWxAm6G_{h*qm;*!d+mqYa`Te>bx4%drEo_P$PV7lB3F6`+mnD%3k z4K+E=h&7sCp+NCA2RlXOz{i8K90sZzgwxp|Yd6vhs}&qrH?D|9fFp}GxMW-T2svYR z;f@FTAY2jjOyba|cMjK^mTSbi&p56H?$+QG0K03I!zQ5672q;p;wpUQWM>+Vncxz@ zGJ(RZ5c0NiwKImt0jW?0TMS!WytBpZJh?a8I^m);=u^g(hE)~p^QJrtZp!T5D#|ze zHYof$DXcM+*X>@tPF98yA3H~mP<7Q|uL7fb>>8OktCMD1N^`nMRf zS4y6XSDFjB-YW&ITxGUzHKwkTv~yRPvycpmd}`1{N#+L4&TU3(P|ngFG^=1I;%?2Eyb#6B7Yvhd1HKvVnUL$8*x<+bs>{`>o3e&Yx!uqx5>Pe#kuOTOmHYC>@ z<0s^fOrJ1ow@SAG&in}z&%p8t)4}tgR-S6tna%5r`Rk;F-RtzTojr;0^ncxWT_+7( z2ZpZeWw^Ht{SLIz7>t2or$Q&{nWPa~k`iB{d0iJ`3~&3M@% z#@jxNEwJ+9L#b{&vC4F(zO+efwMF{`9d=Kz?90T08J1SDL?lbDvQrZSE1-3Z@vv+P zOJcYwI!DEoGbU&X!GTd5V9MPCBj;Ki8*_pv8v*eBj(cm#>|Mw z7e>q#lt9JD?=>eLFsAMm`P{wc*aOC*im%>lPCZ~u+$Zvx`^+(v@_v0un}!jhqjS`{ zg1XASB1Dgv<5>2?3V<^1Q1Z=-saYUce8X&2^*5-yKec3${ z$1^mBWpk{#;a*|i3ht`8AkIvtmBR@@rLDQH61XhF!>*=UOG*G= zHn`QCX&oKF54&dqx(rw?K#|abwU1hHtE=HY;?v4tZGlh9GbI7kwR5->d0Fs^wXpVY zB8nLVt`nL9Xadm3;Za>*Lticn^K#uMFcrhLY^>VIi-9)*v@g(Pxu3QeDfs^Aha+y?CZqU;>FwsL-Wf|j}j&v-H zk0g$s6P9XfbI9r@vto(q8qQ}awxw-no|S_LgAcs^(C(xDpyGzbmz)KYH7uU_QfZiX z)L>wyDy@NaA8buO*OkE#niH(A$rVh=q28-&ZS!gmR;#4iF_lx(Nffz=6*_f;V9YTq zhScTWJ}kduJcIEPG>>Za9f@EgqDB>HFxAikiwMXW&L%NHk*F^RHM+ns0d*h;*zT%o zu_o3$01+xgZ6#H*$5WS!K{V9hV>`q^2saxZa&{QYYvk3!pbXwgmgK%+CqQQ#OgI~` zkj8^u-ELq+F}qD%K%y+0%^3)`U^yRNOBc5pb27Yy|Gv(4dHyja-D)|*%K=uO z0OU}U!>k-opS}J4GKzh|2KR{E%0bbJ;w7+^|3<{o;^TE68#pCH+*v92<~lVtfD%{$y%uKnA@l2jyvBJ&31jGKC*v>NX&w6>wqj1`>=F z0WZR2@u0B+GsOXU!GTU*D9r9fBAM7PoEc0K4;tacBx{~AG45UzJgoI=5!BMPSJi~X6KC2xJcp{?O|FrcCo}~FE*zz zLBDvVM@UCUk-$AJXPUeUD%`t_)xiuVX_MDTzU}MPH2#M96lQW$H`;5L?=qZI8BFal zX+@H$(z*)TrM87wF`XSE-akE8;}zHJbHN5DZ)$yU7&hh759>U57sYGXkxBXSzpDDhgmEk zZqz$%u$njlgEMImU|Neth|R$B^|M0LTl8OBhR?Kx95Oz6Ks=q2lr}<$%QnybobO zv<2$!F#*u}V`|zx_YC3~bit|YeD72beqdfy(Y|Omi#f0Z5~e(GP6X8@ET}QT*(_dY zVPd?j;%JCk@K%IfKCrspY_@S8X_Qcq4Oui8aLy=?q7qocb+mRK?7*J%_+kzFXpY+$ zZLSehIn66z9Z9+^xa^#k<`0?u(v)N(ul_bs;V<{$QEni&=DKXN4_r`Xy&i4Xm^5y) zTUGNY(e{%~-bA0-+-B6Io%8ynUfX^BxHY=5gAl7mXvF2PA_ttda1!r`So}h5-(K5~ zX(M#{(Bn(j(}sUvxZISetF(1k6TtHT4~txPb<+3^%MoNChd`g1yIeXbJW2~a+U{ry zhQ{!~BTpU%GOInhD}a%QYE4u*j-NP*hE^>R)ubZOG>oAVCAzH4Z){;>7=@Nt4k&u| zkr_OmORzIfOQG-_rcEr5Oi5AdascN>FExp>pv`JS0W8&zaTnSgtS^9X$}$eRa8#%H zgw^ko{9cs<2G}Z-OPtg!GQsEz_YfTzx)!A#aV3g7J7MZOi~La8a=@8ylTr4`h1ALx zGC^LZwY=tTkGi3DqPQy(PFEfRq8uqb z)v236^51Hicn+b3tvu-@!SdHa22-M{thDHC-kO@1nybKE4O$5)J8GfYr*RJ!hJAS0 z3V1%?vkKY(>8h}O8Y%(R>qEak)+bs33?3};qO0sdu}5(ZdIA~TV2u;Xh4C#Tc(SG7 zFaW@9l*57?@RXu;mM0SrDNsJ6>H^=Gl3{t#TpE>y)MXsk^x}wu*B*juXF9$3kXWhU zh}Ob=SR4?7y1X?5686S}gbsdY)Nr<$v!h16U(oWg_Iki`B}ukeGFL{8*;h#33$HNC z4;xFb5c%pW%*lt1@rNWn^^m#rkkNVwB|)V=^EATo)Ct&Gw0in#*nxn%hh`8qV%V#x zEH5zW1G)fzIY80cV21NEmgA1UCfDdLN#@yN`B&jrq&QQZsAtbimSNoqp>kVD}0e4|(@IH0aRkNpuRRUjGRGuw`>hWa|E3#=4DgR1Fz{t z98;Y|Xj8G8^*orR3kUPu`twvb|6HScxyV~L3#W6lx%3>vJ}L1kbkxvGt2p%4W6v`d zpR3Pht8v|#-WE16V0OJzRIAnValv`S>+AZofA?AJS;AJvjI;=dV_*&bEIeADj{)lt zm>8yFThb~z!i+5GBZr9{yCKIy!UDX%?~t5VpubXU`iM_u%vEq?As-j~V!7a1j4`V@ zw1ta3P7W@tO#GO^mn3q^gU4~{)+;$N0|45%P>%I|!kOPE@uhv{>TzR5#mD(f zm`nq3kC{z8bjS6XUQoCPT>_MxTVy_ijutI5;;>#@z)mH&>)0%YW01Eo&D|^u^L6Z1 z+BAf27!3%TBsjv@VpODuo!cy3dvkL?dKMYwL#e7RW(TI2SZHmoxg5upwS^{*Y~rq0 z9YzIP%itz(t?8qNafAUlPK=E}7$0M+gxEDScbfAs72hdfXXo8G!&6PWhvcIU=)Y>1 z_+ycAt&A@qL0&jcs&ip)+hurc=GLXq>bKUV@S32P#N)Uwg{D-g4VKrhK@aM!Ujq#< z9%Cqy)z-Gack{qx3KKDOZg5b6&TVX?n!Lj6`?-CvdUiKtaI|H3h5M&Gb5HgR!#2;u zMw&jc39LY84fEh__^w4YwS*rSTJ@pnIEmgErXzh&c_J|yOe8{2GL2!EijU)^+-A&5 z`-}Dxxgh`7s?l&2FX2I1$iqAVH>r#rjL>3Xws79+`gsJ~7T3z0;v$(@EM0{3m{=eR zJrB^DbW$zsfjnq*u_%R^33hE9G+O)3#sQK;aV=`#{XYrI)( zKQVBF(JCa+ui@xouft~9c!D@~Jh+=h^Nsi%RL2K#S)KqbF2r$tc!;BZo`YrN?l;!4P zjEDT6s2fbusz))lnoFVgsKF%wdJ1y{J;EGTXyIuFcBDttCq<56r%ASTMBaWMy#|bT z(6wOg@~HaE%3<+5011Y|)noF~w2sQ_(L}1f<}7-aeST{4u(5Jb9NNHrG~(VNNq~6| zj*AzI8=RGkC0XqVN?Btkq;DV!=}95I6uLX~J@unlMjojgk;Wd5ZSck{qwB-c3vxlQNw|=oTCO7B;Z`8i|tQvcC$-TE$lTHj~J8tmQx@t z9W=W~jLIQN;2x3$lNZYoMQvSdEL^O-_Z&tcn=Irls;8V;(@-u?vAi^Ijv|hi9_veZ zzY)jl+*Hd>h~ueSQfu^xufXX6m>hXt^8j+K_Bg3|<-QWf3iMX0v%*jty_HDT%K*EE z0rh&(JTI)*<5=9#=c1aHVa|nxX>8)dn$`I*#i^!dv3(31reM{D{W|c0iv9_ttwWHY zgT>LutO*+ccjVED)THrWI$zSZ&zF2qOUM(sKj#r)&0z8eLoiIE@qv)_)f5=mp(E#m zzhs;UuMFTVry;R-oUWjU!lJe6U(ox&$q?E*tX!iM=Sx2DosT?`dG!BwXh1RYgJsn| zR1x;88e`H_fVmyB9W@>r-;dT2kGA3LCxTKLG8ncKGC%~?gl->ZD+gh`1m6(G#6gW%svE>c9$2|Gq}<5o`50)Tb%fU90%=FQ3q-YE zyFdma{sm&dfH)MBICi1M!4a=K3|sol4s4h+azynuU|55+P%=)yJ=8=gc53??=%qo-4GjI?BnA=bHY*VG+^ zJ_{UdVxB`P701W{=7D1wkz?erfI_gI_F^oEUJ5PkUTFg14IMtqVf^bV(_J(Osy6qk zMtTnJ=g^E|!F021y~eG^{CXZuBpb)yql#-5&gG#ih7)(?$JTW$1f9f8t&=gdLBmEdD+AS)VWfa^(!BM1m@KXd9hVM zZtkFP7Oye=>y1^l05x$!wmZ$7Fzp+R#tGBC!C1kzSV*ojC-X-0I*DV&0t-{HSWp-E zV)bxgFfg}KrjhV>HV=)QTJo9RD5DrSofZWR_1 zkb@;oWz-l9ug7!M>*3=C?3EQJ=%q1s8|xKiZKKzi6P-HtF8dIps}+~B<_i3-icTF$ zPb_~y;{q|(xm<{)UQic!A?0e3`-4LW&sbRHZb3-^OLmOBm6w?@3w_ln_9>t%*glFcph)SoMQBlzjSjA<6zU7%ut8(lb2!soMMO5cgNW9sr;csar$Q843!YnTRO@U1pSBVPXTDL*gT3Oq*G(ul&g zv9S@I4pvj3WJ0@O%5sX0{XX!92+#D8V2-0aBSMaGD3}%aE>a(10*cWn8VR%ph_7xC z|8;nCRppJRywqZ9;u0CAEn`Zy(UBi3n=W6?$>+XSFHwdkmx#T^*d?+i0(5$txs)@e z(b(r?I*9l(Y%VVmKL&_9yUfW;#JUV|SXKI$82;Y6{8%}B635nY5w(vCY2~;i!!8?S z>6PwqR7Xcj0m?1rB;PG_%&pL_oIM@SwT$JvW#EpYnLm+v0ymkG!? zKFYDqM7)-6nRdTSpYdaHqkP>1HYcFETZ9Bhj*!o6^UT&h`7{Usd=vyC=OTgYm_zj& zt&8LXB+Dv3zSo?_ZkfFz_x76Iy)vXld<6z2*mbiHMO@e?0$kjF>>DxFZ=Bg2I5s|^a!B?Wfir!P z3BC>e#v#!cf;oOra;qMc_|!oq#{}n)(L88QUu^gX%_&SX4w~ce@Hrr7bOy{>_|#PK z2AmRLf$fm4lRoKEPT!5u{1TcnSjkiC1b+-uChC6D6qlFq$AI~^szg(|CEQGt?^zIT z8-%>0_T|BT8WX^UK25wufF^2imsD^Y8`II9?-uVb9c*ylD)ALK4uuW`Yk}CpzEhl` zK;;1@R34Iw+K!yum9d^$W(C$ayX+K#l`E#sMKF^W4?$x$nut%`XwKYdbZ*oqAC%Ib zK2uwdg^peaK2?=3|9Om<#Y2Avl5yy5q3=*fs3<>~-brA1jpanNOQ0=HT3jVIUtbya`VzC_<-Iy!8OC|2Fm17sWQ8-}1JW_pH zX92s2*{NS}2B&yX%pA)p#A=vub1OF<8C8f2A3%sUd@kAXl(i^a(N*_6v1ezaJa%`B zIXe7OsEnT2R40f$!O{mKBoocZDjNz)+;ikppikv2!npmvo7+=LLLbm|Y?@8XU+vUF zGx?MqeSv5NZ6MPHqVAKQ$_qptG?5Y3|3qFpSyzO<@#`_##{?ZICrH%$UYaiDRi3NAzkQ=33az z03$nf99t)@B+z|8f`$f1bRsaOg~Ana=woo4f^r=rF%`#(DtmN}xUK92VOE zDDu#GA&x%5L$3{|CbRLeaRZUX zIi`;+&JhJC25yi{}JQ<1o~IRr(x%goq`zKK|{4wBv8i6*`XnVA8zPnFw((W zb+KqElR4$Nn;ge4op!jgaeb^{pBsoCKGKOKt zK5@i7u}}EUK4H%66DQsn3s&G9e4jA87#Bjt+i%v6$gl=l)%kuIZ7suDH%hW!&Ilcw zd&HRDFZp}>MOW(YH|MazsL<*G8JA5%Q;)OuFq=q=!O+E`QJXkw%)q(#5n};E zC8Y(1Lvsv?%7=~GfVe@Q8IbbN9?~~GE3f(q<$NEy%r&yqhW;Hhx~KH=Bk}~HtHDN6 z3SNqlJ^*f@5)`chlT*2R-lMkSHQ~*+j7k4&y%@W3mOc3 zkQ&+*|%wiPgIVOVAz2X9{O;^+v|I0;EMsyoWOyu1Mv+aAKP>{j&SOSMFOY+ zg|k_u-P{MJw?*O$TSV?EpAIk*0TT;8>eAJI(Ff$yDHwVvNmgFSGvcxYgL1sr&{K}B zgWB~T#4&?SNcCt>0no6h-!Oi!UoXqWOV`N+8u5j-y|B_=TwjFsHZ)&2F5rvR*GWw{ zkl?L>Wj~guPQWTO0qYpjUF5DoCU{UMuM_8AIO#MV zFl2IQDg^+m4LEE4umD&VM;y!IfTxZ<02JGunkS6brBWJfZbB)m@aTZNuaGm$U6Db& zapi-v*TVg8AL3Kj$obuCq)1R0Lb7^|>0K{&>xjc{-8~^z>Z)Q6NH}cHu2WkWROMkk za;E2jt_;fta12%@f1GMQDP#Z9UZ~6PfI7Xh8Unje7abX%U6>fa)D!ByURe!+ma4Ae z=%mWM;^Yv^V!e_GefnEc{rI^I#RevuFj?3q1}f!!#+W%UvkxmRW@De)&<0&Rv_kl* zCEk~PvM`1=9M%g^?`|@E%r&7I>=zS{W+iTD({!?sXk*|^WByjbK@FE;&`7z;1aHM?(8-sTPzsc?$9wsRi7um>wUd`NF)GmOm8PeG0w zaM`%freMdpU&dKzaM9H6hdyof!g(ku&_UpS?}yyok7V`z0wUQ{b6;KSCFWj{+%eUd z$;zF@AOI@{S!}{8Lg zbdQ*0M~(TTp!i3TtbJ5KNmi9)XtNeB)8BL%$6)a?D2=Me?8}VROU?3S^7&fms4qjZ z<;w*8?SVK_a#wqwBn8S}%X z?Z(1(lw=&sFWW=4`d`ydNuzK=tX-BVKtAHLKugukKsX%wPhSJ6oX_{ttn#c zy9o0c*y}*9Y~x@Sr^Eb(=yR`6vTIvzeUp9K+S{5q}=oq?b z7)s*@$2k{HW8)u2A)we8k>GK_wxx5Xx!BprALxiN@f`Hr-0$2gX4X+BL?nx;v|=a6n->FkxKZ#;s3t*HRhO@!J19j zqTz8?R%Vk}zlYl)jEKaOIWFZVw4YSSfBl5)sADp#JOfTcFOQFmti`fszj}E7zl8o( z?cc-j06Q{gF+smgI!nYc`pk+-A&O zsw7xaA2MbKB|dw?T)0KH_AlRRbm0FJ^1L~In^C(_IE@=k=T>9!Mq#c(a;s6fN#gEJ zCcXzfr{YUDnTtcl*v%rJy4hSAGU_)=d0<*u9WrK4io9`BByGfRH&#zdIq`*P=XS%z z5xY)rF&A$!%D18!YTl}{zfF#KL0_Aa31wkq3ObsUtkSnrvJDe@1~@6g=mhaawVM-a zSH!Uvw4n4&h+`yL!8fH$kSeK)?u&xx_F(lq} zx!Fz0-v1skwbA93FC`U{GFloT5tl>LGC80{MU_@BICu#i<{_%)OPG zJRr7zI99Q{`G5=}0krm;ZIBM=6YP{>!`VFZD7sK9-suQn|O z3oh@~_U7X$|5_;8du1{TEd%1vte+5XBrA}>A?CHRuK_5O4PaI`)KUOim?oVN9T5^> zg0y-ICMXSb;fVOkAt4q)*o~>K~(a7x#koe~VP%Npp3N+8GRUBq%d35EGp`c6Z{*g$a_G z0XnbZ&L%Gn7z?L3R`-azoh}EfYG1+0|JS|(D__H~U<@|APp;otFnz;&hH<9yVySMH zwcCNL1$${z6n09+jc|D2(BL$-$|M8val9EYbj0L;tL$DW1LY%lq#x;y$Y&oh>Z`!G z7BfNRMFvM`L?D577urWW$~yl6ggN;%;)}S_wPK_TiG$JclN%qup_+mr z(}#I;>XG(wd6c`yWxIx*GnQcSbxgd`(5Lc7d;|Ax(@SE#4*S292dP2;xO4+ z0lMjK#Braouw2<9a_Il&jvH>D#IaSWaa{ZZAU+14%iv!u#}=lN$3-gvX6LY^mFXkW z!c70TF@YWZ$BoIOCdvj=CzxBq5)ozV95u^1W9*p7;kw0z!S-=o1=os3t&Y*17~Nq6 zKMA8RC@f*JwH-H1&ClUg?tC%&!q@*mf(c-Kr_9(@4PK*@KLTquAKts*#c9Usieo2t z$Af5v_K2Aq92>xwlc(Zv(&=6xUT9S61Nwepu?qD+iNz|c@?yD8Enk&kMh6L>Qn)v( z%Brx_BT7A$_|_pCd&pMR2PL&yzIECXbK-$!Y>Tb>~&&RsdA5L&8|H;sOADQ(9U3u84nX?rSwHMAx#b@KaTny0cMHV zLWZYs9Zpr|oM5jSkE08L@m_V!^yUWa@x&|+29J=Sa@BeBC**Z;drmClvtnzqSVAb9 zm)AByNxlSmEiEQY?Q|P)n7ntfP;uV8+$Puwh^zGhmB+3;@|x?p9LrExqkxa!<+Lob z;c-;(MH8u6%wU$G99*xrI84FXnI`2;mUf${`7qU(P@ArB4BGT%VW8?*3(c_F~WZaz5io59W;7#qUd*KVVW#jM?8mWXBN`R(Q`HZkl_d1fSkm}4TJap;kD zi`owo80Ldh-zoBWE>I8ZHV_{OT|s+tj%bFPs2y~5@RM)e4GCr(B2Q;<#1h`*IZyaU ze(6bE=4lf?-z(_(cZp(cd>0fGgNWC#iUfm4%*U}9j)mHtqKAaMo)O7B6ifJ?2+SeD zJYT-V0JBkieF2`DAc4n&S)|&j_-Z-bW@#^%`TA6j0y|}1BypCCP zTC4#OZ?8A)w4wITp(D0acTXc_YpuD0&lJgnS;KA?xGj_$g#ifc&yW!`)0pXD-Yn57 z9uVae81D-jEx5*)X9a7Ym}FyU0;LMv^PVeSkdaIdm~CV5AO{$+A-x>1NCJJjnt;D^ ze`*gNo;J2GtewI$g6TivW9$2>@ZBXRgbaTu>}Aq`oLN~5Tj#O$IUG@{`LvjQB92)k zRz%0}&?|e98qhT8NVZX0j)GZz@>4hmr5`&zBinYGYjZf_xx_2zsf|3)onrb`<+E)` zv)@cL)It=W-t970@KUXwF>!R(ha(|7qv@y!p&*P|;v(<$f?FbYtFEf~1q zZNQLa4Vs4Fb=WbTf(k&sV9|xw@ip?smYL%Vq!mmKlwjk1B%!!9DVi$LO=GLW~iqd;vn1+#8RVr(zf^&^*fWB@aArO%TZ zlZqb9qD(caC5ELKFu>X&s|YrZYg(xmHh^GeyYy| z3H#)L&Z#(-mL-8&^o4p#o&V7_t373N@|1EocS?;KPl;QzCVbVvQOWIMcs_B;sKMkM z@l7SfvFodKyVxKjUdG2uFu&Mw`ONL|F{H^`jc&&5-XdyYAES5ZWp6i{yUpoShP}sZ z-DcR(KGaXiW)d66z0>le(tlHa-2D4&fRWITq4ZL zOGlAv2Ijyx=Vijg;1K949FHNl>r9~Db&?8RV{n@B>xJW9FPzE^avf7QNZDJM!JIOj zyj)E!FLlt!o3n`DC^@um6c0F<#~`2Cn@k@wkDG+kxyft}8TQQ*cQALstVP8aZZ^9^ zMq9*QV;n=b9mBGc+VoE6K6NQ5mMIF3X64e?PK$}Su&%pn`N8M@Z+F4>JZ zDj5yQWs=LvWhT;(V>{fnM&~Ms=inj;ryG=9@NGpI@?H&b?P{}nLc9XuqU3$A$pH`d zV|rlb_O!7Qfx&q{RGD@PTLdQ4y^a0yF17aK@hdj5valfw(iARXpW*KkDjp}qVdMkm zUSWe15N4+ixuH6%=1JuI!g3Rmf2b z_5H@&K9OUuTOB5Q(qf^g`{g|>$RxfbJ~c3{SjNB;I&1j?z;49n*h&al{$DEVVRWn-f)|VIPAHAR(A{9*dvnhY!+!3FA@nV!QO|xqY{T% zAug@HS2)eR=5jxt1d*dEus#&5*1U>7!{D`JqNjHO?Fl}%0Jj}$D?QyEvTq3@te6AF zPCYb7u!jPSedmy1XBkjz{R9&`&mqUA6i8s1;_Q&m8$p6CpzvfotKti=Nx^5-@F|uZ z;%>u7!$g}YuCV#akZvq3%NA{Hpjk77IQj=Drd3yn8dpy2?vdTx6}S^KrNLZ)&6sM* zS4>^MIq1rj7TCphafzZoo>X>@=n~Untc^YueWDz&#;k6AUlt)o9=ORhvmZS6Jp-ds z5=@b2p@_#i3Y3O0R6#k-5yWSd@*UbzmB-i3(}*;ng*hW5VSIye4vW8cV!G0cZ#TBr z^*Lwc!$0mB_3fK8(ow_VAk6yfcgpT2503m`eE`>rus*m`yp~mv58OQ8DF(ifSbmNP8lzk+@>!#JI@j?{3y6{g{1PXFdgKH%;p_N=Vzo=@j=hAXN$u~KJf3YVKTAJR z@9L3pz-e=SP}WlMp#wZt_>3)PUe48c1bb($lBt4yjf~7H*NAejakUuBx2_h?NL?IZ z@^ZBpxKwe(NZ~5j4lMUTG>_I~P~Oz;AROL|l##4osPp}DGQZzM)+_yTnsMlM@YRF; za{4yDZ8<0&WRNwUg~pY#P%r3!@Mi~v--3zkpwYQlPKgE8xj{S;4}cFZb~t?lUnII( zthc8JjdD)nD>>od+YQaDjM}A=XYDePl+oi{Z7g0ca(smWlJP6#Qm1kMuQ2eP1@+FI z)B~j@*oi<*fHezDi+V--DQg>0m%!8vE8$qEP{t)w*w%*y4YhGaI#sCtxN>oe&ZljO zwVDryPFS?Y$Bfr3rW)910wZO7cng;M_&fuQ94y)SkK>&B!UDEF*@#=ZKo6Dm(vCU3 zQ<@6Q*;mY^l#eM$T7F;%k1by|^bYt89Lzp&gj1}YvTFwWvM}ov4&29PWT!VI@KK1g zuq_3%oRPFs8Ij1y3)3&O2-pgEzCQH}CuGlxIBk$-cI)M6i!fqSd&kggW7iGuT0p|vQ6|vFlg8+Ak0_* z&cOs4R*|r^QhS(@zS$?J4Nv&nu=@>k^Z{>9Nw?dC!uPP8cloev#94ur7p%yRDBIp6 zV$?DP%O$lD7DJ4A>^Ft&&=Dyc;y$*dAC~&Z?hbsbQW=qK{G#^DijXo@xv-w z+=;aw{MihRUHZ2Y;^2_y5^o0KRZPe870=V>tMR-S^L%CEqvwWk(Rs-AR08}QjSr`F z_}i?HD)9lP5AgRQt)zE|HzVo)l6Wn^Bjx*P;x6${q#Ip# zC%|8%aqB@H)_K0%Mtz;#UL8Kn>qW8DUzhp#ujKh&r9=DGIt+N$8}xm&U#sN~!|Y0! zH$YyFc!6R5yJ23Qyuz54mlzg566Ot)=dwIahHg2`E0G7k0IJAYhTc2EyfS%}*J!!R zu=HnPohWN3Xe%xjX@VYw{w+_^BXO`a2!pJDFPVV?0ueLuW4 za2JU`=R6%|AJSog_fdg3WXQM4&z_@s*01WY6yfKB{CmhdSBK84f-qd3A@cLgzr_5# zmubEo$-hXxLB2=6|60wjMEIjY{wz<2*Xy0q{9=S(3Gyeu$nqERnqT7c9@I}Q;HP;0 zUL88m)L}Nl_sI9icbR|wR?RO)_$~5n@(aQJ8r1xJgx?`QPrgBZ?zx&@i15>I;`_<# z&9nTapV$0cgr6n9$oI%*=>I5uUkAyvi02r({~6{L$jiP?%kvDgKMeCm$ZPU_>IC5r z!aSQikNNlv?f(e#s^pc3R~Qyn!#tNf7wUBRD?F;h<~m(J!E?|E&P!gNJUhbk$;e(aD=KU=N{dPKB zf2|-t@`~gYBfJiI9(g(PO6$Y$B;MK_kGF_dt$5rgo=ZsICSK@^Pv0T#C*WP;^{w&g zjjQxLB$I%riH~lHPj3n}sx$;9JX;A%7A zmxw!i!ufAR_bBBbC7w>eZQ|Ko@#)LN?Va&>h4{$sc)Uv7OUU0L-pq#6|1Z{mjd(S3 zf8IviB|aFzKTEtG;1}rps|?q${ypNY3&Z#z>$gEX$MOZ~j}dPYABd#?F7X!e(FiWS z+wsrviTjcA{eUaW0dtT3+IOPgV~5pF+6g7%KM$FRe&&GUIz>+7vwsl$Iqec;dT z5N}5C*Ggf5cZ2dq@K?I_4i?3g}hRma^l&wI$xDJ4z-|s(yd-1JX+Uju5Z?R2VN4FA*PnhQ`Y`>F_Ij4@Zf6%s0UQig@M}^JO}Gm_YqC zZrAcILxa31|GDJn$Qx!@Wa!-X^zx7LpTqn|nO}{en~?w6%2PS1+s)Fg;c~qm=aKrZ z5>H3U9pDb}{4Me6Ys6a#xJ%qR8K1sRyq17_#C_f`i(yc{2Jz9G@f2@Opx4$&!~N zUSMdyHGCa|>GI`M&L$LH@6cN1`R^KhuL9Wh>|+sQ1$(qrLv(C=mC36-s?)m+jlU1)=aAizIs8J3iI0Jb%-xED|EdmWQDM^W zG>MNqs^#ey=}^q=1#c10yef?U5^+Ds-wxwr#M{Knk@O?PJH)#Y{AY=Gi4R5cpCE30 zNVj|bE5ql15Aif{D}sNVxJ7(4g2O0OU4Mpn<=1rnLH%t(xmB#??iBu zc#e1>a(}+h`!h(~e22bp55(tRCf;~)JYEUXvmXlDo#6ac;@O1s4)NCg@%h(? zm+y9g!hGc9(fk?$uV@FALg~l%Q2qE4n7X^ z)IXcN4xbZ?JnvJyE|RO{75SXl46|Pk^W30(wwC7^R+hrN26-0q$uVrU!aSe6<}0^Mmtu!aVC8oUbq+hhb@JxLyXxD+T3e=&ld*^5o^1Pl2I-VVE~e zUgy_zd8}V&xn378Ux~Z|c_oIqw}p9S@*LtGL*q?hom|~eSVAe_fgi*0P)6K!uV&1=Yss-8pg}S2Z{R;{8x$Ri93<=JH&^Grz7d#Lfm>2 z&--Jpk3{)r8>dD2XB$V=Do?LGQU2NTkB-C7HgAgZ&vw00{@Kbi_~xf~y;1(z^8Y`r zUykZ$&sLvN{@Lm?%0Jun7Wll6j)&{@^?crkiD!Q^9xoDaB;X^&OK*%%Um~7)Lp(l8 z+)KbwO!e1hyA7{~>bLjpaR1Z|`iZY-d8rk~t#|5vv-nM>|LZV5K-~L=mRk`#Puy;3 zJpbq6^uq!EbuF(fhVc?{AKshf&-sfmUM8L=-ihSz5cmF2r?dYooW35M|BtoY|4tZh z2Iv1HEie967;gvXC+@?-9@Q`N~D=w-w|c zTp!C<=JP%H5kCJP)M0c#P>1O)?>tpaS%!tL>EF8Y3?uz6U5^FgMTXYzhk04@D#RUz z`7eZdgXA@d`$4!I<`u}ZzNqC{hW<>LHxiVOc#&b@D`B1;l#jT>F!$v!uNst(xX;iy zv>~Vx6}mzBzQpn|EPOMZUn3|V@ghS%70%Bm&poQ;O@=_bk(2M;j58W(!0cq5qu*+!Ry3F@6_pvXLL9o*xwQNpB=`3mw1DC zBa(iQc$4@*1b;vA7V+*~I{zHQ<19Y{_19%R7BAnZe)~7*FxRg`(hTd}hgH1LnbHlu0^87(9&t9uT*9`MYQ}}joUx3!wZ6W1aWU9jQ9N>}kzsU3z;(nz3%S>M-J`%bAVkRf$cZg>r z_!;6g;?A3N`JLa?;iINbUnidVEiE5}+cWulDKeM*J>s2rXnBjg9V~x?c>SGW{0`zx z;uW}SlfP*C7V*Nn!g!G0C!T$G7!S_hChjNT9pcV=;?sAD7oB+AnAY$2zuy!8HfJR6*UDjpvo?kC_m;?)m?)BC(XgT(E};_*E3;s@jLA>u=|c)UP7 z_n~-vn0V&H@pzGVHvu0Z-ug&<`Vw(>IvyV-UioM|ZWFgZ7RE2auvgxXGV#&h3FB`d zULjs`!+22tRpP@R592}p4)LMi4dX%nHRAbCgz+GMm-xU;7!UHV6SqDY#)JGl;>PcV z@gRMJcsl`a5^sJgK7EV02M3H#Z6AXCed6w?!+3CgZQ_;Bgz+GKhj{6;VLV9RB|bbG z#)I_6NA>$Z^tpIEO+5GcFdpP@5x2e&#)JGb#JdT&suUdB9EZ4zFaX3~={q{?Om9)Y zD<9RNm)@*@e@y>YKXB*<v);q;<+R2t@ZBbV_LX7Y0C~-iYrL~S zeky$4Jb8uB5dR|`TJ3Ot!{p`a8gD*M-lj0GM4nsKcxh6Hz8FS6<*!Vh74Y7x@#6k4 z&mph*PAzYKK!=^n!@N3qg|})@|=%pdFN|7Eak$yc2K^zXnD@jp`Q)& z3`gIO%ICGb@J$`MN5Z@edAZ-x^3J<;=v@%z<%0a)s^#tnb=ce;<_!hB3h@u?uyiwj z|J$ag)Hd`T7ky&qMy@@%#??g*R!uQ`4bwZ9G5yUVYzld@d{R z(LC#LJU>f*=_49<|5%5{w0?h@k^41BzUMN(FX}M=SUkT#zWY0xXZ?u|?O%`QkC5;G zuIA;w!E}$u^KJ5tPikK0OFHzv9?!3mU;M1*xqry89?y5lcfLTLr^DR0br`Lm2Kk*& zXxy69VPQF*?~|YZw8nE^)?w$*T z9}3E|k@#;g9E#@`$XB)?gou}uOn|wJikJIp8Nv&_D{$2Yveb3HSWJw zhel64-y^?Bev#LkHRAa#@;m2gyz_d7x5V>1LHQcwmB?$7=SFxwc}4O(^6Ut&OJ0FIm%KuR zXMI55&pde!dD#eWfV>=e74kaU!`G1~FH4?Ho)_T_lV_1vBCitRmB=&5E0R}?@XF+M zexRR|0(rRz&mqqzFHfEk;nm4&l9wZ|xh;IXP4YbQvgA1tUYk6ZJd3%aB(guaoBU7vbf|v&r+x^ZUZrF+^U8ye4^WgjXc5NS;TY9pR0VS0K+NuMpu? z$jg)Gke7|{YUJg}tB}{(8omyXyexS(d0vFqBF`ePL|!Gr>yT%VS0t|(;iW&Q?^~zK z=a0NxgqJ1HCofN)5#bGz*Ca1TUUN(MdJE)vLz0dHM!+N1lbKPQqxEsNLk$8@H`VYeC&nG@eycogpJr1R}%oFz_xVVWB zz2*?{%vZwszlL~$_-F+G9{s)y6K_WFUm#v2o@<2j-$#6ecsYXqf~m__BHoVRk8@pX zlz9FR!}+#K9;ZbrLg>~s543D{lWn?)F}ME#)}N2 z{I5m$gX9e{tOVzeoTtHbRpNE>gYr!gcZiQf@Xr&k5l_$Qat7-%7xn7vaEW&!`1R*$ zyiU9uslUUlKaY6ptKs~g$MZLcmm>IAh&PFkM$Z4sJb#P0`$e69aQ&a<{r8F6k^1`) z^KTQkBKQWDzeBtb$^WN#|GUJq|EkZQ{@*%$nCrI2$F$zK9Ki#>NhpT;YkXL@ivGsDI(&@RV-c_YrwMu%lwxBO-9)W7Su>2Q$0M|r)`bdR#W zY~n+aeBVyId?tLpFR#<*Gsq9lm*wv=^NXhY0@BI*P-MA+^8Yil8@@xIC&(`-e>1{= z+0*2|8hku@M*c3He~F>Zkl7hk*1P=1y_H#PyZog9HS1syt`7BScer4>?xbea;ewgn;n)pB@{j=GQTg2Nh2&exP@eFY% zf-eydF50^}d|lb+>fia7hUL~J{C#0qURc)k8RS>_k^WuS8s-&0s^!*a!~6l3b0ks^ zuV2UKsj2zSw{_TT=&zh{9+y6#rA!OxN*OhJLJ8C=?lc|`@;B_hz}DlM$-Ql@gnh& z2XuOi;W6SP#I2WUyuoqS`Rt!c#0vq=^uNdUVKl%?Oi%nnygr+F^QG~4nRw+FZ>45~zh4e~tl3IT6NnCFw%Aumf_Hj-bLye4`1 zfR_p9XMIAK&nGVzoHxQ7AkTQez78wMZ)Z5aJb4y*Mvz~GH%wlhyygdVzS-U3{7U3y z$?F8XU146Cyc~Hxc}|4qkk=tEOJ06cIKMi1#uTrYyw1ijuNj<|JfEQv;kC)L0z4>R zglEj?`;jHD!>|zHWys4DZ!&Z@gv*yBuRz>mSd8$7$g_!87?yg&`4!145_cI|k^Dx< zD-m}XdXfApLHT$;Jl0EbOZdFC;JoCyi$lX&NM;_+6HemWlaiMt<*$J@k5J{pgAi03{Mk9Uc8KNOD} znJZO0n|mxCPZO`#;&F?3>4WijhPd_iFuoGZzlpbgJ02e(o}GxtbHtsu#p8p-i*Jp` z^Tcy+iN}YCcYiA$FA&eaF&-Z#?p5OPB60go@%RYw+y}z=5k7w<;+^-$$gEX7r}oJy#K_rzpK*^KcvG~Q=icy-uy%ue-_?4nUDL#M_Ilg{f)%i#0Mhy z?Zi98yOHz%6R)pJyb{5?!T9)m{r(pt<(np+Cf@nAaQ(c3=eLMw67URh=aup4v&0*} z9*++YFaJtBo+Iu)9FGqYAABSp&l4~HYCJwf+;~kG{|v9cKs+-Rj}H@Xyfz*$5^pEu zKSF%uRq^Rd#BDnsA0?i9bv$kpFFYELmx(uiGmJlv?RSNE_c!A4D)Esw#N!U}>Uca} zBW{=DahJIJx_G=!JeyEHk9gtr@#!1Ho$qKo{iixKgZH0!F@gvBg%)x5FLb)>q7LP= zTI&5LZv15!A0*x;J`}+l5q)X?(|VkhpWlNg6L!suI&?SfR=~B#1w>m7G z7v?p|bN)cfy>IK#J{9J*$t!+c%bQC&>`aAu#%EZ6zpv$%ufx)Gn3o~X|ALnLf1$(X ztHQh-dBx9adG^nU|1exHL*#j1(Rk(Wb?6V1&x$FM=X{Rx$90(f&;>!&sc@7$`^y@y z{D}^m?+WuOL4M!Vc>b?+*!f2t2AS5#Grp+h?w^zYyzq5+0q?6CFMf->w}#K#A}{+j zjpzPOhsNu|ybgKxtj0@!twaA;!o2in^?mc2%x^)5)@|YPWy$j!8ZUf@{OiKJLGp|n zwcNjj_-|-_P%j1YI(dz|z-bip>@@(=dlVP4sUX#26dAWzfyefGfdD(zxhIuY| zC0>VfE3fBeydGXigS-lPP4cW4hj~7E7I_wV*>afIB`-%_p1i_$!#rzN-?svJrQp1N zm}mbed|kOU`u_Xt!p}kFT>U%0F)VLh8UF2Et$({G!gA*Z{kw8gSYGT8|F#D7Z|`te zUOKLSXDXV zLsKE1i{Qa}dNnxz_rmEr96vk6E0Of?zd!h10*Ac!78(g8wb?VdCWozMXiHxRE-D(i(9CLW735Rs-4{edVI@J{*$~gSHpa_4{JvL^d3wL* zwfTMBKt4=)o%{I$c{xE|Pms40+ttl^{pU-fD+)0pIua3`WG(qks$cM(_^Kld8nb*Yg?F4x{L0))md_MIAdG>Yj{BnZ4 zlOP{1$LHfE$cvNl{91y%lOP{_SA0Hpg1ng^&%Qf8pHhO{OORXdiO;8)Aa@hwh7+Gp zAwljW$U6!0{Cnf`w-e;e1bOy-@%fYzi|1!P6qe`s`w4%p?1+XEcs zypSLtNs!wK@@j(IO^`Pdh55sg z-=)a!a^$ze-_d!!PkA?@4;h%(=Zo@3C=dKK1rL>*z;7qWGhdI-e<(pdnjo(w$o&Ml z^^Jt{Cdfw<sPrx@G*Ze2^_7Esi9<4W*^1u&IkWYGn=cPZKKwhLg@GBL_ zYm^86qXKz{^1x42ARqje&Oh)6707MMqvdQ+9{9Hj_|~7q*H4l1z+X+kuTviQi3;S# zx8w6EP#*Z13HT1>fj_7~-ln`2X$NvGoqtqbN|4tRv(=6L7xAccz!)Wo?D9N*AnFU{}s<~Cdi9_8_(|~$V-2h zz)z5u+6nvwdFk)t`P~Hh=s(2sjem@n+X?b+g1odGpHDkMUi@x6zm*^_{8K!?ks#0i zb3DJEAkTH;`LzUj_Fv-p(Q#PNZb!pt{}aWdexai6`q}tV{D1oQ)78KJPoMwC&9D4J zeV+op`;^~Ux_;s>h!1hUy@CDYPyO@%o9V38_~&FaLH@+~pL+8DB0kLWX1}EU0Tlm0 zhfnwZSRI|N`F$N$PU!vkxg9#pKc?jchDC-YhBm_rLx-Wu&|}zS=rimvG(M>Fw-{y_ z<{0J~78n*8mKfR$D-0cmE<=xDlcCSB!_cVl{0y@Ua}4tg3k;oQ&G&M;e!4%>f5H7| zeoo`=S9R!cb50B_yL`7iJ{G~!q8#p zGV~ZW8Tt%63=Q5li(!^wE(mw?xnVhi`U$SLIjzfMe_Dr~3pBq-{uA|c`+*=D3f%;` z$9?)CGJg08^7NVb{D+d{FNo(C6XbS+JX*fscai(3gWqQhpYD5pw*0#E3y`14C~A@6 z(>;&Nbh)?cd~)y9VQ~I7_lrdPwfyht`i;uH1bO~b@%(y%e6SwRuO!H=Pbcsbym*e?`KZutbUx}By3G%^4JinbF zul`{?f9R|6@@|5>{Iz&~em-8_O^~}^kLQnkBVOK3kh|ZE=Z`ew<=H=qm$wq+r9Y16 z=N^xjcM|08LOj3pt$2C*PvYf`1bO+}@%*7yyxjjCZFk}Po!-apa=&!;llpgbe$pks zK)$tA?_c)U|3B=#37A`D-Tr^tQW_{jQ$`@{hdnH9!yb?&EaHfWK}3Qeq?E#d(8jV2 zpb|i2M9?6J^CD_k9odX*4!96D85S`L%76%wH7Y_7kYN%2C;8rY+vnyyioWmrzj%LF zb7^nR=X~aVp7Z1+lT4BsOZAiZJrc!dtuONd^D=M5_ov|p=r5r^Hz~e92fv2?2K?IF z@%;t(N%$4ar+9z7UxHtM#`d@2S6_|y2jMrKw*ASKY~F1gkFHM@ehK~g70nM`ititR zAHuJ}FFhac*YSHO%9u};S&R3_;Ai0Fkr#-%hm!66DTOM9` zHr^le@WOK*-@^;7c)#J{nLow*6%TKFc=pfnJp&#-Z)-Xr=uroHz4cQx$KBkk56eZB$v`DrEoxN0eQ z6&%Q`Z@)9Yg9`Tay8FB4I@`Ho=ieY$+9DVV?LVSFU)8ImY=+BdNFC6dfcWnNxdyGdvW$7Ld zkF$;K^Y66%uVee;To}XuWB-=$xsu#hYzE1aW#dB5$c74kg~v~~8L#}jZ9BKU%iDR|F79C&K4Mwl#xnmm%gh(R zAF~Xfx8wrW&vCcOnYqu}{?d!C*WBFQrmtDY?P5vV?PbY2ELn%nZDh%Lu;e^gavm(X z9W1#YSaLtG_Zlj1IP+;7&(e;B3sCDWO6C%4Ut)79$7*TB5TM7vW*NTTTcp^M&^)tWD%*yGXOq_ z^h^T-l%5Lrdm zkfX>kWE&YQhhAhKvL88!97c{JTgYS&z8;xF7LaA+5R%6;itQ$H9GP4meaI}bfGi;^ z$QrVNY$1bb=t1U?1!NgnMb?o`WRSG4Pa^w}oPP=16=V%LN)H)Kx1Kbz4_QJEA?r-s z55L#*vx%<@R>1Kh`;h%e?HdFiMUEj`$Z=$%7xPEHgY|5jG_ruKAzR4I`sS68!^jpgy8-qihmqsR?1r{~2swsKrHvPmRb(5P z*~s?yBWuWUWO`$ai>x#M&F3GfO{^z_%p&`cdF20J-&cwlZxC5SHjv}Ua8sLi7TJ$1 zBZrVRB+s)^Y`2k#8907q0a->4A?wI7WE&aGw69Mg)5sjMfE+}QBHPIHEc^OAvWy%? zHj(4VFoWYp_9F+8qsTTgxfy(95m`bGAxDudWO8%+x*W2EtRm~kHZrvZjsrP}97VQ} z$t}$*Aj`;6oz^>-n64-;W$bjv!k|?Mr5D zoPOj0au8WXjv$-J#J2Wz3!j%?Y1@6^CGJO7k)y~lWU!rmT^8Ag97NWU4P*-$e9*ow zL}row$P%)QtRlydP2@N-xxMwJkRdXI%pvp0e&hhMf*eNHkz>ek2kS2&E66IchO8r7 z$n=i(bw%VLvW3j=Wc&4cUAT??Eo35Reuyj}2a&_bI&us-j!f>1uSaH(Ib0moNF_9IKk0c06Dh~#lpuswvVB8SDR$u_@Ua|B)k*+K@p z+Vzk^rjc1>AF_ZPM2;X^$kcAu(}ye}Igep(BOAyja-93$ z2sw=8ycQ;Su)FnUka=VYSwYs23%_3GJ%;_`$mEC7i_9YjkQHPN*+wS%?CbK#QRKi! zjE^D{d)T&bKL1yE8pn}E=8+{NulFHrkCK1Xj=zAcBNKaK{gD4x)?vv!m;7Ahz5HCH zg7dnD97m=e9HU+atJw!Oz($rk;BMQWE+_*n3qHL zBP+=N^nR#@uOInu_WY;g^Xo=2eqw(dC$faBAzR4gr_C!Ohmdt-8yOy8UKTlstRu&{ z|3LFf$SQISIgZSH#=JbTj2uReA;*!~gUla9){w!$m>05y97eX0$)b6E$bMuMIf_iq zhKDR6hmlQWaEN&sEcTa>gUALloCgm%fUG0i$ijT{s>m906xl=uCG$dL z5m`bGBCE&|WF6T=2A{K@6f%SCM^=$FWF0w*978sdZDe8r=7-E6bI2mHgd9Xxku_u; zIfiT_!(*&Jhs-03$P%)G97fiWW8B8`j5f9t$70^dEHaNQAuGrlvVm+PbH`av5jlXY zA%o*>e->Fnjv^B$*#11SA31_-Bl`x-*nQ=L&z~?qGJ2|kp0LivW{#cQ|H1*_9I7->2KKnB60*dj?A8C z`v;H>WE+`2-}V=f6=WTm`X=@x%g8!1ae?hmBm0pf$QCm5E%OGEW5{p_{m2@!h0OdH zz79Ex3@$XDLza=l$mF+e|HAoWyM}Bd(-)anL=GYw$i#PSe*sxT2H(Z_$RXqyGW9*% zUq-f&Ja2=l?av}B$QF_wGrSmm$iyYKT|$l_%aO>-m2C7I<(a zdXX7q9$7+GkTqlj*+K?ap$C~k4kCw`wPe+V=$GLI}HtH?Ss zyxIIbGPuRIN0FSzlC;PFzUw3SiLD#2mw)&A$noouygo*-UHqx_zu&Hh#LsMA8DtST zglr(&$mGw>FCuHmHZpUo?aw3MZ^yf2KJU-x!SCDa1?O=KnXB9RT|qXG!EMIV$TD&m zIf85=6Su=h7La9R1DUwPynf^`GPu)th|D8P$SSgqY;yZwe7}0%UJsae;x0Sx0z(kJ@$#IfBgGW4w%PA~W|IA3!#d+56Co4DPq>JhF;xA+x`<{Z-^R z^8LQv|7w2u2kf|pkWFOxE93ph8nTJZHEe$gSw%LGyxojryYJWL4K$U3r(O#c?^iX1^Uk;&ho2RVRjAd?Sc zKeB=xLng*-e->Fp4k1U8$w$m9BCE*v`+9SJ`ux0&`S(4F<3bK26Tdf}K@K64j~P!R zYux^W@jm1Las-)p-1cXY!^kmY;tAV7gbbRtokZr4CFBTl6xl*1{%BtpBKweo$SQIK zIgT875?}X}CD-kLEA{#q#JEjl@U+dNfUG0Okm+Y^{~&S{+4rpRVdMz1fovfY&zYA- zmXL$UDl*wJuZZkNR*)k|{kg}&pJ!ly6FH95pKGN4WaDIzeBPhF+W7z0_3*EH`FcSK z^IG^i$Z0mO8aQ7!XkokbXWKuD97pEP4Ja$U3sg?Xzuv zvTa#Ljv*5-;rv4mAxDwH-)ui$|HxpQuY=^!UjQFK4kP(`NAhLs$sq@jHDn7JzG7ZK zatPT(=3ce^OU|GF-ud(Y`ubIHo-~lfzuS3JLx!(m8<`%r?IC3Pb=xi>N0GTVj8~D# zH*LFs97Sf|GTuNI|6$uB$nb639zc#DQ}2Ky8%RB#RAATt0FuW;pT|+fejX2xqi=$J zy&lIPIFBbg(L5g42)20~{{y$9b=Q z8}lh7?YL^lab#h-@nPgRw^uM8_F9&Zb!7Sj#*4`0incw7Y#|FP8LuOgE8BKIatPT% zhAG=$LXIMns~9gJ>&U)UjSnNk)oilhzF2J6~(2|0pHu7|HjHjt_H;UgQ!#0Kz@4P<6R<27WM zw(TOaj%*`y8=(i;MD}fLd>Hv&&qI3S_`1?2)-#ICZfe^#B>n%X)aQf23>&W>Sw*I1 zVjjpAvM|ed6PeA}b_1El^Kjqu^TKB44w$45SiH8w$sQ#WU!6#JTjHF?FzDnY$C&LZGQ<_L#DSgUO)~a zQy(;5MplpwWO94k@B4X40sBkHA*BAiWDGpDgY{LB|7sooxAu45Gu*j+c-LLG3)9iR zGd9c2++t=XJp8C54w*A!^O;+086H1(!DgAv%*{5-gqvqJ-(p5)>lvAC!_2nZWirwK zHVW-4tf%v5jqNWJ+g~bfzq3wvN5*!)>tFL{M%?`RoAwuc)_a#}VB;vz-~Eft?C0Nu z?pS9<|6e}ZJE440^j}K_oxic1nDB#$EVpX(PiObym%F2liIu2y!WvU{ivD|FnKfdgs5R|LR_rZs0J^i#DfB$WO=x!KB2L z{%C(9AN|w$|AY;Dg9+1vh|d%sXyiM)!o8HFIX?fAdRo=h2O^4nAhVoK79i#aYp*7;Vj( zGk@M;M;y-DAUNunxik0aOeea|Ch|m>G&pg>+B>ej&f1;J#0k-)pN{rV3NDZSecv9& zj3ee9aqP@F-D846o(R)OOu$8{BV(Gmh@uPIj2R z;OOJCGiFDdM;&qOu}96FF?ZgfN6enr*?q_nI~-NoddqOe;o*#rZ@%dNhaGe5>^YyE zQCcwn*tv6#oxfnlF~=^LKQEH}JG!fR#Jt0!1?$|VB6Z&U=*yg%2XV}T z=|bn5f?Os=cN0UQz-V()^gSe3jN_Ao^Y4t~O9!oc;`o$c^xin02d)i&NJQ8s)lY&)TfUQZvsvf?Yhp+D8Yk2sY9=?``hwtK@(|)PorFV3P zJ<6II=#6S>Bu)$#ao#-4fA@K4{N3kO^iblTjJr%QBIh%EHkI>m$LR6NKbwE%>?zKn zbylV`e{#eAcb&frpPb`9?tPeTIo$cWqHzPfl z!zb5qi{k$YJ~_vov9!%cImaza&*$Ki>$o-XZ-h_IabNdvj@yu)9inCIp8w!FZt!(? zolk{N&T;SZaE=>F&oa@D&bZ_{ZeIM4!6)aq=XyBDElJOB;gjpQRq)q$R^03BX!zthZch9k!6)aquX;GgElSU}(KpD> z^-HefR>c1TeDZd5`|n)XU;d_hTn+f-jpbZFe~Ig_8}0ARhx~r*W`B64>mLuFyz>)? z&gB;opU`>yv-_q7I^V#f3wugeyFGtE5BWvW?Q?NIdA;jrdTgHL>qYn1i~G5oT>o_V z^@gsG|%SG+@8OohrEsB<#9FYuD^ElgOu+526)=0xo{nV+g$(C z@W}_|xGHzL{*~~_w_nc&xGmzH;|k}@Fc4b&f&6rrFPwkN?SB*f4e%o7^U-OYzMi18 z)4EoSf7z3H-tE~d@;mE5{sCOSuXs3n@_%!CE==P51b;00zS6nS&y2f1dG$?~?>XIi z$nUh8g*~OWT%SG7$@X8+gYTh-yeU2PrCpyrm88pGL=X8WdbrO0d&jSHak|^X{^CmU zyc)WErxmac;O|<8wOyb6rEOjQb@Y(yI^?%=efCs#j_0*KUH%06$+f@I`Np@{h5flt zxSZ=b@QL{KtbZ!rFYgoYHxG7wj$1xDp10@4^I|EUw?7xpOUK0X>WT4OpTEzFo(FaB zm+-v)72J>6`b0lImgmb{w~DNT@l?>*jrX5+C6JGKc+8@+r#(F5;aLyQd3c|P=RLgO;YAPc_wbU34|sUl!v{UQ;^9NFeB~f1KX2jrnLF6M zost(P#qm^7mHs`W+ePR5COL0SJfDZfKL$Rz`Ze({fKRUei1@d_Cs)5N{^Rh;)gKjq zrRafc=XlB0Z;1bK_~h!3i9ZORT>Yl_x4|b@za{>g@X6J0i@(*1c)SO${Sx4%3O>2| zS@Fl=ldGQ-fBEP~v7PgoJbJj;z3}#%7k?pN`1s%a_0f|D?~|S(@wbOhu6|Seec+Sp zaV>g2;?BQ)5FWQ2IG&ycT<3)N z55Ona`6R_}!C%N_K1n{`!TL;!rr0?j$hCjr^CP)_Lq0!JeyMxBYoR{`$J5+}$D0*@ zQ~2b%J~{EXgHNu0pZI<7$<@z`|0($7>KDYH3!hy5qWH(cCs)5;{L|r+N1NRX&!4jR z=fNk}{z36Cg-@=2Mf~gGldC@@{vGhi)vt>G5PWhyKWpMY3x6TU09>Ei_ucdJb^74i zKO+8a(MwaE+Y7n+b@9)EPphdn}5-YV;CvXFlZW_ltiHd~)?m;s?T;OcUs%}$~coo&zSbKrKr9lhT}dcJ}la`xPho&itKfb>jT-{wQko=Ij z&d1p&1U?-F^C_T5Lhnzi=H?r%i z?CHr$&qup{Z$QqTbI~*E>B&pa!{{Mr&l(%se3FO8A6LKh%<1~Q0XchqfS!VU}u^YF>luZe#id~)^2#D4@n zx%$DT?)t1X)8vw@X6KBi+>e-a`gwqe+fRh`c?6_nPu}Q59R!Nmw-e+%=;)lbfJ*XJ?#WAX*@j;spx%xTrZ-Gy)eo_35x3_+B^~>U42%lX2s`$(9 zVEyE--xD;8_BbTK<)p5^h(`~2cKMhKK`fA9zLE|&d2A<`FLA7 zA3rPS<6-4|e5;&~SC#Yer*b}?RL;kT%K3OtIUm0%=i@P#PYc>tMGvqSyR5y_KYzb; z`>tgdvxDI3==$osuYi0x>`ioYYV^i1*M9^)`H=Wk@!x`?}zuq z^SXx@?~V6^`{H@k!*ln?`%Moo|1#bWABg954=?^I-VYk_yz1e(U&s4R4=?{F-VYy) z=XDP+J{0c$4bJO~ zJwf67@jcCF-JU(sLw^1gyMyDnN5%8ZvGKfeay)OJ7SHQv#q;Vn;(2gkJTG11 za-LT$&v})+%Jq4kG+v*y*x3^VD@2b^y6hw?ePaZe$L}pJbuCB4}1KQ$FF<*L61M?@v9!c?eRxEe&Wjb z>$l2?uh68_r>$# zgYmrZdk=rY!=Li-=REu`9{!?-zwF_!dH94(8uZOQ3 z&&wV@?BNX`PsR5)R`KvvJ$y9}U){sk@bEP~d@Tk!z{5B6 z@U(|-0H05lKkxcmz$d?2{LB|! zpFi&<*Pr+1#Gj3R@~rfiPjUO7=6t~S6u(h+{lj<0^Fi=dU>6>5{Z!X~96tF&@E4x9 zd%5Qid#b0oJ@i{X|BQHlFdyIF{93#}=JD&5cz@jEm%icpJg(fg<9YL(2*5&(8;n`?&Mu{DV)% z@#ynnazDWP4RV~e3*VnSEdJ-Bd3Nq+$nAJ|zmW=R;{O^xx$E}^i9OuM)!AL`bvp9U zInR58wD{kEPwx8B{nFGl8Z5T^&_BOl$~_W&&0?3AqyEnILcY4(u8WVl{x^3spL`Tu zyk2~_i_Guc9$TlWLGiJ8o_jo=*Pn1X#|A6=ik^0Ld>)AaOI#b-}O&ht&8 z_3x}Fxt`}~&v~9Y*PTD-ud@YZQ(KD+k)^YgHNarA+~#V%aWB)cJ?cwjQAWvaz_VD+|a!Q;} zNqXqFJmZ#!-EoiR{K1Fib(2iZ_1WLIQ~dhWJbugLhd+()@6W~eSMG}U2RwfGi+F#~ zGAADBd6P_{F_k|L>S5c`Ew+YUjfBDbIC% z&VSg`UpqYBZ+raYG4Xz;FaCIwC&c?Dj~`qf@25Tz-ydEV?`J%I@m|;Gx)tT|&z605 zUXd5OtIYFidXVuv{;9~gw*JxM=WE@^A-rB{9zTrrdxP3%<9d37u~^;{G-CUEg80W{ zJwbafcb#pXsUUr=`#5dyXni`5yU1-Fxjv~NBmTwk$<@z_{{nn+^>gBX{3A9Wa`pSf zzZ*We`g!rU-^2RJ)h~#DCwy}Ci{fwdQR^pHzhC?-;FGIg5})T`aFl!gY_w-*-01z@ z;GuJ#_XeT($G|67KPUbz@X6ILiofE=Y(C`bm&HF5KDqi;@&68=T>ZNE1AEzg$klI( z{|tO`^@F3`_228`SbuQWpB4;WlnxfZT(RFje?C&WF!}`-i(UBhG;;lUT3LKMkER9{ z53dWqFPeYnc_R7KlWlPJ)T-`$mdTq>-Y0%=h3kJ9K6ybNw->K*{fpp}x1>LRz3cxC zKKTvOpZtmIe|T@3Kl%1cyT_Zq&Go+npS&#njZxSCJ$!Qhx<;;NvEllwd;;I6z_*wF z>cg(TAAIsn#cw?B`rm|4&fl}g`Lv&Q{RiQb7o|V{yz6hfkIjD}pDOG5n(J5TgJ*3b z3m^Yf-f{g`;gdI|zcdvOpm3Y{=qGJHlgOLc@BP=`1M^~{}%Yy5er}%YpADaUDEgMwxo{mah4^)7p6d3zfFAPuafi6fex3W_=;y8%Y+=RG zy;|q8_Ch`je5r13OMX0fXuJ0&-x@q;{0Q=EqYsF6F6HjOL3ttP<172Y3fH0bwUtf8 zzdYW4&+%ry>-y{|Ulq^8pShgga zYsC{e)PHN*ypX$^G%Om^Y~?tKN{=z2FdyE<7&<)>*2*% z9(}GncHHRmWwYJui`QfM&A8V)Qb9$Ye>Jeq9CkA~k~Y3nZ1 z*L}$8bKG(GCaq!92Pm2E*d~)?u;(zSZHXm~JL-8+% zPi~J+7M)jV@uwYN{p8x85&u;9pFEWQhWMlK z$+bWEIrn(iI@tQjU4L4TyD5zkEoQ#>&wu_{Ct3%=jX&?Jh$^J`gwx% zd=)-9dv=_S?`!bM+0&4om*A7rzxWXAQO=&G^z1#yd~)_oIy9cMr!74A4v`IeYdx+Ip0;rzky7!6#?WrSq&uIeSXdGiSc} zG=bEa`s&GIqOl*o{IDwu)utB_N;nLJZDc;dLDsK&YtM6_;v43l(VNM zJ(G?zpPW5+csP6N(sTOp)4?8!*aXUpc3vuC|i<2ieB((?!SH0x2$p1kzD37?!jH=b@i%Gpztp7~!g zpPW4#oDt92Q<9!Pz$a(V1z)xv;2Ke_rf@wYh3d~)^c;{O>wx%v(9FZ-(XldInpe~YutCs)5M{`2t3)ekOrZ`YTf zWBugnC&fSTYvz-yABw-y*UcwaKO_F-@X6KBiGOIt`pMPLi@)x<=98;m6u$|dT>X;x z)o)lox%y@Cw>r;!a`h|XzXG3J{i^uapKtx->es|Ceban$_3PqiE-;^5{f78=!6#S0 zDgFuHvVL;)+v0CDWInn2!4>ZL{|J0?^^@YC{a@Bku6`)~iWizsu6{=RyWx|opA-MY zZ(BdP`g!p;y2yNT^^4*^2A^F0lK6AKWBufK*(dn3hg)BCKQBG=ziU0@n|8k+EV`es zi~kCIa*liA_pC=b$8Ac_+wjSC+~oJ&^XK%c^^95*99Ux81q;}*qV?h@-K z=eXbSaE@D+p46q*L$2f2#Q!dQa*q4DhjZM9^nCI%8<$+i4Tjxy{vmvFj=SaM)}x%` zhSGC0d~zK(FaC~KSU)+(y~D#fZb^FjzHdF`I&M|`U&1HnxcOo0QOru(x3ma z>t6|r;8a^^b*5uIrP0(Dj2KSwFd+4~>Ui|10pxACmQ{J?8o!xX${?bv{vY9!bKE0u zvL59ewru{eYtr)ud~zMP zDgGHhvwm`pyZq1NImZp2cGvk^@X2-DjQHWL)=$oHul8_`o0pz!-FnD%+_Lz0!YAjr z>)&QQ$~kUTdcF*wT*qyQ{~UbsynTBN=H71OD(AT2GwwP+1)rQfv+uATk|1)}x#~b?JE+J~?|nb(i%hXHW83_qcuwpPW4#|H68dv!^IMr@$v?&p$kzJvHe$ z`EDDRoIS65ID3NU+~Yc7)OyI-^RkDtCoeto@39_o_PpTX?5Rr6(f3*pIeTvRaQ3vN zXXX2>hkQW3zn7kO*WtVH$t&UqFS-8u_ha3_&lkV?s_S0~pZsj`GjF*5=D)Ola-Dze zZP&jUKDo|6H)&PeqAhX{SUMuZn-dL*|pK-xfdn zTl2})&rNgZ{}z05^(*3k^LN%yu6|SegB~`YT>VVaozI42=98;m7XJnK*D_jKDqkI72NsM93g-QDb!E5z75L->az2D9 z*Z|MAbFA6)&a_{%(p`Fs3u zHMjp4@X6oRFMhd&esJ}})!qK>|AhI2)3^7_^#tMZ8{it0>s@-r(NhJlF6;Wa4c&3S z`ez%LT>a)|uD|AA%qP!Hb^F5|T>m=wp3Q$#p*MgIxc} zzgj=J&L?-I>%R$~ob%!JQt@0b<>TBQ`fZQj_2i)c;^`@S zeBbXINuC|wufO+zoK5hQqByxP)T=@IJ zM#bMbnrG*8ALMpCi{3Zh5dU`gbJ!|;&0YZ zuKu|Ae}+%4evsPQx!%9|vh|azpAdhiSIj3@KPmom@X6IriGS{^)=#c}DE^9nH=kVn zwD@WA3=S(o4T>YB(D^E0^T>TO8e+i#l{kr&DO|pJ+ z^+&}&3qHB}4e_6ZPpnB$~EB>@)%_mnsC;o--$<^-@f1Rn;Pp*Dm{2#$5SHB>BZaM2GSHCEJ13tO>{o;S7 z$NI_DFNyy=d~)>%#6Nj?>nB&gEdJDK=98;GDE<(9a`h|Xua&fZa`lJAzXCqF`c?5~ zPPcw?^@qj39zMDHHSxDw!TQP79})jH_~h!>#s5gJ^^?1PZ_xbVCeGv42fF?up2FUB zKG5mu30gPW^R>O5=P$j%xbz&~^%rsWyn>$GP1bX=^dxKUd={+O88`YIH#mDQ^hfhS&w#A+i1f6(es4g|o};5*;N0m++!8;ZhV=Zo>-Pra?AdJ%>lsAPelnky z^nADLM}M~qoIUHVX+2H!oF+ZNkKFTlxa;=@A9inM}LP1oITmKt*7+U`1$ln&riF4Z$QqTmDaJIarEdq7p14v^`pN# zFY|d7J^7#6d~}@$r01k{JLC2SGjv)6`pT;%L|q|1AP zQS=N-Pg{BpO|iR;|k#lS|^L(ZOHV_Tmw^qe6*q4W%P{pj}- zg0p9ZO{}MQTl{>o(sNPQ?+wV=^A>tq=+Sk~OV5GP3ss%-keofwb$L(Fce~9;*STMM z7R<07a`wE{<S$e)a(|X9+v-~VupTZqBA6@4m>A9fmN59tvoIPR2dYb6b z`P8K6%B~;%{!;1Ld^79mzcYS5qtbIr*Y6F;IiI68x1Kh7ekkWpQ+n3iqT@%8e`G$t z>hkFKz}#i?xmJ3{rKh~5^^kKuv$nGNswn-aCiKC z($bUL#^yuLp3yGv32Nxk>pdqu`REU+bk>KQJrlRJ`D90JKDy2Y>A9in_XgzbnY*3! zw9upLT#}xZK4|kHXU|<--V+Sn6Ti-b(sS(g)?uO^xYf3&Q-y2-A8__uwUhM>-e>ciK>J9PJA zuP;Q8bEM~?uD^)0=d4|DTZdaQRIeW&tJUS1589$$t^wf5<9&+~V z_#vB5{{z;e>zt9E`@4Sh_y?RlXY7vSLXWO-y2-A8_`3?qk+d`i;%!r_xiGp3Gi0A9D7*(B(Zr=0WTEiS&#~&($Bd9&+~d=WRZ1 z^xP~xZRuHWZ|fmv&y!sqUGERY&nI!Cd%LK9!g|Qrv*kWEpVDuwN7p%&p3$z~8<4Z- z%uiZR;&<`uoRyy4_qF+uvuCMKSj19{+%|=ZpJU&)~y0A6@5u>DjJe z^C4%?c$Y_yqsHRbxhy?5?QcEg?(4A8;}G$e{j~Yy>Nmw7gio%1@+S9spL~GzldGQ- zzYL#T{gU|qfKRS|Rs6jVwE2*$-w^*-@X6H=e(WCao}aOPa`iLf-wmH!{i6809c2CF z>Q}_S3_iK~b@68%Z2jcwx5d91KDqkgh`T;J7pYB(YaVX>cKe_s8@vnwYu6|zpgO0F%a`gwqpLV4A}0a`lJBpLdM)ldInle}iMqCs%)5{Kw#v zs~--y>v{fh)=#c}pZMwH%_mpCB>r>o$<-ec|MC;8pIrUA__GJhCs)5E{#qxRPp*FQ zM0b6zhfl74R{RAgSwFe@Me#Eyn@_I(p!mQ}^n2tK*`HSq^dwSIE- z8{)5en)&4Fx5fWCd~)@ZC%fyv{pr?Eu6{=RXW)~opBMj}FIhji`X%wVIKzB$^(*54 z9zMDHHSzcVvh|az-w=P|ndXzL-xmK$_~hy*Kku%8e$e{K)z64O4xe28y!c=IiuIGL zUlM=TS>}_gUlIQa_~h!>#6Rb&)=#c}L;M}iHlJMmw)l6zCs#lD1$X_AJ;(aV)z65( z-q*}0S3fWQZ{U-wUlRYcuUkL4`W5k?hEJ}3P5dn?)=#c}L;N$~ldInrfAYE3Pp*FQ zi|+c*hEJ}3M*NH6ldGQ>|7rN->X*bn;2T(faP=$VKM0>({hIh6I}hvc>2HYtYxv~a z-xh!0^RfP({^Tj{`acSvT>CTPANWn{Cs#i&eiJ^q`X%uXy#VVEu6{-QKfxzgzb5`? zzlHVp^f$zR1wOgN{9}aP>3d-vFOn{k-^F zeHZKR=`V?Y6MS;*uZW-h9@am$f6@E>0$lj{Bffu6Ip2?`obRtw&iBhH=lkE3^Zjhf z`TjKJe7~7;zJE+P-w&po@9$F1_iHKV`>&Mq{Zz{N{wU>qzmsyle@QvtkEERMFH+9; z3n}OOf0Xn6Jj(h09OZn!jdH$!MmgUPqnz(=QO@_PDChf6l=J;0%K82f<$S+~a=w2< zIp2?=obRtt&i6|w=ldU&^Zg9U`Thjue7}KmzJEYD-w&XC9Ix*y=j-*#`TD!^alD?c zoUe~7@5k%i%K7@Wa=sp|oUbn{=j+AF`TDPNzMiX`ug@yy>#fT9`l)ih9;%$LZ@PS1 z5H$G{8{6}X=>B}E;HBtOPVR;G+hc|J&&gJ93!N`Wbho14uPdKp{c+Ua`MWLT?&~$v zgT7w(`{TlK-?Z0fIf(J-??kWWeqM&3S0&fat7gQ1wEO)l`n%HLHgA4jHF|&AS?+vx zuG;rIavrtKXIfDD=ti7kH!q3&xb@`v)Mb6HiTv*0y#?oLTmSSRAG=Zt{9> z$UN6x-ag+=p2kQZ*CsX+aBKBD&DVe z6VDqSUfwR=&ut&i^B!K=E#5Eg5zk8=-uPI&-_FPLVDEUI+sDKAjpum}Z|oQESN4zR zRSypiiT5*e<9W`*oBbaDv++Fd;laFkKUs?Bp@)}FjQ2BNi03&EFP$3i2WQ0dq=)Cv zjQ4Y2iRXC_Z+tc0ub&go8y;T%mdC#^o;N)_^SyXKxFnt@Jv?)HykGi$JTH5AcwM|- z`Efk2dU)xl9{;v@Ui0wEo$-EfcRWvec>A7sKgVAfkMCc+KhJx3lfMvM{Q7U>`x_n} zJ`(TOef+U_KmUh#UVb*77oUsgB@fU2CEgF8kLMW=ue}iOmtKtLWe?B)&Gq?stP=aU zD|+5~nEUEIq4!-+IXHS@5F2H&he{H`^EbM z%eX#!a?8c>R8W@lb~KuQ=e#Ai@p#^*fQ}_S1U|X?L*g%UrS+4mUlsoV z_~hyji+?SAa`kKCuXUBphurm}zu$ef`*Wdhbp1t~pUZft%cIZ#;(FQ1x&20;kCUF2 zuI`Mxh_h$^E{}e10D5xL6MVp(&qe4VPm7-x|8e-_>gUB@`x=`kc_{rQ@xKh8T>Xmp zFTy8Rzb1bETAL5K`VH|ff={k~Tl_!4Cs#kYqPzZ|{GrW<-1Qfo4*@Q`{qp*C`Lv*M ztb0FyTh#y0?&oWVy7wD){ziX4#lzbk9?XsJ$#{5BiuY@ui|5H>UCwoA$o&}SUpy|} zZ}-IA??s;*mD?Bllgr2ZjaWbWT%=sT))RehH*wOF1CM&y3!zV3Oo zh}*jGemnZPmdt01nw^K_?s+&Z2nXEr>YI`O&(5px6nFiviTuvv2XfAb*H=dTXW^5p zpA&zrA6Y-S`g!pS@X6ILihnMAa`j8%-wU5y{j&IzuEXOZa6Y;|%EPTMdR<9+ehZ(R zJv&}+{mR)>m7edzCudLc2J2DIo|^QW2%nriPkK0e>eBPk8*N;2_T1p%>}g2P8aG)F zIeWhB;p}Nj4|!Yoi|8R|f8obAu5$JSW%u@S8+>y1Y&>E;%Gr~Yp7Y?7v*#@jXHO_S zb8ohB$=UOOhqEUmJ=@%3J>=}EdN_M>(zDD@tcRRE3p|`XdFlB*d~){e_EYOu&Yq(5 zTmzq+JuCgpdX%%LBt56VCudK~!`V}op1pr=Hn za`j8%Z+4H(hg|)#_(#GgSHB|urSQqsuZsT|d~)?`;;(qG&7WNTy7;z#YS0jVGJ43h zrz!p);ghT17XQQd**wYB4^DG$U)R7VS3fC!@BP+Ku6`)~iSWtQ&xrp7d~)@3;(zFu zHXm~J^Wt9xpIrT-_|qS-esc9o;-3VcT>Y~6Pr)Zwzasvgzq0v|t6vrWM)>6F*Ti45 zVg2Ol*Tp{*KDqi0@!Rmp)o+Tw|F3O677a`kiK{|Y|2`g!rQ4_QCC`bF_ChEJ}3N&IDhYyITvm&LdJQ-hlD zW6(p+pSNG`;p}Nh&%^M^-}UqMFS+N#GQY$50M2ng=;0hUl%AvElk2#7@xKS3oa6r5 z!#QqAdL})L^#|8+tKx43pPb_!?%^D_E+{a*q2C59heaGu-QI)|eeH zxsIC?e>Qw_j(eVmbKIiz+y$Rp$E}F}8hmn&yU`;yf8`vvCOrqhC)aVC;-3Sboa5f= z;T$*kvb)YN!6(;oGvcrNs2vwM$KBV%Ic{Eh&V)~{pPb{a`ld$b z{S)Dn-`V5(nVVhzNASr%Kh^bXce?(cIDhbh{9Uu;uUvoaCay>D1Es(8sO#?!pS)xX z6L5W+PrClO@X2*Pxxc#pJ@CoLmUfRfe8u%A{L$u5-oS3or~SI?ZwsG1jSm3O58rhC zW7!X`e*P`j{~>(xjP#fP;rf4uPp*FLZP#D_Nt~bH>NnqU{UUtwQ05a%zyjMc2j7NI z&iAo2Je=#6lb*>>**wYFvz>>trz}15;ghrHG7o1@U3wmYPtKm@pSF1_XHPKEU7uay zle1^Q!`YLQo@?Nfv*$?e92(b2v}H*>jMGvnN=}U7z#dlkbV! z9sRuclUg<|x%yS{kAY9Fep~#f;FGJLo9xbipFi1r$knfie+PVW^_${v@n`ENS3k3~ zJD*G8ldE4AzxOZJPp*DL{L|r+s~=8r=kqdra`j8%ANIV>hg|)-_>aIRS3j9>=dE)M;$Mz&$@}DXR1*JD z_~h!>#h><~9T&O!$z|R7?*^Y-{i66M!Y5b1CjPbX$<+_0y7PGoKDqjN@l$O(UUK!T z;(rW2x%zGKPlHdcer`E;{y&CKu6{-Q=i!s9-xPoCm+W}S50&#L-{a2beE8(**TtXm zH=IA<>SvaB`%i*Tu6|YgzrrV1KRM0qFTQN^Ay>aF{)6zz)o+Wx`zzK@u6{A;&gW+M znB$~T*2+<{abpP`~I{<_dJT;r|t1;9>2PZ z+s~frx-RFqeM!%_8@N7unj6RS>a2KP%($H6>fa4#e`D)-zwDW3n05U#u>Ry}D_;1# zGM{t(+u@TxkEcDHPi}YDe+NE!c`3WW)35L0`rE%|=L7j;*iFB>x9gt>pZrTQ|IDXd z|0ek4ZG2vX{ox_5PhOhi@|V#={>pOhag|E0&z}0{T%H-n@q+Vh@$|zJT>ohJ z$4#E>`d7jyAH;6o$M#1L5<$9g_2qyuF@#J2D>q-H_P# zmqvfbZT)zEJl2oiA1?3nWkm_mR$yj;r(je{x$dzK=BeyXWHn1U|X?4e?ie z!}`h99}|B*d~)@h;@<X~#>%M98Ay>aG{ukhrt3NLO!|=(~54PFVPGtPM*;_Ur za`hA9e-%Et`bqJhflsb}O8gJ~!{$S-eklIs@X6Iri$D2o>nB$~BmP|Ydsf={k~S^V`T+I+~>9~A#|_~hzW#D5Y#x%xxm?>x!oL#}>R{3?8M^@qh@ zb}8#8SHC9y{_x4w9})j*_~h!>#ou_c&4*n5QSr}!Pp*DL{CnV&t3M|G_DkD*$klI( ze-nIi*N^^A+&S*&ao*_qi#UG{u*sCpxIIAu-#2IC{+Zve)6#Qb*Y6F;*>eth20cAF z>G?T&$l3EEdPY1w1?dSBo%u(fLjh;c-d!I3-a=1LNqSC04>^0TM^9=4dwinnGblYz zqlcV5D=uT}+~?`3O3&_HKYE-a$8`dF20T3@(ld-6a?a-w^bC7?8q%}uvbN6T?D=4q zM}J4v)6FJZ6rI)jHCTGufUEUKkJv~L~nTH;7_FRIVRNB^A*JnU_ zeuo}%_AJ|D>zw!WRHSFeuHPGwvu6Q%20cB)(sKoR$l3EKdg`8@y7Vl+ysa}idv@va zo?zV5GbTO9qlcV5SE47gQT#f$rRQ<A4m?@~Q zoo?$~_VkpcXRodweclk9J*S~(#M3h*JvX6;oIQU=PutT|lb$tKuyrP9&*@#>6Qnn> zbv{Jy4@ae^g&uPDe5}{jr{d{pO3!s&Kl(in;OtrX1J*O{=^2-v&v*UafSf&lL{D+k z_~S}et)_4Nm)-YGk!iL>6zE{djoRzJcyotPtTzAWLL5EA!pBbx;*;()SjNI z^h{jUddS&xWS92@*;#g6bLD&}_4G8P=aR198<4YS+10Hlk%^yA zOL`V`{pjal;Ou!6Jta?1aISkk@3Mxi4>^0T?DFXGn5QQtJu9qfJ>={;smptU+-C8| zm64t&(L>IjJ=U`I8TRz_NzZj%zc(Of&#IyIBsY(rPf>bK>-y2}MFeNhpV2em=^2oo zPpob0L(ZOCx;%P3=IN^0z>hkFCmTnP$T*K1yH}sIR=hN%j`qVr-Pra?Adrd>q%`HKc6w_`9|084anK^271b#p0@NHvc9bkIeYHy^5}V-rzi0Z_ja-Q z2G&E)o(sD?`n?ld#UEEFJrg&y9&+{^+2uXKh^HqjJ-V{lv=d`fR*0&MR>BGvXfrpIrTd_-Df>cYmLD^m}#0ufr!-e?%#J>|hx%$K6kHaTde@y&MH?`v>S3j|ed%Q*X zaG{%!Ed)laSNuIC1uTR*w_Iq|;+pIrTZ z@&68=T>Xmp2W?^VAyZov?)qE+pIrTn_;14}SHB?sVO!aJ z$ki{4{{Vb)^@qjZdTZ+^SHB_tcj1$(KQ8{#+gLxj`r(@Hdd`DSu702Rzk^S%eo6ct zvo;@c^@qg20zSF=b@7+q*80iSZ;5|AeDY8pex z;ghT1Cw^)Nn-97A{o*fxPpW{IA0&SHDmEKfxzgzhC@ab2cAx^#{fO4t#R;hsA#lKDqj%;^%j^`H-vM z68{JA$<Zip&06w|;ed6B$pIrTZ@q2c~`g`UxDE{Z*lWYI5__x3( zSASIeDZ63)J@aXae+qnZ?N6-huKz>u$<o0o$ zLx2n4PssN(DCheVl=J-t%K82Q<$OPYa=yN=oUhj_|NjU(^8m@Fv;UuA&}OFfrG+9y zC5XbH5?dQv5le?5C5RSVVbHduETM^|h|m}mv9!G~Ml+V1*g7Fe3852P+1r}JB-&m{ zERDhMR-NbD{XXBEXMXiZ`h7n>^F7Zw_uT!~E!=-+j{E7%aetgS?sqfC{cGm9AI%*1 zmzm>!F>~DiWsdu~%yEB~IqtVI$Nf|0xF5qE_I@Q zkM8%jTV$c{(ap`)&za+Q9Khvq`-$%CuwT6} z>KpS>~c_Zxoc?vNk3#xZ)_(62!wr+iO1XW3(Q4#ur=ulB*KLt$S3 zeVDuZ!aO~!IqDy#`aSP-dAhFzzi#-wK|i^VK*vSMkAuA3HH`d`pr3N1^qea4#|*z= z_^H+O@ubg5xiQ1lQn^?d{m>u( zgR?(C{#D|Gvp+=sr{aUNKSF+f2VW03`(xzaCO)|KJ6z>5y?>mtS^uQgk$-l-7NWAix19zj{Kv<2mhb_JNdErdEt0Z5$Y+D|EBoh z@-;*^W2WyHbL5mL=R)zpk@Ka&kyECeLwEA+f+OcSgCnOxIa}@QbHI^vhry8(Q_jji z@;TthIosgKsZ!3z;)8o{;=R5#^7qgCcEQ=NlmDdn;OsZZ-*gwB56-@OTdx;4i4V?x zME+OegGY%qelO7b+CNi#C%o?C$B%pK6}^OgHNaBlKo8kSBekLe&KWNKPx`?W|Uv~Li?YH4}O>U>+J6P%N+eGe5rG0i4TsP zD-DjE^w&D)Y4O3URDa#c7pY}_F8LE*Cpi0+MYNw2A3VqTi)#NK@`ID8yW_R?`9a`IDj&MzegyiV`I%dV__|@j zd$oAduGI4_nODBQ$?pwO&PkF3j-1~~PDygsr<`ue8I>Gx$x#Pw~MsLZmDzN7ghI{wBNk7HLp?*+}Ay^->lF)T=GCa55d#26nwiKu5i6xE``Kj*m8-d>wX=d_|5Zu zaGYPiY;cTojdHe}<#WJswGF;oN4I-}_~2-FiGzF&bL6Bc=Wy}Cx!pYZPl^wYcGo}H zx62&u7Afa4@xi&>3i)4%4~};CJH)rk9PL&q=Rxtox!nf&YxMejaI|}_!O?ECu3lar ziVx21=E&dmP~R>%+P&A{XtzK)-#pCcfOETL@=p~X9PPeoaI_m!&i04XdNBA7(XxFW$$N3oX!MWWm`7ekM&hOod*Vp;mA1VD3-Y5SV^<+2I{=MRZr{r`I zets+MukkaV5B|!MeuD)+yQB6G5Fh*@*}lPdGqwM;_}~}Qd#ftDXutjEz8>(@Qo5e% ze%kLAADrtc7qmYlKKLNjpW9#inWC=;JS+7dnDFL#M|u~(KkBBO;=wxSHpu~>HdXhl zbd>f-#Runp<&V~W&rz}*g~w74_IK9)*BzsCcJ6Sk{R{X?GJifYIF@_*1f6q5eqf>Pb^6RIEdG5?GkIxG8^x0uvIY)DhTb=40PR2R3+`XT2-E{l_o)7YN z7w@FU0e*q}<&JK)n{wcOTyPwca=qm5Cq6j)Me=VJADsO@@)tSA*8|ReiTu69ALnu* zdk*+!e#-}0gR>u#|Frnv><^KD(D6PWoc${KW8#CeKTQ6)eLf#t z`^o)oI)DGx2~B^3<2t};EuL(LclPU1L2dVv_wZ28e8~Yv&h{rZ^V?m?$Qh!XTUvhd zJKe&O)Ba1JQ#W#Ilv8Z^$@kMK=NZY#{V3e8QOeoqBtJgjsORz)Pkz7K$Z?nG^ZEsn z1CE^iPWJtB`EWfc%K1ynPp&HpN6zY}_?&`~lck*gmY-Z#q?~spr)uO>>AY;`Q~mgW zXK0>`lK)%r!P$@2(Brmj$>)Q!-$nlM;)AnaApa%t!P)O8fAiCPJ>cxe=($-{mR!5&VGsfyOS3#HMc+D z{JqYY{3E~beQ@^cRO`xoZeUogk^pEu0o3~YMKTTxyWSO* z+LXUczdx@5$9ekk2KWDZs>@Q&E8>IW=nj5?{H@OR?SiA-xdum0iE^f%<8#2d-I)BM z_~2;wIfJ9!8s*G5*S8DK?Yh(azrsUFK*vPdR@RADr7Qk-y$0J|7(I zUTSc(TcMmU#RunhYvj+m)VB+cb{{o3+HFwI_b>A~;M{H+KOi70z~$nDquoUYd=7K8 zo1>h=#Runhi{w8mJ~-Ol{BqwebF^EgoVntIbGudYJFf8g;0^kn#P}lL61EQ|@xhms z%Uh_YcDeTdEk1Zbco$vw&VN(; zCGo-2i|YL1x3vEs@xkw+{OoGlKj>N+PjH$K*|oJl0$=z?R8Mw2?eA2PeBm?6FMVJ8 zmx~WRD9aJ!nO$G|_&qG}jQBWC9-ZZ{O9*zzDNqi0ZeyJfp6v?rc#|;CZW`v%7Ga*x zg?YSHm`6Vd^Wrv|V;rpO{IzYhKi=P&VV?hSm{)tkys>YX=MOUY;RZj-;Kyr@{`MWD zmpk~#>0$1E72?V7h77KQsnhzq)OF4CwF&OWYvOu)jr={t2WNkT{5!-4XTMJV64(2B zz}X)qe_!#z*>8|PBtAI%W8^P$gRcjieRs1S&%?zBXTOd7hr|bGKO%p%Ildln_EY4a zAwD?!Y4RTzADsOR`QNzF*8|Remi&VF;OuviKTmvc_H*QaEIv5<-Q;gM*VhluexCfY z_~7jKkpH^);OrO3Kkg=94>eXnCJ7s*{_hl>aE@fXMd3VA@RZ4kICQZHlGj9{t)?Zh!4(w zmHgvx_xa%L50gLb4)23&ztas|s;?hj*YYPg?sqI6H*=Ebw`IS>@9~Z)=kS)_>A;aw zlbk*yXP9y}{B5({sB?lZiKmLOspPv43zeXwN-j<)d4_r8MR=UsURE?Z!R?p|tT7L4pz3>dp zw^8!{B|bR&(f4%zj`#a<182XB{5!=5XTL!HH~;AK!P)O8|1|Nz*^kM8OMGzlN66pt zPre>-_TBgO_}n2rIQtp$JOAwS!P(D~-zPpe`+elUDn2;-74o;P`g*|GA141M@xj?| zkU#AKpAXJ{YJEMPM~M%frup1O{$1jOv)@Dh;(zh=fV1C6evkOz><^HCv-sfb50U?+ z_~7i1kiW}=zJ74_$H<=}J~;cS4fObbDn2;-UF7fbkgo@v{T}k?i4V?xANe1M56=Do z`PskvdcfHqBL5fSgR?(E{vX5#XMc?RufzvuKeeGA|E(YP^@FqDMgDo>gR|d5{)qVC zd>_A`{EHs(^?hC@uoc%uX*M8Ld z;Oq~Q|4;G3*&iYQn#X)TIQwlI>;CTXxc9-??;<~X!u#Ot_mcmJ_~7ghkblaPJ|CR@ zVe&Vwc^{npG4dPYgR`IM(&KZ@j{ZaDQ zd)E8ly#BUrqWk+N@xj^8kiXM&GCsoD?C;pBts=eW+m9M=t)<2nFyoYynQc{+2PcQeO%G;^F6 zGsk%@bDXy_$9X7ooL4f(c_MS1_i5hYM*gUugSsSHE(?1ODu1%R-*Ic=H^27>j{DBb zy&C3itpcXHBIT6C2j~0F74qK^9~|xO_L^^(IohpK&Y#2w=XM+9Xa3>y!O`wT21mQm zDSF%%h!4)~=Ey&|?%M@NyETKO-2&yzc-`lKbGv2o=ZFuEc9(j?=P*aRG3E4$56dds)V9PQ>P z=hxzcbGt?IpA{b*?XEiN+hvY+%an7p_~6`bmHY?92S>Zn+rC}qXtz!|`-ujdX^3*=uZJ~-Na$KYtUL^+$h>)QqAc4PAU#Ro^bPa7QV z)+lGC_k6qH+^#!akMqIegQMNp;Al5ZIiHIU&h6&O-{yT^Cpg+Y-{5GsNI4_ogLAtT z^1t(eZxaiw?H|Eh!4)~mdXFU_~2-F>c4%v%+YR4Is1qY&h6I8ze9X*v^(iPzFp>M*PWrq zc~|klx!o-JH;NCAc0V;Z+RanW5C7}y1m|{3YFzdT?2-} z+Mm9NuLqp--2&~G#0Tf`uP-hQ$~eC)J~-#cOK5++MSVTsqf~!o8SS4VJ~-zWJGK9s z_}~Lm_56ue(f%freLdiuUnl=O@xjla{Nma=e^h*M&d*KP{$`8$dca30Ki#GMi^K=# z^~-Id{eOuMei!9ex6%G)i~D-OIlr>4_RHdfchUBtzKiz%B|bRkSAVSi8B0h#!ZWlz zZ|tG{0rA24y*kw%?Z1b7;VH_m@1y-4+I&6WoFDJ2{cFSr=lt4%+Fu|(IOkVpX+OWD zuLqpRr*^3JZxGizaTz1=U0o`ze{{@{@zgI7usKDs;>w9 zfAWvh{=wo`h5t|fFSY*=@`e9T{z=+TP4o3sh4c6~PSgHz;)DNB{^{EPJMxA9PySij z&$P?<2>+k_e(j$mepNVskI9{{{g=cC=lmM^>n`Q%0q6OXzF6na79X7R8|2r;2j}{; zSLpmLI($9g$j5y#>-#nCN}Y3&!#;tCQTmHVVUp&WHUgTq(tAElt;PnT> zy!;o zedM38qR$7{e)8q>fwi#*{d73Y7EHmY@92f^g)_ zlbn*|>`dd+M>z{52OK#&eaqKVGjht5b4|ZC^ZnKRIOneOk4_v>JqKSjz}ZEfE# zaMW{Ni?_R8Bd4EoK9L-7KlygPPPu>$t zIg76Ab1FtojdG4?`N?}?Dd#!KX_M;!JkG;2^gP^RJwMLi8Cot4^3M_ZJX)wnJYdx`&sfo z6(5}a9`d`t@9PI=zeN7!;)An4Nd7zGgR@^Ff7A7SJ>cw*kw05}aQ4%i>+yV5d~o)= z$zOK^Uk^C@Me=_pJ~;aWY5Do>$4gRD5vu>*SA!56-^J>G51^hOY;l{WSR}i4V?x zj{Fhv!Pzg6|NTvUJ>cw@$Uk3vaP}+Yza>66`&II{-ptnn&VHTztHlRr-)*JG{~htc z*-w+d;pV;`aQ1WLpDsQ)`vvkJ6Ca%Y68Whud_CaoSID0wK6uvo53aY=$X|I&pAXKy z+ggw3^WuZEpC$i-oX-bmzd-)RTX`Rx{WAIZzA8BTRr2wDRdDtjo&}B9fmost1!oP66Uz>!5r5ynB%$x zb6jU&j_U@@aUFm;&g+@uJe_$_&fmcwY^@i`bt>Vw?~nOkCV#2zo9j`#17|-bA33!k z?{H&}>hG)WndC3*`>Mq|r=s-M-=h+L5tn@bRQRy`*S6N*sV;{H&4dq%4_+a^PX2h# zpLM(7Q8mod2G1M3VDPfRD+aF_yl(L50i%9{=M7#kc-i0;gVzjRH+b|Hqkeig!GCv59Pi_sJbEM>e&)Q0lXWXlO?SNcnxgZ$d0b{`=B3tl(4TT}ZO&pNg1d1rDTd2N*sziV5)eBrlU9rnwHpEmru z;ddE+cDryrdBZOmey`!z4Zmdgx$VRC3>bdd@MFWT8~$+6Pwqo?hn7pH>oR!3;Qa=V z4L)LU_rq{K8H48y-WTM_dBmcj^N8ek(iiCCoYC7Cew-7pqt_R#UsdAc-|G>MwH1Di zeDFGPtY6h5zpK_e_|dw$o;PHB0=}6%kByxC5A{4mPJVrzv+@ppI|e={dDNx(K~CEa z;T*TU&Vipc{08}`r`jFP=`wO^hMzb5{13zVV}@TlEbK=+8sl(8$dBB}#cTS3l>f!} z6pWn0k>Q-wB{~P=mOU}#C(jkk)OGrHllT1^+lPv=9(C;$%4v7G8KLzn<;wJ&)gH;b zYCcy9?(4?9O1S~@pAsKj`^o!_sm|^l{q+R!v>NB+eXZo*FFv^To4?DZ`@7Cef1U-N zQ~4ckV2O+n|0kFDq4Opz_v~&uAImWsqUD(6G|#8N)AFC;XaA~w@WODIS02?I^$Z#H zWS<^Q_?M{9@0%yNQ{%zueYroTV@1Xa;EAH&qBk;7E=bf&X{66u) z+3zR+1@XbzA0&U1ANhK~wV(Vr`O+Dw(Eq6<{=(L~G%ZIz9#dW6pL(8vyZ>sAc``;h z;Nkg`awD`{e%tET1n1>4OyjU|-j4$~kHg5adK~Ue{Lnaz_v>TbFYtKsQffTG8&kqO z|IIMZt`_FeI+~A*{D$FY3_ttRa6LK0FB*Q2;SU*pG3Y19A+%m&e4-sg{Y}ox3|=sJ zzro`mZ+C5bg~lg&J~qfxu1?#r_Feq`2;8q%*xx13CsVsWZ}}4(>o1mXnc97{ke(h}SgEtIby&&wDF3}wQjrK9>ydmuO7=CeX*zYAD?e^`f+XWBr zPm|~5gMP}5()>Io8PDc<2e=HUoX@6QgZ!t(2WNkb{O|4R^TD;BZ1-sXU)1s^xSs#X z_e5su?ZCU@gR|d7{x-Y$;{tn(EcGq)2s7~v8S~BYM)=~2+Zq369?#BiDg_LU} z|C_t}^$48(i2PrP53c=AH%R^cu;ov1ybs48RgHdC-_ki3NDlZ0)UJD5`*Xzy$M^2hukyRv2X`N6zWScNe(>4y zHD>tbG3|r9&ooDWi^l!62KmS-F3>rrhcPnU)@yW~z&-1F`=M6u*vd%|6F>$n8G;*R7Uq@B!#uZ@<~#mWwztBI^q#u7Tl*J_ z58gZ3uc*%mFCOmwVd1Dhy_3#ad@tWFc>kh42lF;%%&R!BbC6%&Rr48=55AHY$G0=_ zUfM^F+gEeclQ-(g?WcX@qz}*>IfF({{y^;`r*yF9$VnX>UN7p0g#BK_$MTZR?f8AP z*zj}3aDLYz;d-KDw2yw(PYCnuFEvMhdyM@0X<@(D@_(iM@p{e<^Ypo4o}aBb>KriI zEuW`-v|G3^%qy2_j{Js^U%M>qXM4lTC4YU`uab{;i$B*n;OSzBr(BAThku={kInO3 zaNqxl}SdURD5vuyU0I!AD<7-evbT?#Rq4j@O!P)O6e~p6A2WP)X{)ys)v)@PlW8#CeUm}0!{e3;) z?Dvy@ulV5Xm&srE0G|)e{s8#{;)AnaA%EI|J|A5Bovv*seI4eAmOsJMvO)LjY4Urr z_gPvp-1w9Pz=~A11&3V4n}p{wVp! zi4V?x+s=CYKNKIF{S5hgAL8o)XTO{Lr^N?nznA<~dVM}P`~Bn}EgXF&@J~;cs z8TrE5FQ20Q&yg>j{ivk< z6^`)B7o7d_Y1;1+ADsQ@SK8kL`NG*RpP~IdpYsxbVb|gF zzthK)mn44kIv)5;N%Q-$sjfo)Jn_MIBj4Sr^Q+>6!^eECoU8kbb_yzNPK8c(W zBd0_;$Zynio#5FQHAjBs0$nF~_`Xug4bpMK^T{|gkE_9bdpNF6_SdxC+vrHYodi$I zIQw>!`;{AJg!n(Dxsw*U+-sleexbj0gEtKB#=<#~!P5rM8a!w4yuk|wFB-gL@Up=x z29FJ1HF(Y7b%Qqy?mjcd-{5J3XAPb+c;4UzgBJ~6GI-hG6@$kHuNu5&@Vdbp26vwu z<8Sb^!LtU>89ZgI5h+Gk9@9cs%o8g?ZXVYP*N+m|G;wYm0_? zX|XWRE)nKAgXaxiFnH16C4-j@UNLxV@T$RU2Co~uVQ|+L9=FKgX@h4Co-=sf;01#h z4PG*M+29p}#|Ez&yk_va!5ap5OB&;E@U+3R2G1EhZ}5V_iv}+lyln7_!DEA04PG;N z-QW#_yD7%_8$50BvcaRN;rx=p8wM{-3+L1fo@)>LvBA?zh5fR@qmHm&GPsMve%9ax zgO?3nHF(3|>7~Q<>x!J}ou?dA+#G6cU>jsa$5pFkU@S?#h2Co_1Ef;P#Yw&`>%LcC+ykYS4^5J^&1}_;rHhA6O zQ7YVS&frCZR}5Ywj^}&9@q90iKkMX!*H#MGS^ZX+*VAF1UNy`MtA}}MjWCba4)b_= zm>08Q-q;|_>s?{)HVyO2W?`P&D$I*N2=m6aVP5MF^U}^?UfdY|&H+X)w_V1E$249KC`8@4ooTKx@ zJT`d#g0SB(c)1+*vloVW&EUn0!hZCdFpmwMzc}nS3|_t@>}M|x^P0hnmxcXkAk1Tf z=PwWY4TG1j2>aP9!@Oqj;#FZkx;o5bgXgaa`wfGauMPXzN|@ISUc4^sN7sjWZ1DUI zVZUMU@|>`ry)n#d1~1MH`_WBd9veJA81@?mFW(&Yv$uqK&EUm(VZU^1n3r!0^UCdE z9^Vn>)i}&+zYX*H@4~!sXPCRY!#uht%+vRVd3GqwbH5Ms{2#)+a9@}g?+^3RAH%%- zr!cSlIn3i~nAaW%^TuDoJbEb1vwscq{KH{hd?d`v!(kr(EzE0w5A(*OVIDmm=GiC0 zJpW{v7i(c&ek#o4r^CGVOqe&G4fE*vFweda=Eax8Jboq28?T0W{yoicU$r_p{QP`+QONM#W5$0~?FfVNs=Gnu- zJlz-OrBlK@H#f}Ptp>j%%;TXjuRb2;(KBHlKNseOm%}{wdYEVDhj}y_=H*GtsO663 zSY0&C3vFQ@PYd(vQej>r>K@Emc>=TT!m=gG%7M4d*v#F1}(Pb6#j(Qm@* zS7q67yNy(sXIBpMYC6obtA=@H^)QbzVP0A*%-ypC&+tpn zY9IY7jcJZLhpz~?TmD@8$Z=n5zTVILbvAH(?-G7vF?sQx?DfFYOK6UItoJt5r-l6n z)$enX@1fK4Y@VlFm7a@(KWO;FhCgihHNzh@{1L-%%j@TsQGea=GloBE_}zxzF#KM_ zA2a-Z!*{pp@7Iryzu~tT{;=UkhCgcfDZ_8uB|QFV!_OFg#_+ohKWq5ChTmoQ{f3`2 z{6WL-HvD13&l~=z;rAGR+mFNJUoiZP;rAMTx8WBJzt`~l48Py-ONKva`2B`IZ1`ov zA2s{|!*AO)JpL8K&lvuo;ddK;Z1}x~KV-OLBk(5{9(hd8UCo@j~IU2ZsGB- z8-B*{M-9K*@EeBTYxrY^-*5QtHe>s5_-%$iZ1|Dkj~ad|=qK-keN-P8VLvq#d|yrS zo*Ba*HvFRDj~ITx;g1@A#qh@rzi#-^wV`>~?lO;s$0uX>y@sDN{Mhh&41d({i-wAQ#bsA;g1>qpy5Z?hv!4X z@H2+r^<23AoZ*)YzsK;04Zmpk(evSY`VGHe_!Yw+GW;RKcQ1tNsTqFW@J9{5V)*Wc z@bVos{FLEmN5b`I4Zmpk-G)D8_yxlsGyFco?|Ly@f7$T+41dt@hYY`J_+y4YV)$Jz zh3jt^exKpD%?ZzkA;V7_zI!=bPnY563_ox9Rm1N!{M;+ydP;^L8~%Xdr(O-`$A(`r z{9(f%HT=5a=U)rgGiLZz!;fwZ&xg!E!uc7)FB^W&@W%|l$M6gFa6LuCA2s}b!!NuZ z&aW8$h~W< z!G{e#X7J3O;d*)u-f!?BgO3_K_0w>>-3IS7_@Kc@4Boa^xZN&;_Zob_;KK$VGk9k2 za6LT+?>G36!AA|A+9%v@x54`iK4|a}gSYJ)Znw+ey#^mJ_^`pp44&C9Tu+a|`wbo& ze8k|c5N)NoZdCum00>SKQBHw`vc@}{d1oW&VGgb8^i}^e~|q5#0O_TCV$tWuLqp{A@c7KADsOv z`I{f*^TF94CjZakgR@^Ff32f^J~;a$@u0 z;q0f$zgv88_H*P%C-{7D_6y_}#0O`;ME>34gKNLT#a$Wqe?P07xbXMux+wgdy!kyT z^8NZZ)m4|)IqM|tHs7ZK-Yvfi2|rq1`}4#H-<$m6O4?uZmp&i7kNn2BwSSZN;N4UG zD50L*I@(|VB%cpHN`7_|?N`MIU%>vh+TZD9pPv>6+ntyA&Gi%<;|ae={)gg&vtJ^AgVTIIIQwPt zPY@rR{R;Vi79X7bnEVCegR@^Hf5z#)esK0{!P#$+|ET!j?7N%v{C8)`{1?uCM1Gg};OwW#KT3RX_Os;2;)AoFBflX& zIQx0>*G_)$uJ!u}!r3p7e~9?t>=((uUVL!&OXR;MJ~;bj@>e|D*ALEqh5S9l2WLMf z{}S=R*{_oStoY#U*U0ZU$JYxw}=nEnfNam9Q`UhtaGMZzMJYU(@=Iki`H&N-3; zUX!1lhF^J4``@_Ow+p@j&F4D#yND0InfT~$_kQ6z)9>qcFOnSa_vrV3qlWh179adp zYPb4HxZNt{YSb?{c-+vnCB-g8=ODcMZ>&4S##81`xHI$acH-(g!ca^^@9(4ar}36qp@&KHPShs zNDg=pjYE2Q?eBA$AAfLZcKr8_v*bT4J~;b1^3mV?in?8l&ydlt>`L07KH%#FuhRT) zd`tU>ix19qx>dA)hxp(p$&%(>y zP1iX)OAh!3G(Nd?wSPX^6^`F8L%#~-KQ2D_N<2Q~FMWmYS4sG?bR1P#PuGKSD;fQ* zX0?B;D`IM0VN`TrIle45lhUgzg}xp>~`ayPH7wj1yV48O`=)Ogd!|g3U`CU2Tcx&Q|E#B_> zrQM8-9&&mpXYy74`Ym{u`0KZLyNe}fI^~op=K#q8N6y8PQj!5)Oa7hWgQwN_Ow236Gv($4v^4bN(ppBd30h=ExZ|a-v^^{hmd1yU3{-Jbb@0 zc`lLG$Jbly%LMmzWBu)PWm>;>zuvE3;JkiCmuJ*GysotH^{f8OH(_2`l7UsDrVP2SO z@M&RQYS$cfmW<_C?$G{mvK+ymo#KZHIaMR4xT4N^KytuwxdG!)URV3buNnF2Y}l{o z!}GJSiT2TM{DUyhZX4$L?KDT7(T~IJx^C@Hnd8?B@afC@@kBk@{j`6$_~4QFXt&R3 zH+P)Qc}#M^`zGt<81EXczj~t1L7k0L!rYx2=EYK&m(J51{i;$uo_D&g+x7Vi{JP=i z4Zm$S-CyMQ8h*Fomx6w$OCK4kGdUkOc+ubkL7tpv1?y>drQr1h>-s~=_0e&~DmVJ` z0&u^)aa@sdCGyV@ADsPu@<+u7*M9Q+81;A8x&F8XoX@Wt~Rq??&zeN7(gT5Yc&X37IO?+_n>*W7Kd~oe|xURvBjF|tk z`OV?uK&*Gx{;sqquBiAN_}1}Hd9SdaJxH&oe!fg~(LQ0nPCnX=FVyEF;Nj!&lKA^i_*jnJ z2Z!g0>(e<^$pP2b-`d@vkyAZE=X@wR;AhBvI@B{{M%9%jADMxzF5OU%=4{az>1tm~!A}dc(^rdkK<#f8h@qe)aOO-*c#ue`VOu9j1NX zZgPG5cD-FfJq5!b3;M}^^NvtXr|S#y zpSR%b_mKaA_~6=4uAk66KlC=gUj|Rhtj0LU zi62^zuzZKN)Z^^?m+UWMJ%7NfcWI8C-XnAlc*D5PT%d9OxYe(e1LtvW&^T;!haU%U z9*0s*kHdM19~uYrt8tI+*WAQ!UAGZ_k~9Fn_=5JAj=c|l#&`Vq!*`!+{}l1TXNr$; zi)lQOlV52CA1wd-uH=CC(0O;}NWEN;6Mt9dtomDDKX@e1+n}DRkyG73=fEE@{Mzne zKl+)j6FJs(&R&{7dnNTZkGsHqKe0bbxgz<05FecVKJu6PozDknzeN63;)Ao_PyX~f zeLgt*W%BPAADsOG@@L-V^TFA#kUv*^aP24C`J?rAe$w5|{0T0r%lP?Jmi(WJ56*s` z{6X=-*)Nixy~o!B&VHHvKZp;`eoX#0_xgNr_G{!nAwD?!4f4M;H!IF>u=A2Pzk^d*RpGU-^%|zvFyyy<7_CY9HtC z;C%jGBp>5eCXVHsJ=R!{X6ts5<1W`6ISnJnT@m(EzX-SMt_u5IhF`ok?B@+XU(r7L zmAg)J^sCp%DI0zt`N)ZO3t!iYj??4d{gfM|^CI4{o!P(D~e~b9w+V60^FK47h|L2Ru5AA<3 z{%tSnarXU7o--L;QRU$J12|eiPPdWc-qtzDFMX)_l7IH=JNRt*nLy;nMt-!&H&vbR z3oq+_frr00ZC_s+UO`_+%_Vg<=Nq{1&%}JIk$2^_1W!EsT?H%T&eZsu5ZsS7>uwOC!(wAX>*zn7f@C3f!4xpY9!_O@d_S3H!^)DIrGlpN78uoLB@1}+Qn0)lB z{106xcrD0NZiKemzin+-C%E2jr(B)HNP8A;6cU>jsau)9tSCcbT`sr_(s+$S;Tw&VG^no5Tlaze4_p z;)AnaBY&euef{93;1m^|-GSd?xj) zc!Bm05Ffli<5s&^`}c|ueiHflE3`lD311I*MEj${)!N@*eDFRR=lZqUzejxV4CO~R zXn*RHz8>&4+2M_k=S|u#h@Tcdo9c;g*8bh%gTF`DMJw~PKc(jD0Z&u?)!VhdpZMdP z>aYGz`**_G9wD6d#=Z zD*3xU@9P2IY;nEacF*bl-XK1Bme%X+i1z<0J~-EtBmajl_OS?0Z-9(viy?n?{(sX&!q9GzpDLD#Rs2G`B7c_JH6=Z0Y8b(t#*E8DxKz#6R$j`2){oE_Q9`N1BFH4;m zRE%eJQ=J1|+9AyAJz-v!@!|aJ31Po>T9~_Y!n|^En3t~#^TwPoFWwsF^*h77a9^00 z?ho_IAH%%*r!cSoIn3PyVV?d=nCBi0^TI=6Uixd8R~`=Y>LX!Z9}aW(_b^XC8s@pj z!o2W!n3tXi^U9N9Uaf_B{i!f_&xCpQ*)T6W7v|;X!@T-Jm^VhkJpEFb=U)!<(ko#e zzZ&NC*TOuihk5SxFfYCl=9M?Yyf#0~-M_*-`&O72M#H@Pc9>V+3G>FgVV?g)b6h8H z&~@_h?dR9pzeu*vCE>Tyelxr1x3KAK{oUbJ*`5n$zrMKk|0_N?`{gOxzv?yFe+g$l zx0Lp`{)hL$*>5bZ{kr(z>{q^_{gdiGADsRC3fiCcy7$4^cPnfED)GVDkJH*;^9`R5 z&VFGv?cX6jIQvmX``vH)d~o)wYis{?@xj?IuBZJI=lgtc_S5TYKl-Ql!P&2Er2VVJ z2Op*5%<3lEpYkuC56*tPnf6Z*ADsQlmf9Z`ADsR2*4p3vEng2fe5}`n`ghg(IKEzQ zt8?Jj_6YmA!@_=J$u+|HM}>X&dN@BmM*FCEKcx6wFwp1dFI_xipb{Iucs7=G38i-w<^A@y&4lkl~LR ze$DVp^TYY0hCgQb?hoPdFa9%}pECSW!_OLi&%eU?-G)D6_yxo7c`KaXXZRzAUpD-n z(Qy8t;nxhmYWUf=!}%kIUpD-P;WrGw?Y{7Q=z1qyPulSN48P0p2Mj-N_(O)@YxpCE zUo!kL!ygFx$@hrqc>`=u`V3w%_^`nn22cGew7in-s=<2=UN-oU!RrQZJ0o0A*5Ew` zFByE$;5CDf89e>#aGl)-FB*Kn;8lZ<8az5PTu)b!x4YE4q4lxd)eT;LFXX3OgPz;D zAUVEjKK}{sk4q+={~RNKRD5vu-HQ78(oIHvJ~;brp06h_Ib6>e*;wdzte$dXdL>hKiH4w$^TS*aLzB2zgolh7o7bX`9BsPJnhRFe_t!sQ^DgL>m75fN6fKa zFvmRCyu)=bsh^X)C#iE`&)a7{(EFXXR$%gem{^}Dg4cf^=Fxqc`{mN^1}Gmq{QYI? z{YxoVpzZ3zt?{4WzP^e5U@!Sg|GT+-lkY(b*M9O`D=pu{TmA%3%RpnkMQ7{z8H*3D z{p5G?*4N8r@_!b-T-=A@TV>zau(HzUAY_ywuDeN~4zwlYucMaVy zwA&Np$@kNFIVR)QT#n$p9J91s&Tsk2_nw6Fa%s?VS?s?HUoHiz6XRL>LiZOuz2Yh| zbNnCl*Lv?$Gk)E z#1Cy(F`oIX9#1@H2+q$L7RaCSv0uL6bzZ*z2`}H=_jJ2mk^_$Ky<$10{u|CId|&76 zih6|i%6%5(6pWnOhB~KDa=?pneH%Hkk(2AvIq=;_;rgSk!+vD=g>A!r+VJz;VSm8z zD}}Hh8-C+R?PFeLPY!c;s^%D>JxjD5%YN#&d*Erc-AK+y$UjzmaQ18D|3Q3k_8a6+8uRslvmc$KkE8Y# zA6)y%@oksh4qun}3)>EtFVOSt?!<5HH-$Io`Qg$f+F$WA?}NW552E?yFx3^W(0;%8 z;LlQizM}mP#Rs2E`Gq;!|H z--r)hqI#-9XjVR@xiCJs(0hh$L7di`)l7W z_~6q1A0WSx*7=u-4_=Vhe8bOgr2WN`wXV4yfe*@R3Evg8e~kFxX}NF%Ki#MOSHuUO zEdvKXo~`}vNxmNN_v8Qz`-{Q7S9AaOgPh9cI_FNw0k6vU7m(9K`yJ#IuG2a2-I(4_ z!B5ZCKDfI@^JNzC{Q}R(d_#V(k)NHXb7n{m_y%(PhIWg$YajU|Mt5xD&&3DV z{zRS9?D%!RD$Vn!TRF+~eBnh^XY$^RoIcK3e96hd;~cDC*#&w%^5Z?#6`n+ez5%>9 z103TFzeIj2X}7tZ2fs_|grBSFeDH$7iv}+lJT`d4;Mu2)dJJANc-i2w!K((Z8N6X| z_jI`a$lz6jN6&|5`JbM=rPxic2% z^$7LEZ)zXBK0nOke};MCUtu1|sB1isB z;)Ao_P5vk1gR`F}f6FPp9&q-1$iGT_aP4=xA=-bv)AA=cM%#~DryC)EiVZ>jBq(ha25dukQyW{=%*gHuK zC(ZK<;t6q<;O8kYbNA6O+TyVbwTu#Tw zkB56FhnH_eIarSIVqw2+Y({F_+Ho_ARjs5 zd6=9p9H6gDct5!>M)T+6*7BO*Jb#90`R?1{moGRk-?qK<@_iujL(3QSk5RvT`^ojs z5A`_U`~sZMFUsU2CvNB*v}+wN)&Cv#d)vaxtGw=a-2eR`f5`CDTZR3+_5FgK!v2Wi zmv;&KnJKz{UuW{XD4j2ZkI-^QzjDEx%EiKl$B@ z_@NYs{n*IQ-W&E^XSklqpTmCI@T14IKP#Ch&HV`YY+3La|H_Nn$9Ptk3)fR6A34?e z;hf&(!#Q=!Pif!RlN>)7+l?HpN2tFX%t`iBi-xxw(F&nq{=( z0;|b=-s#JEf8=JrzR2sc+;%PA>H7Ef%O&e$+{FoR_N%^>f8jLxb-VDw5q`t7lC(P_ zJbupqpv|D<{8za9*xx7{6n}-~eLmg~kQRPo!kgE<@%Pf8qzNu2OgL3W={Ghp9B82`0g{kd`m0(@rO6 z&rxivbGAx&Yd$aMXIhv1-cUh!J>|zId2F@yiIGF&Fn#4_yUFi)ZR=;Il<#J?c=ElH zSA9LRr2e~vm!9){8{rEQ-l|7_FMgV|d-%6J&p$A=Wn!NHJ>kve($(Yph55P6Dw1=b zH>b(`IXdA@e>AVh;R*5Ull_RH-7V98JV#&fb#5hfp3&mTyt>}!U_R6m-mD+*k;Z-Y zPsOj(a@^+IzMk#_eGcaH^9gU}UvgQ&F7>yU8-eHmv(y--t==<>Tx(-c;!aTzmlBd z0>8ezA~`cx_xWxY-(SqX=^d_WiEUDG&R8Ei3u+gf~)t9J+inZrwF} z{bMwLj!SrR{3{Ro6{1_lZCH5jY#$&o?rq_vEBuzzx1PNIH{)|^dw8=d^-LFDd_>pz zOW_6DU(8QG8qZQX``YG2Y>#1Mso!c(qO}|`C z{!Q{h{TBU>pr{EDxzOUCmP;rQPA99b|2PWR)}w!5!0C++?+;jR3l7e#lM z3wP`Kc`{3u`o1J!$FJxe0H!+t|P- zV88q@_y>M_^^h$0DI5Bnep>FkCA^uFr*^_-FLW}W!GjM=gs zo+o}q>e)j4_rCAEo2Hw-Vm0v)<(^Syr}V-`U)^TcqQk z>l5A@w~hSq2G*m0iI4Y7U>pitct8HcZy83Uo?j)rx!iMa`a1iBf8FBA_d4k~_V_KO zU7F|r6kdNyFPAS9-kMi$`u&}o>>Ehunmpw)bUd7E@#Hxld4B@xkAWe%pc(& zwEX10@U=SsJKOqpd+5CNXD#0DO8b4cm5Xmbm4(-y^zCjV^^XY8zvlU2!nfPb*I%Ub z$2)`k;Zmj3|ZNkfRzB8@c`;|xaJX}|JT72v`Pfd7p z9`@2aoFjf-_OpIeo%?&sPtG^z>hav+hrWKiR|oUzpcYTApHu#?6W*LZX_`Na@8CJ! z^M>P!(-PiX?s#7cw*QlM^zHW0@yU(}Z|29(`Uied|2e`7&+74+E4)U>V;>67Ne;$s z#pJ-LnUCw_$p1mYo68aJ+rcS)>nYFil~lz4z3~4>-TA;tJ#YX2gRm&ZzboXL6hfHU-D)FDf3`NQ8f|3} zGu!UgF5B+d-Ln1Y^q2|CV(yc;Xeie+t1{o?yNZaXXW^ zs&8D3zg@<#e*c-gF8Ce$NF#_V`IyM(uRz|4+sj=A`E|G0<842`(nH=Y;LMPN`kt;i z?GKB*_c?LppSb9c#m6&u|C9Y=_5p4Kj}GO0crNnEF=M%17Ovp_?nAj3g9ndcPR8la z-Qe9H;QVji^7k@vWsm=HUPnxX{HPMvpM&)dofzrQB+a{9u?Ot)|7FB=9J*Mt8G5>n zW1e`P{dpJkoJ3spqu^k>o##T{y%XDG;`Tc5NHKFWU+Ov@`U~uN=>+0>Tod#51(1)% z*w1F&ZB1Z3ArJGWE^O#vaNoBKmc#y9@c3jN$IX1{V(^w*?Qy=4xXv5jaeW)1$8!Sw z_96RcKKOX>_#^gsxE|cRN7M~J?^_B#?7{M8oVu2{E*I~Qx&ZojKau6l_qBPrdsrih ztA61V5I$w$Tz)g_1 zp0NAjCvZ9L*PqOKmYm9VdQk3@#8rHT#C&Pri7Y?&WV`$n;z~ZUEthNhbpkxNGYIm@ z7N;mZ-7NDSuo{$mhURqd>m3t?*+}}FLtN5`Ort`Es z?N8px^)>pR2ak*X^*`u|R&YQW`}e72{b8(+JY1|b0NmP}+c${y(FEeEzD=Usn;;+W z%9<;n=MybY>&*}C>w+yOvmTeQb2NBU#9puKi7P*}h<)9zQ&^8xX>a!#;65>4uhE?L z^%y_Q1doaJ$O7WZp1A10`&YxCM{s*BLR^gjm;2QTaQ__k+g#Xl z&}pnE@;vL||6A5*;;Mgz(Z5XI2tnR;2r)^`xe*X>wde{C_UY*@MGNW>kvN!i7R>Yo?+9!UI+I* z$MF`29}b+#^5%Y#ksk^kzus$9l~7axMbTC9dRSAF}+};8Dnj#ks0C#CohrzKj`^Zb6Q`EezflyEbkNTcmr|OF404~X$@RE+BS!L5a*$0p7x98yIPT; zz28;VEB$n?B>MG@#FhS#SO<9F<&#l)3Ai^O^%3VFZSha7d5lJ92CU&Z>b zL%E+3SNi4t_JL=!eCdz&d_I!6l5ZC6`?8j&b)wi$KKdM%kBI&40C=;=t1G~LmvSPh zL4MooT=?N_`}+47;;J2^r`zLmlIGp4DApakJ8fC#K~H!pXH=vAIiu%xd%N#)9_ud> z{i}kw@`I;0&l6T6K|ieJX+QZ;_A?o$KW~AT{?G2uwa}AzljAmm_8oCPmuub=YvS-( z@O6{y^*#OqwnvWp4d8LHUVa%o6z26{S561k&SB^g?Ryn??C+eHy2H*_i7Wp%i*a)m zxJ#TDdoE=C^8Uah;O2Wzx?>zkfJa4~oOqEcm;Bt_?&l`rs$If0?9U)~8*Ar_A-|tp z-b-A`M?`%e0&fxH#o;rQp6*t6G4CBiT(z8{mdS=PJYez6Zwaw+Q%ML2)XMSEQaF7KJFHu7SBsn2E5vkRAK#-qo;U8ho= z>0{=N%fQX|ceqjC;WIf-f+A18uX#7C2 zrC3%4cue%ikHB3bPJ&mnp5_NxgNgr#!4r?#`8Lfg?|RQZ?(YX4>BZ+eX1}fq+#lmO zG@08J-FY#U=TMzfAALJ zpNEO7e6{d>&Obi1*N;YzkPltQ`u%(J__7@1%k#vQo#82*|J~5D+Z>kniFmu0xRS3D z=Mnq=gY790_EZzs`4iud}y39B+M)Z@b^f+!FKrYr&iE=xGLLyk=)WA?_xRpg zvsov;0B*k5#*B}}w{U$eF;Bi5yi}~~yWPt2A;GWHoc4j==6ad^r7wvq`#nGLys-fD zial;)-f|Jg+Y;~r;Nb(=&ohuWt^oHfwdd`7!98Mq+Cp5lV}aP`KRUv^wAda$Cu&aZ z_?5jK&xL$c^p_`zt9nJnKJ7ubEB)Q9&}#OBIaj)mxRMXMe&vop#xrnQ=#Fc#fAeN`U=ud;@ly619y9(UAZ`}0v z@1Z{yW&LIxIqoj@=jxl-pZu?uRjoN$C+=5IC$8$1xPjxdH|)6)dd&OhO}URlK7L#m zZTD`7hmRp26?t{|-E2>3fbH?X53|ANiv7d4h%0-{_n{m6e*!n(U*?9Lv+iN}=6|w1 z{C~@Okhu2qA$C8%p*hWe#J==i_p+Yw>-Ko=4=&GP{{bG{pDi@=|2VjRDO)llhbz3@ zeAe$-#rLk4!*54}w_rbiDe~lO;>!LO>_6-VzujT>axwK7pQQ=rQs6 z8+gt*J_kP%`Ul>}?KNNQtN(+z?l1dep8<9*GhB?b<@dw?z3u+LMDtxO^L-p<9hdU} z>yLKf@!iMW(h3k)d1LNWdw#eD+`RYR#OHI+4}xUfXj7@ z`Qa_ZRk^E==W^ZfPuB-ozGW8cuK+)uxE`ne#qy?Jk7(ZAN{De}_lHKjbrLl%s;Gxhq>HlF+RRVT({S|9MAJ%=U3q2e(YyA`q6<=)>A6>uY#J>duzo! z=N-){udZN!4uk%E9#ML_SxtyH&X$%nfVi^9U(I>OoQIyO<>~nXah|&Z^5*-A24Otf z_fgj46Zb}L0B`w-+hrnG&-xua+?(Sz0Xq+VjO)8l+{YWLIo+2K^<79@*&h+*4t<>K z>k;)mMRU4WCeHDjh-*KLdEY&ppJO#YiOnQp#af!J7K=bZasW>0c{};=f?}0M;;T7;E(SJ{P zn(g=9%o|a2VE+rml^>eKe7pN1mX9Bfc0s*{fH$9LZ?B2qEqOdYH}{;MCa(Q+8jlO+ zErlOL-hT$it-0^f^BJ~hzBm`FB(B;qc91fHeGS{~^^3odO%FpvfJJwKtR{Hyhb< zt9D%X3H!n5c}2^2wcHkugHUh1uI1@|o!C#?dl~z|eBYCq-yQ|tBF-1C2cJ2H+r^Cn z{vfXW7OG(TqiEmJarhJ8i+wKQ>K)?R|6(4v`T%LdZNnGhM-;-$K zJk@5cm=?pZ^4ULW|fx zW*yycIqMILb-}IRa{u-_;;P*XKHzru!T;WO*dFseYo;BaC$8Eh9^rB$kl*oL<{nY* z+2H1TvE7K<>xrxSE-A6M`*!a!FA(?2iosXF&mNRJM{^o4(0|Q7$!^rp%Fduz-^~Y? z&ndhB9v1n>_deURLX1-}@R_2&e*kWt_cwmCK45!V#B)8pz{5MSKh3 zDjvdXcpaCIIE;Y%2DAS?$TR;1_g8X)T!;Lb_X+!XwKzYjA+Gd$X0jfWKOceoiXx74 z6AwEjSdU+vPn}6z>4`nde&_-JEYk9H?*9h+VYKOYpK^WIy>IWoV~Hz0&DifX<(>}i z67$0dcu34Q_WX?X1Q&C@GJ5KWt9UD@u-9uH_)M%%P5#{VbJk<^=XH$-{=bO0YTqVd z|I3P#C1Ea>7qT{ zgn0N3Jm})~HRq@2eaZ6je)1gR%0KI{pK1K?5adJReD-_D`-j`};Wl5fewWCrb>Q;6 zdkwhU$L_ZpdhX*52CfC&Pb04EY$>#tI|cG_F%P^5@_od<=n}|Vlh|*45w|~sw}|^5 zdw`+6K3oSrg}91`)wp+U?7tB5 zF63=)Wy`u1JoLFeZ$Am1p!tRRtc3p0wSMXiV*WhjKPXqs2c96V`|roR|6|^>aX<_6 z@V%^mE*EcAfV;%`#f{*>Wh@whJ&%HiZs(dB{uQ|Y|2SX8kvIDNm&SAxF$tFVLLw zxoG!~iR*kT^5J$ru^(DaWIy<{H!SNo;!56E$$pC<&s+xXDdv9E9rKe{!GmXW`^I4B zUO%&*mIT+gncZahiK})D*4f*!9y}!GdzWiY^OKL*&I;K1BjnBZQ=9x>@(b51f&O?b zEEtdpq{CwkA&dKLa>p;4{L zf0};!7UX?my!#qFDCWtNx^TJj`NZ?U<2Q4;bI~r3f(OO;e$>`%k4MbMPSl*9(-C># z3CM@V`SpI=us!Y=H;5UJ&IJ$e%k5&u({I783pk(Gz@NcwSx-bf|9CFAyubYuag`tZ z?{R)G>y!~W%u9D=ZgKNiRm4^MhWF+ZUN_3U9P+V`S-t{(`w{YP%wtWxx^BmMLPOcl zVUuUTEiqsE9z5E>Pg3{BK2pE!+0H}>pCj=9Eh|7=+36Ac9&^B>3wi&!D^F9b-@zjy z|4iS3+c!RmaXwoG9y*ZcQ7h2CE3_VpXVKq} z+llq~&He-0eF}IK&&8N==Q$(41Lvzjm8@FHRVtHiba;vUYRos}NC zC*$EbH1n}jHK+T-qCdVzTrh_b^+i0_g8T2}IElcY{{#=tW^Ve|@8DrtkE+iK$RD&D`yuoN_lO4Y z2>8Npn49+!EGDk%72TQj8^0Cq4nK%{8gn(L_koMJeU7-&6BGMppBX)3y%78x%g3MR za!r4E4&16_e+J>tllS0ymG01+YXp8Sxb-&klTqIfHK+BmnCF*t=W<*AZ7=sKaQ}z) z@%=6E@F4CNCht}5iTa9tv(Jd@@mI{NkKBvx560QfVX*UJ;>vHHeYn2ndF20qH;a5& zx;NyzcjUPEx8rml9WYy2X2AZU=9< zi#zmM$bSqTTy6K~h5K;1>%_j(3&fRv^L}8HSJyz^b+@)(uv>^u|8c49ux1E*rFHfX%_RAE5JQ>v;GL|c^}+AzKbSi zKh4#f>suu5M;!s~E3=O~cW6%UV-#`zjggA9^tBNj$!T_SiU#n-Oq%ujV^&*NgUY3lD)G9^^c; z7XF`2T-h^UoSSUlm*qnXxLzTQQ`Znz@{yvkGMSdh4?2gSXq8N^k&zItvKlegaim*@C?FYEV- z`#(#-XNveQ%4PkoS**VT?RzD7RP3|83m)5w<6#aeyj>pq%{PMUYt{uP6Ib?IcwZvK ztqZ{;;ymSL=n0GG0Y3!~z0gZrxDIi(bw2BlRd60Q{yY#o665$cd>U~T4+SDW`~<#2 z%-;s~WBpOl-~R<}J{Q>$Nr3wU&j8qf{VBIDPTRmPq|*Jv0gY6 zyydHHbd8KXcMw5Cz)9-?Ocsa+L)teQ4 z1@6H6Vzg-L-7vuGgN3x%NE4jdG*nf`Z^whPu5AZ0sPpqd3 z2EiUN-+Kz&HG$(ci1Dk-QS65tu@5r|yh!B#H;L=KgzqUZ?_F#G_lt5bJeu{d7VrI7 z3qD_*zYjWw^~a9n0C^mF@>_6sFZO3X;^Y7y^o#dehly)DFW~x`_Ih2*Q@&l!elCKa z_Z-af(ZU{@n7A55T=lPopR>Hls|z)!`zkZ+d47)}tS9)qJr7I=kDtr;bBd8q9w4ss z|J(LFvkdZ~d0gKJ?Cdg>^@l&;0d_w4zTooQd?0wDk@YmOJFKgStN3?|dCmu#lYbIi z-;1C>IE?M|;hYQG64qIo(|lgcla~-z{*Ua=<(l={m_pW*vp?6@`2S|&Nw8v?maO5lWnHZKcGmnAFa&yLX+3mL=1sPL0{G|9Blj!*(DIZA#Qf*1 zk!+7g?BCu*T-hVvd-*VUi+JD2@6fa4B6~bveJtx=DAqMQjAH%G4{@F}`+MWS<1vnZ zZhgzT6WsMA6SH3UlDP8cT(RFcx>#{K$A8-1FU}^e>gAu$dLr=KD_Wk$S)pf#<6vhO zUcbzM{9NLy+$ym?TB$kRdl&1qBS*6ydG5b}xYE-so_FXwMseDI7W?OCX-@0b1G(Kv zNPlkDoX&}ap1=E9|6CDo{fR3-SX;6m%z5Gr$afdxLf7M2-i3QX74XCH#J8~i`)6no zw>z+PlIAqdiu0*@qeq@i?W~7Zy!!JMk0jx6SD{Q*AZ9k z8yD{lYXC$3wyAig-JNxT}#!se4mNzPh-zW8o!l%^E|e{l+%sX zL|oN3_%6rQ@v#4OBai3h&G_}V6WGocaej0maiu>f-rIZ|cym7QFPZ+nQz^?^H*tGa z!Jb3G<+;y%;<~?xc~^_(^qk`_+~3VSbC(lYzr3$<4tTIX=O1%#{{!Mm{|fQmk9FW4 zFg|i{Z<;Kbm#)$Kaua0NWE4=X95YyGGdSdk=VAF+ z`Xgc;dKPirzeaPrnDxag;Gy|EkMbeUY*ohcEnbED_BU#Ys@z6R}#Yxr4_B?Ygapkv|n9u(T9xq@$eK{Ri-b&W9LhL705?6X6*K&R^ z_o-$;-h986887aKyj9Efb)mj1z}@&phLz|?2TW%D@_E>Q8U7l#Zv^f27I9VInPUIB z*A&*{>1EF+7ZF$T39)|vO>^o;Uva)Y7y8exV)=rn*`KCf^E9XXmSVqg75GBrZ8J`J zs@Wd*5}rsd!UISXz!Tzr{>?^SoHy-w8tXCNlUu~iU=0F~JY<4pS^f%(l z50*IR+WB<7+rmUWQk%T{ zd{nGQPN;>Qi`hVv{~rYp_2ltlEgn369lZH(EN^B(zB<+u46*!7#QDYGp$ofcJI(pa zBg9p^c*H)^Pny#_vj;4Pp4~&NKP>j)$Abs++0Sms&mpekA9>ZIOSh~j2DJI0P`R(?^i5`{Cu%rkyp?9<@0N$;2sfI?-N($M#c9* z^l4C>=21u4{Z>R=#fe|E`#-^BZhPMNTO;eADfT^P5m$QTed%Yx<^7O%pr?=6hZ#1F z^;n`EtHFIZAK_@Rtjmb2`ntvW$OGWfUiNk9eA|few1&8f z^X_=g&WuwtHSccC#rHp=TGpM=<9eOj*W|aK!6TwyRGiD@x@x%G8L;Pa@Pv3@%H81d zTxrYm*l#hB--d(F7wfOZ;K3q$yYF;9>+y+wsDou3fV9w8G-Fg?e zM~owfTnKr}AL?V)9VZf3?cUOj*I7JEx2&_l+m}mtLG3&LghlN8C4i4m>3G6^CES^3CG8<{QD~x$r)hvAj#13*QPJ zy^7;%F52ZQaNo(iPlB%nvQC@He(Nso$-D|46Z=kmX0g0m%wta{uId|^&HE%~e)5pv z;$Git;PQS*-fZY8;r?RY4?l&t^0QB@U!K*R<_VSde%=3a)?*#S?X{o_JK`VUkyGvS z*zQ*-{px*6ypFp7e!E$7ny-rIJ(m$z^^KLWo_uWMj=hrgRQ=n&KRI1_9J-nn|Ar5n_=fWY)=u&olRWT%a4h94EggzaF@7Ga?&*{AG(M2N1*3U z;;LOjVm;OCTE%I9RqPKOLtK>`eunj!_3|~4uM+#Ean0$x0O!SKe{BEjV2|iu_Yha* z&Xn^a$cM%Gb(cA;CwM2v$rYGCR1jBsmI!+;1#fzopY#f z(jOJ$-P4e77T;^L61?Sp9!FZxURzwxdiv0Gy0MH230Q2qyBD>^J9psa$7`xju|f6>!`V`CyMja3i$JG;#!Y*pXy?8 zcN5RMf;g}F#qei%p|%bKzyUYH518l7#l)zQxU%0b`tKUZ$HcfCxQYGTN93^&i7Pwh zy|tggWBEKW?AntncHqsdr@MHLtOmS~SbsfBTw&H40*}?F`>BN=a?n8zM6pY=4K%yDksPg_G=$>)f?{V3$+ z_eAe}pOUBda$uck_ARd=uH#31|Ju9Y331=!C#`2!D_X%uJglcw*O?4|;EelX8XhrvDXagFjJ zzY;wDHgn^*zdgr#LSM1qQsnJ1;4N3P{9O2L9(V-%lOgaIjJz24b7Ji0BC(%*tl?rF zeie9=*l+oQxc1u?+<(pUYvZ3+`l+9a@#{h2Nzs%k)HxpO!=@#?bPYo}( zj|*qK#QHsAKlvl#s$OoyA$!lVeu8}H4$d=k(D8PCndSRz&w-3%H|sEP*N(lkXSf!Y zHHNtIvui5Hq3K`KwLHD2SLE$Qkhc*1D`3LgKN>8 z@-6yxG3x7kjqBC?4}1Tb1}?vsWG=W>#Cdo%^3T7){kQQx-nrld{>}RR^j-?}3G4q` zRtdPLCr3h8_<1pL6({rsJX(@ZPb_N{ z$+e@`vw*v+xPO`F5#H8%=>7n{huZY(Z^7exvOQ$9{%rpi+v)x<^G4Wt5ph+nd@lZ< zTAuEOp3MIAKz^&YQ7`elNdb6b3ywoK#=)DwBYSd3T#Nm^R}B~M6Zn?6@^c@tk9R6H zkc!Wl_?}$zT*++W%6|DhxjVhXTz;Q>E^(zlN1T5>q&a;bhq&jw|GTV5z9)YMxL=Hq zuY=3)-T3=^u;&i$?-BTO3b_1U;~C(wZ8$N%2*2G;T-hHJdTYtp*<-H>xc=Jx2 zCwt%?PAzy#A(xv#o?HYTui=S-ST-9r}xGypBW41GhJcDC)>n!3be%!NogDQ+X zvj{xl=5hz2++U3R7CaL+-xEFg6V_u*V0&Dchs*$PS-|6+*~eH6-u$(F+!>xwcGCHm zSeHFbT-hn-u{obIPlQf$$OrSdBbvt&?$z>i9xcZGy*^{V#rxX( z<59$wJ+YM>urtw*P6Q8%dv|Am`^A0NwOT*j4-w^_`MD~Wo+}aeRh}fS%8g#m`oL3HkRSpD5*aT!6r; z{sQf?hU39J@Ae|No8HH!KKy^0pMblL~MdhPNh`+ptwABMr6lZfkh5c}|7fJb)Y zcql>vr+uaL(DMjl-*UF*bdOh@>%FTvJ;x`;m$9qaZ+eY#Ff0<|6c?i$MaL%`z&jxZ&=TK>rnyza2?j>4}Q< z!ZTJE=t$nz;-|?hYp?HEzf0_ET}NESxl6o%>;cF}kG8KL zTfo~q$M?O`Lw*+P)3=DLdbvKcuWP;m_lWsw-GA7gptwgmi@4I``=X8L4~%OE{>1XpJ>fUxpYh;v@g9cR#8tU1 zcOIfG><&BM0QZaY?sd@P68B*)_?gR%oXB>LL;rdT+#O=>hdnx)$!*4DY;)=wNKrhV@KPh7wYCN9OY{zF{p&k_6E_3M}yT*~$BgZj?VobGkM)mxJZ z;NKHh{%@IYZ^r?@!cOu2nUlanah5mxTDO49?_+uj+&Y3Q>PGx*_nWel*6A&5Pb2KP zP;(mJ#d9~WYEI8Ziv8Pfi7WdPV%=BuKln%F{{`TF(JsG(H;Xv&{myo-_=funkLH#& z34A{6H~na(=5!AP^MB+234g%O3T|I>KVd3(qzBLZ`@%n$gU7Dq7B}sFA9#3c_P>df zU%;Es;Y4EQnY;fVmn**y;xOVWe&&mH#BG|>xtpl(^Ux#b)!YBc`a_@D=ZB{gSM8e^ z#_c;E?fWA566}we_0A{I(<0h&qP2~-Ga~K@+y%Z)^xs#A>v+D0^SsH=UA9nqDE{#r zZhzQwwB~eQOFUn85BPj>->k=$N)Me!i+p>b=9KsTLy}O8Od(Pm55k~ud1$oaZ z_K(@eE8mLkEdAE5=ThQIPw-Rw_;oAfg9WU|l=}?$OfjF?x(oZ$f2}$i+M4xu7yWlMaiw2=U(#vd@gk1ryRa{`2zp#%9{aB5w2nhN zdeDyBZ^M3Dx5_@Q%^q1xW~3!ud3Vaeyb<0^~bp1 zng0H~;Ub=o&S81^{lZTWSMeD?810BSc^C5XK7e;S*5ecJjV~sy`gMV@^M1{#9mV?u zeukcwZ@K@LVm*8D_N-s_M{5Vx?-I`=9HTiskAVG56NjgQcNgt-E%Y>r`PGBOl|Maa zu|0FS+gK~XL&BepU0FUR=5<#RSAM7}Zf6o#dR&V+ez+IVd!xalPw;%KFWTkEomf6T zkmp4Oh?8@P>vfaZPx}zONX&=xU9871=HU;52XA+43m0*>v3>xLe!}yXe3ZNE&a6j% z&&A>3VR1e(7u+q*adxNoGVA;-;eE%I&*aoHL$7T+0i4 zR)M=-;ff|O&)jb}mbb*Z;BMl|&bi;%=L4@m-v0`><2vl~=kAVjyK&1_pxw_TuHrK+ z?!(*&`RGD!@VT((3-FkDe~a}u*5C3N>o;*&N?gakxVQfb%hNsv=09}9Pk+9I9?w0Tugp4S(%wpccWb7YZ~UM+?H?Y?@+QA|da(VT zT{&-5!OzDNS8?n6ko%FjxAP|C-MewSm~*JweOOPpjOVNCVCS{Ol|9{sJ!>IviFTj* zch(bJ&i;%*&n)o7^W0yI{VT!cKL7svvY&m6?EdkA7l}B3inxjs`TnS*+^nZm>=!*n zT**hj=RjBpJHG@^h$R`JT`~4Qx4vZ!?alf!^WFO%sCYLk_9^G>tI@uXg2xZwenCR|vs`mpUkiJB^kIAABF=9yya#)74fL!a zuKZ>Rzio36+Y|3&FSieI)xPm@JP|hIdq~SueiQ526_EG*gENMCJ|gd6)?>}aJc`|C zO(L%RGhfWR&WC*LJ-eT81`m>7)u)le!g>|lwG+qH8s3(&wmXE&b&LJ;D~RhnS;6gV z`g_;DEbkHXx+}rM;{L|>;LYMaAp;JD-}bSuqfY`4RdSr0b#W88{66&Sh^zO^M4n|k zb*1Tl_d#C1-*UghxZH@yV;6#ZPP6;xHR3uxg&+Kf!*AlgaRazVoa;SETJ*dDy56iFX#oP@Z2JbHRE7pN~M4asGReI=q6U6?!7d$HR;S-uuKN5N1$Xum| z)^X#wKOO;l&LXbjUp{wv9eDU+?iXg9`bO*7!*VU-dLcZmu6eA-C+2(8z++*VvaBbF>wYKRZ<#lM{qOstx0W>d@MYqvz8*0@ zA6mdX`WELmGmhK}Zau-=%s+nxkFB)Vw`L&QGhfvAXYf9Eb31Z2v#hcsxLnuU+>gwA zK4ZjHy_(Bd-uQpek?@Z=@BSxo6}LsgpM3|hd>rqe=UP}+5x85#$ue+xuHEA(_Gbd~ zI%9tUapg}rKW_#PU&-^>7M_M$E5Sopc=g48$c{(D&I>W#)DeK6#$qS=KsmE5rpx5uXPf!{xff^P3ICmH*vh-g^!BYVkbI=im!3wztO9spSz-Rl64ign-XMn0EY%Cy(l;PSm^hYf=tR&u#! zJ}?5j8TSB75xD1pyWVAB`st_OF|nSlC}jO|fBtds@H$>cdsXdrR&w=Gr)!0=Dya=>HhJB!f`Aw@AZ8I9=(hmS%Y@j zcQniU#JSr&;E7}G>m6>5?X8%(7=n6zLGrthovuH4WxWpiyNyx2?WfRzpP)JEDPa%H z#IN249&d4L@;KUenS&meKXtkN9QZKJX@BE#-rqC#503{AyP3OCuSpJi&UfJVUy|CM z1<>#Ro$Iw4`d2yV`5E%jeb}BLBrp;{0ZoZUBev+Uvp)B51x3Q_idI!SJ7Cuv-wK4e+k<0O5*!b{KOWr9+R)e zmax3*OwJpt4`oI782&V$44QHCBf|@Mge``DS~O3p5dOH=IOsox<828J#!drIOkq1` z!p^5OZ>wji178b0p7VGoZ3*nzXFQjixR~`@$UjrT!+-F;Uk=jQJ(HDu+s~trcQvqo z%>MsU&D+XS*vF_zdvlw4S#1 zlsWKoG^hJNJ8+&~3Oi>TemP&Hazo`UhOg*>&efb}kI>>KT%H{eoj-#7eBQ;M_j6a@4 zT=%2W{WLM_f*R;)HhzOYXM%gq=DhJZ^nB=`{};%Ieq{S+LeDlQvYpL`ak(=QtV6(~ z5AgoRI_R$gcQqgnApW1$970JyeuI4IUM|<<;hd9HxotoDX-?0@^g{oFogVN=leiGS7?xw{GOTy%s*2s(F&b@W)vW{2rrci=JAt z0Cs-sAir&p?eUM~{D#MDtUbZqpRnIdoaY)I=Xr&hZyy65d5-;1!|JRP!F?aFyc-8* zk7?evUjKr;h4@?zk#8L2wwnZCmZ=Y*`G_%Uuwav zc^v=ddk2~v^gL+v;Cm25>cRTPWpvNEP_L_)& zfEOI(S3|yKYcAL1rS4PMKe4O1T^7P`<1|ll4E{LTflq~=mIv9vEs(#3xayD1SF^)P z(H~!fd~6ZthjDC{m2lAig9G2HDs_DB>cG#`oc2%d;C94ok*!Z0n_B}k(#&l=THYe&ggM-;PgQJOagCypYwbIle~K!^t?=*EwPuKAl{Sq zTM}Zw^iM5M<0jfGh+pe@8rL_3^^WNmqcykdR)2fcfya%W-`x6_!utP~)k0jwN#vjG zFtg5m;&d)I{6CJ9dHln2)i96G;<#mPbgZd4lqUU{c;bdiSYls4)R|+ z@SLg2&bFW44m{w%8#SkPd5H(u-e%nm?taIu3+aubR)AaI^E|`@`8{jdZ$S_HnatLo zM$PfdNk8U7-g7H&01U(U{v~+x`)(~g55Kcb9qW(X#vR&&Jim+PNs95u1Bv&fbAj-0 zY&mf z@*y{fANK$1Am8nb)Ny!-<`h?0H}!#O$AVkGaJ$b%oSaQu^;7F<25!W|>yS@8$o+95 zrzdOodiJOLd)Bj(-C;F=Tg%RlxnF3FW@x zpyw0FM=oK%4Z=Rs4-WEMPET#;t`2-(2Y!U+t1JaoP-`?1%0{OSRu`mBZU9l40*SQ_Y>e&>sG`6;6S?zd1fuR z=NxVqGY=_lO6|8Q&1rqKE$8h;mc^KSi*OJV=EXQ%dCf#%e|p5?r4*4;h_`4b%YX%74{2mYV~k2~-+n$!996}-;! z!*Q;2kk7?_b#LOS<}F7;K5{s>mswxmt>x)_DwiW9jP=N4;L(BhJn*4|{x6LDVEZ`R z^<0i0{{^hy2jfP7TiY_v!8mmecxY$lFJjzzUh}r?{wCy`uVMKGh@TI^qfxFe9-Fte zJ&)~a{*mL##Njy2+v*QF@XH+dJO{qmfp1PIv!C6M@;sz~i?JpVSM%7pn8#wf%eq9% zx7G6$^h9@K|C@aEe-83{U6|U>6C8N8=F}he;Q_(yt4wo{pAGr=Gwh$GF!^(%X9(A* z7~|J=7qK7wMa+xf2ao1$>+6Gjs0-Ue-AaFEf%{J5yj_62vCKiwe;oMl&=ao2dI#+| z;$pTl_9M^F%{qD}xTl(Xt{e4Qrg>ZYzjffhLr)9l31;1T)C}%N?nzux(~qVQSN8$@ z@3?g#X8-?M@ZfOd8UA6d1dlG}b_pV|j=qHTgzjMdkE6cBHE(NwqXWO!f&a^azoe*xq}kFxwK=zq{b{%y#Ik>}00)G>} zk(yIJ*^Xz(=3d#e-1a|2XLHc@6s~b|dG38q}*8JYK|l!l+k}xbmB?lGkfy zUuBV&hfvaw@1ZAH$bMUcc-!OJ)c)~mPWQm$STCSoPX$lBg3+0W4J!s7evIcKNPE^# zhI?60Bg*w%$MubV<)HPBtE}IgdmaGpI+_#MAozI{aivF|H%-;@ZR>l11E1@_ zpK{=@Yff=EtEVnx0gBrG2DaZHX1)mZJr>+|I|t4%$WH;c_GCZDz-McYza;&*-+@2n zz&~=}t2L)_|10*h*|+=+yanfC^cq|J=|7j(r@qq;(0|_>HjO8)@^%aE$1VY%tU3OY z^y3@{ek=4euj7r(3jEF+;K6~sZ&{3dvgeJe+_s-ln$x&>7{}pE#MKE7@>e?WC!r^Z zd8`{ny$0^um)pza;g7(Zzh(PFh|g{}rMA=Sz(+gqfaWyM#D0;vA2kg;_8nVj?j6km zm-f#$@`$%8^wU2zZ|l!pZ|3&(EaU#W2ow78;PGF$+z9G>q2_J%TnYK;$?UgbkpI*{ zexG?>e&4qC`S7*ia$WPVgPtcG_*=x)JSrsi z!+&s)?{f?L!Mcg_hS~3$2p;vbKbOOw_k#Pb+fO?qpC7NXzSg|0f7Uwi-EK`Cw+CrX z>(IDcD|12RNbvY+94CFz?@o5mQw4d?`<#D*m=K%;-f}+occf42IpS)6Y$5i?%zpkS zMqcbIZgm^`EqXsEjCHW{AkFcYq#vg`@CzOI<(@);Y-M(7siw{J)3hG%l~=xS9id4hE0U=K7lX zZ~=G-@oeI)#6kbb4*YBfeuD#lM03jLfABeA9~8XXovG`Ut2xc*VW)}z(GK!84*Ws~ zei`(K|H19J8~?Cg0*|fYd}7Mo`7VwV-(HvxV;m_0Z(hsoZq_vmz+D&cy!1uLzpXif zBk4zr1K*d{;cC7Sg&zv=J0rneZ*jS1K2{DM{*wJXhl{ta2KNo%`J{=@Cye}K7~hdU zW8jg)xkD^OxvqOsw^tv{Y2A7#`)4=A;Slfy{2AgjXWa_!3vsziA-~E&{|@(ZKD3VP zr7gj*Z0${4`Nz6|zY1}`aS^eit>5c66^=Q4IZ1apO$Pognyym zgQ?qVxaPEe{2$Ak`(vfxt_Rowr3jQ8jC?ugx8A7N4@Q1VUQt%`<8t?ZD0R7GHQ&LC zoz02Utb@wHH*T;&?F6i4P^N`gIHK+o?}n z|DXB`aX0>){9_jMSo!RSX8hw^@WfNNM}&C07rbRE=W`$bn)RmU$(s4k|8d|4MpN4} zn0TuGSna?s*PQlk?&Q4Z!8~CJxChVAHo~;G9rSzw`3Mdqi&>qu%Ok1nIfS^%Cv&m? z9EScQwLHaP5#}xV{10b=%lkjqJLr!%@FyJjf1%%fk6RbG9Pzxu(I5BG z97ZSo$aUanKu_XRZty4u*XO{4uW_DfME_k5?)fM8#}NA6R}T9BXY{XP`C4dO&}JgZ#yi58cDN7peEf)K}}~XMWL5VA((FX2{oOq zlu(m?rP2z&R%_A?3lW!m)g+XXt(sta_aTbH!kh3rVXU7(}0b)neM={lYMlB}b%?UJk` z-MXaHF2;^@+9g>>r|U9pdiw2>q@&aAlB6Tux}?=Eup_N@Nz#G3jOz6Cnuojcn!>T8 zXx80tY+3D;%0e~M?z~E#v1eGNnrUQAB}KN%;3@QxAB(+ezp&}^MDj3 zb=<#3rK5k9@wxpQ>#J+3Yb(p@{bl8+S5}OyZLF*h)zy?WR&pDAbF0c~0+Y%bDwUYm zGd(b^y0+2Vzp0?GBrib!`A0R3E%63Q`m6u2=pv`A*IPV(oQjZQueTwjR1BF`T~py7 zrIvUD8|o%EPOhmdYb>04Sb1G-Lu07EE_9e@y_USn`ue*1(RE`h8>iLR7FO%1>t8~; zYo`?YN0pc42dd>ScHC1*nJb0obsKxDYpWYcj@r0k{bH`zJD`DPJhTiQQ8smIS!?_2 zUm3`5ZTqjCFtD`?O9OjXz*#Al%L8e(TvS;T(o1A-Ag`pdab$6IUSV-{t(X5-SU8$m z5HMdb5Ba#2Tbv4!HXBFla77ootjCg4+9-7uTxW2yZEE6_?G1D5? zv+B)hr8lcqO1Gu-Z$^EYe#E!thKwgl8meTBc4~MqoicUe?RX#3OB0?pX2d?DFH`mv zw@x|Q*k`uD8m3JOj0}{k4X{8>*`&kDLm}!{BPQtmGD@(vBvt73l&gGILR)N=?T8Ji zX{f56+?d;rNC9R14XGiS>1|{NYKz8?n@l@)gNGE4pU~j#&z&(T^_S!Z3UeptC6~X^ zzn3@J+pn{~*uQhXSW}}??s}(hw5j=%y&g5Pb?P_0oimoo%q{3-nYo>|Hn(4At?k#z zGW$&)=*jC`1ktb7P0sI>kNVZ9X%YRZn#&Y>J(RLA57bj)hEvqkz+ZP}Wqm93YFMiK zT`SGyE<*Dq)l1f^RomLRYMv1o*1um8R!DDox5Z{U(kh*&ODwKCQ+Lr;p0D}1s`|=? zs=Atrq<>KAjUJl)t~aM&Yb}MYequ7z`aAu3DwImy0BrzGlG@skmt3*@$+`VnYo9-j zswlqu=7@ErCnb4oAUSMY-HF2)=~&65DYe&IKD}|sh_Q`z^zSs6t(xku znp#btNs}fO=H&(g<Jm7Wow=mpw;@4D0?(nbiP}k94GXq^Geoqf`o%lUH$aVbpc!=x7@96=q z1EWQtp0bt(K<9O~CbPR5ekjhTX&-Hl=P_54V=uSr3mJ+3{OGCehQTi<)tdD@k8P8dgw>O4kabqBB;s zjzFEZLa0c?3R98Jv88p&}3#lRvD@;W?;R|DhQPEi|cr@#5TxctjRHR{r zsYqvi!DFPZNGGjm9rMz0htQISEu5#*wIxYQTDGX{oxUyWwRFN3Gm`MUq_ei9(2|BN zN#5;5;2K+!w4`Ordhe!X%X%#n(jPR_P+<~6XHAOkUs1vprE$P*$Rg0;S-pJYD?s0DaRNE{a+BbGo z(UBcvMmIeOjNZZ$A_kroQ-)ztL9;3cdNdHOi|h%TEsk3e<6& zZpQzw%pRytF0*L%2JV^sW!;@EyF2OcjlS3O*NX1VZuY=VMfc`5JKI5$t>Ert4%}#W zXU*;`he@{VMx1p1T&3+Dr^4KRsplA3ImF3AVXaFEx#gd|!f3jm{ld)JVw1F)DQwf# zjF&u{$c?->+BAi=E~7SGdAvN?l;x>~O!mt&3#ZgaU77FTro2t%&(`uf?oWNq$(yfK zm`i1WYPIWze@MPomi!MJa~0ocDWLma4I#R_R5*EZ^8I{u*+>`TB%rSFX@LP{^-~(^ z>Kjunv*_My+eZa*^OX2;W%Ou3)7ZK*8-|=UvbLhSys{yc2D)*opCq8C%abpuXF_i( z9Ruk4EIm|_@)|msLjPIopK?#S;ybl0gd4skjl~6lKy{tEO-ml)TNwrV9xw?N=qKWj zD+`&9<=x9$0dEO<8Tj>1PE-Ru>jl`~CD>QGY*G zwJ|VqT!2WmpDx9jxJZ(wF{d5rl16V{AW&9u+O&qoKviW~Xe4Q->KN7Z+cos)!{~v5 zz?9l)f%2v%n$XmR8od1iBdM|IlJ(S3pql9au-XfKF5V40KGN0^X*;20i1Nc> z)eZG!`r#d_`G$%m>pNTQ`ihHU(Y*{-z!_D^vehQLp&%1EyEoHyypbw#bi%-rLR)9DNA+Z?(KNcOU0Fk3v4!@)DRp%f!|~7K z>c-L4;nO!Z#;YqTXb_^S#}yk0!o2?L?~!^lRG?GPa8bnrtIMa4Y$&R3X!MVoPNM)l zSxDrBdWsSay?H~Y53jDNETI@Fn^H;71d^PW-V-ypv9Z3Geog<5mwsn#Wm!eaUs2LZ z#pt?<%Jn4-t*NW!5=MEwL+R3ZLu1{P`m(8JAj-|7d*bB^)2nDspBADAZE7kT0tM69 z=Xo>};Xe&536<41RI0zza5ZYOe^kY!Nn=~%dMZWr)WX7~v19!#DT`&OT%w0x?|>@h z+xkkfvU229a$y5q{H8Hj*Pz-zs#-nVSxpaGD&vz4_gAU@IGFn5*ph)Xc+=k~Gmlk| z1*@k7^>D8LrGoyYLLV~g5(|vuQk0{9JK15T*h!P*3`tq78^qQLylU8{il}x;75pm7 zH*o*lJ2028p{f+pR$r2J8=)-Mo39>E;=w1k@{DQvQo56MsfM2oSeuuZujb5LKtJW# zA=K~v^>wFFevl4U&AQ>ap=#%f4LyQD$1fc#H_30Qs=0B6_8++Z(Ex9o%CcH9^=<8E zh)-&?ROOEyrJjSGOp!_xL&}2fK7ZjY7_i75_s*uO_POA{PvLQ@@bQ*%hlTe^M{rxBgl%$#noQ5N=`P0783o` ze>72S$D}-6q2jXI^0Vt2@-wBCE851?3aWDEO-)a$y-gZ~6Fb(Tv`uMif{y(*z0om^ z-!4n*w`oe-iL#R#*y|l$-BelOZ`3haT}1)ek0P>xUc`|*pnpN8f-@_{I7I7YYR=3@ zYkFFpOr^NZf~gtMIs~uXY0WIEyQ&$wXRJ=8brUMf3uPkB$9r}*CU>fHn(qhZR=Sq85wrJTuOycL*h& z#@P7e)>E21)3#DRnJ3BTA|VO!WUQp^drj3-r<_?-y2K=si4z@%xq7`)UX zH*ZR1qrbAgAwgkoV3su`dFaMazOVOmwceRn%&qHhVvZ;ZQ$Bpoh9WyjAqHvs_ zHWU1XL&uGrP&jVv;L#<+$BaELP%@@?LSf*z!f{1ohOKv5?ODr*|`TbGhN)=wDN z>a&3rbt9<(2G`UiwZZzevqx2RFdbLbn)hCbm86OR`*9I1ItaFIc2u{WO>AJ9mD_J% z>nfV|8fb4?oneJKvTaNgnd%L$r3&&|w;}qenkKbTs(q4FOXLhxcVO!~0%-fNvT&hh^<9s)ckg?>$JNz`s_3AE55@BW{f;YZ8WU3M zc=ZxNuSfs;XgzJ^DO3Ki%E@KZY8q*ru2jENQlJj+l3wb(nGI=uJ8WhR(X;HlK!J7$ zO?%0;d4c>1=HcvFoGl;I&X&pz9rAHO6TKa7v-voC7H7f7 z)wO?-@u_o$WXmH?$-cVwuQ)zw-(}I{Y35OW*(oki?d~Kw*2dq?Nj;J_S*8z zkvp}AvuAO(eC(9%+w<{e8=tg~vuAO-J|3W#19Vq=+SFR-RaE~ZsZFq!%8F6h^%RBz zZ+?=e{#uKy_MMu2`?KqRj1wL4|E3(?+IN1IjnA&wd z?{AtRv3>7n-TbV1Uyti%m+`MMKBi+-c0IL$@g?QdZPRW-ItHqCYWD5VuKzbM#H8~7 zUt)aJ&d;*(+4cMe2AEWy|BH-|+V@#EKfB)FzyQ;p_c!zSsJ)+c^V9V{uXpI#X6MCY zo?a4>$R=1hX4sr8ddCbXe1J*b`D?8f+i_%;EzhFQ%{a2LKHrohU^@=arrBBawi!7# z*4vwQ)N9Az*)=?i9yg;!M?Jo2M!I%9o?XMU<8eJcn+4$JALBZ0P8Pk>-bj&h=Cx^8 ze5nIcJ2K0bXVK^F4Hl_w0-?{6K?IiK+#&{MD&t@{rqS;vaC(Pe8y{~=qO$Y3N`J1v2wr{-Yh8-||6ZgdS z?KhpVgU8re3uxOQ=-||p>1~sagN{Dc=5L@swrBok?vL914fMxU=Km%7qc(m6{V|pC zf0h2I?cYrOk++R)2YJaW*EY|CZ2lq9$zpWA4q3cudYzNS=x-Zk@uuu(PWGaUZIr#6 zxNkX`YY~#C>d1;dlX-*b9^{4hM-faCTdHmWaA8+RVlssf@ zl)an3KiNj9PV}dCAL-@^U-Fd_FFn=WIud#5-96??2`|vR>N)0(8;z2l^WKa`wC>h! zMk89&TW5{XX`vI%(V7}E&>R^sBK_vbfD!38hn_=ppgCmT%RpnKZ9@7@k+uoxH-w%X zb)X?qB=iilMJB9Bzd15tMfxqG=YG^8@}5Qp-0Y}2ecw5%PRk*!b5Ms6ZEsfBdc=^P z>oR3TT29WC5$QKad*erY&5@~*RC^)=Mx@^y889OK=4fvWN!1*g9Z7X#q-{d_O_8<< z={H1sqerTS$oNRA+aeQIq~9Ewup<2yaU7F!3)MHFs5g0aVmYDR?5H|@-#MyI-y!Mt z68e5L|EMZ|)%vd!%e4DCRzS*A4YdHbHBpL_B2^43V!jxy-I|EKrZz>`wiS|&tS ztnKxWj=3~-Bx_sROM|IwkyECO8PZ;tN@YmfE4djnrM)iIo++)1td5z|e#9GVxDk^t zxMX4fbW@nJk<)@rVai5MBic8`L~bVtx85j5JV&Y{^I)wKu|T9?j0ZTvQ&DSbw>u>sJeG{ zFmbART4kqMZzQITs&^Wh+NtX47N2JAO(L;v-)`*O+Nn;dm3H1zol~9iQpypv)60bv zRmw!^Y1Z8-FSS?qjN~O<_cTjSv+hp0AywTon3r_T(<(d7dOIbCRQ1kmUeZ-hxA-(` zpE`wX7r*k^tFE6 z)$MQ1Oc}y$W;^Y?V8ZLE(BBDIQdu*3{bi<%S3!qdC#ujIcALElI+Jyv3No8*_6q1w z??44oWWvo}2R&j_9pshv)Q0IVxy*Wix2ARn=cddhf2lsItI%E_ZLbP{jXv5sq;#Ma z{z`pRSD?Kz(0n+xwTz@U>UuiULzaply zcA_Giy1%wx5i_iIpdy>6*S22`({VdcjmPWxD?ikH!yZrM6hY;4ur?AN4QdYb1foo{wMVbifp4`|rWqtaCB zwCR&_`j^pI(sgo*rBuadFqSf~Eu2OywNAfNL~^Q{n@1E{p9?_g#ohtsb+ywg>l=sC zk5QHNwUssgQQrK($WToy8LJ-3%R8>Dv2g6@lH5Rle_eHLV_;-;VIdya>)alf*lt$~ zi`MkCv0oqGHl$L|tTMf5b21)t@Z=+Jy&T$@hiq@{ z44c>QW{P1;%c)Ju^ztBuJ6lHzTH61GOv0kDO$(?;H0Nn~n{{~dG2X^JNAGA-tM6#8 z*mecifeVWnGpTi2;A~Q=0XD^=GP5>e`sw7RR5r=}omqphzUhcTZM$v8Owyr*6@rsV zsd8X8+fCcFfp$w}Q`Xu|8?=FTOJ&eTwOesPUHNqVvctma>S}-0)Dll%D*efP*8kN% zs>0lnDIPGju0B*XCRA8Gc9i-$1#e(vZD?BK;QIQqvkDpI2F6TlT+e7xKypdzf@=QF z0VU;SHD&dIku=A#0wapY3>jP;2sBKa6c`!MWgJ#f-4H5kEU!AOJQSj=wc*!)h$+kZ z9GY@*n;gj1g?ZjUpnQ6uvA(RlGEh@jUe;J$R~x8oA`qBd+rQtyv#HMtr)ABx*Q`_sH+4g99+e(|rqdL)S&VG_S93)TVou?FSC-R%pS5Ez;y=>e% zf!vgqI`xxOmTsngl03})KkB};yKy5)u>a8d5#S-}W0gc#X-ZYr6V>jW`GQB0kc2ix zvU$i=^XoSv?*#G$5|nnI$Gw(>xH7JcjEoFh{6_h;4~fzQw>~Ub*8U;ktT)IY8Fb*1 zC!~xAgP@S&pn)e(H0+6fHT%B6Y%%8|m+xeP$u(|c&P6TH0z;`aS*0T z4Ag2-=ABGO4K(#u&)8sdE|IxR$K=NO0_y?iT-3Tu$3*QrnT{HC!WF?7c#=xiT71z0 zkD+Zu4S~MsGoA!RA2%&L09gt_rbOJcyEzNl+?ry@HpU{}k$x7cxm86_Z8EI0(#!)> z1kK!a$&5ZB*fW8>pOU=CJTFJIeDTdUlDqAm zG`NtGWmBS)$tmHRr+1{JUa)yTQuH`?9y&r|*ZWg)UNtewbS^x2h}l>^Ny-xqNjJ& zX`Dy}yPKD4J}rEklHuqgD1nJ0L(`RaAj7C5=cmJ<8~qYtQc$Bic|S7Fs2WCTyn||( z=;)>z4>#V&i0IBoym;>JM#9??5Az;iwx_dW(^5x{Qebb-JF8!|a=9~d^`*mNCP3bv zb5;Wl;#@bO&U|-9-Ja`iJz5=AJpuAooRj*ovFEEjLmrsz>9qL+lWRAefOO<21@`v5 z+Z=+C_r@_wN7fS{Z_l~SC73u*=Z)0EpoSw1M%|ukn?o?6t|ymWys&zp6vVd$xu0`d zI1y(zH$Uc$^r+q*6sX2+A$Ovgxd&qxiE*=7&w+zi&B0zOB05Qed5dsKv~^bwK_sG~ zlN|U_a_I3#OXuZ~LJ|r($$%eChswa>P5iqehZGXg&{hswI+WC-`5||r+2u@(VJNXj zBkZLjqLUuHJA`uOpix zPrh$7G|2^KYTe*>rJws28ao;fmZr_x+^i-frK?o9qluA9TYu*kN;*oq%7nX}2${6> zeQt@QqNA%kxC4riM{7UmmPk5EI>>}Ltsd#*l zQ7Xy3ArVSCO1jF#+)%FS|6{;!xH%rx_~arr$oli2EhD z2MH4=94O&N6gay0J;=l6-#01|`SwX}57M5B3mbF z`jL$*Kp4}jvu?r6%1Fd`2EzN1xGO>!CI0@AjR?Gdy8Ds0D@K^){qB*CNV{*U`;oOP zLYQRz0U{fbcK>vDkhk&dy0L9DHANY>97%R=z0uU0oOryTAw_Mz`XIYFw@A-Jes9v} z!6Qcc=Zt%9;h%;2-ek{1Nrddr7z5psKLhQ($(;w42)Um%9=aue7V7(uJqhT1%lAQ| zVpp1alanW`7<0C>?f|VyNC{O2 zt3cGP)ySBmHHIsgQt_}wb;Dp=}w|7PRVWb39bk&YHYNb#tlk(A_WNGS2Bp^1{zYDnntsG*6D)@n%0J!*?p z!xc7Ktio2^0hv3&;JFvABdmi6u6Myiv{gC>4P4_wX=tf#4hp!gg;J1M(TKkD1TLwf z5y&n@Gn!FiMI%JG6wOFPT16u?xD?GqLsCT}6u1=4M1f1uKERDPvb9J{2T|70+bjk} zHJ+c!mdze0CYl{eaZ{_$PcSiqK!O`4aDH-$%>-D|1lI3@w=I4`6J>LGaM^?#4!_ zaT%M@Wqkl+BZRw*%}DtB8ylh9Wo#z8-`&^<)h=T*QGHfpGuB!g!Oc|R>@U8#Y2sE# z-CJK>mmTt5H~HN5V#q(I`MIg*78pVO8I90QJGa9K+CPRV5--9--v=>8LX*c7jn3_? zG0>_IgnW-F8p;0Lrbp+B_H;eO7NNgaG z!lv@~P9w2Xe(0l>3eSVuW(h{$&rLS4pTB=r2op#}}3+L`D)yK$(2 zBbdrwjl;OtZ1iavw(n}HV%=Db$Mi9GUj%Ve!R@430*Q?y;$3swPACn*++Jb`Hk!g%SyAVy8i};G{f(UBX;*p?zYwDSlm?5>|=A<(}AUY zmFF4;u|EPNj&09HHiR~0Lm@67YvAZ1jv(6wags@huiO3Zg>XFkIU~GgS#h)3osOUO z`^7KzqrCXzbQC|U=6RtDgNf;4zFe#q`{D*_9k7|WJA@#TmX1itz5xwb9e0o$1@n-YCXPQ&zPHUT4=y$cQXQs8?Kp+}>>DR9N_ zZ1Qt@j-_zXa4vN)(r|8dFcHz8I#_ZJV?B^%bgD*p^UrKb9i-Pqv>-%Pi}xYKq#N%- zNmD_3C&Q$t^|TZn*SivORuwTyzD1(1E_tn^e%~9^Qk1v#5Yk0%uhL69p|*fVZ9;PLIV+ao8=6 z)nfg;U#zNfbNp?&+wqNOHfF#4!hRXN0UQ^wZ66LyJKOT-ala^@HdDEG?}o;@fzJN1 zK9v8b+El>QKk$Ewm&IFIzz>VXar;^=5C2&1kB8&w=?VT|Rqo5@>ToRg#qqURuD6@= z@Q$rBP%KVA|FPV@?$+h8T>S?7Hq&1ePk^piVBMhrneKo6<7vNm zEsNFZ_4OBgqWo7u2vh%bv0R>BwPhHPAD!G=;R{;qP|F*zDV+^7*CGrvc@#a7SmysZ zE%uIWcPm^YrJQsjaos^>;j}!OR14^*d+k>E#@R?H@>JscS6My3z}lG*TCuJCqMRt` zx-6Kj8kcsdY*^ASk_}Vx<*^~cg(1uT+p0o;wtOMRwbzNusiTJ8`7WMZP&l9 z??`R5y2GL=FP1(OvsraF9~O_Rd-!oS_;fmMKZE-y_mC|W{y-u}y^mv5H1+4>-QdCO})|H^J^I^4o`$WWFy+V2K>Sa-F95(;H~vlr83X*WmEYr&vy$FalX| z!eG4kY6h-Vft@FD%*?)UfxO^cG&SKF4<&@6Q8i&I0@^Y|<0l6x_uu9jWIA`%-P3&H zi?!pij7OS&<`WAlSWi4sxl@jA?jaC8F>JXjvS)*#I6%n8H3XsFqFSvWjdNxYqXFI4 z5eGW0;UU5j$4>Y2K@k8klczej*<~Ff%7kbGU4SrxRe16JmJW{%n~TUed;c`RVnhdYO&)<)J(VC1T2l$F?62m&`J#>zsxL4$6Ns*1N%csR@eY`HQy0X8Sk72_#QdKJ}Ej|0XU_|LSs`}MB z$&m+9I*wMPGrl*ilN@;vrQ@hN7e^jM2|02btSscU3*~Z+;2_K8g3@ucBG(1Zp>=LV z={SO<)+M@xYve|hj-wU1Byo;4awAH|5$qq%v_@`3={Q=E8xH4KBR8US9Ko*gJZt1Z zl#V0VV4sI052B77P0q4`4aAa&7tfBeqtoWRc(5em#j}@8#ES<@B3?XsNFrW5SQ7Da zaOYHsc=2FK#EWNlpNJO^mQ=i)WnGSLEQxsW)F=|Iiw8?8Ufj7;Dqh@JQt{$m{ZzcT zu}EHA2ZTytAIdiEP6VK6(e6X24Yd5Q?NI`3Zdzh&oO-m{bo1Q6Q;U<`G2O7ZwLKLU zcX2Ec7LP|wh2<=~c%pV9UOahDA}pTFFcB6{E}aOAr*Pd7i{ffMTeftFJiFa=h&&aE zbcj5~oOFmhb+B}ZJSD_*h&3ciS=3X=NB6~r&%sKPHIsfv~rc!XH0qGbh}hDcfA7jd$}FXChc zp+1r-{34Dj{34DjaGa4;;TLgK;TLgKftQV>3crY>3crY>3S4p|Rrp05Rrp01RZ6UY z#37Kd+DBou)jo2f*wzZGK$Wt;VoTEY~FbCW;6yF_{`B^dFt=fGDc|j{W!A4qr z2eGx)cM$zreFw(U>O0WlR^NeoMSZ6z8F>2EpSH&uyO0XOv9eV@jTNu*X|#lu4!@V+ zXrO--7)zCpg10|v9S1&&$8>1J6MPhpDLfNV1QDF)s)BfG!xMZI&r^7Qpzsu)zQ~WD z1|6D-=pRM%1V!k0O!!eerZ!p*73CI~+GsgcdRt&>qkB*oZGowc?&;}Ew{ubF$$2(d zk;_^0a{VMO$92Q!JcsQ8pYs$mJw8aK9IcK$;5##akh-0fKS=q`iVxD6v*Lps=&bm_ zb({sClB>B-J<^$kit_wiLJECu!JbQ36~UfMT@{oqG}c+-k%<)s?63{Jl9pmV5&sdS zJMkYuHWvL6+{kM2QE*jR5d?G}w7}F#dXOW<3!=?On4iaE(mraH9qD2{j~`L&z*}mN=L$n|E!_W53`)yiH_ zx|_?4C(-=Z3Tm^TYIMmi&MS0t*t&p7wN4URLHXX>$n8khPk;Z|a?#@Du+UN(eBG<3hp&6ksYz-1n5 z0JRLxvjCG^Jc1XRAx0_C#YHUqT2ADle>4e`k8HoL$uBJviSEsl^i5i0fapePWSvei^*_-j8uimd)YFb2Fm z6or9*5RL(SO&kXHK{y8JGl;{$J_yEuC(}_F_y@rl@O&={1OFf#Lo5$?{Es9BW58q4 zC?5C+;TU3hz!r@l9+X5HEBQfe7{2jxqJ9InIHU2fZ=&$Pkxw)p_DvKXs3%9`Vc$gI z2{m_B)}a=!e1msVWBK9V#PEX$9MO1M=m8#zMdN9q2i*60gO)1m7Iumk$fNmbp>KHg zJ{nI8eZzCoSUmh2zrKll=qB91HNT0$6P�yHFy77(6^9@#~x9hkp}=Cp7pd{9r#6 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 z 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

XC;GBYbZD$)bIS?i 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

r7z!-R`qsA| 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