1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-25 21:33:04 +04:00

Compare commits

...

227 Commits

Author SHA1 Message Date
Alexander Alekhin 6a2b3c8d4c release: OpenCV 4.0.0-beta (version++) 2018-10-15 20:31:53 +00:00
Alexander Alekhin edacd91a27 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-10-15 20:15:42 +00:00
Alexander Alekhin 5dd46b54c1 Merge pull request #12848 from alalek:issue_12337 2018-10-15 20:09:36 +00:00
Alexander Alekhin ea502b6e84 Merge pull request #12845 from alalek:workaround_12824 2018-10-15 20:09:06 +00:00
Alexander Alekhin 24ced3d657 Merge pull request #12846 from alalek:issue_12834 2018-10-15 19:19:46 +00:00
Alexander Alekhin c5a5d7eb51 Merge pull request #12843 from alalek:fix_qrdecode_input_validation 2018-10-15 19:18:58 +00:00
Alexander Alekhin ab2c16b2e5 Merge pull request #12829 from tomoaki0705:fixTestVideoOpenCLPyrLK 2018-10-15 19:18:24 +00:00
Alexander Alekhin 113793fee7 Merge pull request #12837 from dkurt:dnn_fix_ie 2018-10-15 19:17:18 +00:00
Alexander Alekhin 954536073d core: update solveLP() interface 2018-10-15 18:58:11 +00:00
Alexander Alekhin b54a70a538 videoio: return -1 is incorrect for function with 'bool' result 2018-10-15 18:20:15 +00:00
Alexander Alekhin cc45c10f3d ocl: bailout from unsupported types 2018-10-15 18:06:06 +00:00
Alexander Alekhin 6d2cfac303 objdetect: validate QRdecode inputs
- drop unnecessary matrix initialization
2018-10-15 17:16:17 +00:00
Alexander Alekhin 13aa23f706 Merge pull request #12836 from dmatveev:gapi_upd151018 2018-10-15 16:20:52 +00:00
Alexander Alekhin f8a27d2603 Merge pull request #12775 from radomsak:radomsak_dnn_fix_caffe_importer_reused_layers 2018-10-15 14:44:23 +00:00
Alexander Alekhin f185640eda Merge pull request #12799 from alalek:update_build_js
* js: update build script

- support emscipten 1.38.12 (wasm is ON by default)
- verbose build messages

* js: use builtin Math functions

* js: disable tracing code completelly
2018-10-15 17:35:21 +03:00
Alexander Alekhin 78b51fb574 Merge pull request #12826 from alalek:issue_8413 2018-10-15 14:24:56 +00:00
Alexander Alekhin 72eccb7694 Merge pull request #12825 from alalek:issue_8413_3.4 2018-10-15 14:23:21 +00:00
Tomoaki Teshima 803f86b9ca fix test failure of PyrLKOpticalFlow.Mat
* remove race condition
  * upload _prevPts to OpenCL device explicitly before calling "sparse"
2018-10-15 22:57:08 +09:00
Alexander Alekhin 7bac615d8f Merge pull request #12344 from terfendail:core_wintr 2018-10-15 13:48:15 +00:00
Dmitry Kurtaev dc3406eed9 Fix Pooling and Convolution layers from Intel's Inference Engine 2018-10-15 16:40:28 +03:00
Dmitry Matveev f0ddc2a53c G-API: Fixed static analysis issue in own::Mat
Tool reported a false alarm on possible out-of-bounds access which
was work-arounded to make code more clear
2018-10-15 16:31:31 +03:00
Alexander Alekhin 1cc3f7abbb Merge pull request #12516 from seiko2plus:changeUnvMultiply16 2018-10-15 12:07:40 +00:00
Adam Radomski 70177143a7 Added test caffe importer layers sharing weights 2018-10-15 11:42:26 +02:00
Vitaly Tuzov 43d9256096 Replaced core module calls to universal intrinsics with wide universal intrinsics 2018-10-15 11:46:45 +03:00
tellowkrinkle 803ff64b14 Merge pull request #12697 from tellowkrinkle:FasterCocoaWindows
* Make cocoa windows draw faster

* Use a CALayer for rendering when possible Uses GPU to scale images, which is important because retina macs will want window sizes much larger (in pixels) than the image

* Fix mouse logic for cocoa windows

* Only halve resolution on retina if image is larger than display
2018-10-14 21:18:05 +03:00
Alexander Alekhin 824241ad5c Merge pull request #12823 from tompollok:3.4 2018-10-14 13:33:23 +00:00
Alexander Alekhin d5d059690f gapi(test): disable divide tests with zeros 2018-10-14 10:47:50 +00:00
Alexander Alekhin fd832bb57d core: follow IEEE 754 rules for floating-point division 2018-10-14 10:47:50 +00:00
Alexander Alekhin 09cb329d73 core(test): zero values divide test (4.0+) 2018-10-14 03:46:29 +00:00
Alexander Alekhin 4a9291fd89 Merge branch 'issue_8413_3.4' 2018-10-14 03:46:01 +00:00
Alexander Alekhin 5677a683a5 core(test): zero values divide test (3.x) 2018-10-14 02:23:17 +00:00
Alexander Alekhin c813ad5533 core(ocl): replace ambiguous 'depth' to 'DEPTH_dst'
- always pass DEPTH_dst value to core/arithm kernel
2018-10-14 02:18:04 +00:00
tompollok 0b77600718 change area() emptiness checks to empty() 2018-10-13 21:35:10 +02:00
Alexander Alekhin 5115e5decb Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-10-13 16:19:05 +00:00
Alexander Alekhin 429a643f42 Merge pull request #12805 from drkoller:imwritedoc 2018-10-13 13:20:33 +00:00
Alexander Alekhin d2a66d3c99 Merge pull request #12815 from alalek:issue_12812 2018-10-13 13:12:55 +00:00
Alexander Alekhin 0f41daeba5 Merge pull request #12641 from dkurt:dnn_samples_args_autofill 2018-10-13 12:28:08 +00:00
Alexander Alekhin 1be75437b7 Merge pull request #12802 from alalek:cmake_pdb 2018-10-13 12:25:36 +00:00
drkoller 978ad4981e Clean up documentation for imread and imwrite 2018-10-12 17:08:01 -04:00
Alexander Alekhin 8c4f886f5f core: re-throw allocation exception if there is no fallback 2018-10-12 19:10:06 +00:00
Alexander Alekhin 0d63c4c28e Merge pull request #12811 from take1014:resize_large_image 2018-10-12 16:59:25 +00:00
Alexander Alekhin 6843d368b2 Merge pull request #12806 from seiko2plus:imgprocPyramidsVSX 2018-10-12 16:59:01 +00:00
take1014 24af70c7e0 resolves 11283 2018-10-12 23:08:25 +09:00
Alexander Alekhin 1ed9ff17e1 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-10-12 10:05:55 +00:00
Sayed Adel 9dc1d388af imgproc: Enable VSX on pyrDown & pyrUp 2018-10-11 23:03:57 +00:00
Alexander Alekhin 28cb714a09 Merge pull request #12803 from alalek:samples_use_cmake_from_msvs 2018-10-11 19:30:49 +00:00
Alexander Alekhin 91c6d36ff8 Merge pull request #12796 from alalek:fix_openmp_performance 2018-10-11 19:29:04 +00:00
Alexander Alekhin be76b451cb Merge pull request #12791 from alalek:win32_dllmain_detect_termination 2018-10-11 19:28:29 +00:00
Alexander Alekhin 53785b6ac6 Merge pull request #12784 from terfendail:pyramids_wintr 2018-10-11 19:26:36 +00:00
Alexander Alekhin 2332fb852d Merge pull request #12748 from terfendail:resize_wintr2 2018-10-11 19:26:17 +00:00
Alexander Alekhin f1fdfa1a51 Merge pull request #12623 from sturkmen72:videoio-4 2018-10-11 19:24:57 +00:00
Alexander Alekhin 0f3fe957f5 Merge pull request #12450 from sturkmen72:update_HOGDescriptor 2018-10-11 19:23:35 +00:00
Alexander Alekhin 41398987c3 Merge pull request #12792 from tomoaki0705:fixCudaImgprocColorGray 2018-10-11 16:32:11 +00:00
Alexander Alekhin de8024ce4a samples: prefer CMake from MSVS
MSVS is shipped with CMake compoment.
2018-10-11 19:19:16 +03:00
Alexander Alekhin 7b9b876726 cmake: improve PDB support 2018-10-11 10:54:37 +00:00
Tomoaki Teshima 944710de4e update the threshold
* fix test failure of cudaimgproc convert color bgr2lab series
2018-10-11 18:45:20 +09:00
Alexander Alekhin 2b3c7490d5 Merge pull request #12521 from allnes:detect_qr_code
Objdetect: QRCode detect + decode
2018-10-11 12:42:05 +03:00
Sayed Adel 8965f3ae06 imgproc:simd Enable VSX and wide universal intrinsics for accumulate operations
- improve cpu dispatching calls to allow more SIMD extentions
    (SSE4.1, AVX2, VSX)
  - wide universal intrinsics
  - replace dummy v_expand with v_expand_low
  - replace v_expand + v_mul_wrap with v_mul_expand for product accumulate operations
  - use FMA for accumulate operations
  - add mask and more types to accumulate's performance tests
2018-10-11 04:37:12 +02:00
Sayed Adel 5771fd693d Change behaviour of 16-bit multiply operator
- redefine 16-bit multiply operator to perform saturating multiply
    instead of non-saturating multiply
  - implement 8-bit multiply operator to perform saturating multiply
  - implement v_mul_wrap() for 8-bit, 16-bit non-saturating multiply
  - improve performance of v_mul_hi() for VSX
  - update intrin tests with new changes
  - replace unv 16-bit multiplication operator with v_mul_wrap due behavior changes

  - Several improvements depend on vpisarev review

    * initial forward declarations for universal intrinsics
    * move emulating SSE intrinsics into separate file
    * implement v_mul_expand for 8-bit
    * reimplement saturating multiply using v_mul_expand + v_pack
    * map v_expand, v_load_expand, v_load_expand_q to sse4.1
    * fix overflow avx2::v_pack(uint32)
    * implement two universal intrinsics v_expand_low and v_expand_high
2018-10-11 04:35:39 +02:00
Vitaly Tuzov 1ff11c84ab Fixed meanStdDev() implementation for the case input matrix has more than 4 channels 2018-10-11 04:30:33 +02:00
Alexander Alekhin 5faaa28870 js: enable calib3d code (no bindings) 2018-10-11 00:49:45 +00:00
Alexander Alekhin fc4679d4cf Merge pull request #12795 from mshabunin:fix-win-python 2018-10-10 20:55:32 +00:00
Alexander Alekhin 761c269e47 Merge pull request #12794 from alalek:fix_warnings 2018-10-10 20:22:07 +00:00
Alexander Alekhin 131d199ae3 Merge pull request #12793 from alalek:cmake_fix_python_standalone 2018-10-10 20:03:02 +00:00
Alexander Alekhin 35c53204cb Merge pull request #12781 from alalek:videoio_drop_rectification_dc1394 2018-10-10 20:01:06 +00:00
Alexander Alekhin f731515628 cmake: fix Python detection for standalone bindings 2018-10-10 22:59:42 +03:00
Alexander Alekhin 4e62900009 core: call omp_set_dynamic() for better CPU usage
Similar to 'OMP_DYNAMIC=TRUE'.
2018-10-10 19:57:43 +00:00
Alexander Alekhin 7813eef92b fix build warnings 2018-10-10 19:26:19 +00:00
Suleyman TURKMEN 59bf2a34fa Update videoio 2018-10-10 21:58:04 +03:00
Suleyman TURKMEN abbb73e894 Update HOGDescriptor 2018-10-10 21:53:35 +03:00
Vitaly Tuzov cc10e6b344 pyrDown and pyrUp SSE2 implementations replaced with wide universal intrinsics implementations 2018-10-10 21:12:47 +03:00
Alexander Alekhin 11e2a216c5 ocl(win32): bypass deallocate() during process termination 2018-10-10 18:06:06 +00:00
Alexander Alekhin 404893810c cmake: fix Python detection for standalone bindings 2018-10-10 16:58:23 +00:00
Alexander Nesterov 53ec8f286b Added QR code decoding. 2018-10-10 15:27:00 +00:00
Alexander Alekhin 70f2ee917e cmake: add DllMain() into each OpenCV DLL
to detect process termination after ExitProcess() call
2018-10-10 11:00:59 +00:00
Alexander Alekhin ad93ed720d Merge pull request #12788 from alalek:samples_winpack_support_buildtools 2018-10-10 09:18:32 +00:00
Adam Radomski cc3ec5d453 Fix dnn caffe importer extract blobs from reused layers 2018-10-10 10:44:56 +02:00
Alexander Alekhin 288251e672 samples: add search for MSVS 2017 BuildTools 2018-10-10 00:34:34 +00:00
Alexander Alekhin dada5a422d Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-10-09 21:20:15 +00:00
Alexander Alekhin 421fdc0e94 Merge pull request #12636 from alalek:winpack_samples_cpp_build_script
* samples: add winpack "drap & drop" build script

* samples: add search for MSVS 2017 Enterprise
2018-10-09 19:01:29 +03:00
Hamdi Sahloul c4d434fd6f CUDA/BgSegm: fix the threshold of MOG2.Update test when detectShadow=true (#12762) 2018-10-09 17:39:39 +03:00
Alexander Alekhin 8bb3d363a4 videoio: drop rectification code for VIDERE cameras 2018-10-09 14:06:15 +00:00
Apoorv Goel b8aa0cddab Merge pull request #12777 from UnderscoreAsterisk:document-cvtColorTwoPlane
* Add documentation for cvtColorTwoPlane

* Change brief and add links
2018-10-09 15:49:17 +03:00
Lubov Batanina 50811e04f2 Merge pull request #12596 from l-bat:l-bat/shufflenet_onnx
* Add Shufflenet support in ONNX

* Add test for transpose layer
2018-10-08 22:18:41 +03:00
Alexander Alekhin 449826288b Merge pull request #12765 from cv3d:ts/cuda/device_name 2018-10-08 19:15:54 +00:00
Alexander Alekhin 1522722fab Merge pull request #12728 from alalek:calib3d_move_undistort 2018-10-08 15:34:30 +00:00
Alexander Alekhin 68fe37b008 Merge pull request #12755 from alalek:fix_allocSingleton 2018-10-08 15:30:17 +00:00
Alexander Alekhin 26ba4f3c1d Merge pull request #12754 from alalek:dnn_ocl4dnn_async_expressions 2018-10-08 15:22:24 +00:00
Alexander Alekhin e19b422854 Merge pull request #12752 from alalek:dnn_cleanup_getUMat 2018-10-08 15:21:50 +00:00
Alexander Alekhin 913c4151bf Merge pull request #12725 from alalek:cmake_python_win32
* cmake: don't ignore Python from PATH environment variable

- this breaks selection between 32/64-bit Python
- this breaks Anaconda/Conda environments
- it is not the CMake default behavior, expected by many projects

* cmake: add Python version check, fallback path on CMake 3.12+

* cmake: drop Python 2.6, allow version selection for Python 3.x
2018-10-08 17:45:50 +03:00
Alexander Alekhin 78a802baae Merge pull request #12767 from dkurt:fix_js_features2d 2018-10-08 14:36:32 +00:00
Vitaly Tuzov 9d602f2752 Replaced SSE2 area resize implementation with wide universal intrinsic implementation 2018-10-08 16:27:52 +03:00
Dmitry Kurtaev 7649e537b7 Fix JavaScript bindings for features2d module 2018-10-07 22:55:38 +03:00
Hamdi Sahloul 2faa4cd933 TS/CUDA: Show device ID in case of multiple devices 2018-10-08 03:00:25 +09:00
Alexander Alekhin 0492301e76 Merge pull request #12753 from mshabunin:fix-ffmpeg-dl 2018-10-05 16:03:34 +00:00
Alexander Alekhin 18bf91a08b core: update allocSingleton implementation, valgrind suppression 2018-10-05 18:25:13 +03:00
Maksim Shabunin 09ef4c9cff FFmpeg: correct licenses install location 2018-10-05 17:10:42 +03:00
Alexander Alekhin 634dd656d5 dnn: don't use Mat expressions with async UMat functions 2018-10-05 17:09:50 +03:00
Alexander Alekhin 9d02d42afe dnn(ocl4dnn): don't use getUMat()
especially in CPU only processing
2018-10-05 15:24:51 +03:00
Alexander Alekhin c716e374c1 Merge pull request #12744 from alalek:issue_12736 2018-10-05 10:20:13 +00:00
Alexander Alekhin aeec6e43eb Merge pull request #12749 from powderluv:fix-clang-cl-tzcnt 2018-10-05 09:28:07 +00:00
Alexander Alekhin 8f1f4273a2 calib3d: move undistort files from imgproc 2018-10-05 07:52:21 +00:00
Anush Elangovan 630a94b8b7 _tzcnt_u32() is undefined in clang-cl so use alternate impl
_tzcnt_u32() is not exported by clang-cl intrin.h so check for
clang-cl and enable an alterate for _tzcnt_u32()

Some discussions:
http://lists.llvm.org/pipermail/cfe-dev/2016-October/051329.html
https://bugs.llvm.org/show_bug.cgi?id=30506

TEST=Build with clang-cl
2018-10-04 14:04:22 -07:00
Alexander Alekhin ceca139f7f Merge pull request #12745 from savuor:fix/ocl_arg_local_size 2018-10-04 16:42:16 +00:00
Rostislav Vasilikhin da5e0ef461 ocl::KernelArg::Local(): added size argument 2018-10-04 17:19:09 +03:00
Alexander Alekhin 4fa6734320 Merge pull request #12741 from GeorgeMironov:fix-cmake-protobuf 2018-10-04 14:17:22 +00:00
Alexander Alekhin a9c8a526cf Merge pull request #12695 from sam09:master 2018-10-04 12:53:37 +00:00
Alexander Alekhin 0926a84a45 cmake: define CV_ErrorNoReturn under CV_STATIC_ANALYSIS
to avoid build break without `__OPENCV_BUILD`
2018-10-04 14:43:43 +03:00
Alexander Alekhin 0101fa789c Merge pull request #12735 from tomoaki0705:fixCudaStereoTestFailure 2018-10-04 11:33:34 +00:00
Alexander Alekhin 12b3d157a5 Merge pull request #12726 from alalek:dnn_ocl_conv_avoid_multiple_expr_evaluation 2018-10-04 11:31:47 +00:00
Georgy Mironov 60c26f8f1e Fix install with external protobuf 2018-10-04 13:48:59 +03:00
Tomoaki Teshima 7294ae0f17 fix test failure of StereoBeliefPropagation
* if the src has odd number of height, access error happens
  * it could happen on width, too
  * check both dst and src range in both width and height
2018-10-04 08:35:34 +09:00
Apoorv Goel 0ffc186680 Merge pull request #12731 from UnderscoreAsterisk:fix-12012
* fix #12012

* Replace CV_StsBadFlag with Error::StsBadFlag
2018-10-03 15:50:04 +03:00
Sam Radhakrishnan 699db77293 Fixes #12692: Update samples/gpu/videoreader.cpp
Change iteration to iterate separately when the video is decode on a GPU to account for different number of frames
2018-10-03 17:42:57 +05:30
Alexander Alekhin 50beef605b Merge pull request #12727 from rnk:fix-clang-cl-cmake 2018-10-03 07:21:06 +00:00
Alexander Alekhin 068ebe8b4d Merge pull request #12693 from peters:patch-1 2018-10-03 06:14:44 +00:00
Reid Kleckner ffaf58349c Fix CMake for clang-cl
Avoids passing -Wall, which will enable literally every warning in
Clang. Avoids passing -ffunction-sections etc to clang-cl, which each
generate warnings.
2018-10-02 14:55:26 -07:00
Alexander Alekhin eec468fa13 dnn(ocl4dnn): calculate activation expression once
- to avoid multiple conditional calls via sub_group() functions
2018-10-02 21:23:41 +00:00
Alexander Alekhin 81c94357e8 Merge pull request #12722 from tomoaki0705:fixCudaFiltersFailure 2018-10-02 20:52:34 +00:00
Peter Rekdal Sunde 042c486b68 Obtain fourcc when AVStream is network stream
The `codec_tag` is only available when opening a file from disk. If `AVStream` is a network stream then `fourcc` must be obtained using `codec_id`. I have tested the following scenarios:
1) Open a `.mp4` file and verify that `codec_tag` is returned (old behavior)
2) Open a `rtsp` stream and verify that `codec_fourcc` is returned (Tested with a MJPEG, H264 and H265 stream)
2018-10-02 22:15:05 +02:00
Alexander Alekhin 6921f967a1 Merge pull request #12605 from terfendail:integral_wintr 2018-10-02 16:40:13 +00:00
Alexander Alekhin 83a0c12144 Merge pull request #12581 from terfendail:lapack_intr 2018-10-02 16:39:50 +00:00
Tomoaki Teshima fa8684b5c8 fix test failure of cudafilters Median_Accuracy
* avoid race condition
2018-10-03 00:59:08 +09:00
Alexander Alekhin 690fb0544c Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-10-02 14:31:05 +03:00
Vitaly Tuzov 283348afc3 SSE2 code in invert() replaced with universal intrinsics 2018-10-02 12:47:07 +03:00
Suleyman TURKMEN ee0c985491 Merge pull request #12649 from sturkmen72:patch-9
Update hog.cpp (#12649)
2018-10-01 22:22:37 +03:00
Alexander Alekhin b41f38ecc7 Merge pull request #12669 from mshabunin:add-paths-config 2018-10-01 15:57:57 +00:00
Alexander Alekhin 682180e0cd Merge pull request #12620 from alalek:ocl_extra_build_options 2018-10-01 15:57:31 +00:00
Alexander Alekhin 1385db48f5 Merge pull request #12711 from alalek:dnn_ocl_idlf_drop_weights_buf 2018-10-01 15:36:49 +00:00
Alexander Alekhin 94201b7cf9 ocl: OPENCV_OPENCL_BUILD_EXTRA_OPTIONS parameter 2018-10-01 17:56:17 +03:00
Maksim Shabunin 15632c6305 Added support for multi-path configuration parameter (env) 2018-10-01 17:50:47 +03:00
Vitaly Tuzov 6b84990620 integral() implementation updated to utilize wide universal intrinsics 2018-10-01 17:25:43 +03:00
Alexander Alekhin c9b6b2cf04 Merge pull request #12714 from antonioborondo:fix_documentation_cuda_compare 2018-10-01 13:35:03 +00:00
Alexander Alekhin 617fe2545c Merge pull request #12709 from WydD:3.4 2018-10-01 13:32:51 +00:00
Alexander Alekhin 93663dc57a Merge pull request #12708 from ldevulder:protobuf-fix-compilation-issue-on-s390 2018-10-01 13:32:29 +00:00
Antonio Borondo 28e55dc5f3 Fix documentation of cv::cuda::compare 2018-10-01 13:23:18 +01:00
Alexander Alekhin ae4c72a153 Merge pull request #12668 from alalek:calib3d_chessboardsb_updates 2018-10-01 00:00:01 +03:00
Alexander Alekhin 9253e8bda2 Merge pull request #12705 from berak:imread_document_grayscale 2018-09-30 23:59:48 +03:00
Alexander Alekhin 0f031b6680 dnn(ocl4dnn): drop weights_buf
- avoid memory access violation during "prefetch" stage
2018-09-30 20:35:41 +00:00
Loic Petit 255b20f6de Fix frame rate rounding in ffmpeg wrapper (#9023) 2018-09-30 22:24:02 +02:00
Loic Devulder ac9ec55b37 3rdparty/protobuf: fix compilation issue on s390
This commit fixes an issue while trying to compile
on s390x architecture.

This is simply a backport of a fixe already applied
in official protobuf code:
- https://github.com/protocolbuffers/protobuf/pull/3955
2018-09-30 21:33:34 +02:00
berak df4139d373 document imread grayscale behaviour 2018-09-30 15:22:26 +02:00
Hamdi Sahloul 1059735bfb Merge pull request #12667 from cv3d:fix/ts_report
TS: fix Python v2/v3 compatibility (#12667)

* TS: fix Python2.7 compatibility

* TS: fix Python3 compatibility

* py3: use integer division '/' => '//' instead of cast
2018-09-29 20:03:54 +03:00
Alexander Alekhin 8f2eb60719 Merge pull request #12690 from cv3d:fix/ts_python_exe 2018-09-29 16:39:05 +00:00
Alexander Alekhin a1ffc00ba8 Merge pull request #12666 from tomoaki0705:cudevTestFailureLuvRGB 2018-09-29 16:36:25 +00:00
Hamdi Sahloul 1a81a97e9f Utilize the currently running Python executable
especially if it matches the module being tested
2018-09-29 23:58:27 +09:00
Tomoaki Teshima e6ef9221cb fix test failure of cudev
* follow the implementation of Luv2RGBfloat in imgproc/src/color_lab.cpp
  * loosen threshold in cudaimgproc
2018-09-29 23:13:12 +09:00
Alexander Alekhin ee84ae0551 Merge pull request #12682 from soonbro:patch-1 2018-09-29 16:03:38 +03:00
Alexander Alekhin bd04568baf Merge pull request #12676 from PWhiddy:patch-1 2018-09-29 16:02:33 +03:00
Alexander Alekhin ea92c2b1a6 Merge pull request #12663 from sturkmen72:patch-12 2018-09-29 12:52:27 +00:00
Alexander Alekhin 8ecdd215b6 Merge pull request #12661 from Slyce-Inc:fix-xcode10-bitcode 2018-09-29 12:50:51 +00:00
Alexander Alekhin 5a3bca8d5c Merge pull request #12576 from cv3d:fix/cuda/polar_to_cart 2018-09-29 12:45:47 +00:00
soonbro 9b9f38afc8 fix typo in FpsMeter.java
'mFramesCouner' -> 'mFramesCounter'
2018-09-29 11:36:47 +00:00
Alexander Alekhin 9ac7aea930 Merge pull request #12653 from cv3d:cuda/legacy_traits 2018-09-28 19:21:04 +00:00
Hamdi Sahloul 5f17cc1abd Fix Python wrapper for GpuMat 2018-09-29 02:47:59 +09:00
Alexander Alekhin 8f6695acc7 CUDA: drop OPENCV_TRAITS_ENABLE_DEPRECATED requirement 2018-09-29 02:47:59 +09:00
chacha21 9524abcd28 Merge pull request #12658 from chacha21:clr-mutex
* hide use of std::mutex from /clr compilation under Visual Studio

C++11 <mutex> is not available when compiling with  /clr under Visual Studio, thus opencv cannot be easily included.
It is fixed by making a CEEMutex wrapper class, around an opaque implementation using std::mutex internally

* fixed compilation outside of Visual Studio

fixed compilation outside of Visual Studio by avoiding some macros

* fixed indentation, prepare getting rid of CEEMutex/CEELockGuard

fixed indentation
After discussion, CEEMutex and CEELockGuard can be totally removed, letting the developer in a /clr context to provide his own implementation

* remove CEEMutex/CEELockGuard
2018-09-28 19:19:05 +03:00
Alexander Alekhin 4fea6179a0 Merge pull request #12659 from dkurt:js_features2d 2018-09-28 16:18:09 +00:00
Alexander Alekhin 055f177a6a Merge pull request #12630 from alalek:docs_blacklist_matlab 2018-09-28 16:15:19 +00:00
Alexander Alekhin 83efde6243 Merge pull request #12678 from cv3d:cleanup/python/enums 2018-09-28 16:07:21 +00:00
Suleyman TURKMEN 8eb987e393 Update findContours parameter type 2018-09-28 18:42:48 +03:00
Dmitry Matveev 2c6ab65476 Merge pull request #12674 from dmatveev:gapi_upd270918
* Update G-API code base to 27-Sep-18

Changes mostly improve standalone build support

* G-API code base update 28-09-2018

* Windows/Documentation warnings should be fixed
* Fixed stability issues in Fluid backend
* Fixed precompiled headers issues in G-API source files

* G-API code base update 28-09-18 EOD

* Fixed several static analysis issues
* Fixed issues found when G-API is built in a standalone mode
2018-09-28 18:42:09 +03:00
Alexander Alekhin 66fdddc339 Merge pull request #12656 from alalek:fix_documentation_build 2018-09-28 14:16:25 +00:00
Andrew Mroczkowski 3c5a6be835 Fix Xcode version parsing error (affects bitcode generation)
The regex was only parsing for a single digit in the major version, causing Xcode 10 to be treated as version "1". Other parts of the script only turn on bitcode generation if the Xcode version is > 7.
2018-09-28 17:01:40 +03:00
Alexander Alekhin 5575171652 Merge pull request #12673 from alalek:fix_build_warnings
* fix build warnings

* python: forbid wrapping of functions with "void*" arguments
2018-09-28 16:53:05 +03:00
Alexander Alekhin a8b0db4e5d Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-09-28 14:14:47 +03:00
Alexander Alekhin 4b895a4d1f Merge pull request #12657 from alalek:docs_repair_cuda_section 2018-09-28 09:45:50 +00:00
Dmitry Kurtaev e9f99063c7 JavaScript bindings for features2d module 2018-09-28 11:04:13 +03:00
Hamdi Sahloul e104fcc000 Generate enum bindings automatically 2018-09-28 15:39:51 +09:00
Peter Whidden 9f0ff03da5 Fix typo "wit" -> "with" 2018-09-27 14:37:59 -07:00
Alexander Alekhin 9ba659af84 Merge pull request #12660 from alalek:flann_drop_useless_mutex 2018-09-27 19:46:59 +00:00
Rostislav Vasilikhin be989b3b60 Merge pull request #12637 from savuor:fix/instr_ipp_ocl
Fixes for instrumentation of IPP and OCL (#12637)

* fixed warning about re-declaring variable when both IPP and instrumentation are enabled

* fixed segfault when no funName provided

* compilation fixed when both OCL and instrumentation are enabled
2018-09-27 22:39:06 +03:00
Alexander Alekhin 0706bd72b8 Merge pull request #12671 from alalek:fix_build_warnings_3.4 2018-09-27 16:23:05 +00:00
Alexander Alekhin f6dc396a0f Merge pull request #12568 from sturkmen72:patch-3 2018-09-27 13:42:44 +00:00
Alexander Alekhin 48e8e76a34 fix build warnings 2018-09-27 16:31:31 +03:00
Alexander Alekhin e4f71994c2 calib3d: findChessboardCornersSB() minor updates
- avoid updating of input image during equalizeHist() call
- avoid for() with double variable (use 'int' instead)
- more CV_Check*() macros
- use Mat_<T>, Matx
- static for local variables
2018-09-27 15:38:01 +03:00
Alexander Alekhin fae329a0ca Merge pull request #12650 from alalek:dnn_ocl4dnn_verification_test
* dnn(ocl4dnn): update kernel checks

* dnn: workaround for IDLF kernels on Intel iGPU

* dnn(test): remove "skip" check for unstable cases
2018-09-27 12:54:23 +03:00
Dmitry Matveev 29e88e50ff Merge pull request #12608 from dmatveev:gapi
* G-API Initial code upload

* Update G-API code base to Sep-24-2018

* The majority of OpenCV buildbot problems was addressed

* Update G-API code base to 24-Sep-18 EOD

* G-API code base update 25-Sep-2018

* Linux warnings should be resolved
* Documentation build should become green
* Number of Windows warnings should be reduced

* Update G-API code base to 25-Sep-18 EOD

* ARMv7 build issue should be resolved
* ADE is bumped to latest version and should fix Clang builds for macOS/iOS
* Remaining Windows warnings should be resolved
* New Linux32 / ARMv7 warnings should be resolved

* G-API code base update 25-Sep-2018-EOD2

* Final Windows warnings should be resolved now

* G-API code base update 26-Sep-2018

* Fixed issues with precompiled headers in module and its tests
2018-09-26 21:50:39 +03:00
Alexander Alekhin 52f52f6786 flann: drop useless mutex 2018-09-26 19:37:44 +03:00
Alexander Alekhin 852f061b26 Merge pull request #12655 from alalek:fix_printf_format_warning 2018-09-26 16:21:07 +00:00
Alexander Alekhin fe56bdeeb9 Merge pull request #12647 from alalek:cmake_js_cleanup
* cmake: js cleanup

- avoid unnecessary 2 messages for other platforms
- drop MODULE_NAME variable

* js: cleanup build_js.py
2018-09-26 18:53:02 +03:00
Vadim Pisarevsky b34d86ca24 Merge pull request #12548 from alalek:videoio_backend_name 2018-09-26 15:19:55 +00:00
Dmitry Kurtaev 24ab751547 Merge pull request #12565 from dkurt:dnn_non_intel_gpu
* Remove isIntel check from deep learning layers

* Remove fp16->fp32 fallbacks where it's not necessary

* Fix Kernel::run to prevent localsize > globalsize
2018-09-26 16:27:00 +03:00
Dmitry Kurtaev c8f3579f93 Fix #12542 (#12603)
* Fix #12542

* Remove ignore of non-virtual-dtor error
2018-09-26 16:08:51 +03:00
Menghui Xie f0d277e452 M_PI changed to CV_PI (#12645)
* M_PI changed to CV_PI

* M_PI changed to CV_PI

* M_PI changed to CV_PI
2018-09-26 16:05:02 +03:00
Alexander Alekhin 962dc21f2b docs: fix CUDA docs section 2018-09-26 15:36:55 +03:00
Alexander Alekhin 2e8483bd1c docs: fix build without opencv_contrib (avoid links to CUDA modules) 2018-09-26 15:24:52 +03:00
Alexander Alekhin 3eec8fd0eb dnn: fix printf format warning 2018-09-26 14:06:04 +03:00
Alexander Alekhin 43e66e7ff9 Merge pull request #12644 from dkurt:dnn_out_layers_names 2018-09-25 16:12:59 +00:00
Dmitry Kurtaev ad5898224d Add a file with preprocessing parameters for deep learning networks 2018-09-25 18:28:37 +03:00
Dmitry Kurtaev f8398d80bc add Net::getUnconnectedOutLayersNames method 2018-09-25 18:10:45 +03:00
Alexander Alekhin d8d025c33b Merge pull request #12599 from mshabunin:printf 2018-09-25 14:44:21 +00:00
Alexander Duda 8811dabbac Merge pull request #12615 from D-Alex:master
findChessboardCornersSB: speed improvements (#12615)

* chessboard: fix do not modify const image

* chessboard: speed up scale space using parallel_for

* chessboard: small improvements

* chessboard: speed up board growing using parallel_for

* chessboard: add flags for tuning detection

* chessboard: fix compiler warnings

* chessborad: change flag name to CALIB_CB_EXHAUSTIVE

This also fixes a typo

* chessboard: fix const ref + remove to_string
2018-09-25 17:06:46 +03:00
Alexander Alekhin 9faacfbc0d Merge pull request #12639 from tomoaki0705:fixFp16CudaFailure 2018-09-25 13:19:51 +00:00
Alexander Alekhin a610be6335 Merge pull request #12591 from sturkmen72:patch-6 2018-09-25 10:05:16 +00:00
Tomoaki Teshima 6a5266df79 fix CvFp16Test failure 2018-09-25 15:00:37 +09:00
Alexander Alekhin 238a3806b0 Merge pull request #12632 from mshabunin:move-opengl-sample 2018-09-24 17:53:11 +00:00
Alexander Alekhin a07a4cefe1 Merge pull request #12629 from cv3d:fix/opengl 2018-09-24 11:32:07 +00:00
Maksim Shabunin a0211a1c2f Moved OpenGL sample to opengl folder 2018-09-24 13:13:30 +03:00
Hamdi Sahloul 47bb09bc4b OpenGL: avoid losing precision in double-to-float conversion 2018-09-24 19:06:48 +09:00
Alexander Alekhin efca746d36 Merge pull request #12622 from cv3d:fix/js_property 2018-09-24 09:36:51 +00:00
Alexander Alekhin 93b0b03447 docs: DOXYGEN_BLACKLIST CMake variable for modules exclusion 2018-09-24 11:34:03 +03:00
Maksim Shabunin e0f524d3b7 Fixed several incorrect printf format specifiers 2018-09-24 11:31:40 +03:00
Pavel Rojtberg d1c842cf29 core: fix printf warnings by using c++11 format 2018-09-24 11:31:40 +03:00
Pavel Rojtberg 4d23a5d92d core: enable printf format warnings for cv::format 2018-09-24 11:31:40 +03:00
Hamdi Sahloul 0739d1c2eb JS: Support enum properties 2018-09-24 16:37:52 +09:00
Alexander Alekhin 475c775b25 Merge pull request #12621 from cv3d:fix/opengl 2018-09-23 20:00:53 +00:00
Hamdi Sahloul b7e8ce4523 fix a bug in OpenGL 2018-09-23 23:07:28 +09:00
Alexander Alekhin 0a23c1bf11 Merge pull request #12614 from alalek:winpack_samples_python_launcher_update 2018-09-23 13:37:36 +00:00
Alexander Alekhin e8fcd721b8 Merge pull request #12612 from alalek:winpack_samples_python_launcher_update 2018-09-22 20:44:46 +00:00
Alexander Alekhin ecef7f7930 samples: update winpack python samples launcher
- accepts script parameter (allows drag & drop from 'explorer')
- use script dir instead of current dir (can launch samples from 'samples/dnn')
- added 'pause' to show error messages (about missing numpy) instead of instant closing
2018-09-22 17:28:58 +00:00
Hamdi Sahloul 5db13fe2a7 cuda::polarToCart: update documentation 2018-09-22 07:02:43 +09:00
Hamdi Sahloul 9932612373 cuda::polarToCart: test double precision and tune tolerance 2018-09-22 07:02:43 +09:00
Hamdi Sahloul 6203c95d31 cuda::polarToCart: Support double precision 2018-09-22 07:02:43 +09:00
Alexander Alekhin d5d19a9f67 Merge pull request #12592 from alalek:dnn_test_at_least_one 2018-09-21 16:49:51 +00:00
Hamdi Sahloul ef5579dc86 Merge pull request #12310 from cv3d:chunks/enum_interface
* Cleanup macros and enable expansion of `__VA_ARGS__` for Visual Studio

* Macros for enum-arguments backwards compatibility

* Convert struct Param to enum struct

* Enabled ParamType.type for enum types

* Enabled `cv.read` and `cv.write` for enum types

* Rename unnamed enum to AAKAZE.DescriptorType

* Rename unnamed enum to AccessFlag

* Rename unnamed enum to AgastFeatureDetector.DetectorType

* Convert struct DrawMatchesFlags to enum struct

* Rename unnamed enum to FastFeatureDetector.DetectorType

* Rename unnamed enum to Formatter.FormatType

* Rename unnamed enum to HOGDescriptor.HistogramNormType

* Rename unnamed enum to DescriptorMatcher.MatcherType

* Rename unnamed enum to KAZE.DiffusivityType

* Rename unnamed enum to ORB.ScoreType

* Rename unnamed enum to UMatData.MemoryFlag

* Rename unnamed enum to _InputArray.KindFlag

* Rename unnamed enum to _OutputArray.DepthMask

* Convert normType enums to static const NormTypes

* Avoid conflicts with ElemType

* Rename unnamed enum to DescriptorStorageFormat
2018-09-21 18:12:35 +03:00
Hamdi Sahloul 84ae8097b1 Merge pull request #12601 from cv3d:fix/js
* JS: Support enum types in constructors

* JS: Avoid unary expression on enum-based consts
2018-09-21 18:11:46 +03:00
Alexander Alekhin f33f236ab6 Merge pull request #12598 from cv3d:cmake/js 2018-09-21 14:59:27 +00:00
Hamdi Sahloul 95b1fe0776 JS: Provides meaningful message in case of compile issues 2018-09-21 04:02:34 +09:00
Hamdi Sahloul 35bee663eb JS: Improves Emscripten detection 2018-09-21 04:02:34 +09:00
Suleyman TURKMEN 98f6ea0785 Update hog.cpp 2018-09-20 13:45:01 +03:00
Alexander Alekhin 295b988657 Merge tag '4.0.0-alpha' 2018-09-19 20:47:17 +00:00
Alexander Alekhin e0a5824028 dnn(test): test at least CPU code path 2018-09-19 13:56:59 +03:00
Alexander Alekhin d3eed2cf23 videoio: CAP_PROP_BACKEND property interface 2018-09-18 16:25:01 +00:00
Alexander Alekhin 51f7eb3a3c videoio(test): add "camera" tests
- disabled due specific requirements (camera, OpenNI camera, etc)
- designed for manual validation
2018-09-18 16:19:19 +00:00
Alexander Alekhin b35fbff675 videoio: added '.getBackendName()' method 2018-09-18 16:19:19 +00:00
Suleyman TURKMEN 30597e5c98 Update seamless_cloning.cpp 2018-09-18 07:22:39 +03:00
465 changed files with 46136 additions and 6681 deletions
+22 -36
View File
@@ -151,6 +151,10 @@ void div(const Size2D &size,
typedef typename internal::VecTraits<T>::vec128 vec128;
typedef typename internal::VecTraits<T>::vec64 vec64;
#if defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
static_assert(std::numeric_limits<T>::is_integer, "template implementation is for integer types only");
#endif
if (scale == 0.0f ||
(std::numeric_limits<T>::is_integer &&
(scale * std::numeric_limits<T>::max()) < 1.0f &&
@@ -311,6 +315,10 @@ void recip(const Size2D &size,
typedef typename internal::VecTraits<T>::vec128 vec128;
typedef typename internal::VecTraits<T>::vec64 vec64;
#if defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
static_assert(std::numeric_limits<T>::is_integer, "template implementation is for integer types only");
#endif
if (scale == 0.0f ||
(std::numeric_limits<T>::is_integer &&
scale < 1.0f &&
@@ -463,8 +471,6 @@ void div(const Size2D &size,
return;
}
float32x4_t v_zero = vdupq_n_f32(0.0f);
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
@@ -485,9 +491,7 @@ void div(const Size2D &size,
float32x4_t v_src0 = vld1q_f32(src0 + j);
float32x4_t v_src1 = vld1q_f32(src1 + j);
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
vreinterpretq_u32_f32(vmulq_f32(v_src0, internal::vrecpq_f32(v_src1))), v_mask)));
vst1q_f32(dst + j, vmulq_f32(v_src0, internal::vrecpq_f32(v_src1)));
}
for (; j < roiw64; j += 2)
@@ -495,14 +499,12 @@ void div(const Size2D &size,
float32x2_t v_src0 = vld1_f32(src0 + j);
float32x2_t v_src1 = vld1_f32(src1 + j);
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
vreinterpret_u32_f32(vmul_f32(v_src0, internal::vrecp_f32(v_src1))), v_mask)));
vst1_f32(dst + j, vmul_f32(v_src0, internal::vrecp_f32(v_src1)));
}
for (; j < size.width; j++)
{
dst[j] = src1[j] ? src0[j] / src1[j] : 0.0f;
dst[j] = src0[j] / src1[j];
}
}
}
@@ -523,10 +525,8 @@ void div(const Size2D &size,
float32x4_t v_src0 = vld1q_f32(src0 + j);
float32x4_t v_src1 = vld1q_f32(src1 + j);
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
vreinterpretq_u32_f32(vmulq_f32(vmulq_n_f32(v_src0, scale),
internal::vrecpq_f32(v_src1))), v_mask)));
vst1q_f32(dst + j, vmulq_f32(vmulq_n_f32(v_src0, scale),
internal::vrecpq_f32(v_src1)));
}
for (; j < roiw64; j += 2)
@@ -534,15 +534,13 @@ void div(const Size2D &size,
float32x2_t v_src0 = vld1_f32(src0 + j);
float32x2_t v_src1 = vld1_f32(src1 + j);
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
vreinterpret_u32_f32(vmul_f32(vmul_n_f32(v_src0, scale),
internal::vrecp_f32(v_src1))), v_mask)));
vst1_f32(dst + j, vmul_f32(vmul_n_f32(v_src0, scale),
internal::vrecp_f32(v_src1)));
}
for (; j < size.width; j++)
{
dst[j] = src1[j] ? src0[j] * scale / src1[j] : 0.0f;
dst[j] = src0[j] * scale / src1[j];
}
}
}
@@ -620,8 +618,6 @@ void reciprocal(const Size2D &size,
return;
}
float32x4_t v_zero = vdupq_n_f32(0.0f);
size_t roiw128 = size.width >= 3 ? size.width - 3 : 0;
size_t roiw64 = size.width >= 1 ? size.width - 1 : 0;
@@ -639,23 +635,19 @@ void reciprocal(const Size2D &size,
float32x4_t v_src1 = vld1q_f32(src1 + j);
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
vreinterpretq_u32_f32(internal::vrecpq_f32(v_src1)), v_mask)));
vst1q_f32(dst + j, internal::vrecpq_f32(v_src1));
}
for (; j < roiw64; j += 2)
{
float32x2_t v_src1 = vld1_f32(src1 + j);
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
vreinterpret_u32_f32(internal::vrecp_f32(v_src1)), v_mask)));
vst1_f32(dst + j, internal::vrecp_f32(v_src1));
}
for (; j < size.width; j++)
{
dst[j] = src1[j] ? 1.0f / src1[j] : 0;
dst[j] = 1.0f / src1[j];
}
}
}
@@ -673,25 +665,19 @@ void reciprocal(const Size2D &size,
float32x4_t v_src1 = vld1q_f32(src1 + j);
uint32x4_t v_mask = vceqq_f32(v_src1,v_zero);
vst1q_f32(dst + j, vreinterpretq_f32_u32(vbicq_u32(
vreinterpretq_u32_f32(vmulq_n_f32(internal::vrecpq_f32(v_src1),
scale)),v_mask)));
vst1q_f32(dst + j, vmulq_n_f32(internal::vrecpq_f32(v_src1), scale));
}
for (; j < roiw64; j += 2)
{
float32x2_t v_src1 = vld1_f32(src1 + j);
uint32x2_t v_mask = vceq_f32(v_src1,vget_low_f32(v_zero));
vst1_f32(dst + j, vreinterpret_f32_u32(vbic_u32(
vreinterpret_u32_f32(vmul_n_f32(internal::vrecp_f32(v_src1),
scale)), v_mask)));
vst1_f32(dst + j, vmul_n_f32(internal::vrecp_f32(v_src1), scale));
}
for (; j < size.width; j++)
{
dst[j] = src1[j] ? scale / src1[j] : 0;
dst[j] = scale / src1[j];
}
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ $output = "$PSScriptRoot\@OPENCV_BIN_INSTALL_PATH@\opencv_ffmpeg@OPENCV_DLLVERSI
Write-Output ("=" * 120)
try {
Get-content -Path "$PSScriptRoot\etc\licenses\ffmpeg-readme.txt" -ErrorAction 'Stop'
Get-content -Path "$PSScriptRoot\@OPENCV_LICENSES_INSTALL_PATH@\ffmpeg-readme.txt" -ErrorAction 'Stop'
} catch {
Write-Output "Refer to OpenCV FFmpeg wrapper readme notes about library usage / licensing details."
}
+2
View File
@@ -40,3 +40,5 @@ if(OPENCV_INSTALL_FFMPEG_DOWNLOAD_SCRIPT)
configure_file("${CMAKE_CURRENT_LIST_DIR}/ffmpeg-download.ps1.in" "${CMAKE_BINARY_DIR}/win-install/ffmpeg-download.ps1" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/win-install/ffmpeg-download.ps1" DESTINATION "." COMPONENT libs)
endif()
ocv_install_3rdparty_licenses(ffmpeg license.txt readme.txt)
@@ -146,6 +146,14 @@ inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
return __atomic_load_n(ptr, __ATOMIC_RELAXED);
}
inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
__atomic_compare_exchange_n(ptr, &old_value, new_value, false,
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
return old_value;
}
#endif // defined(__LP64__)
} // namespace internal
+30
View File
@@ -0,0 +1,30 @@
project(quirc)
set(CURR_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include")
set_property(GLOBAL PROPERTY QUIRC_INCLUDE_DIR ${CURR_INCLUDE_DIR})
ocv_include_directories(${CURR_INCLUDE_DIR})
file(GLOB_RECURSE quirc_headers RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "include/*.h")
file(GLOB_RECURSE quirc_sources RELATIVE "${CMAKE_CURRENT_LIST_DIR}" "src/*.c")
add_library(${PROJECT_NAME} STATIC ${quirc_headers} ${quirc_sources})
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-variable -Wshadow)
set_target_properties(${PROJECT_NAME}
PROPERTIES OUTPUT_NAME ${PROJECT_NAME}
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
COMPILE_PDB_NAME ${PROJECT_NAME}
COMPILE_PDB_NAME_DEBUG "${PROJECT_NAME}${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}
)
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${PROJECT_NAME} PROPERTIES FOLDER "3rdparty")
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${PROJECT_NAME} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
ocv_install_3rdparty_licenses(${PROJECT_NAME} LICENSE)
+16
View File
@@ -0,0 +1,16 @@
quirc -- QR-code recognition library
Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all
copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
+173
View File
@@ -0,0 +1,173 @@
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef QUIRC_H_
#define QUIRC_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct quirc;
/* Obtain the library version string. */
const char *quirc_version(void);
/* Construct a new QR-code recognizer. This function will return NULL
* if sufficient memory could not be allocated.
*/
struct quirc *quirc_new(void);
/* Destroy a QR-code recognizer. */
void quirc_destroy(struct quirc *q);
/* Resize the QR-code recognizer. The size of an image must be
* specified before codes can be analyzed.
*
* This function returns 0 on success, or -1 if sufficient memory could
* not be allocated.
*/
int quirc_resize(struct quirc *q, int w, int h);
/* These functions are used to process images for QR-code recognition.
* quirc_begin() must first be called to obtain access to a buffer into
* which the input image should be placed. Optionally, the current
* width and height may be returned.
*
* After filling the buffer, quirc_end() should be called to process
* the image for QR-code recognition. The locations and content of each
* code may be obtained using accessor functions described below.
*/
uint8_t *quirc_begin(struct quirc *q, int *w, int *h);
void quirc_end(struct quirc *q);
/* This structure describes a location in the input image buffer. */
struct quirc_point {
int x;
int y;
};
/* This enum describes the various decoder errors which may occur. */
typedef enum {
QUIRC_SUCCESS = 0,
QUIRC_ERROR_INVALID_GRID_SIZE,
QUIRC_ERROR_INVALID_VERSION,
QUIRC_ERROR_FORMAT_ECC,
QUIRC_ERROR_DATA_ECC,
QUIRC_ERROR_UNKNOWN_DATA_TYPE,
QUIRC_ERROR_DATA_OVERFLOW,
QUIRC_ERROR_DATA_UNDERFLOW
} quirc_decode_error_t;
/* Return a string error message for an error code. */
const char *quirc_strerror(quirc_decode_error_t err);
/* Limits on the maximum size of QR-codes and their content. */
#define QUIRC_MAX_BITMAP 3917
#define QUIRC_MAX_PAYLOAD 8896
/* QR-code ECC types. */
#define QUIRC_ECC_LEVEL_M 0
#define QUIRC_ECC_LEVEL_L 1
#define QUIRC_ECC_LEVEL_H 2
#define QUIRC_ECC_LEVEL_Q 3
/* QR-code data types. */
#define QUIRC_DATA_TYPE_NUMERIC 1
#define QUIRC_DATA_TYPE_ALPHA 2
#define QUIRC_DATA_TYPE_BYTE 4
#define QUIRC_DATA_TYPE_KANJI 8
/* Common character encodings */
#define QUIRC_ECI_ISO_8859_1 1
#define QUIRC_ECI_IBM437 2
#define QUIRC_ECI_ISO_8859_2 4
#define QUIRC_ECI_ISO_8859_3 5
#define QUIRC_ECI_ISO_8859_4 6
#define QUIRC_ECI_ISO_8859_5 7
#define QUIRC_ECI_ISO_8859_6 8
#define QUIRC_ECI_ISO_8859_7 9
#define QUIRC_ECI_ISO_8859_8 10
#define QUIRC_ECI_ISO_8859_9 11
#define QUIRC_ECI_WINDOWS_874 13
#define QUIRC_ECI_ISO_8859_13 15
#define QUIRC_ECI_ISO_8859_15 17
#define QUIRC_ECI_SHIFT_JIS 20
#define QUIRC_ECI_UTF_8 26
/* This structure is used to return information about detected QR codes
* in the input image.
*/
struct quirc_code {
/* The four corners of the QR-code, from top left, clockwise */
struct quirc_point corners[4];
/* The number of cells across in the QR-code. The cell bitmap
* is a bitmask giving the actual values of cells. If the cell
* at (x, y) is black, then the following bit is set:
*
* cell_bitmap[i >> 3] & (1 << (i & 7))
*
* where i = (y * size) + x.
*/
int size;
uint8_t cell_bitmap[QUIRC_MAX_BITMAP];
};
/* This structure holds the decoded QR-code data */
struct quirc_data {
/* Various parameters of the QR-code. These can mostly be
* ignored if you only care about the data.
*/
int version;
int ecc_level;
int mask;
/* This field is the highest-valued data type found in the QR
* code.
*/
int data_type;
/* Data payload. For the Kanji datatype, payload is encoded as
* Shift-JIS. For all other datatypes, payload is ASCII text.
*/
uint8_t payload[QUIRC_MAX_PAYLOAD];
int payload_len;
/* ECI assignment number */
uint32_t eci;
};
/* Return the number of QR-codes identified in the last processed
* image.
*/
int quirc_count(const struct quirc *q);
/* Extract the QR-code specified by the given index. */
void quirc_extract(const struct quirc *q, int index,
struct quirc_code *code);
/* Decode a QR-code, returning the payload data. */
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
struct quirc_data *data);
#ifdef __cplusplus
}
#endif
#endif
+115
View File
@@ -0,0 +1,115 @@
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef QUIRC_INTERNAL_H_
#define QUIRC_INTERNAL_H_
#include <quirc.h>
#define QUIRC_PIXEL_WHITE 0
#define QUIRC_PIXEL_BLACK 1
#define QUIRC_PIXEL_REGION 2
#ifndef QUIRC_MAX_REGIONS
#define QUIRC_MAX_REGIONS 254
#endif
#define QUIRC_MAX_CAPSTONES 32
#define QUIRC_MAX_GRIDS 8
#define QUIRC_PERSPECTIVE_PARAMS 8
#if QUIRC_MAX_REGIONS < UINT8_MAX
typedef uint8_t quirc_pixel_t;
#elif QUIRC_MAX_REGIONS < UINT16_MAX
typedef uint16_t quirc_pixel_t;
#else
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
#endif
struct quirc_region {
struct quirc_point seed;
int count;
int capstone;
};
struct quirc_capstone {
int ring;
int stone;
struct quirc_point corners[4];
struct quirc_point center;
double c[QUIRC_PERSPECTIVE_PARAMS];
int qr_grid;
};
struct quirc_grid {
/* Capstone indices */
int caps[3];
/* Alignment pattern region and corner */
int align_region;
struct quirc_point align;
/* Timing pattern endpoints */
struct quirc_point tpep[3];
int hscan;
int vscan;
/* Grid size and perspective transform */
int grid_size;
double c[QUIRC_PERSPECTIVE_PARAMS];
};
struct quirc {
uint8_t *image;
quirc_pixel_t *pixels;
int *row_average; /* used by threshold() */
int w;
int h;
int num_regions;
struct quirc_region regions[QUIRC_MAX_REGIONS];
int num_capstones;
struct quirc_capstone capstones[QUIRC_MAX_CAPSTONES];
int num_grids;
struct quirc_grid grids[QUIRC_MAX_GRIDS];
};
/************************************************************************
* QR-code version information database
*/
#define QUIRC_MAX_VERSION 40
#define QUIRC_MAX_ALIGNMENT 7
struct quirc_rs_params {
int bs; /* Small block size */
int dw; /* Small data words */
int ns; /* Number of small blocks */
};
struct quirc_version_info {
int data_bytes;
int apat[QUIRC_MAX_ALIGNMENT];
struct quirc_rs_params ecc[4];
};
extern const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1];
#endif
+919
View File
@@ -0,0 +1,919 @@
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <quirc_internal.h>
#include <string.h>
#include <stdlib.h>
#define MAX_POLY 64
/************************************************************************
* Galois fields
*/
struct galois_field {
int p;
const uint8_t *log;
const uint8_t *exp;
};
static const uint8_t gf16_exp[16] = {
0x01, 0x02, 0x04, 0x08, 0x03, 0x06, 0x0c, 0x0b,
0x05, 0x0a, 0x07, 0x0e, 0x0f, 0x0d, 0x09, 0x01
};
static const uint8_t gf16_log[16] = {
0x00, 0x0f, 0x01, 0x04, 0x02, 0x08, 0x05, 0x0a,
0x03, 0x0e, 0x09, 0x07, 0x06, 0x0d, 0x0b, 0x0c
};
static const struct galois_field gf16 = {
.p = 15,
.log = gf16_log,
.exp = gf16_exp
};
static const uint8_t gf256_exp[256] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01
};
static const uint8_t gf256_log[256] = {
0x00, 0xff, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf
};
static const struct galois_field gf256 = {
.p = 255,
.log = gf256_log,
.exp = gf256_exp
};
/************************************************************************
* Polynomial operations
*/
static void poly_add(uint8_t *dst, const uint8_t *src, uint8_t c,
int shift, const struct galois_field *gf)
{
int i;
int log_c = gf->log[c];
if (!c)
return;
for (i = 0; i < MAX_POLY; i++) {
int p = i + shift;
uint8_t v = src[i];
if (p < 0 || p >= MAX_POLY)
continue;
if (!v)
continue;
dst[p] ^= gf->exp[(gf->log[v] + log_c) % gf->p];
}
}
static uint8_t poly_eval(const uint8_t *s, uint8_t x,
const struct galois_field *gf)
{
int i;
uint8_t sum = 0;
uint8_t log_x = gf->log[x];
if (!x)
return s[0];
for (i = 0; i < MAX_POLY; i++) {
uint8_t c = s[i];
if (!c)
continue;
sum ^= gf->exp[(gf->log[c] + log_x * i) % gf->p];
}
return sum;
}
/************************************************************************
* Berlekamp-Massey algorithm for finding error locator polynomials.
*/
static void berlekamp_massey(const uint8_t *s, int N,
const struct galois_field *gf,
uint8_t *sigma)
{
uint8_t C[MAX_POLY];
uint8_t B[MAX_POLY];
int L = 0;
int m = 1;
uint8_t b = 1;
int n;
memset(B, 0, sizeof(B));
memset(C, 0, sizeof(C));
B[0] = 1;
C[0] = 1;
for (n = 0; n < N; n++) {
uint8_t d = s[n];
uint8_t mult;
int i;
for (i = 1; i <= L; i++) {
if (!(C[i] && s[n - i]))
continue;
d ^= gf->exp[(gf->log[C[i]] +
gf->log[s[n - i]]) %
gf->p];
}
mult = gf->exp[(gf->p - gf->log[b] + gf->log[d]) % gf->p];
if (!d) {
m++;
} else if (L * 2 <= n) {
uint8_t T[MAX_POLY];
memcpy(T, C, sizeof(T));
poly_add(C, B, mult, m, gf);
memcpy(B, T, sizeof(B));
L = n + 1 - L;
b = d;
m = 1;
} else {
poly_add(C, B, mult, m, gf);
m++;
}
}
memcpy(sigma, C, MAX_POLY);
}
/************************************************************************
* Code stream error correction
*
* Generator polynomial for GF(2^8) is x^8 + x^4 + x^3 + x^2 + 1
*/
static int block_syndromes(const uint8_t *data, int bs, int npar, uint8_t *s)
{
int nonzero = 0;
int i;
memset(s, 0, MAX_POLY);
for (i = 0; i < npar; i++) {
int j;
for (j = 0; j < bs; j++) {
uint8_t c = data[bs - j - 1];
if (!c)
continue;
s[i] ^= gf256_exp[((int)gf256_log[c] +
i * j) % 255];
}
if (s[i])
nonzero = 1;
}
return nonzero;
}
static void eloc_poly(uint8_t *omega,
const uint8_t *s, const uint8_t *sigma,
int npar)
{
int i;
memset(omega, 0, MAX_POLY);
for (i = 0; i < npar; i++) {
const uint8_t a = sigma[i];
const uint8_t log_a = gf256_log[a];
int j;
if (!a)
continue;
for (j = 0; j + 1 < MAX_POLY; j++) {
const uint8_t b = s[j + 1];
if (i + j >= npar)
break;
if (!b)
continue;
omega[i + j] ^=
gf256_exp[(log_a + gf256_log[b]) % 255];
}
}
}
static quirc_decode_error_t correct_block(uint8_t *data,
const struct quirc_rs_params *ecc)
{
int npar = ecc->bs - ecc->dw;
uint8_t s[MAX_POLY];
uint8_t sigma[MAX_POLY];
uint8_t sigma_deriv[MAX_POLY];
uint8_t omega[MAX_POLY];
int i;
/* Compute syndrome vector */
if (!block_syndromes(data, ecc->bs, npar, s))
return QUIRC_SUCCESS;
berlekamp_massey(s, npar, &gf256, sigma);
/* Compute derivative of sigma */
memset(sigma_deriv, 0, MAX_POLY);
for (i = 0; i + 1 < MAX_POLY; i += 2)
sigma_deriv[i] = sigma[i + 1];
/* Compute error evaluator polynomial */
eloc_poly(omega, s, sigma, npar - 1);
/* Find error locations and magnitudes */
for (i = 0; i < ecc->bs; i++) {
uint8_t xinv = gf256_exp[255 - i];
if (!poly_eval(sigma, xinv, &gf256)) {
uint8_t sd_x = poly_eval(sigma_deriv, xinv, &gf256);
uint8_t omega_x = poly_eval(omega, xinv, &gf256);
uint8_t error = gf256_exp[(255 - gf256_log[sd_x] +
gf256_log[omega_x]) % 255];
data[ecc->bs - i - 1] ^= error;
}
}
if (block_syndromes(data, ecc->bs, npar, s))
return QUIRC_ERROR_DATA_ECC;
return QUIRC_SUCCESS;
}
/************************************************************************
* Format value error correction
*
* Generator polynomial for GF(2^4) is x^4 + x + 1
*/
#define FORMAT_MAX_ERROR 3
#define FORMAT_SYNDROMES (FORMAT_MAX_ERROR * 2)
#define FORMAT_BITS 15
static int format_syndromes(uint16_t u, uint8_t *s)
{
int i;
int nonzero = 0;
memset(s, 0, MAX_POLY);
for (i = 0; i < FORMAT_SYNDROMES; i++) {
int j;
s[i] = 0;
for (j = 0; j < FORMAT_BITS; j++)
if (u & (1 << j))
s[i] ^= gf16_exp[((i + 1) * j) % 15];
if (s[i])
nonzero = 1;
}
return nonzero;
}
static quirc_decode_error_t correct_format(uint16_t *f_ret)
{
uint16_t u = *f_ret;
int i;
uint8_t s[MAX_POLY];
uint8_t sigma[MAX_POLY];
/* Evaluate U (received codeword) at each of alpha_1 .. alpha_6
* to get S_1 .. S_6 (but we index them from 0).
*/
if (!format_syndromes(u, s))
return QUIRC_SUCCESS;
berlekamp_massey(s, FORMAT_SYNDROMES, &gf16, sigma);
/* Now, find the roots of the polynomial */
for (i = 0; i < 15; i++)
if (!poly_eval(sigma, gf16_exp[15 - i], &gf16))
u ^= (1 << i);
if (format_syndromes(u, s))
return QUIRC_ERROR_FORMAT_ECC;
*f_ret = u;
return QUIRC_SUCCESS;
}
/************************************************************************
* Decoder algorithm
*/
struct datastream {
uint8_t raw[QUIRC_MAX_PAYLOAD];
int data_bits;
int ptr;
uint8_t data[QUIRC_MAX_PAYLOAD];
};
static inline int grid_bit(const struct quirc_code *code, int x, int y)
{
int p = y * code->size + x;
return (code->cell_bitmap[p >> 3] >> (p & 7)) & 1;
}
static quirc_decode_error_t read_format(const struct quirc_code *code,
struct quirc_data *data, int which)
{
int i;
uint16_t format = 0;
uint16_t fdata;
quirc_decode_error_t err;
if (which) {
for (i = 0; i < 7; i++)
format = (format << 1) |
grid_bit(code, 8, code->size - 1 - i);
for (i = 0; i < 8; i++)
format = (format << 1) |
grid_bit(code, code->size - 8 + i, 8);
} else {
static const int xs[15] = {
8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 4, 3, 2, 1, 0
};
static const int ys[15] = {
0, 1, 2, 3, 4, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8
};
for (i = 14; i >= 0; i--)
format = (format << 1) | grid_bit(code, xs[i], ys[i]);
}
format ^= 0x5412;
err = correct_format(&format);
if (err)
return err;
fdata = format >> 10;
data->ecc_level = fdata >> 3;
data->mask = fdata & 7;
return QUIRC_SUCCESS;
}
static int mask_bit(int mask, int i, int j)
{
switch (mask) {
case 0: return !((i + j) % 2);
case 1: return !(i % 2);
case 2: return !(j % 3);
case 3: return !((i + j) % 3);
case 4: return !(((i / 2) + (j / 3)) % 2);
case 5: return !((i * j) % 2 + (i * j) % 3);
case 6: return !(((i * j) % 2 + (i * j) % 3) % 2);
case 7: return !(((i * j) % 3 + (i + j) % 2) % 2);
}
return 0;
}
static int reserved_cell(int version, int i, int j)
{
const struct quirc_version_info *ver = &quirc_version_db[version];
int size = version * 4 + 17;
int ai = -1, aj = -1, a;
/* Finder + format: top left */
if (i < 9 && j < 9)
return 1;
/* Finder + format: bottom left */
if (i + 8 >= size && j < 9)
return 1;
/* Finder + format: top right */
if (i < 9 && j + 8 >= size)
return 1;
/* Exclude timing patterns */
if (i == 6 || j == 6)
return 1;
/* Exclude version info, if it exists. Version info sits adjacent to
* the top-right and bottom-left finders in three rows, bounded by
* the timing pattern.
*/
if (version >= 7) {
if (i < 6 && j + 11 >= size)
return 1;
if (i + 11 >= size && j < 6)
return 1;
}
/* Exclude alignment patterns */
for (a = 0; a < QUIRC_MAX_ALIGNMENT && ver->apat[a]; a++) {
int p = ver->apat[a];
if (abs(p - i) < 3)
ai = a;
if (abs(p - j) < 3)
aj = a;
}
if (ai >= 0 && aj >= 0) {
a--;
if (ai > 0 && ai < a)
return 1;
if (aj > 0 && aj < a)
return 1;
if (aj == a && ai == a)
return 1;
}
return 0;
}
static void read_bit(const struct quirc_code *code,
struct quirc_data *data,
struct datastream *ds, int i, int j)
{
int bitpos = ds->data_bits & 7;
int bytepos = ds->data_bits >> 3;
int v = grid_bit(code, j, i);
if (mask_bit(data->mask, i, j))
v ^= 1;
if (v)
ds->raw[bytepos] |= (0x80 >> bitpos);
ds->data_bits++;
}
static void read_data(const struct quirc_code *code,
struct quirc_data *data,
struct datastream *ds)
{
int y = code->size - 1;
int x = code->size - 1;
int dir = -1;
while (x > 0) {
if (x == 6)
x--;
if (!reserved_cell(data->version, y, x))
read_bit(code, data, ds, y, x);
if (!reserved_cell(data->version, y, x - 1))
read_bit(code, data, ds, y, x - 1);
y += dir;
if (y < 0 || y >= code->size) {
dir = -dir;
x -= 2;
y += dir;
}
}
}
static quirc_decode_error_t codestream_ecc(struct quirc_data *data,
struct datastream *ds)
{
const struct quirc_version_info *ver =
&quirc_version_db[data->version];
const struct quirc_rs_params *sb_ecc = &ver->ecc[data->ecc_level];
struct quirc_rs_params lb_ecc;
const int lb_count =
(ver->data_bytes - sb_ecc->bs * sb_ecc->ns) / (sb_ecc->bs + 1);
const int bc = lb_count + sb_ecc->ns;
const int ecc_offset = sb_ecc->dw * bc + lb_count;
int dst_offset = 0;
int i;
memcpy(&lb_ecc, sb_ecc, sizeof(lb_ecc));
lb_ecc.dw++;
lb_ecc.bs++;
for (i = 0; i < bc; i++) {
uint8_t *dst = ds->data + dst_offset;
const struct quirc_rs_params *ecc =
(i < sb_ecc->ns) ? sb_ecc : &lb_ecc;
const int num_ec = ecc->bs - ecc->dw;
quirc_decode_error_t err;
int j;
for (j = 0; j < ecc->dw; j++)
dst[j] = ds->raw[j * bc + i];
for (j = 0; j < num_ec; j++)
dst[ecc->dw + j] = ds->raw[ecc_offset + j * bc + i];
err = correct_block(dst, ecc);
if (err)
return err;
dst_offset += ecc->dw;
}
ds->data_bits = dst_offset * 8;
return QUIRC_SUCCESS;
}
static inline int bits_remaining(const struct datastream *ds)
{
return ds->data_bits - ds->ptr;
}
static int take_bits(struct datastream *ds, int len)
{
int ret = 0;
while (len && (ds->ptr < ds->data_bits)) {
uint8_t b = ds->data[ds->ptr >> 3];
int bitpos = ds->ptr & 7;
ret <<= 1;
if ((b << bitpos) & 0x80)
ret |= 1;
ds->ptr++;
len--;
}
return ret;
}
static int numeric_tuple(struct quirc_data *data,
struct datastream *ds,
int bits, int digits)
{
int tuple;
int i;
if (bits_remaining(ds) < bits)
return -1;
tuple = take_bits(ds, bits);
for (i = digits - 1; i >= 0; i--) {
data->payload[data->payload_len + i] = tuple % 10 + '0';
tuple /= 10;
}
data->payload_len += digits;
return 0;
}
static quirc_decode_error_t decode_numeric(struct quirc_data *data,
struct datastream *ds)
{
int bits = 14;
int count;
if (data->version < 10)
bits = 10;
else if (data->version < 27)
bits = 12;
count = take_bits(ds, bits);
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
return QUIRC_ERROR_DATA_OVERFLOW;
while (count >= 3) {
if (numeric_tuple(data, ds, 10, 3) < 0)
return QUIRC_ERROR_DATA_UNDERFLOW;
count -= 3;
}
if (count >= 2) {
if (numeric_tuple(data, ds, 7, 2) < 0)
return QUIRC_ERROR_DATA_UNDERFLOW;
count -= 2;
}
if (count) {
if (numeric_tuple(data, ds, 4, 1) < 0)
return QUIRC_ERROR_DATA_UNDERFLOW;
count--;
}
return QUIRC_SUCCESS;
}
static int alpha_tuple(struct quirc_data *data,
struct datastream *ds,
int bits, int digits)
{
int tuple;
int i;
if (bits_remaining(ds) < bits)
return -1;
tuple = take_bits(ds, bits);
for (i = 0; i < digits; i++) {
static const char *alpha_map =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
data->payload[data->payload_len + digits - i - 1] =
alpha_map[tuple % 45];
tuple /= 45;
}
data->payload_len += digits;
return 0;
}
static quirc_decode_error_t decode_alpha(struct quirc_data *data,
struct datastream *ds)
{
int bits = 13;
int count;
if (data->version < 10)
bits = 9;
else if (data->version < 27)
bits = 11;
count = take_bits(ds, bits);
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
return QUIRC_ERROR_DATA_OVERFLOW;
while (count >= 2) {
if (alpha_tuple(data, ds, 11, 2) < 0)
return QUIRC_ERROR_DATA_UNDERFLOW;
count -= 2;
}
if (count) {
if (alpha_tuple(data, ds, 6, 1) < 0)
return QUIRC_ERROR_DATA_UNDERFLOW;
count--;
}
return QUIRC_SUCCESS;
}
static quirc_decode_error_t decode_byte(struct quirc_data *data,
struct datastream *ds)
{
int bits = 16;
int count;
int i;
if (data->version < 10)
bits = 8;
count = take_bits(ds, bits);
if (data->payload_len + count + 1 > QUIRC_MAX_PAYLOAD)
return QUIRC_ERROR_DATA_OVERFLOW;
if (bits_remaining(ds) < count * 8)
return QUIRC_ERROR_DATA_UNDERFLOW;
for (i = 0; i < count; i++)
data->payload[data->payload_len++] = take_bits(ds, 8);
return QUIRC_SUCCESS;
}
static quirc_decode_error_t decode_kanji(struct quirc_data *data,
struct datastream *ds)
{
int bits = 12;
int count;
int i;
if (data->version < 10)
bits = 8;
else if (data->version < 27)
bits = 10;
count = take_bits(ds, bits);
if (data->payload_len + count * 2 + 1 > QUIRC_MAX_PAYLOAD)
return QUIRC_ERROR_DATA_OVERFLOW;
if (bits_remaining(ds) < count * 13)
return QUIRC_ERROR_DATA_UNDERFLOW;
for (i = 0; i < count; i++) {
int d = take_bits(ds, 13);
int msB = d / 0xc0;
int lsB = d % 0xc0;
int intermediate = (msB << 8) | lsB;
uint16_t sjw;
if (intermediate + 0x8140 <= 0x9ffc) {
/* bytes are in the range 0x8140 to 0x9FFC */
sjw = intermediate + 0x8140;
} else {
/* bytes are in the range 0xE040 to 0xEBBF */
sjw = intermediate + 0xc140;
}
data->payload[data->payload_len++] = sjw >> 8;
data->payload[data->payload_len++] = sjw & 0xff;
}
return QUIRC_SUCCESS;
}
static quirc_decode_error_t decode_eci(struct quirc_data *data,
struct datastream *ds)
{
if (bits_remaining(ds) < 8)
return QUIRC_ERROR_DATA_UNDERFLOW;
data->eci = take_bits(ds, 8);
if ((data->eci & 0xc0) == 0x80) {
if (bits_remaining(ds) < 8)
return QUIRC_ERROR_DATA_UNDERFLOW;
data->eci = (data->eci << 8) | take_bits(ds, 8);
} else if ((data->eci & 0xe0) == 0xc0) {
if (bits_remaining(ds) < 16)
return QUIRC_ERROR_DATA_UNDERFLOW;
data->eci = (data->eci << 16) | take_bits(ds, 16);
}
return QUIRC_SUCCESS;
}
static quirc_decode_error_t decode_payload(struct quirc_data *data,
struct datastream *ds)
{
while (bits_remaining(ds) >= 4) {
quirc_decode_error_t err = QUIRC_SUCCESS;
int type = take_bits(ds, 4);
switch (type) {
case QUIRC_DATA_TYPE_NUMERIC:
err = decode_numeric(data, ds);
break;
case QUIRC_DATA_TYPE_ALPHA:
err = decode_alpha(data, ds);
break;
case QUIRC_DATA_TYPE_BYTE:
err = decode_byte(data, ds);
break;
case QUIRC_DATA_TYPE_KANJI:
err = decode_kanji(data, ds);
break;
case 7:
err = decode_eci(data, ds);
break;
default:
goto done;
}
if (err)
return err;
if (!(type & (type - 1)) && (type > data->data_type))
data->data_type = type;
}
done:
/* Add nul terminator to all payloads */
if ((unsigned)data->payload_len >= sizeof(data->payload))
data->payload_len--;
data->payload[data->payload_len] = 0;
return QUIRC_SUCCESS;
}
quirc_decode_error_t quirc_decode(const struct quirc_code *code,
struct quirc_data *data)
{
quirc_decode_error_t err;
struct datastream ds;
if ((code->size - 17) % 4)
return QUIRC_ERROR_INVALID_GRID_SIZE;
memset(data, 0, sizeof(*data));
memset(&ds, 0, sizeof(ds));
data->version = (code->size - 17) / 4;
if (data->version < 1 ||
data->version > QUIRC_MAX_VERSION)
return QUIRC_ERROR_INVALID_VERSION;
/* Read format information -- try both locations */
err = read_format(code, data, 0);
if (err)
err = read_format(code, data, 1);
if (err)
return err;
read_data(code, data, &ds);
err = codestream_ecc(data, &ds);
if (err)
return err;
err = decode_payload(data, &ds);
if (err)
return err;
return QUIRC_SUCCESS;
}
+138
View File
@@ -0,0 +1,138 @@
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <quirc_internal.h>
const char *quirc_version(void)
{
return "1.0";
}
struct quirc *quirc_new(void)
{
struct quirc *q = malloc(sizeof(*q));
if (!q)
return NULL;
memset(q, 0, sizeof(*q));
return q;
}
void quirc_destroy(struct quirc *q)
{
free(q->image);
/* q->pixels may alias q->image when their type representation is of the
same size, so we need to be careful here to avoid a double free */
if (sizeof(*q->image) != sizeof(*q->pixels))
free(q->pixels);
free(q->row_average);
free(q);
}
int quirc_resize(struct quirc *q, int w, int h)
{
uint8_t *image = NULL;
quirc_pixel_t *pixels = NULL;
int *row_average = NULL;
/*
* XXX: w and h should be size_t (or at least unsigned) as negatives
* values would not make much sense. The downside is that it would break
* both the API and ABI. Thus, at the moment, let's just do a sanity
* check.
*/
if (w < 0 || h < 0)
goto fail;
/*
* alloc a new buffer for q->image. We avoid realloc(3) because we want
* on failure to be leave `q` in a consistant, unmodified state.
*/
image = calloc(w, h);
if (!image)
goto fail;
/* compute the "old" (i.e. currently allocated) and the "new"
(i.e. requested) image dimensions */
size_t olddim = q->w * q->h;
size_t newdim = w * h;
size_t min = (olddim < newdim ? olddim : newdim);
/*
* copy the data into the new buffer, avoiding (a) to read beyond the
* old buffer when the new size is greater and (b) to write beyond the
* new buffer when the new size is smaller, hence the min computation.
*/
(void)memcpy(image, q->image, min);
/* alloc a new buffer for q->pixels if needed */
if (sizeof(*q->image) != sizeof(*q->pixels)) {
pixels = calloc(newdim, sizeof(quirc_pixel_t));
if (!pixels)
goto fail;
}
/* alloc a new buffer for q->row_average */
row_average = calloc(w, sizeof(int));
if (!row_average)
goto fail;
/* alloc succeeded, update `q` with the new size and buffers */
q->w = w;
q->h = h;
free(q->image);
q->image = image;
if (sizeof(*q->image) != sizeof(*q->pixels)) {
free(q->pixels);
q->pixels = pixels;
}
free(q->row_average);
q->row_average = row_average;
return 0;
/* NOTREACHED */
fail:
free(image);
free(pixels);
free(row_average);
return -1;
}
int quirc_count(const struct quirc *q)
{
return q->num_grids;
}
static const char *const error_table[] = {
[QUIRC_SUCCESS] = "Success",
[QUIRC_ERROR_INVALID_GRID_SIZE] = "Invalid grid size",
[QUIRC_ERROR_INVALID_VERSION] = "Invalid version",
[QUIRC_ERROR_FORMAT_ECC] = "Format data ECC failure",
[QUIRC_ERROR_DATA_ECC] = "ECC failure",
[QUIRC_ERROR_UNKNOWN_DATA_TYPE] = "Unknown data type",
[QUIRC_ERROR_DATA_OVERFLOW] = "Data overflow",
[QUIRC_ERROR_DATA_UNDERFLOW] = "Data underflow"
};
const char *quirc_strerror(quirc_decode_error_t err)
{
if ((int)err < 8) { return error_table[err]; }
else { return "Unknown error"; }
}
+430
View File
@@ -0,0 +1,430 @@
/* quirc -- QR-code recognition library
* Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <quirc_internal.h>
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
{ /* 0 */
.data_bytes = 0,
.apat = {0},
.ecc = {
{.bs = 0, .dw = 0, .ns = 0},
{.bs = 0, .dw = 0, .ns = 0},
{.bs = 0, .dw = 0, .ns = 0},
{.bs = 0, .dw = 0, .ns = 0}
}
},
{ /* Version 1 */
.data_bytes = 26,
.apat = {0},
.ecc = {
{.bs = 26, .dw = 16, .ns = 1},
{.bs = 26, .dw = 19, .ns = 1},
{.bs = 26, .dw = 9, .ns = 1},
{.bs = 26, .dw = 13, .ns = 1}
}
},
{ /* Version 2 */
.data_bytes = 44,
.apat = {6, 18, 0},
.ecc = {
{.bs = 44, .dw = 28, .ns = 1},
{.bs = 44, .dw = 34, .ns = 1},
{.bs = 44, .dw = 16, .ns = 1},
{.bs = 44, .dw = 22, .ns = 1}
}
},
{ /* Version 3 */
.data_bytes = 70,
.apat = {6, 22, 0},
.ecc = {
{.bs = 70, .dw = 44, .ns = 1},
{.bs = 70, .dw = 55, .ns = 1},
{.bs = 35, .dw = 13, .ns = 2},
{.bs = 35, .dw = 17, .ns = 2}
}
},
{ /* Version 4 */
.data_bytes = 100,
.apat = {6, 26, 0},
.ecc = {
{.bs = 50, .dw = 32, .ns = 2},
{.bs = 100, .dw = 80, .ns = 1},
{.bs = 25, .dw = 9, .ns = 4},
{.bs = 50, .dw = 24, .ns = 2}
}
},
{ /* Version 5 */
.data_bytes = 134,
.apat = {6, 30, 0},
.ecc = {
{.bs = 67, .dw = 43, .ns = 2},
{.bs = 134, .dw = 108, .ns = 1},
{.bs = 33, .dw = 11, .ns = 2},
{.bs = 33, .dw = 15, .ns = 2}
}
},
{ /* Version 6 */
.data_bytes = 172,
.apat = {6, 34, 0},
.ecc = {
{.bs = 43, .dw = 27, .ns = 4},
{.bs = 86, .dw = 68, .ns = 2},
{.bs = 43, .dw = 15, .ns = 4},
{.bs = 43, .dw = 19, .ns = 4}
}
},
{ /* Version 7 */
.data_bytes = 196,
.apat = {6, 22, 38, 0},
.ecc = {
{.bs = 49, .dw = 31, .ns = 4},
{.bs = 98, .dw = 78, .ns = 2},
{.bs = 39, .dw = 13, .ns = 4},
{.bs = 32, .dw = 14, .ns = 2}
}
},
{ /* Version 8 */
.data_bytes = 242,
.apat = {6, 24, 42, 0},
.ecc = {
{.bs = 60, .dw = 38, .ns = 2},
{.bs = 121, .dw = 97, .ns = 2},
{.bs = 40, .dw = 14, .ns = 4},
{.bs = 40, .dw = 18, .ns = 4}
}
},
{ /* Version 9 */
.data_bytes = 292,
.apat = {6, 26, 46, 0},
.ecc = {
{.bs = 58, .dw = 36, .ns = 3},
{.bs = 146, .dw = 116, .ns = 2},
{.bs = 36, .dw = 12, .ns = 4},
{.bs = 36, .dw = 16, .ns = 4}
}
},
{ /* Version 10 */
.data_bytes = 346,
.apat = {6, 28, 50, 0},
.ecc = {
{.bs = 69, .dw = 43, .ns = 4},
{.bs = 86, .dw = 68, .ns = 2},
{.bs = 43, .dw = 15, .ns = 6},
{.bs = 43, .dw = 19, .ns = 6}
}
},
{ /* Version 11 */
.data_bytes = 404,
.apat = {6, 30, 54, 0},
.ecc = {
{.bs = 80, .dw = 50, .ns = 1},
{.bs = 101, .dw = 81, .ns = 4},
{.bs = 36, .dw = 12, .ns = 3},
{.bs = 50, .dw = 22, .ns = 4}
}
},
{ /* Version 12 */
.data_bytes = 466,
.apat = {6, 32, 58, 0},
.ecc = {
{.bs = 58, .dw = 36, .ns = 6},
{.bs = 116, .dw = 92, .ns = 2},
{.bs = 42, .dw = 14, .ns = 7},
{.bs = 46, .dw = 20, .ns = 4}
}
},
{ /* Version 13 */
.data_bytes = 532,
.apat = {6, 34, 62, 0},
.ecc = {
{.bs = 59, .dw = 37, .ns = 8},
{.bs = 133, .dw = 107, .ns = 4},
{.bs = 33, .dw = 11, .ns = 12},
{.bs = 44, .dw = 20, .ns = 8}
}
},
{ /* Version 14 */
.data_bytes = 581,
.apat = {6, 26, 46, 66, 0},
.ecc = {
{.bs = 64, .dw = 40, .ns = 4},
{.bs = 145, .dw = 115, .ns = 3},
{.bs = 36, .dw = 12, .ns = 11},
{.bs = 36, .dw = 16, .ns = 11}
}
},
{ /* Version 15 */
.data_bytes = 655,
.apat = {6, 26, 48, 70, 0},
.ecc = {
{.bs = 65, .dw = 41, .ns = 5},
{.bs = 109, .dw = 87, .ns = 5},
{.bs = 36, .dw = 12, .ns = 11},
{.bs = 54, .dw = 24, .ns = 5}
}
},
{ /* Version 16 */
.data_bytes = 733,
.apat = {6, 26, 50, 74, 0},
.ecc = {
{.bs = 73, .dw = 45, .ns = 7},
{.bs = 122, .dw = 98, .ns = 5},
{.bs = 45, .dw = 15, .ns = 3},
{.bs = 43, .dw = 19, .ns = 15}
}
},
{ /* Version 17 */
.data_bytes = 815,
.apat = {6, 30, 54, 78, 0},
.ecc = {
{.bs = 74, .dw = 46, .ns = 10},
{.bs = 135, .dw = 107, .ns = 1},
{.bs = 42, .dw = 14, .ns = 2},
{.bs = 50, .dw = 22, .ns = 1}
}
},
{ /* Version 18 */
.data_bytes = 901,
.apat = {6, 30, 56, 82, 0},
.ecc = {
{.bs = 69, .dw = 43, .ns = 9},
{.bs = 150, .dw = 120, .ns = 5},
{.bs = 42, .dw = 14, .ns = 2},
{.bs = 50, .dw = 22, .ns = 17}
}
},
{ /* Version 19 */
.data_bytes = 991,
.apat = {6, 30, 58, 86, 0},
.ecc = {
{.bs = 70, .dw = 44, .ns = 3},
{.bs = 141, .dw = 113, .ns = 3},
{.bs = 39, .dw = 13, .ns = 9},
{.bs = 47, .dw = 21, .ns = 17}
}
},
{ /* Version 20 */
.data_bytes = 1085,
.apat = {6, 34, 62, 90, 0},
.ecc = {
{.bs = 67, .dw = 41, .ns = 3},
{.bs = 135, .dw = 107, .ns = 3},
{.bs = 43, .dw = 15, .ns = 15},
{.bs = 54, .dw = 24, .ns = 15}
}
},
{ /* Version 21 */
.data_bytes = 1156,
.apat = {6, 28, 50, 72, 92, 0},
.ecc = {
{.bs = 68, .dw = 42, .ns = 17},
{.bs = 144, .dw = 116, .ns = 4},
{.bs = 46, .dw = 16, .ns = 19},
{.bs = 50, .dw = 22, .ns = 17}
}
},
{ /* Version 22 */
.data_bytes = 1258,
.apat = {6, 26, 50, 74, 98, 0},
.ecc = {
{.bs = 74, .dw = 46, .ns = 17},
{.bs = 139, .dw = 111, .ns = 2},
{.bs = 37, .dw = 13, .ns = 34},
{.bs = 54, .dw = 24, .ns = 7}
}
},
{ /* Version 23 */
.data_bytes = 1364,
.apat = {6, 30, 54, 78, 102, 0},
.ecc = {
{.bs = 75, .dw = 47, .ns = 4},
{.bs = 151, .dw = 121, .ns = 4},
{.bs = 45, .dw = 15, .ns = 16},
{.bs = 54, .dw = 24, .ns = 11}
}
},
{ /* Version 24 */
.data_bytes = 1474,
.apat = {6, 28, 54, 80, 106, 0},
.ecc = {
{.bs = 73, .dw = 45, .ns = 6},
{.bs = 147, .dw = 117, .ns = 6},
{.bs = 46, .dw = 16, .ns = 30},
{.bs = 54, .dw = 24, .ns = 11}
}
},
{ /* Version 25 */
.data_bytes = 1588,
.apat = {6, 32, 58, 84, 110, 0},
.ecc = {
{.bs = 75, .dw = 47, .ns = 8},
{.bs = 132, .dw = 106, .ns = 8},
{.bs = 45, .dw = 15, .ns = 22},
{.bs = 54, .dw = 24, .ns = 7}
}
},
{ /* Version 26 */
.data_bytes = 1706,
.apat = {6, 30, 58, 86, 114, 0},
.ecc = {
{.bs = 74, .dw = 46, .ns = 19},
{.bs = 142, .dw = 114, .ns = 10},
{.bs = 46, .dw = 16, .ns = 33},
{.bs = 50, .dw = 22, .ns = 28}
}
},
{ /* Version 27 */
.data_bytes = 1828,
.apat = {6, 34, 62, 90, 118, 0},
.ecc = {
{.bs = 73, .dw = 45, .ns = 22},
{.bs = 152, .dw = 122, .ns = 8},
{.bs = 45, .dw = 15, .ns = 12},
{.bs = 53, .dw = 23, .ns = 8}
}
},
{ /* Version 28 */
.data_bytes = 1921,
.apat = {6, 26, 50, 74, 98, 122, 0},
.ecc = {
{.bs = 73, .dw = 45, .ns = 3},
{.bs = 147, .dw = 117, .ns = 3},
{.bs = 45, .dw = 15, .ns = 11},
{.bs = 54, .dw = 24, .ns = 4}
}
},
{ /* Version 29 */
.data_bytes = 2051,
.apat = {6, 30, 54, 78, 102, 126, 0},
.ecc = {
{.bs = 73, .dw = 45, .ns = 21},
{.bs = 146, .dw = 116, .ns = 7},
{.bs = 45, .dw = 15, .ns = 19},
{.bs = 53, .dw = 23, .ns = 1}
}
},
{ /* Version 30 */
.data_bytes = 2185,
.apat = {6, 26, 52, 78, 104, 130, 0},
.ecc = {
{.bs = 75, .dw = 47, .ns = 19},
{.bs = 145, .dw = 115, .ns = 5},
{.bs = 45, .dw = 15, .ns = 23},
{.bs = 54, .dw = 24, .ns = 15}
}
},
{ /* Version 31 */
.data_bytes = 2323,
.apat = {6, 30, 56, 82, 108, 134, 0},
.ecc = {
{.bs = 74, .dw = 46, .ns = 2},
{.bs = 145, .dw = 115, .ns = 13},
{.bs = 45, .dw = 15, .ns = 23},
{.bs = 54, .dw = 24, .ns = 42}
}
},
{ /* Version 32 */
.data_bytes = 2465,
.apat = {6, 34, 60, 86, 112, 138, 0},
.ecc = {
{.bs = 74, .dw = 46, .ns = 10},
{.bs = 145, .dw = 115, .ns = 17},
{.bs = 45, .dw = 15, .ns = 19},
{.bs = 54, .dw = 24, .ns = 10}
}
},
{ /* Version 33 */
.data_bytes = 2611,
.apat = {6, 30, 58, 86, 114, 142, 0},
.ecc = {
{.bs = 74, .dw = 46, .ns = 14},
{.bs = 145, .dw = 115, .ns = 17},
{.bs = 45, .dw = 15, .ns = 11},
{.bs = 54, .dw = 24, .ns = 29}
}
},
{ /* Version 34 */
.data_bytes = 2761,
.apat = {6, 34, 62, 90, 118, 146, 0},
.ecc = {
{.bs = 74, .dw = 46, .ns = 14},
{.bs = 145, .dw = 115, .ns = 13},
{.bs = 46, .dw = 16, .ns = 59},
{.bs = 54, .dw = 24, .ns = 44}
}
},
{ /* Version 35 */
.data_bytes = 2876,
.apat = {6, 30, 54, 78, 102, 126, 150},
.ecc = {
{.bs = 75, .dw = 47, .ns = 12},
{.bs = 151, .dw = 121, .ns = 12},
{.bs = 45, .dw = 15, .ns = 22},
{.bs = 54, .dw = 24, .ns = 39}
}
},
{ /* Version 36 */
.data_bytes = 3034,
.apat = {6, 24, 50, 76, 102, 128, 154},
.ecc = {
{.bs = 75, .dw = 47, .ns = 6},
{.bs = 151, .dw = 121, .ns = 6},
{.bs = 45, .dw = 15, .ns = 2},
{.bs = 54, .dw = 24, .ns = 46}
}
},
{ /* Version 37 */
.data_bytes = 3196,
.apat = {6, 28, 54, 80, 106, 132, 158},
.ecc = {
{.bs = 74, .dw = 46, .ns = 29},
{.bs = 152, .dw = 122, .ns = 17},
{.bs = 45, .dw = 15, .ns = 24},
{.bs = 54, .dw = 24, .ns = 49}
}
},
{ /* Version 38 */
.data_bytes = 3362,
.apat = {6, 32, 58, 84, 110, 136, 162},
.ecc = {
{.bs = 74, .dw = 46, .ns = 13},
{.bs = 152, .dw = 122, .ns = 4},
{.bs = 45, .dw = 15, .ns = 42},
{.bs = 54, .dw = 24, .ns = 48}
}
},
{ /* Version 39 */
.data_bytes = 3532,
.apat = {6, 26, 54, 82, 110, 138, 166},
.ecc = {
{.bs = 75, .dw = 47, .ns = 40},
{.bs = 147, .dw = 117, .ns = 20},
{.bs = 45, .dw = 15, .ns = 10},
{.bs = 54, .dw = 24, .ns = 43}
}
},
{ /* Version 40 */
.data_bytes = 3706,
.apat = {6, 30, 58, 86, 114, 142, 170},
.ecc = {
{.bs = 75, .dw = 47, .ns = 18},
{.bs = 148, .dw = 118, .ns = 19},
{.bs = 45, .dw = 15, .ns = 20},
{.bs = 54, .dw = 24, .ns = 34}
}
}
};
+5
View File
@@ -283,6 +283,7 @@ OCV_OPTION(WITH_IMGCODEC_HDR "Include HDR support" ON)
OCV_OPTION(WITH_IMGCODEC_SUNRASTER "Include SUNRASTER support" ON)
OCV_OPTION(WITH_IMGCODEC_PXM "Include PNM (PBM,PGM,PPM) and PAM formats support" ON)
OCV_OPTION(WITH_IMGCODEC_PFM "Include PFM formats support" ON)
OCV_OPTION(WITH_QUIRC "Include library QR-code decoding" ON)
# OpenCV build components
# ===================================================
@@ -696,6 +697,10 @@ if(WITH_OPENVX)
include(cmake/FindOpenVX.cmake)
endif()
if(WITH_QUIRC)
add_subdirectory(3rdparty/quirc)
set(HAVE_QUIRC TRUE)
endif()
# ----------------------------------------------------------------------------
# OpenCV HAL
# ----------------------------------------------------------------------------
@@ -210,7 +210,7 @@ void calib::calibDataController::filterFrames()
worstElemIndex = i;
}
}
showOverlayMessage(cv::format("Frame %d is worst", worstElemIndex + 1));
showOverlayMessage(cv::format("Frame %zu is worst", worstElemIndex + 1));
if(mCalibData->imagePoints.size()) {
mCalibData->imagePoints.erase(mCalibData->imagePoints.begin() + worstElemIndex);
@@ -318,7 +318,7 @@ cv::Mat CalibProcessor::processFrame(const cv::Mat &frame)
saveFrameData();
bool isFrameBad = checkLastFrame();
if (!isFrameBad) {
std::string displayMessage = cv::format("Frame # %d captured", std::max(mCalibData->imagePoints.size(),
std::string displayMessage = cv::format("Frame # %zu captured", std::max(mCalibData->imagePoints.size(),
mCalibData->allCharucoCorners.size()));
if(!showOverlayMessage(displayMessage))
showCaptureMessage(frame, displayMessage);
+7 -2
View File
@@ -86,7 +86,11 @@ endif()
if(CV_GCC OR CV_CLANG)
# High level of warnings.
add_extra_compiler_option(-W)
add_extra_compiler_option(-Wall)
if (NOT MSVC)
# clang-cl interprets -Wall as MSVC would: -Weverything, which is more than
# we want.
add_extra_compiler_option(-Wall)
endif()
add_extra_compiler_option(-Werror=return-type)
add_extra_compiler_option(-Werror=non-virtual-dtor)
add_extra_compiler_option(-Werror=address)
@@ -173,7 +177,7 @@ if(CV_GCC OR CV_CLANG)
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}")
endforeach()
elseif(NOT ((IOS OR ANDROID) AND NOT BUILD_SHARED_LIBS))
elseif(NOT ((IOS OR ANDROID) AND NOT BUILD_SHARED_LIBS) AND NOT MSVC)
# Remove unreferenced functions: function level linking
add_extra_compiler_option(-ffunction-sections)
add_extra_compiler_option(-fdata-sections)
@@ -266,6 +270,7 @@ endif()
# set default visibility to hidden
if((CV_GCC OR CV_CLANG)
AND NOT MSVC
AND NOT OPENCV_SKIP_VISIBILITY_HIDDEN
AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES " -fvisibility")
add_extra_compiler_option(-fvisibility=hidden)
+46 -8
View File
@@ -38,7 +38,7 @@ if(NOT ${found})
set(PYTHON_EXECUTABLE "${${executable}}")
endif()
if(WIN32 AND NOT ${executable})
if(WIN32 AND NOT ${executable} AND OPENCV_PYTHON_PREFER_WIN32_REGISTRY) # deprecated
# search for executable with the same bitness as resulting binaries
# standard FindPythonInterp always prefers executable from system path
# this is really important because we are using the interpreter for numpy search and for choosing the install location
@@ -53,16 +53,53 @@ if(NOT ${found})
endforeach()
endif()
string(REGEX MATCH "^[0-9]+" _preferred_version_major "${preferred_version}")
find_host_package(PythonInterp "${preferred_version}")
if(NOT PYTHONINTERP_FOUND)
if(preferred_version)
set(__python_package_version "${preferred_version} EXACT")
find_host_package(PythonInterp "${preferred_version}" EXACT)
if(NOT PYTHONINTERP_FOUND)
message(STATUS "Python is not found: ${preferred_version} EXACT")
endif()
elseif(min_version)
set(__python_package_version "${min_version}")
find_host_package(PythonInterp "${min_version}")
else()
set(__python_package_version "")
find_host_package(PythonInterp)
endif()
string(REGEX MATCH "^[0-9]+" _python_version_major "${min_version}")
if(PYTHONINTERP_FOUND)
# Check if python major version is correct
if("${_preferred_version_major}" STREQUAL "" OR "${_preferred_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}")
if(" ${_python_version_major}" STREQUAL " ")
set(_python_version_major "${PYTHON_VERSION_MAJOR}")
endif()
if(NOT "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}"
AND NOT DEFINED ${executable}
)
if(NOT OPENCV_SKIP_PYTHON_WARNING)
message(WARNING "CMake's 'find_host_package(PythonInterp ${__python_package_version})' founds wrong Python version:\n"
"PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\n"
"PYTHON_VERSION_STRING=${PYTHON_VERSION_STRING}\n"
"Consider specify '${executable}' variable via CMake command line or environment variables\n")
endif()
ocv_clear_vars(PYTHONINTERP_FOUND PYTHON_EXECUTABLE PYTHON_VERSION_STRING PYTHON_VERSION_MAJOR PYTHON_VERSION_MINOR PYTHON_VERSION_PATCH)
if(NOT CMAKE_VERSION VERSION_LESS "3.12")
if(_python_version_major STREQUAL "2")
set(__PYTHON_PREFIX Python2)
else()
set(__PYTHON_PREFIX Python3)
endif()
find_host_package(${__PYTHON_PREFIX} "${preferred_version}" COMPONENTS Interpreter)
if(${__PYTHON_PREFIX}_EXECUTABLE)
set(PYTHON_EXECUTABLE "${${__PYTHON_PREFIX}_EXECUTABLE}")
find_host_package(PythonInterp "${preferred_version}") # Populate other variables
endif()
else()
message(STATUS "Consider using CMake 3.12+ for better Python support")
endif()
endif()
if(PYTHONINTERP_FOUND AND "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}")
# Copy outputs
set(_found ${PYTHONINTERP_FOUND})
set(_executable ${PYTHON_EXECUTABLE})
@@ -235,7 +272,7 @@ if(OPENCV_PYTHON_SKIP_DETECTION)
return()
endif()
find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
find_python("" "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING
PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND
PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY
@@ -243,7 +280,8 @@ find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH
PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION)
find_python(3.4 "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
option(OPENCV_PYTHON3_VERSION "Python3 version" "")
find_python("${OPENCV_PYTHON3_VERSION}" "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING
PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND
PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY
+4 -2
View File
@@ -44,8 +44,10 @@ else()
if(Protobuf_FOUND)
if(TARGET protobuf::libprotobuf)
add_library(libprotobuf INTERFACE)
target_link_libraries(libprotobuf INTERFACE protobuf::libprotobuf)
add_library(libprotobuf INTERFACE IMPORTED)
set_target_properties(libprotobuf PROPERTIES
INTERFACE_LINK_LIBRARIES protobuf::libprotobuf
)
else()
add_library(libprotobuf UNKNOWN IMPORTED)
set_target_properties(libprotobuf PROPERTIES
+1 -1
View File
@@ -1,6 +1,6 @@
set(MIN_VER_CMAKE 3.5.1)
set(MIN_VER_CUDA 6.5)
set(MIN_VER_PYTHON2 2.6)
set(MIN_VER_PYTHON2 2.7)
set(MIN_VER_PYTHON3 3.2)
set(MIN_VER_ZLIB 1.2.3)
set(MIN_VER_GTK 2.18.0)
+8
View File
@@ -909,6 +909,13 @@ macro(_ocv_create_module)
source_group("Src" FILES "${_VS_VERSION_FILE}")
endif()
endif()
if(WIN32 AND NOT ("${the_module}" STREQUAL "opencv_core" OR "${the_module}" STREQUAL "opencv_world")
AND (BUILD_SHARED_LIBS AND NOT "x${OPENCV_MODULE_TYPE}" STREQUAL "xSTATIC")
AND NOT OPENCV_SKIP_DLLMAIN_GENERATION
)
set(_DLLMAIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/${the_module}_main.cpp")
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/dllmain.cpp.in" "${_DLLMAIN_FILE}" @ONLY)
endif()
source_group("Include" FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp")
source_group("Src" FILES "${${the_module}_pch}")
@@ -918,6 +925,7 @@ macro(_ocv_create_module)
"${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp"
${${the_module}_pch}
${_VS_VERSION_FILE}
${_DLLMAIN_FILE}
)
set_target_properties(${the_module} PROPERTIES LABELS "${OPENCV_MODULE_${the_module}_LABEL};Module")
set_source_files_properties(${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES} ${${the_module}_pch}
+28 -6
View File
@@ -999,6 +999,15 @@ function(ocv_convert_to_lib_name var)
set(${var} ${tmp} PARENT_SCOPE)
endfunction()
if(MSVC AND BUILD_SHARED_LIBS) # no defaults for static libs (modern CMake is required)
if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default" ON)
option(INSTALL_PDB "Add install PDB rules" ON)
elseif(NOT CMAKE_VERSION VERSION_LESS 3.1.0)
option(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL "Don't install PDB files by default (not supported)" OFF)
option(INSTALL_PDB "Add install PDB rules" OFF)
endif()
endif()
# add install command
function(ocv_install_target)
@@ -1030,9 +1039,10 @@ function(ocv_install_target)
endif()
if(MSVC)
if(INSTALL_PDB AND (NOT INSTALL_IGNORE_PDB))
set(__target "${ARGV0}")
set(__target "${ARGV0}")
if(INSTALL_PDB AND NOT INSTALL_IGNORE_PDB
AND NOT OPENCV_${__target}_PDB_SKIP
)
set(__location_key "ARCHIVE") # static libs
get_target_property(__target_type ${__target} TYPE)
if("${__target_type}" STREQUAL "SHARED_LIBRARY")
@@ -1064,16 +1074,28 @@ function(ocv_install_target)
if(DEFINED INSTALL_PDB_COMPONENT AND INSTALL_PDB_COMPONENT)
set(__pdb_install_component "${INSTALL_PDB_COMPONENT}")
endif()
set(__pdb_exclude_from_all "")
if(INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL)
if(NOT CMAKE_VERSION VERSION_LESS 3.6.0)
set(__pdb_exclude_from_all EXCLUDE_FROM_ALL)
else()
message(WARNING "INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL requires CMake 3.6+")
endif()
endif()
# message(STATUS "Adding PDB file installation rule: target=${__target} dst=${__dst} component=${__pdb_install_component}")
if("${__target_type}" STREQUAL "SHARED_LIBRARY")
install(FILES "$<TARGET_PDB_FILE:${__target}>" DESTINATION "${__dst}" COMPONENT ${__pdb_install_component} OPTIONAL)
install(FILES "$<TARGET_PDB_FILE:${__target}>" DESTINATION "${__dst}"
COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
else()
# There is no generator expression similar to TARGET_PDB_FILE and TARGET_PDB_FILE can't be used: https://gitlab.kitware.com/cmake/cmake/issues/16932
# However we still want .pdb files like: 'lib/Debug/opencv_core341d.pdb' or '3rdparty/lib/zlibd.pdb'
install(FILES "$<TARGET_PROPERTY:${__target},ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<IF:$<BOOL:$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_DEBUG>>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_DEBUG>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME>>.pdb"
DESTINATION "${__dst}" CONFIGURATIONS Debug COMPONENT ${__pdb_install_component} OPTIONAL)
DESTINATION "${__dst}" CONFIGURATIONS Debug
COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
install(FILES "$<TARGET_PROPERTY:${__target},ARCHIVE_OUTPUT_DIRECTORY>/$<CONFIG>/$<IF:$<BOOL:$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_RELEASE>>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME_RELEASE>,$<TARGET_PROPERTY:${__target},COMPILE_PDB_NAME>>.pdb"
DESTINATION "${__dst}" CONFIGURATIONS Release COMPONENT ${__pdb_install_component} OPTIONAL)
DESTINATION "${__dst}" CONFIGURATIONS Release
COMPONENT ${__pdb_install_component} OPTIONAL ${__pdb_exclude_from_all})
endif()
else()
message(WARNING "PDB files installation is not supported (need CMake >= 3.1.0)")
+2
View File
@@ -244,5 +244,7 @@
/* OpenCV trace utilities */
#cmakedefine OPENCV_TRACE
/* Library QR-code decoding */
#cmakedefine HAVE_QUIRC
#endif // OPENCV_CVCONFIG_H_INCLUDED
+36
View File
@@ -0,0 +1,36 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef _WIN32
#error "Build configuration error"
#endif
#ifndef CVAPI_EXPORTS
#error "Build configuration error"
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define OPENCV_MODULE_S "@the_module@"
namespace cv {
extern __declspec(dllimport) bool __termination; // Details: #12750
}
extern "C"
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved);
extern "C"
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
{
if (lpReserved != NULL) // called after ExitProcess() call
{
//printf("OpenCV: terminating: " OPENCV_MODULE_S "\n");
cv::__termination = true;
}
}
return TRUE;
}
+18
View File
@@ -14,12 +14,19 @@ if(DOXYGEN_FOUND)
add_custom_target(doxygen)
# not documented modules list
set(blacklist "${DOXYGEN_BLACKLIST}")
list(APPEND blacklist "ts" "java_bindings_generator" "java" "python_bindings_generator" "python2" "python3" "js" "world")
unset(CMAKE_DOXYGEN_TUTORIAL_CONTRIB_ROOT)
unset(CMAKE_DOXYGEN_TUTORIAL_JS_ROOT)
set(OPENCV_MATHJAX_RELPATH "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0" CACHE STRING "URI to a MathJax installation")
set(OPENCV_DOCS_EXCLUDE_CUDA ON)
if(";${OPENCV_MODULES_EXTRA};" MATCHES ";cudev;")
set(OPENCV_DOCS_EXCLUDE_CUDA OFF)
list(APPEND CMAKE_DOXYGEN_ENABLED_SECTIONS "CUDA_MODULES")
endif()
# gathering headers
set(paths_include)
set(paths_doc)
@@ -38,6 +45,15 @@ if(DOXYGEN_FOUND)
if(EXISTS "${header_dir}")
list(APPEND paths_include "${header_dir}")
list(APPEND deps ${header_dir})
if(OPENCV_DOCS_EXCLUDE_CUDA)
if(EXISTS "${OPENCV_MODULE_opencv_${m}_LOCATION}/include/opencv2/${m}/cuda")
list(APPEND CMAKE_DOXYGEN_EXCLUDE_LIST "${OPENCV_MODULE_opencv_${m}_LOCATION}/include/opencv2/${m}/cuda")
endif()
file(GLOB list_cuda_files "${OPENCV_MODULE_opencv_${m}_LOCATION}/include/opencv2/${m}/*cuda*.hpp")
if(list_cuda_files)
list(APPEND CMAKE_DOXYGEN_EXCLUDE_LIST ${list_cuda_files})
endif()
endif()
endif()
# doc folder
set(docs_dir "${OPENCV_MODULE_opencv_${m}_LOCATION}/doc")
@@ -124,6 +140,8 @@ if(DOXYGEN_FOUND)
# set export variables
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_INPUT_LIST "${rootfile} ; ${faqfile} ; ${paths_include} ; ${paths_hal_interface} ; ${paths_doc} ; ${tutorial_path} ; ${tutorial_py_path} ; ${tutorial_js_path} ; ${paths_tutorial} ; ${tutorial_contrib_root}")
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_IMAGE_PATH "${paths_doc} ; ${tutorial_path} ; ${tutorial_py_path} ; ${tutorial_js_path} ; ${paths_tutorial}")
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_EXCLUDE_LIST "${CMAKE_DOXYGEN_EXCLUDE_LIST}")
string(REPLACE ";" " " CMAKE_DOXYGEN_ENABLED_SECTIONS "${CMAKE_DOXYGEN_ENABLED_SECTIONS}")
# TODO: remove paths_doc from EXAMPLE_PATH after face module tutorials/samples moved to separate folders
string(REPLACE ";" " \\\n" CMAKE_DOXYGEN_EXAMPLE_PATH "${example_path} ; ${paths_doc} ; ${paths_sample}")
set(CMAKE_DOXYGEN_LAYOUT "${CMAKE_CURRENT_BINARY_DIR}/DoxygenLayout.xml")
+2 -2
View File
@@ -85,7 +85,7 @@ GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
ENABLED_SECTIONS = @CMAKE_DOXYGEN_ENABLED_SECTIONS@
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_FILES = YES
@@ -104,7 +104,7 @@ INPUT = @CMAKE_DOXYGEN_INPUT_LIST@
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = YES
EXCLUDE =
EXCLUDE = @CMAKE_DOXYGEN_EXCLUDE_LIST@
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = *.inl.hpp *.impl.hpp *_detail.hpp */cudev/**/detail/*.hpp *.m */opencl/runtime/*
EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__*
@@ -23,7 +23,7 @@ import cv2 as cv
img = cv.imread('star.jpg',0)
ret,thresh = cv.threshold(img,127,255,0)
im2,contours,hierarchy = cv.findContours(thresh, 1, 2)
contours,hierarchy = cv.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv.moments(cnt)
@@ -17,7 +17,7 @@ detection and recognition.
- For better accuracy, use binary images. So before finding contours, apply threshold or canny
edge detection.
- Since OpenCV 3.2, findContours() no longer modifies the source image but returns a modified image as the first of three return parameters.
- Since OpenCV 3.2, findContours() no longer modifies the source image.
- In OpenCV, finding contours is like finding white object from black background. So remember,
object to be found should be white and background should be black.
@@ -29,11 +29,11 @@ import cv2 as cv
im = cv.imread('test.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
@endcode
See, there are three arguments in **cv.findContours()** function, first one is source image, second
is contour retrieval mode, third is contour approximation method. And it outputs a modified image, the contours and
hierarchy. contours is a Python list of all the contours in the image. Each individual contour is a
is contour retrieval mode, third is contour approximation method. And it outputs the contours and hierarchy.
Contours is a Python list of all the contours in the image. Each individual contour is a
Numpy array of (x,y) coordinates of boundary points of the object.
@note We will discuss second and third arguments and about hierarchy in details later. Until then,
@@ -39,7 +39,7 @@ import numpy as np
img = cv.imread('star.jpg')
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,thresh = cv.threshold(img_gray, 127, 255,0)
im2,contours,hierarchy = cv.findContours(thresh,2,1)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt = contours[0]
hull = cv.convexHull(cnt,returnPoints = False)
@@ -93,9 +93,9 @@ img2 = cv.imread('star2.jpg',0)
ret, thresh = cv.threshold(img1, 127, 255,0)
ret, thresh2 = cv.threshold(img2, 127, 255,0)
im2,contours,hierarchy = cv.findContours(thresh,2,1)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt1 = contours[0]
im2,contours,hierarchy = cv.findContours(thresh2,2,1)
contours,hierarchy = cv.findContours(thresh2,2,1)
cnt2 = contours[0]
ret = cv.matchShapes(cnt1,cnt2,1,0.0)
@@ -1,3 +1,4 @@
@cond CUDA_MODULES
Similarity check (PNSR and SSIM) on the GPU {#tutorial_gpu_basics_similarity}
===========================================
@todo update this tutorial
@@ -204,3 +205,4 @@ It may be just the improvement needed for your application to work. You may obse
instance of this on the [YouTube here](https://www.youtube.com/watch?v=3_ESXmFlnvY).
@youtube{3_ESXmFlnvY}
@endcond
@@ -1,3 +1,4 @@
@cond CUDA_MODULES
Using a cv::cuda::GpuMat with thrust {#tutorial_gpu_thrust_interop}
===========================================
@@ -68,3 +69,4 @@ Next we will determine how many values are greater than 0 by using thrust::count
We will use those results to create an output buffer for storing the copied values, we will then use copy_if with the same predicate to populate the output buffer.
Lastly we will download the values into a CPU mat for viewing.
@endcond
@@ -1,3 +1,4 @@
@cond CUDA_MODULES
GPU-Accelerated Computer Vision (cuda module) {#tutorial_table_of_content_gpu}
=============================================
@@ -20,3 +21,4 @@ run the OpenCV algorithms.
This tutorial will show you how to wrap a GpuMat into a thrust iterator in order to be able to
use the functions in the thrust library.
@endcond
@@ -56,7 +56,7 @@ Theory
entire pyramid.
- The procedure above was useful to downsample an image. What if we want to make it bigger?:
columns filled with zeros (\f$0 \f$)
- First, upsize the image to twice the original in each dimension, wit the new even rows and
- First, upsize the image to twice the original in each dimension, with the new even rows and
- Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the
values of the "missing pixels"
- These two procedures (downsampling and upsampling as explained above) are implemented by the
@@ -236,7 +236,10 @@ for(;;){
CUDA {#tutorial_transition_hints_cuda}
----
_cuda_ module has been split into several smaller pieces:
CUDA modules has been moved into opencv_contrib repository.
@cond CUDA_MODULES
- _cuda_ - @ref cuda
- _cudaarithm_ - @ref cudaarithm
- _cudabgsegm_ - @ref cudabgsegm
@@ -249,10 +252,7 @@ _cuda_ module has been split into several smaller pieces:
- _cudastereo_ - @ref cudastereo
- _cudawarping_ - @ref cudawarping
- _cudev_ - @ref cudev
`gpu` namespace has been removed, use cv::cuda namespace instead. Many classes has also been renamed, for example:
- `gpu::FAST_GPU` -> cv::cuda::FastFeatureDetector
- `gpu::createBoxFilter_GPU` -> cv::cuda::createBoxFilter
@endcond
Documentation format {#tutorial_transition_docs}
--------------------
+2
View File
@@ -76,11 +76,13 @@ As always, we would be happy to hear your comments and receive your contribution
Learn how to create beautiful photo panoramas and more with OpenCV stitching pipeline.
@cond CUDA_MODULES
- @subpage tutorial_table_of_content_gpu
Squeeze out every
little computational power from your system by utilizing the power of your video card to run the
OpenCV algorithms.
@endcond
- @subpage tutorial_table_of_content_ios
+211 -2
View File
@@ -244,7 +244,9 @@ enum { SOLVEPNP_ITERATIVE = 0,
enum { CALIB_CB_ADAPTIVE_THRESH = 1,
CALIB_CB_NORMALIZE_IMAGE = 2,
CALIB_CB_FILTER_QUADS = 4,
CALIB_CB_FAST_CHECK = 8
CALIB_CB_FAST_CHECK = 8,
CALIB_CB_EXHAUSTIVE = 16,
CALIB_CB_ACCURACY = 32
};
enum { CALIB_CB_SYMMETRIC_GRID = 1,
@@ -847,7 +849,11 @@ CV_EXPORTS_W bool findChessboardCorners( InputArray image, Size patternSize, Out
@param patternSize Number of inner corners per a chessboard row and column
( patternSize = cv::Size(points_per_row,points_per_colum) = cv::Size(columns,rows) ).
@param corners Output array of detected corners.
@param flags operation flags for future improvements
@param flags Various operation flags that can be zero or a combination of the following values:
- **CALIB_CB_NORMALIZE_IMAGE** Normalize the image gamma with equalizeHist before detection.
- **CALIB_CB_EXHAUSTIVE ** Run an exhaustive search to improve detection rate.
- **CALIB_CB_ACCURACY ** Up sample input image to improve sub-pixel accuracy due to aliasing effects.
This should be used if an accurate camera calibration is required.
The function is analog to findchessboardCorners but uses a localized radon
transformation approximated by box filters being more robust to all sort of
@@ -2216,6 +2222,209 @@ public:
int mode = StereoSGBM::MODE_SGBM);
};
//! cv::undistort mode
enum UndistortTypes
{
PROJ_SPHERICAL_ORTHO = 0,
PROJ_SPHERICAL_EQRECT = 1
};
/** @brief Transforms an image to compensate for lens distortion.
The function transforms an image to compensate radial and tangential lens distortion.
The function is simply a combination of #initUndistortRectifyMap (with unity R ) and #remap
(with bilinear interpolation). See the former function for details of the transformation being
performed.
Those pixels in the destination image, for which there is no correspondent pixels in the source
image, are filled with zeros (black color).
A particular subset of the source image that will be visible in the corrected image can be regulated
by newCameraMatrix. You can use #getOptimalNewCameraMatrix to compute the appropriate
newCameraMatrix depending on your requirements.
The camera matrix and the distortion parameters can be determined using #calibrateCamera. If
the resolution of images is different from the resolution used at the calibration stage, \f$f_x,
f_y, c_x\f$ and \f$c_y\f$ need to be scaled accordingly, while the distortion coefficients remain
the same.
@param src Input (distorted) image.
@param dst Output (corrected) image that has the same size and type as src .
@param cameraMatrix Input camera matrix \f$A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
@param distCoeffs Input vector of distortion coefficients
\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
@param newCameraMatrix Camera matrix of the distorted image. By default, it is the same as
cameraMatrix but you may additionally scale and shift the result by using a different matrix.
*/
CV_EXPORTS_W void undistort( InputArray src, OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray newCameraMatrix = noArray() );
/** @brief Computes the undistortion and rectification transformation map.
The function computes the joint undistortion and rectification transformation and represents the
result in the form of maps for remap. The undistorted image looks like original, as if it is
captured with a camera using the camera matrix =newCameraMatrix and zero distortion. In case of a
monocular camera, newCameraMatrix is usually equal to cameraMatrix, or it can be computed by
#getOptimalNewCameraMatrix for a better control over scaling. In case of a stereo camera,
newCameraMatrix is normally set to P1 or P2 computed by #stereoRectify .
Also, this new camera is oriented differently in the coordinate space, according to R. That, for
example, helps to align two heads of a stereo camera so that the epipolar lines on both images
become horizontal and have the same y- coordinate (in case of a horizontally aligned stereo camera).
The function actually builds the maps for the inverse mapping algorithm that is used by remap. That
is, for each pixel \f$(u, v)\f$ in the destination (corrected and rectified) image, the function
computes the corresponding coordinates in the source image (that is, in the original image from
camera). The following process is applied:
\f[
\begin{array}{l}
x \leftarrow (u - {c'}_x)/{f'}_x \\
y \leftarrow (v - {c'}_y)/{f'}_y \\
{[X\,Y\,W]} ^T \leftarrow R^{-1}*[x \, y \, 1]^T \\
x' \leftarrow X/W \\
y' \leftarrow Y/W \\
r^2 \leftarrow x'^2 + y'^2 \\
x'' \leftarrow x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}
+ 2p_1 x' y' + p_2(r^2 + 2 x'^2) + s_1 r^2 + s_2 r^4\\
y'' \leftarrow y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6}
+ p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' + s_3 r^2 + s_4 r^4 \\
s\vecthree{x'''}{y'''}{1} =
\vecthreethree{R_{33}(\tau_x, \tau_y)}{0}{-R_{13}((\tau_x, \tau_y)}
{0}{R_{33}(\tau_x, \tau_y)}{-R_{23}(\tau_x, \tau_y)}
{0}{0}{1} R(\tau_x, \tau_y) \vecthree{x''}{y''}{1}\\
map_x(u,v) \leftarrow x''' f_x + c_x \\
map_y(u,v) \leftarrow y''' f_y + c_y
\end{array}
\f]
where \f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
are the distortion coefficients.
In case of a stereo camera, this function is called twice: once for each camera head, after
stereoRectify, which in its turn is called after #stereoCalibrate. But if the stereo camera
was not calibrated, it is still possible to compute the rectification transformations directly from
the fundamental matrix using #stereoRectifyUncalibrated. For each camera, the function computes
homography H as the rectification transformation in a pixel domain, not a rotation matrix R in 3D
space. R can be computed from H as
\f[\texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix}\f]
where cameraMatrix can be chosen arbitrarily.
@param cameraMatrix Input camera matrix \f$A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$ .
@param distCoeffs Input vector of distortion coefficients
\f$(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6[, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]])\f$
of 4, 5, 8, 12 or 14 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed.
@param R Optional rectification transformation in the object space (3x3 matrix). R1 or R2 ,
computed by #stereoRectify can be passed here. If the matrix is empty, the identity transformation
is assumed. In cvInitUndistortMap R assumed to be an identity matrix.
@param newCameraMatrix New camera matrix \f$A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}\f$.
@param size Undistorted image size.
@param m1type Type of the first output map that can be CV_32FC1, CV_32FC2 or CV_16SC2, see #convertMaps
@param map1 The first output map.
@param map2 The second output map.
*/
CV_EXPORTS_W
void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs,
InputArray R, InputArray newCameraMatrix,
Size size, int m1type, OutputArray map1, OutputArray map2);
//! initializes maps for #remap for wide-angle
CV_EXPORTS
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
Size imageSize, int destImageWidth,
int m1type, OutputArray map1, OutputArray map2,
enum UndistortTypes projType = PROJ_SPHERICAL_EQRECT, double alpha = 0);
static inline
float initWideAngleProjMap(InputArray cameraMatrix, InputArray distCoeffs,
Size imageSize, int destImageWidth,
int m1type, OutputArray map1, OutputArray map2,
int projType, double alpha = 0)
{
return initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize, destImageWidth,
m1type, map1, map2, (UndistortTypes)projType, alpha);
}
/** @brief Returns the default new camera matrix.
The function returns the camera matrix that is either an exact copy of the input cameraMatrix (when
centerPrinicipalPoint=false ), or the modified one (when centerPrincipalPoint=true).
In the latter case, the new camera matrix will be:
\f[\begin{bmatrix} f_x && 0 && ( \texttt{imgSize.width} -1)*0.5 \\ 0 && f_y && ( \texttt{imgSize.height} -1)*0.5 \\ 0 && 0 && 1 \end{bmatrix} ,\f]
where \f$f_x\f$ and \f$f_y\f$ are \f$(0,0)\f$ and \f$(1,1)\f$ elements of cameraMatrix, respectively.
By default, the undistortion functions in OpenCV (see #initUndistortRectifyMap, #undistort) do not
move the principal point. However, when you work with stereo, it is important to move the principal
points in both views to the same y-coordinate (which is required by most of stereo correspondence
algorithms), and may be to the same x-coordinate too. So, you can form the new camera matrix for
each view where the principal points are located at the center.
@param cameraMatrix Input camera matrix.
@param imgsize Camera view image size in pixels.
@param centerPrincipalPoint Location of the principal point in the new camera matrix. The
parameter indicates whether this location should be at the image center or not.
*/
CV_EXPORTS_W
Mat getDefaultNewCameraMatrix(InputArray cameraMatrix, Size imgsize = Size(),
bool centerPrincipalPoint = false);
/** @brief Computes the ideal point coordinates from the observed point coordinates.
The function is similar to #undistort and #initUndistortRectifyMap but it operates on a
sparse set of points instead of a raster image. Also the function performs a reverse transformation
to projectPoints. In case of a 3D object, it does not reconstruct its 3D coordinates, but for a
planar object, it does, up to a translation vector, if the proper R is specified.
For each observed point coordinate \f$(u, v)\f$ the function computes:
\f[
\begin{array}{l}
x^{"} \leftarrow (u - c_x)/f_x \\
y^{"} \leftarrow (v - c_y)/f_y \\
(x',y') = undistort(x^{"},y^{"}, \texttt{distCoeffs}) \\
{[X\,Y\,W]} ^T \leftarrow R*[x' \, y' \, 1]^T \\
x \leftarrow X/W \\
y \leftarrow Y/W \\
\text{only performed if P is specified:} \\
u' \leftarrow x {f'}_x + {c'}_x \\
v' \leftarrow y {f'}_y + {c'}_y
\end{array}
\f]
where *undistort* is an approximate iterative algorithm that estimates the normalized original
point coordinates out of the normalized distorted point coordinates ("normalized" means that the
coordinates do not depend on the camera matrix).
The function can be used for both a stereo camera head or a monocular camera (when R is empty).
@param src Observed point coordinates, 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);
//! @} calib3d
/** @brief The methods in this namespace use a so-called fisheye camera model.
@@ -379,6 +379,39 @@ CVAPI(void) cvReprojectImageTo3D( const CvArr* disparityImage,
CvArr* _3dImage, const CvMat* Q,
int handleMissingValues CV_DEFAULT(0) );
/** @brief Transforms the input image to compensate lens distortion
@see cv::undistort
*/
CVAPI(void) cvUndistort2( const CvArr* src, CvArr* dst,
const CvMat* camera_matrix,
const CvMat* distortion_coeffs,
const CvMat* new_camera_matrix CV_DEFAULT(0) );
/** @brief Computes transformation map from intrinsic camera parameters
that can used by cvRemap
*/
CVAPI(void) cvInitUndistortMap( const CvMat* camera_matrix,
const CvMat* distortion_coeffs,
CvArr* mapx, CvArr* mapy );
/** @brief Computes undistortion+rectification map for a head of stereo camera
@see cv::initUndistortRectifyMap
*/
CVAPI(void) cvInitUndistortRectifyMap( const CvMat* camera_matrix,
const CvMat* dist_coeffs,
const CvMat *R, const CvMat* new_camera_matrix,
CvArr* mapx, CvArr* mapy );
/** @brief Computes the original (undistorted) feature coordinates
from the observed (distorted) coordinates
@see cv::undistortPoints
*/
CVAPI(void) cvUndistortPoints( const CvMat* src, CvMat* dst,
const CvMat* camera_matrix,
const CvMat* dist_coeffs,
const CvMat* R CV_DEFAULT(0),
const CvMat* P CV_DEFAULT(0));
/** @} calib3d_c */
#ifdef __cplusplus
@@ -1,6 +1,7 @@
package org.opencv.test.calib3d;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDouble;
@@ -14,6 +15,15 @@ import org.opencv.imgproc.Imgproc;
public class Calib3dTest extends OpenCVTestCase {
Size size;
@Override
protected void setUp() throws Exception {
super.setUp();
size = new Size(3, 3);
}
public void testCalibrateCameraListOfMatListOfMatSizeMatMatListOfMatListOfMat() {
fail("Not yet implemented");
}
@@ -602,4 +612,131 @@ public class Calib3dTest extends OpenCVTestCase {
Calib3d.computeCorrespondEpilines(left, 1, fundamental, lines);
assertMatEqual(truth, lines, EPS);
}
public void testGetDefaultNewCameraMatrixMat() {
Mat mtx = Calib3d.getDefaultNewCameraMatrix(gray0);
assertFalse(mtx.empty());
assertEquals(0, Core.countNonZero(mtx));
}
public void testGetDefaultNewCameraMatrixMatSizeBoolean() {
Mat mtx = Calib3d.getDefaultNewCameraMatrix(gray0, size, true);
assertFalse(mtx.empty());
assertFalse(0 == Core.countNonZero(mtx));
// TODO_: write better test
}
public void testInitUndistortRectifyMap() {
fail("Not yet implemented");
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
cameraMatrix.put(0, 0, 1, 0, 1);
cameraMatrix.put(1, 0, 0, 1, 1);
cameraMatrix.put(2, 0, 0, 0, 1);
Mat R = new Mat(3, 3, CvType.CV_32F, new Scalar(2));
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat distCoeffs = new Mat();
Mat map1 = new Mat();
Mat map2 = new Mat();
// TODO: complete this test
Calib3d.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, CvType.CV_32F, map1, map2);
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMat() {
fail("Not yet implemented");
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F);
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F);
// Size imageSize = new Size(2, 2);
cameraMatrix.put(0, 0, 1, 0, 1);
cameraMatrix.put(1, 0, 0, 1, 2);
cameraMatrix.put(2, 0, 0, 0, 1);
distCoeffs.put(0, 0, 1, 3, 2, 4);
truth = new Mat(3, 3, CvType.CV_32F);
truth.put(0, 0, 0, 0, 0);
truth.put(1, 0, 0, 0, 0);
truth.put(2, 0, 0, 3, 0);
// TODO: No documentation for this function
// Calib3d.initWideAngleProjMap(cameraMatrix, distCoeffs, imageSize,
// 5, m1type, truthput1, truthput2);
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatInt() {
fail("Not yet implemented");
}
public void testInitWideAngleProjMapMatMatSizeIntIntMatMatIntDouble() {
fail("Not yet implemented");
}
public void testUndistortMatMatMatMat() {
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 1, 0, 1);
put(1, 0, 0, 1, 2);
put(2, 0, 0, 0, 1);
}
};
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
{
put(0, 0, 1, 3, 2, 4);
}
};
Calib3d.undistort(src, dst, cameraMatrix, distCoeffs);
truth = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 0, 0, 0);
put(1, 0, 0, 0, 0);
put(2, 0, 0, 3, 0);
}
};
assertMatEqual(truth, dst, EPS);
}
public void testUndistortMatMatMatMatMat() {
Mat src = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
Mat cameraMatrix = new Mat(3, 3, CvType.CV_32F) {
{
put(0, 0, 1, 0, 1);
put(1, 0, 0, 1, 2);
put(2, 0, 0, 0, 1);
}
};
Mat distCoeffs = new Mat(1, 4, CvType.CV_32F) {
{
put(0, 0, 2, 1, 4, 5);
}
};
Mat newCameraMatrix = new Mat(3, 3, CvType.CV_32F, new Scalar(1));
Calib3d.undistort(src, dst, cameraMatrix, distCoeffs, newCameraMatrix);
truth = new Mat(3, 3, CvType.CV_32F, new Scalar(3));
assertMatEqual(truth, dst, EPS);
}
//undistortPoints(List<Point> src, List<Point> dst, Mat cameraMatrix, Mat distCoeffs)
public void testUndistortPointsListOfPointListOfPointMatMat() {
MatOfPoint2f src = new MatOfPoint2f(new Point(1, 2), new Point(3, 4), new Point(-1, -1));
MatOfPoint2f dst = new MatOfPoint2f();
Mat cameraMatrix = Mat.eye(3, 3, CvType.CV_64FC1);
Mat distCoeffs = new Mat(8, 1, CvType.CV_64FC1, new Scalar(0));
Calib3d.undistortPoints(src, dst, cameraMatrix, distCoeffs);
assertEquals(src.size(), dst.size());
for(int i=0; i<src.toList().size(); i++) {
//Log.d("UndistortPoints", "s="+src.get(i)+", d="+dst.get(i));
assertTrue(src.toList().get(i).equals(dst.toList().get(i)));
}
}
}
+4 -1
View File
@@ -42,7 +42,7 @@
#include "precomp.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/detail/distortion_model.hpp"
#include "distortion_model.hpp"
#include "opencv2/calib3d/calib3d_c.h"
#include <stdio.h>
#include <iterator>
@@ -3541,6 +3541,9 @@ double cv::stereoCalibrate( InputArrayOfArrays _objectPoints,
OutputArray _Emat, OutputArray _Fmat, int flags,
TermCriteria criteria)
{
if (flags & CALIB_USE_EXTRINSIC_GUESS)
CV_Error(Error::StsBadFlag, "stereoCalibrate does not support CALIB_USE_EXTRINSIC_GUESS.");
Mat Rmat, Tmat;
double ret = stereoCalibrate(_objectPoints, _imagePoints1, _imagePoints2, _cameraMatrix1, _distCoeffs1,
_cameraMatrix2, _distCoeffs2, imageSize, Rmat, Tmat, _Emat, _Fmat,
+211 -193
View File
@@ -10,7 +10,7 @@
//#define CV_DETECTORS_CHESSBOARD_DEBUG
#ifdef CV_DETECTORS_CHESSBOARD_DEBUG
#include <opencv2/highgui.hpp>
cv::Mat debug_image;
static cv::Mat debug_image;
#endif
using namespace std;
@@ -21,19 +21,19 @@ namespace details {
/////////////////////////////////////////////////////////////////////////////
// magic numbers used for chessboard corner detection
/////////////////////////////////////////////////////////////////////////////
const float CORNERS_SEARCH = 0.5F; // percentage of the edge length to the next corner used to find new corners
const float MAX_ANGLE = float(48.0/180.0*M_PI); // max angle between line segments supposed to be straight
const float MIN_COS_ANGLE = float(cos(35.0/180*M_PI)); // min cos angle between board edges
const float MIN_RESPONSE_RATIO = 0.3F;
const float ELLIPSE_WIDTH = 0.35F; // width of the search ellipse in percentage of its length
const float RAD2DEG = float(180.0/M_PI);
const int MAX_SYMMETRY_ERRORS = 5; // maximal number of failures during point symmetry test (filtering out lines)
static const float CORNERS_SEARCH = 0.5F; // percentage of the edge length to the next corner used to find new corners
static const float MAX_ANGLE = float(48.0/180.0*CV_PI); // max angle between line segments supposed to be straight
static const float MIN_COS_ANGLE = float(cos(35.0/180*CV_PI)); // min cos angle between board edges
static const float MIN_RESPONSE_RATIO = 0.1F;
static const float ELLIPSE_WIDTH = 0.35F; // width of the search ellipse in percentage of its length
static const float RAD2DEG = float(180.0/CV_PI);
static const int MAX_SYMMETRY_ERRORS = 5; // maximal number of failures during point symmetry test (filtering out lines)
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// some helper methods
static bool isPointOnLine(cv::Point2f l1,cv::Point2f l2,cv::Point2f pt,float min_angle);
static int testPointSymmetry(cv::Mat mat,cv::Point2f pt,float dist,float max_error);
static int testPointSymmetry(const cv::Mat& mat,cv::Point2f pt,float dist,float max_error);
static float calcSubpixel(const float &x_l,const float &x,const float &x_r);
static float calcSubPos(const float &x_l,const float &x,const float &x_r);
static void polyfit(const Mat& src_x, const Mat& src_y, Mat& dst, int order);
@@ -60,26 +60,23 @@ void normalizePoints1D(cv::InputArray _points,cv::OutputArray _T,cv::OutputArray
CV_Error(Error::StsBadArg, "all given points are identical");
double scale = 1.0/mean_dist;
// generate transformation
_T.create(2,2,CV_64FC1);
cv::Mat T = _T.getMat();
T.at<double>(0,0) = scale;
T.at<double>(0,1) = -scale*centroid;
T.at<double>(1,0) = 0;
T.at<double>(1,1) = 1;
cv::Matx22d Tx(
scale, -scale*centroid,
0, 1
);
Mat(Tx, false).copyTo(_T);
// calc normalized points;
cv::Matx22d Tx(T);
_new_points.create(points.rows,1,points.type());
new_points = _new_points.getMat();
cv::Vec2d p;
switch(points.type())
{
case CV_32FC1:
for(int i=0;i < points.rows;++i)
{
p(0) = points.at<float>(i);
p(1) = 1.0;
cv::Vec2d p(points.at<float>(i), 1.0);
p = Tx*p;
new_points.at<float>(i) = float(p(0)/p(1));
}
@@ -87,8 +84,7 @@ void normalizePoints1D(cv::InputArray _points,cv::OutputArray _T,cv::OutputArray
case CV_64FC1:
for(int i=0;i < points.rows;++i)
{
p(0) = points.at<double>(i);
p(1) = 1.0;
cv::Vec2d p(points.at<double>(i), 1.0);
p = Tx*p;
new_points.at<double>(i) = p(0)/p(1);
}
@@ -107,8 +103,7 @@ cv::Mat findHomography1D(cv::InputArray _src,cv::InputArray _dst)
src = src.reshape(1,src.cols);
if(dst.cols > 1 && dst.rows == 1)
dst = dst.reshape(1,dst.cols);
if(src.rows != dst.rows)
CV_Error(Error::StsBadArg, "size mismatch");
CV_CheckEQ(src.rows, dst.rows, "size mismatch");
CV_CheckChannelsEQ(src.channels(), 1, "data with only one channel are supported");
CV_CheckChannelsEQ(dst.channels(), 1, "data with only one channel are supported");
CV_CheckTypeEQ(src.type(), dst.type(), "src and dst must have the same type");
@@ -163,10 +158,10 @@ cv::Mat findHomography1D(cv::InputArray _src,cv::InputArray _dst)
y.at<double>(i) = b_.at<double>(i)/d.at<double>(i);
cv::Mat x = vt.t()*y;
cv::Mat H = (cv::Mat_<double>(2,2) << x.at<double>(0), x.at<double>(1), x.at<double>(2), 1.0);
cv::Matx22d H_(x.at<double>(0), x.at<double>(1), x.at<double>(2), 1.0);
// denormalize
H = dst_T.inv()*H*src_T;
Mat H = dst_T.inv()*Mat(H_, false)*src_T;
// enforce frobeniusnorm of one
double scale = 1.0/cv::norm(H);
@@ -177,8 +172,8 @@ void polyfit(const Mat& src_x, const Mat& src_y, Mat& dst, int order)
int npoints = src_x.checkVector(1);
int nypoints = src_y.checkVector(1);
CV_Assert(npoints == nypoints && npoints >= order+1);
Mat srcX = Mat_<double>(src_x), srcY = Mat_<double>(src_y);
Mat A = Mat_<double>::ones(npoints,order + 1);
Mat_<double> srcX(src_x), srcY(src_y);
Mat_<double> A = Mat_<double>::ones(npoints,order + 1);
// build A matrix
for (int y = 0; y < npoints; ++y)
{
@@ -187,7 +182,7 @@ void polyfit(const Mat& src_x, const Mat& src_y, Mat& dst, int order)
}
cv::Mat w;
solve(A,srcY,w,DECOMP_SVD);
w.convertTo(dst,std::max(std::max(src_x.depth(), src_y.depth()), CV_32F));
w.convertTo(dst, ((src_x.depth() == CV_64F || src_y.depth() == CV_64F) ? CV_64F : CV_32F));
}
float calcSignedDistance(const cv::Vec2f &n,const cv::Point2f &a,const cv::Point2f &pt)
@@ -207,15 +202,16 @@ bool isPointOnLine(cv::Point2f l1,cv::Point2f l2,cv::Point2f pt,float min_angle)
}
// returns how many tests fails out of 10
int testPointSymmetry(cv::Mat mat,cv::Point2f pt,float dist,float max_error)
int testPointSymmetry(const cv::Mat& mat,cv::Point2f pt,float dist,float max_error)
{
cv::Rect image_rect(int(0.5*dist),int(0.5*dist),int(mat.cols-0.5*dist),int(mat.rows-0.5*dist));
cv::Size size(int(0.5*dist),int(0.5*dist));
int count = 0;
cv::Mat patch1,patch2;
cv::Point2f center1,center2;
for(double angle=0;angle <= M_PI;angle+=M_PI*0.1)
for (int angle_i = 0; angle_i < 10; angle_i++)
{
double angle = angle_i * (CV_PI * 0.1);
cv::Point2f n(float(cos(angle)),float(-sin(angle)));
center1 = pt+dist*n;
if(!image_rect.contains(center1))
@@ -284,8 +280,7 @@ void FastX::rotate(float angle,const cv::Mat &img,cv::Size size,cv::Mat &out)con
}
else
{
cv::Mat m = cv::getRotationMatrix2D(cv::Point2f(float(img.cols*0.5),float(img.rows*0.5)),float(angle/M_PI*180),1);
CV_Assert(m.type() == CV_64FC1);
cv::Mat_<double> m = cv::getRotationMatrix2D(cv::Point2f(float(img.cols*0.5),float(img.rows*0.5)),float(angle/CV_PI*180),1);
m.at<double>(0,2) += 0.5*(size.width-img.cols);
m.at<double>(1,2) += 0.5*(size.height-img.rows);
cv::warpAffine(img,out,m,size);
@@ -390,7 +385,7 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
// assuming all elements of the same channel
const int channels = rotated_images.front().channels();
int channels_1 = channels-1;
float resolution = float(M_PI/channels);
float resolution = float(CV_PI/channels);
float angle;
float val1,val2,val3,wrap_around;
@@ -436,9 +431,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
{
angle = float((calcSubPos(val1,val2,val3)+i)*resolution);
if(angle < 0)
angle += float(M_PI);
else if(angle > M_PI)
angle -= float(M_PI);
angle += float(CV_PI);
else if(angle > CV_PI)
angle -= float(CV_PI);
angles_i.push_back(angle);
pt_iter->angle = 360.0F-angle*RAD2DEG;
}
@@ -447,9 +442,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
{
angle = float((calcSubPos(val1,val2,val3)+i)*resolution);
if(angle < 0)
angle += float(M_PI);
else if(angle > M_PI)
angle -= float(M_PI);
angle += float(CV_PI);
else if(angle > CV_PI)
angle -= float(CV_PI);
angles_i.push_back(-angle);
pt_iter->angle = 360.0F-angle*RAD2DEG;
}
@@ -463,9 +458,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
{
angle = float((calcSubPos(val1,val2,wrap_around)+channels-1)*resolution);
if(angle < 0)
angle += float(M_PI);
else if(angle > M_PI)
angle -= float(M_PI);
angle += float(CV_PI);
else if(angle > CV_PI)
angle -= float(CV_PI);
angles_i.push_back(angle);
pt_iter->angle = 360.0F-angle*RAD2DEG;
}
@@ -474,9 +469,9 @@ std::vector<std::vector<float> > FastX::calcAngles(const std::vector<cv::Mat> &r
{
angle = float((calcSubPos(val1,val2,wrap_around)+channels-1)*resolution);
if(angle < 0)
angle += float(M_PI);
else if(angle > M_PI)
angle -= float(M_PI);
angle += float(CV_PI);
else if(angle > CV_PI)
angle -= float(CV_PI);
angles_i.push_back(-angle);
pt_iter->angle = 360.0F-angle*RAD2DEG;
}
@@ -488,10 +483,12 @@ void FastX::findKeyPoints(const std::vector<cv::Mat> &feature_maps, std::vector<
{
//TODO check that all feature_maps have the same size
int num_scales = parameters.max_scale-parameters.min_scale;
if(int(feature_maps.size()) < num_scales)
CV_Error(Error::StsBadArg,"missing feature maps");
if(_mask.data && (_mask.type() != CV_8UC1 || _mask.size() != feature_maps.front().size()))
CV_Error(Error::StsBadMask,"wrong mask type or size");
CV_CheckGE(int(feature_maps.size()), num_scales, "missing feature maps");
if (!_mask.empty())
{
CV_CheckTypeEQ(_mask.type(), CV_8UC1, "wrong mask type");
CV_CheckEQ(_mask.size(), feature_maps.front().size(),"wrong mask type or size");
}
keypoints.clear();
cv::Mat mask;
@@ -512,10 +509,10 @@ void FastX::findKeyPoints(const std::vector<cv::Mat> &feature_maps, std::vector<
cv::Mat src;
for(int scale=parameters.max_scale;scale>=parameters.min_scale;--scale)
{
int window_size = int(pow(2.0,scale+super_res)+1);
int window_size = (1 << (scale + super_res)) + 1;
float window_size2 = 0.5F*window_size;
float window_size4 = 0.25F*window_size;
int window_size2i = int(round(window_size2));
int window_size2i = cvRound(window_size2);
const cv::Mat &feature_map = feature_maps[scale-parameters.min_scale];
int y = ((feature_map.rows)/window_size)-6;
@@ -602,63 +599,67 @@ void FastX::detectAndCompute(cv::InputArray image,cv::InputArray mask,std::vecto
return;
}
void FastX::detectImpl(const cv::Mat& gray_image,
void FastX::detectImpl(const cv::Mat& _gray_image,
std::vector<cv::Mat> &rotated_images,
std::vector<cv::Mat> &feature_maps,
const cv::Mat &_mask)const
{
if(!_mask.empty())
CV_Error(Error::StsBadSize, "Mask is not supported");
CV_CheckTypeEQ(gray_image.type(), CV_8UC1, "Unsupported image type");
CV_CheckTypeEQ(_gray_image.type(), CV_8UC1, "Unsupported image type");
// up-sample if needed
cv::Mat gray_image;
int super_res = int(parameters.super_resolution);
if(super_res)
cv::resize(gray_image,gray_image,cv::Size(),2,2);
cv::resize(_gray_image,gray_image,cv::Size(),2,2);
else
gray_image = _gray_image;
//for each scale
int num_scales = parameters.max_scale-parameters.min_scale+1;
rotated_images.resize(num_scales);
feature_maps.resize(num_scales);
for(int scale=parameters.min_scale;scale <= parameters.max_scale;++scale)
{
// calc images
// for each angle step
int scale_id = scale-parameters.min_scale;
cv::Mat rotated,filtered_h,filtered_v;
int diag = int(sqrt(gray_image.rows*gray_image.rows+gray_image.cols*gray_image.cols));
cv::Size size(diag,diag);
int num = int(0.5001*M_PI/parameters.resolution);
std::vector<cv::Mat> images;
images.resize(2*num);
int scale_size = int(1+pow(2.0,scale+1+super_res));
int scale_size2 = int((scale_size/10)*2+1);
for(int i=0;i<num;++i)
parallel_for_(Range(parameters.min_scale,parameters.max_scale+1),[&](const Range& range){
for(int scale=range.start;scale < range.end;++scale)
{
float angle = parameters.resolution*i;
rotate(-angle,gray_image,size,rotated);
cv::blur(rotated,filtered_h,cv::Size(scale_size,scale_size2));
cv::blur(rotated,filtered_v,cv::Size(scale_size2,scale_size));
// calc images
// for each angle step
int scale_id = scale-parameters.min_scale;
cv::Mat rotated,filtered_h,filtered_v;
int diag = int(sqrt(gray_image.rows*gray_image.rows+gray_image.cols*gray_image.cols));
cv::Size size(diag,diag);
int num = int(0.5001*CV_PI/parameters.resolution);
std::vector<cv::Mat> images;
images.resize(2*num);
int scale_size = int(1+pow(2.0,scale+1+super_res));
int scale_size2 = int((scale_size/10)*2+1);
for(int i=0;i<num;++i)
{
float angle = parameters.resolution*i;
rotate(-angle,gray_image,size,rotated);
cv::blur(rotated,filtered_h,cv::Size(scale_size,scale_size2));
cv::blur(rotated,filtered_v,cv::Size(scale_size2,scale_size));
// rotate filtered images back
rotate(angle,filtered_h,gray_image.size(),images[i]);
rotate(angle,filtered_v,gray_image.size(),images[i+num]);
// rotate filtered images back
rotate(angle,filtered_h,gray_image.size(),images[i]);
rotate(angle,filtered_v,gray_image.size(),images[i+num]);
}
cv::merge(images,rotated_images[scale_id]);
// calc feature map
calcFeatureMap(rotated_images[scale_id],feature_maps[scale_id]);
// filter feature map to improve impulse responses
if(parameters.filter)
{
cv::Mat high,low;
cv::blur(feature_maps[scale_id],low,cv::Size(scale_size,scale_size));
int scale2 = int((scale_size/6))*2+1;
cv::blur(feature_maps[scale_id],high,cv::Size(scale2,scale2));
feature_maps[scale_id] = high-0.8*low;
}
}
cv::merge(images,rotated_images[scale_id]);
// calc feature map
calcFeatureMap(rotated_images[scale_id],feature_maps[scale_id]);
// filter feature map to improve impulse responses
if(parameters.filter)
{
cv::Mat high,low;
cv::blur(feature_maps[scale_id],low,cv::Size(scale_size,scale_size));
int scale2 = int((scale_size/6))*2+1;
cv::blur(feature_maps[scale_id],high,cv::Size(scale2,scale2));
feature_maps[scale_id] = high-0.8*low;
}
}
});
}
void FastX::detectImpl(const cv::Mat& image,std::vector<cv::KeyPoint>& keypoints,std::vector<cv::Mat> &feature_maps,const cv::Mat &mask)const
@@ -718,7 +719,7 @@ cv::Point2f Ellipse::getCenter()const
void Ellipse::draw(cv::InputOutputArray img,const cv::Scalar &color)const
{
cv::ellipse(img,center,axes,360-angle/M_PI*180,0,360,color);
cv::ellipse(img,center,axes,360-angle/CV_PI*180,0,360,color);
}
bool Ellipse::contains(const cv::Point2f &pt)const
@@ -1078,10 +1079,8 @@ const cv::Point2f* Chessboard::Board::PointIter::operator*()const
return cell->bottom_right;
case BOTTOM_LEFT:
return cell->bottom_left;
default:
CV_Assert(false);
}
return NULL;
CV_Assert(false);
}
const cv::Point2f* Chessboard::Board::PointIter::operator->()const
@@ -1252,10 +1251,8 @@ void Chessboard::Board::draw(cv::InputArray m,cv::OutputArray out,cv::InputArray
bool Chessboard::Board::estimatePose(const cv::Size2f &real_size,cv::InputArray _K,cv::OutputArray rvec,cv::OutputArray tvec)const
{
cv::Mat K = _K.getMat();
if(K.type() != CV_64FC1)
throw std::runtime_error("wrong K type");
if(K.rows != 3|| K.cols != 3)
throw std::runtime_error("wrong K size");
CV_CheckTypeEQ(K.type(), CV_64FC1, "wrong K type");
CV_CheckEQ(K.size(), Size(3, 3), "wrong K size");
if(isEmpty())
return false;
@@ -1516,8 +1513,9 @@ void Chessboard::Board::flipVertical()
float Chessboard::Board::findMaxPoint(cv::flann::Index &index,const cv::Mat &data,const Ellipse &ellipse,float white_angle,float black_angle,cv::Point2f &point)
{
// flann data type enriched with angles (third column)
if(data.type() != CV_32FC1 || data.cols != 4)
CV_Error(Error::StsBadArg,"type of flann data is not supported. Expect CV_32FC1");
CV_CheckType(data.type(), CV_32FC1, "type of flann data is not supported");
CV_CheckEQ(data.cols, 4, "4-cols flann data is expected");
std::vector<float> query,dists;
std::vector<int> indices;
query.resize(2);
@@ -1536,15 +1534,15 @@ float Chessboard::Board::findMaxPoint(cv::flann::Index &index,const cv::Mat &dat
if(response < best_score)
continue;
const float &a0 = *(val+2);
float a1 = fabs(a0-white_angle);
float a2 = fabs(a0-black_angle);
if(a1 > M_PI*0.5)
a1= float(fabs(a1-M_PI));
if(a2> M_PI*0.5)
a2= float(fabs(a2-M_PI));
float a1 = std::fabs(a0-white_angle);
float a2 = std::fabs(a0-black_angle);
if(a1 > CV_PI*0.5)
a1 = std::fabs(float(a1-CV_PI));
if(a2> CV_PI*0.5)
a2 = std::fabs(float(a2-CV_PI));
if(a1 < MAX_ANGLE || a2 < MAX_ANGLE )
{
cv::Point2f pt(*val,*(val+1));
cv::Point2f pt(val[0], val[1]);
if(point.x != point.x) // NaN check
point = pt;
if(best_score < response && ellipse.contains(pt))
@@ -1784,7 +1782,7 @@ bool Chessboard::Board::estimateSearchArea(const cv::Point2f &p1,const cv::Point
n = n/norm;
float angle = acos(n.x);
if(n.y > 0)
angle = float(2.0F*M_PI-angle);
angle = float(2.0F*CV_PI-angle);
n = p4-p3;
norm = float(cv::norm(n));
double delta = std::max(3.0F,p*norm);
@@ -1865,6 +1863,7 @@ cv::Point2f &Chessboard::Board::getCorner(int _row,int _col)
}while(_row);
}
CV_Error(Error::StsInternal,"cannot find corner");
// return *top_left->top_left; // never reached
}
bool Chessboard::Board::isCellBlack(int row,int col)const
@@ -2790,7 +2789,7 @@ void Chessboard::findKeyPoints(const cv::Mat& image, std::vector<KeyPoint>& keyp
para.branches = 2; // this is always the case for checssboard corners
para.strength = 10; // minimal threshold
para.resolution = float(M_PI*0.25); // this gives the best results taking interpolation into account
para.resolution = float(CV_PI*0.25); // this gives the best results taking interpolation into account
para.filter = 1;
para.super_resolution = parameters.super_resolution;
para.min_scale = parameters.min_scale;
@@ -2841,7 +2840,7 @@ cv::Mat Chessboard::buildData(const std::vector<KeyPoint>& keypoints)const
{
(*val++) = iter->pt.x;
(*val++) = iter->pt.y;
(*val++) = float(2.0*M_PI-iter->angle/180.0*M_PI);
(*val++) = float(2.0*CV_PI-iter->angle/180.0*CV_PI);
(*val++) = iter->response;
}
return data;
@@ -2871,13 +2870,13 @@ std::vector<cv::KeyPoint> Chessboard::getInitialPoints(cv::flann::Index &flann_i
continue;
const float &angle = data.at<float>(*ids_iter,2);
float angle_temp = fabs(angle-white_angle);
if(angle_temp > M_PI*0.5)
angle_temp = float(fabs(angle_temp-M_PI));
if(angle_temp > CV_PI*0.5)
angle_temp = float(fabs(angle_temp-CV_PI));
if(angle_temp > MAX_ANGLE)
{
angle_temp = fabs(angle-black_angle);
if(angle_temp > M_PI*0.5)
angle_temp = float(fabs(angle_temp-M_PI));
if(angle_temp > CV_PI*0.5)
angle_temp = float(fabs(angle_temp-CV_PI));
if(angle_temp >MAX_ANGLE)
continue;
}
@@ -3008,11 +3007,6 @@ Chessboard::Board Chessboard::detectImpl(const Mat& gray,std::vector<cv::Mat> &f
#endif
CV_CheckTypeEQ(gray.type(),CV_8UC1, "Unsupported image type");
//TODO is this needed?
// double min,max;
// cv::minMaxLoc(gray,&min,&max);
// gray = (gray-min)*(255.0/(max-min));
cv::Size chessboard_size2(parameters.chessboard_size.height,parameters.chessboard_size.width);
std::vector<KeyPoint> keypoints_seed;
std::vector<std::vector<float> > angles;
@@ -3025,17 +3019,15 @@ Chessboard::Board Chessboard::detectImpl(const Mat& gray,std::vector<cv::Mat> &f
std::vector<KeyPoint>::const_iterator seed_iter = keypoints_seed.begin();
int count = 0;
int inum = chessboard_size2.width*chessboard_size2.height;
for(;seed_iter != keypoints_seed.end();++seed_iter)
for(;seed_iter != keypoints_seed.end() && count < inum;++seed_iter,++count)
{
if(fabs(seed_iter->response) > response)
// points are sorted based on response
if(fabs(seed_iter->response) < response)
{
++count;
if(count >= inum)
break;
seed_iter = keypoints_seed.end();
return Chessboard::Board();
}
}
if(seed_iter == keypoints_seed.end())
return Chessboard::Board();
// just add dummy points or flann will fail during knnSearch
if(keypoints_seed.size() < 21)
keypoints_seed.resize(21, cv::KeyPoint(-99999.0F,-99999.0F,0.0F,0.0F,0.0F));
@@ -3070,60 +3062,71 @@ Chessboard::Board Chessboard::detectImpl(const Mat& gray,std::vector<cv::Mat> &f
std::vector<Board> boards;
generateBoards(flann_index, data,*points_iter,white_angle,black_angle,min_response,gray,boards);
std::vector<Chessboard::Board>::iterator iter_boards = boards.begin();
for(;iter_boards != boards.end();++iter_boards)
{
cv::Mat h = iter_boards->estimateHomography();
int size = iter_boards->validateCorners(data,flann_index,h,min_response);
if(size != 9)
continue;
if(!iter_boards->validateContour())
continue;
//grow based on kd-tree
iter_boards->grow(data,flann_index);
if(!iter_boards->checkUnique())
continue;
// check bounding box
std::vector<cv::Point2f> contour = iter_boards->getContour();
std::vector<cv::Point2f>::const_iterator iter = contour.begin();
for(;iter != contour.end();++iter)
parallel_for_(Range(0,(int)boards.size()),[&](const Range& range){
for(int i=range.start;i <range.end;++i)
{
if(!bounding_box.contains(*iter))
break;
}
if(iter != contour.end())
continue;
if(iter_boards->getSize() == parameters.chessboard_size ||
iter_boards->getSize() == chessboard_size2)
{
iter_boards->normalizeOrientation(false);
if(iter_boards->getSize() != parameters.chessboard_size)
auto iter_boards = boards.begin()+i;
cv::Mat h = iter_boards->estimateHomography();
int size = iter_boards->validateCorners(data,flann_index,h,min_response);
if(size != 9 || !iter_boards->validateContour())
{
if(iter_boards->isCellBlack(0,0) == iter_boards->isCellBlack(0,int(iter_boards->colCount())-1))
iter_boards->rotateLeft();
else
iter_boards->rotateRight();
iter_boards->clear();
continue;
}
//grow based on kd-tree
iter_boards->grow(data,flann_index);
if(!iter_boards->checkUnique())
{
iter_boards->clear();
continue;
}
// check bounding box
std::vector<cv::Point2f> contour = iter_boards->getContour();
std::vector<cv::Point2f>::const_iterator iter = contour.begin();
for(;iter != contour.end();++iter)
{
if(!bounding_box.contains(*iter))
break;
}
if(iter != contour.end())
{
iter_boards->clear();
continue;
}
if(iter_boards->getSize() == parameters.chessboard_size ||
iter_boards->getSize() == chessboard_size2)
{
iter_boards->normalizeOrientation(false);
if(iter_boards->getSize() != parameters.chessboard_size)
{
if(iter_boards->isCellBlack(0,0) == iter_boards->isCellBlack(0,int(iter_boards->colCount())-1))
iter_boards->rotateLeft();
else
iter_boards->rotateRight();
}
#ifdef CV_DETECTORS_CHESSBOARD_DEBUG
cv::Mat img;
iter_boards->draw(debug_image,img);
cv::imshow("chessboard",img);
cv::waitKey(-1);
cv::Mat img;
iter_boards->draw(debug_image,img);
cv::imshow("chessboard",img);
cv::waitKey(-1);
#endif
return *iter_boards;
}
else
{
if(iter_boards->getSize().width*iter_boards->getSize().height > chessboard_size2.width*chessboard_size2.height)
}
else
{
if(parameters.larger)
return *iter_boards;
else
return Chessboard::Board();
if(iter_boards->getSize().width*iter_boards->getSize().height < chessboard_size2.width*chessboard_size2.height)
iter_boards->clear();
else if(!parameters.larger)
iter_boards->clear();
}
}
});
// check if a good board was found
for(const auto &board : boards)
{
if(!board.isEmpty())
return board;
}
}
return Chessboard::Board();
@@ -3152,16 +3155,15 @@ void Chessboard::detectImpl(InputArray image, std::vector<KeyPoint>& keypoints,
detectImpl(image.getMat(),keypoints,mask.getMat());
}
}} // end namespace details and cv
} // end namespace details
// public API
bool cv::findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
cv::OutputArray corners_, int flags)
bool findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
cv::OutputArray corners_, int flags)
{
CV_INSTRUMENT_REGION();
int type = image_.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
Mat img = image_.getMat();
CV_CheckType(type, depth == CV_8U && (cn == 1 || cn == 3),
"Only 8-bit grayscale or color images are supported");
if(pattern_size.width <= 2 || pattern_size.height <= 2)
@@ -3170,29 +3172,43 @@ bool cv::findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
}
if (!corners_.needed())
CV_Error(Error::StsNullPtr, "Null pointer to corners");
if (img.channels() != 1)
cvtColor(img, img, COLOR_BGR2GRAY);
Mat img;
if (image_.channels() != 1)
cvtColor(image_, img, COLOR_BGR2GRAY);
else
img = image_.getMat();
details::Chessboard::Parameters para;
para.chessboard_size = pattern_size;
para.min_scale = 2;
para.max_scale = 4;
para.max_tests = 25;
para.max_points = std::max(100,pattern_size.width*pattern_size.height*2);
para.super_resolution = false;
switch(flags)
// setup search based on flags
if(flags & CALIB_CB_NORMALIZE_IMAGE)
{
case 1: // high accuracy profile
para.min_scale = 2;
para.max_scale = 4;
para.max_tests = 100;
para.super_resolution = true;
para.max_points = std::max(500,pattern_size.width*pattern_size.height*2);
break;
default: // default profile
para.min_scale = 2;
para.max_scale = 3;
para.max_tests = 20;
para.max_points = pattern_size.width*pattern_size.height*2;
para.super_resolution = false;
break;
Mat tmp;
cv::equalizeHist(img, tmp);
swap(img, tmp);
flags ^= CALIB_CB_NORMALIZE_IMAGE;
}
if(flags & CALIB_CB_EXHAUSTIVE)
{
para.max_tests = 100;
para.max_points = std::max(500,pattern_size.width*pattern_size.height*2);
flags ^= CALIB_CB_EXHAUSTIVE;
}
if(flags & CALIB_CB_ACCURACY)
{
para.super_resolution = true;
flags ^= CALIB_CB_ACCURACY;
}
if(flags)
CV_Error(Error::StsOutOfRange, cv::format("Invalid remaing flags %d", (int)flags));
std::vector<cv::KeyPoint> corners;
details::Chessboard board(para);
board.detect(img,corners);
@@ -3206,3 +3222,5 @@ bool cv::findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
Mat(points).copyTo(corners_);
return true;
}
} // namespace cv
+1 -1
View File
@@ -32,7 +32,7 @@ class FastX : public cv::Feature2D
Parameters()
{
strength = 40;
resolution = float(M_PI*0.25);
resolution = float(CV_PI*0.25);
branches = 2;
min_scale = 2;
max_scale = 5;
+2 -2
View File
@@ -534,7 +534,7 @@ void cv::fisheye::undistortImage(InputArray distorted, OutputArray undistorted,
{
CV_INSTRUMENT_REGION();
Size size = new_size.area() != 0 ? new_size : distorted.size();
Size size = !new_size.empty() ? new_size : distorted.size();
cv::Mat map1, map2;
fisheye::initUndistortRectifyMap(K, D, cv::Matx33d::eye(), Knew, size, CV_16SC2, map1, map2 );
@@ -601,7 +601,7 @@ void cv::fisheye::estimateNewCameraMatrixForUndistortRectify(InputArray K, Input
new_f[1] /= aspect_ratio;
new_c[1] /= aspect_ratio;
if (new_size.area() > 0)
if (!new_size.empty())
{
double rx = new_size.width /(double)image_size.width;
double ry = new_size.height/(double)image_size.height;
+2 -2
View File
@@ -1226,8 +1226,8 @@ public:
parallel_for_(Range(0, 2), PrefilterInvoker(left0, right0, left, right, _buf, _buf + bufSize1, &params), 1);
Rect validDisparityRect(0, 0, width, height), R1 = params.roi1, R2 = params.roi2;
validDisparityRect = getValidDisparityROI(R1.area() > 0 ? R1 : validDisparityRect,
R2.area() > 0 ? R2 : validDisparityRect,
validDisparityRect = getValidDisparityROI(!R1.empty() ? R1 : validDisparityRect,
!R2.empty() ? R2 : validDisparityRect,
params.minDisparity, params.numDisparities,
params.SADWindowSize);
@@ -41,9 +41,11 @@
//M*/
#include "precomp.hpp"
#include "opencv2/imgproc/detail/distortion_model.hpp"
#include "distortion_model.hpp"
#include "undistort.hpp"
#include "opencv2/calib3d/calib3d_c.h"
cv::Mat cv::getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize,
bool centerPrincipalPoint )
{
@@ -534,29 +536,31 @@ static void cvUndistortPointsInternal( const CvMat* _src, CvMat* _dst, const CvM
}
}
void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,
const CvMat* _distCoeffs,
const CvMat* matR, const CvMat* matP )
void cvUndistortPoints(const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatrix,
const CvMat* _distCoeffs,
const CvMat* matR, const CvMat* matP)
{
cvUndistortPointsInternal(_src, _dst, _cameraMatrix, _distCoeffs, matR, matP,
cv::TermCriteria(cv::TermCriteria::COUNT, 5, 0.01));
}
void cv::undistortPoints( InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat )
namespace cv {
void undistortPoints(InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat)
{
undistortPoints(_src, _dst, _cameraMatrix, _distCoeffs, _Rmat, _Pmat, TermCriteria(TermCriteria::MAX_ITER, 5, 0.01));
}
void cv::undistortPoints( InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat,
TermCriteria criteria)
void undistortPoints(InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat,
TermCriteria criteria)
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat();
@@ -578,10 +582,7 @@ void cv::undistortPoints( InputArray _src, OutputArray _dst,
cvUndistortPointsInternal(&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP, criteria);
}
namespace cv
{
static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int projType)
static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, enum UndistortTypes projType)
{
double x = p.x, y = p.y;
double beta = 1 + 2*alpha;
@@ -613,11 +614,11 @@ static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int pr
}
return Point2f((float)asin(x1), (float)asin(y1));
}
CV_Error(CV_StsBadArg, "Unknown projection type");
CV_Error(Error::StsBadArg, "Unknown projection type");
}
static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType)
static Point2f invMapPointSpherical(Point2f _p, float alpha, enum UndistortTypes projType)
{
double eps = 1e-12;
Vec2d p(_p.x, _p.y), q(_p.x, _p.y), err;
@@ -646,11 +647,10 @@ static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType)
return i < maxiter ? Point2f((float)q[0], (float)q[1]) : Point2f(-FLT_MAX, -FLT_MAX);
}
}
float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeffs0,
Size imageSize, int destImageWidth, int m1type,
OutputArray _map1, OutputArray _map2, int projType, double _alpha )
float initWideAngleProjMap(InputArray _cameraMatrix0, InputArray _distCoeffs0,
Size imageSize, int destImageWidth, int m1type,
OutputArray _map1, OutputArray _map2,
enum UndistortTypes projType, double _alpha)
{
Mat cameraMatrix0 = _cameraMatrix0.getMat(), distCoeffs0 = _distCoeffs0.getMat();
double k[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}, M[9]={0,0,0,0,0,0,0,0,0};
@@ -735,4 +735,5 @@ float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeff
return scale;
}
} // namespace
/* End of file */
@@ -40,8 +40,8 @@
//
//M*/
#ifndef OPENCV_IMGPROC_UNDISTORT_HPP
#define OPENCV_IMGPROC_UNDISTORT_HPP
#ifndef OPENCV_CALIB3D_UNDISTORT_HPP
#define OPENCV_CALIB3D_UNDISTORT_HPP
namespace cv
{
@@ -54,6 +54,6 @@ namespace cv
#endif
}
#endif
#endif // OPENCV_CALIB3D_UNDISTORT_HPP
/* End of file */
+12 -6
View File
@@ -409,6 +409,8 @@ bool CV_ChessboardDetectorTest::checkByGenerator()
int progress = 0;
for(int i = 0; i < test_num; ++i)
{
SCOPED_TRACE(cv::format("test_num=%d", test_num));
progress = update_progress( progress, i, test_num, 0 );
ChessBoardGenerator cbg(sizes[i % sizes_num]);
@@ -439,13 +441,17 @@ bool CV_ChessboardDetectorTest::checkByGenerator()
}
double err = calcErrorMinError(cbg.cornersSize(), corners_found, corners_generated);
if( err > rough_success_error_level )
EXPECT_LE(err, rough_success_error_level) << "bad accuracy of corner guesses";
#if 0
if (err >= rough_success_error_level)
{
ts->printf( cvtest::TS::LOG, "bad accuracy of corner guesses" );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
res = false;
return res;
imshow("cb", cb);
Mat cb_corners = cb.clone();
cv::drawChessboardCorners(cb_corners, cbg.cornersSize(), Mat(corners_found), found);
imshow("corners", cb_corners);
waitKey(0);
}
#endif
}
/* ***** negative ***** */
@@ -566,7 +572,7 @@ bool CV_ChessboardDetectorTest::checkByGeneratorHighAccuracy()
for(int i=15;i<90;i=i+15)
{
// project 3d points to new camera
Vec3f rvec(0.0F,0.05F,float(float(i)/180.0*M_PI));
Vec3f rvec(0.0F,0.05F,float(float(i)/180.0*CV_PI));
Vec3f tvec(0,0,0);
cv::Mat k = (cv::Mat_<double>(3,3) << fx/2,0,center.x*2, 0,fy/2,center.y, 0,0,1);
cv::projectPoints(pts3d,rvec,tvec,k,cv::Mat(),pts2_all);
+581
View File
@@ -42,6 +42,7 @@
#include "test_precomp.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/calib3d/calib3d_c.h"
namespace opencv_test { namespace {
@@ -938,4 +939,584 @@ TEST(Calib3d_DefaultNewCameraMatrix, accuracy) { CV_DefaultNewCameraMatrixTest t
TEST(Calib3d_UndistortPoints, accuracy) { CV_UndistortPointsTest test; test.safe_run(); }
TEST(Calib3d_InitUndistortRectifyMap, accuracy) { CV_InitUndistortRectifyMapTest test; test.safe_run(); }
////////////////////////////// undistort /////////////////////////////////
static void test_remap( const Mat& src, Mat& dst, const Mat& mapx, const Mat& mapy,
Mat* mask=0, int interpolation=CV_INTER_LINEAR )
{
int x, y, k;
int drows = dst.rows, dcols = dst.cols;
int srows = src.rows, scols = src.cols;
const uchar* sptr0 = src.ptr();
int depth = src.depth(), cn = src.channels();
int elem_size = (int)src.elemSize();
int step = (int)(src.step / CV_ELEM_SIZE(depth));
int delta;
if( interpolation != CV_INTER_CUBIC )
{
delta = 0;
scols -= 1; srows -= 1;
}
else
{
delta = 1;
scols = MAX(scols - 3, 0);
srows = MAX(srows - 3, 0);
}
int scols1 = MAX(scols - 2, 0);
int srows1 = MAX(srows - 2, 0);
if( mask )
*mask = Scalar::all(0);
for( y = 0; y < drows; y++ )
{
uchar* dptr = dst.ptr(y);
const float* mx = mapx.ptr<float>(y);
const float* my = mapy.ptr<float>(y);
uchar* m = mask ? mask->ptr(y) : 0;
for( x = 0; x < dcols; x++, dptr += elem_size )
{
float xs = mx[x];
float ys = my[x];
int ixs = cvFloor(xs);
int iys = cvFloor(ys);
if( (unsigned)(ixs - delta - 1) >= (unsigned)scols1 ||
(unsigned)(iys - delta - 1) >= (unsigned)srows1 )
{
if( m )
m[x] = 1;
if( (unsigned)(ixs - delta) >= (unsigned)scols ||
(unsigned)(iys - delta) >= (unsigned)srows )
continue;
}
xs -= ixs;
ys -= iys;
switch( depth )
{
case CV_8U:
{
const uchar* sptr = sptr0 + iys*step + ixs*cn;
for( k = 0; k < cn; k++ )
{
float v00 = sptr[k];
float v01 = sptr[cn + k];
float v10 = sptr[step + k];
float v11 = sptr[step + cn + k];
v00 = v00 + xs*(v01 - v00);
v10 = v10 + xs*(v11 - v10);
v00 = v00 + ys*(v10 - v00);
dptr[k] = (uchar)cvRound(v00);
}
}
break;
case CV_16U:
{
const ushort* sptr = (const ushort*)sptr0 + iys*step + ixs*cn;
for( k = 0; k < cn; k++ )
{
float v00 = sptr[k];
float v01 = sptr[cn + k];
float v10 = sptr[step + k];
float v11 = sptr[step + cn + k];
v00 = v00 + xs*(v01 - v00);
v10 = v10 + xs*(v11 - v10);
v00 = v00 + ys*(v10 - v00);
((ushort*)dptr)[k] = (ushort)cvRound(v00);
}
}
break;
case CV_32F:
{
const float* sptr = (const float*)sptr0 + iys*step + ixs*cn;
for( k = 0; k < cn; k++ )
{
float v00 = sptr[k];
float v01 = sptr[cn + k];
float v10 = sptr[step + k];
float v11 = sptr[step + cn + k];
v00 = v00 + xs*(v01 - v00);
v10 = v10 + xs*(v11 - v10);
v00 = v00 + ys*(v10 - v00);
((float*)dptr)[k] = (float)v00;
}
}
break;
default:
assert(0);
}
}
}
}
class CV_ImgWarpBaseTest : public cvtest::ArrayTest
{
public:
CV_ImgWarpBaseTest( bool warp_matrix );
protected:
int read_params( CvFileStorage* fs );
int prepare_test_case( int test_case_idx );
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
int interpolation;
int max_interpolation;
double spatial_scale_zoom, spatial_scale_decimate;
};
CV_ImgWarpBaseTest::CV_ImgWarpBaseTest( bool warp_matrix )
{
test_array[INPUT].push_back(NULL);
if( warp_matrix )
test_array[INPUT].push_back(NULL);
test_array[INPUT_OUTPUT].push_back(NULL);
test_array[REF_INPUT_OUTPUT].push_back(NULL);
max_interpolation = 5;
interpolation = 0;
element_wise_relative_error = false;
spatial_scale_zoom = 0.01;
spatial_scale_decimate = 0.005;
}
int CV_ImgWarpBaseTest::read_params( CvFileStorage* fs )
{
int code = cvtest::ArrayTest::read_params( fs );
return code;
}
void CV_ImgWarpBaseTest::get_minmax_bounds( int i, int j, int type, Scalar& low, Scalar& high )
{
cvtest::ArrayTest::get_minmax_bounds( i, j, type, low, high );
if( CV_MAT_DEPTH(type) == CV_32F )
{
low = Scalar::all(-10.);
high = Scalar::all(10);
}
}
void CV_ImgWarpBaseTest::get_test_array_types_and_sizes( int test_case_idx,
vector<vector<Size> >& sizes, vector<vector<int> >& types )
{
RNG& rng = ts->get_rng();
int depth = cvtest::randInt(rng) % 3;
int cn = cvtest::randInt(rng) % 3 + 1;
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
depth = depth == 0 ? CV_8U : depth == 1 ? CV_16U : CV_32F;
cn += cn == 2;
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = CV_MAKETYPE(depth, cn);
if( test_array[INPUT].size() > 1 )
types[INPUT][1] = cvtest::randInt(rng) & 1 ? CV_32FC1 : CV_64FC1;
interpolation = cvtest::randInt(rng) % max_interpolation;
}
void CV_ImgWarpBaseTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
{
if( i != INPUT || j != 0 )
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
}
int CV_ImgWarpBaseTest::prepare_test_case( int test_case_idx )
{
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
Mat& img = test_mat[INPUT][0];
int i, j, cols = img.cols;
int type = img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
double scale = depth == CV_16U ? 1000. : 255.*0.5;
double space_scale = spatial_scale_decimate;
vector<float> buffer(img.cols*cn);
if( code <= 0 )
return code;
if( test_mat[INPUT_OUTPUT][0].cols >= img.cols &&
test_mat[INPUT_OUTPUT][0].rows >= img.rows )
space_scale = spatial_scale_zoom;
for( i = 0; i < img.rows; i++ )
{
uchar* ptr = img.ptr(i);
switch( cn )
{
case 1:
for( j = 0; j < cols; j++ )
buffer[j] = (float)((sin((i+1)*space_scale)*sin((j+1)*space_scale)+1.)*scale);
break;
case 2:
for( j = 0; j < cols; j++ )
{
buffer[j*2] = (float)((sin((i+1)*space_scale)+1.)*scale);
buffer[j*2+1] = (float)((sin((i+j)*space_scale)+1.)*scale);
}
break;
case 3:
for( j = 0; j < cols; j++ )
{
buffer[j*3] = (float)((sin((i+1)*space_scale)+1.)*scale);
buffer[j*3+1] = (float)((sin(j*space_scale)+1.)*scale);
buffer[j*3+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
}
break;
case 4:
for( j = 0; j < cols; j++ )
{
buffer[j*4] = (float)((sin((i+1)*space_scale)+1.)*scale);
buffer[j*4+1] = (float)((sin(j*space_scale)+1.)*scale);
buffer[j*4+2] = (float)((sin((i+j)*space_scale)+1.)*scale);
buffer[j*4+3] = (float)((sin((i-j)*space_scale)+1.)*scale);
}
break;
default:
assert(0);
}
/*switch( depth )
{
case CV_8U:
for( j = 0; j < cols*cn; j++ )
ptr[j] = (uchar)cvRound(buffer[j]);
break;
case CV_16U:
for( j = 0; j < cols*cn; j++ )
((ushort*)ptr)[j] = (ushort)cvRound(buffer[j]);
break;
case CV_32F:
for( j = 0; j < cols*cn; j++ )
((float*)ptr)[j] = (float)buffer[j];
break;
default:
assert(0);
}*/
cv::Mat src(1, cols*cn, CV_32F, &buffer[0]);
cv::Mat dst(1, cols*cn, depth, ptr);
src.convertTo(dst, dst.type());
}
return code;
}
class CV_UndistortTest : public CV_ImgWarpBaseTest
{
public:
CV_UndistortTest();
protected:
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void run_func();
int prepare_test_case( int test_case_idx );
void prepare_to_validation( int /*test_case_idx*/ );
double get_success_error_level( int test_case_idx, int i, int j );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
private:
bool useCPlus;
cv::Mat input0;
cv::Mat input1;
cv::Mat input2;
cv::Mat input_new_cam;
cv::Mat input_output;
bool zero_new_cam;
bool zero_distortion;
};
CV_UndistortTest::CV_UndistortTest() : CV_ImgWarpBaseTest( false )
{
//spatial_scale_zoom = spatial_scale_decimate;
test_array[INPUT].push_back(NULL);
test_array[INPUT].push_back(NULL);
test_array[INPUT].push_back(NULL);
spatial_scale_decimate = spatial_scale_zoom;
}
void CV_UndistortTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
{
RNG& rng = ts->get_rng();
CV_ImgWarpBaseTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
int type = types[INPUT][0];
type = CV_MAKETYPE( CV_8U, CV_MAT_CN(type) );
types[INPUT][0] = types[INPUT_OUTPUT][0] = types[REF_INPUT_OUTPUT][0] = type;
types[INPUT][1] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
types[INPUT][2] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
sizes[INPUT][1] = cvSize(3,3);
sizes[INPUT][2] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
types[INPUT][3] = types[INPUT][1];
sizes[INPUT][3] = sizes[INPUT][1];
interpolation = CV_INTER_LINEAR;
}
void CV_UndistortTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
{
if( i != INPUT )
CV_ImgWarpBaseTest::fill_array( test_case_idx, i, j, arr );
}
void CV_UndistortTest::run_func()
{
if (!useCPlus)
{
CvMat a = cvMat(test_mat[INPUT][1]), k = cvMat(test_mat[INPUT][2]);
cvUndistort2( test_array[INPUT][0], test_array[INPUT_OUTPUT][0], &a, &k);
}
else
{
if (zero_distortion)
{
cv::undistort(input0,input_output,input1,cv::Mat());
}
else
{
cv::undistort(input0,input_output,input1,input2);
}
}
}
double CV_UndistortTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
{
int depth = test_mat[INPUT][0].depth();
return depth == CV_8U ? 16 : depth == CV_16U ? 1024 : 5e-2;
}
int CV_UndistortTest::prepare_test_case( int test_case_idx )
{
RNG& rng = ts->get_rng();
int code = CV_ImgWarpBaseTest::prepare_test_case( test_case_idx );
const Mat& src = test_mat[INPUT][0];
double k[4], a[9] = {0,0,0,0,0,0,0,0,1};
double new_cam[9] = {0,0,0,0,0,0,0,0,1};
double sz = MAX(src.rows, src.cols);
Mat& _new_cam0 = test_mat[INPUT][3];
Mat _new_cam(test_mat[INPUT][3].rows,test_mat[INPUT][3].cols,CV_64F,new_cam);
Mat& _a0 = test_mat[INPUT][1];
Mat _a(3,3,CV_64F,a);
Mat& _k0 = test_mat[INPUT][2];
Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);
if( code <= 0 )
return code;
double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
a[2] = (src.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
a[5] = (src.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
a[4] = aspect_ratio*a[0];
k[0] = cvtest::randReal(rng)*0.06 - 0.03;
k[1] = cvtest::randReal(rng)*0.06 - 0.03;
if( k[0]*k[1] > 0 )
k[1] = -k[1];
if( cvtest::randInt(rng)%4 != 0 )
{
k[2] = cvtest::randReal(rng)*0.004 - 0.002;
k[3] = cvtest::randReal(rng)*0.004 - 0.002;
}
else
k[2] = k[3] = 0;
new_cam[0] = a[0] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[0]; //10%
new_cam[4] = a[4] + (cvtest::randReal(rng) - (double)0.5)*0.2*a[4]; //10%
new_cam[2] = a[2] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].rows; //15%
new_cam[5] = a[5] + (cvtest::randReal(rng) - (double)0.5)*0.3*test_mat[INPUT][0].cols; //15%
_a.convertTo(_a0, _a0.depth());
zero_distortion = (cvtest::randInt(rng)%2) == 0 ? false : true;
_k.convertTo(_k0, _k0.depth());
zero_new_cam = (cvtest::randInt(rng)%2) == 0 ? false : true;
_new_cam.convertTo(_new_cam0, _new_cam0.depth());
//Testing C++ code
useCPlus = ((cvtest::randInt(rng) % 2)!=0);
if (useCPlus)
{
input0 = test_mat[INPUT][0];
input1 = test_mat[INPUT][1];
input2 = test_mat[INPUT][2];
input_new_cam = test_mat[INPUT][3];
}
return code;
}
void CV_UndistortTest::prepare_to_validation( int /*test_case_idx*/ )
{
if (useCPlus)
{
Mat& output = test_mat[INPUT_OUTPUT][0];
input_output.convertTo(output, output.type());
}
Mat& src = test_mat[INPUT][0];
Mat& dst = test_mat[REF_INPUT_OUTPUT][0];
Mat& dst0 = test_mat[INPUT_OUTPUT][0];
Mat mapx, mapy;
cvtest::initUndistortMap( test_mat[INPUT][1], test_mat[INPUT][2], dst.size(), mapx, mapy );
Mat mask( dst.size(), CV_8U );
test_remap( src, dst, mapx, mapy, &mask, interpolation );
dst.setTo(Scalar::all(0), mask);
dst0.setTo(Scalar::all(0), mask);
}
class CV_UndistortMapTest : public cvtest::ArrayTest
{
public:
CV_UndistortMapTest();
protected:
void get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types );
void run_func();
int prepare_test_case( int test_case_idx );
void prepare_to_validation( int /*test_case_idx*/ );
double get_success_error_level( int test_case_idx, int i, int j );
void fill_array( int test_case_idx, int i, int j, Mat& arr );
private:
bool dualChannel;
};
CV_UndistortMapTest::CV_UndistortMapTest()
{
test_array[INPUT].push_back(NULL);
test_array[INPUT].push_back(NULL);
test_array[OUTPUT].push_back(NULL);
test_array[OUTPUT].push_back(NULL);
test_array[REF_OUTPUT].push_back(NULL);
test_array[REF_OUTPUT].push_back(NULL);
element_wise_relative_error = false;
}
void CV_UndistortMapTest::get_test_array_types_and_sizes( int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types )
{
RNG& rng = ts->get_rng();
cvtest::ArrayTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
int depth = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
Size sz = sizes[OUTPUT][0];
types[INPUT][0] = types[INPUT][1] = depth;
dualChannel = cvtest::randInt(rng)%2 == 0;
types[OUTPUT][0] = types[OUTPUT][1] =
types[REF_OUTPUT][0] = types[REF_OUTPUT][1] = dualChannel ? CV_32FC2 : CV_32F;
sizes[INPUT][0] = cvSize(3,3);
sizes[INPUT][1] = cvtest::randInt(rng)%2 ? cvSize(4,1) : cvSize(1,4);
sz.width = MAX(sz.width,16);
sz.height = MAX(sz.height,16);
sizes[OUTPUT][0] = sizes[OUTPUT][1] =
sizes[REF_OUTPUT][0] = sizes[REF_OUTPUT][1] = sz;
}
void CV_UndistortMapTest::fill_array( int test_case_idx, int i, int j, Mat& arr )
{
if( i != INPUT )
cvtest::ArrayTest::fill_array( test_case_idx, i, j, arr );
}
void CV_UndistortMapTest::run_func()
{
CvMat a = cvMat(test_mat[INPUT][0]), k = cvMat(test_mat[INPUT][1]);
if (!dualChannel )
cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], test_array[OUTPUT][1] );
else
cvInitUndistortMap( &a, &k, test_array[OUTPUT][0], 0 );
}
double CV_UndistortMapTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
{
return 1e-3;
}
int CV_UndistortMapTest::prepare_test_case( int test_case_idx )
{
RNG& rng = ts->get_rng();
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
const Mat& mapx = test_mat[OUTPUT][0];
double k[4], a[9] = {0,0,0,0,0,0,0,0,1};
double sz = MAX(mapx.rows, mapx.cols);
Mat& _a0 = test_mat[INPUT][0], &_k0 = test_mat[INPUT][1];
Mat _a(3,3,CV_64F,a);
Mat _k(_k0.rows,_k0.cols, CV_MAKETYPE(CV_64F,_k0.channels()),k);
if( code <= 0 )
return code;
double aspect_ratio = cvtest::randReal(rng)*0.6 + 0.7;
a[2] = (mapx.cols - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
a[5] = (mapx.rows - 1)*0.5 + cvtest::randReal(rng)*10 - 5;
a[0] = sz/(0.9 - cvtest::randReal(rng)*0.6);
a[4] = aspect_ratio*a[0];
k[0] = cvtest::randReal(rng)*0.06 - 0.03;
k[1] = cvtest::randReal(rng)*0.06 - 0.03;
if( k[0]*k[1] > 0 )
k[1] = -k[1];
k[2] = cvtest::randReal(rng)*0.004 - 0.002;
k[3] = cvtest::randReal(rng)*0.004 - 0.002;
_a.convertTo(_a0, _a0.depth());
_k.convertTo(_k0, _k0.depth());
if (dualChannel)
{
test_mat[REF_OUTPUT][1] = Scalar::all(0);
test_mat[OUTPUT][1] = Scalar::all(0);
}
return code;
}
void CV_UndistortMapTest::prepare_to_validation( int )
{
Mat mapx, mapy;
cvtest::initUndistortMap( test_mat[INPUT][0], test_mat[INPUT][1], test_mat[REF_OUTPUT][0].size(), mapx, mapy );
if( !dualChannel )
{
mapx.copyTo(test_mat[REF_OUTPUT][0]);
mapy.copyTo(test_mat[REF_OUTPUT][1]);
}
else
{
Mat p[2] = {mapx, mapy};
cv::merge(p, 2, test_mat[REF_OUTPUT][0]);
}
}
TEST(Calib3d_Undistort, accuracy) { CV_UndistortTest test; test.safe_run(); }
TEST(Calib3d_InitUndistortMap, accuracy) { CV_UndistortMapTest test; test.safe_run(); }
}} // namespace
@@ -40,7 +40,7 @@
//M*/
#include "test_precomp.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/calib3d/calib3d_c.h"
namespace opencv_test { namespace {
-4
View File
@@ -81,10 +81,6 @@ if(HAVE_HPX)
ocv_target_link_libraries(${the_module} LINK_PRIVATE "${HPX_LIBRARIES}")
endif()
if(HAVE_CUDA)
ocv_target_compile_definitions(${the_module} PUBLIC OPENCV_TRAITS_ENABLE_DEPRECATED)
endif()
ocv_add_accuracy_tests()
ocv_add_perf_tests()
+35 -20
View File
@@ -415,8 +415,13 @@ The function cv::divide divides one array by another:
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.
Different channels of multi-channel arrays are processed independently.
For integer types when src2(I) is zero, dst(I) will also be zero.
@note In case of floating point data there is no special defined behavior for zero src2(I) values.
Regular floating-point division is used.
Expect correct IEEE-754 behaviour for floating-point data (with NaN, Inf result values).
@note Saturation is not applied when the output array has the depth CV_32S. You may even get
result of an incorrect sign in the case of overflow.
@@ -2997,7 +3002,8 @@ public:
class CV_EXPORTS Formatter
{
public:
enum { FMT_DEFAULT = 0,
enum FormatType {
FMT_DEFAULT = 0,
FMT_MATLAB = 1,
FMT_CSV = 2,
FMT_PYTHON = 3,
@@ -3014,7 +3020,7 @@ public:
virtual void set64fPrecision(int p = 16) = 0;
virtual void setMultiline(bool ml = true) = 0;
static Ptr<Formatter> get(int fmt = FMT_DEFAULT);
static Ptr<Formatter> get(Formatter::FormatType fmt = FMT_DEFAULT);
};
@@ -3037,7 +3043,7 @@ String& operator << (String& out, const Mat& mtx)
class CV_EXPORTS Algorithm;
template<typename _Tp> struct ParamType {};
template<typename _Tp, typename _EnumTp = void> struct ParamType {};
/** @brief This is a base class for all more or less complex algorithms in OpenCV
@@ -3150,9 +3156,9 @@ 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, SCALAR=12 };
enum struct Param {
INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7,
UNSIGNED_INT=8, UINT64=9, UCHAR=11, SCALAR=12
};
@@ -3162,7 +3168,7 @@ template<> struct ParamType<bool>
typedef bool const_param_type;
typedef bool member_type;
enum { type = Param::BOOLEAN };
static const Param type = Param::BOOLEAN;
};
template<> struct ParamType<int>
@@ -3170,7 +3176,7 @@ template<> struct ParamType<int>
typedef int const_param_type;
typedef int member_type;
enum { type = Param::INT };
static const Param type = Param::INT;
};
template<> struct ParamType<double>
@@ -3178,7 +3184,7 @@ template<> struct ParamType<double>
typedef double const_param_type;
typedef double member_type;
enum { type = Param::REAL };
static const Param type = Param::REAL;
};
template<> struct ParamType<String>
@@ -3186,7 +3192,7 @@ template<> struct ParamType<String>
typedef const String& const_param_type;
typedef String member_type;
enum { type = Param::STRING };
static const Param type = Param::STRING;
};
template<> struct ParamType<Mat>
@@ -3194,7 +3200,7 @@ template<> struct ParamType<Mat>
typedef const Mat& const_param_type;
typedef Mat member_type;
enum { type = Param::MAT };
static const Param type = Param::MAT;
};
template<> struct ParamType<std::vector<Mat> >
@@ -3202,7 +3208,7 @@ template<> struct ParamType<std::vector<Mat> >
typedef const std::vector<Mat>& const_param_type;
typedef std::vector<Mat> member_type;
enum { type = Param::MAT_VECTOR };
static const Param type = Param::MAT_VECTOR;
};
template<> struct ParamType<Algorithm>
@@ -3210,7 +3216,7 @@ template<> struct ParamType<Algorithm>
typedef const Ptr<Algorithm>& const_param_type;
typedef Ptr<Algorithm> member_type;
enum { type = Param::ALGORITHM };
static const Param type = Param::ALGORITHM;
};
template<> struct ParamType<float>
@@ -3218,7 +3224,7 @@ template<> struct ParamType<float>
typedef float const_param_type;
typedef float member_type;
enum { type = Param::FLOAT };
static const Param type = Param::FLOAT;
};
template<> struct ParamType<unsigned>
@@ -3226,7 +3232,7 @@ template<> struct ParamType<unsigned>
typedef unsigned const_param_type;
typedef unsigned member_type;
enum { type = Param::UNSIGNED_INT };
static const Param type = Param::UNSIGNED_INT;
};
template<> struct ParamType<uint64>
@@ -3234,7 +3240,7 @@ template<> struct ParamType<uint64>
typedef uint64 const_param_type;
typedef uint64 member_type;
enum { type = Param::UINT64 };
static const Param type = Param::UINT64;
};
template<> struct ParamType<uchar>
@@ -3242,7 +3248,7 @@ template<> struct ParamType<uchar>
typedef uchar const_param_type;
typedef uchar member_type;
enum { type = Param::UCHAR };
static const Param type = Param::UCHAR;
};
template<> struct ParamType<Scalar>
@@ -3250,7 +3256,16 @@ template<> struct ParamType<Scalar>
typedef const Scalar& const_param_type;
typedef Scalar member_type;
enum { type = Param::SCALAR };
static const Param type = Param::SCALAR;
};
template<typename _Tp>
struct ParamType<_Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type>
{
typedef typename std::underlying_type<_Tp>::type const_param_type;
typedef typename std::underlying_type<_Tp>::type member_type;
static const Param type = Param::INT;
};
//! @} core_basic
+13 -11
View File
@@ -390,6 +390,8 @@ CV_EXPORTS CV_NORETURN void error(int _code, const String& _err, const char* _fu
#define CV_Error(...) do { abort(); } while (0)
#define CV_Error_( code, args ) do { cv::format args; abort(); } while (0)
#define CV_Assert( expr ) do { if (!(expr)) abort(); } while (0)
#define CV_ErrorNoReturn CV_Error
#define CV_ErrorNoReturn_ CV_Error_
#else // CV_STATIC_ANALYSIS
@@ -440,17 +442,17 @@ configurations while CV_DbgAssert is only retained in the Debug configuration.
#endif
#define CV_Assert_1 CV_Assert
#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_Assert_2( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_1( __VA_ARGS__ ))
#define CV_Assert_3( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_2( __VA_ARGS__ ))
#define CV_Assert_4( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_3( __VA_ARGS__ ))
#define CV_Assert_5( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_4( __VA_ARGS__ ))
#define CV_Assert_6( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_5( __VA_ARGS__ ))
#define CV_Assert_7( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_6( __VA_ARGS__ ))
#define CV_Assert_8( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_7( __VA_ARGS__ ))
#define CV_Assert_9( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_8( __VA_ARGS__ ))
#define CV_Assert_10( expr, ... ) CV_Assert_1(expr); __CV_EXPAND(CV_Assert_9( __VA_ARGS__ ))
#define CV_Assert_N(...) do { __CV_CAT(CV_Assert_, __CV_VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__); } while(0)
#define CV_Assert_N(...) do { __CV_EXPAND(__CV_CAT(CV_Assert_, __CV_VA_NUM_ARGS(__VA_ARGS__)) (__VA_ARGS__)); } while(0)
//! @endcond
@@ -467,7 +469,7 @@ configurations while CV_DbgAssert is only retained in the Debug configuration.
*/
struct CV_EXPORTS Hamming
{
enum { normType = NORM_HAMMING };
static const NormTypes normType = NORM_HAMMING;
typedef unsigned char ValueType;
typedef int ResultType;
@@ -69,6 +69,7 @@ CV_EXPORTS void CV_NORETURN check_failed_auto(const int v1, const int v2, const
CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v1, const size_t v2, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_auto(const float v1, const float v2, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_auto(const double v1, const double v2, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_<int> v1, const Size_<int> v2, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v1, const int v2, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx);
@@ -77,6 +78,7 @@ CV_EXPORTS void CV_NORETURN check_failed_auto(const int v, const CheckContext& c
CV_EXPORTS void CV_NORETURN check_failed_auto(const size_t v, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_auto(const float v, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_auto(const double v, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_auto(const Size_<int> v, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v, const CheckContext& ctx);
CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v, const CheckContext& ctx);
+2 -2
View File
@@ -134,8 +134,8 @@ public:
CV_WRAP GpuMat(const GpuMat& m);
//! constructor for GpuMat headers pointing to user-allocated data
CV_WRAP GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP);
CV_WRAP GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP);
GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP);
GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP);
//! creates a GpuMat header for a part of the bigger matrix
CV_WRAP GpuMat(const GpuMat& m, Range rowRange, Range colRange);
+137 -1
View File
@@ -80,7 +80,7 @@ namespace cv { namespace debug_build_guard { } using namespace debug_build_guard
#endif
#define __CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define __CV_VA_NUM_ARGS(...) __CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define __CV_VA_NUM_ARGS(...) __CV_EXPAND(__CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
// undef problematic defines sometimes defined by system headers (windows.h in particular)
#undef small
@@ -330,6 +330,142 @@ Cv64suf;
# define MAX(a,b) ((a) < (b) ? (b) : (a))
#endif
///////////////////////////////////////// Enum operators ///////////////////////////////////////
/**
Provides compatibility operators for both classical and C++11 enum classes,
as well as exposing the C++11 enum class members for backwards compatibility
@code
// Provides operators required for flag enums
CV_ENUM_FLAGS(AccessFlag);
// Exposes the listed members of the enum class AccessFlag to the current namespace
CV_ENUM_CLASS_EXPOSE(AccessFlag, ACCESS_READ [, ACCESS_WRITE [, ...] ]);
@endcode
*/
#define __CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST) \
static const EnumType MEMBER_CONST = EnumType::MEMBER_CONST; \
#define __CV_ENUM_CLASS_EXPOSE_2(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_1(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_CLASS_EXPOSE_3(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_2(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_CLASS_EXPOSE_4(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_3(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_CLASS_EXPOSE_5(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_4(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_CLASS_EXPOSE_6(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_5(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_CLASS_EXPOSE_7(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_6(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_CLASS_EXPOSE_8(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_7(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_CLASS_EXPOSE_9(EnumType, MEMBER_CONST, ...) \
__CV_ENUM_CLASS_EXPOSE_1(EnumType, MEMBER_CONST); \
__CV_EXPAND(__CV_ENUM_CLASS_EXPOSE_8(EnumType, __VA_ARGS__)); \
#define __CV_ENUM_FLAGS_LOGICAL_NOT(EnumType) \
static inline bool operator!(const EnumType& val) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return !static_cast<UnderlyingType>(val); \
} \
#define __CV_ENUM_FLAGS_LOGICAL_NOT_EQ(Arg1Type, Arg2Type) \
static inline bool operator!=(const Arg1Type& a, const Arg2Type& b) \
{ \
return static_cast<int>(a) != static_cast<int>(b); \
} \
#define __CV_ENUM_FLAGS_LOGICAL_EQ(Arg1Type, Arg2Type) \
static inline bool operator==(const Arg1Type& a, const Arg2Type& b) \
{ \
return static_cast<int>(a) == static_cast<int>(b); \
} \
#define __CV_ENUM_FLAGS_BITWISE_NOT(EnumType) \
static inline EnumType operator~(const EnumType& val) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return static_cast<EnumType>(~static_cast<UnderlyingType>(val)); \
} \
#define __CV_ENUM_FLAGS_BITWISE_OR(EnumType, Arg1Type, Arg2Type) \
static inline EnumType operator|(const Arg1Type& a, const Arg2Type& b) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return static_cast<EnumType>(static_cast<UnderlyingType>(a) | static_cast<UnderlyingType>(b)); \
} \
#define __CV_ENUM_FLAGS_BITWISE_AND(EnumType, Arg1Type, Arg2Type) \
static inline EnumType operator&(const Arg1Type& a, const Arg2Type& b) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return static_cast<EnumType>(static_cast<UnderlyingType>(a) & static_cast<UnderlyingType>(b)); \
} \
#define __CV_ENUM_FLAGS_BITWISE_XOR(EnumType, Arg1Type, Arg2Type) \
static inline EnumType operator^(const Arg1Type& a, const Arg2Type& b) \
{ \
typedef std::underlying_type<EnumType>::type UnderlyingType; \
return static_cast<EnumType>(static_cast<UnderlyingType>(a) ^ static_cast<UnderlyingType>(b)); \
} \
#define __CV_ENUM_FLAGS_BITWISE_OR_EQ(EnumType, Arg1Type) \
static inline EnumType& operator|=(EnumType& _this, const Arg1Type& val) \
{ \
_this = static_cast<EnumType>(static_cast<int>(_this) | static_cast<int>(val)); \
return _this; \
} \
#define __CV_ENUM_FLAGS_BITWISE_AND_EQ(EnumType, Arg1Type) \
static inline EnumType& operator&=(EnumType& _this, const Arg1Type& val) \
{ \
_this = static_cast<EnumType>(static_cast<int>(_this) & static_cast<int>(val)); \
return _this; \
} \
#define __CV_ENUM_FLAGS_BITWISE_XOR_EQ(EnumType, Arg1Type) \
static inline EnumType& operator^=(EnumType& _this, const Arg1Type& val) \
{ \
_this = static_cast<EnumType>(static_cast<int>(_this) ^ static_cast<int>(val)); \
return _this; \
} \
#define CV_ENUM_CLASS_EXPOSE(EnumType, ...) \
__CV_EXPAND(__CV_CAT(__CV_ENUM_CLASS_EXPOSE_, __CV_VA_NUM_ARGS(__VA_ARGS__))(EnumType, __VA_ARGS__)); \
#define CV_ENUM_FLAGS(EnumType) \
__CV_ENUM_FLAGS_LOGICAL_NOT (EnumType); \
__CV_ENUM_FLAGS_LOGICAL_EQ (EnumType, int); \
__CV_ENUM_FLAGS_LOGICAL_NOT_EQ (EnumType, int); \
\
__CV_ENUM_FLAGS_BITWISE_NOT (EnumType); \
__CV_ENUM_FLAGS_BITWISE_OR (EnumType, EnumType, EnumType); \
__CV_ENUM_FLAGS_BITWISE_AND (EnumType, EnumType, EnumType); \
__CV_ENUM_FLAGS_BITWISE_XOR (EnumType, EnumType, EnumType); \
\
__CV_ENUM_FLAGS_BITWISE_OR_EQ (EnumType, EnumType); \
__CV_ENUM_FLAGS_BITWISE_AND_EQ (EnumType, EnumType); \
__CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType); \
/****************************************************************************************\
* static analysys *
\****************************************************************************************/
@@ -139,8 +139,14 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
# undef CV_FP16
#endif
#if CV_SSE2 || CV_NEON || CV_VSX
#define CV__SIMD_FORWARD 128
#include "opencv2/core/hal/intrin_forward.hpp"
#endif
#if CV_SSE2
#include "opencv2/core/hal/intrin_sse_em.hpp"
#include "opencv2/core/hal/intrin_sse.hpp"
#elif CV_NEON
@@ -168,6 +174,8 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
// (and will be mapped to v256_ counterparts) (e.g. vx_load() => v256_load())
#if CV_AVX2
#define CV__SIMD_FORWARD 256
#include "opencv2/core/hal/intrin_forward.hpp"
#include "opencv2/core/hal/intrin_avx.hpp"
#endif
@@ -368,6 +376,9 @@ inline unsigned int trailingZeros32(unsigned int value) {
unsigned long index = 0;
_BitScanForward(&index, value);
return (unsigned int)index;
#elif defined(__clang__)
// clang-cl doesn't export _tzcnt_u32 for non BMI systems
return value ? __builtin_ctz(value) : 32;
#else
return _tzcnt_u32(value);
#endif
@@ -82,6 +82,14 @@ inline __m128 _v256_extract_low(const __m256& v)
inline __m128d _v256_extract_low(const __m256d& v)
{ return _mm256_castpd256_pd128(v); }
inline __m256i _v256_packs_epu32(const __m256i& a, const __m256i& b)
{
const __m256i m = _mm256_set1_epi32(65535);
__m256i am = _mm256_min_epu32(a, m);
__m256i bm = _mm256_min_epu32(b, m);
return _mm256_packus_epi32(am, bm);
}
///////// Types ////////////
struct v_uint8x32
@@ -626,10 +634,8 @@ OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int8x32, _mm256_adds_epi8)
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int8x32, _mm256_subs_epi8)
OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint16x16, _mm256_adds_epu16)
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint16x16, _mm256_subs_epu16)
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_uint16x16, _mm256_mullo_epi16)
OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_int16x16, _mm256_adds_epi16)
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_int16x16, _mm256_subs_epi16)
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_int16x16, _mm256_mullo_epi16)
OPENCV_HAL_IMPL_AVX_BIN_OP(+, v_uint32x8, _mm256_add_epi32)
OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_uint32x8, _mm256_sub_epi32)
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_uint32x8, _mm256_mullo_epi32)
@@ -650,13 +656,103 @@ OPENCV_HAL_IMPL_AVX_BIN_OP(-, v_float64x4, _mm256_sub_pd)
OPENCV_HAL_IMPL_AVX_BIN_OP(*, v_float64x4, _mm256_mul_pd)
OPENCV_HAL_IMPL_AVX_BIN_OP(/, v_float64x4, _mm256_div_pd)
// saturating multiply 8-bit, 16-bit
inline v_uint8x32 operator * (const v_uint8x32& a, const v_uint8x32& b)
{
v_uint16x16 c, d;
v_mul_expand(a, b, c, d);
return v_pack_u(v_reinterpret_as_s16(c), v_reinterpret_as_s16(d));
}
inline v_int8x32 operator * (const v_int8x32& a, const v_int8x32& b)
{
v_int16x16 c, d;
v_mul_expand(a, b, c, d);
return v_pack(c, d);
}
inline v_uint16x16 operator * (const v_uint16x16& a, const v_uint16x16& b)
{
__m256i pl = _mm256_mullo_epi16(a.val, b.val);
__m256i ph = _mm256_mulhi_epu16(a.val, b.val);
__m256i p0 = _mm256_unpacklo_epi16(pl, ph);
__m256i p1 = _mm256_unpackhi_epi16(pl, ph);
return v_uint16x16(_v256_packs_epu32(p0, p1));
}
inline v_int16x16 operator * (const v_int16x16& a, const v_int16x16& b)
{
__m256i pl = _mm256_mullo_epi16(a.val, b.val);
__m256i ph = _mm256_mulhi_epi16(a.val, b.val);
__m256i p0 = _mm256_unpacklo_epi16(pl, ph);
__m256i p1 = _mm256_unpackhi_epi16(pl, ph);
return v_int16x16(_mm256_packs_epi32(p0, p1));
}
inline v_uint8x32& operator *= (v_uint8x32& a, const v_uint8x32& b)
{ a = a * b; return a; }
inline v_int8x32& operator *= (v_int8x32& a, const v_int8x32& b)
{ a = a * b; return a; }
inline v_uint16x16& operator *= (v_uint16x16& a, const v_uint16x16& b)
{ a = a * b; return a; }
inline v_int16x16& operator *= (v_int16x16& a, const v_int16x16& b)
{ a = a * b; return a; }
/** Non-saturating arithmetics **/
#define OPENCV_HAL_IMPL_AVX_BIN_FUNC(func, _Tpvec, intrin) \
inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
{ return _Tpvec(intrin(a.val, b.val)); }
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint8x32, _mm256_add_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int8x32, _mm256_add_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint16x16, _mm256_add_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int16x16, _mm256_add_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint8x32, _mm256_sub_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int8x32, _mm256_sub_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint16x16, _mm256_sub_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int16x16, _mm256_sub_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_mul_wrap, v_uint16x16, _mm256_mullo_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_mul_wrap, v_int16x16, _mm256_mullo_epi16)
inline v_uint8x32 v_mul_wrap(const v_uint8x32& a, const v_uint8x32& b)
{
__m256i ad = _mm256_srai_epi16(a.val, 8);
__m256i bd = _mm256_srai_epi16(b.val, 8);
__m256i p0 = _mm256_mullo_epi16(a.val, b.val); // even
__m256i p1 = _mm256_slli_epi16(_mm256_mullo_epi16(ad, bd), 8); // odd
const __m256i b01 = _mm256_set1_epi32(0xFF00FF00);
return v_uint8x32(_mm256_blendv_epi8(p0, p1, b01));
}
inline v_int8x32 v_mul_wrap(const v_int8x32& a, const v_int8x32& b)
{
return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b)));
}
// Multiply and expand
inline void v_mul_expand(const v_uint8x32& a, const v_uint8x32& b,
v_uint16x16& c, v_uint16x16& d)
{
v_uint16x16 a0, a1, b0, b1;
v_expand(a, a0, a1);
v_expand(b, b0, b1);
c = v_mul_wrap(a0, b0);
d = v_mul_wrap(a1, b1);
}
inline void v_mul_expand(const v_int8x32& a, const v_int8x32& b,
v_int16x16& c, v_int16x16& d)
{
v_int16x16 a0, a1, b0, b1;
v_expand(a, a0, a1);
v_expand(b, b0, b1);
c = v_mul_wrap(a0, b0);
d = v_mul_wrap(a1, b1);
}
inline void v_mul_expand(const v_int16x16& a, const v_int16x16& b,
v_int32x8& c, v_int32x8& d)
{
v_int16x16 vhi = v_int16x16(_mm256_mulhi_epi16(a.val, b.val));
v_int16x16 v0, v1;
v_zip(a * b, vhi, v0, v1);
v_zip(v_mul_wrap(a, b), vhi, v0, v1);
c = v_reinterpret_as_s32(v0);
d = v_reinterpret_as_s32(v1);
@@ -668,7 +764,7 @@ inline void v_mul_expand(const v_uint16x16& a, const v_uint16x16& b,
v_uint16x16 vhi = v_uint16x16(_mm256_mulhi_epu16(a.val, b.val));
v_uint16x16 v0, v1;
v_zip(a * b, vhi, v0, v1);
v_zip(v_mul_wrap(a, b), vhi, v0, v1);
c = v_reinterpret_as_u32(v0);
d = v_reinterpret_as_u32(v1);
@@ -685,20 +781,6 @@ inline void v_mul_expand(const v_uint32x8& a, const v_uint32x8& b,
inline v_int16x16 v_mul_hi(const v_int16x16& a, const v_int16x16& b) { return v_int16x16(_mm256_mulhi_epi16(a.val, b.val)); }
inline v_uint16x16 v_mul_hi(const v_uint16x16& a, const v_uint16x16& b) { return v_uint16x16(_mm256_mulhi_epu16(a.val, b.val)); }
/** Non-saturating arithmetics **/
#define OPENCV_HAL_IMPL_AVX_BIN_FUNC(func, _Tpvec, intrin) \
inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
{ return _Tpvec(intrin(a.val, b.val)); }
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint8x32, _mm256_add_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int8x32, _mm256_add_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_uint16x16, _mm256_add_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_add_wrap, v_int16x16, _mm256_add_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint8x32, _mm256_sub_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int8x32, _mm256_sub_epi8)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_uint16x16, _mm256_sub_epi16)
OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_sub_wrap, v_int16x16, _mm256_sub_epi16)
/** Bitwise shifts **/
#define OPENCV_HAL_IMPL_AVX_SHIFT_OP(_Tpuvec, _Tpsvec, suffix, srai) \
inline _Tpuvec operator << (const _Tpuvec& a, int imm) \
@@ -1385,6 +1467,10 @@ OPENCV_HAL_IMPL_AVX_TRANSPOSE4x4(v_float32x8, ps, _mm256_castps_si256, _mm256_ca
b0.val = intrin(_v256_extract_low(a.val)); \
b1.val = intrin(_v256_extract_high(a.val)); \
} \
inline _Tpwvec v_expand_low(const _Tpvec& a) \
{ return _Tpwvec(intrin(_v256_extract_low(a.val))); } \
inline _Tpwvec v_expand_high(const _Tpvec& a) \
{ return _Tpwvec(intrin(_v256_extract_high(a.val))); } \
inline _Tpwvec v256_load_expand(const _Tp* ptr) \
{ \
__m128i a = _mm_loadu_si128((const __m128i*)ptr); \
@@ -1430,7 +1516,12 @@ inline void v_pack_store(schar* ptr, const v_int16x16& a)
{ v_store_low(ptr, v_pack(a, a)); }
inline void v_pack_store(uchar* ptr, const v_uint16x16& a)
{ v_store_low(ptr, v_pack(a, a)); }
{
const __m256i m = _mm256_set1_epi16(255);
__m256i am = _mm256_min_epu16(a.val, m);
am = _v256_shuffle_odd_64(_mm256_packus_epi16(am, am));
v_store_low(ptr, v_uint8x32(am));
}
inline void v_pack_u_store(uchar* ptr, const v_int16x16& a)
{ v_store_low(ptr, v_pack_u(a, a)); }
@@ -1484,16 +1575,21 @@ inline v_int16x16 v_pack(const v_int32x8& a, const v_int32x8& b)
{ return v_int16x16(_v256_shuffle_odd_64(_mm256_packs_epi32(a.val, b.val))); }
inline v_uint16x16 v_pack(const v_uint32x8& a, const v_uint32x8& b)
{ return v_uint16x16(_v256_shuffle_odd_64(_mm256_packus_epi32(a.val, b.val))); }
{ return v_uint16x16(_v256_shuffle_odd_64(_v256_packs_epu32(a.val, b.val))); }
inline v_uint16x16 v_pack_u(const v_int32x8& a, const v_int32x8& b)
{ return v_pack(v_reinterpret_as_u32(a), v_reinterpret_as_u32(b)); }
{ return v_uint16x16(_v256_shuffle_odd_64(_mm256_packus_epi32(a.val, b.val))); }
inline void v_pack_store(short* ptr, const v_int32x8& a)
{ v_store_low(ptr, v_pack(a, a)); }
inline void v_pack_store(ushort* ptr, const v_uint32x8& a)
{ v_store_low(ptr, v_pack(a, a)); }
{
const __m256i m = _mm256_set1_epi32(65535);
__m256i am = _mm256_min_epu32(a.val, m);
am = _v256_shuffle_odd_64(_mm256_packus_epi32(am, am));
v_store_low(ptr, v_uint16x16(am));
}
inline void v_pack_u_store(ushort* ptr, const v_int32x8& a)
{ v_store_low(ptr, v_pack_u(a, a)); }
@@ -108,7 +108,7 @@ block and to save contents of the register to memory block.
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
- Expand: @ref v_load_expand, @ref v_load_expand_q, @ref v_expand, @ref v_expand_low, @ref v_expand_high
- Pack: @ref v_pack, @ref v_pack_u, @ref v_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
@@ -185,11 +185,14 @@ Regular integers:
|load, store | x | x | x | x | x | x |
|interleave | x | x | x | x | x | x |
|expand | x | x | x | x | x | x |
|expand_low | x | x | x | x | x | x |
|expand_high | x | x | x | x | x | x |
|expand_q | x | x | | | | |
|add, sub | x | x | x | x | x | x |
|add_wrap, sub_wrap | x | x | x | x | | |
|mul | | | x | x | x | x |
|mul_expand | | | x | x | x | |
|mul_wrap | x | x | x | x | | |
|mul | x | x | x | x | x | x |
|mul_expand | x | x | x | x | x | |
|compare | x | x | x | x | x | x |
|shift | | | x | x | x | x |
|dotprod | | | | x | | |
@@ -680,7 +683,7 @@ 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) \
#define OPENCV_HAL_IMPL_ARITHM_OP(func, bin_op, cast_op, _Tp2) \
template<typename _Tp, int n> \
inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
{ \
@@ -694,12 +697,17 @@ inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \
/** @brief Add values without saturation
For 8- and 16-bit integer values. */
OPENCV_HAL_IMPL_ADD_SUB_OP(v_add_wrap, +, (_Tp), _Tp)
OPENCV_HAL_IMPL_ARITHM_OP(v_add_wrap, +, (_Tp), _Tp)
/** @brief Subtract values without saturation
For 8- and 16-bit integer values. */
OPENCV_HAL_IMPL_ADD_SUB_OP(v_sub_wrap, -, (_Tp), _Tp)
OPENCV_HAL_IMPL_ARITHM_OP(v_sub_wrap, -, (_Tp), _Tp)
/** @brief Multiply values without saturation
For 8- and 16-bit integer values. */
OPENCV_HAL_IMPL_ARITHM_OP(v_mul_wrap, *, (_Tp), _Tp)
//! @cond IGNORED
template<typename T> inline T _absdiff(T a, T b)
@@ -1106,6 +1114,44 @@ template<typename _Tp, int n> inline void v_expand(const v_reg<_Tp, n>& a,
}
}
/** @brief Expand lower values to the wider pack type
Same as cv::v_expand, but return lower half of the vector.
Scheme:
@code
int32x4 int64x2
{A B C D} ==> {A B}
@endcode */
template<typename _Tp, int n>
inline v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>
v_expand_low(const v_reg<_Tp, n>& a)
{
v_reg<typename V_TypeTraits<_Tp>::w_type, n/2> b;
for( int i = 0; i < (n/2); i++ )
b.s[i] = a.s[i];
return b;
}
/** @brief Expand higher values to the wider pack type
Same as cv::v_expand_low, but expand higher half of the vector instead.
Scheme:
@code
int32x4 int64x2
{A B C D} ==> {C D}
@endcode */
template<typename _Tp, int n>
inline v_reg<typename V_TypeTraits<_Tp>::w_type, n/2>
v_expand_high(const v_reg<_Tp, n>& a)
{
v_reg<typename V_TypeTraits<_Tp>::w_type, n/2> b;
for( int i = 0; i < (n/2); i++ )
b.s[i] = a.s[i+(n/2)];
return b;
}
//! @cond IGNORED
template<typename _Tp, int n> inline v_reg<typename V_TypeTraits<_Tp>::int_type, n>
v_reinterpret_as_int(const v_reg<_Tp, n>& a)
@@ -0,0 +1,158 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef CV__SIMD_FORWARD
#error "Need to pre-define forward width"
#endif
namespace cv
{
//! @cond IGNORED
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
/** Types **/
#if CV__SIMD_FORWARD == 512
// [todo] 512
#error "AVX512 Not implemented yet"
#elif CV__SIMD_FORWARD == 256
// 256
#define __CV_VX(fun) v256_##fun
#define __CV_V_UINT8 v_uint8x32
#define __CV_V_INT8 v_int8x32
#define __CV_V_UINT16 v_uint16x16
#define __CV_V_INT16 v_int16x16
#define __CV_V_UINT32 v_uint32x8
#define __CV_V_INT32 v_int32x8
#define __CV_V_UINT64 v_uint64x4
#define __CV_V_INT64 v_int64x4
#define __CV_V_FLOAT32 v_float32x8
#define __CV_V_FLOAT64 v_float64x4
struct v_uint8x32;
struct v_int8x32;
struct v_uint16x16;
struct v_int16x16;
struct v_uint32x8;
struct v_int32x8;
struct v_uint64x4;
struct v_int64x4;
struct v_float32x8;
struct v_float64x4;
#else
// 128
#define __CV_VX(fun) v_##fun
#define __CV_V_UINT8 v_uint8x16
#define __CV_V_INT8 v_int8x16
#define __CV_V_UINT16 v_uint16x8
#define __CV_V_INT16 v_int16x8
#define __CV_V_UINT32 v_uint32x4
#define __CV_V_INT32 v_int32x4
#define __CV_V_UINT64 v_uint64x2
#define __CV_V_INT64 v_int64x2
#define __CV_V_FLOAT32 v_float32x4
#define __CV_V_FLOAT64 v_float64x2
struct v_uint8x16;
struct v_int8x16;
struct v_uint16x8;
struct v_int16x8;
struct v_uint32x4;
struct v_int32x4;
struct v_uint64x2;
struct v_int64x2;
struct v_float32x4;
struct v_float64x2;
#endif
/** Value reordering **/
// Expansion
void v_expand(const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&);
void v_expand(const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&);
void v_expand(const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&);
void v_expand(const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&);
void v_expand(const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&);
void v_expand(const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&);
// Low Expansion
__CV_V_UINT16 v_expand_low(const __CV_V_UINT8&);
__CV_V_INT16 v_expand_low(const __CV_V_INT8&);
__CV_V_UINT32 v_expand_low(const __CV_V_UINT16&);
__CV_V_INT32 v_expand_low(const __CV_V_INT16&);
__CV_V_UINT64 v_expand_low(const __CV_V_UINT32&);
__CV_V_INT64 v_expand_low(const __CV_V_INT32&);
// High Expansion
__CV_V_UINT16 v_expand_high(const __CV_V_UINT8&);
__CV_V_INT16 v_expand_high(const __CV_V_INT8&);
__CV_V_UINT32 v_expand_high(const __CV_V_UINT16&);
__CV_V_INT32 v_expand_high(const __CV_V_INT16&);
__CV_V_UINT64 v_expand_high(const __CV_V_UINT32&);
__CV_V_INT64 v_expand_high(const __CV_V_INT32&);
// Load & Low Expansion
__CV_V_UINT16 __CV_VX(load_expand)(const uchar*);
__CV_V_INT16 __CV_VX(load_expand)(const schar*);
__CV_V_UINT32 __CV_VX(load_expand)(const ushort*);
__CV_V_INT32 __CV_VX(load_expand)(const short*);
__CV_V_UINT64 __CV_VX(load_expand)(const uint*);
__CV_V_INT64 __CV_VX(load_expand)(const int*);
// Load lower 8-bit and expand into 32-bit
__CV_V_UINT32 __CV_VX(load_expand_q)(const uchar*);
__CV_V_INT32 __CV_VX(load_expand_q)(const schar*);
// Saturating Pack
__CV_V_UINT8 v_pack(const __CV_V_UINT16&, const __CV_V_UINT16&);
__CV_V_INT8 v_pack(const __CV_V_INT16&, const __CV_V_INT16&);
__CV_V_UINT16 v_pack(const __CV_V_UINT32&, const __CV_V_UINT32&);
__CV_V_INT16 v_pack(const __CV_V_INT32&, const __CV_V_INT32&);
// Non-saturating Pack
__CV_V_UINT32 v_pack(const __CV_V_UINT64&, const __CV_V_UINT64&);
__CV_V_INT32 v_pack(const __CV_V_INT64&, const __CV_V_INT64&);
// Pack signed integers with unsigned saturation
__CV_V_UINT8 v_pack_u(const __CV_V_INT16&, const __CV_V_INT16&);
__CV_V_UINT16 v_pack_u(const __CV_V_INT32&, const __CV_V_INT32&);
/** Arithmetic, bitwise and comparison operations **/
// Non-saturating multiply
#if CV_VSX
template<typename Tvec>
Tvec v_mul_wrap(const Tvec& a, const Tvec& b);
#else
__CV_V_UINT8 v_mul_wrap(const __CV_V_UINT8&, const __CV_V_UINT8&);
__CV_V_INT8 v_mul_wrap(const __CV_V_INT8&, const __CV_V_INT8&);
__CV_V_UINT16 v_mul_wrap(const __CV_V_UINT16&, const __CV_V_UINT16&);
__CV_V_INT16 v_mul_wrap(const __CV_V_INT16&, const __CV_V_INT16&);
#endif
// Multiply and expand
#if CV_VSX
template<typename Tvec, typename Twvec>
void v_mul_expand(const Tvec& a, const Tvec& b, Twvec& c, Twvec& d);
#else
void v_mul_expand(const __CV_V_UINT8&, const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&);
void v_mul_expand(const __CV_V_INT8&, const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&);
void v_mul_expand(const __CV_V_UINT16&, const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&);
void v_mul_expand(const __CV_V_INT16&, const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&);
void v_mul_expand(const __CV_V_UINT32&, const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&);
void v_mul_expand(const __CV_V_INT32&, const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&);
#endif
/** Cleanup **/
#undef CV__SIMD_FORWARD
#undef __CV_VX
#undef __CV_V_UINT8
#undef __CV_V_INT8
#undef __CV_V_UINT16
#undef __CV_V_INT16
#undef __CV_V_UINT32
#undef __CV_V_INT32
#undef __CV_V_UINT64
#undef __CV_V_INT64
#undef __CV_V_FLOAT32
#undef __CV_V_FLOAT64
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond
} // cv::
@@ -435,10 +435,8 @@ 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)
@@ -476,6 +474,37 @@ inline v_float32x4& operator /= (v_float32x4& a, const v_float32x4& b)
}
#endif
// saturating multiply 8-bit, 16-bit
#define OPENCV_HAL_IMPL_NEON_MUL_SAT(_Tpvec, _Tpwvec) \
inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \
{ \
_Tpwvec c, d; \
v_mul_expand(a, b, c, d); \
return v_pack(c, d); \
} \
inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
{ a = a * b; return a; }
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_int8x16, v_int16x8)
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_uint8x16, v_uint16x8)
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_int16x8, v_int32x4)
OPENCV_HAL_IMPL_NEON_MUL_SAT(v_uint16x8, v_uint32x4)
// Multiply and expand
inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b,
v_int16x8& c, v_int16x8& d)
{
c.val = vmull_s8(vget_low_s8(a.val), vget_low_s8(b.val));
d.val = vmull_s8(vget_high_s8(a.val), vget_high_s8(b.val));
}
inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b,
v_uint16x8& c, v_uint16x8& d)
{
c.val = vmull_u8(vget_low_u8(a.val), vget_low_u8(b.val));
d.val = vmull_u8(vget_high_u8(a.val), vget_high_u8(b.val));
}
inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
v_int32x4& c, v_int32x4& d)
{
@@ -714,6 +743,10 @@ OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_sub_wrap, vsubq_u8)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_sub_wrap, vsubq_s8)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_sub_wrap, vsubq_u16)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_sub_wrap, vsubq_s16)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_mul_wrap, vmulq_u8)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int8x16, v_mul_wrap, vmulq_s8)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint16x8, v_mul_wrap, vmulq_u16)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_int16x8, v_mul_wrap, vmulq_s16)
// TODO: absdiff for signed integers
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_uint8x16, v_absdiff, vabdq_u8)
@@ -1056,6 +1089,14 @@ inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
b0.val = vmovl_##suffix(vget_low_##suffix(a.val)); \
b1.val = vmovl_##suffix(vget_high_##suffix(a.val)); \
} \
inline _Tpwvec v_expand_low(const _Tpvec& a) \
{ \
return _Tpwvec(vmovl_##suffix(vget_low_##suffix(a.val))); \
} \
inline _Tpwvec v_expand_high(const _Tpvec& a) \
{ \
return _Tpwvec(vmovl_##suffix(vget_high_##suffix(a.val))); \
} \
inline _Tpwvec v_load_expand(const _Tp* ptr) \
{ \
return _Tpwvec(vmovl_##suffix(vld1_##suffix(ptr))); \
@@ -59,6 +59,8 @@ namespace cv
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
///////// Types ////////////
struct v_uint8x16
{
typedef uchar lane_type;
@@ -436,13 +438,7 @@ inline __m128i v_select_si128(__m128i mask, __m128i a, __m128i b)
}
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)));
}
{ return v_uint16x8(_v128_packs_epu32(a.val, b.val)); }
inline void v_pack_store(ushort* ptr, const v_uint32x4& a)
{
@@ -472,6 +468,9 @@ void v_rshr_pack_store(ushort* ptr, const v_uint32x4& a)
inline v_uint16x8 v_pack_u(const v_int32x4& a, const v_int32x4& b)
{
#if CV_SSE4_1
return v_uint16x8(_mm_packus_epi32(a.val, b.val));
#else
__m128i delta32 = _mm_set1_epi32(32768);
// preliminary saturate negative values to zero
@@ -480,34 +479,51 @@ inline v_uint16x8 v_pack_u(const v_int32x4& a, const v_int32x4& b)
__m128i r = _mm_packs_epi32(_mm_sub_epi32(a1, delta32), _mm_sub_epi32(b1, delta32));
return v_uint16x8(_mm_sub_epi16(r, _mm_set1_epi16(-32768)));
#endif
}
inline void v_pack_u_store(ushort* ptr, const v_int32x4& a)
{
#if CV_SSE4_1
_mm_storel_epi64((__m128i*)ptr, _mm_packus_epi32(a.val, a.val));
#else
__m128i delta32 = _mm_set1_epi32(32768);
__m128i a1 = _mm_sub_epi32(a.val, delta32);
__m128i r = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
_mm_storel_epi64((__m128i*)ptr, r);
#endif
}
template<int n> inline
v_uint16x8 v_rshr_pack_u(const v_int32x4& a, const v_int32x4& b)
{
#if CV_SSE4_1
__m128i delta = _mm_set1_epi32(1 << (n - 1));
return v_uint16x8(_mm_packus_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n),
_mm_srai_epi32(_mm_add_epi32(b.val, delta), n)));
#else
__m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
__m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32);
__m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
__m128i b1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(b.val, delta), n), delta32);
__m128i b2 = _mm_sub_epi16(_mm_packs_epi32(b1, b1), _mm_set1_epi16(-32768));
return v_uint16x8(_mm_unpacklo_epi64(a2, b2));
#endif
}
template<int n> inline
void v_rshr_pack_u_store(ushort* ptr, const v_int32x4& a)
{
#if CV_SSE4_1
__m128i delta = _mm_set1_epi32(1 << (n - 1));
__m128i a1 = _mm_srai_epi32(_mm_add_epi32(a.val, delta), n);
_mm_storel_epi64((__m128i*)ptr, _mm_packus_epi32(a1, a1));
#else
__m128i delta = _mm_set1_epi32(1 << (n-1)), delta32 = _mm_set1_epi32(32768);
__m128i a1 = _mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(a.val, delta), n), delta32);
__m128i a2 = _mm_sub_epi16(_mm_packs_epi32(a1, a1), _mm_set1_epi16(-32768));
_mm_storel_epi64((__m128i*)ptr, a2);
#endif
}
inline v_int16x8 v_pack(const v_int32x4& a, const v_int32x4& b)
@@ -658,14 +674,14 @@ 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_uint32x4, _v128_mullo_epi32)
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_int32x4, _mm_add_epi32)
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_int32x4, _mm_sub_epi32)
OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_int32x4, _v128_mullo_epi32)
OPENCV_HAL_IMPL_SSE_BIN_OP(+, v_float32x4, _mm_add_ps)
OPENCV_HAL_IMPL_SSE_BIN_OP(-, v_float32x4, _mm_sub_ps)
OPENCV_HAL_IMPL_SSE_BIN_OP(*, v_float32x4, _mm_mul_ps)
@@ -679,35 +695,49 @@ 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)
// saturating multiply 8-bit, 16-bit
#define OPENCV_HAL_IMPL_SSE_MUL_SAT(_Tpvec, _Tpwvec) \
inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \
{ \
_Tpwvec c, d; \
v_mul_expand(a, b, c, d); \
return v_pack(c, d); \
} \
inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
{ a = a * b; return a; }
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int8x16, v_int16x8)
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_uint16x8, v_uint32x4)
OPENCV_HAL_IMPL_SSE_MUL_SAT(v_int16x8, v_int32x4)
inline v_uint8x16 operator * (const v_uint8x16& a, const v_uint8x16& 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));
v_uint16x8 c, d;
v_mul_expand(a, b, c, d);
return v_pack_u(v_reinterpret_as_s16(c), v_reinterpret_as_s16(d));
}
inline v_int32x4 operator * (const v_int32x4& a, const v_int32x4& b)
inline v_uint8x16& operator *= (v_uint8x16& a, const v_uint8x16& b)
{ a = a * b; return a; }
// Multiply and expand
inline void v_mul_expand(const v_uint8x16& a, const v_uint8x16& b,
v_uint16x8& c, v_uint16x8& d)
{
#if CV_SSE4_1
return v_int32x4(_mm_mullo_epi32(a.val, b.val));
#else
__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));
#endif
v_uint16x8 a0, a1, b0, b1;
v_expand(a, a0, a1);
v_expand(b, b0, b1);
c = v_mul_wrap(a0, b0);
d = v_mul_wrap(a1, b1);
}
inline v_uint32x4& operator *= (v_uint32x4& a, const v_uint32x4& b)
inline void v_mul_expand(const v_int8x16& a, const v_int8x16& b,
v_int16x8& c, v_int16x8& d)
{
a = a * b;
return a;
}
inline v_int32x4& operator *= (v_int32x4& a, const v_int32x4& b)
{
a = a * b;
return a;
v_int16x8 a0, a1, b0, b1;
v_expand(a, a0, a1);
v_expand(b, b0, b1);
c = v_mul_wrap(a0, b0);
d = v_mul_wrap(a1, b1);
}
inline void v_mul_expand(const v_int16x8& a, const v_int16x8& b,
@@ -998,6 +1028,22 @@ OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint8x16, v_sub_wrap, _mm_sub_epi8)
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int8x16, v_sub_wrap, _mm_sub_epi8)
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_sub_wrap, _mm_sub_epi16)
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_sub_wrap, _mm_sub_epi16)
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_uint16x8, v_mul_wrap, _mm_mullo_epi16)
OPENCV_HAL_IMPL_SSE_BIN_FUNC(v_int16x8, v_mul_wrap, _mm_mullo_epi16)
inline v_uint8x16 v_mul_wrap(const v_uint8x16& a, const v_uint8x16& b)
{
__m128i ad = _mm_srai_epi16(a.val, 8);
__m128i bd = _mm_srai_epi16(b.val, 8);
__m128i p0 = _mm_mullo_epi16(a.val, b.val); // even
__m128i p1 = _mm_slli_epi16(_mm_mullo_epi16(ad, bd), 8); // odd
const __m128i b01 = _mm_set1_epi32(0xFF00FF00);
return v_uint8x16(_v128_blendv_epi8(p0, p1, b01));
}
inline v_int8x16 v_mul_wrap(const v_int8x16& a, const v_int8x16& b)
{
return v_reinterpret_as_s8(v_mul_wrap(v_reinterpret_as_u8(a), v_reinterpret_as_u8(b)));
}
#define OPENCV_HAL_IMPL_SSE_ABSDIFF_8_16(_Tpuvec, _Tpsvec, bits, smask32) \
inline _Tpuvec v_absdiff(const _Tpuvec& a, const _Tpuvec& b) \
@@ -1482,70 +1528,39 @@ OPENCV_HAL_IMPL_SSE_SELECT(v_float32x4, ps)
OPENCV_HAL_IMPL_SSE_SELECT(v_float64x2, pd)
#endif
#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)); \
}
/* Expand */
#define OPENCV_HAL_IMPL_SSE_EXPAND(_Tpvec, _Tpwvec, _Tp, intrin) \
inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
{ \
b0.val = intrin(a.val); \
b1.val = __CV_CAT(intrin, _high)(a.val); \
} \
inline _Tpwvec v_expand_low(const _Tpvec& a) \
{ return _Tpwvec(intrin(a.val)); } \
inline _Tpwvec v_expand_high(const _Tpvec& a) \
{ return _Tpwvec(__CV_CAT(intrin, _high)(a.val)); } \
inline _Tpwvec v_load_expand(const _Tp* ptr) \
{ \
__m128i a = _mm_loadl_epi64((const __m128i*)ptr); \
return _Tpwvec(intrin(a)); \
}
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, 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)
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint8x16, v_uint16x8, uchar, _v128_cvtepu8_epi16)
OPENCV_HAL_IMPL_SSE_EXPAND(v_int8x16, v_int16x8, schar, _v128_cvtepi8_epi16)
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint16x8, v_uint32x4, ushort, _v128_cvtepu16_epi32)
OPENCV_HAL_IMPL_SSE_EXPAND(v_int16x8, v_int32x4, short, _v128_cvtepi16_epi32)
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint32x4, v_uint64x2, unsigned, _v128_cvtepu32_epi64)
OPENCV_HAL_IMPL_SSE_EXPAND(v_int32x4, v_int64x2, int, _v128_cvtepi32_epi64)
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));
}
#define OPENCV_HAL_IMPL_SSE_EXPAND_Q(_Tpvec, _Tp, intrin) \
inline _Tpvec v_load_expand_q(const _Tp* ptr) \
{ \
__m128i a = _mm_cvtsi32_si128(*(const int*)ptr); \
return _Tpvec(intrin(a)); \
}
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));
}
OPENCV_HAL_IMPL_SSE_EXPAND_Q(v_uint32x4, uchar, _v128_cvtepu8_epi32)
OPENCV_HAL_IMPL_SSE_EXPAND_Q(v_int32x4, schar, _v128_cvtepi8_epi32)
#define OPENCV_HAL_IMPL_SSE_UNPACKS(_Tpvec, suffix, cast_from, cast_to) \
inline void v_zip(const _Tpvec& a0, const _Tpvec& a1, _Tpvec& b0, _Tpvec& b1) \
@@ -0,0 +1,167 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#ifndef OPENCV_HAL_INTRIN_SSE_EM_HPP
#define OPENCV_HAL_INTRIN_SSE_EM_HPP
namespace cv
{
//! @cond IGNORED
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
#define OPENCV_HAL_SSE_WRAP_1(fun, tp) \
inline tp _v128_##fun(const tp& a) \
{ return _mm_##fun(a); }
#define OPENCV_HAL_SSE_WRAP_2(fun, tp) \
inline tp _v128_##fun(const tp& a, const tp& b) \
{ return _mm_##fun(a, b); }
#define OPENCV_HAL_SSE_WRAP_3(fun, tp) \
inline tp _v128_##fun(const tp& a, const tp& b, const tp& c) \
{ return _mm_##fun(a, b, c); }
///////////////////////////// XOP /////////////////////////////
// [todo] define CV_XOP
#if 1 // CV_XOP
inline __m128i _v128_comgt_epu32(const __m128i& a, const __m128i& b)
{
const __m128i delta = _mm_set1_epi32((int)0x80000000);
return _mm_cmpgt_epi32(_mm_xor_si128(a, delta), _mm_xor_si128(b, delta));
}
// wrapping XOP
#else
OPENCV_HAL_SSE_WRAP_2(_v128_comgt_epu32, __m128i)
#endif // !CV_XOP
///////////////////////////// SSE4.1 /////////////////////////////
#if !CV_SSE4_1
/** Swizzle **/
inline __m128i _v128_blendv_epi8(const __m128i& a, const __m128i& b, const __m128i& mask)
{ return _mm_xor_si128(a, _mm_and_si128(_mm_xor_si128(b, a), mask)); }
/** Convert **/
// 8 >> 16
inline __m128i _v128_cvtepu8_epi16(const __m128i& a)
{
const __m128i z = _mm_setzero_si128();
return _mm_unpacklo_epi8(a, z);
}
inline __m128i _v128_cvtepi8_epi16(const __m128i& a)
{ return _mm_srai_epi16(_mm_unpacklo_epi8(a, a), 8); }
// 8 >> 32
inline __m128i _v128_cvtepu8_epi32(const __m128i& a)
{
const __m128i z = _mm_setzero_si128();
return _mm_unpacklo_epi16(_mm_unpacklo_epi8(a, z), z);
}
inline __m128i _v128_cvtepi8_epi32(const __m128i& a)
{
__m128i r = _mm_unpacklo_epi8(a, a);
r = _mm_unpacklo_epi8(r, r);
return _mm_srai_epi32(r, 24);
}
// 16 >> 32
inline __m128i _v128_cvtepu16_epi32(const __m128i& a)
{
const __m128i z = _mm_setzero_si128();
return _mm_unpacklo_epi16(a, z);
}
inline __m128i _v128_cvtepi16_epi32(const __m128i& a)
{ return _mm_srai_epi32(_mm_unpacklo_epi16(a, a), 16); }
// 32 >> 64
inline __m128i _v128_cvtepu32_epi64(const __m128i& a)
{
const __m128i z = _mm_setzero_si128();
return _mm_unpacklo_epi32(a, z);
}
inline __m128i _v128_cvtepi32_epi64(const __m128i& a)
{ return _mm_unpacklo_epi32(a, _mm_srai_epi32(a, 31)); }
/** Arithmetic **/
inline __m128i _v128_mullo_epi32(const __m128i& a, const __m128i& b)
{
__m128i c0 = _mm_mul_epu32(a, b);
__m128i c1 = _mm_mul_epu32(_mm_srli_epi64(a, 32), _mm_srli_epi64(b, 32));
__m128i d0 = _mm_unpacklo_epi32(c0, c1);
__m128i d1 = _mm_unpackhi_epi32(c0, c1);
return _mm_unpacklo_epi64(d0, d1);
}
/** Math **/
inline __m128i _v128_min_epu32(const __m128i& a, const __m128i& b)
{ return _v128_blendv_epi8(a, b, _v128_comgt_epu32(a, b)); }
// wrapping SSE4.1
#else
OPENCV_HAL_SSE_WRAP_1(cvtepu8_epi16, __m128i)
OPENCV_HAL_SSE_WRAP_1(cvtepi8_epi16, __m128i)
OPENCV_HAL_SSE_WRAP_1(cvtepu8_epi32, __m128i)
OPENCV_HAL_SSE_WRAP_1(cvtepi8_epi32, __m128i)
OPENCV_HAL_SSE_WRAP_1(cvtepu16_epi32, __m128i)
OPENCV_HAL_SSE_WRAP_1(cvtepi16_epi32, __m128i)
OPENCV_HAL_SSE_WRAP_1(cvtepu32_epi64, __m128i)
OPENCV_HAL_SSE_WRAP_1(cvtepi32_epi64, __m128i)
OPENCV_HAL_SSE_WRAP_2(min_epu32, __m128i)
OPENCV_HAL_SSE_WRAP_2(mullo_epi32, __m128i)
OPENCV_HAL_SSE_WRAP_3(blendv_epi8, __m128i)
#endif // !CV_SSE4_1
///////////////////////////// Revolutionary /////////////////////////////
/** Convert **/
// 16 << 8
inline __m128i _v128_cvtepu8_epi16_high(const __m128i& a)
{
const __m128i z = _mm_setzero_si128();
return _mm_unpackhi_epi8(a, z);
}
inline __m128i _v128_cvtepi8_epi16_high(const __m128i& a)
{ return _mm_srai_epi16(_mm_unpackhi_epi8(a, a), 8); }
// 32 << 16
inline __m128i _v128_cvtepu16_epi32_high(const __m128i& a)
{
const __m128i z = _mm_setzero_si128();
return _mm_unpackhi_epi16(a, z);
}
inline __m128i _v128_cvtepi16_epi32_high(const __m128i& a)
{ return _mm_srai_epi32(_mm_unpackhi_epi16(a, a), 16); }
// 64 << 32
inline __m128i _v128_cvtepu32_epi64_high(const __m128i& a)
{
const __m128i z = _mm_setzero_si128();
return _mm_unpackhi_epi32(a, z);
}
inline __m128i _v128_cvtepi32_epi64_high(const __m128i& a)
{ return _mm_unpackhi_epi32(a, _mm_srai_epi32(a, 31)); }
/** Miscellaneous **/
inline __m128i _v128_packs_epu32(const __m128i& a, const __m128i& b)
{
const __m128i m = _mm_set1_epi32(65535);
__m128i am = _v128_min_epu32(a, m);
__m128i bm = _v128_min_epu32(b, m);
#if CV_SSE4_1
return _mm_packus_epi32(am, bm);
#else
const __m128i d = _mm_set1_epi32(32768), nd = _mm_set1_epi16(-32768);
am = _mm_sub_epi32(am, d);
bm = _mm_sub_epi32(bm, d);
am = _mm_packs_epi32(am, bm);
return _mm_sub_epi16(am, nd);
#endif
}
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond
} // cv::
#endif // OPENCV_HAL_INTRIN_SSE_EM_HPP
@@ -315,6 +315,10 @@ inline void v_expand(const _Tpvec& a, _Tpwvec& b0, _Tpwvec& b1) \
b0.val = fh(a.val); \
b1.val = fl(a.val); \
} \
inline _Tpwvec v_expand_low(const _Tpvec& a) \
{ return _Tpwvec(fh(a.val)); } \
inline _Tpwvec v_expand_high(const _Tpvec& a) \
{ return _Tpwvec(fl(a.val)); } \
inline _Tpwvec v_load_expand(const _Tp* ptr) \
{ return _Tpwvec(fh(vec_ld_l8(ptr))); }
@@ -418,10 +422,8 @@ 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)
@@ -441,16 +443,30 @@ 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)
// saturating multiply
#define OPENCV_HAL_IMPL_VSX_MUL_SAT(_Tpvec, _Tpwvec) \
inline _Tpvec operator * (const _Tpvec& a, const _Tpvec& b) \
{ \
_Tpwvec c, d; \
v_mul_expand(a, b, c, d); \
return v_pack(c, d); \
} \
inline _Tpvec& operator *= (_Tpvec& a, const _Tpvec& b) \
{ a = a * b; return a; }
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_int8x16, v_int16x8)
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_uint8x16, v_uint16x8)
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_int16x8, v_int32x4)
OPENCV_HAL_IMPL_VSX_MUL_SAT(v_uint16x8, v_uint32x4)
template<typename Tvec, typename Twvec>
inline void v_mul_expand(const Tvec& a, const Tvec& b, Twvec& c, Twvec& 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));
Twvec p0 = Twvec(vec_mule(a.val, b.val));
Twvec p1 = Twvec(vec_mulo(a.val, b.val));
v_zip(p0, p1, c, d);
}
inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, v_uint64x2& c, v_uint64x2& d)
{
c.val = vec_mul(vec_unpackhu(a.val), vec_unpackhu(b.val));
@@ -459,17 +475,17 @@ inline void v_mul_expand(const v_uint32x4& a, const v_uint32x4& b, v_uint64x2& c
inline v_int16x8 v_mul_hi(const v_int16x8& a, const v_int16x8& b)
{
return v_int16x8(vec_packs(
vec_sra(vec_mul(vec_unpackh(a.val), vec_unpackh(b.val)), vec_uint4_sp(16)),
vec_sra(vec_mul(vec_unpackl(a.val), vec_unpackl(b.val)), vec_uint4_sp(16))
));
vec_int4 p0 = vec_mule(a.val, b.val);
vec_int4 p1 = vec_mulo(a.val, b.val);
static const vec_uchar16 perm = {2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31};
return v_int16x8(vec_perm(vec_short8_c(p0), vec_short8_c(p1), perm));
}
inline v_uint16x8 v_mul_hi(const v_uint16x8& a, const v_uint16x8& b)
{
return v_uint16x8(vec_packs(
vec_sr(vec_mul(vec_unpackhu(a.val), vec_unpackhu(b.val)), vec_uint4_sp(16)),
vec_sr(vec_mul(vec_unpacklu(a.val), vec_unpacklu(b.val)), vec_uint4_sp(16))
));
vec_uint4 p0 = vec_mule(a.val, b.val);
vec_uint4 p1 = vec_mulo(a.val, b.val);
static const vec_uchar16 perm = {2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31};
return v_uint16x8(vec_perm(vec_ushort8_c(p0), vec_ushort8_c(p1), perm));
}
/** Non-saturating arithmetics **/
@@ -480,6 +496,7 @@ inline _Tpvec func(const _Tpvec& a, const _Tpvec& b) \
OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_add_wrap, vec_add)
OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_sub_wrap, vec_sub)
OPENCV_HAL_IMPL_VSX_BIN_FUNC(v_mul_wrap, vec_mul)
/** Bitwise shifts **/
#define OPENCV_HAL_IMPL_VSX_SHIFT_OP(_Tpvec, shr, splfunc) \
+20 -16
View File
@@ -61,8 +61,10 @@ namespace cv
//! @addtogroup core_basic
//! @{
enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
enum AccessFlag { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 };
CV_ENUM_FLAGS(AccessFlag);
__CV_ENUM_FLAGS_BITWISE_AND(AccessFlag, int, AccessFlag);
CV__DEBUG_NS_BEGIN
@@ -156,7 +158,7 @@ Custom type is wrapped as Mat-compatible `CV_8UC<N>` values (N = sizeof(T), N <=
class CV_EXPORTS _InputArray
{
public:
enum {
enum KindFlag {
KIND_SHIFT = 16,
FIXED_TYPE = 0x8000 << KIND_SHIFT,
FIXED_SIZE = 0x4000 << KIND_SHIFT,
@@ -221,7 +223,7 @@ public:
void* getObj() const;
Size getSz() const;
int kind() const;
_InputArray::KindFlag kind() const;
int dims(int i=-1) const;
int cols(int i=-1) const;
int rows(int i=-1) const;
@@ -257,7 +259,8 @@ protected:
void init(int _flags, const void* _obj);
void init(int _flags, const void* _obj, Size _sz);
};
CV_ENUM_FLAGS(_InputArray::KindFlag);
__CV_ENUM_FLAGS_BITWISE_AND(_InputArray::KindFlag, int, _InputArray::KindFlag);
/** @brief This type is very similar to InputArray except that it is used for input/output and output function
parameters.
@@ -287,7 +290,7 @@ generators:
class CV_EXPORTS _OutputArray : public _InputArray
{
public:
enum
enum DepthMask
{
DEPTH_MASK_8U = 1 << CV_8U,
DEPTH_MASK_8S = 1 << CV_8S,
@@ -356,9 +359,9 @@ public:
std::vector<cuda::GpuMat>& 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 create(Size sz, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
void createSameSize(const _InputArray& arr, int mtype) const;
void release() const;
void clear() const;
@@ -467,10 +470,10 @@ public:
// 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;
void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const = 0;
virtual bool allocate(UMatData* data, AccessFlag accessflags, UMatUsageFlags usageFlags) const = 0;
virtual void deallocate(UMatData* data) const = 0;
virtual void map(UMatData* data, int accessflags) const;
virtual void map(UMatData* data, AccessFlag accessflags) const;
virtual void unmap(UMatData* data) const;
virtual void download(UMatData* data, void* dst, int dims, const size_t sz[],
const size_t srcofs[], const size_t srcstep[],
@@ -523,7 +526,7 @@ protected:
// it should be explicitly initialized using init().
struct CV_EXPORTS UMatData
{
enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
enum MemoryFlag { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64,
ASYNC_CLEANUP=128
@@ -553,13 +556,14 @@ struct CV_EXPORTS UMatData
uchar* origdata;
size_t size;
int flags;
UMatData::MemoryFlag flags;
void* handle;
void* userdata;
int allocatorFlags_;
int mapcount;
UMatData* originalUMatData;
};
CV_ENUM_FLAGS(UMatData::MemoryFlag);
struct CV_EXPORTS MatSize
@@ -1061,7 +1065,7 @@ public:
Mat& operator = (const MatExpr& expr);
//! retrieve UMat from Mat
UMat getUMat(int accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const;
UMat getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const;
/** @brief Creates a matrix header for the specified matrix row.
@@ -2420,7 +2424,7 @@ public:
//! assignment operators
UMat& operator = (const UMat& m);
Mat getMat(int flags) const;
Mat getMat(AccessFlag flags) const;
//! returns a new matrix header for the specified row
UMat row(int y) const;
@@ -2546,7 +2550,7 @@ public:
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* handle(AccessFlag accessFlags) const;
void ndoffset(size_t* ofs) const;
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
+22 -22
View File
@@ -83,7 +83,7 @@ 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() { init(0 + NONE, 0); }
inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); }
inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }
inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }
@@ -185,12 +185,12 @@ inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::
////////////////////////////////////////////////////////////////////////////////////////
inline _OutputArray::_OutputArray() { init(ACCESS_WRITE, 0); }
inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags|ACCESS_WRITE, _obj); }
inline _OutputArray::_OutputArray() { init(NONE + ACCESS_WRITE, 0); }
inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags + ACCESS_WRITE, _obj); }
inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_WRITE, &vec); }
inline _OutputArray::_OutputArray(UMat& m) { init(UMAT+ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT+ACCESS_WRITE, &vec); }
inline _OutputArray::_OutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT + ACCESS_WRITE, &vec); }
inline _OutputArray::_OutputArray(UMat& m) { init(UMAT + ACCESS_WRITE, &m); }
inline _OutputArray::_OutputArray(std::vector<UMat>& vec) { init(STD_VECTOR_UMAT + ACCESS_WRITE, &vec); }
template<typename _Tp> inline
_OutputArray::_OutputArray(std::vector<_Tp>& vec)
@@ -311,8 +311,8 @@ _OutputArray _OutputArray::rawOut(std::array<_Tp, _Nm>& arr)
///////////////////////////////////////////////////////////////////////////////////////////
inline _InputOutputArray::_InputOutputArray() { init(ACCESS_RW, 0); }
inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags|ACCESS_RW, _obj); }
inline _InputOutputArray::_InputOutputArray() { init(0+ACCESS_RW, 0); }
inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags+ACCESS_RW, _obj); }
inline _InputOutputArray::_InputOutputArray(Mat& m) { init(MAT+ACCESS_RW, &m); }
inline _InputOutputArray::_InputOutputArray(std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_RW, &vec); }
inline _InputOutputArray::_InputOutputArray(UMat& m) { init(UMAT+ACCESS_RW, &m); }
@@ -600,7 +600,7 @@ Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
template<typename _Tp> 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()),
: 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())
@@ -637,7 +637,7 @@ Mat::Mat(const std::initializer_list<int> sizes, const std::initializer_list<_Tp
template<typename _Tp, std::size_t _Nm> 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()),
: 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())
@@ -654,7 +654,7 @@ Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
template<typename _Tp, int n> 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),
: 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 )
@@ -670,7 +670,7 @@ Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
template<typename _Tp, int m, int n> 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),
: 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 )
@@ -686,7 +686,7 @@ Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
template<typename _Tp> 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),
: 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 )
@@ -705,7 +705,7 @@ Mat::Mat(const Point_<_Tp>& pt, bool copyData)
template<typename _Tp> 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),
: 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 )
@@ -725,7 +725,7 @@ Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
template<typename _Tp> 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),
: 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>();
@@ -1554,7 +1554,7 @@ template<typename _Tp> inline
Mat_<_Tp>::Mat_()
: Mat()
{
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
}
template<typename _Tp> inline
@@ -1611,7 +1611,7 @@ template<typename _Tp> inline
Mat_<_Tp>::Mat_(const Mat& m)
: Mat()
{
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
*this = m;
}
@@ -1751,7 +1751,7 @@ void Mat_<_Tp>::release()
{
Mat::release();
#ifdef _DEBUG
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
#endif
}
@@ -2069,7 +2069,7 @@ template<typename _Tp> inline
Mat_<_Tp>::Mat_(Mat&& m)
: Mat()
{
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
*this = m;
}
@@ -2095,7 +2095,7 @@ template<typename _Tp> inline
Mat_<_Tp>::Mat_(MatExpr&& e)
: Mat()
{
flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value;
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
*this = Mat(e);
}
@@ -2431,7 +2431,7 @@ SparseMatConstIterator_<_Tp> SparseMat::end() const
template<typename _Tp> inline
SparseMat_<_Tp>::SparseMat_()
{
flags = MAGIC_VAL | traits::Type<_Tp>::value;
flags = MAGIC_VAL + traits::Type<_Tp>::value;
}
template<typename _Tp> inline
@@ -3654,7 +3654,7 @@ UMat::UMat(const UMat& m)
template<typename _Tp> 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()),
: 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())
+77 -76
View File
@@ -59,7 +59,7 @@ CV_EXPORTS_W void finish();
CV_EXPORTS bool haveSVM();
class CV_EXPORTS Context;
class CV_EXPORTS Device;
class CV_EXPORTS_W_SIMPLE Device;
class CV_EXPORTS Kernel;
class CV_EXPORTS Program;
class CV_EXPORTS ProgramSource;
@@ -67,14 +67,14 @@ class CV_EXPORTS Queue;
class CV_EXPORTS PlatformInfo;
class CV_EXPORTS Image2D;
class CV_EXPORTS Device
class CV_EXPORTS_W_SIMPLE Device
{
public:
Device();
CV_WRAP Device();
explicit Device(void* d);
Device(const Device& d);
Device& operator = (const Device& d);
~Device();
CV_WRAP ~Device();
void set(void* d);
@@ -89,24 +89,24 @@ public:
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;
CV_WRAP String name() const;
CV_WRAP String extensions() const;
CV_WRAP bool isExtensionSupported(const String& extensionName) const;
CV_WRAP String version() const;
CV_WRAP String vendorName() const;
CV_WRAP String OpenCL_C_Version() const;
CV_WRAP String OpenCLVersion() const;
CV_WRAP int deviceVersionMajor() const;
CV_WRAP int deviceVersionMinor() const;
CV_WRAP String driverVersion() const;
void* ptr() const;
int type() const;
CV_WRAP int type() const;
int addressBits() const;
bool available() const;
bool compilerAvailable() const;
bool linkerAvailable() const;
CV_WRAP int addressBits() const;
CV_WRAP bool available() const;
CV_WRAP bool compilerAvailable() const;
CV_WRAP bool linkerAvailable() const;
enum
{
@@ -119,21 +119,21 @@ public:
FP_SOFT_FLOAT=(1 << 6),
FP_CORRECTLY_ROUNDED_DIVIDE_SQRT=(1 << 7)
};
int doubleFPConfig() const;
int singleFPConfig() const;
int halfFPConfig() const;
CV_WRAP int doubleFPConfig() const;
CV_WRAP int singleFPConfig() const;
CV_WRAP int halfFPConfig() const;
bool endianLittle() const;
bool errorCorrectionSupport() const;
CV_WRAP bool endianLittle() const;
CV_WRAP bool errorCorrectionSupport() const;
enum
{
EXEC_KERNEL=(1 << 0),
EXEC_NATIVE_KERNEL=(1 << 1)
};
int executionCapabilities() const;
CV_WRAP int executionCapabilities() const;
size_t globalMemCacheSize() const;
CV_WRAP size_t globalMemCacheSize() const;
enum
{
@@ -141,38 +141,38 @@ public:
READ_ONLY_CACHE=1,
READ_WRITE_CACHE=2
};
int globalMemCacheType() const;
int globalMemCacheLineSize() const;
size_t globalMemSize() const;
CV_WRAP int globalMemCacheType() const;
CV_WRAP int globalMemCacheLineSize() const;
CV_WRAP size_t globalMemSize() const;
size_t localMemSize() const;
CV_WRAP size_t localMemSize() const;
enum
{
NO_LOCAL_MEM=0,
LOCAL_IS_LOCAL=1,
LOCAL_IS_GLOBAL=2
};
int localMemType() const;
bool hostUnifiedMemory() const;
CV_WRAP int localMemType() const;
CV_WRAP bool hostUnifiedMemory() const;
bool imageSupport() const;
CV_WRAP bool imageSupport() const;
bool imageFromBufferSupport() const;
CV_WRAP bool imageFromBufferSupport() const;
uint imagePitchAlignment() const;
uint imageBaseAddressAlignment() const;
/// deprecated, use isExtensionSupported() method (probably with "cl_khr_subgroups" value)
bool intelSubgroupsSupport() const;
CV_WRAP bool intelSubgroupsSupport() const;
size_t image2DMaxWidth() const;
size_t image2DMaxHeight() const;
CV_WRAP size_t image2DMaxWidth() const;
CV_WRAP size_t image2DMaxHeight() const;
size_t image3DMaxWidth() const;
size_t image3DMaxHeight() const;
size_t image3DMaxDepth() const;
CV_WRAP size_t image3DMaxWidth() const;
CV_WRAP size_t image3DMaxHeight() const;
CV_WRAP size_t image3DMaxDepth() const;
size_t imageMaxBufferSize() const;
size_t imageMaxArraySize() const;
CV_WRAP size_t imageMaxBufferSize() const;
CV_WRAP size_t imageMaxArraySize() const;
enum
{
@@ -181,53 +181,53 @@ public:
VENDOR_INTEL=2,
VENDOR_NVIDIA=3
};
int vendorID() const;
CV_WRAP int vendorID() const;
// FIXIT
// dev.isAMD() doesn't work for OpenCL CPU devices from AMD OpenCL platform.
// This method should use platform name instead of vendor name.
// After fix restore code in arithm.cpp: ocl_compare()
inline bool isAMD() const { return vendorID() == VENDOR_AMD; }
inline bool isIntel() const { return vendorID() == VENDOR_INTEL; }
inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; }
CV_WRAP inline bool isAMD() const { return vendorID() == VENDOR_AMD; }
CV_WRAP inline bool isIntel() const { return vendorID() == VENDOR_INTEL; }
CV_WRAP inline bool isNVidia() const { return vendorID() == VENDOR_NVIDIA; }
int maxClockFrequency() const;
int maxComputeUnits() const;
int maxConstantArgs() const;
size_t maxConstantBufferSize() const;
CV_WRAP int maxClockFrequency() const;
CV_WRAP int maxComputeUnits() const;
CV_WRAP int maxConstantArgs() const;
CV_WRAP size_t maxConstantBufferSize() const;
size_t maxMemAllocSize() const;
size_t maxParameterSize() const;
CV_WRAP size_t maxMemAllocSize() const;
CV_WRAP size_t maxParameterSize() const;
int maxReadImageArgs() const;
int maxWriteImageArgs() const;
int maxSamplers() const;
CV_WRAP int maxReadImageArgs() const;
CV_WRAP int maxWriteImageArgs() const;
CV_WRAP int maxSamplers() const;
size_t maxWorkGroupSize() const;
int maxWorkItemDims() const;
CV_WRAP size_t maxWorkGroupSize() const;
CV_WRAP int maxWorkItemDims() const;
void maxWorkItemSizes(size_t*) const;
int memBaseAddrAlign() const;
CV_WRAP int memBaseAddrAlign() const;
int nativeVectorWidthChar() const;
int nativeVectorWidthShort() const;
int nativeVectorWidthInt() const;
int nativeVectorWidthLong() const;
int nativeVectorWidthFloat() const;
int nativeVectorWidthDouble() const;
int nativeVectorWidthHalf() const;
CV_WRAP int nativeVectorWidthChar() const;
CV_WRAP int nativeVectorWidthShort() const;
CV_WRAP int nativeVectorWidthInt() const;
CV_WRAP int nativeVectorWidthLong() const;
CV_WRAP int nativeVectorWidthFloat() const;
CV_WRAP int nativeVectorWidthDouble() const;
CV_WRAP int nativeVectorWidthHalf() const;
int preferredVectorWidthChar() const;
int preferredVectorWidthShort() const;
int preferredVectorWidthInt() const;
int preferredVectorWidthLong() const;
int preferredVectorWidthFloat() const;
int preferredVectorWidthDouble() const;
int preferredVectorWidthHalf() const;
CV_WRAP int preferredVectorWidthChar() const;
CV_WRAP int preferredVectorWidthShort() const;
CV_WRAP int preferredVectorWidthInt() const;
CV_WRAP int preferredVectorWidthLong() const;
CV_WRAP int preferredVectorWidthFloat() const;
CV_WRAP int preferredVectorWidthDouble() const;
CV_WRAP int preferredVectorWidthHalf() const;
size_t printfBufferSize() const;
size_t profilingTimerResolution() const;
CV_WRAP size_t printfBufferSize() const;
CV_WRAP size_t profilingTimerResolution() const;
static const Device& getDefault();
CV_WRAP static const Device& getDefault();
protected:
struct Impl;
@@ -352,7 +352,8 @@ public:
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 Local(size_t localMemSize)
{ return KernelArg(LOCAL, 0, 1, 1, 0, localMemSize); }
static KernelArg PtrWriteOnly(const UMat& m)
{ return KernelArg(PTR_ONLY+WRITE_ONLY, (UMat*)&m); }
static KernelArg PtrReadOnly(const UMat& m)
@@ -59,11 +59,18 @@ static inline bool isOpenCLActivated() { return false; }
}
#else
#define CV_OCL_RUN_(condition, func, ...) \
try \
{ \
if (cv::ocl::isOpenCLActivated() && (condition) && func) \
{ \
CV_IMPL_ADD(CV_IMPL_OCL); \
return __VA_ARGS__; \
}
} \
} \
catch (const cv::Exception& e) \
{ \
CV_UNUSED(e); /* TODO: Add some logging here */ \
}
#endif
#else
+2 -6
View File
@@ -548,7 +548,7 @@ calling unmapGLBuffer() function.
@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);
CV_EXPORTS UMat mapGLBuffer(const Buffer& buffer, AccessFlag accessFlags = ACCESS_READ | ACCESS_WRITE);
/** @brief Unmaps Buffer object (releases UMat, previously mapped from Buffer).
@@ -558,13 +558,11 @@ by the call to mapGLBuffer() function.
*/
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.
@@ -573,8 +571,6 @@ This function should be explicitly called after OpenGL context creation and befo
*/
CV_EXPORTS void setGlDevice(int device = 0);
//! @}
}}
//! @cond IGNORED
@@ -51,6 +51,12 @@
#include <cstdio>
#if defined(__GNUC__) || defined(__clang__) // at least GCC 3.1+, clang 3.5+
# define CV_FORMAT_PRINTF(string_idx, first_to_check) __attribute__ ((format (printf, string_idx, first_to_check)))
#else
# define CV_FORMAT_PRINTF(A, B)
#endif
//! @cond IGNORED
namespace cv
@@ -386,13 +392,24 @@ template<typename _Tp> static inline _Tp randu()
The function acts like sprintf but forms and returns an STL string. It can be used to form an error
message in the Exception constructor.
@param fmt printf-compatible formatting specifiers.
**Note**:
|Type|Specifier|
|-|-|
|`const char*`|`%s`|
|`char`|`%c`|
|`float` / `double`|`%f`,`%g`|
|`int`, `long`, `long long`|`%d`, `%ld`, ``%lld`|
|`unsigned`, `unsigned long`, `unsigned long long`|`%u`, `%lu`, `%llu`|
|`uint64` -> `uintmax_t`, `int64` -> `intmax_t`|`%ju`, `%jd`|
|`size_t`|`%zu`|
*/
CV_EXPORTS String format( const char* fmt, ... );
CV_EXPORTS String format( const char* fmt, ... ) CV_FORMAT_PRINTF(1, 2);
///////////////////////////////// Formatted output of cv::Mat /////////////////////////////////
static inline
Ptr<Formatted> format(InputArray mtx, int fmt)
Ptr<Formatted> format(InputArray mtx, Formatter::FormatType fmt)
{
return Formatter::get(fmt)->format(mtx.getMat());
}
+1 -1
View File
@@ -293,7 +293,7 @@ and the remaining to \f$A\f$. It should contain 32- or 64-bit floating point num
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_EXPORTS_W int solveLP(InputArray Func, InputArray Constr, OutputArray z);
//! @}
@@ -544,6 +544,11 @@ public:
*/
CV_WRAP_AS(at) FileNode operator[](int i) const;
/** @brief Returns keys of a mapping node.
@returns Keys of a mapping node.
*/
CV_WRAP std::vector<String> keys() const;
/** @brief Returns type of the node.
@returns Type of the node. See FileNode::Type
*/
@@ -1049,6 +1054,12 @@ void write(FileStorage& fs, const String& name, const DMatch& m)
write(fs, m.distance);
}
template<typename _Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type* = nullptr>
static inline void write( FileStorage& fs, const String& name, const _Tp& val )
{
write(fs, name, static_cast<int>(val));
}
template<typename _Tp> static inline
void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec )
{
@@ -1137,6 +1148,14 @@ void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_
r(vec, maxCount);
}
template<typename _Tp, typename std::enable_if< std::is_enum<_Tp>::value >::type* = nullptr>
static inline void read(const FileNode& node, _Tp& value, const _Tp& default_value = static_cast<_Tp>(0))
{
int temp;
read(node, temp, static_cast<int>(default_value));
value = static_cast<_Tp>(temp);
}
template<typename _Tp> static inline
void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() )
{
+10 -6
View File
@@ -142,9 +142,13 @@ namespace cv
CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
//! Allocate all memory buffers which will not be freed, ease filtering memcheck issues
template <typename T>
T* allocSingleton(size_t count) { return static_cast<T*>(fastMalloc(sizeof(T) * count)); }
}
CV_EXPORTS void* allocSingletonBuffer(size_t size);
//! Allocate all memory buffers which will not be freed, ease filtering memcheck issues
template <typename T> static inline
T* allocSingleton(size_t count = 1) { return static_cast<T*>(allocSingletonBuffer(sizeof(T) * count)); }
} // namespace
#if 1 // TODO: Remove in OpenCV 4.x
@@ -704,12 +708,12 @@ CV_EXPORTS InstrNode* getCurrentNode();
if(::cv::instr::useInstrumentation()){\
::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\
try{\
auto status = ((FUN)(__VA_ARGS__));\
auto instrStatus = ((FUN)(__VA_ARGS__));\
if(ERROR_COND){\
::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
}\
return status;\
return instrStatus;\
}catch(...){\
::cv::instr::getCurrentNode()->m_payload.m_funError = true;\
CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\
@@ -750,7 +754,7 @@ CV_EXPORTS InstrNode* getCurrentNode();
// Wrapper region instrumentation macro
#define CV_INSTRUMENT_REGION_IPP(); CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP)
// Function instrumentation macro
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, status < 0, FUN, __VA_ARGS__)
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, instrStatus < 0, FUN, __VA_ARGS__)
// Diagnostic markers
#define CV_INSTRUMENT_MARK_IPP(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME)
@@ -58,7 +58,9 @@
#include <functional>
#if !defined(_M_CEE)
#include <mutex> // std::mutex, std::lock_guard
#endif
namespace cv
{
@@ -674,8 +676,10 @@ void Mat::forEach_impl(const Functor& operation) {
/////////////////////////// Synchronization Primitives ///////////////////////////////
#if !defined(_M_CEE)
typedef std::recursive_mutex Mutex;
typedef std::lock_guard<cv::Mutex> AutoLock;
#endif
// TLS interface
class CV_EXPORTS TLSDataContainer
@@ -943,8 +947,8 @@ public:
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;
void getByName(const String& name, bool space_delete, Param type, void* dst) const;
void getByIndex(int index, bool space_delete, Param type, void* dst) const;
struct Impl;
Impl* impl;
@@ -5,11 +5,17 @@
#ifndef OPENCV_CONFIGURATION_PRIVATE_HPP
#define OPENCV_CONFIGURATION_PRIVATE_HPP
#include "opencv2/core/cvstd.hpp"
#include <vector>
#include <string>
namespace cv { namespace utils {
typedef std::vector<std::string> Paths;
CV_EXPORTS bool getConfigurationParameterBool(const char* name, bool defaultValue);
CV_EXPORTS size_t getConfigurationParameterSizeT(const char* name, size_t defaultValue);
CV_EXPORTS cv::String getConfigurationParameterString(const char* name, const char* defaultValue);
CV_EXPORTS Paths getConfigurationParameterPaths(const char* name, const Paths &defaultValue = Paths());
}} // namespace
@@ -37,6 +37,10 @@ namespace trace {
//! @cond IGNORED
#define CV_TRACE_NS cv::utils::trace
#if !defined(OPENCV_DISABLE_TRACE) && defined(__EMSCRIPTEN__)
#define OPENCV_DISABLE_TRACE 1
#endif
namespace details {
#ifndef __OPENCV_TRACE
@@ -8,7 +8,7 @@
#define CV_VERSION_MAJOR 4
#define CV_VERSION_MINOR 0
#define CV_VERSION_REVISION 0
#define CV_VERSION_STATUS "-alpha"
#define CV_VERSION_STATUS "-beta"
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
+12 -10
View File
@@ -130,19 +130,21 @@ VSX_FINLINE(rt) fnm(const rg& a, const rg& b) \
# undef vec_mul
# endif
/*
* there's no a direct instruction for supporting 16-bit multiplication in ISA 2.07,
* there's no a direct instruction for supporting 8-bit, 16-bit multiplication in ISA 2.07,
* XLC Implement it by using instruction "multiply even", "multiply odd" and "permute"
* 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); \
# define VSX_IMPL_MULH(Tvec, cperm) \
VSX_FINLINE(Tvec) vec_mul(const Tvec& a, const Tvec& b) \
{ \
static const vec_uchar16 ev_od = {cperm}; \
return vec_perm((Tvec)vec_mule(a, b), (Tvec)vec_mulo(a, b), ev_od); \
}
VSX_IMPL_MULH(vec_short8, vec_short8_c)
VSX_IMPL_MULH(vec_ushort8, vec_ushort8_c)
#define VSX_IMPL_MULH_P16 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30
VSX_IMPL_MULH(vec_char16, VSX_IMPL_MULH_P16)
VSX_IMPL_MULH(vec_uchar16, VSX_IMPL_MULH_P16)
#define VSX_IMPL_MULH_P8 0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29
VSX_IMPL_MULH(vec_short8, VSX_IMPL_MULH_P8)
VSX_IMPL_MULH(vec_ushort8, VSX_IMPL_MULH_P8)
// vmuluwm can be used for unsigned or signed integers, that's what they said
VSX_IMPL_2VRG(vec_int4, vec_int4, vmuluwm, vec_mul)
VSX_IMPL_2VRG(vec_uint4, vec_uint4, vmuluwm, vec_mul)
@@ -7,6 +7,19 @@ typedef cuda::GpuMat::Allocator GpuMat_Allocator;
typedef cuda::HostMem::AllocType HostMem_AllocType;
typedef cuda::Event::CreateFlags Event_CreateFlags;
template<> struct pyopencvVecConverter<cuda::GpuMat>
{
static bool to(PyObject* obj, std::vector<cuda::GpuMat>& value, const ArgInfo info)
{
return pyopencv_to_generic_vec(obj, value, info);
}
static PyObject* from(const std::vector<cuda::GpuMat>& value)
{
return pyopencv_from_generic_vec(value);
}
};
CV_PY_TO_CLASS(cuda::GpuMat);
CV_PY_TO_CLASS(cuda::Stream);
CV_PY_TO_CLASS(cuda::Event);
@@ -15,16 +28,10 @@ CV_PY_TO_CLASS(cuda::HostMem);
CV_PY_TO_CLASS_PTR(cuda::GpuMat);
CV_PY_TO_CLASS_PTR(cuda::GpuMat::Allocator);
CV_PY_TO_ENUM(cuda::Event::CreateFlags);
CV_PY_TO_ENUM(cuda::HostMem::AllocType);
CV_PY_TO_ENUM(cuda::FeatureSet);
CV_PY_FROM_CLASS(cuda::GpuMat);
CV_PY_FROM_CLASS(cuda::Stream);
CV_PY_FROM_CLASS(cuda::HostMem);
CV_PY_FROM_CLASS_PTR(cuda::GpuMat::Allocator);
CV_PY_FROM_ENUM(cuda::DeviceInfo::ComputeMode);
#endif
@@ -6,7 +6,6 @@ typedef std::vector<Range> vector_Range;
CV_PY_TO_CLASS(UMat);
CV_PY_FROM_CLASS(UMat);
CV_PY_TO_ENUM(UMatUsageFlags);
static bool cv_mappable_to(const Ptr<Mat>& src, Ptr<UMat>& dst)
{
+1 -1
View File
@@ -50,7 +50,7 @@ public:
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.
*/
CV_WRAP void* handle(int accessFlags) const;
CV_WRAP void* handle(AccessFlag accessFlags) const;
// offset of the submatrix (or 0)
CV_PROP_RW size_t offset;
+20 -16
View File
@@ -105,14 +105,18 @@ static bool ocl_binary_op(InputArray _src1, InputArray _src2, OutputArray _dst,
int scalarcn = kercn == 3 ? 4 : kercn;
int rowsPerWI = d.isIntel() ? 4 : 1;
sprintf(opts, "-D %s%s -D %s -D dstT=%s%s -D dstT_C1=%s -D workST=%s -D cn=%d -D rowsPerWI=%d",
const int dstDepth = srcdepth;
const int dstType = CV_MAKETYPE(dstDepth, kercn);
const int dstType1 = CV_MAKETYPE(dstDepth, 1);
const int scalarType = CV_MAKETYPE(srcdepth, scalarcn);
sprintf(opts, "-D %s%s -D %s%s -D dstT=%s -D DEPTH_dst=%d -D dstT_C1=%s -D workST=%s -D cn=%d -D rowsPerWI=%d",
haveMask ? "MASK_" : "", haveScalar ? "UNARY_OP" : "BINARY_OP", oclop2str[oclop],
bitwise ? ocl::memopTypeToStr(CV_MAKETYPE(srcdepth, kercn)) :
ocl::typeToStr(CV_MAKETYPE(srcdepth, kercn)), doubleSupport ? " -D DOUBLE_SUPPORT" : "",
bitwise ? ocl::memopTypeToStr(CV_MAKETYPE(srcdepth, 1)) :
ocl::typeToStr(CV_MAKETYPE(srcdepth, 1)),
bitwise ? ocl::memopTypeToStr(CV_MAKETYPE(srcdepth, scalarcn)) :
ocl::typeToStr(CV_MAKETYPE(srcdepth, scalarcn)),
doubleSupport ? " -D DOUBLE_SUPPORT" : "",
bitwise ? ocl::memopTypeToStr(dstType) : ocl::typeToStr(dstType),
dstDepth,
bitwise ? ocl::memopTypeToStr(dstType1) : ocl::typeToStr(dstType1),
bitwise ? ocl::memopTypeToStr(scalarType) : ocl::typeToStr(scalarType),
kercn, rowsPerWI);
ocl::Kernel k("KF", ocl::core::arithm_oclsrc, opts);
@@ -167,7 +171,7 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst,
bool bitwise, int oclop )
{
const _InputArray *psrc1 = &_src1, *psrc2 = &_src2;
int kind1 = psrc1->kind(), kind2 = psrc2->kind();
_InputArray::KindFlag kind1 = psrc1->kind(), kind2 = psrc2->kind();
int type1 = psrc1->type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1);
int type2 = psrc2->type(), depth2 = CV_MAT_DEPTH(type2), cn2 = CV_MAT_CN(type2);
int dims1 = psrc1->dims(), dims2 = psrc2->dims();
@@ -501,12 +505,12 @@ static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
char cvtstr[4][32], opts[1024];
sprintf(opts, "-D %s%s -D %s -D srcT1=%s -D srcT1_C1=%s -D srcT2=%s -D srcT2_C1=%s "
"-D dstT=%s -D dstT_C1=%s -D workT=%s -D workST=%s -D scaleT=%s -D wdepth=%d -D convertToWT1=%s "
"-D dstT=%s -D DEPTH_dst=%d -D dstT_C1=%s -D workT=%s -D workST=%s -D scaleT=%s -D wdepth=%d -D convertToWT1=%s "
"-D convertToWT2=%s -D convertToDT=%s%s -D cn=%d -D rowsPerWI=%d -D convertFromU=%s",
(haveMask ? "MASK_" : ""), (haveScalar ? "UNARY_OP" : "BINARY_OP"),
oclop2str[oclop], ocl::typeToStr(CV_MAKETYPE(depth1, kercn)),
ocl::typeToStr(depth1), ocl::typeToStr(CV_MAKETYPE(depth2, kercn)),
ocl::typeToStr(depth2), ocl::typeToStr(CV_MAKETYPE(ddepth, kercn)),
ocl::typeToStr(depth2), ocl::typeToStr(CV_MAKETYPE(ddepth, kercn)), ddepth,
ocl::typeToStr(ddepth), ocl::typeToStr(CV_MAKETYPE(wdepth, kercn)),
ocl::typeToStr(CV_MAKETYPE(wdepth, scalarcn)),
ocl::typeToStr(wdepth), wdepth,
@@ -600,7 +604,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
void* usrdata=0, int oclop=-1 )
{
const _InputArray *psrc1 = &_src1, *psrc2 = &_src2;
int kind1 = psrc1->kind(), kind2 = psrc2->kind();
_InputArray::KindFlag kind1 = psrc1->kind(), kind2 = psrc2->kind();
bool haveMask = !_mask.empty();
bool reallocate = false;
int type1 = psrc1->type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1);
@@ -1099,12 +1103,12 @@ static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, in
const char * const operationMap[] = { "==", ">", ">=", "<", "<=", "!=" };
char cvt[40];
String opts = format("-D %s -D srcT1=%s -D dstT=%s -D workT=srcT1 -D cn=%d"
String opts = format("-D %s -D srcT1=%s -D dstT=%s -D DEPTH_dst=%d -D workT=srcT1 -D cn=%d"
" -D convertToDT=%s -D OP_CMP -D CMP_OPERATOR=%s -D srcT1_C1=%s"
" -D srcT2_C1=%s -D dstT_C1=%s -D workST=%s -D rowsPerWI=%d%s",
haveScalar ? "UNARY_OP" : "BINARY_OP",
ocl::typeToStr(CV_MAKE_TYPE(depth1, kercn)),
ocl::typeToStr(CV_8UC(kercn)), kercn,
ocl::typeToStr(CV_8UC(kercn)), CV_8U, kercn,
ocl::convertTypeStr(depth1, CV_8U, kercn, cvt),
operationMap[op], ocl::typeToStr(depth1),
ocl::typeToStr(depth1), ocl::typeToStr(CV_8U),
@@ -1214,7 +1218,7 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
CV_OCL_RUN(_src1.dims() <= 2 && _src2.dims() <= 2 && OCL_PERFORMANCE_CHECK(_dst.isUMat()),
ocl_compare(_src1, _src2, _dst, op, haveScalar))
int kind1 = _src1.kind(), kind2 = _src2.kind();
_InputArray::KindFlag kind1 = _src1.kind(), kind2 = _src2.kind();
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 && src1.size() == src2.size() && src1.type() == src2.type() )
@@ -1587,7 +1591,7 @@ static bool ocl_inRange( InputArray _src, InputArray _lowerb,
InputArray _upperb, OutputArray _dst )
{
const ocl::Device & d = ocl::Device::getDefault();
int skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
_InputArray::KindFlag skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
Size ssize = _src.size(), lsize = _lowerb.size(), usize = _upperb.size();
int stype = _src.type(), ltype = _lowerb.type(), utype = _upperb.type();
int sdepth = CV_MAT_DEPTH(stype), ldepth = CV_MAT_DEPTH(ltype), udepth = CV_MAT_DEPTH(utype);
@@ -1712,7 +1716,7 @@ void cv::inRange(InputArray _src, InputArray _lowerb,
_upperb.dims() <= 2 && OCL_PERFORMANCE_CHECK(_dst.isUMat()),
ocl_inRange(_src, _lowerb, _upperb, _dst))
int skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
_InputArray::KindFlag skind = _src.kind(), lkind = _lowerb.kind(), ukind = _upperb.kind();
Mat src = _src.getMat(), lb = _lowerb.getMat(), ub = _upperb.getMat();
bool lbScalar = false, ubScalar = false;
+10 -4
View File
@@ -516,7 +516,10 @@ div_i( const T* src1, size_t step1, const T* src2, size_t step2,
for( ; i < width; i++ )
{
T num = src1[i], denom = src2[i];
dst[i] = denom != 0 ? saturate_cast<T>(num*scale_f/denom) : (T)0;
T v = 0;
if (denom != 0)
v = saturate_cast<T>(num*scale_f/denom);
dst[i] = v;
}
}
}
@@ -538,7 +541,7 @@ div_f( const T* src1, size_t step1, const T* src2, size_t step2,
for( ; i < width; i++ )
{
T num = src1[i], denom = src2[i];
dst[i] = denom != 0 ? saturate_cast<T>(num*scale_f/denom) : (T)0;
dst[i] = saturate_cast<T>(num*scale_f/denom);
}
}
}
@@ -559,7 +562,10 @@ recip_i( const T* src2, size_t step2,
for( ; i < width; i++ )
{
T denom = src2[i];
dst[i] = denom != 0 ? saturate_cast<T>(scale_f/denom) : (T)0;
T v = 0;
if (denom != 0)
v = saturate_cast<T>(scale_f/denom);
dst[i] = v;
}
}
}
@@ -580,7 +586,7 @@ recip_f( const T* src2, size_t step2,
for( ; i < width; i++ )
{
T denom = src2[i];
dst[i] = denom != 0 ? saturate_cast<T>(scale_f/denom) : (T)0;
dst[i] = saturate_cast<T>(scale_f/denom);
}
}
}
-16
View File
@@ -1433,7 +1433,6 @@ struct Div_SIMD<float>
return x;
v_float32x4 v_scale = v_setall_f32((float)scale);
v_float32x4 v_zero = v_setzero_f32();
for ( ; x <= width - 8; x += 8)
{
@@ -1445,9 +1444,6 @@ struct Div_SIMD<float>
v_float32x4 res0 = f0 * v_scale / f2;
v_float32x4 res1 = f1 * v_scale / f3;
res0 = v_select(f2 == v_zero, v_zero, res0);
res1 = v_select(f3 == v_zero, v_zero, res1);
v_store(dst + x, res0);
v_store(dst + x + 4, res1);
}
@@ -1675,7 +1671,6 @@ struct Recip_SIMD<float>
return x;
v_float32x4 v_scale = v_setall_f32((float)scale);
v_float32x4 v_zero = v_setzero_f32();
for ( ; x <= width - 8; x += 8)
{
@@ -1685,9 +1680,6 @@ struct Recip_SIMD<float>
v_float32x4 res0 = v_scale / f0;
v_float32x4 res1 = v_scale / f1;
res0 = v_select(f0 == v_zero, v_zero, res0);
res1 = v_select(f1 == v_zero, v_zero, res1);
v_store(dst + x, res0);
v_store(dst + x + 4, res1);
}
@@ -1712,7 +1704,6 @@ struct Div_SIMD<double>
return x;
v_float64x2 v_scale = v_setall_f64(scale);
v_float64x2 v_zero = v_setzero_f64();
for ( ; x <= width - 4; x += 4)
{
@@ -1724,9 +1715,6 @@ struct Div_SIMD<double>
v_float64x2 res0 = f0 * v_scale / f2;
v_float64x2 res1 = f1 * v_scale / f3;
res0 = v_select(f2 == v_zero, v_zero, res0);
res1 = v_select(f3 == v_zero, v_zero, res1);
v_store(dst + x, res0);
v_store(dst + x + 2, res1);
}
@@ -1749,7 +1737,6 @@ struct Recip_SIMD<double>
return x;
v_float64x2 v_scale = v_setall_f64(scale);
v_float64x2 v_zero = v_setzero_f64();
for ( ; x <= width - 4; x += 4)
{
@@ -1759,9 +1746,6 @@ struct Recip_SIMD<double>
v_float64x2 res0 = v_scale / f0;
v_float64x2 res1 = v_scale / f1;
res0 = v_select(f0 == v_zero, v_zero, res0);
res1 = v_select(f1 == v_zero, v_zero, res1);
v_store(dst + x, res0);
v_store(dst + x + 2, res1);
}
+5 -5
View File
@@ -237,11 +237,11 @@ static bool ocl_mixChannels(InputArrayOfArrays _src, InputOutputArrayOfArrays _d
dstargs[i] = dst[dst_idx];
dstargs[i].offset += dst_cnidx * esz;
declsrc += format("DECLARE_INPUT_MAT(%d)", i);
decldst += format("DECLARE_OUTPUT_MAT(%d)", i);
indexdecl += format("DECLARE_INDEX(%d)", i);
declproc += format("PROCESS_ELEM(%d)", i);
declcn += format(" -D scn%d=%d -D dcn%d=%d", i, src[src_idx].channels(), i, dst[dst_idx].channels());
declsrc += format("DECLARE_INPUT_MAT(%zu)", i);
decldst += format("DECLARE_OUTPUT_MAT(%zu)", i);
indexdecl += format("DECLARE_INDEX(%zu)", i);
declproc += format("PROCESS_ELEM(%zu)", i);
declcn += format(" -D scn%zu=%d -D dcn%zu=%d", i, src[src_idx].channels(), i, dst[dst_idx].channels());
}
ocl::Kernel k("mixChannels", ocl::core::mixchannels_oclsrc,
+8
View File
@@ -113,6 +113,10 @@ void check_failed_auto(const double v1, const double v2, const CheckContext& ctx
{
check_failed_auto_<double>(v1, v2, ctx);
}
void check_failed_auto(const Size_<int> v1, const Size_<int> v2, const CheckContext& ctx)
{
check_failed_auto_< Size_<int> >(v1, v2, ctx);
}
template<typename T> static CV_NORETURN
@@ -163,6 +167,10 @@ void check_failed_auto(const double v, const CheckContext& ctx)
{
check_failed_auto_<double>(v, ctx);
}
void check_failed_auto(const Size_<int> v, const CheckContext& ctx)
{
check_failed_auto_< Size_<int> >(v, ctx);
}
}} // namespace
+4 -4
View File
@@ -53,7 +53,7 @@ struct CommandLineParser::Impl
};
static const char* get_type_name(int type)
static const char* get_type_name(Param type)
{
if( type == Param::INT )
return "int";
@@ -81,7 +81,7 @@ static bool parse_bool(std::string str)
return b;
}
static void from_str(const String& str, int type, void* dst)
static void from_str(const String& str, Param type, void* dst)
{
std::stringstream ss(str.c_str());
if( type == Param::INT )
@@ -117,7 +117,7 @@ static void from_str(const String& str, int type, void* dst)
}
}
void CommandLineParser::getByName(const String& name, bool space_delete, int type, void* dst) const
void CommandLineParser::getByName(const String& name, bool space_delete, Param type, void* dst) const
{
CV_TRY
{
@@ -154,7 +154,7 @@ void CommandLineParser::getByName(const String& name, bool space_delete, int typ
}
void CommandLineParser::getByIndex(int index, bool space_delete, int type, void* dst) const
void CommandLineParser::getByIndex(int index, bool space_delete, Param type, void* dst) const
{
CV_TRY
{
+2 -2
View File
@@ -375,10 +375,10 @@ static bool ocl_convertScaleAbs( InputArray _src, OutputArray _dst, double alpha
int rowsPerWI = d.isIntel() ? 4 : 1;
char cvt[2][50];
int wdepth = std::max(depth, CV_32F);
String build_opt = format("-D OP_CONVERT_SCALE_ABS -D UNARY_OP -D dstT=%s -D srcT1=%s"
String build_opt = format("-D OP_CONVERT_SCALE_ABS -D UNARY_OP -D dstT=%s -D DEPTH_dst=%d -D srcT1=%s"
" -D workT=%s -D wdepth=%d -D convertToWT1=%s -D convertToDT=%s"
" -D workT1=%s -D rowsPerWI=%d%s",
ocl::typeToStr(CV_8UC(kercn)),
ocl::typeToStr(CV_8UC(kercn)), CV_8U,
ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)),
ocl::typeToStr(CV_MAKE_TYPE(wdepth, kercn)), wdepth,
ocl::convertTypeStr(depth, wdepth, kercn, cvt[0]),
+16 -14
View File
@@ -90,20 +90,21 @@ copyMask_<uchar>(const uchar* _src, size_t sstep, const uchar* mask, size_t mste
const uchar* src = (const uchar*)_src;
uchar* dst = (uchar*)_dst;
int x = 0;
#if CV_SIMD128
#if CV_SIMD
{
v_uint8x16 v_zero = v_setzero_u8();
v_uint8 v_zero = vx_setzero_u8();
for( ; x <= size.width - 16; x += 16 )
for( ; x <= size.width - v_uint8::nlanes; x += v_uint8::nlanes )
{
v_uint8x16 v_src = v_load(src + x),
v_dst = v_load(dst + x),
v_nmask = v_load(mask + x) == v_zero;
v_uint8 v_src = vx_load(src + x),
v_dst = vx_load(dst + x),
v_nmask = vx_load(mask + x) == v_zero;
v_dst = v_select(v_nmask, v_dst, v_src);
v_store(dst + x, v_dst);
}
}
vx_cleanup();
#endif
for( ; x < size.width; x++ )
if( mask[x] )
@@ -121,25 +122,26 @@ copyMask_<ushort>(const uchar* _src, size_t sstep, const uchar* mask, size_t mst
const ushort* src = (const ushort*)_src;
ushort* dst = (ushort*)_dst;
int x = 0;
#if CV_SIMD128
#if CV_SIMD
{
v_uint8x16 v_zero = v_setzero_u8();
v_uint8 v_zero = vx_setzero_u8();
for( ; x <= size.width - 16; x += 16 )
for( ; x <= size.width - v_uint8::nlanes; x += v_uint8::nlanes )
{
v_uint16x8 v_src1 = v_load(src + x), v_src2 = v_load(src + x + 8),
v_dst1 = v_load(dst + x), v_dst2 = v_load(dst + x + 8);
v_uint16 v_src1 = vx_load(src + x), v_src2 = vx_load(src + x + v_uint16::nlanes),
v_dst1 = vx_load(dst + x), v_dst2 = vx_load(dst + x + v_uint16::nlanes);
v_uint8x16 v_nmask1, v_nmask2;
v_uint8x16 v_nmask = v_load(mask + x) == v_zero;
v_uint8 v_nmask1, v_nmask2;
v_uint8 v_nmask = vx_load(mask + x) == v_zero;
v_zip(v_nmask, v_nmask, v_nmask1, v_nmask2);
v_dst1 = v_select(v_reinterpret_as_u16(v_nmask1), v_dst1, v_src1);
v_dst2 = v_select(v_reinterpret_as_u16(v_nmask2), v_dst2, v_src2);
v_store(dst + x, v_dst1);
v_store(dst + x + 8, v_dst2);
v_store(dst + x + v_uint16::nlanes, v_dst2);
}
}
vx_cleanup();
#endif
for( ; x < size.width; x++ )
if( mask[x] )
+2 -2
View File
@@ -60,7 +60,7 @@ public:
UMatData* allocate(int dims, const int* sizes, int type,
void* data0, size_t* step,
int /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
AccessFlag /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
{
size_t total = CV_ELEM_SIZE(type);
for (int i = dims-1; i >= 0; i--)
@@ -100,7 +100,7 @@ public:
return u;
}
bool allocate(UMatData* u, int /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
bool allocate(UMatData* u, AccessFlag /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
{
return (u != NULL);
}
+83 -106
View File
@@ -277,40 +277,42 @@ template<typename T> struct VBLAS
int givensx(T*, T*, int, T, T, T*, T*) const { return 0; }
};
#if CV_SIMD128
#if CV_SIMD
template<> inline int VBLAS<float>::dot(const float* a, const float* b, int n, float* result) const
{
if( n < 8 )
if( n < 2*v_float32::nlanes )
return 0;
int k = 0;
v_float32x4 s0 = v_setzero_f32();
for( ; k <= n - v_float32x4::nlanes; k += v_float32x4::nlanes )
v_float32 s0 = vx_setzero_f32();
for( ; k <= n - v_float32::nlanes; k += v_float32::nlanes )
{
v_float32x4 a0 = v_load(a + k);
v_float32x4 b0 = v_load(b + k);
v_float32 a0 = vx_load(a + k);
v_float32 b0 = vx_load(b + k);
s0 += a0 * b0;
}
*result = v_reduce_sum(s0);
vx_cleanup();
return k;
}
template<> inline int VBLAS<float>::givens(float* a, float* b, int n, float c, float s) const
{
if( n < 4 )
if( n < v_float32::nlanes)
return 0;
int k = 0;
v_float32x4 c4 = v_setall_f32(c), s4 = v_setall_f32(s);
for( ; k <= n - v_float32x4::nlanes; k += v_float32x4::nlanes )
v_float32 c4 = vx_setall_f32(c), s4 = vx_setall_f32(s);
for( ; k <= n - v_float32::nlanes; k += v_float32::nlanes )
{
v_float32x4 a0 = v_load(a + k);
v_float32x4 b0 = v_load(b + k);
v_float32x4 t0 = (a0 * c4) + (b0 * s4);
v_float32x4 t1 = (b0 * c4) - (a0 * s4);
v_float32 a0 = vx_load(a + k);
v_float32 b0 = vx_load(b + k);
v_float32 t0 = (a0 * c4) + (b0 * s4);
v_float32 t1 = (b0 * c4) - (a0 * s4);
v_store(a + k, t0);
v_store(b + k, t1);
}
vx_cleanup();
return k;
}
@@ -318,17 +320,17 @@ template<> inline int VBLAS<float>::givens(float* a, float* b, int n, float c, f
template<> inline int VBLAS<float>::givensx(float* a, float* b, int n, float c, float s,
float* anorm, float* bnorm) const
{
if( n < 4 )
if( n < v_float32::nlanes)
return 0;
int k = 0;
v_float32x4 c4 = v_setall_f32(c), s4 = v_setall_f32(s);
v_float32x4 sa = v_setzero_f32(), sb = v_setzero_f32();
for( ; k <= n - v_float32x4::nlanes; k += v_float32x4::nlanes )
v_float32 c4 = vx_setall_f32(c), s4 = vx_setall_f32(s);
v_float32 sa = vx_setzero_f32(), sb = vx_setzero_f32();
for( ; k <= n - v_float32::nlanes; k += v_float32::nlanes )
{
v_float32x4 a0 = v_load(a + k);
v_float32x4 b0 = v_load(b + k);
v_float32x4 t0 = (a0 * c4) + (b0 * s4);
v_float32x4 t1 = (b0 * c4) - (a0 * s4);
v_float32 a0 = vx_load(a + k);
v_float32 b0 = vx_load(b + k);
v_float32 t0 = (a0 * c4) + (b0 * s4);
v_float32 t1 = (b0 * c4) - (a0 * s4);
v_store(a + k, t0);
v_store(b + k, t1);
sa += t0 + t0;
@@ -336,26 +338,28 @@ template<> inline int VBLAS<float>::givensx(float* a, float* b, int n, float c,
}
*anorm = v_reduce_sum(sa);
*bnorm = v_reduce_sum(sb);
vx_cleanup();
return k;
}
#if CV_SIMD128_64F
#if CV_SIMD_64F
template<> inline int VBLAS<double>::dot(const double* a, const double* b, int n, double* result) const
{
if( n < 4 )
if( n < 2*v_float64::nlanes )
return 0;
int k = 0;
v_float64x2 s0 = v_setzero_f64();
for( ; k <= n - v_float64x2::nlanes; k += v_float64x2::nlanes )
v_float64 s0 = vx_setzero_f64();
for( ; k <= n - v_float64::nlanes; k += v_float64::nlanes )
{
v_float64x2 a0 = v_load(a + k);
v_float64x2 b0 = v_load(b + k);
v_float64 a0 = vx_load(a + k);
v_float64 b0 = vx_load(b + k);
s0 += a0 * b0;
}
double sbuf[2];
v_store(sbuf, s0);
*result = sbuf[0] + sbuf[1];
vx_cleanup();
return k;
}
@@ -363,16 +367,17 @@ template<> inline int VBLAS<double>::dot(const double* a, const double* b, int n
template<> inline int VBLAS<double>::givens(double* a, double* b, int n, double c, double s) const
{
int k = 0;
v_float64x2 c2 = v_setall_f64(c), s2 = v_setall_f64(s);
for( ; k <= n - v_float64x2::nlanes; k += v_float64x2::nlanes )
v_float64 c2 = vx_setall_f64(c), s2 = vx_setall_f64(s);
for( ; k <= n - v_float64::nlanes; k += v_float64::nlanes )
{
v_float64x2 a0 = v_load(a + k);
v_float64x2 b0 = v_load(b + k);
v_float64x2 t0 = (a0 * c2) + (b0 * s2);
v_float64x2 t1 = (b0 * c2) - (a0 * s2);
v_float64 a0 = vx_load(a + k);
v_float64 b0 = vx_load(b + k);
v_float64 t0 = (a0 * c2) + (b0 * s2);
v_float64 t1 = (b0 * c2) - (a0 * s2);
v_store(a + k, t0);
v_store(b + k, t1);
}
vx_cleanup();
return k;
}
@@ -381,14 +386,14 @@ template<> inline int VBLAS<double>::givensx(double* a, double* b, int n, double
double* anorm, double* bnorm) const
{
int k = 0;
v_float64x2 c2 = v_setall_f64(c), s2 = v_setall_f64(s);
v_float64x2 sa = v_setzero_f64(), sb = v_setzero_f64();
for( ; k <= n - v_float64x2::nlanes; k += v_float64x2::nlanes )
v_float64 c2 = vx_setall_f64(c), s2 = vx_setall_f64(s);
v_float64 sa = vx_setzero_f64(), sb = vx_setzero_f64();
for( ; k <= n - v_float64::nlanes; k += v_float64::nlanes )
{
v_float64x2 a0 = v_load(a + k);
v_float64x2 b0 = v_load(b + k);
v_float64x2 t0 = (a0 * c2) + (b0 * s2);
v_float64x2 t1 = (b0 * c2) - (a0 * s2);
v_float64 a0 = vx_load(a + k);
v_float64 b0 = vx_load(b + k);
v_float64 t0 = (a0 * c2) + (b0 * s2);
v_float64 t1 = (b0 * c2) - (a0 * s2);
v_store(a + k, t0);
v_store(b + k, t1);
sa += t0 * t0;
@@ -401,8 +406,8 @@ template<> inline int VBLAS<double>::givensx(double* a, double* b, int n, double
*bnorm = bbuf[0] + bbuf[1];
return k;
}
#endif //CV_SIMD128_64F
#endif //CV_SIMD128
#endif //CV_SIMD_64F
#endif //CV_SIMD
template<typename _Tp> void
JacobiSVDImpl_(_Tp* At, size_t astep, _Tp* _W, _Tp* Vt, size_t vstep,
@@ -910,37 +915,23 @@ double cv::invert( InputArray _src, OutputArray _dst, int method )
{
result = true;
d = 1./d;
#if CV_SSE2
if(USE_SSE2)
{
__m128 zero = _mm_setzero_ps();
__m128 t0 = _mm_loadl_pi(zero, (const __m64*)srcdata); //t0 = sf(0,0) sf(0,1)
__m128 t1 = _mm_loadh_pi(zero, (const __m64*)(srcdata+srcstep)); //t1 = sf(1,0) sf(1,1)
__m128 s0 = _mm_or_ps(t0, t1);
__m128 det =_mm_set1_ps((float)d);
s0 = _mm_mul_ps(s0, det);
static const uchar CV_DECL_ALIGNED(16) inv[16] = {0,0,0,0,0,0,0,0x80,0,0,0,0x80,0,0,0,0};
__m128 pattern = _mm_load_ps((const float*)inv);
s0 = _mm_xor_ps(s0, pattern);//==-1*s0
s0 = _mm_shuffle_ps(s0, s0, _MM_SHUFFLE(0,2,1,3));
_mm_storel_pi((__m64*)dstdata, s0);
_mm_storeh_pi((__m64*)((float*)(dstdata+dststep)), s0);
}
else
#endif
{
double t0, t1;
t0 = Sf(0,0)*d;
t1 = Sf(1,1)*d;
Df(1,1) = (float)t0;
Df(0,0) = (float)t1;
t0 = -Sf(0,1)*d;
t1 = -Sf(1,0)*d;
Df(0,1) = (float)t0;
Df(1,0) = (float)t1;
}
#if CV_SIMD128
static const float CV_DECL_ALIGNED(16) inv[4] = { 0.f,-0.f,-0.f,0.f };
v_float32x4 s0 = (v_load_halves((const float*)srcdata, (const float*)(srcdata + srcstep)) * v_setall_f32((float)d)) ^ v_load((const float *)inv);//0123//3120
s0 = v_extract<3>(s0, v_combine_low(v_rotate_right<1>(s0), s0));
v_store_low((float*)dstdata, s0);
v_store_high((float*)(dstdata + dststep), s0);
#else
double t0, t1;
t0 = Sf(0,0)*d;
t1 = Sf(1,1)*d;
Df(1,1) = (float)t0;
Df(0,0) = (float)t1;
t0 = -Sf(0,1)*d;
t1 = -Sf(1,0)*d;
Df(0,1) = (float)t0;
Df(1,0) = (float)t1;
#endif
}
}
else
@@ -950,39 +941,25 @@ double cv::invert( InputArray _src, OutputArray _dst, int method )
{
result = true;
d = 1./d;
#if CV_SSE2
if(USE_SSE2)
{
__m128d s0 = _mm_loadu_pd((const double*)srcdata); //s0 = sf(0,0) sf(0,1)
__m128d s1 = _mm_loadu_pd ((const double*)(srcdata+srcstep));//s1 = sf(1,0) sf(1,1)
__m128d sm = _mm_unpacklo_pd(s0, _mm_load_sd((const double*)(srcdata+srcstep)+1)); //sm = sf(0,0) sf(1,1) - main diagonal
__m128d ss = _mm_shuffle_pd(s0, s1, _MM_SHUFFLE2(0,1)); //ss = sf(0,1) sf(1,0) - secondary diagonal
__m128d det = _mm_load1_pd((const double*)&d);
sm = _mm_mul_pd(sm, det);
static const uchar CV_DECL_ALIGNED(16) inv[8] = {0,0,0,0,0,0,0,0x80};
__m128d pattern = _mm_load1_pd((double*)inv);
ss = _mm_mul_pd(ss, det);
ss = _mm_xor_pd(ss, pattern);//==-1*ss
s0 = _mm_shuffle_pd(sm, ss, _MM_SHUFFLE2(0,1));
s1 = _mm_shuffle_pd(ss, sm, _MM_SHUFFLE2(0,1));
_mm_storeu_pd((double*)dstdata, s0);
_mm_storeu_pd((double*)(dstdata+dststep), s1);
}
else
#endif
{
double t0, t1;
t0 = Sd(0,0)*d;
t1 = Sd(1,1)*d;
Dd(1,1) = t0;
Dd(0,0) = t1;
t0 = -Sd(0,1)*d;
t1 = -Sd(1,0)*d;
Dd(0,1) = t0;
Dd(1,0) = t1;
}
#if CV_SIMD128_64F
v_float64x2 det = v_setall_f64(d);
v_float64x2 s0 = v_load((const double*)srcdata) * det;
v_float64x2 s1 = v_load((const double*)(srcdata+srcstep)) * det;
v_float64x2 sm = v_extract<1>(s1, s0);//30
v_float64x2 ss = v_extract<1>(s0, s1) ^ v_setall_f64(-0.);//12
v_store((double*)dstdata, v_combine_low(sm, ss));//31
v_store((double*)(dstdata + dststep), v_combine_high(ss, sm));//20
#else
double t0, t1;
t0 = Sd(0,0)*d;
t1 = Sd(1,1)*d;
Dd(1,1) = t0;
Dd(0,0) = t1;
t0 = -Sd(0,1)*d;
t1 = -Sd(1,0)*d;
Dd(0,1) = t0;
Dd(1,0) = t1;
#endif
}
}
}
+3 -3
View File
@@ -184,7 +184,7 @@ Mat LDA::subspaceProject(InputArray _W, InputArray _mean, InputArray _src) {
}
// make sure mean is correct if not empty
if(!mean.empty() && (mean.total() != (size_t) d)) {
String error_message = format("Wrong mean shape for the given data matrix. Expected %d, but was %d.", d, mean.total());
String error_message = format("Wrong mean shape for the given data matrix. Expected %d, but was %zu.", d, mean.total());
CV_Error(Error::StsBadArg, error_message);
}
// create temporary matrices
@@ -222,7 +222,7 @@ Mat LDA::subspaceReconstruct(InputArray _W, InputArray _mean, InputArray _src)
}
// make sure mean is correct if not empty
if(!mean.empty() && (mean.total() != (size_t) W.rows)) {
String error_message = format("Wrong mean shape for the given eigenvector matrix. Expected %d, but was %d.", W.cols, mean.total());
String error_message = format("Wrong mean shape for the given eigenvector matrix. Expected %d, but was %zu.", W.cols, mean.total());
CV_Error(Error::StsBadArg, error_message);
}
// initialize temporary matrices
@@ -1076,7 +1076,7 @@ void LDA::lda(InputArrayOfArrays _src, InputArray _lbls) {
}
// throw error if less labels, than samples
if (labels.size() != static_cast<size_t>(N)) {
String error_message = format("The number of samples must equal the number of labels. Given %d labels, %d samples. ", labels.size(), N);
String error_message = format("The number of samples must equal the number of labels. Given %zu labels, %d samples. ", labels.size(), N);
CV_Error(Error::StsBadArg, error_message);
}
// warn if within-classes scatter matrix becomes singular
+13 -10
View File
@@ -90,18 +90,20 @@ static void swap_columns(Mat_<double>& A,int col1,int col2);
#define SWAP(type,a,b) {type tmp=(a);(a)=(b);(b)=tmp;}
//return codes:-2 (no_sol - unbdd),-1(no_sol - unfsbl), 0(single_sol), 1(multiple_sol=>least_l2_norm)
int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
int solveLP(InputArray Func_, InputArray Constr_, OutputArray z_)
{
dprintf(("call to solveLP\n"));
//sanity check (size, type, no. of channels)
CV_Assert(Func.type()==CV_64FC1 || Func.type()==CV_32FC1);
CV_Assert(Constr.type()==CV_64FC1 || Constr.type()==CV_32FC1);
CV_Assert((Func.rows==1 && (Constr.cols-Func.cols==1))||
(Func.cols==1 && (Constr.cols-Func.rows==1)));
if (!z.empty())
CV_CheckTypeEQ(z.type(), CV_64FC1, "");
else
CV_CheckType(z.type(), z.type() == CV_64FC1 || z.type() == CV_8UC1/*empty cv::Mat*/, "");
CV_Assert(Func_.type()==CV_64FC1 || Func_.type()==CV_32FC1);
CV_Assert(Constr_.type()==CV_64FC1 || Constr_.type()==CV_32FC1);
CV_Assert((Func_.rows()==1 && (Constr_.cols()-Func_.cols()==1))||
(Func_.cols()==1 && (Constr_.cols()-Func_.rows()==1)));
if (z_.fixedType())
CV_CheckType(z_.type(), z_.type() == CV_64FC1 || z_.type() == CV_32FC1 || z_.type() == CV_32SC1, "");
Mat Func = Func_.getMat();
Mat Constr = Constr_.getMat();
//copy arguments for we will shall modify them
Mat_<double> bigC=Mat_<double>(1,(Func.rows==1?Func.cols:Func.rows)+1),
@@ -129,7 +131,7 @@ int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
}
//return the optimal solution
z.create(c.cols,1,CV_64FC1);
Mat z(c.cols,1,CV_64FC1);
MatIterator_<double> it=z.begin<double>();
unsigned int nsize = (unsigned int)N.size();
for(int i=1;i<=c.cols;i++,it++){
@@ -140,6 +142,7 @@ int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
}
}
z.copyTo(z_);
return res;
}
+82 -71
View File
@@ -71,8 +71,8 @@ static bool ocl_math_op(InputArray _src1, InputArray _src2, OutputArray _dst, in
int rowsPerWI = d.isIntel() ? 4 : 1;
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D %s -D %s -D dstT=%s -D rowsPerWI=%d%s", _src2.empty() ? "UNARY_OP" : "BINARY_OP",
oclop2str[oclop], ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)), rowsPerWI,
format("-D %s -D %s -D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d%s", _src2.empty() ? "UNARY_OP" : "BINARY_OP",
oclop2str[oclop], ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)), depth, rowsPerWI,
double_support ? " -D DOUBLE_SUPPORT" : ""));
if (k.empty())
return false;
@@ -238,9 +238,9 @@ static bool ocl_cartToPolar( InputArray _src1, InputArray _src2,
return false;
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D BINARY_OP -D dstT=%s -D depth=%d -D rowsPerWI=%d -D OP_CTP_%s%s",
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)),
depth, rowsPerWI, angleInDegrees ? "AD" : "AR",
format("-D BINARY_OP -D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D OP_CTP_%s%s",
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), depth,
rowsPerWI, angleInDegrees ? "AD" : "AR",
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
if (k.empty())
return false;
@@ -474,9 +474,10 @@ static bool ocl_polarToCart( InputArray _mag, InputArray _angle,
return false;
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D dstT=%s -D rowsPerWI=%d -D depth=%d -D BINARY_OP -D OP_PTC_%s%s",
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), rowsPerWI,
depth, angleInDegrees ? "AD" : "AR",
format("-D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D BINARY_OP -D OP_PTC_%s%s",
ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), depth,
rowsPerWI,
angleInDegrees ? "AD" : "AR",
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
if (k.empty())
return false;
@@ -606,17 +607,15 @@ void polarToCart( InputArray src1, InputArray src2,
{
k = 0;
#if CV_SIMD128
if( hasSIMD128() )
#if CV_SIMD
int cWidth = v_float32::nlanes;
for( ; k <= len - cWidth; k += cWidth )
{
int cWidth = v_float32x4::nlanes;
for( ; k <= len - cWidth; k += cWidth )
{
v_float32x4 v_m = v_load(mag + k);
v_store(x + k, v_load(x + k) * v_m);
v_store(y + k, v_load(y + k) * v_m);
}
v_float32 v_m = vx_load(mag + k);
v_store(x + k, vx_load(x + k) * v_m);
v_store(y + k, vx_load(y + k) * v_m);
}
vx_cleanup();
#endif
for( ; k < len; k++ )
@@ -735,7 +734,7 @@ struct iPow_SIMD
}
};
#if CV_SIMD128
#if CV_SIMD
template <>
struct iPow_SIMD<uchar, int>
@@ -743,13 +742,13 @@ struct iPow_SIMD<uchar, int>
int operator() ( const uchar * src, uchar * dst, int len, int power )
{
int i = 0;
v_uint32x4 v_1 = v_setall_u32(1u);
v_uint32 v_1 = vx_setall_u32(1u);
for ( ; i <= len - 8; i += 8)
for ( ; i <= len - v_uint16::nlanes; i += v_uint16::nlanes)
{
v_uint32x4 v_a1 = v_1, v_a2 = v_1;
v_uint16x8 v = v_load_expand(src + i);
v_uint32x4 v_b1, v_b2;
v_uint32 v_a1 = v_1, v_a2 = v_1;
v_uint16 v = vx_load_expand(src + i);
v_uint32 v_b1, v_b2;
v_expand(v, v_b1, v_b2);
int p = power;
@@ -771,6 +770,7 @@ struct iPow_SIMD<uchar, int>
v = v_pack(v_a1, v_a2);
v_pack_store(dst + i, v);
}
vx_cleanup();
return i;
}
@@ -782,13 +782,13 @@ struct iPow_SIMD<schar, int>
int operator() ( const schar * src, schar * dst, int len, int power)
{
int i = 0;
v_int32x4 v_1 = v_setall_s32(1);
v_int32 v_1 = vx_setall_s32(1);
for ( ; i <= len - 8; i += 8)
for ( ; i <= len - v_int16::nlanes; i += v_int16::nlanes)
{
v_int32x4 v_a1 = v_1, v_a2 = v_1;
v_int16x8 v = v_load_expand(src + i);
v_int32x4 v_b1, v_b2;
v_int32 v_a1 = v_1, v_a2 = v_1;
v_int16 v = vx_load_expand(src + i);
v_int32 v_b1, v_b2;
v_expand(v, v_b1, v_b2);
int p = power;
@@ -810,6 +810,7 @@ struct iPow_SIMD<schar, int>
v = v_pack(v_a1, v_a2);
v_pack_store(dst + i, v);
}
vx_cleanup();
return i;
}
@@ -821,13 +822,13 @@ struct iPow_SIMD<ushort, int>
int operator() ( const ushort * src, ushort * dst, int len, int power)
{
int i = 0;
v_uint32x4 v_1 = v_setall_u32(1u);
v_uint32 v_1 = vx_setall_u32(1u);
for ( ; i <= len - 8; i += 8)
for ( ; i <= len - v_uint16::nlanes; i += v_uint16::nlanes)
{
v_uint32x4 v_a1 = v_1, v_a2 = v_1;
v_uint16x8 v = v_load(src + i);
v_uint32x4 v_b1, v_b2;
v_uint32 v_a1 = v_1, v_a2 = v_1;
v_uint16 v = vx_load(src + i);
v_uint32 v_b1, v_b2;
v_expand(v, v_b1, v_b2);
int p = power;
@@ -849,6 +850,7 @@ struct iPow_SIMD<ushort, int>
v = v_pack(v_a1, v_a2);
v_store(dst + i, v);
}
vx_cleanup();
return i;
}
@@ -860,13 +862,13 @@ struct iPow_SIMD<short, int>
int operator() ( const short * src, short * dst, int len, int power)
{
int i = 0;
v_int32x4 v_1 = v_setall_s32(1);
v_int32 v_1 = vx_setall_s32(1);
for ( ; i <= len - 8; i += 8)
for ( ; i <= len - v_int16::nlanes; i += v_int16::nlanes)
{
v_int32x4 v_a1 = v_1, v_a2 = v_1;
v_int16x8 v = v_load(src + i);
v_int32x4 v_b1, v_b2;
v_int32 v_a1 = v_1, v_a2 = v_1;
v_int16 v = vx_load(src + i);
v_int32 v_b1, v_b2;
v_expand(v, v_b1, v_b2);
int p = power;
@@ -888,6 +890,7 @@ struct iPow_SIMD<short, int>
v = v_pack(v_a1, v_a2);
v_store(dst + i, v);
}
vx_cleanup();
return i;
}
@@ -899,12 +902,12 @@ struct iPow_SIMD<int, int>
int operator() ( const int * src, int * dst, int len, int power)
{
int i = 0;
v_int32x4 v_1 = v_setall_s32(1);
v_int32 v_1 = vx_setall_s32(1);
for ( ; i <= len - 8; i += 8)
for ( ; i <= len - v_int32::nlanes*2; i += v_int32::nlanes*2)
{
v_int32x4 v_a1 = v_1, v_a2 = v_1;
v_int32x4 v_b1 = v_load(src + i), v_b2 = v_load(src + i + 4);
v_int32 v_a1 = v_1, v_a2 = v_1;
v_int32 v_b1 = vx_load(src + i), v_b2 = vx_load(src + i + v_int32::nlanes);
int p = power;
while( p > 1 )
@@ -923,8 +926,9 @@ struct iPow_SIMD<int, int>
v_a2 *= v_b2;
v_store(dst + i, v_a1);
v_store(dst + i + 4, v_a2);
v_store(dst + i + v_int32::nlanes, v_a2);
}
vx_cleanup();
return i;
}
@@ -936,12 +940,12 @@ struct iPow_SIMD<float, float>
int operator() ( const float * src, float * dst, int len, int power)
{
int i = 0;
v_float32x4 v_1 = v_setall_f32(1.f);
v_float32 v_1 = vx_setall_f32(1.f);
for ( ; i <= len - 8; i += 8)
for ( ; i <= len - v_float32::nlanes*2; i += v_float32::nlanes*2)
{
v_float32x4 v_a1 = v_1, v_a2 = v_1;
v_float32x4 v_b1 = v_load(src + i), v_b2 = v_load(src + i + 4);
v_float32 v_a1 = v_1, v_a2 = v_1;
v_float32 v_b1 = vx_load(src + i), v_b2 = vx_load(src + i + v_float32::nlanes);
int p = std::abs(power);
if( power < 0 )
{
@@ -965,26 +969,27 @@ struct iPow_SIMD<float, float>
v_a2 *= v_b2;
v_store(dst + i, v_a1);
v_store(dst + i + 4, v_a2);
v_store(dst + i + v_float32::nlanes, v_a2);
}
vx_cleanup();
return i;
}
};
#if CV_SIMD128_64F
#if CV_SIMD_64F
template <>
struct iPow_SIMD<double, double>
{
int operator() ( const double * src, double * dst, int len, int power)
{
int i = 0;
v_float64x2 v_1 = v_setall_f64(1.);
v_float64 v_1 = vx_setall_f64(1.);
for ( ; i <= len - 4; i += 4)
for ( ; i <= len - v_float64::nlanes*2; i += v_float64::nlanes*2)
{
v_float64x2 v_a1 = v_1, v_a2 = v_1;
v_float64x2 v_b1 = v_load(src + i), v_b2 = v_load(src + i + 2);
v_float64 v_a1 = v_1, v_a2 = v_1;
v_float64 v_b1 = vx_load(src + i), v_b2 = vx_load(src + i + v_float64::nlanes);
int p = std::abs(power);
if( power < 0 )
{
@@ -1008,8 +1013,9 @@ struct iPow_SIMD<double, double>
v_a2 *= v_b2;
v_store(dst + i, v_a1);
v_store(dst + i + 2, v_a2);
v_store(dst + i + v_float64::nlanes, v_a2);
}
vx_cleanup();
return i;
}
@@ -1169,8 +1175,8 @@ static bool ocl_pow(InputArray _src, double power, OutputArray _dst,
const char * const op = issqrt ? "OP_SQRT" : is_ipower ? "OP_POWN" : "OP_POW";
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D dstT=%s -D depth=%d -D rowsPerWI=%d -D %s -D UNARY_OP%s",
ocl::typeToStr(depth), depth, rowsPerWI, op,
format("-D dstT=%s -D DEPTH_dst=%d -D rowsPerWI=%d -D %s -D UNARY_OP%s",
ocl::typeToStr(depth), depth, rowsPerWI, op,
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
if (k.empty())
return false;
@@ -1271,10 +1277,17 @@ void pow( InputArray _src, double power, OutputArray _dst )
Cv64suf inf64, nan64;
float* fbuf = 0;
double* dbuf = 0;
#ifndef __EMSCRIPTEN__
inf32.i = 0x7f800000;
nan32.i = 0x7fffffff;
inf64.i = CV_BIG_INT(0x7FF0000000000000);
nan64.i = CV_BIG_INT(0x7FFFFFFFFFFFFFFF);
#else
inf32.f = std::numeric_limits<float>::infinity();
nan32.f = std::numeric_limits<float>::quiet_NaN();
inf64.f = std::numeric_limits<double>::infinity();
nan64.f = std::numeric_limits<double>::quiet_NaN();
#endif
if( src.ptr() == dst.ptr() )
{
@@ -1560,8 +1573,8 @@ static bool ocl_patchNaNs( InputOutputArray _a, float value )
{
int rowsPerWI = ocl::Device::getDefault().isIntel() ? 4 : 1;
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D UNARY_OP -D OP_PATCH_NANS -D dstT=float -D rowsPerWI=%d",
rowsPerWI));
format("-D UNARY_OP -D OP_PATCH_NANS -D dstT=float -D DEPTH_dst=%d -D rowsPerWI=%d",
CV_32F, rowsPerWI));
if (k.empty())
return false;
@@ -1594,9 +1607,9 @@ void patchNaNs( InputOutputArray _a, double _val )
Cv32suf val;
val.f = (float)_val;
#if CV_SIMD128
v_int32x4 v_mask1 = v_setall_s32(0x7fffffff), v_mask2 = v_setall_s32(0x7f800000);
v_int32x4 v_val = v_setall_s32(val.i);
#if CV_SIMD
v_int32 v_mask1 = vx_setall_s32(0x7fffffff), v_mask2 = vx_setall_s32(0x7f800000);
v_int32 v_val = vx_setall_s32(val.i);
#endif
for( size_t i = 0; i < it.nplanes; i++, ++it )
@@ -1604,18 +1617,16 @@ void patchNaNs( InputOutputArray _a, double _val )
int* tptr = ptrs[0];
size_t j = 0;
#if CV_SIMD128
if( hasSIMD128() )
#if CV_SIMD
size_t cWidth = (size_t)v_int32::nlanes;
for ( ; j + cWidth <= len; j += cWidth)
{
size_t cWidth = (size_t)v_int32x4::nlanes;
for ( ; j + cWidth <= len; j += cWidth)
{
v_int32x4 v_src = v_load(tptr + j);
v_int32x4 v_cmp_mask = v_mask2 < (v_src & v_mask1);
v_int32x4 v_dst = v_select(v_cmp_mask, v_val, v_src);
v_store(tptr + j, v_dst);
}
v_int32 v_src = vx_load(tptr + j);
v_int32 v_cmp_mask = v_mask2 < (v_src & v_mask1);
v_int32 v_dst = v_select(v_cmp_mask, v_val, v_src);
v_store(tptr + j, v_dst);
}
vx_cleanup();
#endif
for( ; j < len; j++ )
+14 -3
View File
@@ -27,16 +27,26 @@ float fastAtan2(float y, float x);
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
using namespace std;
using namespace cv;
namespace {
#ifdef __EMSCRIPTEN__
static inline float atan_f32(float y, float x)
{
float a = atan2(y, x) * 180.0f / CV_PI;
if (a < 0.0f)
a += 360.0f;
if (a >= 360.0f)
a -= 360.0f;
return a; // range [0; 360)
}
#else
static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI);
static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI);
static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI);
static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI);
using namespace cv;
static inline float atan_f32(float y, float x)
{
float ax = std::abs(x), ay = std::abs(y);
@@ -59,6 +69,7 @@ static inline float atan_f32(float y, float x)
a = 360.f - a;
return a;
}
#endif
#if CV_SIMD
@@ -363,7 +374,7 @@ void sqrt64f(const double* src, double* dst, int len)
// Workaround for ICE in MSVS 2015 update 3 (issue #7795)
// CV_AVX is not used here, because generated code is faster in non-AVX mode.
// (tested with disabled IPP on i5-6300U)
#if (defined _MSC_VER && _MSC_VER >= 1900)
#if (defined _MSC_VER && _MSC_VER >= 1900) || defined(__EMSCRIPTEN__)
void exp32f(const float *src, float *dst, int n)
{
CV_INSTRUMENT_REGION();
+85 -107
View File
@@ -2310,18 +2310,12 @@ static void scaleAdd_32f(const float* src1, const float* src2, float* dst,
{
float alpha = *_alpha;
int i = 0;
#if CV_SIMD128
if (hasSIMD128())
{
v_float32x4 v_alpha = v_setall_f32(alpha);
const int cWidth = v_float32x4::nlanes;
for (; i <= len - cWidth; i += cWidth)
{
v_float32x4 v_src1 = v_load(src1 + i);
v_float32x4 v_src2 = v_load(src2 + i);
v_store(dst + i, (v_src1 * v_alpha) + v_src2);
}
}
#if CV_SIMD
v_float32 v_alpha = vx_setall_f32(alpha);
const int cWidth = v_float32::nlanes;
for (; i <= len - cWidth; i += cWidth)
v_store(dst + i, v_muladd(vx_load(src1 + i), v_alpha, vx_load(src2 + i)));
vx_cleanup();
#endif
for (; i < len; i++)
dst[i] = src1[i] * alpha + src2[i];
@@ -2333,22 +2327,12 @@ static void scaleAdd_64f(const double* src1, const double* src2, double* dst,
{
double alpha = *_alpha;
int i = 0;
#if CV_SIMD128_64F
if (hasSIMD128())
{
v_float64x2 a2 = v_setall_f64(alpha);
const int cWidth = v_float64x2::nlanes;
for (; i <= len - cWidth * 2; i += cWidth * 2)
{
v_float64x2 x0, x1, y0, y1, t0, t1;
x0 = v_load(src1 + i); x1 = v_load(src1 + i + cWidth);
y0 = v_load(src2 + i); y1 = v_load(src2 + i + cWidth);
t0 = x0 * a2 + y0;
t1 = x1 * a2 + y1;
v_store(dst + i, t0);
v_store(dst + i + cWidth, t1);
}
}
#if CV_SIMD_64F
v_float64 a2 = vx_setall_f64(alpha);
const int cWidth = v_float64::nlanes;
for (; i <= len - cWidth; i += cWidth)
v_store(dst + i, v_muladd(vx_load(src1 + i), a2, vx_load(src2 + i)));
vx_cleanup();
#endif
for (; i < len; i++)
dst[i] = src1[i] * alpha + src2[i];
@@ -2375,10 +2359,10 @@ static bool ocl_scaleAdd( InputArray _src1, double alpha, InputArray _src2, Outp
char cvt[2][50];
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D OP_SCALE_ADD -D BINARY_OP -D dstT=%s -D workT=%s -D convertToWT1=%s"
format("-D OP_SCALE_ADD -D BINARY_OP -D dstT=%s -D DEPTH_dst=%d -D workT=%s -D convertToWT1=%s"
" -D srcT1=dstT -D srcT2=dstT -D convertToDT=%s -D workT1=%s"
" -D wdepth=%d%s -D rowsPerWI=%d",
ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)),
ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)), depth,
ocl::typeToStr(CV_MAKE_TYPE(wdepth, kercn)),
ocl::convertTypeStr(depth, wdepth, kercn, cvt[0]),
ocl::convertTypeStr(wdepth, depth, kercn, cvt[1]),
@@ -3025,42 +3009,40 @@ static double dotProd_8u(const uchar* src1, const uchar* src2, int len)
#endif
int i = 0;
#if CV_SIMD128
if (hasSIMD128())
#if CV_SIMD
int len0 = len & -v_uint16::nlanes, blockSize0 = (1 << 15), blockSize;
while (i < len0)
{
int len0 = len & -8, blockSize0 = (1 << 15), blockSize;
blockSize = std::min(len0 - i, blockSize0);
v_int32 v_sum = vx_setzero_s32();
const int cWidth = v_uint16::nlanes;
while (i < len0)
int j = 0;
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
{
blockSize = std::min(len0 - i, blockSize0);
v_int32x4 v_sum = v_setzero_s32();
const int cWidth = v_uint16x8::nlanes;
v_uint16 v_src10, v_src20, v_src11, v_src21;
v_expand(vx_load(src1 + j), v_src10, v_src11);
v_expand(vx_load(src2 + j), v_src20, v_src21);
int j = 0;
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
{
v_uint16x8 v_src10, v_src20, v_src11, v_src21;
v_expand(v_load(src1 + j), v_src10, v_src11);
v_expand(v_load(src2 + j), v_src20, v_src21);
v_sum += v_dotprod(v_reinterpret_as_s16(v_src10), v_reinterpret_as_s16(v_src20));
v_sum += v_dotprod(v_reinterpret_as_s16(v_src11), v_reinterpret_as_s16(v_src21));
}
for (; j <= blockSize - cWidth; j += cWidth)
{
v_int16x8 v_src10 = v_reinterpret_as_s16(v_load_expand(src1 + j));
v_int16x8 v_src20 = v_reinterpret_as_s16(v_load_expand(src2 + j));
v_sum += v_dotprod(v_src10, v_src20);
}
r += (double)v_reduce_sum(v_sum);
src1 += blockSize;
src2 += blockSize;
i += blockSize;
v_sum += v_dotprod(v_reinterpret_as_s16(v_src10), v_reinterpret_as_s16(v_src20));
v_sum += v_dotprod(v_reinterpret_as_s16(v_src11), v_reinterpret_as_s16(v_src21));
}
for (; j <= blockSize - cWidth; j += cWidth)
{
v_int16 v_src10 = v_reinterpret_as_s16(vx_load_expand(src1 + j));
v_int16 v_src20 = v_reinterpret_as_s16(vx_load_expand(src2 + j));
v_sum += v_dotprod(v_src10, v_src20);
}
r += (double)v_reduce_sum(v_sum);
src1 += blockSize;
src2 += blockSize;
i += blockSize;
}
vx_cleanup();
#elif CV_NEON
if( cv::checkHardwareSupport(CV_CPU_NEON) )
{
@@ -3113,42 +3095,40 @@ static double dotProd_8s(const schar* src1, const schar* src2, int len)
double r = 0.0;
int i = 0;
#if CV_SIMD128
if (hasSIMD128())
#if CV_SIMD
int len0 = len & -v_int16::nlanes, blockSize0 = (1 << 14), blockSize;
while (i < len0)
{
int len0 = len & -8, blockSize0 = (1 << 14), blockSize;
blockSize = std::min(len0 - i, blockSize0);
v_int32 v_sum = vx_setzero_s32();
const int cWidth = v_int16::nlanes;
while (i < len0)
int j = 0;
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
{
blockSize = std::min(len0 - i, blockSize0);
v_int32x4 v_sum = v_setzero_s32();
const int cWidth = v_int16x8::nlanes;
v_int16 v_src10, v_src20, v_src11, v_src21;
v_expand(vx_load(src1 + j), v_src10, v_src11);
v_expand(vx_load(src2 + j), v_src20, v_src21);
int j = 0;
for (; j <= blockSize - cWidth * 2; j += cWidth * 2)
{
v_int16x8 v_src10, v_src20, v_src11, v_src21;
v_expand(v_load(src1 + j), v_src10, v_src11);
v_expand(v_load(src2 + j), v_src20, v_src21);
v_sum += v_dotprod(v_src10, v_src20);
v_sum += v_dotprod(v_src11, v_src21);
}
for (; j <= blockSize - cWidth; j += cWidth)
{
v_int16x8 v_src10 = v_load_expand(src1 + j);
v_int16x8 v_src20 = v_load_expand(src2 + j);
v_sum += v_dotprod(v_src10, v_src20);
}
r += (double)v_reduce_sum(v_sum);
src1 += blockSize;
src2 += blockSize;
i += blockSize;
v_sum += v_dotprod(v_src10, v_src20);
v_sum += v_dotprod(v_src11, v_src21);
}
for (; j <= blockSize - cWidth; j += cWidth)
{
v_int16 v_src10 = vx_load_expand(src1 + j);
v_int16 v_src20 = vx_load_expand(src2 + j);
v_sum += v_dotprod(v_src10, v_src20);
}
r += (double)v_reduce_sum(v_sum);
src1 += blockSize;
src2 += blockSize;
i += blockSize;
}
vx_cleanup();
#elif CV_NEON
if( cv::checkHardwareSupport(CV_CPU_NEON) )
{
@@ -3232,28 +3212,26 @@ static double dotProd_32f(const float* src1, const float* src2, int len)
#endif
int i = 0;
#if CV_SIMD128
if (hasSIMD128())
#if CV_SIMD
int len0 = len & -v_float32::nlanes, blockSize0 = (1 << 13), blockSize;
while (i < len0)
{
int len0 = len & -4, blockSize0 = (1 << 13), blockSize;
blockSize = std::min(len0 - i, blockSize0);
v_float32 v_sum = vx_setzero_f32();
while (i < len0)
{
blockSize = std::min(len0 - i, blockSize0);
v_float32x4 v_sum = v_setzero_f32();
int j = 0;
int cWidth = v_float32::nlanes;
for (; j <= blockSize - cWidth; j += cWidth)
v_sum = v_muladd(vx_load(src1 + j), vx_load(src2 + j), v_sum);
int j = 0;
int cWidth = v_float32x4::nlanes;
for (; j <= blockSize - cWidth; j += cWidth)
v_sum = v_muladd(v_load(src1 + j), v_load(src2 + j), v_sum);
r += v_reduce_sum(v_sum);
r += v_reduce_sum(v_sum);
src1 += blockSize;
src2 += blockSize;
i += blockSize;
}
src1 += blockSize;
src2 += blockSize;
i += blockSize;
}
vx_cleanup();
#endif
return r + dotProd_(src1, src2, len - i);
}
+9 -8
View File
@@ -7,7 +7,7 @@
namespace cv {
void MatAllocator::map(UMatData*, int) const
void MatAllocator::map(UMatData*, AccessFlag) const
{
}
@@ -127,7 +127,7 @@ class StdMatAllocator CV_FINAL : public MatAllocator
{
public:
UMatData* allocate(int dims, const int* sizes, int type,
void* data0, size_t* step, int /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
void* data0, size_t* step, AccessFlag /*flags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
{
size_t total = CV_ELEM_SIZE(type);
for( int i = dims-1; i >= 0; i-- )
@@ -154,7 +154,7 @@ public:
return u;
}
bool allocate(UMatData* u, int /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
bool allocate(UMatData* u, AccessFlag /*accessFlags*/, UMatUsageFlags /*usageFlags*/) const CV_OVERRIDE
{
if(!u) return false;
return true;
@@ -355,15 +355,16 @@ void Mat::create(int d, const int* _sizes, int _type)
#endif
if(!a)
a = a0;
CV_TRY
try
{
u = a->allocate(dims, size, _type, 0, step.p, 0, USAGE_DEFAULT);
u = a->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
CV_Assert(u != 0);
}
CV_CATCH_ALL
catch (...)
{
if(a != a0)
u = a0->allocate(dims, size, _type, 0, step.p, 0, USAGE_DEFAULT);
if (a == a0)
throw;
u = a0->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
CV_Assert(u != 0);
}
CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
+1 -1
View File
@@ -892,7 +892,7 @@ static bool ocl_reduce(InputArray _src, OutputArray _dst,
tileHeight = min(tileHeight, defDev.localMemSize() / buf_cols / CV_ELEM_SIZE(CV_MAKETYPE(wdepth, cn)) / maxItemInGroupCount);
}
char cvt[3][40];
cv::String build_opt = format("-D OP_REDUCE_PRE -D BUF_COLS=%d -D TILE_HEIGHT=%d -D %s -D dim=1"
cv::String build_opt = format("-D OP_REDUCE_PRE -D BUF_COLS=%d -D TILE_HEIGHT=%zu -D %s -D dim=1"
" -D cn=%d -D ddepth=%d"
" -D srcT=%s -D bufT=%s -D dstT=%s"
" -D convertToWT=%s -D convertToBufT=%s -D convertToDT=%s%s",
+45 -44
View File
@@ -14,8 +14,8 @@ namespace cv {
Mat _InputArray::getMat_(int i) const
{
int k = kind();
int accessFlags = flags & ACCESS_MASK;
_InputArray::KindFlag k = kind();
AccessFlag accessFlags = flags & ACCESS_MASK;
if( k == MAT )
{
@@ -132,8 +132,8 @@ Mat _InputArray::getMat_(int i) const
UMat _InputArray::getUMat(int i) const
{
int k = kind();
int accessFlags = flags & ACCESS_MASK;
_InputArray::KindFlag k = kind();
AccessFlag accessFlags = flags & ACCESS_MASK;
if( k == UMAT )
{
@@ -164,8 +164,8 @@ UMat _InputArray::getUMat(int i) const
void _InputArray::getMatVector(std::vector<Mat>& mv) const
{
int k = kind();
int accessFlags = flags & ACCESS_MASK;
_InputArray::KindFlag k = kind();
AccessFlag accessFlags = flags & ACCESS_MASK;
if( k == MAT )
{
@@ -272,8 +272,8 @@ void _InputArray::getMatVector(std::vector<Mat>& mv) const
void _InputArray::getUMatVector(std::vector<UMat>& umv) const
{
int k = kind();
int accessFlags = flags & ACCESS_MASK;
_InputArray::KindFlag k = kind();
AccessFlag accessFlags = flags & ACCESS_MASK;
if( k == NONE )
{
@@ -334,7 +334,7 @@ void _InputArray::getUMatVector(std::vector<UMat>& umv) const
cuda::GpuMat _InputArray::getGpuMat() const
{
int k = kind();
_InputArray::KindFlag k = kind();
if (k == CUDA_GPU_MAT)
{
@@ -360,7 +360,7 @@ cuda::GpuMat _InputArray::getGpuMat() const
}
void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if (k == STD_VECTOR_CUDA_GPU_MAT)
{
gpumv = *(std::vector<cuda::GpuMat>*)obj;
@@ -368,7 +368,7 @@ void _InputArray::getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const
}
ogl::Buffer _InputArray::getOGlBuffer() const
{
int k = kind();
_InputArray::KindFlag k = kind();
CV_Assert(k == OPENGL_BUFFER);
@@ -376,7 +376,7 @@ ogl::Buffer _InputArray::getOGlBuffer() const
return *gl_buf;
}
int _InputArray::kind() const
_InputArray::KindFlag _InputArray::kind() const
{
return flags & KIND_MASK;
}
@@ -393,7 +393,7 @@ int _InputArray::cols(int i) const
Size _InputArray::size(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
{
@@ -515,7 +515,8 @@ Size _InputArray::size(int i) const
int _InputArray::sizend(int* arrsz, int i) const
{
int j, d=0, k = kind();
int j, d = 0;
_InputArray::KindFlag k = kind();
if( k == NONE )
;
@@ -583,7 +584,7 @@ int _InputArray::sizend(int* arrsz, int i) const
bool _InputArray::sameSize(const _InputArray& arr) const
{
int k1 = kind(), k2 = arr.kind();
_InputArray::KindFlag k1 = kind(), k2 = arr.kind();
Size sz1;
if( k1 == MAT )
@@ -617,7 +618,7 @@ bool _InputArray::sameSize(const _InputArray& arr) const
int _InputArray::dims(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
{
@@ -714,7 +715,7 @@ int _InputArray::dims(int i) const
size_t _InputArray::total(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
{
@@ -763,7 +764,7 @@ size_t _InputArray::total(int i) const
int _InputArray::type(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
return ((const Mat*)obj)->type();
@@ -852,7 +853,7 @@ int _InputArray::channels(int i) const
bool _InputArray::empty() const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
return ((const Mat*)obj)->empty();
@@ -924,7 +925,7 @@ bool _InputArray::empty() const
bool _InputArray::isContinuous(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
return i < 0 ? ((const Mat*)obj)->isContinuous() : true;
@@ -965,7 +966,7 @@ bool _InputArray::isContinuous(int i) const
bool _InputArray::isSubmatrix(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
return i < 0 ? ((const Mat*)obj)->isSubmatrix() : false;
@@ -1003,7 +1004,7 @@ bool _InputArray::isSubmatrix(int i) const
size_t _InputArray::offset(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
{
@@ -1067,7 +1068,7 @@ size_t _InputArray::offset(int i) const
size_t _InputArray::step(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
{
@@ -1127,7 +1128,7 @@ size_t _InputArray::step(int i) const
void _InputArray::copyTo(const _OutputArray& arr) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == NONE )
arr.release();
@@ -1156,7 +1157,7 @@ void _InputArray::copyTo(const _OutputArray& arr) const
void _InputArray::copyTo(const _OutputArray& arr, const _InputArray & mask) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == NONE )
arr.release();
@@ -1185,9 +1186,9 @@ bool _OutputArray::fixedType() const
return (flags & FIXED_TYPE) == FIXED_TYPE;
}
void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{
CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == _sz);
@@ -1227,9 +1228,9 @@ void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int
create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
}
void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{
CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows));
@@ -1270,7 +1271,7 @@ void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTran
}
void _OutputArray::create(int d, const int* sizes, int mtype, int i,
bool allowTransposed, int fixedDepthMask) const
bool allowTransposed, _OutputArray::DepthMask fixedDepthMask) const
{
int sizebuf[2];
if(d == 1)
@@ -1280,7 +1281,7 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
sizebuf[1] = 1;
sizes = sizebuf;
}
int k = kind();
_InputArray::KindFlag k = kind();
mtype = CV_MAT_TYPE(mtype);
if( k == MAT )
@@ -1667,7 +1668,7 @@ void _OutputArray::release() const
{
CV_Assert(!fixedSize());
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
{
@@ -1735,7 +1736,7 @@ void _OutputArray::release() const
void _OutputArray::clear() const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == MAT )
{
@@ -1754,7 +1755,7 @@ bool _OutputArray::needed() const
Mat& _OutputArray::getMatRef(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( i < 0 )
{
CV_Assert( k == MAT );
@@ -1779,7 +1780,7 @@ Mat& _OutputArray::getMatRef(int i) const
UMat& _OutputArray::getUMatRef(int i) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( i < 0 )
{
CV_Assert( k == UMAT );
@@ -1796,34 +1797,34 @@ UMat& _OutputArray::getUMatRef(int i) const
cuda::GpuMat& _OutputArray::getGpuMatRef() const
{
int k = kind();
_InputArray::KindFlag k = kind();
CV_Assert( k == CUDA_GPU_MAT );
return *(cuda::GpuMat*)obj;
}
std::vector<cuda::GpuMat>& _OutputArray::getGpuMatVecRef() const
{
int k = kind();
_InputArray::KindFlag k = kind();
CV_Assert(k == STD_VECTOR_CUDA_GPU_MAT);
return *(std::vector<cuda::GpuMat>*)obj;
}
ogl::Buffer& _OutputArray::getOGlBufferRef() const
{
int k = kind();
_InputArray::KindFlag k = kind();
CV_Assert( k == OPENGL_BUFFER );
return *(ogl::Buffer*)obj;
}
cuda::HostMem& _OutputArray::getHostMemRef() const
{
int k = kind();
_InputArray::KindFlag k = kind();
CV_Assert( k == CUDA_HOST_MEM );
return *(cuda::HostMem*)obj;
}
void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if( k == NONE )
;
@@ -1847,7 +1848,7 @@ void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
void _OutputArray::assign(const UMat& u) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if (k == UMAT)
{
*(UMat*)obj = u;
@@ -1869,7 +1870,7 @@ void _OutputArray::assign(const UMat& u) const
void _OutputArray::assign(const Mat& m) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if (k == UMAT)
{
m.copyTo(*(UMat*)obj); // TODO check m.getUMat()
@@ -1891,7 +1892,7 @@ void _OutputArray::assign(const Mat& m) const
void _OutputArray::assign(const std::vector<UMat>& v) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if (k == STD_VECTOR_UMAT)
{
std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
@@ -1929,7 +1930,7 @@ void _OutputArray::assign(const std::vector<UMat>& v) const
void _OutputArray::assign(const std::vector<Mat>& v) const
{
int k = kind();
_InputArray::KindFlag k = kind();
if (k == STD_VECTOR_UMAT)
{
std::vector<UMat>& this_v = *(std::vector<UMat>*)obj;
+48 -22
View File
@@ -238,6 +238,20 @@ static const bool CV_OPENCL_DISABLE_BUFFER_RECT_OPERATIONS = utils::getConfigura
#endif
);
static const String getBuildExtraOptions()
{
static String param_buildExtraOptions;
static bool initialized = false;
if (!initialized)
{
param_buildExtraOptions = utils::getConfigurationParameterString("OPENCV_OPENCL_BUILD_EXTRA_OPTIONS", "");
initialized = true;
if (!param_buildExtraOptions.empty())
CV_LOG_WARNING(NULL, "OpenCL: using extra build options: '" << param_buildExtraOptions << "'");
}
return param_buildExtraOptions;
}
#endif // HAVE_OPENCL
struct UMat2D
@@ -2972,8 +2986,8 @@ int Kernel::set(int i, const KernelArg& arg)
cl_int status = 0;
if( arg.m )
{
int accessFlags = ((arg.flags & KernelArg::READ_ONLY) ? ACCESS_READ : 0) +
((arg.flags & KernelArg::WRITE_ONLY) ? ACCESS_WRITE : 0);
AccessFlag accessFlags = ((arg.flags & KernelArg::READ_ONLY) ? ACCESS_READ : static_cast<AccessFlag>(0)) |
((arg.flags & KernelArg::WRITE_ONLY) ? ACCESS_WRITE : static_cast<AccessFlag>(0));
bool ptronly = (arg.flags & KernelArg::PTR_ONLY) != 0;
cl_mem h = (cl_mem)arg.m->handle(accessFlags);
@@ -3050,7 +3064,7 @@ int Kernel::set(int i, const KernelArg& arg)
i += 3;
}
}
p->addUMat(*arg.m, (accessFlags & ACCESS_WRITE) != 0);
p->addUMat(*arg.m, !!(accessFlags & ACCESS_WRITE));
return i;
}
status = clSetKernelArg(p->handle, (cl_uint)i, arg.sz, arg.obj);
@@ -3073,7 +3087,7 @@ bool Kernel::run(int dims, size_t _globalsize[], size_t _localsize[],
dims == 1 ? 64 : dims == 2 ? (i == 0 ? 256 : 8) : dims == 3 ? (8>>(int)(i>0)) : 1;
CV_Assert( val > 0 );
total *= _globalsize[i];
if (_globalsize[i] == 1)
if (_globalsize[i] == 1 && !_localsize)
val = 1;
globalsize[i] = divUp(_globalsize[i], (unsigned int)val) * val;
}
@@ -3086,7 +3100,7 @@ bool Kernel::run(int dims, size_t _globalsize[], size_t _localsize[],
bool Kernel::Impl::run(int dims, size_t globalsize[], size_t localsize[],
bool sync, int64* timeNS, const Queue& q)
{
CV_INSTRUMENT_REGION_OPENCL_RUN(name.c_str(););
CV_INSTRUMENT_REGION_OPENCL_RUN(name.c_str());
if (!handle || isInProgress)
return false;
@@ -3104,9 +3118,9 @@ bool Kernel::Impl::run(int dims, size_t globalsize[], size_t localsize[],
if (retval != CL_SUCCESS)
#endif
{
cv::String msg = cv::format("clEnqueueNDRangeKernel('%s', dims=%d, globalsize=%dx%dx%d, localsize=%s) sync=%s", name.c_str(), (int)dims,
cv::String msg = cv::format("clEnqueueNDRangeKernel('%s', dims=%d, globalsize=%zux%zux%zu, localsize=%s) sync=%s", name.c_str(), (int)dims,
globalsize[0], (dims > 1 ? globalsize[1] : 1), (dims > 2 ? globalsize[2] : 1),
(localsize ? cv::format("%dx%dx%d", localsize[0], (dims > 1 ? localsize[1] : 1), (dims > 2 ? localsize[2] : 1)) : cv::String("NULL")).c_str(),
(localsize ? cv::format("%zux%zux%zu", localsize[0], (dims > 1 ? localsize[1] : 1), (dims > 2 ? localsize[2] : 1)) : cv::String("NULL")).c_str(),
sync ? "true" : "false"
);
if (retval != CL_SUCCESS)
@@ -3317,7 +3331,7 @@ struct ProgramSource::Impl
default:
CV_Error(Error::StsInternal, "Internal error");
}
sourceHash_ = cv::format("%08llx", hash);
sourceHash_ = cv::format("%08jx", (uintmax_t)hash);
isHashUpdated = true;
}
@@ -3517,6 +3531,9 @@ struct Program::Impl
buildflags = joinBuildOptions(buildflags, " -D AMD_DEVICE");
else if (device.isIntel())
buildflags = joinBuildOptions(buildflags, " -D INTEL_DEVICE");
const String param_buildExtraOptions = getBuildExtraOptions();
if (!param_buildExtraOptions.empty())
buildflags = joinBuildOptions(buildflags, param_buildExtraOptions);
}
compile(ctx, src_, errmsg);
}
@@ -4516,13 +4533,13 @@ public:
}
UMatData* defaultAllocate(int dims, const int* sizes, int type, void* data, size_t* step,
int flags, UMatUsageFlags usageFlags) const
AccessFlag flags, UMatUsageFlags usageFlags) const
{
UMatData* u = matStdAllocator->allocate(dims, sizes, type, data, step, flags, usageFlags);
return u;
}
void getBestFlags(const Context& ctx, int /*flags*/, UMatUsageFlags usageFlags, int& createFlags, int& flags0) const
void getBestFlags(const Context& ctx, AccessFlag /*flags*/, UMatUsageFlags usageFlags, int& createFlags, UMatData::MemoryFlag& flags0) const
{
const Device& dev = ctx.device(0);
createFlags = 0;
@@ -4530,13 +4547,13 @@ public:
createFlags |= CL_MEM_ALLOC_HOST_PTR;
if( dev.hostUnifiedMemory() )
flags0 = 0;
flags0 = static_cast<UMatData::MemoryFlag>(0);
else
flags0 = UMatData::COPY_ON_MAP;
}
UMatData* allocate(int dims, const int* sizes, int type,
void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const CV_OVERRIDE
void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const CV_OVERRIDE
{
if(!useOpenCL())
return defaultAllocate(dims, sizes, type, data, step, flags, usageFlags);
@@ -4552,7 +4569,8 @@ public:
Context& ctx = Context::getDefault();
flushCleanupQueue();
int createFlags = 0, flags0 = 0;
int createFlags = 0;
UMatData::MemoryFlag flags0 = static_cast<UMatData::MemoryFlag>(0);
getBestFlags(ctx, flags, usageFlags, createFlags, flags0);
void* handle = NULL;
@@ -4600,7 +4618,7 @@ public:
return u;
}
bool allocate(UMatData* u, int accessFlags, UMatUsageFlags usageFlags) const CV_OVERRIDE
bool allocate(UMatData* u, AccessFlag accessFlags, UMatUsageFlags usageFlags) const CV_OVERRIDE
{
if(!u)
return false;
@@ -4613,12 +4631,13 @@ public:
{
CV_Assert(u->origdata != 0);
Context& ctx = Context::getDefault();
int createFlags = 0, flags0 = 0;
int createFlags = 0;
UMatData::MemoryFlag flags0 = static_cast<UMatData::MemoryFlag>(0);
getBestFlags(ctx, accessFlags, usageFlags, createFlags, flags0);
cl_context ctx_handle = (cl_context)ctx.ptr();
int allocatorFlags = 0;
int tempUMatFlags = 0;
UMatData::MemoryFlag tempUMatFlags = static_cast<UMatData::MemoryFlag>(0);
void* handle = NULL;
cl_int retval = CL_SUCCESS;
@@ -4703,7 +4722,7 @@ public:
u->flags |= tempUMatFlags;
u->allocatorFlags_ = allocatorFlags;
}
if(accessFlags & ACCESS_WRITE)
if (!!(accessFlags & ACCESS_WRITE))
u->markHostCopyObsolete(true);
return true;
}
@@ -4749,7 +4768,7 @@ public:
CV_Assert(u->handle != 0);
CV_Assert(u->mapcount == 0);
if (u->flags & UMatData::ASYNC_CLEANUP)
if (!!(u->flags & UMatData::ASYNC_CLEANUP))
addToCleanupQueue(u);
else
deallocate_(u);
@@ -4757,6 +4776,10 @@ public:
void deallocate_(UMatData* u) const
{
#ifdef _WIN32
if (cv::__termination) // process is not in consistent state (after ExitProcess call) and terminating
return; // avoid any OpenCL calls
#endif
if(u->tempUMat())
{
CV_Assert(u->origdata);
@@ -4924,11 +4947,11 @@ public:
}
// synchronized call (external UMatDataAutoLock, see UMat::getMat)
void map(UMatData* u, int accessFlags) const CV_OVERRIDE
void map(UMatData* u, AccessFlag accessFlags) const CV_OVERRIDE
{
CV_Assert(u && u->handle);
if(accessFlags & ACCESS_WRITE)
if (!!(accessFlags & ACCESS_WRITE))
u->markDeviceCopyObsolete(true);
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
@@ -4995,7 +5018,7 @@ public:
}
}
if( (accessFlags & ACCESS_READ) != 0 && u->hostCopyObsolete() )
if (!!(accessFlags & ACCESS_READ) && u->hostCopyObsolete())
{
AlignedDataPtr<false, true> alignedPtr(u->data, u->size, CV_OPENCL_DATA_PTR_ALIGNMENT);
#ifdef HAVE_OPENCL_SVM
@@ -5735,7 +5758,7 @@ void convertFromBuffer(void* cl_mem_buffer, size_t step, int rows, int cols, int
dst.u = new UMatData(getOpenCLAllocator());
dst.u->data = 0;
dst.u->allocatorFlags_ = 0; // not allocated from any OpenCV buffer pool
dst.u->flags = 0;
dst.u->flags = static_cast<UMatData::MemoryFlag>(0);
dst.u->handle = cl_mem_buffer;
dst.u->origdata = 0;
dst.u->prevAllocator = 0;
@@ -5982,6 +6005,7 @@ const char* typeToStr(int type)
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"
};
int cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type);
CV_Assert(depth != CV_16F); // Workaround for: https://github.com/opencv/opencv/issues/12824
return cn > 16 ? "?" : tab[depth*16 + cn-1];
}
@@ -5999,6 +6023,7 @@ const char* memopTypeToStr(int type)
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"
};
int cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type);
CV_Assert(depth != CV_16F); // Workaround for: https://github.com/opencv/opencv/issues/12824
return cn > 16 ? "?" : tab[depth*16 + cn-1];
}
@@ -6016,6 +6041,7 @@ const char* vecopTypeToStr(int type)
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?"
};
int cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type);
CV_Assert(depth != CV_16F); // Workaround for: https://github.com/opencv/opencv/issues/12824
return cn > 16 ? "?" : tab[depth*16 + cn-1];
}
+50 -3
View File
@@ -71,7 +71,30 @@
#pragma OPENCL FP_FAST_FMA ON
#endif
#if depth <= 5
#if !defined(DEPTH_dst)
#error "Kernel configuration error: DEPTH_dst value is required"
#elif !(DEPTH_dst >= 0 && DEPTH_dst <= 7)
#error "Kernel configuration error: invalid DEPTH_dst value"
#endif
#if defined(depth)
#error "Kernel configuration error: ambiguous 'depth' value is defined, use 'DEPTH_dst' instead"
#endif
#if DEPTH_dst < 5 /* CV_32F */
#define CV_DST_TYPE_IS_INTEGER
#else
#define CV_DST_TYPE_IS_FP
#endif
#if DEPTH_dst != 6 /* CV_64F */
#define CV_DST_TYPE_FIT_32F 1
#else
#define CV_DST_TYPE_FIT_32F 0
#endif
#if CV_DST_TYPE_FIT_32F
#define CV_PI M_PI_F
#else
#define CV_PI M_PI
@@ -204,9 +227,15 @@
#define PROCESS_ELEM storedst(convertToDT(srcelem1 * scale * srcelem2))
#elif defined OP_DIV
#ifdef CV_DST_TYPE_IS_INTEGER
#define PROCESS_ELEM \
workT e2 = srcelem2, zero = (workT)(0); \
storedst(convertToDT(e2 != zero ? srcelem1 / e2 : zero))
#else
#define PROCESS_ELEM \
workT e2 = srcelem2; \
storedst(convertToDT(srcelem1 / e2))
#endif
#elif defined OP_DIV_SCALE
#undef EXTRA_PARAMS
@@ -217,9 +246,15 @@
#else
#define EXTRA_PARAMS , scaleT scale
#endif
#ifdef CV_DST_TYPE_IS_INTEGER
#define PROCESS_ELEM \
workT e2 = srcelem2, zero = (workT)(0); \
storedst(convertToDT(e2 == zero ? zero : (srcelem1 * (workT)(scale) / e2)))
#else
#define PROCESS_ELEM \
workT e2 = srcelem2; \
storedst(convertToDT(srcelem1 * (workT)(scale) / e2))
#endif
#elif defined OP_RDIV_SCALE
#undef EXTRA_PARAMS
@@ -230,16 +265,28 @@
#else
#define EXTRA_PARAMS , scaleT scale
#endif
#ifdef CV_DST_TYPE_IS_INTEGER
#define PROCESS_ELEM \
workT e1 = srcelem1, zero = (workT)(0); \
storedst(convertToDT(e1 == zero ? zero : (srcelem2 * (workT)(scale) / e1)))
#else
#define PROCESS_ELEM \
workT e1 = srcelem1; \
storedst(convertToDT(srcelem2 * (workT)(scale) / e1))
#endif
#elif defined OP_RECIP_SCALE
#undef EXTRA_PARAMS
#define EXTRA_PARAMS , scaleT scale
#ifdef CV_DST_TYPE_IS_INTEGER
#define PROCESS_ELEM \
workT e1 = srcelem1, zero = (workT)(0); \
storedst(convertToDT(e1 != zero ? scale / e1 : zero))
#else
#define PROCESS_ELEM \
workT e1 = srcelem1; \
storedst(convertToDT(scale / e1))
#endif
#elif defined OP_ADDW
#undef EXTRA_PARAMS
@@ -283,7 +330,7 @@
#define PROCESS_ELEM storedst(pown(srcelem1, srcelem2))
#elif defined OP_SQRT
#if depth <= 5
#if CV_DST_TYPE_FIT_32F
#define PROCESS_ELEM storedst(native_sqrt(srcelem1))
#else
#define PROCESS_ELEM storedst(sqrt(srcelem1))
@@ -324,7 +371,7 @@
#endif
#elif defined OP_CTP_AD || defined OP_CTP_AR
#if depth <= 5
#if CV_DST_TYPE_FIT_32F
#define CV_EPSILON FLT_EPSILON
#else
#define CV_EPSILON DBL_EPSILON
+11 -11
View File
@@ -1434,14 +1434,14 @@ void cv::ogl::render(const ogl::Texture2D& tex, Rect_<double> wndRect, Rect_<dou
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR);
CV_CheckGlError();
const float vertex[] =
const double vertex[] =
{
wndRect.x, wndRect.y, 0.0f,
wndRect.x, (wndRect.y + wndRect.height), 0.0f,
wndRect.x + wndRect.width, (wndRect.y + wndRect.height), 0.0f,
wndRect.x + wndRect.width, wndRect.y, 0.0f
wndRect.x, wndRect.y, 0.0,
wndRect.x, (wndRect.y + wndRect.height), 0.0,
wndRect.x + wndRect.width, (wndRect.y + wndRect.height), 0.0,
wndRect.x + wndRect.width, wndRect.y, 0.0
};
const float texCoords[] =
const double texCoords[] =
{
texRect.x, texRect.y,
texRect.x, texRect.y + texRect.height,
@@ -1454,7 +1454,7 @@ void cv::ogl::render(const ogl::Texture2D& tex, Rect_<double> wndRect, Rect_<dou
gl::EnableClientState(gl::TEXTURE_COORD_ARRAY);
CV_CheckGlError();
gl::TexCoordPointer(2, gl::FLOAT, 0, texCoords);
gl::TexCoordPointer(2, gl::DOUBLE, 0, texCoords);
CV_CheckGlError();
gl::DisableClientState(gl::NORMAL_ARRAY);
@@ -1464,7 +1464,7 @@ void cv::ogl::render(const ogl::Texture2D& tex, Rect_<double> wndRect, Rect_<dou
gl::EnableClientState(gl::VERTEX_ARRAY);
CV_CheckGlError();
gl::VertexPointer(3, gl::FLOAT, 0, vertex);
gl::VertexPointer(3, gl::DOUBLE, 0, vertex);
CV_CheckGlError();
gl::DrawArrays(gl::QUADS, 0, 4);
@@ -1804,8 +1804,8 @@ void convertFromGLTexture2D(const Texture2D& texture, OutputArray dst)
#endif
}
//void mapGLBuffer(const Buffer& buffer, UMat& dst, int accessFlags)
UMat mapGLBuffer(const Buffer& buffer, int accessFlags)
//void mapGLBuffer(const Buffer& buffer, UMat& dst, AccessFlag accessFlags)
UMat mapGLBuffer(const Buffer& buffer, AccessFlag accessFlags)
{
CV_UNUSED(buffer); CV_UNUSED(accessFlags);
#if !defined(HAVE_OPENGL)
@@ -1824,7 +1824,7 @@ UMat mapGLBuffer(const Buffer& buffer, int accessFlags)
switch (accessFlags & (ACCESS_READ|ACCESS_WRITE))
{
default:
case ACCESS_READ|ACCESS_WRITE:
case ACCESS_READ+ACCESS_WRITE:
clAccessFlags = CL_MEM_READ_WRITE;
break;
case ACCESS_READ:

Some files were not shown because too many files have changed in this diff Show More