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

Compare commits

...

153 Commits

Author SHA1 Message Date
Alexander Alekhin 371bba8f54 release: OpenCV 4.1.0
OpenCV 4.1.0
2019-04-07 17:09:10 +00:00
Alexander Alekhin 2eaf35eb63 Merge tag '4.1.0-openvino' 2019-04-07 17:07:27 +00:00
Alexander Alekhin 0b9d53829f Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-04-07 12:35:15 +00:00
Alexander Alekhin dad2247b56 Merge tag '3.4.6' 2019-04-07 11:02:40 +00:00
Alexander Alekhin 33b765d797 OpenCV version++ (3.4.6)
OpenCV 3.4.6
2019-04-06 21:43:23 +00:00
Alexander Alekhin 4368f04afa Merge pull request #14271 from alalek:issue_14259 2019-04-06 21:37:10 +00:00
Alexander Alekhin b5961cc5d1 calib3d: don't change input data
- estimateAffine2D/estimateAffinePartial2D() calls
2019-04-06 19:28:41 +00:00
Alexander Alekhin c9fc27b337 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-04-05 19:08:23 +00:00
Maksim Shabunin aa1359dc19 Merge pull request #14267 from mshabunin:fix-osx-camera-auth
* Added authorization request to AVFoundation camera backend (OSX 10.14+)
2019-04-05 21:58:01 +03:00
Alexander Alekhin 28925572f6 Merge pull request #14268 from alalek:fix_ossfuzz_13283 2019-04-05 18:56:19 +00:00
Alexander Alekhin 0c490accae imgcodecs(tiff): check TIFF tile size
oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13280
oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13283
2019-04-05 18:13:15 +03:00
Dmitry Kurtaev 4c2100e02c Merge pull request #14266 from dkurt:fix_qrcode_decode_java
* Fix decode and detectAndDecode Java wrappers for QRCodeDetector

* revert changes in objdetect

* java: fix wrapping of std::string type
2019-04-05 17:15:51 +03:00
Alexander Alekhin 1b5a9c9718 Merge pull request #14256 from alalek:fix_docs_links_3.4 2019-04-05 12:45:50 +00:00
Alexander Alekhin bd43e4f28b Merge pull request #14251 from dkurt:dnn_tf_manage_switch 2019-04-05 12:43:22 +00:00
Dmitry Kurtaev ec41a4897a Remove Switch and Merge nodes from TensorFlow networks 2019-04-05 12:32:35 +03:00
Alexander Alekhin 473941c341 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-04-04 18:09:24 +00:00
Alexander Alekhin 1fb93b62c0 Merge pull request #14249 from alalek:imgcodecs_tiff_update_3.4 2019-04-04 16:17:09 +00:00
Alexander Alekhin d38869eb76 docs: fix links
- replace tutorial links via docs.opencv.org
- remove link on OpenCV 2.4
- avoid links on outdated packages
2019-04-04 18:57:22 +03:00
mehlukas ab21dc6d47 Merge pull request #14245 from mehlukas:3.4-fixtutorial
* improve thresholding tutorial, fix grammar issues and incorrections

* keep full list of simple thresholding types
2019-04-04 17:44:03 +03:00
BALACHANDAR S aa167434e6 Merge pull request #14252 from balachandarsv:master-mac-openvino-support
* Mac support for op inference engine

Adding condition to check for mac and add corresponding libraries

* Adding mac support in test cases
2019-04-04 17:37:45 +03:00
Alexander Alekhin ba5ddd6499 imgcodecs(tiff): sanitize tiff decoder
- more checks
- drop separate branches for 32FC1/32FC3(read) handling
- added for 32F/64F non-compressed
- added tests for 32FC3 (RAW + hdr SGILOG compression)
- added test 64FC1
- dump tiff errors on stderr
2019-04-04 14:16:53 +03:00
Alexander Alekhin 4001346a30 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-04-03 19:33:52 +00:00
Alexander Alekhin d8b8c3b145 Merge pull request #14233 from alalek:cmake_fix_license_install 2019-04-03 19:30:47 +00:00
Alexander Alekhin ba6c2df15d Merge pull request #14229 from alalek:ffmpeg_downloader_elevated_run 2019-04-03 19:29:28 +00:00
Alexander Alekhin c300070b8a Merge pull request #14241 from alalek:openvino_2019R1 2019-04-03 19:26:46 +00:00
103yiran 4bb6edf176 Merge pull request #14117 from 103yiran:103yiran-patch-dnn
* Postpone variable definitions

* dnn: reduce scope of 'Mat image' variable
2019-04-03 22:13:11 +03:00
Alexander Alekhin cafa010389 dnn(test): skip tests 2019-04-03 17:49:05 +03:00
Alexander Alekhin ee7255aac4 Merge pull request #14144 from alalek:issue_14143 2019-04-03 14:35:54 +00:00
Alexander Alekhin 8bc8a94645 dnn: update DNNTestOpenVINO.models tests
- models are moved out from OpenVINO package
- need to download them separatelly
2019-04-03 15:39:47 +03:00
Alexander Alekhin 8483801eab dnn: use OpenVINO 2019R1 defines 2019-04-03 15:39:47 +03:00
Alexander Alekhin 5dc606097c Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-04-02 20:54:41 +00:00
Alexander Alekhin d4a96b699e Merge pull request #14234 from alalek:backport_14203 2019-04-02 16:34:41 +00:00
Alexander Alekhin 14843679af Merge pull request #14217 from alalek:fix_world_gapi_tests 2019-04-02 16:27:12 +00:00
Alexander Alekhin 4fa4bef41d cmake: fix licenses install rules 2019-04-02 19:24:14 +03:00
Alexander Alekhin 785a540ebd Merge pull request #14175 from paroj:copyto 2019-04-02 16:18:00 +00:00
Alexander Alekhin c4ec46c195 imgcodecs(sunras): avoid undefined shift
backporting of commit: f2803aba07
2019-04-02 18:38:01 +03:00
Alexander Alekhin d2854448c2 Merge pull request #14203 from alalek:fix_ossfuzz_13292 2019-04-02 15:15:13 +00:00
Alexander Alekhin 69ff7a76d6 Merge pull request #14228 from dkurt:conv_1x1 2019-04-02 14:35:50 +00:00
Alexander Alekhin 3ca6a72457 Merge pull request #14222 from alalek:cmake_remove_test_include_dirs 2019-04-02 14:34:36 +00:00
Alexander Alekhin 7d2118e324 Merge pull request #14223 from alalek:backport_14201 2019-04-02 14:33:57 +00:00
Alexander Alekhin 97548b01c7 FFmpeg: try to download wrapper with elevated privileges 2019-04-02 16:40:11 +03:00
Dmitry Kurtaev e3286c9055 Enable 1x1 convolution optimization 2019-04-02 14:05:17 +03:00
Alexander Alekhin cd6d8048bb gapi: fix tests build 2019-04-02 13:46:25 +03:00
Alexander Alekhin 3d7a3a51a7 cmake: don't add tests dirs as include directories
- use relative paths for includes
- fix PCH generation with GCC (dummy file has been used)
2019-04-02 13:46:25 +03:00
Alexander Alekhin df1f62b34c Merge pull request #14225 from zuoshaobo:my3.4 2019-04-02 09:57:26 +00:00
Alexander Alekhin 2f288f94e5 Merge pull request #14227 from dkurt:fix_build_with_ie 2019-04-02 09:38:05 +00:00
Alexander Alekhin 2a2d195240 cmake: don't add tests dirs as include directories
- use relative paths for includes
- fix PCH generation with GCC (dummy file has been used)
2019-04-02 12:28:25 +03:00
Dmitry Kurtaev 07655c2b4d Fix build with IE > 2018R5 2019-04-02 11:54:50 +03:00
zuoshaobo a34c02a001 add support for tf.add_n operation 2019-04-02 03:20:53 -04:00
Alexander Alekhin b4e2c99346 Merge pull request #14201 from alalek:fix_ossfuzz_13295 2019-04-01 18:47:00 +00:00
Alexander Alekhin 33dde339fe Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-04-01 18:11:55 +03:00
Alexander Alekhin 341e2fa72d Merge pull request #14214 from alalek:backport_14202 2019-04-01 14:39:25 +00:00
Alexander Alekhin 21f0146402 Merge pull request #14212 from dkurt:reduce_ie_models_tests 2019-04-01 14:38:07 +00:00
Alexander Alekhin 45169577ca Merge pull request #14207 from alalek:fix_leak_eigenvalue_decomposition 2019-04-01 14:17:37 +00:00
Alexander Alekhin 2ece029fe0 imgcodecs(tiff): avoid leak of helper struct on malformed inputs
backporting of commit: 45428b897f
2019-04-01 14:08:40 +00:00
Alexander Alekhin 06193f28ef Merge pull request #14194 from alalek:backport_14193 2019-04-01 14:03:13 +00:00
Dmitry Kurtaev 144b1f4d9d Reduce number of tested models from OpenVINO 2019-04-01 15:15:00 +03:00
Alexander Alekhin bda90dae77 Merge pull request #14200 from alalek:fix_imgcodecs_stream_set_pos 2019-04-01 11:04:20 +00:00
Alexander Alekhin 1e583942b9 core(lda): don't perform calculations in constructor
- exceptions from constructor will not cause destructor calls
2019-03-31 21:48:44 +00:00
Alexander Alekhin 066c074b66 Merge pull request #14206 from alalek:issue_14205 2019-03-31 20:58:17 +00:00
Alexander Alekhin 142a524d2f cmake: fix CUDA world build 2019-03-31 19:56:30 +00:00
Alexander Alekhin 7142f46d1c Merge pull request #14202 from alalek:fix_ossfuzz_13285 2019-03-31 14:39:20 +00:00
Alexander Alekhin 6894651027 Merge pull request #14198 from alalek:issue_14195 2019-03-31 12:56:57 +00:00
Alexander Alekhin 6dfb6a3016 imgcodecs: fix RBaseStream::setPos() outside of current block
Seeking outside of the current block doesn't update actual data,
so getByte()/etc will get wrong data from stalled buffer.
2019-03-31 12:55:32 +00:00
Alexander Alekhin f2803aba07 imgcodecs(sunras): avoid undefined shift
oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13292
2019-03-31 12:14:42 +00:00
Alexander Alekhin 45428b897f imgcodecs(tiff): avoid leak of helper struct on malformed inputs
oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13285
2019-03-31 11:50:33 +00:00
Alexander Alekhin 4b91dfd215 Merge pull request #14199 from devnexen:openbsd_build_fix 2019-03-31 11:14:42 +00:00
Alexander Alekhin ccb89a889a imgcodecs(bmp): limit size of processed images
2Gb+ images can't be handled properly by current implementation

backporting of commit: 50a6f9d251
2019-03-31 10:52:33 +00:00
Alexander Alekhin 50a6f9d251 imgcodecs(bmp): limit size of processed images
2Gb+ images can't be handled properly by current implementation

ozz-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13295
2019-03-31 10:48:07 +00:00
David Carlier 06a4c20f60 OpenBSD build fix
required for close calls.
2019-03-31 10:54:47 +01:00
Alexander Alekhin fcb07c64f3 cmake: fix build of dnn tests with shared common code
- don't share .cpp files (PCH support is broken)
2019-03-31 08:52:25 +00:00
Alexander Alekhin 6316b3ed91 Merge pull request #14196 from seiko2plus:issue14195 2019-03-31 08:18:55 +00:00
Sayed Adel de22442046 dnn:perf add missing definition __OPENCV_TEST to fix pch 2019-03-31 03:28:33 +02:00
Alexander Alekhin 10ce935823 3rdparty(zlib): prevent uninitialized use of state->check
backporting of commit: 8afb2f0cb7
2019-03-30 20:26:49 +00:00
Alexander Alekhin 360758e8ae Merge pull request #14193 from alalek:fix_ossfuzz_13317 2019-03-30 20:26:15 +00:00
Alexander Alekhin 8afb2f0cb7 3rdparty(zlib): prevent uninitialized use of state->check
ozz-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13317
PR: https://github.com/opencv/opencv/pull/14193
zlib upstream bug: madler/zlib#245
Ported fix: https://chromium.googlesource.com/chromium/src/+/ee376c65abdd5afe787bfb63af9f2e82fdc35c2e
2019-03-30 18:46:10 +00:00
Alexander Alekhin 7442100caa Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-03-29 19:29:36 +00:00
Maksim Shabunin 52cd1dacbf Merge pull request #14156 from mshabunin:videowriter-bad-test
* videoio: added bad parameters handling to VideoWriter

* AVFoundation/Writer: support UTF-8, check input parameters
2019-03-29 17:52:22 +03:00
Lubov Batanina 7d3d6bc4e2 Merge pull request #13932 from l-bat:MyriadX_master_dldt
* Fix precision in tests for MyriadX

* Fix ONNX tests

* Add output range in ONNX tests

* Skip tests on Myriad OpenVINO 2018R5

* Add detect MyriadX

* Add detect MyriadX on OpenVINO R5

* Skip tests on Myriad next version of OpenVINO

* dnn(ie): VPU type from environment variable

* dnn(test): validate VPU type

* dnn(test): update DLIE test skip conditions
2019-03-29 16:42:58 +03:00
Pavel Rojtberg 62775660d1 core: python - test cv::copyTo with pre-allocated dst 2019-03-29 13:56:26 +01:00
George Wilson 982e6fc721 Merge pull request #14154 from GeorgeWilson96:bugfix/14148
* Fixed #14148 Broken Documentation Link

* fixup: use 3.4 branch
2019-03-28 22:31:38 +03:00
Alexander Alekhin f75152a597 gapi: fix build with Intel Compiler 2019 2019-03-28 19:24:43 +00:00
Alexander Alekhin b761ec0132 Merge pull request #14177 from alalek:fix_14173 2019-03-28 14:57:07 +00:00
Alexander Alekhin 3cd6e3b304 Merge pull request #14166 from dkurt:fix_slim_mobilenet_v2 2019-03-28 14:37:35 +00:00
Alexander Alekhin 1fb8dcb0de Merge pull request #14170 from alalek:cmake_hide_helper_modules 2019-03-28 14:25:27 +00:00
Alexander Alekhin 428ff431df Merge pull request #14168 from alalek:dnn_fix_drop_IE_2018R2 2019-03-28 14:23:39 +00:00
Alexander Alekhin c7c987843c cmake: emit error if CUDA is enabled without opencv_contrib 2019-03-28 16:51:11 +03:00
Alexander Alekhin 73191ad3ec Merge pull request #14172 from smirnov-alexey:gapi_fix_nv12_valgrind 2019-03-28 13:45:45 +00:00
smirnov-alexey 769d2f4c44 Fix valgrind issue in NV12 test 2019-03-28 12:59:51 +03:00
Alexander Alekhin 8ce7d9a4d1 cmake: hide helper modules
- bindings generators
- keep "ts" module
2019-03-27 21:43:25 +00:00
Alexander Alekhin e8c20bfae6 dnn: fix support drop for IE<2018R3
- fix build with IE 2018R3
2019-03-27 20:36:48 +00:00
Alexander Alekhin d6b82dcd65 Merge pull request #14162 from alalek:eliminate_coverity_scan_issues
core: eliminate coverity scan issues (#14162)

* core(hal): avoid using of r,g,b,a parameters in interleave/deinterleave

- static analysis tools blame on possible parameters reordering
- align AVX parameters with corresponding SSE/NEO/VSX/cpp code

* core: avoid "i,j" parameters in Matx methods

- static analysis tools blame on possible parameters reordering

* core: resolve coverity scan issues
2019-03-27 15:48:00 +03:00
Alexander Alekhin 5368a4ac41 Merge pull request #14102 from alalek:core_refactor_eigenvalues 2019-03-27 12:46:51 +00:00
Dmitry Kurtaev 9cfd219d70 Fix Mobilenet v2 from TensorFlow slim 2019-03-27 15:10:57 +03:00
Alexander Alekhin 90df5e00b4 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-03-26 18:56:54 +00:00
Alexander Alekhin 9340fc0c50 Merge pull request #14146 from alalek:cmake_cmp0068 2019-03-26 17:16:59 +00:00
Alexander Alekhin f738e490a3 Merge pull request #13989 from kohei-us:onnx-conv-transpose-output-shape 2019-03-26 17:04:52 +00:00
Alexander Alekhin 55366caecd Merge pull request #14155 from alalek:fix_macos_ocl_warnings_3.4 2019-03-26 15:34:49 +00:00
Kohei Yoshida 212420516f Add a test case for handling output_shape property for deconvolution layer. 2019-03-26 10:46:17 -04:00
Kohei Yoshida 3bcff7f941 Make use of explicit output shape for the de-convolution layer.
This is relevant to cases where the net is loaded from an ONNX model
containing ConvTranspose layers, which may include the output_shape
attribute.

c.f. https://github.com/onnx/onnx/blob/master/docs/Operators.md#ConvTranspose
2019-03-26 10:46:09 -04:00
Alexander Alekhin 6686559c70 ocl: define CL_SILENCE_DEPRECATION on MacOSX 2019-03-26 13:11:53 +03:00
Alexander Alekhin cedd78d526 Merge pull request #14142 from mshabunin:fix-c-api-3.4 2019-03-25 18:58:28 +00:00
Alexander Alekhin c443a3d657 cmake: set CMP0068 => NEW 2019-03-25 19:25:51 +03:00
Alexander Alekhin 5f88bbe3d5 Merge pull request #14141 from dkurt:dnn_ie_relax_lrn 2019-03-25 13:45:26 +00:00
Maksim Shabunin 41da3ef1d2 Fixed cvdef.h for MSVC C users 2019-03-25 16:44:08 +03:00
Dmitry Kurtaev 714b38360f Extend LRN layer support with IE backend 2019-03-25 12:53:34 +03:00
iPanda 097fc1a271 Merge pull request #13972 from Mainvooid:add_cuda_support_for_D3D11_interop
* Add CUDA support for D3D11 interop. #13888

color_detail.hpp: fixed build error : dynamic initialization is not supported for a __constant__ variable.
directx.cpp: Add CUDA support(cl_nv_d3d11_sharing) for D3D11 interop.  #13888

Update directx.cpp

Format adjustment.

Update directx.cpp

fix error.

Update directx.cpp

Format adjustment

Update directx.cpp

fix trailing whitespace.

fix format errors

convert indentation to spaces .
Trim trailing whitespace.
Add information about source of cl_d3d11_ext.h
Avoid unrelated changes.

Increase compile-time conditional judgment.

Increase the judgment of whether the OCL device has the required extensions at compile time.

Add compilation option  `HAVE_CLNVEXT`.Check CL support in runtime.

Check result of `clGetExtensionFunctionAddressForPlatform` for KHR is invalid.It always can get the address(from OpenCL.dll),So I check NV support(from nvopencl64.dll) before KHR when `HAVE_CLNVEXT` is enabled.

Delete cl_d3d11_ext.h

Modified parameter list

fix "cannot open include file: 'CL/cl_d3d11_ext.h'"

 remove not referenced var

fix C2143: syntax error

Improve compile-time judgment.

dlrectx.cpp Modify the detection order.
initializeContextFromD3D11Device:
```
    // try with NV(Need to check it first)
    // try with KHR
```

fix warnig C4100

Revert "fix warnig C4100"

This reverts commit 76e5becb67780071d0cbde61cc4f5f807ad7c5ac.

fix warning C4100

fix warning C4505

Format alignment

Format adjustment and automatically detect header files.

Automatically detect header files when users are not configured or configuration errors occur.

avoid unrelated changes.

Update .cmake

Update .cmake

* fix build errors

* fix warning:defined but not used

* Revert "fix warning:defined but not used"

This reverts commit 7ab3537cd0.

* fix warning:defined but not used

* fix build error for mac

* fix build error for win

* optimizing branch judgment

* Revert "optimizing branch judgment"

This reverts commit 88b72b870e.

* fix warning C4702: unreachable code

* remove unused code

* Fix problems that may lead to undefined behavior

* Add status check

* fix error C2664,C2665 : cannot convert argument

* Format adjustment

VSCODE will automatically format the indentation to 4 spaces in some situation.

* fix error C2440

* fix error C2440

* add cl_d3d11_ext.h

* Format adjustment

* remove unnecessary checks
2019-03-24 18:34:09 +03:00
Alexander Alekhin 2bd0844be3 Merge pull request #14126 from brad-kelly:integral_avx512_cn1 2019-03-23 12:09:46 +00:00
Brad Kelly 0fe17eeb68 Implementing AVX512 Support for 1 channel mats for CV_64F format 2019-03-22 09:44:23 -07:00
Alexander Alekhin 8c25a8eb7b Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2019-03-22 19:31:31 +03:00
Alexander Alekhin f147ba16e2 Merge pull request #14124 from alalek:fix_python_samples 2019-03-22 15:10:46 +00:00
Alexander Alekhin b82ecaf48c Merge pull request #14125 from alalek:cmake_ie_env_vars 2019-03-22 15:10:25 +00:00
Alexander Alekhin c43371f190 Merge pull request #14101 from alalek:core_fix_constexpt_fallback 2019-03-22 10:34:19 +00:00
Alexander Alekhin 65fc863d86 cmake: support OpenVINO env variable: INTEL_OPENVINO_DIR 2019-03-22 00:03:03 +03:00
Pedro Ferreira da Costa 9cef78b685 Merge pull request #14109 from PedroFerreiradaCosta:adding_python_version_to_anisotropic_tutorial
* Created python version of the code for the anisotropic image segmentation tutorial. Created python/cpp toggles for the markdown file.

* fix doxygen warnings
2019-03-21 22:53:12 +03:00
Alexander Alekhin fbed33cc1f samples: fix python samples compatibility with demo.py 2019-03-21 19:42:34 +00:00
Alexander Alekhin 865bd7abff Merge pull request #14121 from seiko2plus:cmake_vsx_fix_aligned_test 2019-03-21 13:25:39 +00:00
Alexander Alekhin a509ec0d91 Merge pull request #14112 from alalek:android_pack_default_api21 2019-03-21 13:23:11 +00:00
Alexander Alekhin 49f43b03b1 Merge pull request #14108 from alalek:fix_python_samples_3.4 2019-03-21 13:22:55 +00:00
Alexander Alekhin 58835eeb78 Merge pull request #14113 from Bharat123rox:calibration 2019-03-21 09:55:31 +00:00
Sayed Adel 0df607e5dd cmake:vsx Fix compilation fail on aligned runtime test when c++11 enabled 2019-03-21 11:21:00 +02:00
Bharat123Rox ea68f7ea1e Remove dead link in calib3d.hpp 2019-03-21 07:41:32 +05:30
Alexander Alekhin 40da61a314 Merge pull request #14096 from oseiskar:fix-android-sample-menus 2019-03-20 21:58:49 +00:00
Alexander Alekhin f473b61585 android: build package with API 21
enables Video I/O backend via Media NDK
2019-03-20 19:21:43 +03:00
Alexander Alekhin e09a464242 Merge pull request #14092 from mattismyname:fix-kmeans 2019-03-20 16:20:46 +00:00
Alexander Alekhin 4e60db9030 Merge pull request #14110 from seiko2plus:core_vsx_fp16 2019-03-20 16:04:20 +00:00
Matthew K. Gumbel 74e3403620 flann/kmeans: Fix non-determinism of KMeans index
When running with >1 OpenCV thread, KMeans index generation was
non-deterministic because of a RWW race. Issue is resolved by removing
the offending logic from the parallel section.
2019-03-20 08:44:31 -07:00
Alexander Alekhin a8e635f177 Merge pull request #14069 from terfendail:transform_wintr 2019-03-20 15:39:40 +00:00
Alexander Alekhin 6501cb93a4 Merge pull request #14104 from alalek:android_build_sdk_reduce_mem_usage 2019-03-20 15:35:05 +00:00
Alexander Alekhin 04fad57fc1 samples: fix python samples compatibility with demo.py 2019-03-20 18:32:34 +03:00
Sayed Adel f41359688b core:vsx Add support for VSX3 half precision conversions 2019-03-20 10:19:42 +02:00
Giles Payne 0d1a0b126b Merge pull request #14005 from komakai:android-video-cap
* Add Android Media NDK video i/o file capture back-end

* Fix failing test

* Improve error handling/prevent resource leaks

* Add license text

* Modify default for WITH_ANDROID_MEDIANDK option

* Fix spelling of deleter_AMediaExtractor
2019-03-19 21:28:45 +03:00
Alexander Alekhin 9a202c1522 Merge pull request #14090 from andrey-golubev:gapi_unused_node_fluid_fix 2019-03-19 15:15:53 +00:00
Alexander Alekhin 6c862fae13 Merge pull request #14099 from seiko2plus:vsx_improvements_3 2019-03-19 14:59:58 +00:00
Alexander Alekhin ce1432e42d Merge pull request #14103 from alalek:fixup_test_14089 2019-03-19 14:19:00 +00:00
Alexander Alekhin e8a0bc5794 android: reduce memory consumption by gradle builds 2019-03-19 16:50:08 +03:00
Alexander Alekhin 93a402d0f2 core: fix Core_EigenNonSymmetric.convergence test 2019-03-19 15:18:43 +03:00
Alexander Alekhin e783e6677e Merge pull request #14091 from alalek:core_cache_dir_version_update 2019-03-19 10:33:36 +00:00
Alexander Alekhin f4c2c4412b Merge pull request #14089 from alalek:fix_14088 2019-03-19 10:33:03 +00:00
Sayed Adel 4fe2d9bdbc core:vsx Several improvements(3)
* optimize v_lut_deinterleave
 * optimize v_interleave_/pairs/quads/triplets
 * optimize v_lut, use vec_extract instead of aligned store
2019-03-19 12:30:50 +02:00
Alexander Alekhin 8518d078d7 core: fix fallback CV_CONSTEXPR definition
keep it empty to avoid failures of these declarations:
static CV_CONSTEXPR const int var = ...;
2019-03-19 13:02:22 +03:00
Otto Seiskari 3a1ccd5f43 Remove fullscreen android:theme where it hides the menu
Many of the Android samples rely on an options menu to work properly
but, at least on newer devices, the menu is permanently hidden by the
Android theme "Theme.NoTitleBar.Fullscreen", which means that most
of the examples were dysfunctional.
2019-03-18 21:23:47 +02:00
Vitaly Tuzov d43597c199 transform() implementation updated to utilize wide universal intrinsics 2019-03-18 20:33:19 +03:00
Alexander Alekhin 6e90b85cae core: cache dir version update 2019-03-18 19:17:54 +03:00
Alexander Alekhin 5451b89aed core: refactor EigenvalueDecomposition (hqr2)
- fix resource allocation management
- reduce variables scope
- fix complex_div
- fix comments, constants
- simplify add/sub operations
2019-03-18 19:07:34 +03:00
Alexander Alekhin fdf6323942 Merge pull request #14026 from Palmitoxico:android-ndk 2019-03-18 15:40:03 +00:00
Andrey Golubev dd2823aaec [G-API] Allow unused nodes in Fluid backend
Allow nodes produced after some operation to be
"unused": not being an output and not being used
as inputs to other operations

Add fluid test to cover this case
2019-03-18 18:20:11 +03:00
Augusto Fraga Giachero 032e458085 Avoid unexpected line breaks in version_string.inc
The Android NDK 16b has a bug that sets the ANDROID_NDK_REVISION
variable incorrectly, generating an unexpected line break in the
middle of the string. This breaks the build as the generated
version_string.inc presents an invalid C string.

Remove leading and trailing line breaks, warns for line breaks in the
middle of 'msg' and escape them before appending to
OPENCV_BUILD_INFO_STR.
2019-03-18 11:57:05 -03:00
Alexander Alekhin a7c4ee9ae1 core: add iterations limit check in eigenNonSymmetric() 2019-03-18 17:49:17 +03:00
Alexander Alekhin ec25689b42 Merge pull request #14083 from PedroFerreiradaCosta:adding_quick_navigation_between_tutorials 2019-03-18 13:13:40 +00:00
Pedro Ferreira da Costa 4fac12c8d3 adding missing quick navigation to ImageProc module 2019-03-18 09:45:41 +00:00
Alexander Alekhin cae1859324 Merge pull request #14079 from npochhi:cmake_change 2019-03-16 16:54:11 +00:00
npochhi 352f4fead6 changes cmake_system_name matching condition 2019-03-16 20:24:06 +05:30
211 changed files with 4738 additions and 2272 deletions
+16
View File
@@ -12,6 +12,22 @@ Write-Output ("=" * 120)
Write-Output ""
if(![System.IO.File]::Exists($output)) {
try {
[io.file]::OpenWrite($output).close()
} catch {
Write-Warning "Unable to write: $output"
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Warning "Launching with 'Administrator' elevated privileges..."
Pause
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
exit
} else {
Write-Output "FATAL: Unable to write with elevated privileges: $output"
Pause
exit 1
}
}
try {
Write-Output ("Downloading: " + $output)
Import-Module BitsTransfer
+122
View File
@@ -0,0 +1,122 @@
/**********************************************************************************
* Copyright (c) 2008-2009 The Khronos Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and/or associated documentation files (the
* "Materials"), to deal in the Materials without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Materials, and to
* permit persons to whom the Materials are furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
**********************************************************************************/
#ifndef __OPENCL_CL_D3D11_EXT_H
#define __OPENCL_CL_D3D11_EXT_H
#include <d3d11.h>
#include <CL/cl.h>
#include <CL/cl_platform.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
* cl_nv_d3d11_sharing */
typedef cl_uint cl_d3d11_device_source_nv;
typedef cl_uint cl_d3d11_device_set_nv;
/******************************************************************************/
// Error Codes
#define CL_INVALID_D3D11_DEVICE_NV -1006
#define CL_INVALID_D3D11_RESOURCE_NV -1007
#define CL_D3D11_RESOURCE_ALREADY_ACQUIRED_NV -1008
#define CL_D3D11_RESOURCE_NOT_ACQUIRED_NV -1009
// cl_d3d11_device_source_nv
#define CL_D3D11_DEVICE_NV 0x4019
#define CL_D3D11_DXGI_ADAPTER_NV 0x401A
// cl_d3d11_device_set_nv
#define CL_PREFERRED_DEVICES_FOR_D3D11_NV 0x401B
#define CL_ALL_DEVICES_FOR_D3D11_NV 0x401C
// cl_context_info
#define CL_CONTEXT_D3D11_DEVICE_NV 0x401D
// cl_mem_info
#define CL_MEM_D3D11_RESOURCE_NV 0x401E
// cl_image_info
#define CL_IMAGE_D3D11_SUBRESOURCE_NV 0x401F
// cl_command_type
#define CL_COMMAND_ACQUIRE_D3D11_OBJECTS_NV 0x4020
#define CL_COMMAND_RELEASE_D3D11_OBJECTS_NV 0x4021
/******************************************************************************/
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromD3D11NV_fn)(
cl_platform_id platform,
cl_d3d11_device_source_nv d3d_device_source,
void * d3d_object,
cl_d3d11_device_set_nv d3d_device_set,
cl_uint num_entries,
cl_device_id * devices,
cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11BufferNV_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Buffer * resource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture2DNV_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Texture2D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture3DNV_fn)(
cl_context context,
cl_mem_flags flags,
ID3D11Texture3D * resource,
UINT subresource,
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireD3D11ObjectsNV_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseD3D11ObjectsNV_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
cl_mem * mem_objects,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
#ifdef __cplusplus
}
#endif
#endif // __OPENCL_CL_D3D11_H
+1 -1
View File
@@ -84,4 +84,4 @@ if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${PNG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
ocv_install_3rdparty_licenses(libpng LICENSE README opencv-libpng.patch)
ocv_install_3rdparty_licenses(libpng LICENSE README)
+2 -1
View File
@@ -4588,7 +4588,8 @@ png_image_free(png_imagep image)
if (image != NULL && image->opaque != NULL &&
image->opaque->error_buf == NULL)
{
png_image_free_function(image);
/* Ignore errors here: */
(void)png_safe_execute(image, png_image_free_function, image);
image->opaque = NULL;
}
}
+1
View File
@@ -228,6 +228,7 @@ int stream_size;
state->strm = strm;
state->window = Z_NULL;
state->mode = HEAD; /* to pass state test in inflateReset2() */
state->check = 1L; /* 1L is the result of adler32() zero length data */
ret = inflateReset2(strm, windowBits);
if (ret != Z_OK) {
ZFREE(strm, state);
@@ -0,0 +1,12 @@
diff --git a/3rdparty/zlib/inflate.c b/3rdparty/zlib/inflate.c
index ac333e8c2e..19a2cf2ed8 100644
--- a/3rdparty/zlib/inflate.c
+++ b/3rdparty/zlib/inflate.c
@@ -228,6 +228,7 @@ int stream_size;
state->strm = strm;
state->window = Z_NULL;
state->mode = HEAD; /* to pass state test in inflateReset2() */
+ state->check = 1L; /* 1L is the result of adler32() zero length data */
ret = inflateReset2(strm, windowBits);
if (ret != Z_OK) {
ZFREE(strm, state);
+19 -2
View File
@@ -108,6 +108,10 @@ if(POLICY CMP0067)
cmake_policy(SET CMP0067 NEW)
endif()
if(POLICY CMP0068)
cmake_policy(SET CMP0068 NEW) # CMake 3.9+: `RPATH` settings on macOS do not affect `install_name`.
endif()
include(cmake/OpenCVUtils.cmake)
ocv_cmake_reset_hooks()
ocv_check_environment_variables(OPENCV_CMAKE_HOOKS_DIR)
@@ -368,6 +372,9 @@ OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON
OCV_OPTION(WITH_DIRECTX "Include DirectX support" ON
VISIBLE_IF WIN32 AND NOT WINRT
VERIFY HAVE_DIRECTX)
OCV_OPTION(WITH_OPENCL_D3D11_NV "Include NVIDIA OpenCL D3D11 support" WITH_DIRECTX
VISIBLE_IF WIN32 AND NOT WINRT
VERIFY HAVE_OPENCL_D3D11_NV)
OCV_OPTION(WITH_LIBREALSENSE "Include Intel librealsense support" OFF
VISIBLE_IF NOT WITH_INTELPERC
VERIFY HAVE_LIBREALSENSE)
@@ -410,6 +417,9 @@ OCV_OPTION(WITH_IMGCODEC_PFM "Include PFM formats support" ON
OCV_OPTION(WITH_QUIRC "Include library QR-code decoding" ON
VISIBLE_IF TRUE
VERIFY HAVE_QUIRC)
OCV_OPTION(WITH_ANDROID_MEDIANDK "Use Android Media NDK for Video I/O (Android)" (ANDROID_NATIVE_API_LEVEL GREATER 20)
VISIBLE_IF ANDROID
VERIFY HAVE_ANDROID_MEDIANDK)
# OpenCV build components
# ===================================================
@@ -712,7 +722,7 @@ if(UNIX)
CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD)
if(ANDROID)
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m log)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|NetBSD|DragonFly|OpenBSD|Haiku")
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|NetBSD|DragonFly|OpenBSD|Haiku")
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} m pthread)
elseif(EMSCRIPTEN)
# no need to link to system libs with emscripten
@@ -1175,7 +1185,13 @@ status(" 3rdparty dependencies:" ${deps_3rdparty})
# ========================== OpenCV modules ==========================
status("")
status(" OpenCV modules:")
string(REPLACE "opencv_" "" OPENCV_MODULES_BUILD_ST "${OPENCV_MODULES_BUILD}")
set(OPENCV_MODULES_BUILD_ST "")
foreach(the_module ${OPENCV_MODULES_BUILD})
if(NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "INTERNAL" OR the_module STREQUAL "opencv_ts")
list(APPEND OPENCV_MODULES_BUILD_ST "${the_module}")
endif()
endforeach()
string(REPLACE "opencv_" "" OPENCV_MODULES_BUILD_ST "${OPENCV_MODULES_BUILD_ST}")
string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_USER_ST "${OPENCV_MODULES_DISABLED_USER}")
string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_AUTO_ST "${OPENCV_MODULES_DISABLED_AUTO}")
string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_FORCE_ST "${OPENCV_MODULES_DISABLED_FORCE}")
@@ -1567,6 +1583,7 @@ if(WITH_OPENCL OR HAVE_OPENCL)
IF HAVE_OPENCL_SVM THEN "SVM"
IF HAVE_CLAMDFFT THEN "AMDFFT"
IF HAVE_CLAMDBLAS THEN "AMDBLAS"
IF HAVE_OPENCL_D3D11_NV THEN "NVD3D11"
ELSE "no extra features")
status("")
status(" OpenCL:" HAVE_OPENCL THEN "YES (${opencl_features})" ELSE "NO")
+8 -1
View File
@@ -296,11 +296,18 @@ endif()
# workaround gcc bug for aligned ld/st
# https://github.com/opencv/opencv/issues/13211
if((PPC64LE AND NOT CMAKE_CROSSCOMPILING) OR OPENCV_FORCE_COMPILER_CHECK_VSX_ALIGNED)
ocv_check_runtime_flag("${CPU_BASELINE_FLAGS}" "OPENCV_CHECK_VSX_ALIGNED" "${OpenCV_SOURCE_DIR}/cmake/checks/runtime/cpu_vsx_aligned.cpp")
ocv_check_runtime_flag("${CPU_BASELINE_FLAGS}" OPENCV_CHECK_VSX_ALIGNED "${OpenCV_SOURCE_DIR}/cmake/checks/runtime/cpu_vsx_aligned.cpp")
if(NOT OPENCV_CHECK_VSX_ALIGNED)
add_extra_compiler_option_force(-DCV_COMPILER_VSX_BROKEN_ALIGNED)
endif()
endif()
# validate inline asm with fixes register number and constraints wa, wd, wf
if(PPC64LE)
ocv_check_compiler_flag(CXX "${CPU_BASELINE_FLAGS}" OPENCV_CHECK_VSX_ASM "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx_asm.cpp")
if(NOT OPENCV_CHECK_VSX_ASM)
add_extra_compiler_option_force(-DCV_COMPILER_VSX_BROKEN_ASM)
endif()
endif()
# combine all "extra" options
if(NOT OPENCV_SKIP_EXTRA_COMPILER_FLAGS)
+21 -12
View File
@@ -1,7 +1,6 @@
# The script detects Intel(R) Inference Engine installation
#
# Cache variables:
# INF_ENGINE_OMP_DIR - directory with OpenMP library to link with (needed by some versions of IE)
# INF_ENGINE_RELEASE - a number reflecting IE source interface (linked with OpenVINO release)
#
# Detect parameters:
@@ -11,8 +10,8 @@
# - INF_ENGINE_INCLUDE_DIRS - headers search location
# - INF_ENGINE_LIB_DIRS - library search location
# 3. OpenVINO location:
# - environment variable INTEL_CVSDK_DIR is set to location of OpenVINO installation dir
# - INF_ENGINE_PLATFORM - part of name of library directory representing its platform (default ubuntu_16.04)
# - environment variable INTEL_OPENVINO_DIR is set to location of OpenVINO installation dir
# - INF_ENGINE_PLATFORM - part of name of library directory representing its platform
#
# Result:
# INF_ENGINE_TARGET - set to name of imported library target representing InferenceEngine
@@ -36,11 +35,13 @@ function(add_custom_ie_build _inc _lib _lib_rel _lib_dbg _msg)
IMPORTED_IMPLIB_DEBUG "${_lib_dbg}"
INTERFACE_INCLUDE_DIRECTORIES "${_inc}"
)
find_library(omp_lib iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
if(NOT omp_lib)
message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
else()
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${omp_lib}")
if(NOT INF_ENGINE_RELEASE VERSION_GREATER "2018050000")
find_library(INF_ENGINE_OMP_LIBRARY iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
if(NOT INF_ENGINE_OMP_LIBRARY)
message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
else()
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${INF_ENGINE_OMP_LIBRARY}")
endif()
endif()
set(INF_ENGINE_VERSION "Unknown" CACHE STRING "")
set(INF_ENGINE_TARGET inference_engine PARENT_SCOPE)
@@ -64,9 +65,17 @@ if(NOT INF_ENGINE_TARGET AND INF_ENGINE_LIB_DIRS AND INF_ENGINE_INCLUDE_DIRS)
add_custom_ie_build("${ie_custom_inc}" "${ie_custom_lib}" "${ie_custom_lib_rel}" "${ie_custom_lib_dbg}" "INF_ENGINE_{INCLUDE,LIB}_DIRS")
endif()
set(_loc "$ENV{INTEL_CVSDK_DIR}")
set(_loc "$ENV{INTEL_OPENVINO_DIR}")
if(NOT _loc AND DEFINED ENV{INTEL_CVSDK_DIR})
set(_loc "$ENV{INTEL_CVSDK_DIR}") # OpenVINO 2018.x
endif()
if(NOT INF_ENGINE_TARGET AND _loc)
set(INF_ENGINE_PLATFORM "ubuntu_16.04" CACHE STRING "InferenceEngine platform (library dir)")
if(NOT INF_ENGINE_RELEASE VERSION_GREATER "2018050000")
set(INF_ENGINE_PLATFORM_DEFAULT "ubuntu_16.04")
else()
set(INF_ENGINE_PLATFORM_DEFAULT "")
endif()
set(INF_ENGINE_PLATFORM "${INF_ENGINE_PLATFORM_DEFAULT}" CACHE STRING "InferenceEngine platform (library dir)")
find_path(ie_custom_env_inc "inference_engine.hpp" PATHS "${_loc}/deployment_tools/inference_engine/include" NO_DEFAULT_PATH)
find_library(ie_custom_env_lib "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/${INF_ENGINE_PLATFORM}/intel64" NO_DEFAULT_PATH)
find_library(ie_custom_env_lib_rel "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Release" NO_DEFAULT_PATH)
@@ -78,9 +87,9 @@ endif()
if(INF_ENGINE_TARGET)
if(NOT INF_ENGINE_RELEASE)
message(WARNING "InferenceEngine version have not been set, 2018R5 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
message(WARNING "InferenceEngine version have not been set, 2019R1 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
endif()
set(INF_ENGINE_RELEASE "2018050000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
set(INF_ENGINE_RELEASE "2019010000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
)
+7 -2
View File
@@ -2,14 +2,19 @@ set(OPENCL_FOUND ON CACHE BOOL "OpenCL library is found")
if(APPLE)
set(OPENCL_LIBRARY "-framework OpenCL" CACHE STRING "OpenCL library")
set(OPENCL_INCLUDE_DIR "" CACHE PATH "OpenCL include directory")
else(APPLE)
else()
set(OPENCL_LIBRARY "" CACHE STRING "OpenCL library")
set(OPENCL_INCLUDE_DIR "${OpenCV_SOURCE_DIR}/3rdparty/include/opencl/1.2" CACHE PATH "OpenCL include directory")
ocv_install_3rdparty_licenses(opencl-headers "${OpenCV_SOURCE_DIR}/3rdparty/include/opencl/LICENSE.txt")
endif(APPLE)
endif()
mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY)
if(OPENCL_FOUND)
if(WITH_OPENCL_D3D11_NV AND EXISTS "${OPENCL_INCLUDE_DIR}/CL/cl_d3d11_ext.h")
set(HAVE_OPENCL_D3D11_NV ON)
endif()
if(OPENCL_LIBRARY)
set(HAVE_OPENCL_STATIC ON)
set(OPENCL_LIBRARIES "${OPENCL_LIBRARY}")
+6 -1
View File
@@ -245,7 +245,12 @@ if(NOT DEFINED IPPROOT)
return()
endif()
set(IPPROOT "${ICV_PACKAGE_ROOT}/icv")
ocv_install_3rdparty_licenses(ippicv "${IPPROOT}/readme.htm" "${ICV_PACKAGE_ROOT}/EULA.txt")
ocv_install_3rdparty_licenses(ippicv "${IPPROOT}/readme.htm")
if(WIN32)
ocv_install_3rdparty_licenses(ippicv "${ICV_PACKAGE_ROOT}/EULA.rtf")
else()
ocv_install_3rdparty_licenses(ippicv "${ICV_PACKAGE_ROOT}/EULA.txt")
endif()
endif()
file(TO_CMAKE_PATH "${IPPROOT}" __IPPROOT)
+5 -1
View File
@@ -148,9 +148,13 @@ if(BUILD_IPP_IW)
set(IPPIW_ROOT "${IPPROOT}/../iw")
ocv_install_3rdparty_licenses(ippiw
"${IPPIW_ROOT}/../EULA.txt"
"${IPPIW_ROOT}/../support.txt"
"${IPPIW_ROOT}/../third-party-programs.txt")
if(WIN32)
ocv_install_3rdparty_licenses(ippiw "${IPPIW_ROOT}/../EULA.rtf")
else()
ocv_install_3rdparty_licenses(ippiw "${IPPIW_ROOT}/../EULA.txt")
endif()
# Package sources
get_filename_component(__PATH "${IPPROOT}/../iw/" ABSOLUTE)
+2 -2
View File
@@ -1148,7 +1148,7 @@ function(ocv_add_perf_tests)
source_group("Src" FILES "${${the_target}_pch}")
ocv_add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
ocv_target_include_modules(${the_target} ${perf_deps} "${perf_path}")
ocv_target_include_modules(${the_target} ${perf_deps})
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${perf_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_PERF_${the_module}_DEPS})
add_dependencies(opencv_perf_tests ${the_target})
@@ -1239,7 +1239,7 @@ function(ocv_add_accuracy_tests)
source_group("Src" FILES "${${the_target}_pch}")
ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
ocv_target_include_modules(${the_target} ${test_deps} "${test_path}")
ocv_target_include_modules(${the_target} ${test_deps})
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test")
ocv_target_include_directories(${the_target} "${CMAKE_CURRENT_BINARY_DIR}/test")
endif()
+1
View File
@@ -261,6 +261,7 @@ MACRO(ADD_PRECOMPILED_HEADER _targetName _input)
)
_PCH_GET_COMPILE_FLAGS(_compile_FLAGS)
list(APPEND _compile_FLAGS "${_PCH_include_prefix}\"${_path}\"")
get_target_property(type ${_targetName} TYPE)
if(type STREQUAL "SHARED_LIBRARY")
+11 -2
View File
@@ -822,6 +822,11 @@ function(ocv_output_status msg)
message(STATUS "${msg}")
string(REPLACE "\\" "\\\\" msg "${msg}")
string(REPLACE "\"" "\\\"" msg "${msg}")
string(REGEX REPLACE "^\n+|\n+$" "" msg "${msg}")
if(msg MATCHES "\n")
message(WARNING "String to be inserted to version_string.inc has an unexpected line break: '${msg}'")
string(REPLACE "\n" "\\n" msg "${msg}")
endif()
set(OPENCV_BUILD_INFO_STR "${OPENCV_BUILD_INFO_STR}\"${msg}\\n\"\n" CACHE INTERNAL "")
endfunction()
@@ -1195,13 +1200,17 @@ endfunction()
# ocv_install_3rdparty_licenses(<library-name> <filename1> [<filename2> ..])
function(ocv_install_3rdparty_licenses library)
foreach(filename ${ARGN})
set(filepath "${filename}")
if(NOT IS_ABSOLUTE "${filepath}")
set(filepath "${CMAKE_CURRENT_LIST_DIR}/${filepath}")
endif()
get_filename_component(name "${filename}" NAME)
install(
FILES "${filename}"
FILES "${filepath}"
DESTINATION "${OPENCV_LICENSES_INSTALL_PATH}"
COMPONENT licenses
RENAME "${library}-${name}"
OPTIONAL)
)
endforeach()
endfunction()
+21
View File
@@ -0,0 +1,21 @@
#if defined(__VSX__)
#if defined(__PPC64__) && defined(__LITTLE_ENDIAN__)
#include <altivec.h>
#else
#error "OpenCV only supports little-endian mode"
#endif
#else
#error "VSX is not supported"
#endif
/*
* xlc and wide versions of clang don't support %x<n> in the inline asm template which fixes register number
* when using any of the register constraints wa, wd, wf
*/
int main()
{
__vector float vf;
__vector signed int vi;
__asm__ __volatile__ ("xvcvsxwsp %x0,%x1" : "=wf" (vf) : "wa" (vi));
return 0;
}
+1
View File
@@ -2,6 +2,7 @@
// https://github.com/opencv/opencv/issues/13211
#include <altivec.h>
#undef bool
#define vsx_ld vec_vsx_ld
#define vsx_st vec_vsx_st
+3
View File
@@ -100,6 +100,9 @@
#cmakedefine HAVE_OPENCL_STATIC
#cmakedefine HAVE_OPENCL_SVM
/* NVIDIA OpenCL D3D Extensions support */
#cmakedefine HAVE_OPENCL_D3D11_NV
/* OpenEXR codec */
#cmakedefine HAVE_OPENEXR
+1
View File
@@ -40,6 +40,7 @@ if(DOXYGEN_FOUND)
foreach(m ${OPENCV_MODULES_MAIN} ${OPENCV_MODULES_EXTRA})
list(FIND blacklist ${m} _pos)
if(${_pos} EQUAL -1)
list(APPEND CMAKE_DOXYGEN_ENABLED_SECTIONS "HAVE_opencv_${m}")
# include folder
set(header_dir "${OPENCV_MODULE_opencv_${m}_LOCATION}/include")
if(EXISTS "${header_dir}")
@@ -41,8 +41,7 @@ you need 256 values to show the above histogram. But consider, what if you need
of pixels for all pixel values separately, but number of pixels in a interval of pixel values? say
for example, you need to find the number of pixels lying between 0 to 15, then 16 to 31, ..., 240 to 255.
You will need only 16 values to represent the histogram. And that is what is shown in example
given in [OpenCV Tutorials on
histograms](http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html#histogram-calculation).
given in @ref tutorial_histogram_calculation "OpenCV Tutorials on histograms".
So what you do is simply split the whole histogram to 16 sub-parts and value of each sub-part is the
sum of all pixel count in it. This each sub-part is called "BIN". In first case, number of bins
@@ -4,20 +4,21 @@ Image Thresholding {#tutorial_py_thresholding}
Goal
----
- In this tutorial, you will learn Simple thresholding, Adaptive thresholding, Otsu's thresholding
etc.
- You will learn these functions : **cv.threshold**, **cv.adaptiveThreshold** etc.
- In this tutorial, you will learn Simple thresholding, Adaptive thresholding and Otsu's thresholding.
- You will learn the functions **cv.threshold** and **cv.adaptiveThreshold**.
Simple Thresholding
-------------------
Here, the matter is straight forward. If pixel value is greater than a threshold value, it is
assigned one value (may be white), else it is assigned another value (may be black). The function
used is **cv.threshold**. First argument is the source image, which **should be a grayscale
image**. Second argument is the threshold value which is used to classify the pixel values. Third
argument is the maxVal which represents the value to be given if pixel value is more than (sometimes
less than) the threshold value. OpenCV provides different styles of thresholding and it is decided
by the fourth parameter of the function. Different types are:
Here, the matter is straight forward. For every pixel, the same threshold value is applied.
If the pixel value is smaller than the threshold, it is set to 0, otherwise it is set to a maximum value.
The function **cv.threshold** is used to apply the thresholding.
The first argument is the source image, which **should be a grayscale image**.
The second argument is the threshold value which is used to classify the pixel values.
The third argument is the maximum value which is assigned to pixel values exceeding the threshold.
OpenCV provides different types of thresholding which is given by the fourth parameter of the function.
Basic thresholding as described above is done by using the type cv.THRESH_BINARY.
All simple thresholding types are:
- cv.THRESH_BINARY
- cv.THRESH_BINARY_INV
@@ -25,12 +26,12 @@ by the fourth parameter of the function. Different types are:
- cv.THRESH_TOZERO
- cv.THRESH_TOZERO_INV
Documentation clearly explain what each type is meant for. Please check out the documentation.
See the documentation of the types for the differences.
Two outputs are obtained. First one is a **retval** which will be explained later. Second output is
our **thresholded image**.
The method returns two outputs.
The first is the threshold that was used and the second output is the **thresholded image**.
Code :
This code compares the different simple thresholding types:
@code{.py}
import cv2 as cv
import numpy as np
@@ -53,34 +54,31 @@ for i in xrange(6):
plt.show()
@endcode
@note To plot multiple images, we have used plt.subplot() function. Please checkout Matplotlib docs
for more details.
@note To plot multiple images, we have used the plt.subplot() function. Please checkout the matplotlib docs for more details.
Result is given below :
The code yields this result:
![image](images/threshold.jpg)
Adaptive Thresholding
---------------------
In the previous section, we used a global value as threshold value. But it may not be good in all
the conditions where image has different lighting conditions in different areas. In that case, we go
for adaptive thresholding. In this, the algorithm calculate the threshold for a small regions of the
image. So we get different thresholds for different regions of the same image and it gives us better
results for images with varying illumination.
In the previous section, we used one global value as a threshold.
But this might not be good in all cases, e.g. if an image has different lighting conditions in different areas.
In that case, adaptive thresholding thresholding can help.
Here, the algorithm determines the threshold for a pixel based on a small region around it.
So we get different thresholds for different regions of the same image which gives better results for images with varying illumination.
It has three special input params and only one output argument.
Additionally to the parameters described above, the method cv.adaptiveThreshold three input parameters:
**Adaptive Method** - It decides how thresholding value is calculated.
- cv.ADAPTIVE_THRESH_MEAN_C : threshold value is the mean of neighbourhood area.
- cv.ADAPTIVE_THRESH_GAUSSIAN_C : threshold value is the weighted sum of neighbourhood
values where weights are a gaussian window.
The **adaptiveMethod** decides how the threshold value is calculated:
- cv.ADAPTIVE_THRESH_MEAN_C: The threshold value is the mean of the neighbourhood area minus the constant **C**.
- cv.ADAPTIVE_THRESH_GAUSSIAN_C: The threshold value is a gaussian-weighted sum of the neighbourhood
values minus the constant **C**.
**Block Size** - It decides the size of neighbourhood area.
The **blockSize** determines the size of the neighbourhood area and **C** is a constant that is subtracted from the mean or weighted sum of the neighbourhood pixels.
**C** - It is just a constant which is subtracted from the mean or weighted mean calculated.
Below piece of code compares global thresholding and adaptive thresholding for an image with varying
The code below compares global thresholding and adaptive thresholding for an image with varying
illumination:
@code{.py}
import cv2 as cv
@@ -106,33 +104,30 @@ for i in xrange(4):
plt.xticks([]),plt.yticks([])
plt.show()
@endcode
Result :
Result:
![image](images/ada_threshold.jpg)
Otsus Binarization
Otsu's Binarization
-------------------
In the first section, I told you there is a second parameter **retVal**. Its use comes when we go
for Otsus Binarization. So what is it?
In global thresholding, we used an arbitrary chosen value as a threshold.
In contrast, Otsu's method avoids having to choose a value and determines it automatically.
In global thresholding, we used an arbitrary value for threshold value, right? So, how can we know a
value we selected is good or not? Answer is, trial and error method. But consider a **bimodal
image** (*In simple words, bimodal image is an image whose histogram has two peaks*). For that
image, we can approximately take a value in the middle of those peaks as threshold value, right ?
That is what Otsu binarization does. So in simple words, it automatically calculates a threshold
value from image histogram for a bimodal image. (For images which are not bimodal, binarization
wont be accurate.)
Consider an image with only two distinct image values (*bimodal image*), where the histogram would only consist of two peaks.
A good threshold would be in the middle of those two values.
Similarly, Otsu's method determines an optimal global threshold value from the image histogram.
For this, our cv.threshold() function is used, but pass an extra flag, cv.THRESH_OTSU. **For
threshold value, simply pass zero**. Then the algorithm finds the optimal threshold value and
returns you as the second output, retVal. If Otsu thresholding is not used, retVal is same as the
threshold value you used.
In order to do so, the cv.threshold() function is used, where cv.THRESH_OTSU is passed as an extra flag.
The threshold value can be chosen arbitrary.
The algorithm then finds the optimal threshold value which is returned as the first output.
Check out below example. Input image is a noisy image. In first case, I applied global thresholding
for a value of 127. In second case, I applied Otsus thresholding directly. In third case, I
filtered image with a 5x5 gaussian kernel to remove the noise, then applied Otsu thresholding. See
how noise filtering improves the result.
Check out the example below.
The input image is a noisy image.
In the first case, global thresholding with a value of 127 is applied.
In the second case, Otsu's thresholding is applied directly.
In the third case, the image is first filtered with a 5x5 gaussian kernel to remove the noise, then Otsu thresholding is applied.
See how noise filtering improves the result.
@code{.py}
import cv2 as cv
import numpy as np
@@ -167,17 +162,17 @@ for i in xrange(3):
plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()
@endcode
Result :
Result:
![image](images/otsu.jpg)
### How Otsu's Binarization Works?
### How does Otsu's Binarization work?
This section demonstrates a Python implementation of Otsu's binarization to show how it works
actually. If you are not interested, you can skip this.
Since we are working with bimodal images, Otsu's algorithm tries to find a threshold value (t) which
minimizes the **weighted within-class variance** given by the relation :
minimizes the **weighted within-class variance** given by the relation:
\f[\sigma_w^2(t) = q_1(t)\sigma_1^2(t)+q_2(t)\sigma_2^2(t)\f]
@@ -186,7 +181,7 @@ where
\f[q_1(t) = \sum_{i=1}^{t} P(i) \quad \& \quad q_2(t) = \sum_{i=t+1}^{I} P(i)\f]\f[\mu_1(t) = \sum_{i=1}^{t} \frac{iP(i)}{q_1(t)} \quad \& \quad \mu_2(t) = \sum_{i=t+1}^{I} \frac{iP(i)}{q_2(t)}\f]\f[\sigma_1^2(t) = \sum_{i=1}^{t} [i-\mu_1(t)]^2 \frac{P(i)}{q_1(t)} \quad \& \quad \sigma_2^2(t) = \sum_{i=t+1}^{I} [i-\mu_2(t)]^2 \frac{P(i)}{q_2(t)}\f]
It actually finds a value of t which lies in between two peaks such that variances to both classes
are minimum. It can be simply implemented in Python as follows:
are minimal. It can be simply implemented in Python as follows:
@code{.py}
img = cv.imread('noisy2.png',0)
blur = cv.GaussianBlur(img,(5,5),0)
@@ -220,7 +215,6 @@ for i in xrange(1,256):
ret, otsu = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
print( "{} {}".format(thresh,ret) )
@endcode
*(Some of the functions may be new here, but we will cover them in coming chapters)*
Additional Resources
--------------------
@@ -15,18 +15,18 @@ Installing OpenCV from prebuilt binaries
-# Below Python packages are to be downloaded and installed to their default locations.
-# [Python-2.7.x](http://www.python.org/ftp/python/2.7.13/python-2.7.13.msi).
-# Python 3.x (3.4+) or Python 2.7.x from [here](https://www.python.org/downloads/).
-# [Numpy](https://sourceforge.net/projects/numpy/files/NumPy/1.10.2/numpy-1.10.2-win32-superpack-python2.7.exe/download).
-# Numpy package (for example, using `pip install numpy` command).
-# [Matplotlib](https://sourceforge.net/projects/matplotlib/files/matplotlib/matplotlib-1.5.0/windows/matplotlib-1.5.0.win32-py2.7.exe/download) (*Matplotlib is optional, but recommended since we use it a lot in our tutorials*).
-# Matplotlib (`pip install matplotlib`) (*Matplotlib is optional, but recommended since we use it a lot in our tutorials*).
-# Install all packages into their default locations. Python will be installed to `C:/Python27/`.
-# Install all packages into their default locations. Python will be installed to `C:/Python27/` in case of Python 2.7.
-# After installation, open Python IDLE. Enter **import numpy** and make sure Numpy is working fine.
-# Download latest OpenCV release from [sourceforge
site](http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.6/OpenCV-2.4.6.0.exe/download)
-# Download latest OpenCV release from [GitHub](https://github.com/opencv/opencv/releases) or
[SourceForge site](https://sourceforge.net/projects/opencvlibrary/files/)
and double-click to extract it.
-# Goto **opencv/build/python/2.7** folder.
@@ -49,16 +49,13 @@ Building OpenCV from source
-# [Visual Studio 2012](http://go.microsoft.com/?linkid=9816768)
-# [CMake](http://www.cmake.org/files/v2.8/cmake-2.8.11.2-win32-x86.exe)
-# [CMake](https://cmake.org/download/)
-# Download and install necessary Python packages to their default locations
-# [Python 2.7.x](http://python.org/ftp/python/2.7.5/python-2.7.5.msi)
-# Python
-# [Numpy](http://sourceforge.net/projects/numpy/files/NumPy/1.7.1/numpy-1.7.1-win32-superpack-python2.7.exe/download)
-# [Matplotlib](https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-1.3.0/matplotlib-1.3.0.win32-py2.7.exe)
(*Matplotlib is optional, but recommended since we use it a lot in our tutorials.*)
-# Numpy
@note In this case, we are using 32-bit binaries of Python packages. But if you want to use
OpenCV for x64, 64-bit binaries of Python packages are to be installed. Problem is that, there
@@ -30,4 +30,9 @@ If you want to change unit use -u option (mm inches, px, m)
If you want to change page size use -w and -h options
If you want to create a ChArUco board read tutorial Detection of ChArUco Corners in opencv_contrib tutorial(https://docs.opencv.org/3.4/df/d4a/tutorial_charuco_detection.html)
@cond HAVE_opencv_aruco
If you want to create a ChArUco board read @ref tutorial_charuco_detection "tutorial Detection of ChArUco Corners" in opencv_contrib tutorial.
@endcond
@cond !HAVE_opencv_aruco
If you want to create a ChArUco board read tutorial Detection of ChArUco Corners in opencv_contrib tutorial.
@endcond
@@ -25,7 +25,7 @@ Explanation
[bvlc_googlenet.caffemodel](http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel)
Also you need file with names of [ILSVRC2012](http://image-net.org/challenges/LSVRC/2012/browse-synsets) classes:
[classification_classes_ILSVRC2012.txt](https://github.com/opencv/opencv/tree/master/samples/dnn/classification_classes_ILSVRC2012.txt).
[classification_classes_ILSVRC2012.txt](https://github.com/opencv/opencv/blob/master/samples/data/dnn/classification_classes_ILSVRC2012.txt).
Put these files into working dir of this program example.
@@ -97,9 +97,7 @@ I1 = gI1; // Download, gI1.download(I1) will work too
@endcode
Once you have your data up in the GPU memory you may call GPU enabled functions of OpenCV. Most of
the functions keep the same name just as on the CPU, with the difference that they only accept
*GpuMat* inputs. A full list of these you will find in the documentation: [online
here](http://docs.opencv.org/modules/gpu/doc/gpu.html) or the OpenCV reference manual that comes
with the source code.
*GpuMat* inputs.
Another thing to keep in mind is that not for all channel numbers you can make efficient algorithms
on the GPU. Generally, I found that the input images for the GPU images need to be either one or
@@ -1,6 +1,9 @@
Anisotropic image segmentation by a gradient structure tensor {#tutorial_anisotropic_image_segmentation_by_a_gst}
==========================
@prev_tutorial{tutorial_motion_deblur_filter}
@next_tutorial{tutorial_periodic_noise_removing_filter}
Goal
----
@@ -45,28 +48,65 @@ The orientation of an anisotropic image:
Coherency:
\f[C = \frac{\lambda_1 - \lambda_2}{\lambda_1 + \lambda_2}\f]
The coherency ranges from 0 to 1. For ideal local orientation (\f$\lambda_2\f$ = 0, \f$\lambda_1\f$ > 0) it is one, for an isotropic gray value structure (\f$\lambda_1\f$ = \f$\lambda_2\f$ > 0) it is zero.
The coherency ranges from 0 to 1. For ideal local orientation (\f$\lambda_2\f$ = 0, \f$\lambda_1\f$ > 0) it is one, for an isotropic gray value structure (\f$\lambda_1\f$ = \f$\lambda_2\f$ \> 0) it is zero.
Source code
-----------
You can find source code in the `samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp` of the OpenCV source code library.
@include cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp
@add_toggle_cpp
@include cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp
@end_toggle
@add_toggle_python
@include samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py
@end_toggle
Explanation
-----------
An anisotropic image segmentation algorithm consists of a gradient structure tensor calculation, an orientation calculation, a coherency calculation and an orientation and coherency thresholding:
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp main
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp main
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py main
@end_toggle
A function calcGST() calculates orientation and coherency by using a gradient structure tensor. An input parameter w defines a window size:
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp calcGST
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp calcGST
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py calcGST
@end_toggle
The below code applies a thresholds LowThr and HighThr to image orientation and a threshold C_Thr to image coherency calculated by the previous function. LowThr and HighThr define orientation range:
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp thresholding
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp thresholding
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py thresholding
@end_toggle
And finally we combine thresholding results:
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp combining
@add_toggle_cpp
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp combining
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py combining
@end_toggle
Result
------
@@ -1,6 +1,9 @@
Motion Deblur Filter {#tutorial_motion_deblur_filter}
==========================
@prev_tutorial{tutorial_out_of_focus_deblur_filter}
@next_tutorial{tutorial_anisotropic_image_segmentation_by_a_gst}
Goal
----
@@ -2,6 +2,7 @@ Out-of-focus Deblur Filter {#tutorial_out_of_focus_deblur_filter}
==========================
@prev_tutorial{tutorial_distance_transform}
@next_tutorial{tutorial_motion_deblur_filter}
Goal
----
@@ -1,6 +1,8 @@
Periodic Noise Removing Filter {#tutorial_periodic_noise_removing_filter}
==========================
@prev_tutorial{tutorial_anisotropic_image_segmentation_by_a_gst}
Goal
----
@@ -71,7 +71,7 @@ The structure of package contents looks as follows:
- `doc` folder contains various OpenCV documentation in PDF format. It's also available online at
<http://docs.opencv.org>.
@note The most recent docs (nightly build) are at <http://docs.opencv.org/2.4>. Generally, it's more
@note The most recent docs (nightly build) are at <http://docs.opencv.org/master>. Generally, it's more
up-to-date, but can refer to not-yet-released functionality.
@todo I'm not sure that this is the best place to talk about OpenCV Manager
@@ -85,10 +85,6 @@ applications developers:
- Automatic updates and bug fixes;
- Trusted OpenCV library source. All packages with OpenCV are published on Google Play;
For additional information on OpenCV Manager see the:
- [Slides](https://docs.google.com/a/itseez.com/presentation/d/1EO_1kijgBg_BsjNp2ymk-aarg-0K279_1VZRcPplSuk/present#slide=id.p)
- [Reference Manual](http://docs.opencv.org/android/refman.html)
Manual OpenCV4Android SDK setup
-------------------------------
@@ -96,8 +92,8 @@ Manual OpenCV4Android SDK setup
### Get the OpenCV4Android SDK
-# Go to the [OpenCV download page on
SourceForge](http://sourceforge.net/projects/opencvlibrary/files/opencv-android/) and download
the latest available version. Currently it's [OpenCV-2.4.9-android-sdk.zip](http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.9/OpenCV-2.4.9-android-sdk.zip/download).
SourceForge](http://sourceforge.net/projects/opencvlibrary/files/) and download
the latest available version. This tutorial is based on this package: [OpenCV-2.4.9-android-sdk.zip](http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.9/OpenCV-2.4.9-android-sdk.zip/download).
-# Create a new folder for Android with OpenCV development. For this tutorial we have unpacked
OpenCV SDK to the `C:\Work\OpenCV4Android\` directory.
@@ -27,8 +27,8 @@ lein run
Preamble
--------
For detailed instruction on installing OpenCV with desktop Java support refer to the [corresponding
tutorial](http://docs.opencv.org/2.4.4-beta/doc/tutorials/introduction/desktop_java/java_dev_intro.html).
For detailed instruction on installing OpenCV with desktop Java support refer to the @ref tutorial_java_dev_intro "corresponding
tutorial".
If you are in hurry, here is a minimum quick start guide to install OpenCV on Mac OS X:
@@ -302,7 +302,7 @@ Then you can start interacting with OpenCV by just referencing the fully qualifi
classes.
@note
[Here](http://docs.opencv.org/java/) you can find the full OpenCV Java API.
[Here](https://docs.opencv.org/master/javadoc/index.html) you can find the full OpenCV Java API.
@code{.clojure}
user=> (org.opencv.core.Point. 0 0)
@@ -387,8 +387,7 @@ user=> (javadoc Rect)
@endcode
### Mimic the OpenCV Java Tutorial Sample in the REPL
Let's now try to port to Clojure the [opencv java tutorial
sample](http://docs.opencv.org/2.4.4-beta/doc/tutorials/introduction/desktop_java/java_dev_intro.html).
Let's now try to port to Clojure the @ref tutorial_java_dev_intro "OpenCV Java tutorial sample".
Instead of writing it in a source file we're going to evaluate it at the REPL.
Following is the original Java source code of the cited sample.
@@ -94,8 +94,6 @@ the weight vector \f$\beta\f$ and the bias \f$\beta_{0}\f$ of the optimal hyperp
Source Code
-----------
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html#introductiontosvms)
@add_toggle_cpp
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp)
@@ -89,9 +89,6 @@ Source Code
You may also find the source code in `samples/cpp/tutorial_code/ml/non_linear_svms` folder of the OpenCV source library or
[download it from here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp).
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code
using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/non_linear_svms/non_linear_svms.html#nonlinearsvms)
@add_toggle_cpp
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp)
@@ -177,8 +177,6 @@ pattern (every view is described by several 3D-2D point correspondences).
opencv_source_code/samples/cpp/calibration.cpp
- A calibration sample in order to do 3D reconstruction can be found at
opencv_source_code/samples/cpp/build3dmodel.cpp
- A calibration sample of an artificially generated camera and chessboard patterns can be
found at opencv_source_code/samples/cpp/calibration_artificial.cpp
- A calibration example on stereo calibration can be found at
opencv_source_code/samples/cpp/stereo_calib.cpp
- A calibration example on stereo matching can be found at
+14
View File
@@ -833,6 +833,13 @@ Mat estimateAffine2D(InputArray _from, InputArray _to, OutputArray _inliers,
to.convertTo(tmp2, CV_32FC2);
to = tmp2;
}
else
{
// avoid changing of inputs in compressElems() call
from = from.clone();
to = to.clone();
}
// convert to N x 1 vectors
from = from.reshape(2, count);
to = to.reshape(2, count);
@@ -900,6 +907,13 @@ Mat estimateAffinePartial2D(InputArray _from, InputArray _to, OutputArray _inlie
to.convertTo(tmp2, CV_32FC2);
to = tmp2;
}
else
{
// avoid changing of inputs in compressElems() call
from = from.clone();
to = to.clone();
}
// convert to N x 1 vectors
from = from.reshape(2, count);
to = to.reshape(2, count);
@@ -152,4 +152,46 @@ TEST_P(EstimateAffine2D, testConversion)
INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffine2D, Method::all());
// https://github.com/opencv/opencv/issues/14259
TEST(EstimateAffine2D, issue_14259_dont_change_inputs)
{
/*const static*/ float pts0_[10] = {
0.0f, 0.0f,
0.0f, 8.0f,
4.0f, 0.0f, // outlier
8.0f, 8.0f,
8.0f, 0.0f
};
/*const static*/ float pts1_[10] = {
0.1f, 0.1f,
0.1f, 8.1f,
0.0f, 4.0f, // outlier
8.1f, 8.1f,
8.1f, 0.1f
};
Mat pts0(Size(1, 5), CV_32FC2, (void*)pts0_);
Mat pts1(Size(1, 5), CV_32FC2, (void*)pts1_);
Mat pts0_copy = pts0.clone();
Mat pts1_copy = pts1.clone();
Mat inliers;
cv::Mat A = cv::estimateAffine2D(pts0, pts1, inliers);
for(int i = 0; i < pts0.rows; ++i)
{
EXPECT_EQ(pts0_copy.at<Vec2f>(i), pts0.at<Vec2f>(i)) << "pts0: i=" << i;
}
for(int i = 0; i < pts1.rows; ++i)
{
EXPECT_EQ(pts1_copy.at<Vec2f>(i), pts1.at<Vec2f>(i)) << "pts1: i=" << i;
}
EXPECT_EQ(0, (int)inliers.at<uchar>(2));
}
}} // namespace
@@ -161,4 +161,46 @@ TEST_P(EstimateAffinePartial2D, testConversion)
INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffinePartial2D, Method::all());
// https://github.com/opencv/opencv/issues/14259
TEST(EstimateAffinePartial2D, issue_14259_dont_change_inputs)
{
/*const static*/ float pts0_[10] = {
0.0f, 0.0f,
0.0f, 8.0f,
4.0f, 0.0f, // outlier
8.0f, 8.0f,
8.0f, 0.0f
};
/*const static*/ float pts1_[10] = {
0.1f, 0.1f,
0.1f, 8.1f,
0.0f, 4.0f, // outlier
8.1f, 8.1f,
8.1f, 0.1f
};
Mat pts0(Size(1, 5), CV_32FC2, (void*)pts0_);
Mat pts1(Size(1, 5), CV_32FC2, (void*)pts1_);
Mat pts0_copy = pts0.clone();
Mat pts1_copy = pts1.clone();
Mat inliers;
cv::Mat A = cv::estimateAffinePartial2D(pts0, pts1, inliers);
for(int i = 0; i < pts0.rows; ++i)
{
EXPECT_EQ(pts0_copy.at<Vec2f>(i), pts0.at<Vec2f>(i)) << "pts0: i=" << i;
}
for(int i = 0; i < pts1.rows; ++i)
{
EXPECT_EQ(pts1_copy.at<Vec2f>(i), pts1.at<Vec2f>(i)) << "pts1: i=" << i;
}
EXPECT_EQ(0, (int)inliers.at<uchar>(2));
}
}} // namespace
+4 -1
View File
@@ -3,7 +3,7 @@ set(the_description "The Core Functionality")
ocv_add_dispatched_file(mathfuncs_core SSE2 AVX AVX2)
ocv_add_dispatched_file(stat SSE4_2 AVX2)
ocv_add_dispatched_file(arithm SSE2 SSE4_1 AVX2 VSX3)
ocv_add_dispatched_file(convert SSE2 AVX2)
ocv_add_dispatched_file(convert SSE2 AVX2 VSX3)
ocv_add_dispatched_file(convert_scale SSE2 AVX2)
ocv_add_dispatched_file(count_non_zero SSE2 AVX2)
ocv_add_dispatched_file(matmul SSE2 AVX2)
@@ -35,6 +35,9 @@ if(DEFINED WINRT AND NOT DEFINED ENABLE_WINRT_MODE_NATIVE)
endif()
if(HAVE_CUDA)
if(NOT HAVE_opencv_cudev)
message(FATAL_ERROR "CUDA: OpenCV requires enabled 'cudev' module from 'opencv_contrib' repository: https://github.com/opencv/opencv_contrib")
endif()
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wenum-compare -Wunused-function -Wshadow)
endif()
+1 -1
View File
@@ -691,7 +691,7 @@ __CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType)
# endif
#endif
#ifndef CV_CONSTEXPR
# define CV_CONSTEXPR const
# define CV_CONSTEXPR
#endif
// Integer types portatibility
@@ -2022,7 +2022,7 @@ inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b
b = v_uint64x4(b0);
}
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g, v_uint8x32& r )
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& a, v_uint8x32& b, v_uint8x32& c )
{
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 32));
@@ -2051,12 +2051,12 @@ inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g,
g0 = _mm256_shuffle_epi8(g0, sh_g);
r0 = _mm256_shuffle_epi8(r0, sh_r);
b = v_uint8x32(b0);
g = v_uint8x32(g0);
r = v_uint8x32(r0);
a = v_uint8x32(b0);
b = v_uint8x32(g0);
c = v_uint8x32(r0);
}
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16& g, v_uint16x16& r )
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& a, v_uint16x16& b, v_uint16x16& c )
{
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 16));
@@ -2082,12 +2082,12 @@ inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16&
g0 = _mm256_shuffle_epi8(g0, sh_g);
r0 = _mm256_shuffle_epi8(r0, sh_r);
b = v_uint16x16(b0);
g = v_uint16x16(g0);
r = v_uint16x16(r0);
a = v_uint16x16(b0);
b = v_uint16x16(g0);
c = v_uint16x16(r0);
}
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8& g, v_uint32x8& r )
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& a, v_uint32x8& b, v_uint32x8& c )
{
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 8));
@@ -2104,12 +2104,12 @@ inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8&
g0 = _mm256_shuffle_epi32(g0, 0xb1);
r0 = _mm256_shuffle_epi32(r0, 0xc6);
b = v_uint32x8(b0);
g = v_uint32x8(g0);
r = v_uint32x8(r0);
a = v_uint32x8(b0);
b = v_uint32x8(g0);
c = v_uint32x8(r0);
}
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g, v_uint64x4& r )
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b, v_uint64x4& c )
{
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 4));
@@ -2122,12 +2122,12 @@ inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g
__m256i g0 = _mm256_alignr_epi8(s12, s01, 8);
__m256i r0 = _mm256_unpackhi_epi64(s20r, s12);
b = v_uint64x4(b0);
g = v_uint64x4(g0);
r = v_uint64x4(r0);
a = v_uint64x4(b0);
b = v_uint64x4(g0);
c = v_uint64x4(r0);
}
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g, v_uint8x32& r, v_uint8x32& a )
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& a, v_uint8x32& b, v_uint8x32& c, v_uint8x32& d )
{
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 32));
@@ -2156,13 +2156,13 @@ inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g,
__m256i r0 = _mm256_unpacklo_epi32(phl, phh);
__m256i a0 = _mm256_unpackhi_epi32(phl, phh);
b = v_uint8x32(b0);
g = v_uint8x32(g0);
r = v_uint8x32(r0);
a = v_uint8x32(a0);
a = v_uint8x32(b0);
b = v_uint8x32(g0);
c = v_uint8x32(r0);
d = v_uint8x32(a0);
}
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16& g, v_uint16x16& r, v_uint16x16& a )
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& a, v_uint16x16& b, v_uint16x16& c, v_uint16x16& d )
{
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 16));
@@ -2190,13 +2190,13 @@ inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16&
__m256i r0 = _mm256_unpacklo_epi32(phl, phh);
__m256i a0 = _mm256_unpackhi_epi32(phl, phh);
b = v_uint16x16(b0);
g = v_uint16x16(g0);
r = v_uint16x16(r0);
a = v_uint16x16(a0);
a = v_uint16x16(b0);
b = v_uint16x16(g0);
c = v_uint16x16(r0);
d = v_uint16x16(a0);
}
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8& g, v_uint32x8& r, v_uint32x8& a )
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& a, v_uint32x8& b, v_uint32x8& c, v_uint32x8& d )
{
__m256i p0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i p1 = _mm256_loadu_si256((const __m256i*)(ptr + 8));
@@ -2218,13 +2218,13 @@ inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8&
__m256i r0 = _mm256_unpacklo_epi32(phl, phh);
__m256i a0 = _mm256_unpackhi_epi32(phl, phh);
b = v_uint32x8(b0);
g = v_uint32x8(g0);
r = v_uint32x8(r0);
a = v_uint32x8(a0);
a = v_uint32x8(b0);
b = v_uint32x8(g0);
c = v_uint32x8(r0);
d = v_uint32x8(a0);
}
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g, v_uint64x4& r, v_uint64x4& a )
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b, v_uint64x4& c, v_uint64x4& d )
{
__m256i bgra0 = _mm256_loadu_si256((const __m256i*)ptr);
__m256i bgra1 = _mm256_loadu_si256((const __m256i*)(ptr + 4));
@@ -2241,10 +2241,10 @@ inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g
__m256i r0 = _mm256_unpacklo_epi64(h02, h13);
__m256i a0 = _mm256_unpackhi_epi64(h02, h13);
b = v_uint64x4(b0);
g = v_uint64x4(g0);
r = v_uint64x4(r0);
a = v_uint64x4(a0);
a = v_uint64x4(b0);
b = v_uint64x4(g0);
c = v_uint64x4(r0);
d = v_uint64x4(a0);
}
///////////////////////////// store interleave /////////////////////////////////////
@@ -2353,7 +2353,7 @@ inline void v_store_interleave( uint64* ptr, const v_uint64x4& x, const v_uint64
}
}
inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x32& g, const v_uint8x32& r,
inline void v_store_interleave( uchar* ptr, const v_uint8x32& a, const v_uint8x32& b, const v_uint8x32& c,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
const __m256i sh_b = _mm256_setr_epi8(
@@ -2366,9 +2366,9 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x3
10, 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15,
10, 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15);
__m256i b0 = _mm256_shuffle_epi8(b.val, sh_b);
__m256i g0 = _mm256_shuffle_epi8(g.val, sh_g);
__m256i r0 = _mm256_shuffle_epi8(r.val, sh_r);
__m256i b0 = _mm256_shuffle_epi8(a.val, sh_b);
__m256i g0 = _mm256_shuffle_epi8(b.val, sh_g);
__m256i r0 = _mm256_shuffle_epi8(c.val, sh_r);
const __m256i m0 = _mm256_setr_epi8(0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0);
@@ -2403,7 +2403,7 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x3
}
}
inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint16x16& g, const v_uint16x16& r,
inline void v_store_interleave( ushort* ptr, const v_uint16x16& a, const v_uint16x16& b, const v_uint16x16& c,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
const __m256i sh_b = _mm256_setr_epi8(
@@ -2416,9 +2416,9 @@ inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint1
4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15,
4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15);
__m256i b0 = _mm256_shuffle_epi8(b.val, sh_b);
__m256i g0 = _mm256_shuffle_epi8(g.val, sh_g);
__m256i r0 = _mm256_shuffle_epi8(r.val, sh_r);
__m256i b0 = _mm256_shuffle_epi8(a.val, sh_b);
__m256i g0 = _mm256_shuffle_epi8(b.val, sh_g);
__m256i r0 = _mm256_shuffle_epi8(c.val, sh_r);
const __m256i m0 = _mm256_setr_epi8(0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1,
0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0);
@@ -2453,12 +2453,12 @@ inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint1
}
}
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint32x8& g, const v_uint32x8& r,
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& a, const v_uint32x8& b, const v_uint32x8& c,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
__m256i b0 = _mm256_shuffle_epi32(b.val, 0x6c);
__m256i g0 = _mm256_shuffle_epi32(g.val, 0xb1);
__m256i r0 = _mm256_shuffle_epi32(r.val, 0xc6);
__m256i b0 = _mm256_shuffle_epi32(a.val, 0x6c);
__m256i g0 = _mm256_shuffle_epi32(b.val, 0xb1);
__m256i r0 = _mm256_shuffle_epi32(c.val, 0xc6);
__m256i p0 = _mm256_blend_epi32(_mm256_blend_epi32(b0, g0, 0x92), r0, 0x24);
__m256i p1 = _mm256_blend_epi32(_mm256_blend_epi32(g0, r0, 0x92), b0, 0x24);
@@ -2488,12 +2488,12 @@ inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint
}
}
inline void v_store_interleave( uint64* ptr, const v_uint64x4& b, const v_uint64x4& g, const v_uint64x4& r,
inline void v_store_interleave( uint64* ptr, const v_uint64x4& a, const v_uint64x4& b, const v_uint64x4& c,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
__m256i s01 = _mm256_unpacklo_epi64(b.val, g.val);
__m256i s12 = _mm256_unpackhi_epi64(g.val, r.val);
__m256i s20 = _mm256_blend_epi32(r.val, b.val, 0xcc);
__m256i s01 = _mm256_unpacklo_epi64(a.val, b.val);
__m256i s12 = _mm256_unpackhi_epi64(b.val, c.val);
__m256i s20 = _mm256_blend_epi32(c.val, a.val, 0xcc);
__m256i bgr0 = _mm256_permute2x128_si256(s01, s20, 0 + 2*16);
__m256i bgr1 = _mm256_blend_epi32(s01, s12, 0x0f);
@@ -2519,14 +2519,14 @@ inline void v_store_interleave( uint64* ptr, const v_uint64x4& b, const v_uint64
}
}
inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x32& g,
const v_uint8x32& r, const v_uint8x32& a,
inline void v_store_interleave( uchar* ptr, const v_uint8x32& a, const v_uint8x32& b,
const v_uint8x32& c, const v_uint8x32& d,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
__m256i bg0 = _mm256_unpacklo_epi8(b.val, g.val);
__m256i bg1 = _mm256_unpackhi_epi8(b.val, g.val);
__m256i ra0 = _mm256_unpacklo_epi8(r.val, a.val);
__m256i ra1 = _mm256_unpackhi_epi8(r.val, a.val);
__m256i bg0 = _mm256_unpacklo_epi8(a.val, b.val);
__m256i bg1 = _mm256_unpackhi_epi8(a.val, b.val);
__m256i ra0 = _mm256_unpacklo_epi8(c.val, d.val);
__m256i ra1 = _mm256_unpackhi_epi8(c.val, d.val);
__m256i bgra0_ = _mm256_unpacklo_epi16(bg0, ra0);
__m256i bgra1_ = _mm256_unpackhi_epi16(bg0, ra0);
@@ -2561,14 +2561,14 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x3
}
}
inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint16x16& g,
const v_uint16x16& r, const v_uint16x16& a,
inline void v_store_interleave( ushort* ptr, const v_uint16x16& a, const v_uint16x16& b,
const v_uint16x16& c, const v_uint16x16& d,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
__m256i bg0 = _mm256_unpacklo_epi16(b.val, g.val);
__m256i bg1 = _mm256_unpackhi_epi16(b.val, g.val);
__m256i ra0 = _mm256_unpacklo_epi16(r.val, a.val);
__m256i ra1 = _mm256_unpackhi_epi16(r.val, a.val);
__m256i bg0 = _mm256_unpacklo_epi16(a.val, b.val);
__m256i bg1 = _mm256_unpackhi_epi16(a.val, b.val);
__m256i ra0 = _mm256_unpacklo_epi16(c.val, d.val);
__m256i ra1 = _mm256_unpackhi_epi16(c.val, d.val);
__m256i bgra0_ = _mm256_unpacklo_epi32(bg0, ra0);
__m256i bgra1_ = _mm256_unpackhi_epi32(bg0, ra0);
@@ -2603,14 +2603,14 @@ inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint1
}
}
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint32x8& g,
const v_uint32x8& r, const v_uint32x8& a,
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& a, const v_uint32x8& b,
const v_uint32x8& c, const v_uint32x8& d,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
__m256i bg0 = _mm256_unpacklo_epi32(b.val, g.val);
__m256i bg1 = _mm256_unpackhi_epi32(b.val, g.val);
__m256i ra0 = _mm256_unpacklo_epi32(r.val, a.val);
__m256i ra1 = _mm256_unpackhi_epi32(r.val, a.val);
__m256i bg0 = _mm256_unpacklo_epi32(a.val, b.val);
__m256i bg1 = _mm256_unpackhi_epi32(a.val, b.val);
__m256i ra0 = _mm256_unpacklo_epi32(c.val, d.val);
__m256i ra1 = _mm256_unpackhi_epi32(c.val, d.val);
__m256i bgra0_ = _mm256_unpacklo_epi64(bg0, ra0);
__m256i bgra1_ = _mm256_unpackhi_epi64(bg0, ra0);
@@ -2645,14 +2645,14 @@ inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint
}
}
inline void v_store_interleave( uint64* ptr, const v_uint64x4& b, const v_uint64x4& g,
const v_uint64x4& r, const v_uint64x4& a,
inline void v_store_interleave( uint64* ptr, const v_uint64x4& a, const v_uint64x4& b,
const v_uint64x4& c, const v_uint64x4& d,
hal::StoreMode mode=hal::STORE_UNALIGNED )
{
__m256i bg0 = _mm256_unpacklo_epi64(b.val, g.val);
__m256i bg1 = _mm256_unpackhi_epi64(b.val, g.val);
__m256i ra0 = _mm256_unpacklo_epi64(r.val, a.val);
__m256i ra1 = _mm256_unpackhi_epi64(r.val, a.val);
__m256i bg0 = _mm256_unpacklo_epi64(a.val, b.val);
__m256i bg1 = _mm256_unpackhi_epi64(a.val, b.val);
__m256i ra0 = _mm256_unpacklo_epi64(c.val, d.val);
__m256i ra1 = _mm256_unpackhi_epi64(c.val, d.val);
__m256i bgra0 = _mm256_permute2x128_si256(bg0, ra0, 0 + 2*16);
__m256i bgra1 = _mm256_permute2x128_si256(bg1, ra1, 0 + 2*16);
@@ -11,11 +11,6 @@
#define CV_SIMD128 1
#define CV_SIMD128_64F 1
/**
* todo: supporting half precision for power9
* convert instractions xvcvhpsp, xvcvsphp
**/
namespace cv
{
@@ -1077,117 +1072,188 @@ inline v_float64x2 v_lut_pairs(const double* tab, const int* idx) { return v_loa
inline v_int32x4 v_lut(const int* tab, const v_int32x4& idxvec)
{
int CV_DECL_ALIGNED(32) idx[4];
v_store_aligned(idx, idxvec);
const int idx[4] = {
vec_extract(idxvec.val, 0),
vec_extract(idxvec.val, 1),
vec_extract(idxvec.val, 2),
vec_extract(idxvec.val, 3)
};
return v_int32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
}
inline v_uint32x4 v_lut(const unsigned* tab, const v_int32x4& idxvec)
{
int CV_DECL_ALIGNED(32) idx[4];
v_store_aligned(idx, idxvec);
const int idx[4] = {
vec_extract(idxvec.val, 0),
vec_extract(idxvec.val, 1),
vec_extract(idxvec.val, 2),
vec_extract(idxvec.val, 3)
};
return v_uint32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
}
inline v_float32x4 v_lut(const float* tab, const v_int32x4& idxvec)
{
int CV_DECL_ALIGNED(32) idx[4];
v_store_aligned(idx, idxvec);
const int idx[4] = {
vec_extract(idxvec.val, 0),
vec_extract(idxvec.val, 1),
vec_extract(idxvec.val, 2),
vec_extract(idxvec.val, 3)
};
return v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
}
inline v_float64x2 v_lut(const double* tab, const v_int32x4& idxvec)
{
int CV_DECL_ALIGNED(32) idx[4];
v_store_aligned(idx, idxvec);
const int idx[2] = {
vec_extract(idxvec.val, 0),
vec_extract(idxvec.val, 1)
};
return v_float64x2(tab[idx[0]], tab[idx[1]]);
}
inline void v_lut_deinterleave(const float* tab, const v_int32x4& idxvec, v_float32x4& x, v_float32x4& y)
{
int CV_DECL_ALIGNED(32) idx[4];
v_store_aligned(idx, idxvec);
x = v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
y = v_float32x4(tab[idx[0]+1], tab[idx[1]+1], tab[idx[2]+1], tab[idx[3]+1]);
vec_float4 xy0 = vec_ld_l8(tab + vec_extract(idxvec.val, 0));
vec_float4 xy1 = vec_ld_l8(tab + vec_extract(idxvec.val, 1));
vec_float4 xy2 = vec_ld_l8(tab + vec_extract(idxvec.val, 2));
vec_float4 xy3 = vec_ld_l8(tab + vec_extract(idxvec.val, 3));
vec_float4 xy02 = vec_mergeh(xy0, xy2); // x0, x2, y0, y2
vec_float4 xy13 = vec_mergeh(xy1, xy3); // x1, x3, y1, y3
x.val = vec_mergeh(xy02, xy13);
y.val = vec_mergel(xy02, xy13);
}
inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_float64x2& x, v_float64x2& y)
{
int CV_DECL_ALIGNED(32) idx[4];
v_store_aligned(idx, idxvec);
x = v_float64x2(tab[idx[0]], tab[idx[1]]);
y = v_float64x2(tab[idx[0]+1], tab[idx[1]+1]);
vec_double2 xy0 = vsx_ld(vec_extract(idxvec.val, 0), tab);
vec_double2 xy1 = vsx_ld(vec_extract(idxvec.val, 1), tab);
x.val = vec_mergeh(xy0, xy1);
y.val = vec_mergel(xy0, xy1);
}
inline v_int8x16 v_interleave_pairs(const v_int8x16& vec)
{
vec_short8 vec0 = vec_mergeh((vec_short8)vec.val, (vec_short8)vec_mergesql(vec.val, vec.val));
vec0 = vec_mergeh(vec0, vec_mergesql(vec0, vec0));
return v_int8x16(vec_mergeh((vec_char16)vec0, (vec_char16)vec_mergesql(vec0, vec0)));
static const vec_uchar16 perm = {0, 2, 1, 3, 4, 6, 5, 7, 8, 10, 9, 11, 12, 14, 13, 15};
return v_int8x16(vec_perm(vec.val, vec.val, perm));
}
inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); }
inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec)
{ return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); }
inline v_int8x16 v_interleave_quads(const v_int8x16& vec)
{
vec_char16 vec0 = (vec_char16)vec_mergeh((vec_int4)vec.val, (vec_int4)vec_mergesql(vec.val, vec.val));
return v_int8x16(vec_mergeh(vec0, vec_mergesql(vec0, vec0)));
static const vec_uchar16 perm = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15};
return v_int8x16(vec_perm(vec.val, vec.val, perm));
}
inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); }
inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec)
{ return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); }
inline v_int16x8 v_interleave_pairs(const v_int16x8& vec)
{
vec_short8 vec0 = (vec_short8)vec_mergeh((vec_int4)vec.val, (vec_int4)vec_mergesql(vec.val, vec.val));
return v_int16x8(vec_mergeh(vec0, vec_mergesql(vec0, vec0)));
static const vec_uchar16 perm = {0,1, 4,5, 2,3, 6,7, 8,9, 12,13, 10,11, 14,15};
return v_int16x8(vec_perm(vec.val, vec.val, perm));
}
inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); }
inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec)
{ return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); }
inline v_int16x8 v_interleave_quads(const v_int16x8& vec)
{
return v_int16x8(vec_mergeh(vec.val, vec_mergesql(vec.val, vec.val)));
static const vec_uchar16 perm = {0,1, 8,9, 2,3, 10,11, 4,5, 12,13, 6,7, 14,15};
return v_int16x8(vec_perm(vec.val, vec.val, perm));
}
inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); }
inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec)
{ return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); }
inline v_int32x4 v_interleave_pairs(const v_int32x4& vec)
{
return v_int32x4(vec_mergeh(vec.val, vec_mergesql(vec.val, vec.val)));
static const vec_uchar16 perm = {0,1,2,3, 8,9,10,11, 4,5,6,7, 12,13,14,15};
return v_int32x4(vec_perm(vec.val, vec.val, perm));
}
inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec) { return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
inline v_float32x4 v_interleave_pairs(const v_float32x4& vec) { return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec)
{ return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
inline v_float32x4 v_interleave_pairs(const v_float32x4& vec)
{ return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
inline v_int8x16 v_pack_triplets(const v_int8x16& vec)
{
schar CV_DECL_ALIGNED(32) val[16];
v_store_aligned(val, vec);
return v_int8x16(val[0], val[1], val[2], val[4], val[5], val[6], val[8], val[9], val[10], val[12], val[13], val[14], val[15], val[15], val[15], val[15]);
static const vec_uchar16 perm = {0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 15, 15, 15};
return v_int8x16(vec_perm(vec.val, vec.val, perm));
}
inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); }
inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec)
{ return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); }
inline v_int16x8 v_pack_triplets(const v_int16x8& vec)
{
short CV_DECL_ALIGNED(32) val[8];
v_store_aligned(val, vec);
return v_int16x8(val[0], val[1], val[2], val[4], val[5], val[6], val[7], val[7]);
static const vec_uchar16 perm = {0,1, 2,3, 4,5, 8,9, 10,11, 12,13, 14,15, 14,15};
return v_int16x8(vec_perm(vec.val, vec.val, perm));
}
inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); }
inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec)
{ return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); }
inline v_int32x4 v_pack_triplets(const v_int32x4& vec) { return vec; }
inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) { return vec; }
inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; }
inline v_int32x4 v_pack_triplets(const v_int32x4& vec)
{ return vec; }
inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec)
{ return vec; }
inline v_float32x4 v_pack_triplets(const v_float32x4& vec)
{ return vec; }
/////// FP16 support ////////
// [TODO] implement these 2 using VSX or universal intrinsics (copy from intrin_sse.cpp and adopt)
inline v_float32x4 v_load_expand(const float16_t* ptr)
{
return v_float32x4((float)ptr[0], (float)ptr[1], (float)ptr[2], (float)ptr[3]);
vec_ushort8 vf16 = vec_ld_l8((const ushort*)ptr);
#if CV_VSX3 && defined(vec_extract_fp_from_shorth)
return v_float32x4(vec_extract_fp_from_shorth(vf16));
#elif CV_VSX3 && !defined(CV_COMPILER_VSX_BROKEN_ASM)
vec_float4 vf32;
__asm__ __volatile__ ("xvcvhpsp %x0,%x1" : "=wf" (vf32) : "wa" (vec_mergeh(vf16, vf16)));
return v_float32x4(vf32);
#else
const vec_int4 z = vec_int4_z, delta = vec_int4_sp(0x38000000);
const vec_int4 signmask = vec_int4_sp(0x80000000);
const vec_int4 maxexp = vec_int4_sp(0x7c000000);
const vec_float4 deltaf = vec_float4_c(vec_int4_sp(0x38800000));
vec_int4 bits = vec_int4_c(vec_mergeh(vec_short8_c(z), vec_short8_c(vf16)));
vec_int4 e = vec_and(bits, maxexp), sign = vec_and(bits, signmask);
vec_int4 t = vec_add(vec_sr(vec_xor(bits, sign), vec_uint4_sp(3)), delta); // ((h & 0x7fff) << 13) + delta
vec_int4 zt = vec_int4_c(vec_sub(vec_float4_c(vec_add(t, vec_int4_sp(1 << 23))), deltaf));
t = vec_add(t, vec_and(delta, vec_cmpeq(maxexp, e)));
vec_bint4 zmask = vec_cmpeq(e, z);
vec_int4 ft = vec_sel(t, zt, zmask);
return v_float32x4(vec_float4_c(vec_or(ft, sign)));
#endif
}
inline void v_pack_store(float16_t* ptr, const v_float32x4& v)
{
float CV_DECL_ALIGNED(32) f[4];
v_store_aligned(f, v);
ptr[0] = float16_t(f[0]);
ptr[1] = float16_t(f[1]);
ptr[2] = float16_t(f[2]);
ptr[3] = float16_t(f[3]);
// fixme: Is there any buitin op or intrinsic that cover "xvcvsphp"?
#if CV_VSX3 && !defined(CV_COMPILER_VSX_BROKEN_ASM)
vec_ushort8 vf16;
__asm__ __volatile__ ("xvcvsphp %x0,%x1" : "=wa" (vf16) : "wf" (v.val));
vec_st_l8(vec_mergesqe(vf16, vf16), ptr);
#else
const vec_int4 signmask = vec_int4_sp(0x80000000);
const vec_int4 rval = vec_int4_sp(0x3f000000);
vec_int4 t = vec_int4_c(v.val);
vec_int4 sign = vec_sra(vec_and(t, signmask), vec_uint4_sp(16));
t = vec_and(vec_nor(signmask, signmask), t);
vec_bint4 finitemask = vec_cmpgt(vec_int4_sp(0x47800000), t);
vec_bint4 isnan = vec_cmpgt(t, vec_int4_sp(0x7f800000));
vec_int4 naninf = vec_sel(vec_int4_sp(0x7c00), vec_int4_sp(0x7e00), isnan);
vec_bint4 tinymask = vec_cmpgt(vec_int4_sp(0x38800000), t);
vec_int4 tt = vec_int4_c(vec_add(vec_float4_c(t), vec_float4_c(rval)));
tt = vec_sub(tt, rval);
vec_int4 odd = vec_and(vec_sr(t, vec_uint4_sp(13)), vec_int4_sp(1));
vec_int4 nt = vec_add(t, vec_int4_sp(0xc8000fff));
nt = vec_sr(vec_add(nt, odd), vec_uint4_sp(13));
t = vec_sel(nt, tt, tinymask);
t = vec_sel(naninf, t, finitemask);
t = vec_or(t, sign);
vec_st_l8(vec_packs(t, t), ptr);
#endif
}
inline void v_cleanup() {}
+12 -12
View File
@@ -163,7 +163,7 @@ public:
template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
//! extract part of the matrix
template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int base_row, int base_col) const;
//! extract the matrix row
Matx<_Tp, 1, n> row(int i) const;
@@ -191,8 +191,8 @@ public:
Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const;
//! element access
const _Tp& operator ()(int i, int j) const;
_Tp& operator ()(int i, int j);
const _Tp& operator ()(int row, int col) const;
_Tp& operator ()(int row, int col);
//! 1D element access
const _Tp& operator ()(int i) const;
@@ -742,13 +742,13 @@ Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
template<typename _Tp, int m, int n>
template<int m1, int n1> inline
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int base_row, int base_col) const
{
CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
CV_DbgAssert(0 <= base_row && base_row+m1 <= m && 0 <= base_col && base_col+n1 <= n);
Matx<_Tp, m1, n1> s;
for( int di = 0; di < m1; di++ )
for( int dj = 0; dj < n1; dj++ )
s(di, dj) = (*this)(i+di, j+dj);
s(di, dj) = (*this)(base_row+di, base_col+dj);
return s;
}
@@ -779,17 +779,17 @@ typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const
}
template<typename _Tp, int m, int n> inline
const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const
const _Tp& Matx<_Tp, m, n>::operator()(int row_idx, int col_idx) const
{
CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
return this->val[i*n + j];
CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n );
return this->val[row_idx*n + col_idx];
}
template<typename _Tp, int m, int n> inline
_Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
_Tp& Matx<_Tp, m, n>::operator ()(int row_idx, int col_idx)
{
CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
return val[i*n + j];
CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n );
return val[row_idx*n + col_idx];
}
template<typename _Tp, int m, int n> inline
@@ -96,6 +96,7 @@
#define clWaitForEvents clWaitForEvents_
#if defined __APPLE__
#define CL_SILENCE_DEPRECATION
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
@@ -8,7 +8,7 @@
#define CV_VERSION_MAJOR 4
#define CV_VERSION_MINOR 1
#define CV_VERSION_REVISION 0
#define CV_VERSION_STATUS "-openvino"
#define CV_VERSION_STATUS ""
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
@@ -291,6 +291,8 @@ VSX_IMPL_1RG(vec_udword2, wi, vec_float4, wf, xvcvspuxds, vec_ctulo)
*
* So we're not able to use inline asm and only use built-in functions that CLANG supports
* and use __builtin_convertvector if clang missng any of vector conversions built-in functions
*
* todo: clang asm template bug is fixed, need to reconsider the current workarounds.
*/
// convert vector helper
+10
View File
@@ -918,7 +918,13 @@ int cv::borderInterpolate( int p, int len, int borderType )
{
CV_TRACE_FUNCTION_VERBOSE();
CV_DbgAssert(len > 0);
#ifdef CV_STATIC_ANALYSIS
if(p >= 0 && p < len)
#else
if( (unsigned)p < (unsigned)len )
#endif
;
else if( borderType == BORDER_REPLICATE )
p = p < 0 ? 0 : len - 1;
@@ -934,7 +940,11 @@ int cv::borderInterpolate( int p, int len, int borderType )
else
p = len - 1 - (p - len) - delta;
}
#ifdef CV_STATIC_ANALYSIS
while(p < 0 || p >= len);
#else
while( (unsigned)p >= (unsigned)len );
#endif
}
else if( borderType == BORDER_WRAP )
{
+469 -86
View File
@@ -48,13 +48,13 @@
#ifdef HAVE_DIRECTX
#include <vector>
# include "directx.inc.hpp"
#include "directx.inc.hpp"
#else // HAVE_DIRECTX
#define NO_DIRECTX_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
#endif
#ifndef HAVE_OPENCL
# define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
#define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
#endif // HAVE_OPENCL
namespace cv { namespace directx {
@@ -168,7 +168,7 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
//case DXGI_FORMAT_BC7_TYPELESS:
//case DXGI_FORMAT_BC7_UNORM:
//case DXGI_FORMAT_BC7_UNORM_SRGB:
#ifdef HAVE_DIRECTX_NV12
#ifdef HAVE_DIRECTX_NV12 //D3DX11 should support DXGI_FORMAT_NV12.
case DXGI_FORMAT_NV12: return CV_8UC3;
#endif
default: break;
@@ -256,75 +256,70 @@ Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
std::vector<cl_platform_id> platforms(numPlatforms);
status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
size_t exts_len;
cv::AutoBuffer<char> extensions;
bool is_support_cl_khr_d3d11_sharing = false;
#ifdef HAVE_OPENCL_D3D11_NV
bool is_support_cl_nv_d3d11_sharing = false;
#endif
for (int i = 0; i < (int)numPlatforms; i++)
{
status = clGetPlatformIDs(numPlatforms, &platforms[i], NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, NULL, &exts_len);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS");
extensions.resize(exts_len);
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, exts_len, static_cast<void*>(extensions.data()), NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available CL_PLATFORM_EXTENSIONS");
if (strstr(extensions.data(), "cl_khr_d3d11_sharing"))
is_support_cl_khr_d3d11_sharing = true;
#ifdef HAVE_OPENCL_D3D11_NV
if (strstr(extensions.data(), "cl_nv_d3d11_sharing"))
is_support_cl_nv_d3d11_sharing = true;
#endif
}
#ifdef HAVE_OPENCL_D3D11_NV
if (!is_support_cl_nv_d3d11_sharing && !is_support_cl_khr_d3d11_sharing)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
#else
if (!is_support_cl_khr_d3d11_sharing)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
#endif
int found = -1;
cl_device_id device = NULL;
cl_uint numDevices = 0;
cl_context context = NULL;
// try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
for (int i = 0; i < (int)numPlatforms; i++)
#ifdef HAVE_OPENCL_D3D11_NV
if (is_support_cl_nv_d3d11_sharing)
{
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
if (!clGetDeviceIDsFromD3D11KHR)
continue;
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
continue;
if (numDevices > 0)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
NULL, NULL
};
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
{
clReleaseDevice(device);
}
else
{
found = i;
break;
}
}
}
if (found < 0)
{
// try with CL_ALL_DEVICES_FOR_D3D11_KHR
// try with CL_PREFERRED_DEVICES_FOR_D3D11_NV
for (int i = 0; i < (int)numPlatforms; i++)
{
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
if (!clGetDeviceIDsFromD3D11KHR)
clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
if (!clGetDeviceIDsFromD3D11NV)
continue;
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
CL_PREFERRED_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
if (status != CL_SUCCESS)
continue;
if (numDevices > 0)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
NULL, NULL
CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
//CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
0
};
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
{
@@ -338,9 +333,127 @@ Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
}
}
if (found < 0)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
}
{
// try with CL_ALL_DEVICES_FOR_D3D11_NV
for (int i = 0; i < (int)numPlatforms; i++)
{
clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
if (!clGetDeviceIDsFromD3D11NV)
continue;
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
CL_ALL_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
if (status != CL_SUCCESS)
continue;
if (numDevices > 0)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
//CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
0
};
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
{
clReleaseDevice(device);
}
else
{
found = i;
break;
}
}
}
}
}
#endif
if (is_support_cl_khr_d3d11_sharing)
{
if (found < 0)
{
// try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
for (int i = 0; i < (int)numPlatforms; i++)
{
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
if (!clGetDeviceIDsFromD3D11KHR)
continue;
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
continue;
if (numDevices > 0)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
NULL, NULL
};
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
{
clReleaseDevice(device);
}
else
{
found = i;
break;
}
}
}
}
if (found < 0)
{
// try with CL_ALL_DEVICES_FOR_D3D11_KHR
for (int i = 0; i < (int)numPlatforms; i++)
{
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
if (!clGetDeviceIDsFromD3D11KHR)
continue;
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
continue;
if (numDevices > 0)
{
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
NULL, NULL
};
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
{
clReleaseDevice(device);
}
else
{
found = i;
break;
}
}
}
}
}
if (found < 0)
{
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
}
Context& ctx = Context::getDefault(false);
initializeContextFromHandle(ctx, platforms[found], context, device);
@@ -679,29 +792,85 @@ Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9
} // namespace cv::ocl
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
#ifdef HAVE_OPENCL_D3D11_NV
clCreateFromD3D11Texture2DNV_fn clCreateFromD3D11Texture2DNV = NULL;
clEnqueueAcquireD3D11ObjectsNV_fn clEnqueueAcquireD3D11ObjectsNV = NULL;
clEnqueueReleaseD3D11ObjectsNV_fn clEnqueueReleaseD3D11ObjectsNV = NULL;
#endif
clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
static void __OpenCLinitializeD3D11()
static bool __OpenCLinitializeD3D11()
{
using namespace cv::ocl;
static cl_platform_id initializedPlatform = NULL;
cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
if (initializedPlatform != platform)
bool useCLNVEXT = false;
size_t exts_len;
cl_int status = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, 0, NULL, &exts_len);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS");
cv::AutoBuffer<char> extensions(exts_len);
status = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, exts_len, static_cast<void*>(extensions.data()), NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available CL_PLATFORM_EXTENSIONS");
bool is_support_cl_khr_d3d11_sharing = false;
if (strstr(extensions.data(), "cl_khr_d3d11_sharing"))
is_support_cl_khr_d3d11_sharing = true;
#ifdef HAVE_OPENCL_D3D11_NV
bool is_support_cl_nv_d3d11_sharing = false;
if (strstr(extensions.data(), "cl_nv_d3d11_sharing"))
is_support_cl_nv_d3d11_sharing = true;
if (!is_support_cl_nv_d3d11_sharing && !is_support_cl_khr_d3d11_sharing)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
#else
if (!is_support_cl_khr_d3d11_sharing)
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
#endif
#ifdef HAVE_OPENCL_D3D11_NV
if (is_support_cl_nv_d3d11_sharing)
{
clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
initializedPlatform = platform;
if (initializedPlatform != platform)
{
clCreateFromD3D11Texture2DNV = (clCreateFromD3D11Texture2DNV_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DNV");
clEnqueueAcquireD3D11ObjectsNV = (clEnqueueAcquireD3D11ObjectsNV_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsNV");
clEnqueueReleaseD3D11ObjectsNV = (clEnqueueReleaseD3D11ObjectsNV_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsNV");
initializedPlatform = platform;
}
if (clCreateFromD3D11Texture2DNV && clEnqueueAcquireD3D11ObjectsNV && clEnqueueReleaseD3D11ObjectsNV)
{
useCLNVEXT = true;
}
}
if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
else
#endif
{
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
if (is_support_cl_khr_d3d11_sharing)
{
if (initializedPlatform != platform)
{
clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
initializedPlatform = platform;
}
if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
{
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
}
}
}
return useCLNVEXT;
}
#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
@@ -762,14 +931,9 @@ bool ocl_convert_bgr_to_nv12(
namespace directx {
void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
static void __convertToD3D11Texture2DKHR(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
{
CV_UNUSED(src); CV_UNUSED(pD3D11Texture2D);
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif defined(HAVE_OPENCL)
__OpenCLinitializeD3D11();
D3D11_TEXTURE2D_DESC desc = { 0 };
pD3D11Texture2D->GetDesc(&desc);
@@ -797,7 +961,6 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
#ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0;
#endif
clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
@@ -863,22 +1026,108 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
}
#endif
}
#endif
#else
// TODO memcpy
NO_OPENCL_SUPPORT_ERROR;
#if defined(HAVE_OPENCL_D3D11_NV)
static void __convertToD3D11Texture2DNV(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
{
D3D11_TEXTURE2D_DESC desc = { 0 };
pD3D11Texture2D->GetDesc(&desc);
int srcType = src.type();
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
CV_Assert(textureType == srcType);
Size srcSize = src.size();
CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
UMat u = src.getUMat();
// TODO Add support for roi
CV_Assert(u.offset == 0);
CV_Assert(u.isContinuous());
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
using namespace cv::ocl;
Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr();
cl_int status = 0;
cl_mem clImage = 0;
#ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0;
#endif
clImage = clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
#ifdef HAVE_DIRECTX_NV12
if (DXGI_FORMAT_NV12 == desc.Format)
{
clImageUV = clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
}
#endif
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
#ifdef HAVE_DIRECTX_NV12
if(DXGI_FORMAT_NV12 == desc.Format)
{
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
}
else
#endif
{
size_t offset = 0; // TODO
size_t origin[3] = { 0, 0, 0 };
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, origin, region, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
}
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
status = clFinish(q); // TODO Use events
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
status = clReleaseMemObject(clImage); // TODO RAII
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
#ifdef HAVE_DIRECTX_NV12
if(DXGI_FORMAT_NV12 == desc.Format)
{
status = clReleaseMemObject(clImageUV);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
}
#endif
}
#endif
void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
static void __convertFromD3D11Texture2DKHR(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
{
CV_UNUSED(pD3D11Texture2D); CV_UNUSED(dst);
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif defined(HAVE_OPENCL)
__OpenCLinitializeD3D11();
D3D11_TEXTURE2D_DESC desc = { 0 };
pD3D11Texture2D->GetDesc(&desc);
@@ -968,10 +1217,144 @@ void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
}
#endif
}
#endif
#else
// TODO memcpy
#if defined(HAVE_OPENCL_D3D11_NV)
static void __convertFromD3D11Texture2DNV(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
{
D3D11_TEXTURE2D_DESC desc = { 0 };
pD3D11Texture2D->GetDesc(&desc);
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
CV_Assert(textureType >= 0);
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
dst.create(Size(desc.Width, desc.Height), textureType);
UMat u = dst.getUMat();
// TODO Add support for roi
CV_Assert(u.offset == 0);
CV_Assert(u.isContinuous());
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
using namespace cv::ocl;
Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr();
cl_int status = 0;
cl_mem clImage = 0;
clImage = clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
#ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0;
if(DXGI_FORMAT_NV12 == desc.Format)
{
clImageUV = clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
}
#endif
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
#ifdef HAVE_DIRECTX_NV12
if (DXGI_FORMAT::DXGI_FORMAT_NV12 == desc.Format)
{
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
if (!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
}
else
#endif
{
size_t offset = 0; // TODO
size_t origin[3] = { 0, 0, 0 };
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, origin, region, offset, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
}
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
status = clFinish(q); // TODO Use events
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
status = clReleaseMemObject(clImage); // TODO RAII
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
#ifdef HAVE_DIRECTX_NV12
if(DXGI_FORMAT_NV12 == desc.Format)
{
status = clReleaseMemObject(clImageUV);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
}
#endif
}
#endif
void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
{
CV_UNUSED(src); CV_UNUSED(pD3D11Texture2D);
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR;
#else
bool useCLNVEXT = __OpenCLinitializeD3D11();
if(!useCLNVEXT){
__convertToD3D11Texture2DKHR(src,pD3D11Texture2D);
}
#ifdef HAVE_OPENCL_D3D11_NV
else
{
__convertToD3D11Texture2DNV(src,pD3D11Texture2D);
}
#endif
#endif
}
void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
{
CV_UNUSED(pD3D11Texture2D); CV_UNUSED(dst);
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR;
#else
bool useCLNVEXT = __OpenCLinitializeD3D11();
if(!useCLNVEXT){
__convertFromD3D11Texture2DKHR(pD3D11Texture2D,dst);
}
#ifdef HAVE_OPENCL_D3D11_NV
else
{
__convertFromD3D11Texture2DNV(pD3D11Texture2D,dst);
}
#endif
#endif
}
+3
View File
@@ -48,6 +48,9 @@
#include "opencv2/core/opencl/runtime/opencl_core.hpp"
#include <CL/cl_d3d11.h>
#ifdef HAVE_OPENCL_D3D11_NV
#include <CL/cl_d3d11_ext.h>
#endif
#include <CL/cl_d3d10.h>
#include <CL/cl_dx9_media_sharing.h>
#endif // HAVE_OPENCL
+114 -101
View File
@@ -248,9 +248,6 @@ private:
// Holds the data dimension.
int n;
// Stores real/imag part of a complex division.
double cdivr, cdivi;
// Pointer to internal memory.
double *d, *e, *ort;
double **V, **H;
@@ -297,8 +294,9 @@ private:
return arr;
}
void cdiv(double xr, double xi, double yr, double yi) {
static void complex_div(double xr, double xi, double yr, double yi, double& cdivr, double& cdivi) {
double r, dv;
CV_DbgAssert(std::abs(yr) + std::abs(yi) > 0.0);
if (std::abs(yr) > std::abs(yi)) {
r = yi / yr;
dv = yr + r * yi;
@@ -322,24 +320,27 @@ private:
// Fortran subroutine in EISPACK.
// Initialize
int nn = this->n;
const int max_iters_count = 1000 * this->n;
const int nn = this->n; CV_Assert(nn > 0);
int n1 = nn - 1;
int low = 0;
int high = nn - 1;
double eps = std::pow(2.0, -52.0);
const int low = 0;
const int high = nn - 1;
const double eps = std::numeric_limits<double>::epsilon();
double exshift = 0.0;
double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y;
// Store roots isolated by balanc and compute matrix norm
double norm = 0.0;
for (int i = 0; i < nn; i++) {
#if 0 // 'if' condition is always false
if (i < low || i > high) {
d[i] = H[i][i];
e[i] = 0.0;
}
#endif
for (int j = std::max(i - 1, 0); j < nn; j++) {
norm = norm + std::abs(H[i][j]);
norm += std::abs(H[i][j]);
}
}
@@ -353,7 +354,7 @@ private:
if (norm < FLT_EPSILON) {
break;
}
s = std::abs(H[l - 1][l - 1]) + std::abs(H[l][l]);
double s = std::abs(H[l - 1][l - 1]) + std::abs(H[l][l]);
if (s == 0.0) {
s = norm;
}
@@ -364,29 +365,26 @@ private:
}
// Check for convergence
// One root found
if (l == n1) {
// One root found
H[n1][n1] = H[n1][n1] + exshift;
d[n1] = H[n1][n1];
e[n1] = 0.0;
n1--;
iter = 0;
// Two roots found
} else if (l == n1 - 1) {
w = H[n1][n1 - 1] * H[n1 - 1][n1];
p = (H[n1 - 1][n1 - 1] - H[n1][n1]) / 2.0;
q = p * p + w;
z = std::sqrt(std::abs(q));
// Two roots found
double w = H[n1][n1 - 1] * H[n1 - 1][n1];
double p = (H[n1 - 1][n1 - 1] - H[n1][n1]) * 0.5;
double q = p * p + w;
double z = std::sqrt(std::abs(q));
H[n1][n1] = H[n1][n1] + exshift;
H[n1 - 1][n1 - 1] = H[n1 - 1][n1 - 1] + exshift;
x = H[n1][n1];
// Real pair
double x = H[n1][n1];
if (q >= 0) {
// Real pair
if (p >= 0) {
z = p + z;
} else {
@@ -400,10 +398,10 @@ private:
e[n1 - 1] = 0.0;
e[n1] = 0.0;
x = H[n1][n1 - 1];
s = std::abs(x) + std::abs(z);
double s = std::abs(x) + std::abs(z);
p = x / s;
q = z / s;
r = std::sqrt(p * p + q * q);
double r = std::sqrt(p * p + q * q);
p = p / r;
q = q / r;
@@ -431,9 +429,8 @@ private:
V[i][n1] = q * V[i][n1] - p * z;
}
// Complex pair
} else {
// Complex pair
d[n1 - 1] = x + p;
d[n1] = x + p;
e[n1 - 1] = z;
@@ -442,28 +439,25 @@ private:
n1 = n1 - 2;
iter = 0;
} else {
// No convergence yet
} else {
// Form shift
x = H[n1][n1];
y = 0.0;
w = 0.0;
double x = H[n1][n1];
double y = 0.0;
double w = 0.0;
if (l < n1) {
y = H[n1 - 1][n1 - 1];
w = H[n1][n1 - 1] * H[n1 - 1][n1];
}
// Wilkinson's original ad hoc shift
if (iter == 10) {
exshift += x;
for (int i = low; i <= n1; i++) {
H[i][i] -= x;
}
s = std::abs(H[n1][n1 - 1]) + std::abs(H[n1 - 1][n1 - 2]);
double s = std::abs(H[n1][n1 - 1]) + std::abs(H[n1 - 1][n1 - 2]);
x = y = 0.75 * s;
w = -0.4375 * s * s;
}
@@ -471,14 +465,14 @@ private:
// MATLAB's new ad hoc shift
if (iter == 30) {
s = (y - x) / 2.0;
double s = (y - x) * 0.5;
s = s * s + w;
if (s > 0) {
s = std::sqrt(s);
if (y < x) {
s = -s;
}
s = x - w / ((y - x) / 2.0 + s);
s = x - w / ((y - x) * 0.5 + s);
for (int i = low; i <= n1; i++) {
H[i][i] -= s;
}
@@ -487,14 +481,20 @@ private:
}
}
iter = iter + 1; // (Could check iteration count here.)
iter = iter + 1;
if (iter > max_iters_count)
CV_Error(Error::StsNoConv, "Algorithm doesn't converge (complex eigen values?)");
double p = std::numeric_limits<double>::quiet_NaN();
double q = std::numeric_limits<double>::quiet_NaN();
double r = std::numeric_limits<double>::quiet_NaN();
// Look for two consecutive small sub-diagonal elements
int m = n1 - 2;
while (m >= l) {
z = H[m][m];
double z = H[m][m];
r = x - z;
s = y - z;
double s = y - z;
p = (r * s - w) / H[m + 1][m] + H[m][m + 1];
q = H[m + 1][m + 1] - z - r - s;
r = H[m + 2][m + 1];
@@ -523,6 +523,7 @@ private:
// Double QR step involving rows l:n and columns m:n
for (int k = m; k < n1; k++) {
bool notlast = (k != n1 - 1);
if (k != m) {
p = H[k][k - 1];
@@ -538,7 +539,7 @@ private:
if (x == 0.0) {
break;
}
s = std::sqrt(p * p + q * q + r * r);
double s = std::sqrt(p * p + q * q + r * r);
if (p < 0) {
s = -s;
}
@@ -551,7 +552,7 @@ private:
p = p + s;
x = p / s;
y = q / s;
z = r / s;
double z = r / s;
q = q / p;
r = r / p;
@@ -563,8 +564,8 @@ private:
p = p + r * H[k + 2][j];
H[k + 2][j] = H[k + 2][j] - p * z;
}
H[k][j] = H[k][j] - p * x;
H[k + 1][j] = H[k + 1][j] - p * y;
H[k][j] -= p * x;
H[k + 1][j] -= p * y;
}
// Column modification
@@ -575,8 +576,8 @@ private:
p = p + z * H[i][k + 2];
H[i][k + 2] = H[i][k + 2] - p * r;
}
H[i][k] = H[i][k] - p;
H[i][k + 1] = H[i][k + 1] - p * q;
H[i][k] -= p;
H[i][k + 1] -= p * q;
}
// Accumulate transformations
@@ -602,17 +603,19 @@ private:
}
for (n1 = nn - 1; n1 >= 0; n1--) {
p = d[n1];
q = e[n1];
// Real vector
double p = d[n1];
double q = e[n1];
if (q == 0) {
// Real vector
double z = std::numeric_limits<double>::quiet_NaN();
double s = std::numeric_limits<double>::quiet_NaN();
int l = n1;
H[n1][n1] = 1.0;
for (int i = n1 - 1; i >= 0; i--) {
w = H[i][i] - p;
r = 0.0;
double w = H[i][i] - p;
double r = 0.0;
for (int j = l; j <= n1; j++) {
r = r + H[i][j] * H[j][n1];
}
@@ -627,34 +630,38 @@ private:
} else {
H[i][n1] = -r / (eps * norm);
}
// Solve real equations
} else {
x = H[i][i + 1];
y = H[i + 1][i];
// Solve real equations
CV_DbgAssert(!cvIsNaN(z));
double x = H[i][i + 1];
double y = H[i + 1][i];
q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
t = (x * s - z * r) / q;
double t = (x * s - z * r) / q;
H[i][n1] = t;
if (std::abs(x) > std::abs(z)) {
H[i + 1][n1] = (-r - w * t) / x;
} else {
CV_DbgAssert(z != 0.0);
H[i + 1][n1] = (-s - y * t) / z;
}
}
// Overflow control
t = std::abs(H[i][n1]);
double t = std::abs(H[i][n1]);
if ((eps * t) * t > 1) {
double inv_t = 1.0 / t;
for (int j = i; j <= n1; j++) {
H[j][n1] = H[j][n1] / t;
H[j][n1] *= inv_t;
}
}
}
}
// Complex vector
} else if (q < 0) {
// Complex vector
double z = std::numeric_limits<double>::quiet_NaN();
double r = std::numeric_limits<double>::quiet_NaN();
double s = std::numeric_limits<double>::quiet_NaN();
int l = n1 - 1;
// Last vector component imaginary so matrix is triangular
@@ -663,9 +670,11 @@ private:
H[n1 - 1][n1 - 1] = q / H[n1][n1 - 1];
H[n1 - 1][n1] = -(H[n1][n1] - p) / H[n1][n1 - 1];
} else {
cdiv(0.0, -H[n1 - 1][n1], H[n1 - 1][n1 - 1] - p, q);
H[n1 - 1][n1 - 1] = cdivr;
H[n1 - 1][n1] = cdivi;
complex_div(
0.0, -H[n1 - 1][n1],
H[n1 - 1][n1 - 1] - p, q,
H[n1 - 1][n1 - 1], H[n1 - 1][n1]
);
}
H[n1][n1 - 1] = 0.0;
H[n1][n1] = 1.0;
@@ -677,7 +686,7 @@ private:
ra = ra + H[i][j] * H[j][n1 - 1];
sa = sa + H[i][j] * H[j][n1];
}
w = H[i][i] - p;
double w = H[i][i] - p;
if (e[i] < 0.0) {
z = w;
@@ -686,41 +695,42 @@ private:
} else {
l = i;
if (e[i] == 0) {
cdiv(-ra, -sa, w, q);
H[i][n1 - 1] = cdivr;
H[i][n1] = cdivi;
complex_div(
-ra, -sa,
w, q,
H[i][n1 - 1], H[i][n1]
);
} else {
// Solve complex equations
x = H[i][i + 1];
y = H[i + 1][i];
double x = H[i][i + 1];
double y = H[i + 1][i];
vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
vi = (d[i] - p) * 2.0 * q;
if (vr == 0.0 && vi == 0.0) {
vr = eps * norm * (std::abs(w) + std::abs(q) + std::abs(x)
+ std::abs(y) + std::abs(z));
}
cdiv(x * r - z * ra + q * sa,
x * s - z * sa - q * ra, vr, vi);
H[i][n1 - 1] = cdivr;
H[i][n1] = cdivi;
complex_div(
x * r - z * ra + q * sa, x * s - z * sa - q * ra,
vr, vi,
H[i][n1 - 1], H[i][n1]);
if (std::abs(x) > (std::abs(z) + std::abs(q))) {
H[i + 1][n1 - 1] = (-ra - w * H[i][n1 - 1] + q
* H[i][n1]) / x;
H[i + 1][n1] = (-sa - w * H[i][n1] - q * H[i][n1
- 1]) / x;
} else {
cdiv(-r - y * H[i][n1 - 1], -s - y * H[i][n1], z,
q);
H[i + 1][n1 - 1] = cdivr;
H[i + 1][n1] = cdivi;
complex_div(
-r - y * H[i][n1 - 1], -s - y * H[i][n1],
z, q,
H[i + 1][n1 - 1], H[i + 1][n1]);
}
}
// Overflow control
t = std::max(std::abs(H[i][n1 - 1]), std::abs(H[i][n1]));
double t = std::max(std::abs(H[i][n1 - 1]), std::abs(H[i][n1]));
if ((eps * t) * t > 1) {
for (int j = i; j <= n1; j++) {
H[j][n1 - 1] = H[j][n1 - 1] / t;
@@ -734,6 +744,7 @@ private:
// Vectors of isolated roots
#if 0 // 'if' condition is always false
for (int i = 0; i < nn; i++) {
if (i < low || i > high) {
for (int j = i; j < nn; j++) {
@@ -741,14 +752,15 @@ private:
}
}
}
#endif
// Back transformation to get eigenvectors of original matrix
for (int j = nn - 1; j >= low; j--) {
for (int i = low; i <= high; i++) {
z = 0.0;
double z = 0.0;
for (int k = low; k <= std::min(j, high); k++) {
z = z + V[i][k] * H[k][j];
z += V[i][k] * H[k][j];
}
V[i][j] = z;
}
@@ -848,15 +860,15 @@ private:
// Releases all internal working memory.
void release() {
// releases the working data
delete[] d;
delete[] e;
delete[] ort;
delete[] d; d = NULL;
delete[] e; e = NULL;
delete[] ort; ort = NULL;
for (int i = 0; i < n; i++) {
delete[] H[i];
delete[] V[i];
if (H) delete[] H[i];
if (V) delete[] V[i];
}
delete[] H;
delete[] V;
delete[] H; H = NULL;
delete[] V; V = NULL;
}
// Computes the Eigenvalue Decomposition for a matrix given in H.
@@ -866,7 +878,7 @@ private:
d = alloc_1d<double> (n);
e = alloc_1d<double> (n);
ort = alloc_1d<double> (n);
try {
{
// Reduce to Hessenberg form.
orthes();
// Reduce Hessenberg to real Schur form.
@@ -884,11 +896,6 @@ private:
// Deallocate the memory by releasing all internal working data.
release();
}
catch (...)
{
release();
throw;
}
}
public:
@@ -896,15 +903,19 @@ public:
// given in src. This function is a port of the EigenvalueSolver in JAMA,
// which has been released to public domain by The MathWorks and the
// National Institute of Standards and Technology (NIST).
EigenvalueDecomposition(InputArray src, bool fallbackSymmetric = true) {
compute(src, fallbackSymmetric);
EigenvalueDecomposition() :
n(0),
d(NULL), e(NULL), ort(NULL),
V(NULL), H(NULL)
{
// nothing
}
// This function computes the Eigenvalue Decomposition for a general matrix
// given in src. This function is a port of the EigenvalueSolver in JAMA,
// which has been released to public domain by The MathWorks and the
// National Institute of Standards and Technology (NIST).
void compute(InputArray src, bool fallbackSymmetric)
void compute(InputArray src, bool fallbackSymmetric = true)
{
CV_INSTRUMENT_REGION();
@@ -934,7 +945,7 @@ public:
}
}
~EigenvalueDecomposition() {}
~EigenvalueDecomposition() { release(); }
// Returns the eigenvalues of the Eigenvalue Decomposition.
Mat eigenvalues() const { return _eigenvalues; }
@@ -959,7 +970,8 @@ void eigenNonSymmetric(InputArray _src, OutputArray _evals, OutputArray _evects)
else
src64f = src;
EigenvalueDecomposition eigensystem(src64f, false);
EigenvalueDecomposition eigensystem;
eigensystem.compute(src64f, false);
// EigenvalueDecomposition returns transposed and non-sorted eigenvalues
std::vector<double> eigenvalues64f;
@@ -1135,7 +1147,8 @@ void LDA::lda(InputArrayOfArrays _src, InputArray _lbls) {
// M = inv(Sw)*Sb
Mat M;
gemm(Swi, Sb, 1.0, Mat(), 0.0, M);
EigenvalueDecomposition es(M);
EigenvalueDecomposition es;
es.compute(M);
_eigenvalues = es.eigenvalues();
_eigenvectors = es.eigenvectors();
// reshape eigenvalues, so they are stored by column
+164 -180
View File
@@ -1451,115 +1451,82 @@ transform_( const T* src, T* dst, const WT* m, int len, int scn, int dcn )
}
}
#if CV_SIMD128 && !defined(__aarch64__)
static inline void
load3x3Matrix(const float* m, v_float32x4& m0, v_float32x4& m1, v_float32x4& m2, v_float32x4& m3)
{
m0 = v_float32x4(m[0], m[4], m[8], 0);
m1 = v_float32x4(m[1], m[5], m[9], 0);
m2 = v_float32x4(m[2], m[6], m[10], 0);
m3 = v_float32x4(m[3], m[7], m[11], 0);
}
#endif
#if CV_SIMD128
static inline v_int16x8
v_matmulvec(const v_int16x8 &v0, const v_int16x8 &m0, const v_int16x8 &m1, const v_int16x8 &m2, const v_int32x4 &m3, const int BITS)
{
// v0 : 0 b0 g0 r0 b1 g1 r1 ?
v_int32x4 t0 = v_dotprod(v0, m0); // a0 b0 a1 b1
v_int32x4 t1 = v_dotprod(v0, m1); // c0 d0 c1 d1
v_int32x4 t2 = v_dotprod(v0, m2); // e0 f0 e1 f1
v_int32x4 t3 = v_setzero_s32();
v_int32x4 s0, s1, s2, s3;
v_transpose4x4(t0, t1, t2, t3, s0, s1, s2, s3);
s0 = s0 + s1 + m3; // B0 G0 R0 ?
s2 = s2 + s3 + m3; // B1 G1 R1 ?
s0 = s0 >> BITS;
s2 = s2 >> BITS;
v_int16x8 result = v_pack(s0, v_setzero_s32()); // B0 G0 R0 0 0 0 0 0
result = v_reinterpret_as_s16(v_reinterpret_as_s64(result) << 16); // 0 B0 G0 R0 0 0 0 0
result = result | v_pack(v_setzero_s32(), s2); // 0 B0 G0 R0 B1 G1 R1 0
return result;
}
#endif
static void
transform_8u( const uchar* src, uchar* dst, const float* m, int len, int scn, int dcn )
{
#if CV_SIMD128
#if CV_SIMD
const int BITS = 10, SCALE = 1 << BITS;
const float MAX_M = (float)(1 << (15 - BITS));
if( hasSIMD128() && scn == 3 && dcn == 3 &&
std::abs(m[0]) < MAX_M && std::abs(m[1]) < MAX_M && std::abs(m[2]) < MAX_M && std::abs(m[3]) < MAX_M*256 &&
std::abs(m[4]) < MAX_M && std::abs(m[5]) < MAX_M && std::abs(m[6]) < MAX_M && std::abs(m[7]) < MAX_M*256 &&
std::abs(m[8]) < MAX_M && std::abs(m[9]) < MAX_M && std::abs(m[10]) < MAX_M && std::abs(m[11]) < MAX_M*256 )
if( scn == 3 && dcn == 3 &&
std::abs(m[0]) < MAX_M && std::abs(m[1]) < MAX_M && std::abs(m[ 2]) < MAX_M*256 && std::abs(m[ 3]) < MAX_M*256 &&
std::abs(m[4]) < MAX_M && std::abs(m[5]) < MAX_M && std::abs(m[ 6]) < MAX_M*256 && std::abs(m[ 7]) < MAX_M*256 &&
std::abs(m[8]) < MAX_M && std::abs(m[9]) < MAX_M && std::abs(m[10]) < MAX_M*256 && std::abs(m[11]) < MAX_M*256 )
{
const int nChannels = 3;
const int cWidth = v_int16x8::nlanes;
// faster fixed-point transformation
short m00 = saturate_cast<short>(m[0]*SCALE), m01 = saturate_cast<short>(m[1]*SCALE),
m02 = saturate_cast<short>(m[2]*SCALE), m10 = saturate_cast<short>(m[4]*SCALE),
m11 = saturate_cast<short>(m[5]*SCALE), m12 = saturate_cast<short>(m[6]*SCALE),
m20 = saturate_cast<short>(m[8]*SCALE), m21 = saturate_cast<short>(m[9]*SCALE),
m22 = saturate_cast<short>(m[10]*SCALE);
int m03 = saturate_cast<int>((m[3]+0.5f)*SCALE), m13 = saturate_cast<int>((m[7]+0.5f)*SCALE ),
m23 = saturate_cast<int>((m[11]+0.5f)*SCALE);
v_int16x8 m0 = v_int16x8(0, m00, m01, m02, m00, m01, m02, 0);
v_int16x8 m1 = v_int16x8(0, m10, m11, m12, m10, m11, m12, 0);
v_int16x8 m2 = v_int16x8(0, m20, m21, m22, m20, m21, m22, 0);
v_int32x4 m3 = v_int32x4(m03, m13, m23, 0);
union {
short s[6];
int p[3];
} m16;
m16.s[0] = saturate_cast<short>(m[0] * SCALE); m16.s[1] = saturate_cast<short>(m[1] * SCALE);
m16.s[2] = saturate_cast<short>(m[4] * SCALE); m16.s[3] = saturate_cast<short>(m[5] * SCALE);
m16.s[4] = saturate_cast<short>(m[8] * SCALE); m16.s[5] = saturate_cast<short>(m[9] * SCALE);
int m32[] = {saturate_cast<int>(m[ 2] * SCALE), saturate_cast<int>(m[ 3] * SCALE),
saturate_cast<int>(m[ 6] * SCALE), saturate_cast<int>(m[ 7] * SCALE),
saturate_cast<int>(m[10] * SCALE), saturate_cast<int>(m[11] * SCALE)};
v_int16 m01 = v_reinterpret_as_s16(vx_setall_s32(m16.p[0]));
v_int32 m2 = vx_setall_s32(m32[0]);
v_int32 m3 = vx_setall_s32(m32[1]);
v_int16 m45 = v_reinterpret_as_s16(vx_setall_s32(m16.p[1]));
v_int32 m6 = vx_setall_s32(m32[2]);
v_int32 m7 = vx_setall_s32(m32[3]);
v_int16 m89 = v_reinterpret_as_s16(vx_setall_s32(m16.p[2]));
v_int32 m10 = vx_setall_s32(m32[4]);
v_int32 m11 = vx_setall_s32(m32[5]);
int x = 0;
for (; x <= (len - cWidth) * nChannels; x += cWidth * nChannels)
for (; x <= (len - v_uint8::nlanes) * nChannels; x += v_uint8::nlanes * nChannels)
{
// load 8 pixels
v_int16x8 v0 = v_reinterpret_as_s16(v_load_expand(src + x));
v_int16x8 v1 = v_reinterpret_as_s16(v_load_expand(src + x + cWidth));
v_int16x8 v2 = v_reinterpret_as_s16(v_load_expand(src + x + cWidth * 2));
v_int16x8 v3;
v_uint8 b, g, r;
v_load_deinterleave(src + x, b, g, r);
v_uint8 bgl, bgh;
v_zip(b, g, bgl, bgh);
v_uint16 rl, rh;
v_expand(r, rl, rh);
// rotate and pack
v3 = v_rotate_right<1>(v2); // 0 b6 g6 r6 b7 g7 r7 0
v2 = v_rotate_left <5>(v2, v1); // 0 b4 g4 r4 b5 g5 r5 0
v1 = v_rotate_left <3>(v1, v0); // 0 b2 g2 r2 b3 g3 r3 0
v0 = v_rotate_left <1>(v0); // 0 b0 g0 r0 b1 g1 r1 0
// multiply with matrix and normalize
v0 = v_matmulvec(v0, m0, m1, m2, m3, BITS); // 0 B0 G0 R0 B1 G1 R1 0
v1 = v_matmulvec(v1, m0, m1, m2, m3, BITS); // 0 B2 G2 R2 B3 G3 R3 0
v2 = v_matmulvec(v2, m0, m1, m2, m3, BITS); // 0 B4 G4 R4 B5 G5 R5 0
v3 = v_matmulvec(v3, m0, m1, m2, m3, BITS); // 0 B6 G6 R6 B7 G7 R7 0
// narrow down as uint8x16
v_uint8x16 z0 = v_pack_u(v0, v_setzero_s16()); // 0 B0 G0 R0 B1 G1 R1 0 0 0 0 0 0 0 0 0
v_uint8x16 z1 = v_pack_u(v1, v_setzero_s16()); // 0 B2 G2 R2 B3 G3 R3 0 0 0 0 0 0 0 0 0
v_uint8x16 z2 = v_pack_u(v2, v_setzero_s16()); // 0 B4 G4 R4 B5 G5 R5 0 0 0 0 0 0 0 0 0
v_uint8x16 z3 = v_pack_u(v3, v_setzero_s16()); // 0 B6 G6 R6 B7 G7 R7 0 0 0 0 0 0 0 0 0
// rotate and pack
z0 = v_reinterpret_as_u8(v_reinterpret_as_u64(z0) >> 8) | v_reinterpret_as_u8(v_reinterpret_as_u64(z1) << 40); // B0 G0 R0 B1 G1 R1 B2 G2 0 0 0 0 0 0 0 0
z1 = v_reinterpret_as_u8(v_reinterpret_as_u64(z1) >> 24) | v_reinterpret_as_u8(v_reinterpret_as_u64(z2) << 24); // R2 B3 G3 R3 B4 G4 R4 B5 0 0 0 0 0 0 0 0
z2 = v_reinterpret_as_u8(v_reinterpret_as_u64(z2) >> 40) | v_reinterpret_as_u8(v_reinterpret_as_u64(z3) << 8); // G5 R6 B6 G6 R6 B7 G7 R7 0 0 0 0 0 0 0 0
// store on memory
v_store_low(dst + x, z0);
v_store_low(dst + x + cWidth, z1);
v_store_low(dst + x + cWidth * 2, z2);
v_int16 dbl, dbh, dgl, dgh, drl, drh;
v_uint16 p0, p2;
v_int32 p1, p3;
v_expand(bgl, p0, p2);
v_expand(v_reinterpret_as_s16(rl), p1, p3);
dbl = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m01) + p1 * m2 + m3,
v_dotprod(v_reinterpret_as_s16(p2), m01) + p3 * m2 + m3);
dgl = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m45) + p1 * m6 + m7,
v_dotprod(v_reinterpret_as_s16(p2), m45) + p3 * m6 + m7);
drl = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m89) + p1 * m10 + m11,
v_dotprod(v_reinterpret_as_s16(p2), m89) + p3 * m10 + m11);
v_expand(bgh, p0, p2);
v_expand(v_reinterpret_as_s16(rh), p1, p3);
dbh = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m01) + p1 * m2 + m3,
v_dotprod(v_reinterpret_as_s16(p2), m01) + p3 * m2 + m3);
dgh = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m45) + p1 * m6 + m7,
v_dotprod(v_reinterpret_as_s16(p2), m45) + p3 * m6 + m7);
drh = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m89) + p1 * m10 + m11,
v_dotprod(v_reinterpret_as_s16(p2), m89) + p3 * m10 + m11);
v_store_interleave(dst + x, v_pack_u(dbl, dbh), v_pack_u(dgl, dgh), v_pack_u(drl, drh));
}
m32[1] = saturate_cast<int>((m[3] + 0.5f)*SCALE);
m32[3] = saturate_cast<int>((m[7] + 0.5f)*SCALE);
m32[5] = saturate_cast<int>((m[11] + 0.5f)*SCALE);
for( ; x < len * nChannels; x += nChannels )
{
int v0 = src[x], v1 = src[x+1], v2 = src[x+2];
uchar t0 = saturate_cast<uchar>((m00*v0 + m01*v1 + m02*v2 + m03)>>BITS);
uchar t1 = saturate_cast<uchar>((m10*v0 + m11*v1 + m12*v2 + m13)>>BITS);
uchar t2 = saturate_cast<uchar>((m20*v0 + m21*v1 + m22*v2 + m23)>>BITS);
uchar t0 = saturate_cast<uchar>((m16.s[0] * v0 + m16.s[1] * v1 + m32[0] * v2 + m32[1]) >> BITS);
uchar t1 = saturate_cast<uchar>((m16.s[2] * v0 + m16.s[3] * v1 + m32[2] * v2 + m32[3]) >> BITS);
uchar t2 = saturate_cast<uchar>((m16.s[4] * v0 + m16.s[5] * v1 + m32[4] * v2 + m32[5]) >> BITS);
dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
}
vx_cleanup();
return;
}
#endif
@@ -1570,64 +1537,65 @@ transform_8u( const uchar* src, uchar* dst, const float* m, int len, int scn, in
static void
transform_16u( const ushort* src, ushort* dst, const float* m, int len, int scn, int dcn )
{
#if CV_SIMD128 && !defined(__aarch64__)
if( hasSIMD128() && scn == 3 && dcn == 3 )
#if CV_SIMD && !defined(__aarch64__)
if( scn == 3 && dcn == 3 )
{
const int nChannels = 3;
const int cWidth = v_float32x4::nlanes;
v_int16x8 delta = v_int16x8(0, -32768, -32768, -32768, -32768, -32768, -32768, 0);
v_float32x4 m0, m1, m2, m3;
load3x3Matrix(m, m0, m1, m2, m3);
m3 -= v_float32x4(32768.f, 32768.f, 32768.f, 0.f);
int x = 0;
for( ; x <= (len - cWidth) * nChannels; x += cWidth * nChannels )
#if CV_SIMD_WIDTH > 16
v_float32 m0 = vx_setall_f32(m[ 0]);
v_float32 m1 = vx_setall_f32(m[ 1]);
v_float32 m2 = vx_setall_f32(m[ 2]);
v_float32 m3 = vx_setall_f32(m[ 3] - 32768.f);
v_float32 m4 = vx_setall_f32(m[ 4]);
v_float32 m5 = vx_setall_f32(m[ 5]);
v_float32 m6 = vx_setall_f32(m[ 6]);
v_float32 m7 = vx_setall_f32(m[ 7] - 32768.f);
v_float32 m8 = vx_setall_f32(m[ 8]);
v_float32 m9 = vx_setall_f32(m[ 9]);
v_float32 m10 = vx_setall_f32(m[10]);
v_float32 m11 = vx_setall_f32(m[11] - 32768.f);
v_int16 delta = vx_setall_s16(-32768);
for (; x <= (len - v_uint16::nlanes)*3; x += v_uint16::nlanes*3)
{
// load 4 pixels
v_uint16x8 v0_16 = v_load(src + x); // b0 g0 r0 b1 g1 r1 b2 g2
v_uint16x8 v2_16 = v_load_low(src + x + cWidth * 2); // r2 b3 g3 r3 ? ? ? ?
v_uint16 b, g, r;
v_load_deinterleave(src + x, b, g, r);
v_uint32 bl, bh, gl, gh, rl, rh;
v_expand(b, bl, bh);
v_expand(g, gl, gh);
v_expand(r, rl, rh);
// expand to 4 vectors
v_uint32x4 v0_32, v1_32, v2_32, v3_32, dummy_32;
v_expand(v_rotate_right<3>(v0_16), v1_32, dummy_32); // b1 g1 r1
v_expand(v_rotate_right<1>(v2_16), v3_32, dummy_32); // b3 g3 r3
v_expand(v_rotate_right<6>(v0_16, v2_16), v2_32, dummy_32); // b2 g2 r2
v_expand(v0_16, v0_32, dummy_32); // b0 g0 r0
// convert to float32x4
v_float32x4 x0 = v_cvt_f32(v_reinterpret_as_s32(v0_32)); // b0 g0 r0
v_float32x4 x1 = v_cvt_f32(v_reinterpret_as_s32(v1_32)); // b1 g1 r1
v_float32x4 x2 = v_cvt_f32(v_reinterpret_as_s32(v2_32)); // b2 g2 r2
v_float32x4 x3 = v_cvt_f32(v_reinterpret_as_s32(v3_32)); // b3 g3 r3
// multiply and convert back to int32x4
v_int32x4 y0, y1, y2, y3;
y0 = v_round(v_matmuladd(x0, m0, m1, m2, m3)); // B0 G0 R0
y1 = v_round(v_matmuladd(x1, m0, m1, m2, m3)); // B1 G1 R1
y2 = v_round(v_matmuladd(x2, m0, m1, m2, m3)); // B2 G2 R2
y3 = v_round(v_matmuladd(x3, m0, m1, m2, m3)); // B3 G3 R3
// narrow down to int16x8
v_int16x8 v0 = v_add_wrap(v_pack(v_rotate_left<1>(y0), y1), delta); // 0 B0 G0 R0 B1 G1 R1 0
v_int16x8 v2 = v_add_wrap(v_pack(v_rotate_left<1>(y2), y3), delta); // 0 B2 G2 R2 B3 G3 R3 0
// rotate and pack
v0 = v_rotate_right<1>(v0) | v_rotate_left<5>(v2); // B0 G0 R0 B1 G1 R1 B2 G2
v2 = v_rotate_right<3>(v2); // R2 B3 G3 R3 0 0 0 0
// store 4 pixels
v_store(dst + x, v_reinterpret_as_u16(v0));
v_store_low(dst + x + cWidth * 2, v_reinterpret_as_u16(v2));
v_int16 db, dg, dr;
db = v_add_wrap(v_pack(v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bl)), m0, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gl)), m1, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rl)), m2, m3)))),
v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bh)), m0, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gh)), m1, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rh)), m2, m3))))), delta);
dg = v_add_wrap(v_pack(v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bl)), m4, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gl)), m5, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rl)), m6, m7)))),
v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bh)), m4, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gh)), m5, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rh)), m6, m7))))), delta);
dr = v_add_wrap(v_pack(v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bl)), m8, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gl)), m9, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rl)), m10, m11)))),
v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bh)), m8, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gh)), m9, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rh)), m10, m11))))), delta);
v_store_interleave(dst + x, v_reinterpret_as_u16(db), v_reinterpret_as_u16(dg), v_reinterpret_as_u16(dr));
}
for( ; x < len * nChannels; x += nChannels )
#endif
v_float32x4 _m0l(m[0], m[4], m[ 8], 0.f);
v_float32x4 _m1l(m[1], m[5], m[ 9], 0.f);
v_float32x4 _m2l(m[2], m[6], m[10], 0.f);
v_float32x4 _m3l(m[3] - 32768.f, m[7] - 32768.f, m[11] - 32768.f, 0.f);
v_float32x4 _m0h = v_rotate_left<1>(_m0l);
v_float32x4 _m1h = v_rotate_left<1>(_m1l);
v_float32x4 _m2h = v_rotate_left<1>(_m2l);
v_float32x4 _m3h = v_rotate_left<1>(_m3l);
v_int16x8 _delta(0, -32768, -32768, -32768, -32768, -32768, -32768, 0);
for( ; x <= len*3 - v_uint16x8::nlanes; x += 3*v_uint16x8::nlanes/4 )
v_store(dst + x, v_rotate_right<1>(v_reinterpret_as_u16(v_add_wrap(v_pack(
v_round(v_matmuladd(v_cvt_f32(v_reinterpret_as_s32(v_load_expand(src + x ))), _m0h, _m1h, _m2h, _m3h)),
v_round(v_matmuladd(v_cvt_f32(v_reinterpret_as_s32(v_load_expand(src + x + 3))), _m0l, _m1l, _m2l, _m3l))), _delta))));
for( ; x < len * 3; x += 3 )
{
float v0 = src[x], v1 = src[x + 1], v2 = src[x + 2];
ushort t0 = saturate_cast<ushort>(m[0] * v0 + m[1] * v1 + m[2] * v2 + m[3]);
ushort t1 = saturate_cast<ushort>(m[4] * v0 + m[5] * v1 + m[6] * v2 + m[7]);
ushort t0 = saturate_cast<ushort>(m[0] * v0 + m[1] * v1 + m[ 2] * v2 + m[ 3]);
ushort t1 = saturate_cast<ushort>(m[4] * v0 + m[5] * v1 + m[ 6] * v2 + m[ 7]);
ushort t2 = saturate_cast<ushort>(m[8] * v0 + m[9] * v1 + m[10] * v2 + m[11]);
dst[x] = t0; dst[x + 1] = t1; dst[x + 2] = t2;
}
vx_cleanup();
return;
}
#endif
@@ -1638,52 +1606,68 @@ transform_16u( const ushort* src, ushort* dst, const float* m, int len, int scn,
static void
transform_32f( const float* src, float* dst, const float* m, int len, int scn, int dcn )
{
#if CV_SIMD128 && !defined(__aarch64__)
if( hasSIMD128() )
#if CV_SIMD && !defined(__aarch64__)
int x = 0;
if( scn == 3 && dcn == 3 )
{
int x = 0;
if( scn == 3 && dcn == 3 )
int idx[v_float32::nlanes/2];
for( int i = 0; i < v_float32::nlanes/4; i++ )
{
const int cWidth = 3;
v_float32x4 m0, m1, m2, m3;
load3x3Matrix(m, m0, m1, m2, m3);
for( ; x < (len - 1)*cWidth; x += cWidth )
{
v_float32x4 x0 = v_load(src + x);
v_float32x4 y0 = v_matmuladd(x0, m0, m1, m2, m3);
v_store_low(dst + x, y0);
dst[x + 2] = v_combine_high(y0, y0).get0();
}
for( ; x < len*cWidth; x += cWidth )
{
float v0 = src[x], v1 = src[x+1], v2 = src[x+2];
float t0 = saturate_cast<float>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
float t1 = saturate_cast<float>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
float t2 = saturate_cast<float>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
}
return;
idx[i] = 3*i;
idx[i + v_float32::nlanes/4] = 0;
}
if( scn == 4 && dcn == 4 )
float _m[] = { m[0], m[4], m[ 8], 0.f,
m[1], m[5], m[ 9], 0.f,
m[2], m[6], m[10], 0.f,
m[3], m[7], m[11], 0.f };
v_float32 m0 = vx_lut_quads(_m , idx + v_float32::nlanes/4);
v_float32 m1 = vx_lut_quads(_m + 4, idx + v_float32::nlanes/4);
v_float32 m2 = vx_lut_quads(_m + 8, idx + v_float32::nlanes/4);
v_float32 m3 = vx_lut_quads(_m + 12, idx + v_float32::nlanes/4);
for( ; x <= len*3 - v_float32::nlanes; x += 3*v_float32::nlanes/4 )
v_store(dst + x, v_pack_triplets(v_matmuladd(vx_lut_quads(src + x, idx), m0, m1, m2, m3)));
for( ; x < len*3; x += 3 )
{
const int cWidth = 4;
v_float32x4 m0 = v_float32x4(m[0], m[5], m[10], m[15]);
v_float32x4 m1 = v_float32x4(m[1], m[6], m[11], m[16]);
v_float32x4 m2 = v_float32x4(m[2], m[7], m[12], m[17]);
v_float32x4 m3 = v_float32x4(m[3], m[8], m[13], m[18]);
v_float32x4 m4 = v_float32x4(m[4], m[9], m[14], m[19]);
for( ; x < len*cWidth; x += cWidth )
{
v_float32x4 x0 = v_load(src + x);
v_float32x4 y0 = v_matmul(x0, m0, m1, m2, m3) + m4;
v_store(dst + x, y0);
}
return;
float v0 = src[x], v1 = src[x+1], v2 = src[x+2];
float t0 = saturate_cast<float>(m[0]*v0 + m[1]*v1 + m[ 2]*v2 + m[ 3]);
float t1 = saturate_cast<float>(m[4]*v0 + m[5]*v1 + m[ 6]*v2 + m[ 7]);
float t2 = saturate_cast<float>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
}
vx_cleanup();
return;
}
if( scn == 4 && dcn == 4 )
{
#if CV_SIMD_WIDTH > 16
int idx[v_float32::nlanes/4];
for( int i = 0; i < v_float32::nlanes/4; i++ )
idx[i] = 0;
float _m[] = { m[4], m[9], m[14], m[19] };
v_float32 m0 = vx_lut_quads(m , idx);
v_float32 m1 = vx_lut_quads(m+ 5, idx);
v_float32 m2 = vx_lut_quads(m+10, idx);
v_float32 m3 = vx_lut_quads(m+15, idx);
v_float32 m4 = vx_lut_quads(_m, idx);
for( ; x <= len*4 - v_float32::nlanes; x += v_float32::nlanes )
{
v_float32 v_src = vx_load(src + x);
v_store(dst + x, v_reduce_sum4(v_src * m0, v_src * m1, v_src * m2, v_src * m3) + m4);
}
#endif
v_float32x4 _m0 = v_load(m );
v_float32x4 _m1 = v_load(m + 5);
v_float32x4 _m2 = v_load(m + 10);
v_float32x4 _m3 = v_load(m + 15);
v_float32x4 _m4(m[4], m[9], m[14], m[19]);
for( ; x < len*4; x += v_float32x4::nlanes )
{
v_float32x4 v_src = v_load(src + x);
v_store(dst + x, v_reduce_sum4(v_src * _m0, v_src * _m1, v_src * _m2, v_src * _m3) + _m4);
}
vx_cleanup();
return;
}
#endif
@@ -5,6 +5,7 @@
@CL_REMAP_ORIGIN@
#if defined __APPLE__
#define CL_SILENCE_DEPRECATION
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
@@ -47,6 +47,7 @@
#if defined(HAVE_OPENCL_STATIC)
#if defined __APPLE__
#define CL_SILENCE_DEPRECATION
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
+1 -1
View File
@@ -94,7 +94,7 @@ void* allocSingletonBuffer(size_t size) { return fastMalloc(size); }
#include <cstdlib> // std::abort
#endif
#if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __HAIKU__ || defined __Fuchsia__
#if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __HAIKU__ || defined __Fuchsia__
# include <unistd.h>
# include <fcntl.h>
# include <elf.h>
+1 -1
View File
@@ -495,7 +495,7 @@ cv::String getCacheDirectory(const char* sub_directory_name, const char* configu
if (utils::fs::isDirectory(default_cache_path))
{
cv::String default_cache_path_base = utils::fs::join(default_cache_path, "opencv");
default_cache_path = utils::fs::join(default_cache_path_base, "4.0" CV_VERSION_STATUS);
default_cache_path = utils::fs::join(default_cache_path_base, CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) CV_VERSION_STATUS);
if (utils::getConfigurationParameterBool("OPENCV_CACHE_SHOW_CLEANUP_MESSAGE", true)
&& !utils::fs::isDirectory(default_cache_path))
{
+23
View File
@@ -519,4 +519,27 @@ TEST_P(Core_EigenZero, double)
}
INSTANTIATE_TEST_CASE_P(/**/, Core_EigenZero, testing::Values(2, 3, 5));
TEST(Core_EigenNonSymmetric, convergence)
{
Matx33d m(
0, -1, 0,
1, 0, 1,
0, -1, 0);
Mat eigenvalues, eigenvectors;
// eigen values are complex, algorithm doesn't converge
try
{
cv::eigenNonSymmetric(m, eigenvalues, eigenvectors);
std::cout << Mat(eigenvalues.t()) << std::endl;
}
catch (const cv::Exception& e)
{
EXPECT_EQ(Error::StsNoConv, e.code) << e.what();
}
catch (...)
{
FAIL() << "Unknown exception has been raised";
}
}
}} // namespace
+1 -1
View File
@@ -1020,7 +1020,7 @@ static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMa
int i, j, cols;
int cn, depth, mat_depth;
CvMat astub, bstub, *a, *b;
double mat[16];
double mat[16] = {0.0};
a = cvGetMat( _src, &astub, 0, 0 );
b = cvGetMat( _dst, &bstub, 0, 0 );
+9 -1
View File
@@ -89,7 +89,15 @@ ocv_glob_module_sources(${sources_options} SOURCES ${fw_srcs})
ocv_create_module(${libs} ${INF_ENGINE_TARGET})
ocv_add_samples()
ocv_add_accuracy_tests(${INF_ENGINE_TARGET})
ocv_add_perf_tests(${INF_ENGINE_TARGET})
set(perf_path "${CMAKE_CURRENT_LIST_DIR}/perf")
file(GLOB_RECURSE perf_srcs "${perf_path}/*.cpp")
file(GLOB_RECURSE perf_hdrs "${perf_path}/*.hpp" "${perf_path}/*.h")
ocv_add_perf_tests(${INF_ENGINE_TARGET}
FILES test_common "${CMAKE_CURRENT_LIST_DIR}/test/test_common.hpp" "${CMAKE_CURRENT_LIST_DIR}/test/test_common.impl.hpp"
FILES Src ${perf_srcs}
FILES Include ${perf_hdrs}
)
ocv_option(${the_module}_PERF_CAFFE "Add performance tests of Caffe framework" OFF)
ocv_option(${the_module}_PERF_CLCAFFE "Add performance tests of clCaffe framework" OFF)
+3 -7
View File
@@ -955,13 +955,6 @@ CV__DNN_INLINE_NS_BEGIN
CV_OUT std::vector<int>& indices,
const float eta = 1.f, const int top_k = 0);
/** @brief Release a Myriad device is binded by OpenCV.
*
* Single Myriad device cannot be shared across multiple processes which uses
* Inference Engine's Myriad plugin.
*/
CV_EXPORTS_W void resetMyriadDevice();
//! @}
CV__DNN_INLINE_NS_END
}
@@ -970,4 +963,7 @@ CV__DNN_INLINE_NS_END
#include <opencv2/dnn/layer.hpp>
#include <opencv2/dnn/dnn.inl.hpp>
/// @deprecated Include this header directly from application. Automatic inclusion will be removed
#include <opencv2/dnn/utils/inference_engine.hpp>
#endif /* OPENCV_DNN_DNN_HPP */
@@ -0,0 +1,43 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#ifndef OPENCV_DNN_UTILS_INF_ENGINE_HPP
#define OPENCV_DNN_UTILS_INF_ENGINE_HPP
#include "../dnn.hpp"
namespace cv { namespace dnn {
CV__DNN_INLINE_NS_BEGIN
/** @brief Release a Myriad device (binded by OpenCV).
*
* Single Myriad device cannot be shared across multiple processes which uses
* Inference Engine's Myriad plugin.
*/
CV_EXPORTS_W void resetMyriadDevice();
/* Values for 'OPENCV_DNN_IE_VPU_TYPE' parameter */
#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_UNSPECIFIED ""
/// Intel(R) Movidius(TM) Neural Compute Stick, NCS (USB 03e7:2150), Myriad2 (https://software.intel.com/en-us/movidius-ncs)
#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2 "Myriad2"
/// Intel(R) Neural Compute Stick 2, NCS2 (USB 03e7:2485), MyriadX (https://software.intel.com/ru-ru/neural-compute-stick)
#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X "MyriadX"
/** @brief Returns Inference Engine VPU type.
*
* See values of `CV_DNN_INFERENCE_ENGINE_VPU_TYPE_*` macros.
*/
CV_EXPORTS_W cv::String getInferenceEngineVPUType();
CV__DNN_INLINE_NS_END
}} // namespace
#endif // OPENCV_DNN_UTILS_INF_ENGINE_HPP
+6
View File
@@ -0,0 +1,6 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "perf_precomp.hpp"
#include "../test/test_common.impl.hpp" // shared with accuracy tests
+9
View File
@@ -185,6 +185,11 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX");
#endif
processNet("dnn/ssd_inception_v2_coco_2017_11_17.pb", "ssd_inception_v2_coco_2017_11_17.pbtxt", "",
Mat(cv::Size(300, 300), CV_32FC3));
}
@@ -217,6 +222,10 @@ PERF_TEST_P_(DNNTestNetwork, FastNeuralStyle_eccv16)
PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled in OpenVINO 2019R1");
#endif
if (backend == DNN_BACKEND_HALIDE ||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
+10 -12
View File
@@ -253,7 +253,7 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
std::vector<Mat> images;
images_.getMatVector(images);
CV_Assert(!images.empty());
for (int i = 0; i < images.size(); i++)
for (size_t i = 0; i < images.size(); i++)
{
Size imgSize = images[i].size();
if (size == Size())
@@ -283,11 +283,10 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
images[i] *= scalefactor;
}
size_t i, nimages = images.size();
size_t nimages = images.size();
Mat image0 = images[0];
int nch = image0.channels();
CV_Assert(image0.dims == 2);
Mat image;
if (nch == 3 || nch == 4)
{
int sz[] = { (int)nimages, nch, image0.rows, image0.cols };
@@ -295,9 +294,9 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
Mat blob = blob_.getMat();
Mat ch[4];
for( i = 0; i < nimages; i++ )
for(size_t i = 0; i < nimages; i++ )
{
image = images[i];
const Mat& image = images[i];
CV_Assert(image.depth() == blob_.depth());
nch = image.channels();
CV_Assert(image.dims == 2 && (nch == 3 || nch == 4));
@@ -317,9 +316,9 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
blob_.create(4, sz, ddepth);
Mat blob = blob_.getMat();
for( i = 0; i < nimages; i++ )
for(size_t i = 0; i < nimages; i++ )
{
Mat image = images[i];
const Mat& image = images[i];
CV_Assert(image.depth() == blob_.depth());
nch = image.channels();
CV_Assert(image.dims == 2 && (nch == 1));
@@ -1700,7 +1699,7 @@ struct Net::Impl
preferableTarget == DNN_TARGET_MYRIAD ||
preferableTarget == DNN_TARGET_FPGA) && !fused)
{
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
for (const std::string& name : {"weights", "biases"})
{
auto it = ieNode->layer.getParameters().find(name);
@@ -2146,10 +2145,6 @@ struct Net::Impl
}
}
}
if (preferableBackend != DNN_BACKEND_OPENCV)
continue; // Go to the next layer.
// the optimization #2. if there is no layer that takes max pooling layer's computed
// max indices (and only some semantical segmentation networks might need this;
// many others only take the maximum values), then we switch the max pooling
@@ -2170,6 +2165,9 @@ struct Net::Impl
}
}
if (preferableBackend != DNN_BACKEND_OPENCV)
continue; // Go to the next layer.
// the optimization #3. if there is concat layer that concatenates channels
// from the inputs together (i.e. axis == 1) then we make the inputs of
// the concat layer to write to the concatenation output buffer
+1 -1
View File
@@ -676,7 +676,7 @@ public:
int inpCnAll = input.size[1], width = input.size[3], height = input.size[2];
int inpCn = inpCnAll / ngroups;
p.is1x1_ = kernel == Size(0,0) && pad == Size(0, 0);
p.is1x1_ = kernel == Size(1,1) && pad == Size(0, 0);
p.useAVX = checkHardwareSupport(CPU_AVX);
p.useAVX2 = checkHardwareSupport(CPU_AVX2);
p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX;
+1 -1
View File
@@ -92,7 +92,7 @@ public:
virtual bool supportBackend(int backendId) CV_OVERRIDE
{
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
return (bias == 1) && (preferableTarget != DNN_TARGET_MYRIAD || type == SPATIAL_NRM);
return bias == 1;
return backendId == DNN_BACKEND_OPENCV ||
backendId == DNN_BACKEND_HALIDE ||
(backendId == DNN_BACKEND_VKCOM && haveVulkan() && (size % 2 == 1) && (type == CHANNEL_NRM));
@@ -290,7 +290,7 @@ public:
weights = wrapToInfEngineBlob(blobs[0], {(size_t)numChannels}, InferenceEngine::Layout::C);
l.getParameters()["channel_shared"] = blobs[0].total() == 1;
}
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
l.getParameters()["weights"] = weights;
#else
l.addConstantData("weights", weights);
+9 -1
View File
@@ -148,10 +148,18 @@ public:
{
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
{
if (preferableTarget == DNN_TARGET_MYRIAD)
#ifdef HAVE_INF_ENGINE
if (preferableTarget == DNN_TARGET_MYRIAD) {
if (type == MAX && (pad_l == 1 && pad_t == 1) && stride == Size(2, 2) ) {
return !isMyriadX();
}
return type == MAX || type == AVE;
}
else
return type != STOCHASTIC;
#else
return false;
#endif
}
else
return backendId == DNN_BACKEND_OPENCV ||
+31
View File
@@ -591,6 +591,37 @@ void ONNXImporter::populateNet(Net dstNet)
}
layerParams.set("num_output", layerParams.blobs[0].size[1] * layerParams.get<int>("group", 1));
layerParams.set("bias_term", node_proto.input_size() == 3);
if (layerParams.has("output_shape"))
{
const DictValue& outShape = layerParams.get("output_shape");
if (outShape.size() != 4)
CV_Error(Error::StsNotImplemented, "Output shape must have 4 elements.");
const int strideY = layerParams.get<int>("stride_h", 1);
const int strideX = layerParams.get<int>("stride_w", 1);
const int outH = outShape.getIntValue(2);
const int outW = outShape.getIntValue(3);
if (layerParams.get<String>("pad_mode") == "SAME")
{
layerParams.set("adj_w", (outW - 1) % strideX);
layerParams.set("adj_h", (outH - 1) % strideY);
}
else if (layerParams.get<String>("pad_mode") == "VALID")
{
if (!layerParams.has("kernel_h") || !layerParams.has("kernel_w"))
CV_Error(Error::StsNotImplemented,
"Required attributes 'kernel_h' and 'kernel_w' are not present.");
int kernelH = layerParams.get<int>("kernel_h");
int kernelW = layerParams.get<int>("kernel_w");
layerParams.set("adj_w", (outW - kernelW) % strideX);
layerParams.set("adj_h", (outH - kernelH) % strideY);
}
}
}
else if (layer_type == "Transpose")
{
+129 -5
View File
@@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018, Intel Corporation, all rights reserved.
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "precomp.hpp"
@@ -12,8 +12,14 @@
#ifdef HAVE_INF_ENGINE
#include <ie_extension.h>
#include <ie_plugin_dispatcher.hpp>
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R5)
#include <vpu/vpu_plugin_config.hpp>
#endif
#endif // HAVE_INF_ENGINE
#include <opencv2/core/utils/configuration.private.hpp>
#include <opencv2/core/utils/logger.hpp>
namespace cv { namespace dnn {
#ifdef HAVE_INF_ENGINE
@@ -124,7 +130,7 @@ void InfEngineBackendNet::init(int targetId)
for (int id : unconnectedLayersIds)
{
InferenceEngine::Builder::OutputLayer outLayer("myconv1");
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
// Inference Engine determines network precision by ports.
InferenceEngine::Precision p = (targetId == DNN_TARGET_MYRIAD ||
targetId == DNN_TARGET_OPENCL_FP16) ?
@@ -182,7 +188,7 @@ void InfEngineBackendNet::init(int targetId)
void InfEngineBackendNet::addLayer(InferenceEngine::Builder::Layer& layer)
{
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
// Add weights to network and connect them after input blobs.
std::map<std::string, InferenceEngine::Parameter>& params = layer.getParameters();
std::vector<int> blobsIds;
@@ -223,7 +229,7 @@ void InfEngineBackendNet::addLayer(InferenceEngine::Builder::Layer& layer)
CV_Assert(layers.insert({layerName, id}).second);
unconnectedLayersIds.insert(id);
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
// By default, all the weights are connected to last ports ids.
for (int i = 0; i < blobsIds.size(); ++i)
{
@@ -683,6 +689,64 @@ static std::map<InferenceEngine::TargetDevice, InferenceEngine::InferenceEngineP
return sharedPlugins;
}
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R5) && !defined(OPENCV_DNN_IE_VPU_TYPE_DEFAULT)
static bool detectMyriadX_()
{
InferenceEngine::Builder::Network builder("");
InferenceEngine::idx_t inpId = builder.addLayer(
InferenceEngine::Builder::InputLayer().setPort(InferenceEngine::Port({1})));
#if INF_ENGINE_RELEASE <= 2018050000
InferenceEngine::idx_t clampId;
{
InferenceEngine::Builder::Layer l = InferenceEngine::Builder::ClampLayer();
auto& blobs = l.getConstantData();
auto blob = InferenceEngine::make_shared_blob<int16_t>(
InferenceEngine::Precision::FP16,
InferenceEngine::Layout::C, {1});
blob->allocate();
blobs[""] = blob;
clampId = builder.addLayer({inpId}, l);
}
builder.addLayer({InferenceEngine::PortInfo(clampId)}, InferenceEngine::Builder::OutputLayer());
#else
InferenceEngine::idx_t clampId = builder.addLayer({inpId}, InferenceEngine::Builder::ClampLayer());
builder.addLayer({InferenceEngine::PortInfo(clampId)},
InferenceEngine::Builder::OutputLayer().setPort(InferenceEngine::Port({},
InferenceEngine::Precision::FP16)));
#endif
InferenceEngine::CNNNetwork cnn = InferenceEngine::CNNNetwork(
InferenceEngine::Builder::convertToICNNNetwork(builder.build()));
InferenceEngine::TargetDevice device = InferenceEngine::TargetDevice::eMYRIAD;
InferenceEngine::InferenceEnginePluginPtr enginePtr;
{
AutoLock lock(getInitializationMutex());
auto& sharedPlugins = getSharedPlugins();
auto pluginIt = sharedPlugins.find(device);
if (pluginIt != sharedPlugins.end()) {
enginePtr = pluginIt->second;
} else {
auto dispatcher = InferenceEngine::PluginDispatcher({""});
enginePtr = dispatcher.getSuitablePlugin(device);
sharedPlugins[device] = enginePtr;
}
}
auto plugin = InferenceEngine::InferencePlugin(enginePtr);
try
{
auto netExec = plugin.LoadNetwork(cnn, {{InferenceEngine::VPUConfigParams::KEY_VPU_PLATFORM,
InferenceEngine::VPUConfigParams::VPU_2480}});
auto infRequest = netExec.CreateInferRequest();
} catch(...) {
return false;
}
return true;
}
#endif // >= 2018R5
void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net)
{
CV_Assert(!isInitialized());
@@ -720,6 +784,8 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net)
continue;
#ifdef _WIN32
std::string libName = "cpu_extension" + suffixes[i] + ".dll";
#elif defined(__APPLE__)
std::string libName = "libcpu_extension" + suffixes[i] + ".dylib";
#else
std::string libName = "libcpu_extension" + suffixes[i] + ".so";
#endif // _WIN32
@@ -784,7 +850,11 @@ bool InfEngineBackendLayer::getMemoryShapes(const std::vector<MatShape> &inputs,
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const
{
#if INF_ENGINE_VER_MAJOR_EQ(INF_ENGINE_RELEASE_2018R3)
InferenceEngine::ICNNNetwork::InputShapes inShapes = const_cast<InferenceEngine::CNNNetwork&>(t_net).getInputShapes();
#else
InferenceEngine::ICNNNetwork::InputShapes inShapes = t_net.getInputShapes();
#endif
InferenceEngine::ICNNNetwork::InputShapes::iterator itr;
bool equal_flag = true;
size_t i = 0;
@@ -835,7 +905,7 @@ InferenceEngine::Blob::Ptr convertFp16(const InferenceEngine::Blob::Ptr& blob)
void addConstantData(const std::string& name, InferenceEngine::Blob::Ptr data,
InferenceEngine::Builder::Layer& l)
{
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
l.getParameters()[name] = data;
#else
l.addConstantData(name, data);
@@ -875,5 +945,59 @@ void resetMyriadDevice()
#endif // HAVE_INF_ENGINE
}
#ifdef HAVE_INF_ENGINE
bool isMyriadX()
{
static bool myriadX = getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X;
return myriadX;
}
static std::string getInferenceEngineVPUType_()
{
static std::string param_vpu_type = utils::getConfigurationParameterString("OPENCV_DNN_IE_VPU_TYPE", "");
if (param_vpu_type == "")
{
#if defined(OPENCV_DNN_IE_VPU_TYPE_DEFAULT)
param_vpu_type = OPENCV_DNN_IE_VPU_TYPE_DEFAULT;
#elif INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R5)
CV_LOG_INFO(NULL, "OpenCV-DNN: running Inference Engine VPU autodetection: Myriad2/X. In case of other accelerator types specify 'OPENCV_DNN_IE_VPU_TYPE' parameter");
try {
bool isMyriadX_ = detectMyriadX_();
if (isMyriadX_)
{
param_vpu_type = CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X;
}
else
{
param_vpu_type = CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2;
}
}
catch (...)
{
CV_LOG_WARNING(NULL, "OpenCV-DNN: Failed Inference Engine VPU autodetection. Specify 'OPENCV_DNN_IE_VPU_TYPE' parameter.");
param_vpu_type.clear();
}
#else
CV_LOG_WARNING(NULL, "OpenCV-DNN: VPU auto-detection is not implemented. Consider specifying VPU type via 'OPENCV_DNN_IE_VPU_TYPE' parameter");
param_vpu_type = CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2;
#endif
}
CV_LOG_INFO(NULL, "OpenCV-DNN: Inference Engine VPU type='" << param_vpu_type << "'");
return param_vpu_type;
}
cv::String getInferenceEngineVPUType()
{
static cv::String vpu_type = getInferenceEngineVPUType_();
return vpu_type;
}
#else // HAVE_INF_ENGINE
cv::String getInferenceEngineVPUType()
{
CV_Error(Error::StsNotImplemented, "This OpenCV build doesn't include InferenceEngine support");
}
#endif // HAVE_INF_ENGINE
CV__DNN_INLINE_NS_END
}} // namespace dnn, namespace cv
+14 -7
View File
@@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018, Intel Corporation, all rights reserved.
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#ifndef __OPENCV_DNN_OP_INF_ENGINE_HPP__
@@ -12,6 +12,8 @@
#include "opencv2/core/cvstd.hpp"
#include "opencv2/dnn.hpp"
#include "opencv2/dnn/utils/inference_engine.hpp"
#ifdef HAVE_INF_ENGINE
#if defined(__GNUC__) && __GNUC__ >= 5
//#pragma GCC diagnostic push
@@ -25,10 +27,11 @@
#define INF_ENGINE_RELEASE_2018R3 2018030000
#define INF_ENGINE_RELEASE_2018R4 2018040000
#define INF_ENGINE_RELEASE_2018R5 2018050000
#define INF_ENGINE_RELEASE_2019R1 2019010000
#ifndef INF_ENGINE_RELEASE
#warning("IE version have not been provided via command-line. Using 2018R5 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2018R5
#warning("IE version have not been provided via command-line. Using 2019R1 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2019R1
#endif
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
@@ -114,10 +117,8 @@ public:
virtual size_t getBatchSize() const CV_NOEXCEPT CV_OVERRIDE;
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R2)
virtual InferenceEngine::StatusCode AddExtension(const InferenceEngine::IShapeInferExtensionPtr& extension, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT;
virtual InferenceEngine::StatusCode reshape(const InputShapes& inputShapes, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT;
#endif
virtual InferenceEngine::StatusCode AddExtension(const InferenceEngine::IShapeInferExtensionPtr& extension, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT CV_OVERRIDE;
virtual InferenceEngine::StatusCode reshape(const InputShapes& inputShapes, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT CV_OVERRIDE;
void init(int targetId);
@@ -279,6 +280,12 @@ private:
InferenceEngine::CNNNetwork t_net;
};
CV__DNN_INLINE_NS_BEGIN
bool isMyriadX();
CV__DNN_INLINE_NS_END
#endif // HAVE_INF_ENGINE
bool haveInfEngine();
@@ -10,6 +10,7 @@
#ifdef HAVE_PROTOBUF
#include "tf_graph_simplifier.hpp"
#include <queue>
namespace cv { namespace dnn {
CV__DNN_INLINE_NS_BEGIN
@@ -630,6 +631,21 @@ public:
}
};
class SoftMaxSlimSubgraph : public Subgraph
{
public:
SoftMaxSlimSubgraph()
{
int input = addNodeToMatch("");
int shape = addNodeToMatch("Const");
int shapeOp = addNodeToMatch("Shape", input);
int reshape = addNodeToMatch("Reshape", input, shape);
int softmax = addNodeToMatch("Softmax", reshape);
addNodeToMatch("Reshape", softmax, shapeOp);
setFusedNode("Softmax", input);
}
};
void simplifySubgraphs(tensorflow::GraphDef& net)
{
std::vector<Ptr<Subgraph> > subgraphs;
@@ -646,6 +662,7 @@ void simplifySubgraphs(tensorflow::GraphDef& net)
subgraphs.push_back(Ptr<Subgraph>(new ResizeBilinearSubgraph()));
subgraphs.push_back(Ptr<Subgraph>(new UpsamplingKerasSubgraph()));
subgraphs.push_back(Ptr<Subgraph>(new ReshapeAsShapeSubgraph()));
subgraphs.push_back(Ptr<Subgraph>(new SoftMaxSlimSubgraph()));
int numNodes = net.node_size();
std::vector<int> matchedNodesIds;
@@ -867,7 +884,6 @@ void sortByExecutionOrder(tensorflow::GraphDef& net)
nodesToAdd.pop_back();
permIds.push_back(nodeToAdd);
// std::cout << net.node(nodeToAdd).name() << '\n';
for (int i = 0; i < edges[nodeToAdd].size(); ++i)
{
@@ -886,6 +902,85 @@ void sortByExecutionOrder(tensorflow::GraphDef& net)
permute(net.mutable_node(), permIds);
}
// Remove training switches (Switch and Merge nodes and corresponding subgraphs).
void removePhaseSwitches(tensorflow::GraphDef& net)
{
std::vector<int> nodesToRemove;
std::map<std::string, int> nodesMap;
std::map<std::string, int>::iterator nodesMapIt;
std::queue<int> mergeOpSubgraphNodes;
for (int i = 0; i < net.node_size(); ++i)
{
const tensorflow::NodeDef& node = net.node(i);
nodesMap.insert(std::make_pair(node.name(), i));
if (node.op() == "Switch" || node.op() == "Merge")
{
CV_Assert(node.input_size() > 0);
// Replace consumers' inputs.
for (int j = 0; j < net.node_size(); ++j)
{
tensorflow::NodeDef* consumer = net.mutable_node(j);
for (int k = 0; k < consumer->input_size(); ++k)
{
std::string inpName = consumer->input(k);
inpName = inpName.substr(0, inpName.rfind(':'));
if (inpName == node.name())
{
consumer->set_input(k, node.input(0));
}
}
}
nodesToRemove.push_back(i);
if (node.op() == "Merge")
mergeOpSubgraphNodes.push(i);
}
}
std::vector<int> numConsumers(net.node_size(), 0);
for (int i = 0; i < net.node_size(); ++i)
{
const tensorflow::NodeDef& node = net.node(i);
for (int j = 0; j < node.input_size(); ++j)
{
std::string inpName = node.input(j);
inpName = inpName.substr(1 + (int)inpName.find('^'), inpName.rfind(':'));
nodesMapIt = nodesMap.find(inpName);
CV_Assert(nodesMapIt != nodesMap.end());
numConsumers[nodesMapIt->second] += 1;
}
}
// Remove subgraphs of unused nodes which are terminated by Merge nodes.
while (!mergeOpSubgraphNodes.empty())
{
const tensorflow::NodeDef& node = net.node(mergeOpSubgraphNodes.front());
mergeOpSubgraphNodes.pop();
for (int i = 0; i < node.input_size(); ++i)
{
std::string inpName = node.input(i);
inpName = inpName.substr(1 + (int)inpName.find('^'), inpName.rfind(':'));
nodesMapIt = nodesMap.find(inpName);
CV_Assert(nodesMapIt != nodesMap.end());
int inpNodeId = nodesMapIt->second;
if (numConsumers[inpNodeId] == 1)
{
mergeOpSubgraphNodes.push(inpNodeId);
nodesToRemove.push_back(inpNodeId);
}
else if (numConsumers[inpNodeId] > 0)
numConsumers[inpNodeId] -= 1;
}
}
std::sort(nodesToRemove.begin(), nodesToRemove.end());
for (int i = nodesToRemove.size() - 1; i >= 0; --i)
{
if (nodesToRemove[i] < net.node_size()) // Ids might be repeated.
net.mutable_node()->DeleteSubrange(nodesToRemove[i], 1);
}
}
CV__DNN_INLINE_NS_END
}} // namespace dnn, namespace cv
@@ -27,6 +27,8 @@ void releaseTensor(tensorflow::TensorProto* tensor);
void sortByExecutionOrder(tensorflow::GraphDef& net);
void removePhaseSwitches(tensorflow::GraphDef& net);
CV__DNN_INLINE_NS_END
}} // namespace dnn, namespace cv
+7 -1
View File
@@ -657,11 +657,17 @@ static int predictOutputDataLayout(const tensorflow::GraphDef& net,
void TFImporter::populateNet(Net dstNet)
{
if (!netTxt.ByteSize())
removePhaseSwitches(netBin);
RemoveIdentityOps(netBin);
RemoveIdentityOps(netTxt);
if (!netTxt.ByteSize())
{
simplifySubgraphs(netBin);
sortByExecutionOrder(netBin);
}
std::set<String> layers_to_ignore;
@@ -939,7 +945,7 @@ void TFImporter::populateNet(Net dstNet)
if (getDataLayout(name, data_layouts) == DATA_LAYOUT_UNKNOWN)
data_layouts[name] = DATA_LAYOUT_NHWC;
}
else if (type == "BiasAdd" || type == "Add" || type == "Sub")
else if (type == "BiasAdd" || type == "Add" || type == "Sub" || type=="AddN")
{
bool haveConst = false;
for(int ii = 0; !haveConst && ii < layer.input_size(); ++ii)
+66 -18
View File
@@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018, Intel Corporation, all rights reserved.
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "test_precomp.hpp"
@@ -157,21 +157,29 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe)
throw SkipTestException("");
Mat sample = imread(findDataFile("dnn/street.png", false));
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
float diffScores = (target == DNN_TARGET_OPENCL_FP16) ? 6e-3 : 0.0;
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
inp, "detection_out", "", diffScores);
float diffScores = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 1.5e-2 : 0.0;
float diffSquares = (target == DNN_TARGET_MYRIAD) ? 0.063 : 0.0;
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.252 : 0.0;
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
inp, "detection_out", "", diffScores, diffSquares, detectionConfThresh);
}
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX");
#endif
Mat sample = imread(findDataFile("dnn/street.png", false));
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 560), Scalar(127.5, 127.5, 127.5), false);
float diffScores = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.029 : 0.0;
float diffSquares = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0;
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
inp, "detection_out", "", diffScores, diffSquares);
inp, "detection_out", "", diffScores, diffSquares);
}
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
@@ -180,16 +188,22 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
throw SkipTestException("");
Mat sample = imread(findDataFile("dnn/street.png", false));
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.011 : 0.0;
float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.06 : 0.0;
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.095 : 0.0;
float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0;
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.216 : 0.2;
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt",
inp, "detection_out", "", l1, lInf);
inp, "detection_out", "", l1, lInf, detectionConfThresh);
}
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX");
#endif
Mat sample = imread(findDataFile("dnn/street.png", false));
Mat inp = blobFromImage(sample, 1.0f, Size(300, 560), Scalar(), false);
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0;
@@ -215,32 +229,54 @@ TEST_P(DNNTestNetwork, SSD_VGG16)
if (backend == DNN_BACKEND_HALIDE && target == DNN_TARGET_CPU)
throw SkipTestException("");
double scoreThreshold = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0325 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.032 : 0.0;
Mat sample = imread(findDataFile("dnn/street.png", false));
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel",
"dnn/ssd_vgg16.prototxt", inp, "detection_out", "", scoreThreshold);
"dnn/ssd_vgg16.prototxt", inp, "detection_out", "", scoreThreshold, lInf);
}
TEST_P(DNNTestNetwork, OpenPose_pose_coco)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
#endif
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0056 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.072 : 0.0;
processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt",
Size(46, 46));
Size(46, 46), "", "", l1, lInf);
}
TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
#endif
// output range: [-0.001, 0.97]
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.16 : 0.0;
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt",
Size(46, 46));
Size(46, 46), "", "", l1, lInf);
}
TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
#endif
// The same .caffemodel but modified .prototxt
// See https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/pose/poseParameters.cpp
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi_faster_4_stages.prototxt",
@@ -250,17 +286,24 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
TEST_P(DNNTestNetwork, OpenFace)
{
#if defined(INF_ENGINE_RELEASE)
#if INF_ENGINE_RELEASE == 2018050000
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
#elif INF_ENGINE_RELEASE < 2018040000
throw SkipTestException("Test is disabled for Myriad targets");
#elif INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX target");
#else
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("Test is enabled starts from OpenVINO 2018R4");
throw SkipTestException("Test has been fixed in OpenVINO 2018R4");
#endif
#endif
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "");
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0024 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.0071 : 0.0;
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "", "", l1, lInf);
}
TEST_P(DNNTestNetwork, opencv_face_detector)
@@ -275,6 +318,11 @@ TEST_P(DNNTestNetwork, opencv_face_detector)
TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
{
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX");
#endif
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
Mat sample = imread(findDataFile("dnn/street.png", false));
@@ -289,7 +337,7 @@ TEST_P(DNNTestNetwork, DenseNet_121)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
// Reference output values are in range [-3.807, 4.605]
float l1 = 0.0, lInf = 0.0;
if (target == DNN_TARGET_OPENCL_FP16)
{
@@ -297,7 +345,7 @@ TEST_P(DNNTestNetwork, DenseNet_121)
}
else if (target == DNN_TARGET_MYRIAD)
{
l1 = 6e-2; lInf = 0.27;
l1 = 0.1; lInf = 0.6;
}
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", Size(224, 224), "", "", l1, lInf);
}
+15 -8
View File
@@ -376,6 +376,7 @@ TEST(Reproducibility_GoogLeNet_fp16, Accuracy)
TEST_P(Test_Caffe_nets, Colorization)
{
checkBackend();
Mat inp = blobFromNPY(_tf("colorization_inp.npy"));
Mat ref = blobFromNPY(_tf("colorization_out.npy"));
Mat kernel = blobFromNPY(_tf("colorization_pts_in_hull.npy"));
@@ -393,8 +394,12 @@ TEST_P(Test_Caffe_nets, Colorization)
Mat out = net.forward();
// Reference output values are in range [-29.1, 69.5]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.25 : 4e-4;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 5.3 : 3e-3;
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.25 : 4e-4;
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 5.3 : 3e-3;
if (target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
{
l1 = 0.6; lInf = 15;
}
normAssert(out, ref, "", l1, lInf);
}
@@ -423,7 +428,7 @@ TEST_P(Test_Caffe_nets, DenseNet_121)
}
else if (target == DNN_TARGET_MYRIAD)
{
l1 = 0.097; lInf = 0.52;
l1 = 0.11; lInf = 0.5;
}
normAssert(out, ref, "", l1, lInf);
}
@@ -515,12 +520,14 @@ INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector,
TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
{
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE > 2018030000
|| (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("Test is disabled for DLIE OpenCL targets"); // very slow
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for Myriad targets");
#endif
)
throw SkipTestException("");
static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.949398, 99.2454, 210.141, 601.205, 462.849,
0, 7, 0.997022, 481.841, 92.3218, 722.685, 175.953,
0, 12, 0.993028, 133.221, 189.377, 350.994, 563.166);
+6
View File
@@ -0,0 +1,6 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "test_common.impl.hpp" // shared with perf tests
+65 -246
View File
@@ -1,266 +1,77 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
// 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_TEST_COMMON_HPP__
#define __OPENCV_TEST_COMMON_HPP__
#include "opencv2/dnn/utils/inference_engine.hpp"
#ifdef HAVE_OPENCL
#include "opencv2/core/ocl.hpp"
#endif
namespace cv { namespace dnn {
CV__DNN_INLINE_NS_BEGIN
static inline void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
{
switch (v) {
case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return;
case DNN_BACKEND_HALIDE: *os << "HALIDE"; return;
case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE"; return;
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
} // don't use "default:" to emit compiler warnings
*os << "DNN_BACKEND_UNKNOWN(" << (int)v << ")";
}
static inline void PrintTo(const cv::dnn::Target& v, std::ostream* os)
{
switch (v) {
case DNN_TARGET_CPU: *os << "CPU"; return;
case DNN_TARGET_OPENCL: *os << "OCL"; return;
case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return;
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
case DNN_TARGET_VULKAN: *os << "VULKAN"; return;
case DNN_TARGET_FPGA: *os << "FPGA"; return;
} // don't use "default:" to emit compiler warnings
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
}
void PrintTo(const cv::dnn::Backend& v, std::ostream* os);
void PrintTo(const cv::dnn::Target& v, std::ostream* os);
using opencv_test::tuple;
using opencv_test::get;
static inline void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os)
{
PrintTo(get<0>(v), os);
*os << "/";
PrintTo(get<1>(v), os);
}
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os);
CV__DNN_INLINE_NS_END
}} // namespace
}} // namespace cv::dnn
namespace opencv_test {
using namespace cv::dnn;
static inline const std::string &getOpenCVExtraDir()
{
return cvtest::TS::ptr()->get_data_path();
}
static inline void normAssert(cv::InputArray ref, cv::InputArray test, const char *comment = "",
double l1 = 0.00001, double lInf = 0.0001)
{
double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total();
EXPECT_LE(normL1, l1) << comment;
void normAssert(
cv::InputArray ref, cv::InputArray test, const char *comment = "",
double l1 = 0.00001, double lInf = 0.0001);
double normInf = cvtest::norm(ref, test, cv::NORM_INF);
EXPECT_LE(normInf, lInf) << comment;
}
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m);
static std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m)
{
EXPECT_EQ(m.type(), CV_32FC1);
EXPECT_EQ(m.dims, 2);
EXPECT_EQ(m.cols, 4);
std::vector<cv::Rect2d> boxes(m.rows);
for (int i = 0; i < m.rows; ++i)
{
CV_Assert(m.row(i).isContinuous());
const float* data = m.ptr<float>(i);
double l = data[0], t = data[1], r = data[2], b = data[3];
boxes[i] = cv::Rect2d(l, t, r - l, b - t);
}
return boxes;
}
static inline void normAssertDetections(const std::vector<int>& refClassIds,
const std::vector<float>& refScores,
const std::vector<cv::Rect2d>& refBoxes,
const std::vector<int>& testClassIds,
const std::vector<float>& testScores,
const std::vector<cv::Rect2d>& testBoxes,
const char *comment = "", double confThreshold = 0.0,
double scores_diff = 1e-5, double boxes_iou_diff = 1e-4)
{
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
for (int i = 0; i < testBoxes.size(); ++i)
{
double testScore = testScores[i];
if (testScore < confThreshold)
continue;
int testClassId = testClassIds[i];
const cv::Rect2d& testBox = testBoxes[i];
bool matched = false;
for (int j = 0; j < refBoxes.size() && !matched; ++j)
{
if (!matchedRefBoxes[j] && testClassId == refClassIds[j] &&
std::abs(testScore - refScores[j]) < scores_diff)
{
double interArea = (testBox & refBoxes[j]).area();
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
if (std::abs(iou - 1.0) < boxes_iou_diff)
{
matched = true;
matchedRefBoxes[j] = true;
}
}
}
if (!matched)
std::cout << cv::format("Unmatched prediction: class %d score %f box ",
testClassId, testScore) << testBox << std::endl;
EXPECT_TRUE(matched) << comment;
}
// Check unmatched reference detections.
for (int i = 0; i < refBoxes.size(); ++i)
{
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
{
std::cout << cv::format("Unmatched reference: class %d score %f box ",
refClassIds[i], refScores[i]) << refBoxes[i] << std::endl;
EXPECT_LE(refScores[i], confThreshold) << comment;
}
}
}
void normAssertDetections(
const std::vector<int>& refClassIds,
const std::vector<float>& refScores,
const std::vector<cv::Rect2d>& refBoxes,
const std::vector<int>& testClassIds,
const std::vector<float>& testScores,
const std::vector<cv::Rect2d>& testBoxes,
const char *comment = "", double confThreshold = 0.0,
double scores_diff = 1e-5, double boxes_iou_diff = 1e-4);
// For SSD-based object detection networks which produce output of shape 1x1xNx7
// where N is a number of detections and an every detection is represented by
// a vector [batchId, classId, confidence, left, top, right, bottom].
static inline void normAssertDetections(cv::Mat ref, cv::Mat out, const char *comment = "",
double confThreshold = 0.0, double scores_diff = 1e-5,
double boxes_iou_diff = 1e-4)
{
CV_Assert(ref.total() % 7 == 0);
CV_Assert(out.total() % 7 == 0);
ref = ref.reshape(1, ref.total() / 7);
out = out.reshape(1, out.total() / 7);
void normAssertDetections(
cv::Mat ref, cv::Mat out, const char *comment = "",
double confThreshold = 0.0, double scores_diff = 1e-5,
double boxes_iou_diff = 1e-4);
cv::Mat refClassIds, testClassIds;
ref.col(1).convertTo(refClassIds, CV_32SC1);
out.col(1).convertTo(testClassIds, CV_32SC1);
std::vector<float> refScores(ref.col(2)), testScores(out.col(2));
std::vector<cv::Rect2d> refBoxes = matToBoxes(ref.colRange(3, 7));
std::vector<cv::Rect2d> testBoxes = matToBoxes(out.colRange(3, 7));
normAssertDetections(refClassIds, refScores, refBoxes, testClassIds, testScores,
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
}
bool readFileInMemory(const std::string& filename, std::string& content);
static inline bool readFileInMemory(const std::string& filename, std::string& content)
{
std::ios::openmode mode = std::ios::in | std::ios::binary;
std::ifstream ifs(filename.c_str(), mode);
if (!ifs.is_open())
return false;
#ifdef HAVE_INF_ENGINE
bool validateVPUType();
#endif
content.clear();
ifs.seekg(0, std::ios::end);
content.reserve(ifs.tellg());
ifs.seekg(0, std::ios::beg);
content.assign((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
return true;
}
namespace opencv_test {
using namespace cv::dnn;
static inline
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
bool withInferenceEngine = true,
bool withHalide = false,
bool withCpuOCV = true,
bool withVkCom = true
)
{
std::vector< tuple<Backend, Target> > targets;
std::vector< Target > available;
if (withHalide)
{
available = getAvailableTargets(DNN_BACKEND_HALIDE);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
}
if (withInferenceEngine)
{
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, *i));
}
if (withVkCom)
{
available = getAvailableTargets(DNN_BACKEND_VKCOM);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_VKCOM, *i));
}
{
available = getAvailableTargets(DNN_BACKEND_OPENCV);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
{
if (!withCpuOCV && *i == DNN_TARGET_CPU)
continue;
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
}
}
if (targets.empty()) // validate at least CPU mode
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
return testing::ValuesIn(targets);
}
);
} // namespace
namespace opencv_test {
using namespace cv::dnn;
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
{
@@ -276,29 +87,29 @@ public:
getDefaultThresholds(backend, target, &default_l1, &default_lInf);
}
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
{
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
{
*l1 = 4e-3;
*lInf = 2e-2;
}
else
{
*l1 = 1e-5;
*lInf = 1e-4;
}
}
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
{
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
{
*l1 = 4e-3;
*lInf = 2e-2;
}
else
{
*l1 = 1e-5;
*lInf = 1e-4;
}
}
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
inp->size[0] != 1 && inp->size[0] != ref->size[0])
throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
}
}
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
inp->size[0] != 1 && inp->size[0] != ref->size[0])
throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
}
}
protected:
void checkBackend(Mat* inp = 0, Mat* ref = 0)
@@ -309,4 +120,12 @@ protected:
} // namespace
// src/op_inf_engine.hpp
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_GE(ver) (((INF_ENGINE_RELEASE) / 10000) >= ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_LT(ver) (((INF_ENGINE_RELEASE) / 10000) < ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_LE(ver) (((INF_ENGINE_RELEASE) / 10000) <= ((ver) / 10000))
#define INF_ENGINE_VER_MAJOR_EQ(ver) (((INF_ENGINE_RELEASE) / 10000) == ((ver) / 10000))
#endif
+294
View File
@@ -0,0 +1,294 @@
// 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.
// Used in accuracy and perf tests as a content of .cpp file
// Note: don't use "precomp.hpp" here
#include "opencv2/ts.hpp"
#include "opencv2/ts/ts_perf.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/dnn.hpp"
#include "test_common.hpp"
#include <opencv2/core/utils/configuration.private.hpp>
#include <opencv2/core/utils/logger.hpp>
namespace cv { namespace dnn {
CV__DNN_INLINE_NS_BEGIN
void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
{
switch (v) {
case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return;
case DNN_BACKEND_HALIDE: *os << "HALIDE"; return;
case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE"; return;
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
} // don't use "default:" to emit compiler warnings
*os << "DNN_BACKEND_UNKNOWN(" << (int)v << ")";
}
void PrintTo(const cv::dnn::Target& v, std::ostream* os)
{
switch (v) {
case DNN_TARGET_CPU: *os << "CPU"; return;
case DNN_TARGET_OPENCL: *os << "OCL"; return;
case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return;
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
case DNN_TARGET_VULKAN: *os << "VULKAN"; return;
case DNN_TARGET_FPGA: *os << "FPGA"; return;
} // don't use "default:" to emit compiler warnings
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
}
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os)
{
PrintTo(get<0>(v), os);
*os << "/";
PrintTo(get<1>(v), os);
}
CV__DNN_INLINE_NS_END
}} // namespace
namespace opencv_test {
void normAssert(
cv::InputArray ref, cv::InputArray test, const char *comment /*= ""*/,
double l1 /*= 0.00001*/, double lInf /*= 0.0001*/)
{
double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total();
EXPECT_LE(normL1, l1) << comment;
double normInf = cvtest::norm(ref, test, cv::NORM_INF);
EXPECT_LE(normInf, lInf) << comment;
}
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m)
{
EXPECT_EQ(m.type(), CV_32FC1);
EXPECT_EQ(m.dims, 2);
EXPECT_EQ(m.cols, 4);
std::vector<cv::Rect2d> boxes(m.rows);
for (int i = 0; i < m.rows; ++i)
{
CV_Assert(m.row(i).isContinuous());
const float* data = m.ptr<float>(i);
double l = data[0], t = data[1], r = data[2], b = data[3];
boxes[i] = cv::Rect2d(l, t, r - l, b - t);
}
return boxes;
}
void normAssertDetections(
const std::vector<int>& refClassIds,
const std::vector<float>& refScores,
const std::vector<cv::Rect2d>& refBoxes,
const std::vector<int>& testClassIds,
const std::vector<float>& testScores,
const std::vector<cv::Rect2d>& testBoxes,
const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
{
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
for (int i = 0; i < testBoxes.size(); ++i)
{
double testScore = testScores[i];
if (testScore < confThreshold)
continue;
int testClassId = testClassIds[i];
const cv::Rect2d& testBox = testBoxes[i];
bool matched = false;
for (int j = 0; j < refBoxes.size() && !matched; ++j)
{
if (!matchedRefBoxes[j] && testClassId == refClassIds[j] &&
std::abs(testScore - refScores[j]) < scores_diff)
{
double interArea = (testBox & refBoxes[j]).area();
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
if (std::abs(iou - 1.0) < boxes_iou_diff)
{
matched = true;
matchedRefBoxes[j] = true;
}
}
}
if (!matched)
std::cout << cv::format("Unmatched prediction: class %d score %f box ",
testClassId, testScore) << testBox << std::endl;
EXPECT_TRUE(matched) << comment;
}
// Check unmatched reference detections.
for (int i = 0; i < refBoxes.size(); ++i)
{
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
{
std::cout << cv::format("Unmatched reference: class %d score %f box ",
refClassIds[i], refScores[i]) << refBoxes[i] << std::endl;
EXPECT_LE(refScores[i], confThreshold) << comment;
}
}
}
// For SSD-based object detection networks which produce output of shape 1x1xNx7
// where N is a number of detections and an every detection is represented by
// a vector [batchId, classId, confidence, left, top, right, bottom].
void normAssertDetections(
cv::Mat ref, cv::Mat out, const char *comment /*= ""*/,
double confThreshold /*= 0.0*/, double scores_diff /*= 1e-5*/,
double boxes_iou_diff /*= 1e-4*/)
{
CV_Assert(ref.total() % 7 == 0);
CV_Assert(out.total() % 7 == 0);
ref = ref.reshape(1, ref.total() / 7);
out = out.reshape(1, out.total() / 7);
cv::Mat refClassIds, testClassIds;
ref.col(1).convertTo(refClassIds, CV_32SC1);
out.col(1).convertTo(testClassIds, CV_32SC1);
std::vector<float> refScores(ref.col(2)), testScores(out.col(2));
std::vector<cv::Rect2d> refBoxes = matToBoxes(ref.colRange(3, 7));
std::vector<cv::Rect2d> testBoxes = matToBoxes(out.colRange(3, 7));
normAssertDetections(refClassIds, refScores, refBoxes, testClassIds, testScores,
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
}
bool readFileInMemory(const std::string& filename, std::string& content)
{
std::ios::openmode mode = std::ios::in | std::ios::binary;
std::ifstream ifs(filename.c_str(), mode);
if (!ifs.is_open())
return false;
content.clear();
ifs.seekg(0, std::ios::end);
content.reserve(ifs.tellg());
ifs.seekg(0, std::ios::beg);
content.assign((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
return true;
}
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
bool withInferenceEngine /*= true*/,
bool withHalide /*= false*/,
bool withCpuOCV /*= true*/,
bool withVkCom /*= true*/
)
{
#ifdef HAVE_INF_ENGINE
bool withVPU = validateVPUType();
#endif
std::vector< tuple<Backend, Target> > targets;
std::vector< Target > available;
if (withHalide)
{
available = getAvailableTargets(DNN_BACKEND_HALIDE);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
}
#ifdef HAVE_INF_ENGINE
if (withInferenceEngine)
{
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
{
if (*i == DNN_TARGET_MYRIAD && !withVPU)
continue;
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, *i));
}
}
#else
CV_UNUSED(withInferenceEngine);
#endif
if (withVkCom)
{
available = getAvailableTargets(DNN_BACKEND_VKCOM);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
targets.push_back(make_tuple(DNN_BACKEND_VKCOM, *i));
}
{
available = getAvailableTargets(DNN_BACKEND_OPENCV);
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
{
if (!withCpuOCV && *i == DNN_TARGET_CPU)
continue;
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
}
}
if (targets.empty()) // validate at least CPU mode
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
return testing::ValuesIn(targets);
}
#ifdef HAVE_INF_ENGINE
static std::string getTestInferenceEngineVPUType()
{
static std::string param_vpu_type = utils::getConfigurationParameterString("OPENCV_TEST_DNN_IE_VPU_TYPE", "");
return param_vpu_type;
}
static bool validateVPUType_()
{
std::string test_vpu_type = getTestInferenceEngineVPUType();
if (test_vpu_type == "DISABLED" || test_vpu_type == "disabled")
{
return false;
}
std::vector<Target> available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
bool have_vpu_target = false;
for (std::vector<Target>::const_iterator i = available.begin(); i != available.end(); ++i)
{
if (*i == DNN_TARGET_MYRIAD)
{
have_vpu_target = true;
break;
}
}
if (test_vpu_type.empty())
{
if (have_vpu_target)
{
CV_LOG_INFO(NULL, "OpenCV-DNN-Test: VPU type for testing is not specified via 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter.")
}
}
else
{
if (!have_vpu_target)
{
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter requires VPU of type = '" << test_vpu_type << "', but VPU is not detected. STOP.");
exit(1);
}
std::string dnn_vpu_type = getInferenceEngineVPUType();
if (dnn_vpu_type != test_vpu_type)
{
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'testing' and 'detected' VPU types mismatch: '" << test_vpu_type << "' vs '" << dnn_vpu_type << "'. STOP.");
exit(1);
}
}
return true;
}
bool validateVPUType()
{
static bool result = validateVPUType_();
return result;
}
#endif // HAVE_INF_ENGINE
} // namespace
+47 -12
View File
@@ -267,6 +267,16 @@ public:
TEST_P(Test_Darknet_nets, YoloVoc)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("Test is disabled");
#endif
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX (need to update check function)");
#endif
// batchId, classId, confidence, left, top, right, bottom
Mat ref = (Mat_<float>(6, 7) << 0, 6, 0.750469f, 0.577374f, 0.127391f, 0.902949f, 0.300809f, // a car
0, 1, 0.780879f, 0.270762f, 0.264102f, 0.732475f, 0.745412f, // a bicycle
@@ -282,15 +292,24 @@ TEST_P(Test_Darknet_nets, YoloVoc)
std::string config_file = "yolo-voc.cfg";
std::string weights_file = "yolo-voc.weights";
// batch size 1
{
SCOPED_TRACE("batch size 1");
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
}
// batch size 2
{
SCOPED_TRACE("batch size 2");
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, nmsThreshold);
}
}
TEST_P(Test_Darknet_nets, TinyYoloVoc)
{
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX (need to update check function)");
#endif
// batchId, classId, confidence, left, top, right, bottom
Mat ref = (Mat_<float>(4, 7) << 0, 6, 0.761967f, 0.579042f, 0.159161f, 0.894482f, 0.31994f, // a car
0, 11, 0.780595f, 0.129696f, 0.386467f, 0.445275f, 0.920994f, // a dog
@@ -303,18 +322,29 @@ TEST_P(Test_Darknet_nets, TinyYoloVoc)
std::string config_file = "tiny-yolo-voc.cfg";
std::string weights_file = "tiny-yolo-voc.weights";
// batch size 1
{
SCOPED_TRACE("batch size 1");
testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), scoreDiff, iouDiff);
}
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018040000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_MYRIAD)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018040000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test with 'batch size 2' is disabled for Myriad target (fixed in 2018R5)");
#endif
// batch size 2
{
SCOPED_TRACE("batch size 2");
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
}
}
TEST_P(Test_Darknet_nets, YOLOv3)
{
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX");
#endif
// batchId, classId, confidence, left, top, right, bottom
Mat ref = (Mat_<float>(9, 7) << 0, 7, 0.952983f, 0.614622f, 0.150257f, 0.901369f, 0.289251f, // a truck
0, 1, 0.987908f, 0.150913f, 0.221933f, 0.742255f, 0.74626f, // a bicycle
@@ -332,13 +362,18 @@ TEST_P(Test_Darknet_nets, YOLOv3)
std::string config_file = "yolov3.cfg";
std::string weights_file = "yolov3.weights";
// batch size 1
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
if ((backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_MYRIAD) &&
(backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_OPENCL))
{
// batch size 2
SCOPED_TRACE("batch size 1");
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
}
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
throw SkipTestException("Test with 'batch size 2' is disabled for DLIE/OpenCL target");
#endif
{
SCOPED_TRACE("batch size 2");
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
}
}
+91 -10
View File
@@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
// This tests doesn't require any external data. They just compare outputs of
@@ -158,15 +158,26 @@ TEST_P(Deconvolution, Accuracy)
bool hasBias = get<6>(GetParam());
Backend backendId = get<0>(get<7>(GetParam()));
Target targetId = get<1>(get<7>(GetParam()));
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && (targetId == DNN_TARGET_CPU || targetId == DNN_TARGET_MYRIAD) &&
dilation.width == 2 && dilation.height == 2)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018040000
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU &&
hasBias && group != 1)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018040000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU
&& hasBias && group != 1)
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
&& inChannels == 6 && outChannels == 4 && group == 1
&& kernel == Size(1, 3) && pad == Size(1, 0)
&& stride == Size(1, 1) && dilation == Size(1, 1))
throw SkipTestException("Test is disabled");
#endif
int sz[] = {inChannels, outChannels / group, kernel.height, kernel.width};
Mat weights(4, &sz[0], CV_32F);
randu(weights, -1.0f, 1.0f);
@@ -228,6 +239,10 @@ TEST_P(LRN, Accuracy)
Backend backendId = get<0>(get<5>(GetParam()));
Target targetId = get<1>(get<5>(GetParam()));
if ((inSize.width == 5 || inSize.height == 5) && targetId == DNN_TARGET_MYRIAD &&
nrmType == "ACROSS_CHANNELS")
throw SkipTestException("This test case is disabled");
LayerParams lp;
lp.set("norm_region", nrmType);
lp.set("local_size", localSize);
@@ -266,10 +281,18 @@ TEST_P(AvePooling, Accuracy)
Size stride = get<3>(GetParam());
Backend backendId = get<0>(get<4>(GetParam()));
Target targetId = get<1>(get<4>(GetParam()));
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018040000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2018050000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
&& kernel == Size(1, 1) && (stride == Size(1, 1) || stride == Size(2, 2)))
throw SkipTestException("Test is disabled for MyriadX target");
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2018040000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD &&
stride == Size(3, 2) && kernel == Size(3, 3) && outSize != Size(1, 1))
throw SkipTestException("Test is enabled starts from OpenVINO 2018R4");
throw SkipTestException("Test is fixed in OpenVINO 2018R4");
#endif
const int inWidth = (outSize.width - 1) * stride.width + kernel.width;
@@ -311,6 +334,32 @@ TEST_P(MaxPooling, Accuracy)
Backend backendId = get<0>(get<5>(GetParam()));
Target targetId = get<1>(get<5>(GetParam()));
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
&& inSize == Size(7, 6) && kernel == Size(3, 2)
&& (stride == Size(1, 1) || stride == Size(2, 2))
&& (pad == Size(0, 1) || pad == Size(1, 1))
)
throw SkipTestException("Test is disabled in OpenVINO <= 2018R5");
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
&& (kernel == Size(2, 2) || kernel == Size(3, 2))
&& stride == Size(1, 1) && (pad == Size(0, 0) || pad == Size(0, 1))
)
throw SkipTestException("Problems with output dimension in OpenVINO 2018R5");
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
&& (stride == Size(1, 1) || stride == Size(2, 2))
&& (pad == Size(0, 1) || pad == Size(1, 1))
)
throw SkipTestException("Test is disabled for MyriadX target");
#endif
LayerParams lp;
lp.set("pool", "max");
lp.set("kernel_w", kernel.width);
@@ -512,6 +561,12 @@ TEST_P(ReLU, Accuracy)
float negativeSlope = get<0>(GetParam());
Backend backendId = get<0>(get<1>(GetParam()));
Target targetId = get<1>(get<1>(GetParam()));
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE
&& negativeSlope < 0
)
throw SkipTestException("Test is disabled");
#endif
LayerParams lp;
lp.set("negative_slope", negativeSlope);
@@ -534,6 +589,13 @@ TEST_P(NoParamActivation, Accuracy)
LayerParams lp;
lp.type = get<0>(GetParam());
lp.name = "testLayer";
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE
&& lp.type == "AbsVal"
)
throw SkipTestException("Test is disabled");
#endif
testInPlaceActivation(lp, backendId, targetId);
}
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, NoParamActivation, Combine(
@@ -619,6 +681,20 @@ TEST_P(Concat, Accuracy)
Backend backendId = get<0>(get<2>(GetParam()));
Target targetId = get<1>(get<2>(GetParam()));
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
&& inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
)
throw SkipTestException("Test is disabled for Myriad target"); // crash
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU
&& inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
)
throw SkipTestException("Test is disabled for DLIE/CPU target");
#endif
Net net;
std::vector<int> convLayerIds;
@@ -687,10 +763,15 @@ TEST_P(Eltwise, Accuracy)
Backend backendId = get<0>(get<4>(GetParam()));
Target targetId = get<1>(get<4>(GetParam()));
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE > 2018050000
if (backendId == DNN_BACKEND_INFERENCE_ENGINE &&
(targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD &&
inSize == Vec3i(1, 4, 5))
throw SkipTestException("Test is disabled for Myriad target");
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && numConv > 1)
throw SkipTestException("Test is disabled for DLIE backend");
#endif
Net net;
+97 -59
View File
@@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018, Intel Corporation, all rights reserved.
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "test_precomp.hpp"
@@ -21,9 +21,18 @@ static void initDLDTDataPath()
static bool initialized = false;
if (!initialized)
{
#if INF_ENGINE_RELEASE <= 2018050000
const char* dldtTestDataPath = getenv("INTEL_CVSDK_DIR");
if (dldtTestDataPath)
cvtest::addDataSearchPath(cv::utils::fs::join(dldtTestDataPath, "deployment_tools"));
cvtest::addDataSearchPath(dldtTestDataPath);
#else
const char* omzDataPath = getenv("OPENCV_OPEN_MODEL_ZOO_DATA_PATH");
if (omzDataPath)
cvtest::addDataSearchPath(omzDataPath);
const char* dnnDataPath = getenv("OPENCV_DNN_TEST_DATA_PATH");
if (dnnDataPath)
cvtest::addDataSearchPath(std::string(dnnDataPath) + "/omz_intel_models");
#endif
initialized = true;
}
#endif
@@ -33,6 +42,76 @@ using namespace cv;
using namespace cv::dnn;
using namespace InferenceEngine;
struct OpenVINOModelTestCaseInfo
{
const char* modelPathFP32;
const char* modelPathFP16;
};
static const std::map<std::string, OpenVINOModelTestCaseInfo>& getOpenVINOTestModels()
{
static std::map<std::string, OpenVINOModelTestCaseInfo> g_models {
#if INF_ENGINE_RELEASE <= 2018050000
{ "age-gender-recognition-retail-0013", {
"deployment_tools/intel_models/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013",
"deployment_tools/intel_models/age-gender-recognition-retail-0013/FP16/age-gender-recognition-retail-0013"
}},
{ "face-person-detection-retail-0002", {
"deployment_tools/intel_models/face-person-detection-retail-0002/FP32/face-person-detection-retail-0002",
"deployment_tools/intel_models/face-person-detection-retail-0002/FP16/face-person-detection-retail-0002"
}},
{ "head-pose-estimation-adas-0001", {
"deployment_tools/intel_models/head-pose-estimation-adas-0001/FP32/head-pose-estimation-adas-0001",
"deployment_tools/intel_models/head-pose-estimation-adas-0001/FP16/head-pose-estimation-adas-0001"
}},
{ "person-detection-retail-0002", {
"deployment_tools/intel_models/person-detection-retail-0002/FP32/person-detection-retail-0002",
"deployment_tools/intel_models/person-detection-retail-0002/FP16/person-detection-retail-0002"
}},
{ "vehicle-detection-adas-0002", {
"deployment_tools/intel_models/vehicle-detection-adas-0002/FP32/vehicle-detection-adas-0002",
"deployment_tools/intel_models/vehicle-detection-adas-0002/FP16/vehicle-detection-adas-0002"
}}
#else
// layout is defined by open_model_zoo/model_downloader
// Downloaded using these parameters for Open Model Zoo downloader (2019R1):
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
// --name face-person-detection-retail-0002,face-person-detection-retail-0002-fp16,age-gender-recognition-retail-0013,age-gender-recognition-retail-0013-fp16,head-pose-estimation-adas-0001,head-pose-estimation-adas-0001-fp16,person-detection-retail-0002,person-detection-retail-0002-fp16,vehicle-detection-adas-0002,vehicle-detection-adas-0002-fp16
{ "age-gender-recognition-retail-0013", {
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013",
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013-fp16"
}},
{ "face-person-detection-retail-0002", {
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002",
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002-fp16"
}},
{ "head-pose-estimation-adas-0001", {
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001",
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001-fp16"
}},
{ "person-detection-retail-0002", {
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002",
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002-fp16"
}},
{ "vehicle-detection-adas-0002", {
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002",
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002-fp16"
}}
#endif
};
return g_models;
}
static const std::vector<std::string> getOpenVINOTestModelsList()
{
std::vector<std::string> result;
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
for (const auto& it : models)
result.push_back(it.first);
return result;
}
static inline void genData(const std::vector<size_t>& dims, Mat& m, Blob::Ptr& dataPtr)
{
std::vector<int> reversedDims(dims.begin(), dims.end());
@@ -93,6 +172,8 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
continue;
#ifdef _WIN32
std::string libName = "cpu_extension" + suffixes[i] + ".dll";
#elif defined(__APPLE__)
std::string libName = "libcpu_extension" + suffixes[i] + ".dylib";
#else
std::string libName = "libcpu_extension" + suffixes[i] + ".so";
#endif // _WIN32
@@ -172,41 +253,23 @@ void runCV(Target target, const std::string& xmlPath, const std::string& binPath
}
}
typedef TestWithParam<tuple<Target, String> > DNNTestOpenVINO;
typedef TestWithParam<tuple<Target, std::string> > DNNTestOpenVINO;
TEST_P(DNNTestOpenVINO, models)
{
initDLDTDataPath();
Target target = (dnn::Target)(int)get<0>(GetParam());
std::string modelName = get<1>(GetParam());
bool isFP16 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD);
#ifdef INF_ENGINE_RELEASE
#if INF_ENGINE_RELEASE <= 2018030000
if (target == DNN_TARGET_MYRIAD && (modelName == "landmarks-regression-retail-0001" ||
modelName == "semantic-segmentation-adas-0001" ||
modelName == "face-reidentification-retail-0001"))
throw SkipTestException("");
#elif INF_ENGINE_RELEASE == 2018040000
if (modelName == "single-image-super-resolution-0034" ||
(target == DNN_TARGET_MYRIAD && (modelName == "license-plate-recognition-barrier-0001" ||
modelName == "landmarks-regression-retail-0009" ||
modelName == "semantic-segmentation-adas-0001")))
throw SkipTestException("");
#elif INF_ENGINE_RELEASE == 2018050000
if (modelName == "single-image-super-resolution-0063" ||
modelName == "single-image-super-resolution-1011" ||
modelName == "single-image-super-resolution-1021" ||
(target == DNN_TARGET_OPENCL_FP16 && modelName == "face-reidentification-retail-0095") ||
(target == DNN_TARGET_MYRIAD && (modelName == "license-plate-recognition-barrier-0001" ||
modelName == "semantic-segmentation-adas-0001")))
throw SkipTestException("");
#endif
#endif
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
const auto it = models.find(modelName);
ASSERT_TRUE(it != models.end()) << modelName;
OpenVINOModelTestCaseInfo modelInfo = it->second;
std::string modelPath = isFP16 ? modelInfo.modelPathFP16 : modelInfo.modelPathFP32;
std::string precision = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? "FP16" : "FP32";
std::string prefix = utils::fs::join("intel_models",
utils::fs::join(modelName,
utils::fs::join(precision, modelName)));
std::string xmlPath = findDataFile(prefix + ".xml");
std::string binPath = findDataFile(prefix + ".bin");
std::string xmlPath = findDataFile(modelPath + ".xml");
std::string binPath = findDataFile(modelPath + ".bin");
std::map<std::string, cv::Mat> inputsMap;
std::map<std::string, cv::Mat> ieOutputsMap, cvOutputsMap;
@@ -226,37 +289,12 @@ TEST_P(DNNTestOpenVINO, models)
}
}
static testing::internal::ParamGenerator<String> intelModels()
{
initDLDTDataPath();
std::vector<String> modelsNames;
std::string path;
try
{
path = findDataDirectory("intel_models", false);
}
catch (...)
{
std::cerr << "ERROR: Can't find OpenVINO models. Check INTEL_CVSDK_DIR environment variable (run setup.sh)" << std::endl;
return ValuesIn(modelsNames); // empty list
}
cv::utils::fs::glob_relative(path, "", modelsNames, false, true);
modelsNames.erase(
std::remove_if(modelsNames.begin(), modelsNames.end(),
[&](const String& dir){ return !utils::fs::isDirectory(utils::fs::join(path, dir)); }),
modelsNames.end()
);
CV_Assert(!modelsNames.empty());
return ValuesIn(modelsNames);
}
INSTANTIATE_TEST_CASE_P(/**/,
DNNTestOpenVINO,
Combine(testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)), intelModels())
Combine(testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)),
testing::ValuesIn(getOpenVINOTestModelsList())
)
);
}}
+23 -10
View File
@@ -236,9 +236,9 @@ TEST_P(Test_Caffe_layers, Dropout)
TEST_P(Test_Caffe_layers, Concat)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE > 2018050000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
throw SkipTestException("Test is disabled for Myriad targets");
#endif
testLayerUsingCaffeModels("layer_concat");
testLayerUsingCaffeModels("layer_concat_optim", true, false);
@@ -247,14 +247,19 @@ TEST_P(Test_Caffe_layers, Concat)
TEST_P(Test_Caffe_layers, Fused_Concat)
{
#if defined(INF_ENGINE_RELEASE)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
{
if (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16 ||
(INF_ENGINE_RELEASE < 2018040000 && target == DNN_TARGET_CPU))
throw SkipTestException("");
}
throw SkipTestException("Test is disabled for DLIE due negative_slope parameter");
#endif
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE
&& (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16
|| (INF_ENGINE_RELEASE < 2018040000 && target == DNN_TARGET_CPU))
)
throw SkipTestException("Test is disabled for DLIE");
#endif
checkBackend();
// Test case
@@ -312,7 +317,10 @@ TEST_P(Test_Caffe_layers, layer_prelu_fc)
{
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("");
testLayerUsingCaffeModels("layer_prelu_fc", true, false);
// Reference output values are in range [-0.0001, 10.3906]
double l1 = (target == DNN_TARGET_MYRIAD) ? 0.005 : 0.0;
double lInf = (target == DNN_TARGET_MYRIAD) ? 0.021 : 0.0;
testLayerUsingCaffeModels("layer_prelu_fc", true, false, l1, lInf);
}
//template<typename XMat>
@@ -358,6 +366,11 @@ TEST_P(Test_Caffe_layers, Reshape_Split_Slice)
TEST_P(Test_Caffe_layers, Conv_Elu)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE <= 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
#endif
Net net = readNetFromTensorflow(_tf("layer_elu_model.pb"));
ASSERT_FALSE(net.empty());
@@ -938,7 +951,7 @@ TEST_P(Layer_Test_Convolution_DLDT, Accuracy)
Mat out = net.forward();
double l1 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 1.4e-3 : 1e-5;
double l1 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 1.5e-3 : 1e-5;
double lInf = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 1.8e-2 : 1e-4;
normAssert(outDefault, out, "", l1, lInf);
+90 -71
View File
@@ -2,14 +2,13 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2018, Intel Corporation, all rights reserved.
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "test_precomp.hpp"
#include "npy_blob.hpp"
#include <opencv2/dnn/shape_utils.hpp>
namespace opencv_test { namespace {
template<typename TString>
@@ -28,7 +27,8 @@ public:
pb
};
void testONNXModels(const String& basename, const Extension ext = npy, const double l1 = 0, const float lInf = 0)
void testONNXModels(const String& basename, const Extension ext = npy,
const double l1 = 0, const float lInf = 0, const bool useSoftmax = false)
{
String onnxmodel = _tf("models/" + basename + ".onnx");
Mat inp, ref;
@@ -51,7 +51,21 @@ public:
net.setPreferableTarget(target);
net.setInput(inp);
Mat out = net.forward();
Mat out = net.forward("");
if (useSoftmax)
{
LayerParams lp;
Net netSoftmax;
netSoftmax.addLayerToPrev("softmaxLayer", "SoftMax", lp);
netSoftmax.setPreferableBackend(DNN_BACKEND_OPENCV);
netSoftmax.setInput(out);
out = netSoftmax.forward();
netSoftmax.setInput(ref);
ref = netSoftmax.forward();
}
normAssert(ref, out, "", l1 ? l1 : default_l1, lInf ? lInf : default_lInf);
}
};
@@ -65,6 +79,18 @@ TEST_P(Test_ONNX_layers, MaxPooling)
TEST_P(Test_ONNX_layers, Convolution)
{
testONNXModels("convolution");
}
TEST_P(Test_ONNX_layers, Two_convolution)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX"); // 2018R5+ is failed
#endif
// Reference output values are in range [-0.855, 0.611]
testONNXModels("two_convolution");
}
@@ -73,6 +99,7 @@ TEST_P(Test_ONNX_layers, Deconvolution)
testONNXModels("deconvolution");
testONNXModels("two_deconvolution");
testONNXModels("deconvolution_group");
testONNXModels("deconvolution_output_shape");
}
TEST_P(Test_ONNX_layers, Dropout)
@@ -133,6 +160,11 @@ TEST_P(Test_ONNX_layers, Multiplication)
TEST_P(Test_ONNX_layers, Constant)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
#endif
testONNXModels("constant");
}
@@ -243,7 +275,8 @@ TEST_P(Test_ONNX_nets, CaffeNet)
TEST_P(Test_ONNX_nets, RCNN_ILSVRC13)
{
testONNXModels("rcnn_ilsvrc13", pb);
// Reference output values are in range [-4.992, -1.161]
testONNXModels("rcnn_ilsvrc13", pb, 0.0045);
}
#ifdef OPENCV_32BIT_CONFIGURATION
@@ -252,21 +285,8 @@ TEST_P(Test_ONNX_nets, DISABLED_VGG16) // memory usage >2Gb
TEST_P(Test_ONNX_nets, VGG16)
#endif
{
double l1 = default_l1;
double lInf = default_lInf;
// output range: [-69; 72]
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) {
l1 = 0.087;
lInf = 0.585;
}
else if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL) {
lInf = 1.2e-4;
}
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
l1 = 0.131;
#endif
testONNXModels("vgg16", pb, l1, lInf);
// output range: [-69; 72], after Softmax [0; 0.96]
testONNXModels("vgg16", pb, default_l1, default_lInf, true);
}
#ifdef OPENCV_32BIT_CONFIGURATION
@@ -275,19 +295,9 @@ TEST_P(Test_ONNX_nets, DISABLED_VGG16_bn) // memory usage >2Gb
TEST_P(Test_ONNX_nets, VGG16_bn)
#endif
{
double l1 = default_l1;
double lInf = default_lInf;
// output range: [-16; 27]
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) {
l1 = 0.0086;
lInf = 0.037;
}
else if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
(target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)) {
l1 = 0.031;
lInf = 0.2;
}
testONNXModels("vgg16-bn", pb, l1, lInf);
// output range: [-16; 27], after Softmax [0; 0.67]
const double lInf = (target == DNN_TARGET_MYRIAD) ? 0.038 : default_lInf;
testONNXModels("vgg16-bn", pb, default_l1, lInf, true);
}
TEST_P(Test_ONNX_nets, ZFNet)
@@ -297,56 +307,62 @@ TEST_P(Test_ONNX_nets, ZFNet)
TEST_P(Test_ONNX_nets, ResNet18v1)
{
// output range: [-16; 22]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.022 : default_l1;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.12 : default_lInf;
testONNXModels("resnet18v1", pb, l1, lInf);
// output range: [-16; 22], after Softmax [0, 0.51]
testONNXModels("resnet18v1", pb, default_l1, default_lInf, true);
}
TEST_P(Test_ONNX_nets, ResNet50v1)
{
// output range: [-67; 75]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.6 : 1.25e-5;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.51 : 1.2e-4;
testONNXModels("resnet50v1", pb, l1, lInf);
// output range: [-67; 75], after Softmax [0, 0.98]
testONNXModels("resnet50v1", pb, default_l1, default_lInf, true);
}
TEST_P(Test_ONNX_nets, ResNet101_DUC_HDC)
{
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_OPENCL
|| target == DNN_TARGET_MYRIAD) {
throw SkipTestException("");
}
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled for DLIE targets");
#endif
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for Myriad targets");
#endif
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_OPENCL)
throw SkipTestException("Test is disabled for OpenCL targets");
testONNXModels("resnet101_duc_hdc", pb);
}
TEST_P(Test_ONNX_nets, TinyYolov2)
{
if (cvtest::skipUnstableTests ||
(backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))) {
throw SkipTestException("");
}
if (cvtest::skipUnstableTests)
throw SkipTestException("Skip unstable test");
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE
&& (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
)
throw SkipTestException("Test is disabled for DLIE OpenCL targets");
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
// output range: [-11; 8]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : default_l1;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.14 : default_lInf;
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : default_l1;
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.14 : default_lInf;
testONNXModels("tiny_yolo2", pb, l1, lInf);
}
TEST_P(Test_ONNX_nets, CNN_MNIST)
{
// output range: [-1952; 6574]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 3.82 : 4.4e-4;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 13.5 : 2e-3;
testONNXModels("cnn_mnist", pb, l1, lInf);
// output range: [-1952; 6574], after Softmax [0; 1]
testONNXModels("cnn_mnist", pb, default_l1, default_lInf, true);
}
TEST_P(Test_ONNX_nets, MobileNet_v2)
{
// output range: [-166; 317]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.4 : 7e-5;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 2.87 : 5e-4;
testONNXModels("mobilenetv2", pb, l1, lInf);
// output range: [-166; 317], after Softmax [0; 1]
testONNXModels("mobilenetv2", pb, default_l1, default_lInf, true);
}
TEST_P(Test_ONNX_nets, LResNet100E_IR)
@@ -371,9 +387,17 @@ TEST_P(Test_ONNX_nets, LResNet100E_IR)
TEST_P(Test_ONNX_nets, Emotion_ferplus)
{
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
double l1 = default_l1;
double lInf = default_lInf;
// Output values are in range [-2.01109, 2.11111]
// Output values are in range [-2.011, 2.111]
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
l1 = 0.007;
else if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
@@ -390,25 +414,20 @@ TEST_P(Test_ONNX_nets, Emotion_ferplus)
TEST_P(Test_ONNX_nets, Inception_v2)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("");
testONNXModels("inception_v2", pb);
testONNXModels("inception_v2", pb, default_l1, default_lInf, true);
}
TEST_P(Test_ONNX_nets, DenseNet121)
{
// output range: [-87; 138]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.12 : 2.2e-5;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.74 : 1.23e-4;
testONNXModels("densenet121", pb, l1, lInf);
// output range: [-87; 138], after Softmax [0; 1]
testONNXModels("densenet121", pb, default_l1, default_lInf, true);
}
TEST_P(Test_ONNX_nets, Inception_v1)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for OpenVINO 2018R5");
throw SkipTestException("Test is disabled for Myriad targets");
#endif
testONNXModels("inception_v1", pb);
}
+135 -28
View File
@@ -2,7 +2,7 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
/*
@@ -133,12 +133,27 @@ TEST_P(Test_TensorFlow_layers, conv)
TEST_P(Test_TensorFlow_layers, padding)
{
runTensorFlowNet("padding_same");
runTensorFlowNet("padding_valid");
runTensorFlowNet("spatial_padding");
runTensorFlowNet("keras_pad_concat");
}
TEST_P(Test_TensorFlow_layers, padding_same)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled for DLIE");
#endif
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
// Reference output values are in range [0.0006, 2.798]
runTensorFlowNet("padding_same");
}
TEST_P(Test_TensorFlow_layers, eltwise)
{
runTensorFlowNet("eltwise_add_mul");
@@ -170,6 +185,16 @@ TEST_P(Test_TensorFlow_layers, batch_norm)
runTensorFlowNet("mvn_batch_norm_1x1");
}
TEST_P(Test_TensorFlow_layers, slim_batch_norm)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled for DLIE");
// Output values range: [-40.0597, 207.827]
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.041 : default_l1;
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.33 : default_lInf;
runTensorFlowNet("slim_batch_norm", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, pooling)
{
runTensorFlowNet("max_pool_even");
@@ -181,6 +206,13 @@ TEST_P(Test_TensorFlow_layers, pooling)
// TODO: fix tests and replace to pooling
TEST_P(Test_TensorFlow_layers, ave_pool_same)
{
// Reference output values are in range [-0.519531, 0.112976]
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
runTensorFlowNet("ave_pool_same");
}
@@ -200,8 +232,11 @@ TEST_P(Test_TensorFlow_layers, matmul)
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("");
runTensorFlowNet("matmul");
runTensorFlowNet("nhwc_reshape_matmul");
runTensorFlowNet("nhwc_transpose_reshape_matmul");
// Reference output values are in range [-5.688, 4.484]
double l1 = target == DNN_TARGET_MYRIAD ? 6.1e-3 : default_l1;
runTensorFlowNet("nhwc_reshape_matmul", false, l1);
}
TEST_P(Test_TensorFlow_layers, reshape)
@@ -216,26 +251,36 @@ TEST_P(Test_TensorFlow_layers, reshape)
TEST_P(Test_TensorFlow_layers, flatten)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD))
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled for DLIE");
#endif
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
)
throw SkipTestException("Test is disabled for Myriad2");
#endif
runTensorFlowNet("flatten", true);
}
TEST_P(Test_TensorFlow_layers, unfused_flatten)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled for DLIE");
#endif
runTensorFlowNet("unfused_flatten");
runTensorFlowNet("unfused_flatten_unknown_batch");
}
TEST_P(Test_TensorFlow_layers, leaky_relu)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
throw SkipTestException("");
throw SkipTestException("Test is disabled for DLIE/OCL target (OpenVINO 2018R5)");
#endif
runTensorFlowNet("leaky_relu_order1");
runTensorFlowNet("leaky_relu_order2");
@@ -244,14 +289,30 @@ TEST_P(Test_TensorFlow_layers, leaky_relu)
TEST_P(Test_TensorFlow_layers, l2_normalize)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
runTensorFlowNet("l2_normalize");
}
// TODO: fix it and add to l2_normalize
TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE
&& (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
)
throw SkipTestException("Test is disabled for DLIE for OpenCL targets");
#endif
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for Myriad targets");
#endif
runTensorFlowNet("l2_normalize_3d");
}
@@ -300,6 +361,13 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
{
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
checkBackend();
std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt", false);
std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false);
@@ -320,6 +388,7 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
0, 3, 0.75838411, 0.44668293, 0.45907149, 0.49459291, 0.52197015,
0, 10, 0.95932811, 0.38349164, 0.32528657, 0.40387636, 0.39165527,
0, 10, 0.93973452, 0.66561931, 0.37841269, 0.68074018, 0.42907384);
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0097 : default_l1;
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : default_lInf;
normAssertDetections(ref, out, "", 0.5, scoreDiff, iouDiff);
@@ -329,6 +398,13 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
{
checkBackend();
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false);
std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt", false);
@@ -354,7 +430,7 @@ TEST_P(Test_TensorFlow_nets, Faster_RCNN)
"faster_rcnn_resnet50_coco_2018_01_28"};
checkBackend();
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE) ||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("");
@@ -380,10 +456,11 @@ TEST_P(Test_TensorFlow_nets, Faster_RCNN)
TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("Unstable test case");
throw SkipTestException("Test is disabled for DLIE OpenCL targets in OpenVINO 2018R5");
#endif
checkBackend();
std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt", false);
std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false);
@@ -399,9 +476,9 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
net.setInput(blob);
Mat out = net.forward();
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.011 : 1.1e-5;
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.021 : default_lInf;
normAssertDetections(ref, out, "", 0.4, scoreDiff, iouDiff);
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.048 : 1.1e-5;
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.058 : default_lInf;
normAssertDetections(ref, out, "", 0.45, scoreDiff, iouDiff);
}
TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
@@ -444,7 +521,13 @@ TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
// np.save('east_text_detection.geometry.npy', geometry)
TEST_P(Test_TensorFlow_nets, EAST_text_detection)
{
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for Myriad targets");
#endif
checkBackend();
std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false);
std::string imgPath = findDataFile("cv/ximgproc/sources/08.png", false);
std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy", false);
@@ -478,8 +561,8 @@ TEST_P(Test_TensorFlow_nets, EAST_text_detection)
}
else if (target == DNN_TARGET_MYRIAD)
{
lInf_scores = 0.214;
l1_geometry = 0.47; lInf_geometry = 15.34;
lInf_scores = 0.41;
l1_geometry = 0.28; lInf_geometry = 5.94;
}
else
{
@@ -493,17 +576,40 @@ INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
TEST_P(Test_TensorFlow_layers, fp16_weights)
{
const float l1 = 0.00071;
const float lInf = 0.012;
float l1 = 0.00078;
float lInf = 0.012;
runTensorFlowNet("fp16_single_conv", false, l1, lInf);
runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
runTensorFlowNet("fp16_max_pool_odd_same", false, l1, lInf);
runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
runTensorFlowNet("fp16_eltwise_add_mul", false, l1, lInf);
runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
runTensorFlowNet("fp16_max_pool_even", false, l1, lInf);
runTensorFlowNet("fp16_padding_same", false, l1, lInf);
runTensorFlowNet("fp16_pad_and_concat", false, l1, lInf);
runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
// Reference output values are in range [0.0889, 1.651]
runTensorFlowNet("fp16_max_pool_even", false, (target == DNN_TARGET_MYRIAD) ? 0.003 : l1, lInf);
if (target == DNN_TARGET_MYRIAD) {
l1 = 0.0041;
lInf = 0.024;
}
// Reference output values are in range [0, 10.75]
runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
// Reference output values are in range [0.418, 2.297]
runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
}
TEST_P(Test_TensorFlow_layers, fp16_padding_same)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled for DLIE");
#endif
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
throw SkipTestException("Test is disabled for MyriadX");
#endif
// Reference output values are in range [-3.504, -0.002]
runTensorFlowNet("fp16_padding_same", false, 6e-4, 4e-3);
}
TEST_P(Test_TensorFlow_layers, defun)
@@ -549,6 +655,7 @@ TEST_P(Test_TensorFlow_layers, slice)
TEST_P(Test_TensorFlow_layers, softmax)
{
runTensorFlowNet("keras_softmax");
runTensorFlowNet("slim_softmax");
}
TEST_P(Test_TensorFlow_layers, relu6)
+15 -5
View File
@@ -148,8 +148,8 @@ TEST_P(Test_Torch_layers, run_reshape_single_sample)
{
// Reference output values in range [14.4586, 18.4492].
runTorchNet("net_reshape_single_sample", "", false, false, true,
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.0073 : default_l1,
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.025 : default_lInf);
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.033 : default_l1,
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.05 : default_lInf);
}
TEST_P(Test_Torch_layers, run_linear)
@@ -272,9 +272,9 @@ class Test_Torch_nets : public DNNTestLayer {};
TEST_P(Test_Torch_nets, OpenFace_accuracy)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
throw SkipTestException("Test is disabled for Myriad targets");
#endif
checkBackend();
@@ -295,8 +295,12 @@ TEST_P(Test_Torch_nets, OpenFace_accuracy)
net.setInput(inputBlob);
Mat out = net.forward();
// Reference output values are in range [-0.17212, 0.263492]
// on Myriad problem layer: l4_Pooling - does not use pads_begin
float l1 = (target == DNN_TARGET_OPENCL_FP16) ? 4e-4 : 1e-5;
float lInf = (target == DNN_TARGET_OPENCL_FP16) ? 1.5e-3 : 1e-3;
Mat outRef = readTorchBlob(_tf("net_openface_output.dat"), true);
normAssert(out, outRef, "", default_l1, default_lInf);
normAssert(out, outRef, "", l1, lInf);
}
static Mat getSegmMask(const Mat& scores)
@@ -393,6 +397,12 @@ TEST_P(Test_Torch_nets, ENet_accuracy)
// -model models/instance_norm/feathers.t7
TEST_P(Test_Torch_nets, FastNeuralStyle_accuracy)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
#endif
checkBackend();
#if defined(INF_ENGINE_RELEASE)
@@ -276,17 +276,15 @@ public:
public:
KMeansDistanceComputer(Distance _distance, const Matrix<ElementType>& _dataset,
const int _branching, const int* _indices, const Matrix<double>& _dcenters, const size_t _veclen,
int* _count, int* _belongs_to, std::vector<DistanceType>& _radiuses, bool& _converged)
std::vector<int> &_new_centroids, std::vector<DistanceType> &_sq_dists)
: distance(_distance)
, dataset(_dataset)
, branching(_branching)
, indices(_indices)
, dcenters(_dcenters)
, veclen(_veclen)
, count(_count)
, belongs_to(_belongs_to)
, radiuses(_radiuses)
, converged(_converged)
, new_centroids(_new_centroids)
, sq_dists(_sq_dists)
{
}
@@ -297,8 +295,8 @@ public:
for( int i = begin; i<end; ++i)
{
DistanceType sq_dist = distance(dataset[indices[i]], dcenters[0], veclen);
int new_centroid = 0;
DistanceType sq_dist(distance(dataset[indices[i]], dcenters[0], veclen));
int new_centroid(0);
for (int j=1; j<branching; ++j) {
DistanceType new_sq_dist = distance(dataset[indices[i]], dcenters[j], veclen);
if (sq_dist>new_sq_dist) {
@@ -306,15 +304,8 @@ public:
sq_dist = new_sq_dist;
}
}
if (sq_dist > radiuses[new_centroid]) {
radiuses[new_centroid] = sq_dist;
}
if (new_centroid != belongs_to[i]) {
CV_XADD(&count[belongs_to[i]], -1);
CV_XADD(&count[new_centroid], 1);
belongs_to[i] = new_centroid;
converged = false;
}
sq_dists[i] = sq_dist;
new_centroids[i] = new_centroid;
}
}
@@ -325,10 +316,8 @@ public:
const int* indices;
const Matrix<double>& dcenters;
const size_t veclen;
int* count;
int* belongs_to;
std::vector<DistanceType>& radiuses;
bool& converged;
std::vector<int> &new_centroids;
std::vector<DistanceType> &sq_dists;
KMeansDistanceComputer& operator=( const KMeansDistanceComputer & ) { return *this; }
};
@@ -796,10 +785,27 @@ private:
}
}
std::vector<int> new_centroids(indices_length);
std::vector<DistanceType> sq_dists(indices_length);
// reassign points to clusters
KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, count, belongs_to, radiuses, converged);
KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, new_centroids, sq_dists);
parallel_for_(cv::Range(0, (int)indices_length), invoker);
for (int i=0; i < (int)indices_length; ++i) {
DistanceType sq_dist(sq_dists[i]);
int new_centroid(new_centroids[i]);
if (sq_dist > radiuses[new_centroid]) {
radiuses[new_centroid] = sq_dist;
}
if (new_centroid != belongs_to[i]) {
count[belongs_to[i]]--;
count[new_centroid]++;
belongs_to[i] = new_centroid;
converged = false;
}
}
for (int i=0; i<branching; ++i) {
// if one cluster converges to an empty cluster,
// move an element into that cluster
@@ -328,7 +328,8 @@ namespace util
util::type_list_index<T, Types...>::value;
if (v.index() == t_index)
return reinterpret_cast<T&>(v.memory);
return *(T*)(&v.memory); // workaround for ICC 2019
// original code: return reinterpret_cast<T&>(v.memory);
else
throw_error(bad_variant_access());
}
@@ -340,7 +341,8 @@ namespace util
util::type_list_index<T, Types...>::value;
if (v.index() == t_index)
return reinterpret_cast<const T&>(v.memory);
return *(const T*)(&v.memory); // workaround for ICC 2019
// original code: return reinterpret_cast<const T&>(v.memory);
else
throw_error(bad_variant_access());
}
@@ -5,5 +5,5 @@
// Copyright (C) 2018 Intel Corporation
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "gapi_core_perf_tests_inl.hpp"
@@ -5,5 +5,5 @@
// Copyright (C) 2018 Intel Corporation
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "gapi_imgproc_perf_tests_inl.hpp"
@@ -5,7 +5,7 @@
// Copyright (C) 2018 Intel Corporation
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "../../test/common/gapi_tests_common.hpp"
namespace opencv_test
@@ -1399,6 +1399,20 @@ void GFluidBackendImpl::addBackendPasses(ade::ExecutionEngineSetupContext &ectx)
// will be copied by views on each iteration and base our choice
// on this criteria)
auto readers = node->outNodes();
// There can be a situation when __internal__ nodes produced as part of some
// operation are unused later in the graph:
//
// in -> OP1
// |------> internal_1 // unused node
// |------> internal_2 -> OP2
// |------> out
//
// To allow graphs like the one above, skip nodes with empty outNodes()
if (readers.empty()) {
continue;
}
const auto &candidate = ade::util::find_if(readers, [&](ade::NodeHandle nh) {
return fg.metadata(nh).contains<FluidUnit>() &&
fg.metadata(nh).get<FluidUnit>().border_size == fd.border_size;
@@ -7,7 +7,7 @@
// FIXME: move out from Common
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
#include "opencv2/gapi/cpu/core.hpp"
#include <ade/util/algorithm.hpp>
+1 -1
View File
@@ -5,5 +5,5 @@
// Copyright (C) 2018 Intel Corporation
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
#include "gapi_core_tests_inl.hpp"
@@ -5,5 +5,5 @@
// Copyright (C) 2018 Intel Corporation
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
#include "gapi_imgproc_tests_inl.hpp"
@@ -564,6 +564,7 @@ TEST_P(NV12toRGBTest, AccuracyTest)
// Additional mat for uv
cv::Mat in_mat_uv(cv::Size(sz.width / 2, sz.height / 2), CV_8UC2);
cv::randn(in_mat_uv, cv::Scalar::all(127), cv::Scalar::all(40.f));
cv::GComputation c(cv::GIn(in_y, in_uv), cv::GOut(out));
c.apply(cv::gin(in_mat1, in_mat_uv), cv::gout(out_mat_gapi), std::move(compile_args));
@@ -594,6 +595,7 @@ TEST_P(NV12toBGRTest, AccuracyTest)
// Additional mat for uv
cv::Mat in_mat_uv(cv::Size(sz.width / 2, sz.height / 2), CV_8UC2);
cv::randn(in_mat_uv, cv::Scalar::all(127), cv::Scalar::all(40.f));
cv::GComputation c(cv::GIn(in_y, in_uv), cv::GOut(out));
c.apply(cv::gin(in_mat1, in_mat_uv), cv::gout(out_mat_gapi), std::move(compile_args));
@@ -5,5 +5,5 @@
// Copyright (C) 2018 Intel Corporation
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
#include "gapi_operators_tests_inl.hpp"
@@ -5,7 +5,7 @@
// Copyright (C) 2018 Intel Corporation
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
#include "../common/gapi_operators_tests.hpp"
#define CORE_FLUID cv::gapi::core::fluid::kernels()
+15
View File
@@ -752,4 +752,19 @@ INSTANTIATE_TEST_CASE_P(Fluid, NV12RoiTest,
,std::make_pair(cv::Size{1920, 1080}, cv::Rect{0, 710, 1920, 270})
));
TEST(Fluid, UnusedNodeTest) {
cv::GMat in;
cv::GMat a, b, c, d;
std::tie(a, b, c, d) = cv::gapi::split4(in);
cv::GMat out = cv::gapi::merge3(a, b, c);
cv::Mat in_mat(cv::Size(8, 8), CV_8UC4);
cv::Mat out_mat(cv::Size(8, 8), CV_8UC3);
cv::GComputation comp(cv::GIn(in), cv::GOut(out));
ASSERT_NO_THROW(comp.apply(cv::gin(in_mat), cv::gout(out_mat),
cv::compile_args(cv::gapi::core::fluid::kernels())));
}
} // namespace opencv_test
@@ -5,8 +5,8 @@
// Copyright (C) 2018 Intel Corporation
#include "test_precomp.hpp"
#include "gapi_mock_kernels.hpp"
#include "../test_precomp.hpp"
#include "../gapi_mock_kernels.hpp"
#include "compiler/gmodel.hpp"
#include "compiler/gcompiler.hpp"
@@ -5,7 +5,7 @@
// Copyright (C) 2018 Intel Corporation
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
namespace opencv_test
{
@@ -5,7 +5,7 @@
// Copyright (C) 2018 Intel Corporation
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
namespace opencv_test {
// Tests on T/Kind matching ////////////////////////////////////////////////////

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