1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-28 23:03:03 +04:00

Compare commits

...

265 Commits

Author SHA1 Message Date
Alexander Alekhin 1363496c11 release: OpenCV 4.5.1 2020-12-21 20:01:38 +00:00
Alexander Alekhin a029f03edc Merge pull request #19187 from alalek:samples_python_3.9 2020-12-21 18:16:00 +00:00
Alexander Alekhin 03df48899c Merge pull request #19186 from AsyaPronina:asyadev/fix_gframe_as_internal_data_for_gexecutor 2020-12-21 18:15:24 +00:00
Alexander Alekhin b51ae87828 samples: check for Python 3.9 2020-12-21 14:59:34 +00:00
Anastasiya Pronina cdbea6f0a0 GFrame as internal node in GExecutor 2020-12-21 14:06:47 +03:00
Alexander Alekhin 6659d55a9d Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-12-20 18:40:22 +00:00
Alexander Alekhin e6c9291e32 Merge pull request #19180 from alalek:fixup_19161 2020-12-20 18:39:01 +00:00
Alexander Alekhin a6f14ca97c js(build): fix generator with Python3
- class_info.props is a 'list'
2020-12-20 17:42:47 +00:00
Alexander Alekhin c555a6747d Merge pull request #19177 from alalek:doxygen_drop_TCL_SUBST 2020-12-20 16:40:58 +00:00
Alexander Alekhin dd276dbb59 Merge pull request #19176 from alalek:issue_19131 2020-12-20 16:40:28 +00:00
Alexander Alekhin 70d82017fe Merge pull request #19175 from alalek:issue_18520 2020-12-20 16:39:56 +00:00
Alexander Alekhin 663bd73518 Merge pull request #19164 from fpetrogalli:tranform_16u 2020-12-20 16:38:59 +00:00
Francesco Petrogalli c526705f4f [cv::transform] Enable CV_SIMD for the 16U case on AArch64. 2020-12-20 15:58:21 +00:00
Alexander Alekhin c84d2cb32a Merge pull request #18604 from vrabaud:master 2020-12-20 15:50:33 +00:00
Vincent Rabaud ff211371bc Replace FLANNException by CV_Error. 2020-12-20 14:17:28 +01:00
Alexander Alekhin e9a4734a57 doxygen: drop deprecated TCL_SUBST 2020-12-20 05:05:48 +00:00
Alexander Alekhin 3359bdc464 docs(core): fix process_video_frame() code snippet 2020-12-20 02:27:46 +00:00
Alexander Alekhin 17faee5d81 imgproc: add rotatedRectangleIntersection empty input handling 2020-12-20 02:06:50 +00:00
Alexander Alekhin b4795086fe Merge pull request #19168 from alalek:abi_experimental_quaternion 2020-12-19 19:22:52 +00:00
Alexander Alekhin 5cd852f9bd Merge pull request #19170 from vrabaud:3.4 2020-12-19 19:22:30 +00:00
Vincent Rabaud 4c75b1c102 Fix comment typos. 2020-12-19 08:22:37 +01:00
Alexander Alekhin a6b5771297 ABI: exclude quaternion header from ABI/API check
- this API is experimental for now
2020-12-18 21:45:08 +00:00
Alexander Alekhin dac298ef41 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-12-18 20:47:56 +00:00
Alexander Alekhin ef27c11d50 Merge pull request #19162 from alalek:backport_18985 2020-12-18 20:29:49 +00:00
Alexander Alekhin cd3939a153 Merge pull request #19158 from alalek:build_opencv_winpack_dldt_2021.2.0 2020-12-18 20:29:33 +00:00
Alexander Alekhin 9f5463ce42 Merge pull request #19152 from LupusSanctus:am/color_issue 2020-12-18 20:28:12 +00:00
Anastasia Murzova 3bc1b53962 Added YUV conversion fix
Fixed OpenCV issue #18878
2020-12-18 21:40:32 +03:00
Alexander Alekhin de1b919641 Merge pull request #19161 from alalek:js_robust_code_generation 2020-12-18 15:12:17 +00:00
Alexander Alekhin 3e9158acd6 Merge pull request #19128 from asmorkalov:as/gapi_phase_tolerance 2020-12-18 13:43:07 +00:00
Alexander Alekhin 03e224ee83 Merge pull request #19127 from asmorkalov:as/photo_fix_arm64 2020-12-18 13:42:26 +00:00
Steffen Urban c2bc171ef6 js: backport PR18985
original commit: b82700ae41
2020-12-18 12:12:10 +00:00
Alexander Alekhin f8740e124c js: robust code generation
- avoid randomized output due to unpredictable dict/set order
2020-12-18 12:02:48 +00:00
Steffen Urban b82700ae41 Merge pull request #18985 from ZEISS:feature/aruco_js_fix
Aruco javascript fix and added functionality

* whitespace

* updated docu. updated regexp.

* update docu

* embindgen regex

* removed parser arg

* remove whitespace

* removed aruco hint

* remove whitespace

* removed aruco hint

* new docu string

* removed extra line

* remove whitespace

* removed aruco hint

* new docu string

* removed extra line
2020-12-18 12:01:48 +00:00
Alexander Smorkalov 009860e98a arm64 fix: Replaced float value strong equal checks with check with tolerance. 2020-12-18 14:57:51 +03:00
Alexander Smorkalov 57da381ae3 Increased Photo_CalibrateDebevec.regression test tolerance to pass on arm64 with gcc 9.3. 2020-12-18 14:46:40 +03:00
Alexander Alekhin 935cb4076b Merge pull request #19154 from alalek:fixup_19089 2020-12-18 11:23:02 +00:00
Alexander Alekhin b2ea15da35 Merge pull request #19137 from VadimLevin:dev/vlevin/safe-string-conversion 2020-12-18 11:20:50 +00:00
Alexander Alekhin 9733177083 Merge pull request #19105 from alalek:js_build_update 2020-12-18 11:12:30 +00:00
Alexander Alekhin fa665141bb Merge pull request #19104 from alalek:docs_cmake_msvs2019 2020-12-18 11:10:52 +00:00
Alexander Alekhin 64720f15a2 doc(windows): update how to handle MSVS 2019 2020-12-18 08:24:26 +00:00
Alexander Alekhin 8df0f13230 build: winpack_dldt with dldt 2021.2.0 2020-12-18 06:54:51 +00:00
Alexander Alekhin 624d532000 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-12-17 21:05:34 +00:00
Alexander Alekhin 94e7be3714 docs(calib3d): avoid reference on legacy C API constants 2020-12-17 21:03:27 +00:00
Alexander Alekhin 9b4adc9acb Merge pull request #19146 from alalek:dnn_openvino_2021.2.0 2020-12-17 19:50:36 +00:00
Alexander Alekhin e27162397a Merge pull request #19143 from vrabaud:stack 2020-12-17 19:47:43 +00:00
Alexander Alekhin 99d750d597 Merge pull request #19139 from vrabaud:find1 2020-12-17 19:40:22 +00:00
Vadim Pisarevsky c51f5e8d76 Merge pull request #19082 from vpisarev:rvv_copyright 2020-12-17 17:10:17 +00:00
Vadim Pisarevsky ba7dbca018 added information about the contribution & ISCAS copyright 2020-12-17 18:28:17 +08:00
Vincent Rabaud 8391a23600 Optimize calls to std::string::find() and friends for a single char.
The character literal overload is more efficient. More info at:

http://clang.llvm.org/extra/clang-tidy/checks/performance-faster-string-find.html
2020-12-17 09:39:23 +01:00
Vincent Rabaud ec3ef520e6 Move big objects (>20k) from stack to heap. 2020-12-17 09:36:51 +01:00
Alexander Alekhin 28aab134db dnn(test): update tests for OpenVINO 2021.2 2020-12-17 07:53:35 +00:00
Alexander Alekhin 752cc26ad6 dnn: use OpenVINO 2021.2 defines
original commit: 4699d2ba0c
2020-12-16 22:22:17 +00:00
Alexander Alekhin d159417474 Merge pull request #19101 from alalek:issue_5209 2020-12-16 22:13:18 +00:00
Alexander Alekhin 7d7ab462d6 Merge pull request #19130 from dmatveev:dm/fix_docs_ocv451 2020-12-16 20:26:41 +00:00
Alexander Alekhin c4c21c2fa7 Merge pull request #19142 from rgarnov:rg/include_format_in_core 2020-12-16 20:26:05 +00:00
Ruslan Garnov e06a497c7c Added format.hpp include to core.hpp 2020-12-16 19:29:06 +03:00
Vadim Levin 7b0d7d0c9a fix: conversion to string in python bindings
If provided `PyObject` can't be converted to string `TypeError` is
 reported instead of `SytemError` without any message.
2020-12-16 15:11:58 +03:00
Ruslan Garnov f7cab121fe Merge pull request #19112 from rgarnov:rg/generic_copy_kernel
Generic copy kernel

* Moved RMat wrapping of cv::Mats to StreamingInput

* Generalized GCopy kernel

* Generic GCopy kernel: applied review comments
2020-12-16 11:18:08 +00:00
Alexander Alekhin 7631056b8a Merge pull request #19114 from alalek:issue_18937 2020-12-15 20:47:05 +00:00
Alexander Alekhin 4107dc7355 Merge pull request #19089 from IanMaquignaz:fix_34_calib3d_parameterReferences 2020-12-15 20:46:09 +00:00
Dmitry Matveev b74804f61f G-API: Fix various Doxygen isses for the 4.5.1 release 2020-12-15 23:21:46 +03:00
Anatoliy Talamanov 50baf76cc2 Merge pull request #19107 from TolyaTalamanov:at/hotfix-gstreamingbackend
[G-API] GStreamingBackend hotfix

* GStreamingBackend hotfix

* Fix comments to review

* Add strides

* Removew while loop inside actor
2020-12-15 18:05:26 +00:00
Ian Maquignaz 085a131801 Applied '@ref' linking for 3.4 Calib3D parameters and added enum cv::fisheye::CALIB_ZERO_DISPARITY == cv::CALIB_ZERO_DISPARITY == 0x400 == 1 << 10.
Fisheye test has been updated to use new enum cv::fisheye::CALIB_ZERO_DISPARITY and included CV_StaticAssert(...) to ensure cv::CALIB_ZERO_DISPARITY == cv::fisheye::CALIB_ZERO_DISPARITY.
2020-12-15 12:33:43 -05:00
Alexander Alekhin 50fed1d774 Merge pull request #19115 from alalek:dnn_ocl_conv_fp16_consistency 2020-12-15 16:09:15 +00:00
Alexander Alekhin c240355cc6 dnn(ocl): avoid mess FP16/FP32 in convolution layer 2020-12-15 08:51:24 +00:00
Alexander Alekhin a9edcc1705 Merge pull request #19110 from alalek:test_videoio_require_ffmpeg 2020-12-15 08:48:23 +00:00
Alexander Alekhin 4b3d2c8834 dnn(ocl): fix gemm kernels with beta=0
- dst is not initialized, may include NaN values
- 0*NaN produces NaN
2020-12-15 00:58:43 +00:00
Orest Chura fcdd69fd97 Merge pull request #19103 from OrestChura:oc/cvtI420_perftests
[G-API]: Performance tests for color conversion kernels

* Performance tests for 5 new color conversion kernels:
 - BGR2RGB
 - BGR2I420
 - RGB2I420
 - I4202BGR
 - I4202RGB

* Addressing comment
2020-12-14 22:45:41 +00:00
Alexander Alekhin 48d9031efb videoio(test): add FFmpeg backend check
- configure through OPENCV_TEST_VIDEOIO_BACKEND_REQUIRE_FFMPEG environment variable
2020-12-14 18:29:52 +00:00
Alexander Alekhin a8adb99e94 Merge pull request #19106 from xerus:fix_typo 2020-12-14 16:27:53 +00:00
Pavel Grunt b01ae2de05 Fix a typo s/VERISON/VERSION/ 2020-12-14 12:02:25 +01:00
Anna Khakimova 46e275dfe4 Merge pull request #18869 from anna-khakimova:ak/kalman
* GAPI: Kalman filter stateful kernel

* Applied comments

* Applied comments. Second iteration

* Add overload without control vector

* Remove structure constructor and dimension fields.

* Add sample as test

* Remove visualization from test-sample + correct doxygen comments

* Applied comments.
2020-12-14 08:56:37 +00:00
Alexander Alekhin af71b03000 js: update documentation and builds scripts
- support modern Emscripten build process
- replaced Docker image
- replaced Emscripten's web URLs
2020-12-14 04:42:15 +00:00
Alexander Alekhin 392991fa0b core(opencl): add version check before clCreateFromGLTexture() call 2020-12-13 20:57:26 +00:00
Jonathan Cole 743f1810c7 Merge pull request #19088 from Rightpoint:task/colejd/make-xcframework-output-path-explicit
Make xcframework output path argument explicit and required

* Make output path argument explicit and required

* Improve xcframework documentation

* Add TODOs for future breaking changes on build_framework.py scripts
2020-12-12 17:35:25 +00:00
Alexander Alekhin dd1494eebf Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-12-11 19:27:20 +00:00
Alexander Alekhin 1bfc75ac23 Merge pull request #19079 from alalek:issue_18713 2020-12-11 19:15:26 +00:00
Alexander Alekhin 5bb45baa6c Merge pull request #19085 from OrestChura:oc/fix_new_streaming_tests 2020-12-11 19:14:29 +00:00
Alexander Alekhin def679554f Merge pull request #19084 from alalek:issue_16197 2020-12-11 19:13:40 +00:00
Alexander Alekhin 08b6abd711 Merge pull request #19068 from alalek:issue_18157 2020-12-11 19:11:04 +00:00
Alexander Alekhin 33761ee06b Merge pull request #19064 from alalek:cmake_update_mkl 2020-12-11 19:10:16 +00:00
Alexander Alekhin a04479746a Merge pull request #19045 from alalek:issue_17553
* flann: avoid dangling pointers on lost features data

* flann: fix Index::load()
2020-12-11 19:09:35 +00:00
Alexander Alekhin d2b8fd6401 Merge pull request #19062 from alalek:3.4_issue_17553 2020-12-11 19:08:46 +00:00
Alexander Alekhin 8ac304517e Merge pull request #19055 from alalek:4.x_issue_18244 2020-12-11 19:07:57 +00:00
Alexander Alekhin 4f236d1c50 Merge pull request #19054 from alalek:3.4_issue_18244 2020-12-11 19:07:34 +00:00
Alexander Alekhin f9f9e2ad4a Merge pull request #19049 from alalek:issue_17282 2020-12-11 19:06:47 +00:00
Alexander Alekhin e52291cbcc Merge pull request #19048 from alalek:android_gradle_5.6.4 2020-12-11 19:06:13 +00:00
Alexander Alekhin 23c246882e Merge pull request #19071 from LupusSanctus:am/dnn_nearest_resize_3.4 2020-12-11 18:25:55 +00:00
Alexander Alekhin f290ff215e features2d: fix ORB::setFirstScale() handling 2020-12-11 18:05:24 +00:00
OrestChura 79b4dc14a3 Fix new streaming tests for CI 2020-12-11 20:26:39 +03:00
Anatoliy Talamanov 8ed0fc6f0c Merge pull request #19009 from TolyaTalamanov:at/media-frame-copy
[G-API] GStreamingBackend

* Snapshot

* Implement StreamingBackend

* Refactoring

* Refactoring 2

* Clean up

* Add missing functionality to support MediaFrame as output

* Partially address review comments

* Fix build

* Implement reshape for gstreamingbackend and add a test on it

* Address more comments

* Add format.hpp to gapi.hpp

* Fix debug build

* Address review comments

Co-authored-by: Smirnov Alexey <alexey.smirnov@intel.com>
2020-12-11 16:29:34 +00:00
Alexander Alekhin 9f01b97e14 Merge pull request #19024 from komakai:cmake319-proposal2 2020-12-11 15:14:43 +00:00
Sergei Slashchinin 1f3255d76b Merge pull request #18591 from sl-sergei:download_utilities
Scripts for downloading models in DNN samples

* Initial commit. Utility classes and functions for downloading files

* updated download script

* Support YAML parsing, update download script and configs

* Fix problem with archived files

* fix models.yml

* Move download utilities to more appropriate place

* Fix script description

* Update README

* update utilities for broader range of files

* fix loading with no hashsum provided

* remove unnecessary import

* fix for Python2

* Add usage examples for downloadFile function

* Add more secure cache folder selection

* Remove trailing whitespaces

* Fix indentation

* Update function interface

* Change function for temp dir, change entry name in models.yml

* Update getCacheDirectory function call

* Return python implementation for cache directory selection, use more specific env variable

* Fix whitespace
2020-12-11 10:15:32 +00:00
Yosshi999 fdeac73a59 Merge pull request #18983 from Yosshi999:bitexact-gaussian-16U-faster
support SIMD for larger symmetric Bit-exact 16U gaussian blur

* support SIMD for bit-exact 16U symmetric gaussian blur

* use tighter SIMD registers
2020-12-11 10:14:15 +00:00
Alexander Alekhin 175cd03ff2 calib3d: fix findCirclesGrid hang
- detect case with infinite loop and raise NoConv exception
- handle such exception
- add support for case with missing `blobDetector` (image contains Point2f array of candidates)
- add regression test
- undone rectification for "failed" detections too
- drop redirectError() usage
2020-12-11 07:31:50 +00:00
Jonathan Cole 9f52244574 Merge pull request #19076 from Rightpoint:bugfix/colejd/fix-path-resolution-bugs
Fix path resolution bugs for XCFramework builds

* Fix incorrect paths for intermediate frameworks

* Remove unnecessary `./` prepend preventing use of absolute paths
2020-12-11 07:14:28 +00:00
Alexander Alekhin d6a7f5e1e0 Merge pull request #19075 from alalek:dnn_fix_halide_build 2020-12-10 20:37:37 +00:00
Alexander Alekhin fce8d8e090 Merge pull request #19074 from alalek:dnn_test_tolerance_east 2020-12-10 20:29:36 +00:00
Alexander Alekhin 8ce08dedfe Merge pull request #19072 from mshabunin:sink-sync-off 2020-12-10 20:05:47 +00:00
Alexander Alekhin 32377ce57d android: add -llog for libprotobuf 2020-12-10 20:00:58 +00:00
Alexander Alekhin d84a9484b7 dnn: fix build with Halide, skip tests with crashes 2020-12-10 18:23:24 +00:00
Alexander Alekhin 8ff27a07bb dnn(test): adjust EAST test tolerance 2020-12-10 16:39:20 +00:00
Maksim Shabunin 55a2bcbe15 videoio: turn off syncronized sink in GStreamer 2020-12-10 16:07:28 +03:00
Anastasia Murzova f2422ace7d Added TF nearest neighbour resize behaviour alignment
Relates to OpenCV issue #18721
2020-12-10 15:53:24 +03:00
Giles Payne d1ea2ad143 CMake version checks for iOS and macOS builds 2020-12-10 21:43:26 +09:00
Alexander Alekhin 3e5d7e1718 imgproc: fix minAreaRect() 2020-12-10 08:57:58 +00:00
Alexander Alekhin de385009ae Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-12-09 18:09:00 +00:00
Alexander Alekhin 114848d313 Merge pull request #18712 from mshabunin:doc-update-2 2020-12-09 21:05:17 +03:00
Alexander Alekhin 8286d84fb1 Merge pull request #19061 from alalek:dnn_load_face_detector_with_external_protobuf 2020-12-09 18:03:52 +00:00
Alexander Alekhin c42d0c8374 Merge pull request #19060 from alalek:issue_18097 2020-12-09 18:02:41 +00:00
Alexander Alekhin 37bfb3c48d Merge pull request #19059 from alalek:fixup_19000 2020-12-09 18:01:04 +00:00
Alexander Alekhin b3937288e5 cmake: update MKL library searching
- allow to specify MKL_LIBRARIES through command-line
2020-12-09 16:36:15 +00:00
Anatoliy Talamanov a55150b1bc Merge pull request #19002 from TolyaTalamanov:at/infer_gframe
[G-API] Support GFrame for infer

* GInfer(GFrame), currently broken

* Fixed (API only)

* Support GFrame in GIEBackend

* Fix comments to review

* Fix comments to review

* Fix doxygen

* Fix building with different IE versions

* Fix warning on MacOS

Co-authored-by: Dmitry Matveev <dmitry.matveev@intel.com>
Co-authored-by: Smirnov Alexey <alexey.smirnov@intel.com>
2020-12-09 14:00:56 +00:00
Alexander Alekhin 7eaa548b6d flann: drop wrapping of Index class
- due to lifetime restrictions on passed 'features' parameter and its dangling pointers
- dangling pointer issue is fixed for OpenCV 4.5.1+
2020-12-09 05:39:35 +00:00
Alexander Alekhin d7e936de5c dnn(caffe): add DetectionOutputParameter.clip to .proto file
- allow to load opencv_face_detector with external unpatched protobuf
2020-12-09 05:21:07 +00:00
Alexander Alekhin d2bc0e5fe0 js(wasm): use fallback on missing intrinsics in Emscripten 2.0.0+ 2020-12-09 04:19:53 +00:00
Alexander Alekhin d8107a5125 Merge pull request #18996 from LupusSanctus:am/dnn_bilinear_resize 2020-12-08 21:09:41 +00:00
Anastasia Murzova a82c50eac2 Added TF resize_bilinear behaviour alignment
Fixes OpenCV issue #18721
2020-12-08 22:51:38 +03:00
Alexander Alekhin 7fa9efbfd8 cmake: fix handling of wrappers dependencies 2020-12-08 19:10:04 +00:00
Alexander Alekhin b5a9ef6b7b Merge pull request #19052 from diablodale:fix18888-opencl-doc 2020-12-08 18:03:19 +00:00
Alexander Alekhin 8ebe320270 cmake: don't define ENABLE_NEON flags in non-cross-compiling mode
- NEON / ANDROID_ARM_NEON are toolchain-specific flags
- they are usually not defined for native builds
- let work CPU_BASELINE=DETECT properly
2020-12-08 18:01:03 +00:00
Alexander Alekhin fe3893ff01 cmake: don't define ENABLE_NEON flags in non-cross-compiling mode
- NEON / ANDROID_ARM_NEON are toolchain-specific flags
- they are usually not defined for native builds
- let work CPU_BASELINE=DETECT properly
2020-12-08 18:00:40 +00:00
Orest Chura f41327df0c Merge pull request #18969 from OrestChura:oc/fix_notes_returns
[G-API] Multiple return/note fix

* Fix doxygen:
 - multiple return
 - multiple notes

* Addressing comments
 - divide description of split(merge)3/4
2020-12-08 15:44:33 +00:00
Dale Phurrough f77276311d clarify opencl execution context doc
- fix opencv/opencv#18888
2020-12-08 16:08:53 +01:00
Alexander Alekhin e8348e5f64 Merge pull request #19046 from alalek:issue_16861 2020-12-08 11:34:20 +00:00
Alexander Alekhin 619cc01ca1 Merge pull request #19044 from OrestChura:oc/fix_coverity_warn_kmeans 2020-12-08 10:31:31 +00:00
Dale Phurrough ad94d8cc4f Merge pull request #19029 from diablodale:fix19004-memthreadstart
add thread-safe startup of fastMalloc and fastFree

* add perf test core memory allocation

* fix threading in isAlignedAllocationEnabled()

* tweaks requested by maintainer
2020-12-08 10:05:14 +00:00
Alexander Alekhin c3cebc3ac5 android: use gradle 5.6.4 2020-12-08 07:18:30 +00:00
Alexander Alekhin fb85974d01 android: use protected fields in JavaCamera2View 2020-12-08 05:18:21 +00:00
OrestChura 02488c5cbb Moved G-API output to the first place of arguments in comparison functions 2020-12-08 02:44:01 +03:00
Alexander Alekhin 3377ddaf09 Merge pull request #19041 from alalek:issue_19025 2020-12-07 22:31:53 +00:00
Alexander Alekhin 40ca8f4695 Merge pull request #19035 from berak:fix_dnn_net_dump_colors 2020-12-07 22:11:49 +00:00
Alexander Alekhin 962f5c9b82 videoio(test): skip GStreamer in 'frame_timestamp' tests
- CAP_PROP_POS_MSEC is not reliable
2020-12-07 21:35:01 +00:00
Alexander Alekhin 2c634eeef2 Merge pull request #19023 from alalek:core_update_allocator_stats_type 2020-12-07 20:41:37 +00:00
Alexander Alekhin c6e60f06eb Merge pull request #19019 from alalek:cmake_avoid_excessive_trace_dump 2020-12-07 20:40:56 +00:00
Alexander Alekhin e5d2642780 Merge pull request #19015 from alalek:dnn_use_fma 2020-12-07 20:40:21 +00:00
berak cf28b5e5be dnn: add another color to Net::Impl::dump() 2020-12-07 17:58:40 +01:00
Maksim Shabunin c79a1528ad Added TOC to most of tutorials 2020-12-07 19:13:54 +03:00
Alexander Alekhin 31619faa70 Merge pull request #19021 from alalek:4.x_build_warnings_gcc_4.8.5 2020-12-06 17:22:45 +00:00
Alexander Alekhin a9f4f8ded4 Merge pull request #19022 from alalek:cmake_avoid_duplication_of_winit_self 2020-12-06 16:14:25 +00:00
joshdoe 541a09b7ac Merge pull request #18535 from joshdoe:gray16_gstreamer_writing
Add CV_16UC1/GRAY16_LE support to GStreamer backend for VideoWriter

* videoio(backend): add Writer_open_with_params to plugin API

This will allow arbitrary parameters to be passed to plugin backends

* videoio(gstreamer): add GRAY16_LE/CV_16UC1 writing support to GStreamer

This introduces a new property VIDEOWRITER_PROP_DEPTH, which defaults to
CV_8U, but for GStreamer can be set to CV_16U.

Also, fix another test to not fail if plugin isn't found, copying logic
from the read_write test.

* videoio(plugin): fix handling plugins with previous API level

* videoio: coding style

* fix warning
2020-12-05 21:28:07 +00:00
Alexander Alekhin 26e8048a0a core: update handling of allocator stats type
- don't use OPENCV_ALLOCATOR_STATS_COUNTER_TYPE definition in non C++11 builds
- don't use with MinGW
2020-12-05 20:54:47 +00:00
Alexander Alekhin 6bfb0dda85 cmake: avoid duplication of -Winit-self flag 2020-12-05 20:18:02 +00:00
Alexander Alekhin d1b5a78171 build warnings
- GCC 4.8.5 / CentOS 7
2020-12-05 20:08:29 +00:00
Alexander Alekhin 753ccd6b17 Merge pull request #19018 from alalek:issue_19016 2020-12-05 19:59:22 +00:00
Alexander Alekhin 8ae1552a5b cmake: avoid excessive output from cmake --trace/--trace-expand
- `cmake . --trace-expand -DCMAKE_TRACE_MODE=1`
2020-12-05 13:29:43 +00:00
Alexander Alekhin 08bee40fa2 samples: replace regex
- GCC 4.8.5 doesn't support regex
2020-12-05 12:50:37 +00:00
Alexander Alekhin 00f36a3149 dnn: prefer to use v_fma() instead of v_c += v_a * v_b 2020-12-05 11:51:03 +00:00
Maksim Shabunin 461e26b60b doc: tutorial refactor 2020-12-05 01:57:36 +03:00
Alexander Alekhin 6fdb7aee84 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-12-04 18:26:58 +00:00
Alexander Alekhin 12a36b5a94 Merge pull request #18955 from alalek:test_debug_flag 2020-12-04 18:10:00 +00:00
Wenqing Zhang 22d64ae08f Merge pull request #17570 from HannibalAPE:text_det_recog_demo
[GSoC] High Level API and Samples for Scene Text Detection and Recognition

* APIs and samples for scene text detection and recognition

* update APIs and tutorial for Text Detection and Recognition

* API updates:
(1) put decodeType into struct Voc
(2) optimize the post-processing of DB

* sample update:
(1) add transformation into scene_text_spotting.cpp
(2) modify text_detection.cpp with API update

* update tutorial

* simplify text recognition API
update tutorial

* update impl usage in recognize() and detect()

* dnn: refactoring public API of TextRecognitionModel/TextDetectionModel

* update provided models
update opencv.bib

* dnn: adjust text rectangle angle

* remove points ordering operation in model.cpp

* update gts of DB test in test_model.cpp

* dnn: ensure to keep text rectangle angle

- avoid 90/180 degree turns

* dnn(text): use quadrangle result in TextDetectionModel API

* dnn: update Text Detection API
(1) keep points' order consistent with (bl, tl, tr, br) in unclip
(2) update contourScore with boundingRect
2020-12-03 18:47:40 +00:00
Alexander Alekhin e371592f75 Merge pull request #18965 from alalek:cmake_gen_js_code 2020-12-03 18:10:30 +00:00
Alexander Alekhin 84a3654371 Merge pull request #19000 from alalek:cmake_fix_order_of_bindings_generators 2020-12-03 18:08:40 +00:00
Alexander Alekhin 7e5c4fe1cd cmake(js): update js targets
- unconditional js bindings source code generation
- use common name for tests: opencv_test_js
2020-12-03 14:18:54 +00:00
Alexander Alekhin 5ecf693774 Merge pull request #18997 from alalek:disable_github_action_workflow 2020-12-03 16:55:35 +03:00
Alexander Alekhin 773ccc4bf8 Merge pull request #18993 from alalek:issue_18984 2020-12-03 13:55:07 +00:00
Alexander Alekhin b31ce408ae cmake: fix processing order of <wrapper>_bindings_generator
- ensure that wrapped modules are already processed
2020-12-03 13:01:46 +00:00
Alexander Alekhin 7983c484b2 Merge pull request #18998 from upupming:patch-1 2020-12-03 10:59:59 +00:00
Alexander Alekhin 6502737bd5 Merge pull request #18992 from vertexcite:patch-1 2020-12-03 10:58:47 +00:00
Alexander Alekhin b98dd728ca Merge pull request #18966 from Staticity:add_live_timestamps_to_msmf 2020-12-03 10:57:25 +00:00
Randall Britten 7f3ba5963d Fixed minor typo "poins" in documentation page 2020-12-03 12:46:23 +03:00
Yiming Li 43e58de918 fix: typo 2020-12-03 17:06:41 +08:00
Alexander Alekhin b7a70fda79 github(actions): manual trigger for arm64-build-checks.yml 2020-12-03 02:21:35 +00:00
Alexander Alekhin e309ad8465 Merge pull request #18994 from alalek:umat_drop_unavailable_methods 2020-12-02 22:54:47 +00:00
Jaime Rivera 2fa624aef0 Add Timestamps to MSMF Video Capture by index
Enable frame timestamp tests for MSMF

Add functional test for camera live timestamps

Remove trailing whitespace

Add timestamp test to all functional tests. Protect div by 0

Add Timestamps to MSMF Video Capture by index
2020-12-02 16:36:09 -05:00
Vadim Pisarevsky b023fcd264 Merge pull request #18911 from chargerKong:quat 2020-12-02 19:14:47 +00:00
Alexander Alekhin e958600f32 Merge pull request #18986 from alalek:fix_ipp_17453_2 2020-12-02 19:09:24 +00:00
Alexander Alekhin 484251c52b Merge pull request #18831 from rjiejie:master-opt@pipeline 2020-12-02 19:07:38 +00:00
Alexander Alekhin e98c845f0b Merge pull request #18977 from Rightpoint:objc-collision-fix 2020-12-02 19:06:57 +00:00
Vadim Pisarevsky e4ed1d08f4 Merge pull request #18462 from joy2myself:riscv_toolchian 2020-12-02 18:38:17 +00:00
Kong Liangqian 8e32566583 Add adding and subtraction operations between a number and a quaternion;
fix a typo;
Add documentation of quaternion operators;
Restrict the type of scalar: the same as quaternion;
2020-12-03 01:38:15 +08:00
Alexander Alekhin 512be4ab65 Merge pull request #18991 from alalek:workaround_12959 2020-12-02 17:34:22 +00:00
Alexander Alekhin 6f8120cb3a core(UMat): drop unavailable methods 2020-12-02 15:02:43 +00:00
Vadim Pisarevsky a3de45741e Merge pull request #18971 from GArik:orbbec 2020-12-02 13:33:32 +00:00
Vadim Pisarevsky 7d7d907de7 Merge pull request #18228 from joy2myself:rvv 2020-12-02 13:27:35 +00:00
Alexander Alekhin c42d47d94a cmake: clean cached INTERNAL variable used for 3rdparty deps 2020-12-02 12:34:24 +00:00
Alexander Alekhin d35e2f5339 core(ipp): workaround getIppTopFeatures() value mismatch 2020-12-02 11:33:55 +00:00
Zhangyin 673e4e20f0 Added RISC-V backend of universal intrinsics 2020-12-02 14:25:03 +08:00
Igor Murzov 38a4eaf8a3 Orbbec tutorial: Sync frames from two streams and process depth & color simultaneously 2020-12-02 00:07:28 +03:00
Giles Payne 29b453eb86 Objective-C name clash avoidance 2020-12-01 11:22:57 -08:00
Alexander Alekhin ef0eed8d3c Merge pull request #18981 from anton-potapov:fix_gnet_package_compilation_std_17 2020-12-01 17:42:12 +00:00
Alexander Alekhin 91ce6ef190 core(ipp): disable SSE4.2 code path in countNonZero() 2020-12-01 14:01:42 +00:00
Daniel Cauchi 9d37cdaa66 Merge pull request #18891 from CowKeyMan:NMS_boxes_with_different_labels
Add option for NMS for boxes with different labels

* DetectionModel impl

* Add option for NMS for boxes with different labels

In the detect function in modules/dnn/include/opencv2/dnn/dnn.hpp, whose implementation can be found at modules/dnn/src/model.cpp, the Non Max Suppression (NMS) is applied only for objects of the same label. Thus, a flag
was added with the purpose to allow developers to choose if they want to keep the default implementation or wether they would like NMS to be applied to all the boxes, regardless of label.

The flag is called nmsDifferentLabels, and is given a default value of false, which applies the current default implementation, thus allowing existing projects to update opencv without disruption

Solves issue opencv#18832

* Change return type of set & Add default constr

* Add assertions due to default constructor
2020-12-01 13:50:24 +00:00
Alexander Alekhin 3f686a6ab8 Merge pull request #18967 from anton-potapov:reuse_move_through_copy 2020-12-01 12:57:06 +00:00
Alexander Alekhin db3e3a766a Merge pull request #18978 from Rightpoint:testing-ios-deployment-target 2020-12-01 12:53:53 +00:00
Sergei Slashchinin 9cef41000a Merge pull request #18973 from sl-sergei:fix_vulkan_build
* Fix build when HAVE_VULKAN is ON

* Fix warnings
2020-12-01 12:52:09 +00:00
Alexander Alekhin fc54853d44 Merge pull request #18972 from Rightpoint:task/colejd/prevent-existing-xcframework-error 2020-12-01 12:36:29 +00:00
Alexander Alekhin 6f5af6eb42 Merge pull request #18982 from anton-potapov:sole_tbb_executor_async_test 2020-12-01 12:34:12 +00:00
Anton Potapov eb6d8e6af2 TBB executor for GAPI: fix race consition in Async test
The test has race condition, which is addressed by the patch.

The race is next:

    Master thread is calling execute (effectively blocked, waiting for
callback to be called)
    "Async" thread picks up the callback
    Call the callback
    Then sets the variables in test
    After call back is called, master thread is unblocked and may check
the variables (set in point 4 by the "async" thread) earlier then they
actually changed

Changes:

    callback should be called as the last step (after flag variables are
    set), as it effectively unblock the master thread

fixes #18974
2020-12-01 11:12:36 +03:00
Anton Potapov 446f344818 GAPI: fix C++17 compilation errors in GNetPackage (fixes #17385)
- explicitly declared default constructor
- made initilizer_list  constructor to accept the list by copy
   -- as it is  more canonical (and as copying the initializer_list does
not force copy of the list items)
   -- current version anyway does not do what it is intended to
2020-12-01 09:34:53 +03:00
Chris Ballinger 3c40f87af3 Bump default IPHONEOS_DEPLOYMENT_TARGET to 9.0 2020-11-30 17:34:34 -08:00
Alexander Alekhin aac30e772f Merge pull request #18968 from asmorkalov:as/cap_prop_frame_msec_test 2020-11-30 22:49:54 +00:00
Jonathan Cole 69e1167882 Delete xcframework if it already exists before building a new one 2020-11-30 16:51:48 -05:00
Alexander Alekhin acc142d4ba Merge pull request #18930 from alalek:issue_18502 2020-11-30 18:22:59 +00:00
Alexander Alekhin e726ff3296 Merge pull request #18948 from alalek:python_syntax 2020-11-30 18:11:43 +00:00
Anna Khakimova 56568dae31 Merge pull request #18674 from anna-khakimova:ak/backgroundSubtractor
GAPI: New BackgroundSubtractor stateful kernel

* New BackgroundSubtractorMOG2 kernel

* Add BS parameters
2020-11-30 18:09:42 +00:00
Alexander Smorkalov 24fac5f56d Added test for VideoCapture CAP_PROP_FRAME_MSEC option.
- Suppressed FFMPEG + h264, h265 as it does not pass tests with CI configuration.
- Suppressed MediaFoundation backend as it always returns zero for now.
2020-11-30 20:08:21 +03:00
Anton Potapov 74b6646737 GAPI: reuse copy_through_move_t in the gasync.cpp file 2020-11-30 16:26:54 +03:00
Orest Chura 986ad4ff06 Merge pull request #18857 from OrestChura:oc/kmeans
[G-API]: kmeans() Standard Kernel Implementation

* cv::gapi::kmeans kernel implementation
 - 4 overloads:
    - standard GMat - for any dimensionality
    - GMat without bestLabels initialization
    - GArray<Point2f> - for 2D
    - GArray<Point3f> - for 3D
 - Accuracy tests:
   - for every input - 2 tests
   1) without initializing. In this case, no comparison with cv::kmeans is done as kmeans uses random auto-initialization
   2) with initialization
   - in both cases, only 1 attempt is done as after first attempt kmeans initializes bestLabels randomly

* Addressing comments
 - bestLabels is returned to its original place among parameters
 - checkVector and isPointsVector functions are merged into one, shared between core.hpp & imgproc.hpp by placing it into gmat.hpp (and implementation - to gmat.cpp)
 - typos corrected

* addressing comments
 - unified names in tests
 - const added
 - typos

* Addressing comments
 - fixed the doc note
 - ddepth -> expectedDepth, `< 0 ` -> `== -1`

* Fix unsupported cases of input Mat
 - supported: multiple channels, reversed width
 - added test cases for those
 - added notes in docs
 - refactored checkVector to return dimentionality along with quantity

* Addressing comments
 - makes chackVector smaller and (maybe) clearer

* Addressing comments

* Addressing comments
 - cv::checkVector -> cv::gapi::detail

* Addressing comments
 - Changed checkVector: returns bool, quantity & dimensionality as references

* Addressing comments
 - Polishing checkVector
 - FIXME added

* Addressing discussion
 - checkVector: added overload, separate two different functionalities
 - depth assert - out of the function

* Addressing comments
 - quantity -> amount, dimensionality -> dim
 - Fix typos

* Addressing comments
 - fix docs
 - use 2 variable's definitions instead of one (for all non-trivial variables)
2020-11-30 13:18:43 +00:00
Anton Potapov 95ce8f45ea Merge pull request #17851 from anton-potapov:sole_tbb_executor
* TBB executor for GAPI

 - the sole executor
 - unit tests for it
 - no usage in the GAPI at the momnet

* TBB executor for GAPI

 - introduced new overload of execute to explicitly accept tbb::arena
   argument
 - added more basic tests
 - moved arena creation code into tests
 -

* TBB executor for GAPI

 - fixed compie errors & warnings

* TBB executor for GAPI

 - split all-in-one execute() function into logicaly independant parts

* TBB executor for GAPI

 - used util::variant in in the tile_node

* TBB executor for GAPI

 - moved copy_through_move to separate header
 - rearranged details staff in proper namespaces
 - moved all implementation into detail namespace

* TBB executor for GAPI

 - fixed build error with TBB 4.4.
 - fixed build warnings

* TBB executor for GAPI

 - aligned strings width
 - fixed spaces in expressions
 - fixed english grammar
 - minor improvements

* TBB executor for GAPI

 - added more comments
 - minor improvements

* TBB executor for GAPI

 - changed ITT_ prefix for macroses to GAPI_ITT

* TBB executor for GAPI

 - no more "unused" warning for GAPI_DbgAssert
 - changed local assert macro to man onto GAPI_DbgAssert

* TBB executor for GAPI

 - file renamings
 - changed local assert macro to man onto GAPI_DbgAsse

* TBB executor for GAPI

 - test file renamed
 - add more comments

* TBB executor for GAPI

 - minor clenups and cosmetic changes

* TBB executor for GAPI

 - minor clenups and cosmetic changes

* TBB executor for GAPI

 - changed spaces and curly braces alignment

* TBB executor for GAPI

 - minor cleanups

* TBB executor for GAPI

 - minor cleanups
2020-11-30 13:15:13 +00:00
Zhiming-Zeng 4e4458416d Merge pull request #18064 from akineeic:gsoc_2020_dnn
[GSoC] Develop OpenCV.js DNN modules for promising web use cases together with their tutorials

* [Opencv.js doc] Init commit to add image classification example in opencv.js tutorial

* [Opencv.js doc] Make the code snippet interactive and put the functions into code snippet.

* Fix the utils.loadOpenCv for promise module

* [Opencv.js doc] Code modify and fixed layout issue.

* [Opencv.js doc] Add a JSON file to store parameters for models and show in the web page.

* [Opencv.js doc] Change let to const.

* [Opencv.js doc] Init commit to add image classification example with camera in opencv.js tutorial

* [Opencv.js doc] Init commit to add semantic segmentation example in opencv.js tutorial

* [Opencv.js doc] Add object detection example, supprot YOLOv2

* [Opencv.js doc] Support SSD model for object detection example

* [Opencv.js doc] Add fast neural style transfer example with opencv.js

* [Opencv.js doc] Add pose estimation example in opencv.js tutorial

* Delete whitespace for code check

* [Opencv.js doc] Add object detection example with camera

* [Opencv.js doc] Add json files containing model information to each example

* [Opencv.js doc] Add a js file for common function in dnn example

* [Opencv.js doc] Create single function getBlobFromImage

* [Opencv.js doc] Add url of model into webpage

* [OpenCV.js doc] Update UI for running

* [Opencv.js doc] Load dnn model by input button

* [Opencv.js doc] Fix some UI issues

* [Opencv.js doc] Change code format

Co-authored-by: Ningxin Hu <ningxin.hu@intel.com>
2020-11-29 10:09:42 +00:00
Alexander Alekhin da2978f607 ts: cvtest::debugLevel / --test_debug=<N> option 2020-11-28 13:13:28 +00:00
Anatoliy Talamanov 7521f207b1 Merge pull request #18762 from TolyaTalamanov:at/support-garray
[G-API] Wrap GArray

* Wrap GArray for output

* Collect in/out info in graph

* Add imgproc tests

* Add cv::Point2f

* Update test_gapi_imgproc.py

* Fix comments to review
2020-11-27 17:39:46 +00:00
Alexander Alekhin 2155296a13 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-11-27 14:08:06 +00:00
Alexander Alekhin 23be514886 Merge pull request #18935 from rgarnov:rg/remove_double_handle_new_stream_call 2020-11-27 14:05:01 +00:00
Alexander Alekhin 77b986c7a1 apple/build_xcframework.py: python syntax
- make happy old Python linters
2020-11-27 13:54:14 +00:00
Alexander Alekhin f90673ef4c Merge pull request #18938 from alalek:issue_18865 2020-11-27 08:55:49 +00:00
Alexander Alekhin df18431b45 Merge pull request #18285 from YashasSamaga:cuda4dnn-update-tests 2020-11-27 08:26:45 +00:00
Alexander Alekhin 7c78c59e64 Merge pull request #18939 from alalek:unstable_test_18937 2020-11-27 08:21:25 +00:00
Alexander Alekhin 5c987e4c75 Merge pull request #18924 from alalek:4.x-xcode12
(4.x) build: Xcode 12 support

* build: xcode 12 support, cmake fixes

* ts: eliminate clang 11 warnigns

* 3rdparty: clang 11 warnings

* features2d: eliminate build warnings

* test: warnings

* gapi: warnings from 18928
2020-11-26 22:56:59 +00:00
Alexander Alekhin 0cc92bd67c Merge pull request #18922 from alalek:3.4-xcode12 2020-11-26 22:14:55 +00:00
Alexander Alekhin 7efc0011fd gapi(test): avoid anonymous namespace types as template parameters 2020-11-26 21:37:54 +00:00
Alexander Alekhin 2cf2456f4c dnn(test): skip unstable GatherMultiOutput OCL_FP16 test 2020-11-26 21:30:21 +00:00
Ruslan Garnov ece14eae24 Removed redundant call of handleNewStream in streaming executor 2020-11-26 22:46:26 +03:00
Alexander Alekhin 3c9d03c36f Merge pull request #18929 from alalek:gapi_test_eliminate_rand 2020-11-26 16:03:35 +00:00
Alexander Alekhin 8c5b3c4150 Merge pull request #17077 from i386x:check-negative-values 2020-11-26 15:07:58 +00:00
Alexander Alekhin 36d771affc python: restore sys.path in bootstrap()
- multiprocessing need to start from bootstrap code
- loading may fail due to missing os.add_dll_directory() calls
2020-11-26 13:10:25 +00:00
Alexander Alekhin 7afd48658c gapi: eliminate std::rand() and RAND_MAX from tests 2020-11-26 10:20:02 +00:00
Alexander Alekhin 387a76ba59 build: xcode 12 support, cmake fixes 2020-11-26 07:54:03 +00:00
Alexander Alekhin f601e817fe Merge pull request #18914 from alalek:videoio_fix_missing_get_capture_domain 2020-11-25 13:46:57 +00:00
Alexander Alekhin 3fd0d0dafb Merge pull request #18918 from gabrielnhn:patch-2 2020-11-25 13:46:37 +00:00
Gabriel Nascarella Hishida f28895cd6b doc: Fix example code using deprecated xrange
xrange was abandoned and doesn't exist in Python 3. range() works just the same
2020-11-25 09:34:38 -03:00
Alexander Alekhin d65c6af3a5 Merge pull request #18907 from diablodale:exec_context_create_addref 2020-11-25 09:25:57 +00:00
Dale Phurrough c08e38acd0 fix missing addref() in ocl::Context::create(str)
- fix https://github.com/opencv/opencv/issues/18906
- unable to add related test cases as there is
  no public access to Context:Impl refcounts
2020-11-25 01:53:41 +01:00
Alexander Alekhin 0800f6f91b videoio: add missing getCaptureDomain() methods 2020-11-24 22:26:10 +00:00
Jonathan Cole 85b0fb2a9c Merge pull request #18826 from Rightpoint:feature/colejd/build-catalyst-xcframework
Support XCFramework builds, Catalyst

* Early work on xcframework support

* Improve legibility

* Somehow this works

* Specify ABIs in a place where they won't get erased

If you pass in the C/CXX flags from the Python script, they won't be respected. By doing it in the actual toolchain, the options are respected and Catalyst successfully links.

* Clean up and push updates

* Actually use Catalyst ABI

Needed to specify EXE linker flags to get compiler tests to link to the Catalyst ABIs.

* Clean up

* Revert changes to common toolchain that don't matter

* Try some things

* Support Catalyst build in OSX scripts

* Remove unnecessary iOS reference to AssetsLibrary framework

* Getting closer

* Try some things, port to Python 3

* Some additional fixes

* Point Cmake Plist gen to osx directory for Catalyst targets

* Remove dynamic lib references for Catalyst, copy iOS instead of macos

* Add flag for building only specified archs, remove iOS catalyst refs

* Add build-xcframework.sh

* Update build-xcframework.sh

* Add presumptive Apple Silicon support

* Add arm64 iphonesimulator target

* Fix xcframework build

* Working on arm64 iOS simulator

* Support 2.7 (replace run with check_output)

* Correctly check output of uname_m against arch

* Clean up

* Use lipo for intermediate frameworks, add python script

Remove unneeded __init__.py

* Simplify python xcframework build script

* Add --only-64-bit flag

* Add --framework-name flag

* Document

* Commit to f-strings, improve console output

* Add i386 to iphonesimulator platform in xcframework generator

* Enable objc for non-Catalyst frameworks

* Fix xcframework builder for paths with spaces

* Use arch when specifying Catalyst build platform in build command

* Fix incorrect settings for framework_name argparse configuration

* Prefer underscores instead of hyphens in new flags

* Move Catalyst flags to where they'll actually get used

* Use --without=objc on Catalyst target for now

* Remove get_or_create_folder and simplify logic

* Remove unused import

* Tighten up help text

* Document

* Move common functions into cv_build_utils

* Improve documentation

* Remove old build script

* Add readme

* Check for required CMake and Xcode versions

* Clean up TODOs and re-enable `copy_samples()`

Remove TODO

Fixup

* Add missing print_function import

* Clarify CMake dependency documentation

* Revert python2 change in gen_objc

* Remove unnecessary builtins imports

* Remove trailing whitespace

* Avoid building Catalyst unless specified

This makes Catalyst support a non-breaking change, though defaults should be specified when a breaking change is possible.

* Prevent lipoing for the same archs on different platforms before build

* Rename build-xcframework.py to build_xcframework.py

* Check for duplicate archs more carefully

* Prevent sample copying error when directory already exists

This can happen when building multiple architectures for the same platform.

* Simplify code for checking for default archs

* Improve build_xcframework.py header text

* Correctly resolve Python script paths

* Parse only known args in ios/osx build_framework.py

* Pass through uncaptured args in build_xcframework to osx/ios build

* Fix typo

* Fix typo

* Fix unparameterized build path for intermediate frameworks

* Fix dyanmic info.plist path for catalyst

* Fix utf-8 Python 3 issue

* Add dynamic flag to osx script

* Rename platform to platforms, remove armv7s and i386

* Fix creation of dynamic framework on maccatalyst and macos

* Update platforms/apple/readme.md

* Add `macos_archs` flag and deprecate `archs` flag

* Allow specification of archs when generating xcframework from terminal

* Change xcframework platform argument names to match archs flag names

* Remove platforms as a concept and shadow archs flags from ios/osx .py

* Improve documentation

* Fix building of objc module on Catalyst, excluding Swift

* Clean up build folder logic a bit

* Fix framework_name flag

* Drop passthrough_args, use unknown_args instead

* minor: coding style changes

Co-authored-by: Chris Ballinger <cballinger@rightpoint.com>
2020-11-24 21:54:54 +00:00
Maxim Pashchenkov 19d825aa16 Merge pull request #18904 from mpashchenkov:mp/ocv-gapi-skip-gm-tests
G-API: Adding skip for GraphMeta tests

* Added skip for GraphMeta tests

* Removed false
2020-11-24 17:51:02 +00:00
Sergei Slashchinin f4f462c50b Merge pull request #18862 from sl-sergei:support_pool1d
Support for Pool1d layer for OpenCV and OpenCL targets

* Initial version of Pool1d support

* Fix variable naming

* Fix 1d pooling for OpenCL

* Change support logic, remove unnecessary variable, split the tests

* Remove other depricated variables

* Fix warning. Check tests

* Change support check logic

* Change support check logic, 2
2020-11-24 16:52:45 +00:00
Alexander Alekhin e1a8fc0417 Merge pull request #18905 from alalek:objc_fix_return_type_handling 2020-11-24 11:39:01 +00:00
Alexander Alekhin eafe6ccdbe objc: fix handling of std::vector<std::vector<T>> return type 2020-11-23 19:16:23 +00:00
Alexander Alekhin 359ecda4fc Merge pull request #18896 from alalek:cmake_fix_eigen_detection 2020-11-23 17:19:18 +00:00
Alexander Alekhin bf0846f0ea Merge pull request #18895 from oravital7:flip-module 2020-11-23 17:18:59 +00:00
Alexander Alekhin 0401d5920c Merge pull request #18845 from joegeisbauer:fix_reduce_mean_index_error 2020-11-23 17:03:47 +00:00
Alexander Alekhin ac418e999d cmake: update condition for find_package(Eigen3 CONFIG) 2020-11-22 16:28:53 +00:00
Alexander Alekhin ae42815b7d Merge pull request #18887 from HollowMan6:patch-1 2020-11-22 14:40:30 +00:00
Or Avital 5a3a915a9b Remove unnecessary condition (will never reach) 2020-11-22 14:19:20 +02:00
Hollow Man 632a08ff40 Fix typo in docs
adatapted -> adapted
2020-11-22 00:38:37 +08:00
YashasSamaga 0f8ab0557e enable fusion tests, update thresholds and fix missed eltwise fusions 2020-11-21 17:35:20 +05:30
Alexander Alekhin 1b3dd8f38b Merge pull request #18882 from alalek:build_warning_calib3d_drop_register 2020-11-20 22:46:31 +00:00
Jiri Kucera ce31c9c448 core(matrix): Negative values checks
Add checks that prevents indexing an array by negative values.
2020-11-20 22:51:06 +01:00
Alexander Alekhin bc434e8f67 calib3d: eliminate 'register' build warning 2020-11-20 20:32:59 +00:00
Alexander Alekhin 0105f8fa38 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2020-11-20 20:32:00 +00:00
Joe e05c2e0f1d Fix Reduce Mean error for MobileNets DNN
Fix for index error for Reduce Mean

Correct Reduce Mean indexing error
2020-11-20 11:17:02 -06:00
Nathan Godwin 2255973b0f Merge pull request #18371 from nathanrgodwin:sqpnp_dev
Added SQPnP algorithm to SolvePnP

* Added sqpnp

* Fixed test case

* Added fix for duplicate point checking and inverse func reuse

* Changes for 3x speedup

Changed norm method (significant speed increase), changed nearest rotation computation to FOAM

* Added symmetric 3x3 inverse and unrolled loops

* Fixed error with SVD

* Fixed error from with indices

Indices were initialized negative. When nullspace is large, points coplanar, and rotation near 0, indices not changed.
2020-11-20 11:25:17 +00:00
Julien ac24a72e66 Merge pull request #18841 from JulienMaille:patch-2
Fixing dnn Resize layer for variable input size

* Fix onnx loading of resize/upsample layers for different opset

* group all DynamicResize tests

* cleaned up scales checks

* Simplify branching
2020-11-20 11:14:00 +00:00
Alexander Alekhin 049b50d9c0 Merge pull request #18858 from fegorsch:improve-persistence-doc 2020-11-20 11:12:25 +00:00
Alexander Alekhin 12fd382fec Merge pull request #18868 from mpashchenkov:mp/onnx-small-cmake-fix 2020-11-20 08:37:21 +00:00
Felix Gorschlüter c996fd1c06 Small improvements to persistence-API doc 2020-11-20 10:49:51 +03:00
Jonathan Cole c4c9cdd2b1 Merge pull request #18855 from Rightpoint:feature/colejd/add-apple-conversions-to-framework-builds
Expose CGImage <-> Mat conversion for iOS platforms

* Add apple_conversions to framework builds

This exposes CGImage <-> Mat conversion.

* Export Mat <-> CGImage methods on iOS targets

* Add CGImage converters to iOS objc helper class

* Add CF_RETURNS_RETAINED annotations to methods returning CGImageRef
2020-11-19 21:20:32 +00:00
Maxim Pashchenkov 34c4e454c5 Added small cmake fix 2020-11-19 21:22:19 +03:00
chargerKong 11cfa64a10 Merge pull request #18335 from chargerKong:master
Ordinary quaternion

* version 1.0

* add assumeUnit;
add UnitTest;
check boundary value;
fix the func using method: func(obj);
fix 4x4;
add rodrigues vector transformation;
fix mat to quat;

* fix blank and tab

* fix blank and tab
modify test;cpp to hpp

* mainly improve comment;
add rvec2Quat;fix toRodrigues;
fix throw to CV_Error

* fix bug of quatd * int;
combine hpp and cpp;
fix << overload error in win system;
modify include in test file;

* move implementation to quaternion.ini.hpp;
change some constructor to createFrom* function;
change Rodrigues vector to rotation vector;
change the matexpr to mat of 3x3 return type;
improve comments;

* try fix log function error in win

* add enums for assumeUnit;
improve docs;
add using std::cos funcs

* remove using std::* from header;
add std::* in affine.hpp,warpers_inl.hpp;

* quat: coding style

* quat: AssumeType => QuatAssumeType
2020-11-19 16:59:33 +00:00
Alexander Alekhin adafb20d1e Merge pull request #18854 from GArik:orbbec 2020-11-19 12:00:59 +00:00
Ian Maquignaz bb067c7ebf Merge pull request #18849 from IanMaquignaz:fix_findFundamentalMat_parameters
Minimum change to address issue #18837
2020-11-19 11:20:20 +00:00
Alexander Alekhin 599bb9c457 Merge pull request #18848 from IanMaquignaz:fixEpipolarGeometryTutorial 2020-11-19 11:18:03 +00:00
Alexander Alekhin dbfa1bfba4 Merge pull request #18863 from l-bat:lb/fix_test 2020-11-19 11:01:14 +00:00
Igor Murzov f8c7862f69 Add tutorial on how to use Orbbec Astra 3D cameras 2020-11-19 13:31:22 +03:00
Liubov Batanina b86f129393 Fixed Test_Model.DetectionOutput 2020-11-19 12:11:52 +03:00
Jojo R 12b8d542b7 norm.cpp(normL2Sqr_): improve performance of pipeline
The most of target machine use one type cpu unit resource
to execute some one type of instruction, e.g.
all vx_load API use load/store cpu unit,
and v_muladd API use mul/mula cpu unit, we interleave
vx_load and v_muladd to improve performance on most targets like
RISCV or ARM.
2020-11-19 09:49:49 +08:00
Ian Maquignaz fef23768fe Fixed issue with Epipolar Geometry Tutorial 2020-11-18 12:34:27 -05:00
Alexander Alekhin 328883b6ea Merge pull request #18675 from sturkmen72:update-documentation 2020-11-18 16:50:35 +00:00
Alexander Alekhin 87ed750510 Merge pull request #17839 from malliaridis:master 2020-11-18 16:48:36 +00:00
Suleyman TURKMEN cc7f17f011 update documentation 2020-11-18 17:07:04 +03:00
Christos Malliaridis 3c25fd1ba5 Update and expand erosion / dilation tutorial
- Add python explanation for erosion and dilation
- Add java explanation for erosion and dilation
- Restructure and reword specific sections
2020-11-18 13:32:24 +01:00
ZhangYin b91e701f35 modified rvv option for clang to match LLVM upstream 2020-09-29 14:15:11 +08:00
607 changed files with 21477 additions and 4423 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
name: arm64 build checks
on: [pull_request]
on: workflow_dispatch
jobs:
build:
+1
View File
@@ -109,6 +109,7 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow -Wunused -Wsign-compare -Wundef -W
-Wmissing-prototypes # gcc/clang
-Wreorder
-Wunused-result
-Wimplicit-const-int-float-conversion # clang
)
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wclass-memaccess)
+4
View File
@@ -11,6 +11,10 @@ set(OPENJPEG_LIBRARY_NAME libopenjp2)
project(openjpeg C)
ocv_warnings_disable(CMAKE_C_FLAGS
-Wimplicit-const-int-float-conversion # clang
)
#-----------------------------------------------------------------------------
# OPENJPEG version number, useful for packaging and doxygen doc:
set(OPENJPEG_VERSION_MAJOR 2)
+5
View File
@@ -153,6 +153,11 @@ set_target_properties(libprotobuf
ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}
)
if(ANDROID)
# https://github.com/opencv/opencv/issues/17282
target_link_libraries(libprotobuf INTERFACE "-landroid" "-llog")
endif()
get_protobuf_version(Protobuf_VERSION "${PROTOBUF_ROOT}/src")
set(Protobuf_VERSION ${Protobuf_VERSION} CACHE INTERNAL "" FORCE)
+2 -4
View File
@@ -17,9 +17,7 @@ endif()
include(cmake/OpenCVMinDepVersions.cmake)
if(CMAKE_GENERATOR MATCHES Xcode AND XCODE_VERSION VERSION_GREATER 4.3)
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
elseif(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
#Required to resolve linker error issues due to incompatibility with CMake v3.0+ policies.
#CMake fails to find _fseeko() which leads to subsequent linker error.
@@ -488,7 +486,7 @@ OCV_OPTION(OPENCV_ENABLE_MEMORY_SANITIZER "Better support for memory/address san
OCV_OPTION(ENABLE_OMIT_FRAME_POINTER "Enable -fomit-frame-pointer for GCC" ON IF CV_GCC )
OCV_OPTION(ENABLE_POWERPC "Enable PowerPC for GCC" ON IF (CV_GCC AND CMAKE_SYSTEM_PROCESSOR MATCHES powerpc.*) )
OCV_OPTION(ENABLE_FAST_MATH "Enable compiler options for fast math optimizations on FP computations (not recommended)" OFF)
if(NOT IOS AND (NOT ANDROID OR OPENCV_ANDROID_USE_LEGACY_FLAGS)) # Use CPU_BASELINE instead
if(NOT IOS AND (NOT ANDROID OR OPENCV_ANDROID_USE_LEGACY_FLAGS) AND CMAKE_CROSSCOMPILING) # Use CPU_BASELINE instead
OCV_OPTION(ENABLE_NEON "Enable NEON instructions" (NEON OR ANDROID_ARM_NEON OR AARCH64) IF (CV_GCC OR CV_CLANG) AND (ARM OR AARCH64 OR IOS) )
OCV_OPTION(ENABLE_VFPV3 "Enable VFPv3-D32 instructions" OFF IF (CV_GCC OR CV_CLANG) AND (ARM OR AARCH64 OR IOS) )
endif()
+1 -1
View File
@@ -4,7 +4,7 @@ set(ONNXRT_ROOT_DIR "" CACHE PATH "ONNX Runtime install directory")
# For now, check the old name ORT_INSTALL_DIR
if(ORT_INSTALL_DIR AND NOT ONNXRT_ROOT_DIR)
set(ONNXRT_ROOT_DIR ORT_INSTALL_DIR)
set(ONNXRT_ROOT_DIR ${ORT_INSTALL_DIR})
endif()
if(ONNXRT_ROOT_DIR)
+1 -2
View File
@@ -122,7 +122,6 @@ if(CV_GCC OR CV_CLANG)
endif()
add_extra_compiler_option(-Wsign-promo)
add_extra_compiler_option(-Wuninitialized)
add_extra_compiler_option(-Winit-self)
if(CV_GCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0) AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
add_extra_compiler_option(-Wno-psabi)
endif()
@@ -153,7 +152,7 @@ if(CV_GCC OR CV_CLANG)
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
add_extra_compiler_option(-Wno-missing-field-initializers) # GCC 4.x emits warnings about {}, fixed in GCC 5+
endif()
if(CV_CLANG AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
if(CV_CLANG AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
add_extra_compiler_option(-Wno-deprecated-enum-enum-conversion)
add_extra_compiler_option(-Wno-deprecated-anon-enum-enum-conversion)
endif()
+2 -2
View File
@@ -129,9 +129,9 @@ endif()
if(INF_ENGINE_TARGET)
if(NOT INF_ENGINE_RELEASE)
message(WARNING "InferenceEngine version has not been set, 2021.1 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
message(WARNING "InferenceEngine version has not been set, 2021.2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
endif()
set(INF_ENGINE_RELEASE "2021010000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
set(INF_ENGINE_RELEASE "2021020000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
)
+26 -18
View File
@@ -6,6 +6,7 @@
if(BUILD_ZLIB)
ocv_clear_vars(ZLIB_FOUND)
else()
ocv_clear_internal_cache_vars(ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
find_package(ZLIB "${MIN_VER_ZLIB}")
if(ZLIB_FOUND AND ANDROID)
if(ZLIB_LIBRARIES MATCHES "/usr/(lib|lib32|lib64)/libz.so$")
@@ -15,11 +16,12 @@ else()
endif()
if(NOT ZLIB_FOUND)
ocv_clear_vars(ZLIB_LIBRARY ZLIB_LIBRARIES ZLIB_INCLUDE_DIRS)
ocv_clear_vars(ZLIB_LIBRARY ZLIB_LIBRARIES ZLIB_INCLUDE_DIR)
set(ZLIB_LIBRARY zlib)
set(ZLIB_LIBRARY zlib CACHE INTERNAL "")
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/zlib")
set(ZLIB_INCLUDE_DIRS "${${ZLIB_LIBRARY}_SOURCE_DIR}" "${${ZLIB_LIBRARY}_BINARY_DIR}")
set(ZLIB_INCLUDE_DIR "${${ZLIB_LIBRARY}_SOURCE_DIR}" "${${ZLIB_LIBRARY}_BINARY_DIR}" CACHE INTERNAL "")
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
ocv_parse_header2(ZLIB "${${ZLIB_LIBRARY}_SOURCE_DIR}/zlib.h" ZLIB_VERSION)
@@ -30,23 +32,25 @@ if(WITH_JPEG)
if(BUILD_JPEG)
ocv_clear_vars(JPEG_FOUND)
else()
ocv_clear_internal_cache_vars(JPEG_LIBRARY JPEG_INCLUDE_DIR)
include(FindJPEG)
endif()
if(NOT JPEG_FOUND)
ocv_clear_vars(JPEG_LIBRARY JPEG_LIBRARIES JPEG_INCLUDE_DIR)
ocv_clear_vars(JPEG_LIBRARY JPEG_INCLUDE_DIR)
if(NOT BUILD_JPEG_TURBO_DISABLE)
set(JPEG_LIBRARY libjpeg-turbo)
set(JPEG_LIBRARY libjpeg-turbo CACHE INTERNAL "")
set(JPEG_LIBRARIES ${JPEG_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg-turbo")
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}/src")
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}/src" CACHE INTERNAL "")
else()
set(JPEG_LIBRARY libjpeg)
set(JPEG_LIBRARY libjpeg CACHE INTERNAL "")
set(JPEG_LIBRARIES ${JPEG_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg")
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}")
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}" CACHE INTERNAL "")
endif()
set(JPEG_INCLUDE_DIRS "${JPEG_INCLUDE_DIR}")
endif()
macro(ocv_detect_jpeg_version header_file)
@@ -74,6 +78,7 @@ if(WITH_TIFF)
if(BUILD_TIFF)
ocv_clear_vars(TIFF_FOUND)
else()
ocv_clear_internal_cache_vars(TIFF_LIBRARY TIFF_INCLUDE_DIR)
include(FindTIFF)
if(TIFF_FOUND)
ocv_parse_header("${TIFF_INCLUDE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
@@ -83,10 +88,10 @@ if(WITH_TIFF)
if(NOT TIFF_FOUND)
ocv_clear_vars(TIFF_LIBRARY TIFF_LIBRARIES TIFF_INCLUDE_DIR)
set(TIFF_LIBRARY libtiff)
set(TIFF_LIBRARY libtiff CACHE INTERNAL "")
set(TIFF_LIBRARIES ${TIFF_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libtiff")
set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}")
set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}" CACHE INTERNAL "")
ocv_parse_header("${${TIFF_LIBRARY}_SOURCE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
endif()
@@ -117,6 +122,7 @@ if(WITH_WEBP)
if(BUILD_WEBP)
ocv_clear_vars(WEBP_FOUND WEBP_LIBRARY WEBP_LIBRARIES WEBP_INCLUDE_DIR)
else()
ocv_clear_internal_cache_vars(WEBP_LIBRARY WEBP_INCLUDE_DIR)
include(cmake/OpenCVFindWebP.cmake)
if(WEBP_FOUND)
set(HAVE_WEBP 1)
@@ -128,12 +134,12 @@ endif()
if(WITH_WEBP AND NOT WEBP_FOUND
AND (NOT ANDROID OR HAVE_CPUFEATURES)
)
set(WEBP_LIBRARY libwebp)
ocv_clear_vars(WEBP_LIBRARY WEBP_INCLUDE_DIR)
set(WEBP_LIBRARY libwebp CACHE INTERNAL "")
set(WEBP_LIBRARIES ${WEBP_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libwebp")
set(WEBP_INCLUDE_DIR "${${WEBP_LIBRARY}_SOURCE_DIR}/src")
set(WEBP_INCLUDE_DIR "${${WEBP_LIBRARY}_SOURCE_DIR}/src" CACHE INTERNAL "")
set(HAVE_WEBP 1)
endif()
@@ -192,10 +198,10 @@ if(WITH_JASPER AND NOT HAVE_OPENJPEG)
if(NOT JASPER_FOUND)
ocv_clear_vars(JASPER_LIBRARY JASPER_LIBRARIES JASPER_INCLUDE_DIR)
set(JASPER_LIBRARY libjasper)
set(JASPER_LIBRARY libjasper CACHE INTERNAL "")
set(JASPER_LIBRARIES ${JASPER_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjasper")
set(JASPER_INCLUDE_DIR "${${JASPER_LIBRARY}_SOURCE_DIR}")
set(JASPER_INCLUDE_DIR "${${JASPER_LIBRARY}_SOURCE_DIR}" CACHE INTERNAL "")
endif()
set(HAVE_JASPER YES)
@@ -210,6 +216,7 @@ if(WITH_PNG)
if(BUILD_PNG)
ocv_clear_vars(PNG_FOUND)
else()
ocv_clear_internal_cache_vars(PNG_LIBRARY PNG_INCLUDE_DIR)
include(FindPNG)
if(PNG_FOUND)
include(CheckIncludeFile)
@@ -225,10 +232,10 @@ if(WITH_PNG)
if(NOT PNG_FOUND)
ocv_clear_vars(PNG_LIBRARY PNG_LIBRARIES PNG_INCLUDE_DIR PNG_PNG_INCLUDE_DIR HAVE_LIBPNG_PNG_H PNG_DEFINITIONS)
set(PNG_LIBRARY libpng)
set(PNG_LIBRARY libpng CACHE INTERNAL "")
set(PNG_LIBRARIES ${PNG_LIBRARY})
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libpng")
set(PNG_INCLUDE_DIR "${${PNG_LIBRARY}_SOURCE_DIR}")
set(PNG_INCLUDE_DIR "${${PNG_LIBRARY}_SOURCE_DIR}" CACHE INTERNAL "")
set(PNG_DEFINITIONS "")
ocv_parse_header("${PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
endif()
@@ -241,6 +248,7 @@ endif()
if(WITH_OPENEXR)
ocv_clear_vars(HAVE_OPENEXR)
if(NOT BUILD_OPENEXR)
ocv_clear_internal_cache_vars(OPENEXR_INCLUDE_PATHS OPENEXR_LIBRARIES OPENEXR_ILMIMF_LIBRARY OPENEXR_VERSION)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindOpenEXR.cmake")
endif()
@@ -270,7 +278,7 @@ if(WITH_GDAL)
endif()
endif()
if (WITH_GDCM)
if(WITH_GDCM)
find_package(GDCM QUIET)
if(NOT GDCM_FOUND)
set(HAVE_GDCM NO)
+4 -1
View File
@@ -51,7 +51,10 @@ endif(WITH_CUDA)
# --- Eigen ---
if(WITH_EIGEN AND NOT HAVE_EIGEN)
if(NOT OPENCV_SKIP_EIGEN_FIND_PACKAGE_CONFIG)
if((OPENCV_FORCE_EIGEN_FIND_PACKAGE_CONFIG
OR NOT (CMAKE_VERSION VERSION_LESS "3.0.0") # Eigen3Targets.cmake required CMake 3.0.0+
) AND NOT OPENCV_SKIP_EIGEN_FIND_PACKAGE_CONFIG
)
find_package(Eigen3 CONFIG QUIET) # Ceres 2.0.0 CMake scripts doesn't work with CMake's FindEigen3.cmake module (due to missing EIGEN3_VERSION_STRING)
endif()
if(NOT Eigen3_FOUND)
+87 -65
View File
@@ -3,7 +3,14 @@
# installation/package
#
# Parameters:
# MKL_WITH_TBB
# MKL_ROOT_DIR / ENV{MKLROOT}
# MKL_INCLUDE_DIR
# MKL_LIBRARIES
# MKL_USE_SINGLE_DYNAMIC_LIBRARY - use single dynamic library mkl_rt.lib / libmkl_rt.so
# MKL_WITH_TBB / MKL_WITH_OPENMP
#
# Extra:
# MKL_LIB_FIND_PATHS
#
# On return this will define:
#
@@ -13,12 +20,6 @@
# MKL_LIBRARIES - MKL libraries that are used by OpenCV
#
macro (mkl_find_lib VAR NAME DIRS)
find_path(${VAR} ${NAME} ${DIRS} NO_DEFAULT_PATH)
set(${VAR} ${${VAR}}/${NAME})
unset(${VAR} CACHE)
endmacro()
macro(mkl_fail)
set(HAVE_MKL OFF)
set(MKL_ROOT_DIR "${MKL_ROOT_DIR}" CACHE PATH "Path to MKL directory")
@@ -39,43 +40,50 @@ macro(get_mkl_version VERSION_FILE)
set(MKL_VERSION_STR "${MKL_VERSION_MAJOR}.${MKL_VERSION_MINOR}.${MKL_VERSION_UPDATE}" CACHE STRING "MKL version" FORCE)
endmacro()
OCV_OPTION(MKL_USE_SINGLE_DYNAMIC_LIBRARY "Use MKL Single Dynamic Library thorugh mkl_rt.lib / libmkl_rt.so" OFF)
OCV_OPTION(MKL_WITH_TBB "Use MKL with TBB multithreading" OFF)#ON IF WITH_TBB)
OCV_OPTION(MKL_WITH_OPENMP "Use MKL with OpenMP multithreading" OFF)#ON IF WITH_OPENMP)
if(NOT DEFINED MKL_USE_MULTITHREAD)
OCV_OPTION(MKL_WITH_TBB "Use MKL with TBB multithreading" OFF)#ON IF WITH_TBB)
OCV_OPTION(MKL_WITH_OPENMP "Use MKL with OpenMP multithreading" OFF)#ON IF WITH_OPENMP)
if(NOT MKL_ROOT_DIR AND DEFINED MKL_INCLUDE_DIR AND EXISTS "${MKL_INCLUDE_DIR}/mkl.h")
file(TO_CMAKE_PATH "${MKL_INCLUDE_DIR}" MKL_INCLUDE_DIR)
get_filename_component(MKL_ROOT_DIR "${MKL_INCLUDE_DIR}/.." ABSOLUTE)
endif()
if(NOT MKL_ROOT_DIR)
file(TO_CMAKE_PATH "${MKL_ROOT_DIR}" mkl_root_paths)
if(DEFINED ENV{MKLROOT})
file(TO_CMAKE_PATH "$ENV{MKLROOT}" path)
list(APPEND mkl_root_paths "${path}")
endif()
if(WITH_MKL AND NOT mkl_root_paths)
if(WIN32)
set(ProgramFilesx86 "ProgramFiles(x86)")
file(TO_CMAKE_PATH "$ENV{${ProgramFilesx86}}" path)
list(APPEND mkl_root_paths ${path}/IntelSWTools/compilers_and_libraries/windows/mkl)
endif()
if(UNIX)
list(APPEND mkl_root_paths "/opt/intel/mkl")
endif()
endif()
find_path(MKL_ROOT_DIR include/mkl.h PATHS ${mkl_root_paths})
endif()
#check current MKL_ROOT_DIR
if(NOT MKL_ROOT_DIR OR NOT EXISTS "${MKL_ROOT_DIR}/include/mkl.h")
set(mkl_root_paths "${MKL_ROOT_DIR}")
if(DEFINED ENV{MKLROOT})
list(APPEND mkl_root_paths "$ENV{MKLROOT}")
endif()
if(WITH_MKL AND NOT mkl_root_paths)
if(WIN32)
set(ProgramFilesx86 "ProgramFiles(x86)")
list(APPEND mkl_root_paths $ENV{${ProgramFilesx86}}/IntelSWTools/compilers_and_libraries/windows/mkl)
endif()
if(UNIX)
list(APPEND mkl_root_paths "/opt/intel/mkl")
endif()
endif()
find_path(MKL_ROOT_DIR include/mkl.h PATHS ${mkl_root_paths})
mkl_fail()
endif()
set(MKL_INCLUDE_DIRS "${MKL_ROOT_DIR}/include" CACHE PATH "Path to MKL include directory")
set(MKL_INCLUDE_DIR "${MKL_ROOT_DIR}/include" CACHE PATH "Path to MKL include directory")
if(NOT MKL_ROOT_DIR
OR NOT EXISTS "${MKL_ROOT_DIR}"
OR NOT EXISTS "${MKL_INCLUDE_DIRS}"
OR NOT EXISTS "${MKL_INCLUDE_DIRS}/mkl_version.h"
OR NOT EXISTS "${MKL_INCLUDE_DIR}"
OR NOT EXISTS "${MKL_INCLUDE_DIR}/mkl_version.h"
)
mkl_fail()
mkl_fail()
endif()
get_mkl_version(${MKL_INCLUDE_DIRS}/mkl_version.h)
get_mkl_version(${MKL_INCLUDE_DIR}/mkl_version.h)
#determine arch
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
@@ -95,52 +103,66 @@ else()
set(MKL_ARCH_SUFFIX "c")
endif()
if(MKL_VERSION_STR VERSION_GREATER "11.3.0" OR MKL_VERSION_STR VERSION_EQUAL "11.3.0")
set(mkl_lib_find_paths
${MKL_ROOT_DIR}/lib)
foreach(MKL_ARCH ${MKL_ARCH_LIST})
list(APPEND mkl_lib_find_paths
${MKL_ROOT_DIR}/lib/${MKL_ARCH}
${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH}
${MKL_ROOT_DIR}/${MKL_ARCH})
endforeach()
set(mkl_lib_find_paths ${MKL_LIB_FIND_PATHS} ${MKL_ROOT_DIR}/lib)
foreach(MKL_ARCH ${MKL_ARCH_LIST})
list(APPEND mkl_lib_find_paths
${MKL_ROOT_DIR}/lib/${MKL_ARCH}
${MKL_ROOT_DIR}/${MKL_ARCH}
)
endforeach()
set(mkl_lib_list "mkl_intel_${MKL_ARCH_SUFFIX}")
if(MKL_USE_SINGLE_DYNAMIC_LIBRARY AND NOT (MKL_VERSION_STR VERSION_LESS "10.3.0"))
if(MKL_WITH_TBB)
list(APPEND mkl_lib_list mkl_tbb_thread tbb)
elseif(MKL_WITH_OPENMP)
if(MSVC)
list(APPEND mkl_lib_list mkl_intel_thread libiomp5md)
else()
list(APPEND mkl_lib_list mkl_gnu_thread)
endif()
# https://software.intel.com/content/www/us/en/develop/articles/a-new-linking-model-single-dynamic-library-mkl_rt-since-intel-mkl-103.html
set(mkl_lib_list "mkl_rt")
elseif(NOT (MKL_VERSION_STR VERSION_LESS "11.3.0"))
foreach(MKL_ARCH ${MKL_ARCH_LIST})
list(APPEND mkl_lib_find_paths
${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH}
)
endforeach()
set(mkl_lib_list "mkl_intel_${MKL_ARCH_SUFFIX}")
if(MKL_WITH_TBB)
list(APPEND mkl_lib_list mkl_tbb_thread tbb)
elseif(MKL_WITH_OPENMP)
if(MSVC)
list(APPEND mkl_lib_list mkl_intel_thread libiomp5md)
else()
list(APPEND mkl_lib_list mkl_sequential)
list(APPEND mkl_lib_list mkl_gnu_thread)
endif()
else()
list(APPEND mkl_lib_list mkl_sequential)
endif()
list(APPEND mkl_lib_list mkl_core)
list(APPEND mkl_lib_list mkl_core)
else()
message(STATUS "MKL version ${MKL_VERSION_STR} is not supported")
mkl_fail()
message(STATUS "MKL version ${MKL_VERSION_STR} is not supported")
mkl_fail()
endif()
set(MKL_LIBRARIES "")
foreach(lib ${mkl_lib_list})
find_library(${lib} NAMES ${lib} ${lib}_dll HINTS ${mkl_lib_find_paths})
mark_as_advanced(${lib})
if(NOT ${lib})
mkl_fail()
if(NOT MKL_LIBRARIES)
set(MKL_LIBRARIES "")
foreach(lib ${mkl_lib_list})
set(lib_var_name MKL_LIBRARY_${lib})
find_library(${lib_var_name} NAMES ${lib} ${lib}_dll HINTS ${mkl_lib_find_paths})
mark_as_advanced(${lib_var_name})
if(NOT ${lib_var_name})
mkl_fail()
endif()
list(APPEND MKL_LIBRARIES ${${lib}})
endforeach()
list(APPEND MKL_LIBRARIES ${${lib_var_name}})
endforeach()
endif()
message(STATUS "Found MKL ${MKL_VERSION_STR} at: ${MKL_ROOT_DIR}")
set(HAVE_MKL ON)
set(MKL_ROOT_DIR "${MKL_ROOT_DIR}" CACHE PATH "Path to MKL directory")
set(MKL_INCLUDE_DIRS "${MKL_INCLUDE_DIRS}" CACHE PATH "Path to MKL include directory")
set(MKL_LIBRARIES "${MKL_LIBRARIES}" CACHE STRING "MKL libraries")
if(UNIX AND NOT MKL_LIBRARIES_DONT_HACK)
set(MKL_INCLUDE_DIRS "${MKL_INCLUDE_DIR}")
set(MKL_LIBRARIES "${MKL_LIBRARIES}")
if(UNIX AND NOT MKL_USE_SINGLE_DYNAMIC_LIBRARY AND NOT MKL_LIBRARIES_DONT_HACK)
#it's ugly but helps to avoid cyclic lib problem
set(MKL_LIBRARIES ${MKL_LIBRARIES} ${MKL_LIBRARIES} ${MKL_LIBRARIES} "-lpthread" "-lm" "-ldl")
endif()
+5 -1
View File
@@ -2,7 +2,11 @@ set(OPENCV_APPLE_BUNDLE_NAME "OpenCV")
set(OPENCV_APPLE_BUNDLE_ID "org.opencv")
if(IOS)
if (APPLE_FRAMEWORK AND DYNAMIC_PLIST)
if(MAC_CATALYST)
# Copy the iOS plist over to the OSX directory if building iOS library for Catalyst
configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in"
"${CMAKE_BINARY_DIR}/osx/Info.plist")
elseif(APPLE_FRAMEWORK AND DYNAMIC_PLIST)
configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.Dynamic.plist.in"
"${CMAKE_BINARY_DIR}/ios/Info.plist")
else()
+15 -14
View File
@@ -98,15 +98,6 @@ macro(ocv_add_dependencies full_modname)
endforeach()
unset(__depsvar)
# hack for python
set(__python_idx)
list(FIND OPENCV_MODULE_${full_modname}_WRAPPERS "python" __python_idx)
if (NOT __python_idx EQUAL -1)
list(REMOVE_ITEM OPENCV_MODULE_${full_modname}_WRAPPERS "python")
list(APPEND OPENCV_MODULE_${full_modname}_WRAPPERS "python_bindings_generator" "python2" "python3")
endif()
unset(__python_idx)
ocv_list_unique(OPENCV_MODULE_${full_modname}_REQ_DEPS)
ocv_list_unique(OPENCV_MODULE_${full_modname}_OPT_DEPS)
ocv_list_unique(OPENCV_MODULE_${full_modname}_PRIVATE_REQ_DEPS)
@@ -210,11 +201,6 @@ macro(ocv_add_module _name)
set(OPENCV_MODULES_DISABLED_USER ${OPENCV_MODULES_DISABLED_USER} "${the_module}" CACHE INTERNAL "List of OpenCV modules explicitly disabled by user")
endif()
# add reverse wrapper dependencies
foreach (wrapper ${OPENCV_MODULE_${the_module}_WRAPPERS})
ocv_add_dependencies(opencv_${wrapper} OPTIONAL ${the_module})
endforeach()
# stop processing of current file
ocv_cmake_hook(POST_ADD_MODULE)
ocv_cmake_hook(POST_ADD_MODULE_${the_module})
@@ -501,6 +487,21 @@ function(__ocv_resolve_dependencies)
endforeach()
endif()
# add reverse wrapper dependencies (BINDINDS)
foreach(the_module ${OPENCV_MODULES_BUILD})
foreach (wrapper ${OPENCV_MODULE_${the_module}_WRAPPERS})
if(wrapper STREQUAL "python") # hack for python (BINDINDS)
ocv_add_dependencies(opencv_python2 OPTIONAL ${the_module})
ocv_add_dependencies(opencv_python3 OPTIONAL ${the_module})
else()
ocv_add_dependencies(opencv_${wrapper} OPTIONAL ${the_module})
endif()
if(DEFINED OPENCV_MODULE_opencv_${wrapper}_bindings_generator_CLASS)
ocv_add_dependencies(opencv_${wrapper}_bindings_generator OPTIONAL ${the_module})
endif()
endforeach()
endforeach()
# disable MODULES with unresolved dependencies
set(has_changes ON)
while(has_changes)
+39 -2
View File
@@ -8,7 +8,20 @@ include(CMakeParseArguments)
function(ocv_cmake_dump_vars)
set(OPENCV_SUPPRESS_DEPRECATIONS 1) # suppress deprecation warnings from variable_watch() guards
get_cmake_property(__variableNames VARIABLES)
cmake_parse_arguments(DUMP "" "TOFILE" "" ${ARGN})
cmake_parse_arguments(DUMP "FORCE" "TOFILE" "" ${ARGN})
# avoid generation of excessive logs with "--trace" or "--trace-expand" parameters
# Note: `-DCMAKE_TRACE_MODE=1` should be passed to CMake through command line. It is not a CMake buildin variable for now (2020-12)
# Use `cmake . -UCMAKE_TRACE_MODE` to remove this variable from cache
if(CMAKE_TRACE_MODE AND NOT DUMP_FORCE)
if(DUMP_TOFILE)
file(WRITE ${CMAKE_BINARY_DIR}/${DUMP_TOFILE} "Skipped due to enabled CMAKE_TRACE_MODE")
else()
message(AUTHOR_WARNING "ocv_cmake_dump_vars() is skipped due to enabled CMAKE_TRACE_MODE")
endif()
return()
endif()
set(regex "${DUMP_UNPARSED_ARGUMENTS}")
string(TOLOWER "${regex}" regex_lower)
set(__VARS "")
@@ -400,6 +413,24 @@ macro(ocv_clear_vars)
endforeach()
endmacro()
# Clears passed variables with INTERNAL type from CMake cache
macro(ocv_clear_internal_cache_vars)
foreach(_var ${ARGN})
get_property(_propertySet CACHE ${_var} PROPERTY TYPE SET)
if(_propertySet)
get_property(_type CACHE ${_var} PROPERTY TYPE)
if(_type STREQUAL "INTERNAL")
message("Cleaning INTERNAL cached variable: ${_var}")
unset(${_var} CACHE)
endif()
endif()
endforeach()
unset(_propertySet)
unset(_type)
endmacro()
set(OCV_COMPILER_FAIL_REGEX
"argument .* is not valid" # GCC 9+ (including support of unicode quotes)
"command[- ]line option .* is valid for .* but not for C\\+\\+" # GNU
@@ -1512,10 +1543,16 @@ function(ocv_add_library target)
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG 1)
if(IOS AND NOT MAC_CATALYST)
set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/ios/Info.plist")
else()
set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/osx/Info.plist")
endif()
set_target_properties(${target} PROPERTIES
FRAMEWORK TRUE
MACOSX_FRAMEWORK_IDENTIFIER org.opencv
MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_BINARY_DIR}/ios/Info.plist
MACOSX_FRAMEWORK_INFO_PLIST ${OPENCV_APPLE_INFO_PLIST}
# "current version" in semantic format in Mach-O binary file
VERSION ${OPENCV_LIBVERSION}
# "compatibility version" in semantic format in Mach-O binary file
+1
View File
@@ -0,0 +1 @@
set(OPENCV_SKIP_LINK_AS_NEEDED 1)
+1
View File
@@ -27,6 +27,7 @@
opencv2/core/cuda*
opencv2/core/opencl*
opencv2/core/private*
opencv2/core/quaternion*
opencv/cxeigen.hpp
opencv2/core/eigen.hpp
opencv2/flann/hdf5.h
-1
View File
@@ -39,7 +39,6 @@ ALIASES += end_toggle="@htmlonly[block] </div> @endhtmlonly"
ALIASES += prev_tutorial{1}="**Prev Tutorial:** \ref \1 \n"
ALIASES += next_tutorial{1}="**Next Tutorial:** \ref \1 \n"
ALIASES += youtube{1}="@htmlonly[block]<div align='center'><iframe title='Video' width='560' height='349' src='https://www.youtube.com/embed/\1?rel=0' frameborder='0' align='middle' allowfullscreen></iframe></div>@endhtmlonly"
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
@@ -0,0 +1,119 @@
getBlobFromImage = function(inputSize, mean, std, swapRB, image) {
let mat;
if (typeof(image) === 'string') {
mat = cv.imread(image);
} else {
mat = image;
}
let matC3 = new cv.Mat(mat.matSize[0], mat.matSize[1], cv.CV_8UC3);
cv.cvtColor(mat, matC3, cv.COLOR_RGBA2BGR);
let input = cv.blobFromImage(matC3, std, new cv.Size(inputSize[0], inputSize[1]),
new cv.Scalar(mean[0], mean[1], mean[2]), swapRB);
matC3.delete();
return input;
}
loadLables = async function(labelsUrl) {
let response = await fetch(labelsUrl);
let label = await response.text();
label = label.split('\n');
return label;
}
loadModel = async function(e) {
return new Promise((resolve) => {
let file = e.target.files[0];
let path = file.name;
let reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(ev) {
if (reader.readyState === 2) {
let buffer = reader.result;
let data = new Uint8Array(buffer);
cv.FS_createDataFile('/', path, data, true, false, false);
resolve(path);
}
}
});
}
getTopClasses = function(probs, labels, topK = 3) {
probs = Array.from(probs);
let indexes = probs.map((prob, index) => [prob, index]);
let sorted = indexes.sort((a, b) => {
if (a[0] === b[0]) {return 0;}
return a[0] < b[0] ? -1 : 1;
});
sorted.reverse();
let classes = [];
for (let i = 0; i < topK; ++i) {
let prob = sorted[i][0];
let index = sorted[i][1];
let c = {
label: labels[index],
prob: (prob * 100).toFixed(2)
}
classes.push(c);
}
return classes;
}
loadImageToCanvas = function(e, canvasId) {
let files = e.target.files;
let imgUrl = URL.createObjectURL(files[0]);
let canvas = document.getElementById(canvasId);
let ctx = canvas.getContext('2d');
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = imgUrl;
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
}
drawInfoTable = async function(jsonUrl, divId) {
let response = await fetch(jsonUrl);
let json = await response.json();
let appendix = document.getElementById(divId);
for (key of Object.keys(json)) {
let h3 = document.createElement('h3');
h3.textContent = key + " model";
appendix.appendChild(h3);
let table = document.createElement('table');
let head_tr = document.createElement('tr');
for (head of Object.keys(json[key][0])) {
let th = document.createElement('th');
th.textContent = head;
th.style.border = "1px solid black";
head_tr.appendChild(th);
}
table.appendChild(head_tr)
for (model of json[key]) {
let tr = document.createElement('tr');
for (params of Object.keys(model)) {
let td = document.createElement('td');
td.style.border = "1px solid black";
if (params !== "modelUrl" && params !== "configUrl" && params !== "labelsUrl") {
td.textContent = model[params];
tr.appendChild(td);
} else {
let a = document.createElement('a');
let link = document.createTextNode('link');
a.append(link);
a.href = model[params];
td.appendChild(a);
tr.appendChild(td);
}
}
table.appendChild(tr);
}
table.style.width = "800px";
table.style.borderCollapse = "collapse";
appendix.appendChild(table);
}
}
@@ -0,0 +1,263 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Image Classification Example</title>
<link href="js_example_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Image Classification Example</h2>
<p>
This tutorial shows you how to write an image classification example with OpenCV.js.<br>
To try the example you should click the <b>modelFile</b> button(and <b>configFile</b> button if needed) to upload inference model.
You can find the model URLs and parameters in the <a href="#appendix">model info</a> section.
Then You should change the parameters in the first code snippet according to the uploaded model.
Finally click <b>Try it</b> button to see the result. You can choose any other images.<br>
</p>
<div class="control"><button id="tryIt" disabled>Try it</button></div>
<div>
<table cellpadding="0" cellspacing="0" width="0" border="0">
<tr>
<td>
<canvas id="canvasInput" width="400" height="400"></canvas>
</td>
<td>
<table style="visibility: hidden;" id="result">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col" width=300>Label</th>
<th scope="col">Probability</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td id="label0" align="center"></td>
<td id="prob0" align="center"></td>
</tr>
<tr>
<th scope="row">2</th>
<td id="label1" align="center"></td>
<td id="prob1" align="center"></td>
</tr>
<tr>
<th scope="row">3</th>
<td id="label2" align="center"></td>
<td id="prob2" align="center"></td>
</tr>
</tbody>
</table>
<p id='status' align="left"></p>
</td>
</tr>
<tr>
<td>
<div class="caption">
canvasInput <input type="file" id="fileInput" name="file" accept="image/*">
</div>
</td>
<td></td>
</tr>
<tr>
<td>
<div class="caption">
modelFile <input type="file" id="modelFile">
</div>
</td>
</tr>
<tr>
<td>
<div class="caption">
configFile <input type="file" id="configFile">
</div>
</td>
</tr>
</table>
</div>
<div>
<p class="err" id="errorMessage"></p>
</div>
<div>
<h3>Help function</h3>
<p>1.The parameters for model inference which you can modify to investigate more models.</p>
<textarea class="code" rows="13" cols="100" id="codeEditor" spellcheck="false"></textarea>
<p>2.Main loop in which will read the image from canvas and do inference once.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor1" spellcheck="false"></textarea>
<p>3.Load labels from txt file and process it into an array.</p>
<textarea class="code" rows="7" cols="100" id="codeEditor2" spellcheck="false"></textarea>
<p>4.Get blob from image as input for net, and standardize it with <b>mean</b> and <b>std</b>.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor3" spellcheck="false"></textarea>
<p>5.Fetch model file and save to emscripten file system once click the input button.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor4" spellcheck="false"></textarea>
<p>6.The post-processing, including softmax if needed and get the top classes from the output vector.</p>
<textarea class="code" rows="35" cols="100" id="codeEditor5" spellcheck="false"></textarea>
</div>
<div id="appendix">
<h2>Model Info:</h2>
</div>
<script src="utils.js" type="text/javascript"></script>
<script src="js_dnn_example_helper.js" type="text/javascript"></script>
<script id="codeSnippet" type="text/code-snippet">
inputSize = [224,224];
mean = [104, 117, 123];
std = 1;
swapRB = false;
// record if need softmax function for post-processing
needSoftmax = false;
// url for label file, can from local or Internet
labelsUrl = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/classification_classes_ILSVRC2012.txt";
</script>
<script id="codeSnippet1" type="text/code-snippet">
main = async function() {
const labels = await loadLables(labelsUrl);
const input = getBlobFromImage(inputSize, mean, std, swapRB, 'canvasInput');
let net = cv.readNet(configPath, modelPath);
net.setInput(input);
const start = performance.now();
const result = net.forward();
const time = performance.now()-start;
const probs = softmax(result);
const classes = getTopClasses(probs, labels);
updateResult(classes, time);
input.delete();
net.delete();
result.delete();
}
</script>
<script id="codeSnippet5" type="text/code-snippet">
softmax = function(result) {
let arr = result.data32F;
if (needSoftmax) {
const maxNum = Math.max(...arr);
const expSum = arr.map((num) => Math.exp(num - maxNum)).reduce((a, b) => a + b);
return arr.map((value, index) => {
return Math.exp(value - maxNum) / expSum;
});
} else {
return arr;
}
}
</script>
<script type="text/javascript">
let jsonUrl = "js_image_classification_model_info.json";
drawInfoTable(jsonUrl, 'appendix');
let utils = new Utils('errorMessage');
utils.loadCode('codeSnippet', 'codeEditor');
utils.loadCode('codeSnippet1', 'codeEditor1');
let loadLablesCode = 'loadLables = ' + loadLables.toString();
document.getElementById('codeEditor2').value = loadLablesCode;
let getBlobFromImageCode = 'getBlobFromImage = ' + getBlobFromImage.toString();
document.getElementById('codeEditor3').value = getBlobFromImageCode;
let loadModelCode = 'loadModel = ' + loadModel.toString();
document.getElementById('codeEditor4').value = loadModelCode;
utils.loadCode('codeSnippet5', 'codeEditor5');
let getTopClassesCode = 'getTopClasses = ' + getTopClasses.toString();
document.getElementById('codeEditor5').value += '\n' + '\n' + getTopClassesCode;
let canvas = document.getElementById('canvasInput');
let ctx = canvas.getContext('2d');
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'space_shuttle.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
let tryIt = document.getElementById('tryIt');
tryIt.addEventListener('click', () => {
initStatus();
document.getElementById('status').innerHTML = 'Running function main()...';
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
if (modelPath === "") {
document.getElementById('status').innerHTML = 'Runing failed.';
utils.printError('Please upload model file by clicking the button first.');
} else {
setTimeout(main, 1);
}
});
let fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (e) => {
initStatus();
loadImageToCanvas(e, 'canvasInput');
});
let configPath = "";
let configFile = document.getElementById('configFile');
configFile.addEventListener('change', async (e) => {
initStatus();
configPath = await loadModel(e);
document.getElementById('status').innerHTML = `The config file '${configPath}' is created successfully.`;
});
let modelPath = "";
let modelFile = document.getElementById('modelFile');
modelFile.addEventListener('change', async (e) => {
initStatus();
modelPath = await loadModel(e);
document.getElementById('status').innerHTML = `The model file '${modelPath}' is created successfully.`;
configPath = "";
configFile.value = "";
});
utils.loadOpenCv(() => {
tryIt.removeAttribute('disabled');
});
var main = async function() {};
var softmax = function(result){};
var getTopClasses = function(mat, labels, topK = 3){};
utils.executeCode('codeEditor1');
utils.executeCode('codeEditor2');
utils.executeCode('codeEditor3');
utils.executeCode('codeEditor4');
utils.executeCode('codeEditor5');
function updateResult(classes, time) {
try{
classes.forEach((c,i) => {
let labelElement = document.getElementById('label'+i);
let probElement = document.getElementById('prob'+i);
labelElement.innerHTML = c.label;
probElement.innerHTML = c.prob + '%';
});
let result = document.getElementById('result');
result.style.visibility = 'visible';
document.getElementById('status').innerHTML = `<b>Model:</b> ${modelPath}<br>
<b>Inference time:</b> ${time.toFixed(2)} ms`;
} catch(e) {
console.log(e);
}
}
function initStatus() {
document.getElementById('status').innerHTML = '';
document.getElementById('result').style.visibility = 'hidden';
utils.clearError();
}
</script>
</body>
</html>
@@ -0,0 +1,65 @@
{
"caffe": [
{
"model": "alexnet",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"needSoftmax": "false",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/classification_classes_ILSVRC2012.txt",
"modelUrl": "http://dl.caffe.berkeleyvision.org/bvlc_alexnet.caffemodel",
"configUrl": "https://raw.githubusercontent.com/BVLC/caffe/master/models/bvlc_alexnet/deploy.prototxt"
},
{
"model": "densenet",
"mean": "127.5, 127.5, 127.5",
"std": "0.007843",
"swapRB": "false",
"needSoftmax": "true",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/classification_classes_ILSVRC2012.txt",
"modelUrl": "https://drive.google.com/open?id=0B7ubpZO7HnlCcHlfNmJkU2VPelE",
"configUrl": "https://raw.githubusercontent.com/shicai/DenseNet-Caffe/master/DenseNet_121.prototxt"
},
{
"model": "googlenet",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"needSoftmax": "false",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/classification_classes_ILSVRC2012.txt",
"modelUrl": "http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel",
"configUrl": "https://raw.githubusercontent.com/BVLC/caffe/master/models/bvlc_googlenet/deploy.prototxt"
},
{
"model": "squeezenet",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"needSoftmax": "false",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/classification_classes_ILSVRC2012.txt",
"modelUrl": "https://raw.githubusercontent.com/forresti/SqueezeNet/master/SqueezeNet_v1.0/squeezenet_v1.0.caffemodel",
"configUrl": "https://raw.githubusercontent.com/forresti/SqueezeNet/master/SqueezeNet_v1.0/deploy.prototxt"
},
{
"model": "VGG",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"needSoftmax": "false",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/classification_classes_ILSVRC2012.txt",
"modelUrl": "http://www.robots.ox.ac.uk/~vgg/software/very_deep/caffe/VGG_ILSVRC_19_layers.caffemodel",
"configUrl": "https://gist.githubusercontent.com/ksimonyan/3785162f95cd2d5fee77/raw/f02f8769e64494bcd3d7e97d5d747ac275825721/VGG_ILSVRC_19_layers_deploy.prototxt"
}
],
"tensorflow": [
{
"model": "inception",
"mean": "123, 117, 104",
"std": "1",
"swapRB": "true",
"needSoftmax": "false",
"labelsUrl": "https://raw.githubusercontent.com/petewarden/tf_ios_makefile_example/master/data/imagenet_comp_graph_label_strings.txt",
"modelUrl": "https://raw.githubusercontent.com/petewarden/tf_ios_makefile_example/master/data/tensorflow_inception_graph.pb"
}
]
}
@@ -0,0 +1,281 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Image Classification Example with Camera</title>
<link href="js_example_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Image Classification Example with Camera</h2>
<p>
This tutorial shows you how to write an image classification example with camera.<br>
To try the example you should click the <b>modelFile</b> button(and <b>configFile</b> button if needed) to upload inference model.
You can find the model URLs and parameters in the <a href="#appendix">model info</a> section.
Then You should change the parameters in the first code snippet according to the uploaded model.
Finally click <b>Start/Stop</b> button to start or stop the camera capture.<br>
</p>
<div class="control"><button id="startAndStop" disabled>Start</button></div>
<div>
<table cellpadding="0" cellspacing="0" width="0" border="0">
<tr>
<td>
<video id="videoInput" width="400" height="400"></video>
</td>
<td>
<table style="visibility: hidden;" id="result">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col" width=300>Label</th>
<th scope="col">Probability</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td id="label0" align="center"></td>
<td id="prob0" align="center"></td>
</tr>
<tr>
<th scope="row">2</th>
<td id="label1" align="center"></td>
<td id="prob1" align="center"></td>
</tr>
<tr>
<th scope="row">3</th>
<td id="label2" align="center"></td>
<td id="prob2" align="center"></td>
</tr>
</tbody>
</table>
<p id='status' align="left"></p>
</td>
</tr>
<tr>
<td>
<div class="caption">
videoInput
</div>
</td>
<td></td>
</tr>
<tr>
<td>
<div class="caption">
modelFile <input type="file" id="modelFile">
</div>
</td>
</tr>
<tr>
<td>
<div class="caption">
configFile <input type="file" id="configFile">
</div>
</td>
</tr>
</table>
</div>
<div>
<p class="err" id="errorMessage"></p>
</div>
<div>
<h3>Help function</h3>
<p>1.The parameters for model inference which you can modify to investigate more models.</p>
<textarea class="code" rows="13" cols="100" id="codeEditor" spellcheck="false"></textarea>
<p>2.The function to capture video from camera, and the main loop in which will do inference once.</p>
<textarea class="code" rows="35" cols="100" id="codeEditor1" spellcheck="false"></textarea>
<p>3.Load labels from txt file and process it into an array.</p>
<textarea class="code" rows="7" cols="100" id="codeEditor2" spellcheck="false"></textarea>
<p>4.Get blob from image as input for net, and standardize it with <b>mean</b> and <b>std</b>.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor3" spellcheck="false"></textarea>
<p>5.Fetch model file and save to emscripten file system once click the input button.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor4" spellcheck="false"></textarea>
<p>6.The post-processing, including softmax if needed and get the top classes from the output vector.</p>
<textarea class="code" rows="35" cols="100" id="codeEditor5" spellcheck="false"></textarea>
</div>
<div id="appendix">
<h2>Model Info:</h2>
</div>
<script src="utils.js" type="text/javascript"></script>
<script src="js_dnn_example_helper.js" type="text/javascript"></script>
<script id="codeSnippet" type="text/code-snippet">
inputSize = [224,224];
mean = [104, 117, 123];
std = 1;
swapRB = false;
// record if need softmax function for post-processing
needSoftmax = false;
// url for label file, can from local or Internet
labelsUrl = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/classification_classes_ILSVRC2012.txt";
</script>
<script id="codeSnippet1" type="text/code-snippet">
let frame = new cv.Mat(video.height, video.width, cv.CV_8UC4);
let cap = new cv.VideoCapture(video);
main = async function(frame) {
const labels = await loadLables(labelsUrl);
const input = getBlobFromImage(inputSize, mean, std, swapRB, frame);
let net = cv.readNet(configPath, modelPath);
net.setInput(input);
const start = performance.now();
const result = net.forward();
const time = performance.now()-start;
const probs = softmax(result);
const classes = getTopClasses(probs, labels);
updateResult(classes, time);
setTimeout(processVideo, 0);
input.delete();
net.delete();
result.delete();
}
function processVideo() {
try {
if (!streaming) {
return;
}
cap.read(frame);
main(frame);
} catch (err) {
utils.printError(err);
}
}
setTimeout(processVideo, 0);
</script>
<script id="codeSnippet5" type="text/code-snippet">
softmax = function(result) {
let arr = result.data32F;
if (needSoftmax) {
const maxNum = Math.max(...arr);
const expSum = arr.map((num) => Math.exp(num - maxNum)).reduce((a, b) => a + b);
return arr.map((value, index) => {
return Math.exp(value - maxNum) / expSum;
});
} else {
return arr;
}
}
</script>
<script type="text/javascript">
let jsonUrl = "js_image_classification_model_info.json";
drawInfoTable(jsonUrl, 'appendix');
let utils = new Utils('errorMessage');
utils.loadCode('codeSnippet', 'codeEditor');
utils.loadCode('codeSnippet1', 'codeEditor1');
let loadLablesCode = 'loadLables = ' + loadLables.toString();
document.getElementById('codeEditor2').value = loadLablesCode;
let getBlobFromImageCode = 'getBlobFromImage = ' + getBlobFromImage.toString();
document.getElementById('codeEditor3').value = getBlobFromImageCode;
let loadModelCode = 'loadModel = ' + loadModel.toString();
document.getElementById('codeEditor4').value = loadModelCode;
utils.loadCode('codeSnippet5', 'codeEditor5');
let getTopClassesCode = 'getTopClasses = ' + getTopClasses.toString();
document.getElementById('codeEditor5').value += '\n' + '\n' + getTopClassesCode;
let video = document.getElementById('videoInput');
let streaming = false;
let startAndStop = document.getElementById('startAndStop');
startAndStop.addEventListener('click', () => {
if (!streaming) {
utils.clearError();
utils.startCamera('qvga', onVideoStarted, 'videoInput');
} else {
utils.stopCamera();
onVideoStopped();
}
});
let configPath = "";
let configFile = document.getElementById('configFile');
configFile.addEventListener('change', async (e) => {
initStatus();
configPath = await loadModel(e);
document.getElementById('status').innerHTML = `The config file '${configPath}' is created successfully.`;
});
let modelPath = "";
let modelFile = document.getElementById('modelFile');
modelFile.addEventListener('change', async (e) => {
initStatus();
modelPath = await loadModel(e);
document.getElementById('status').innerHTML = `The model file '${modelPath}' is created successfully.`;
configPath = "";
configFile.value = "";
});
utils.loadOpenCv(() => {
startAndStop.removeAttribute('disabled');
});
var main = async function(frame) {};
var softmax = function(result){};
var getTopClasses = function(mat, labels, topK = 3){};
utils.executeCode('codeEditor1');
utils.executeCode('codeEditor2');
utils.executeCode('codeEditor3');
utils.executeCode('codeEditor4');
utils.executeCode('codeEditor5');
function onVideoStarted() {
streaming = true;
startAndStop.innerText = 'Stop';
videoInput.width = videoInput.videoWidth;
videoInput.height = videoInput.videoHeight;
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
}
function onVideoStopped() {
streaming = false;
startAndStop.innerText = 'Start';
initStatus();
}
function updateResult(classes, time) {
try{
classes.forEach((c,i) => {
let labelElement = document.getElementById('label'+i);
let probElement = document.getElementById('prob'+i);
labelElement.innerHTML = c.label;
probElement.innerHTML = c.prob + '%';
});
let result = document.getElementById('result');
result.style.visibility = 'visible';
document.getElementById('status').innerHTML = `<b>Model:</b> ${modelPath}<br>
<b>Inference time:</b> ${time.toFixed(2)} ms`;
} catch(e) {
console.log(e);
}
}
function initStatus() {
document.getElementById('status').innerHTML = '';
document.getElementById('result').style.visibility = 'hidden';
utils.clearError();
}
</script>
</body>
</html>
@@ -0,0 +1,387 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Object Detection Example</title>
<link href="js_example_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Object Detection Example</h2>
<p>
This tutorial shows you how to write an object detection example with OpenCV.js.<br>
To try the example you should click the <b>modelFile</b> button(and <b>configFile</b> button if needed) to upload inference model.
You can find the model URLs and parameters in the <a href="#appendix">model info</a> section.
Then You should change the parameters in the first code snippet according to the uploaded model.
Finally click <b>Try it</b> button to see the result. You can choose any other images.<br>
</p>
<div class="control"><button id="tryIt" disabled>Try it</button></div>
<div>
<table cellpadding="0" cellspacing="0" width="0" border="0">
<tr>
<td>
<canvas id="canvasInput" width="400" height="400"></canvas>
</td>
<td>
<canvas id="canvasOutput" style="visibility: hidden;" width="400" height="400"></canvas>
</td>
</tr>
<tr>
<td>
<div class="caption">
canvasInput <input type="file" id="fileInput" name="file" accept="image/*">
</div>
</td>
<td>
<p id='status' align="left"></p>
</td>
</tr>
<tr>
<td>
<div class="caption">
modelFile <input type="file" id="modelFile" name="file">
</div>
</td>
</tr>
<tr>
<td>
<div class="caption">
configFile <input type="file" id="configFile">
</div>
</td>
</tr>
</table>
</div>
<div>
<p class="err" id="errorMessage"></p>
</div>
<div>
<h3>Help function</h3>
<p>1.The parameters for model inference which you can modify to investigate more models.</p>
<textarea class="code" rows="15" cols="100" id="codeEditor" spellcheck="false"></textarea>
<p>2.Main loop in which will read the image from canvas and do inference once.</p>
<textarea class="code" rows="16" cols="100" id="codeEditor1" spellcheck="false"></textarea>
<p>3.Load labels from txt file and process it into an array.</p>
<textarea class="code" rows="7" cols="100" id="codeEditor2" spellcheck="false"></textarea>
<p>4.Get blob from image as input for net, and standardize it with <b>mean</b> and <b>std</b>.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor3" spellcheck="false"></textarea>
<p>5.Fetch model file and save to emscripten file system once click the input button.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor4" spellcheck="false"></textarea>
<p>6.The post-processing, including get boxes from output and draw boxes into the image.</p>
<textarea class="code" rows="35" cols="100" id="codeEditor5" spellcheck="false"></textarea>
</div>
<div id="appendix">
<h2>Model Info:</h2>
</div>
<script src="utils.js" type="text/javascript"></script>
<script src="js_dnn_example_helper.js" type="text/javascript"></script>
<script id="codeSnippet" type="text/code-snippet">
inputSize = [300, 300];
mean = [127.5, 127.5, 127.5];
std = 0.007843;
swapRB = false;
confThreshold = 0.5;
nmsThreshold = 0.4;
// The type of output, can be YOLO or SSD
outType = "SSD";
// url for label file, can from local or Internet
labelsUrl = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/object_detection_classes_pascal_voc.txt";
</script>
<script id="codeSnippet1" type="text/code-snippet">
main = async function() {
const labels = await loadLables(labelsUrl);
const input = getBlobFromImage(inputSize, mean, std, swapRB, 'canvasInput');
let net = cv.readNet(configPath, modelPath);
net.setInput(input);
const start = performance.now();
const result = net.forward();
const time = performance.now()-start;
const output = postProcess(result, labels);
updateResult(output, time);
input.delete();
net.delete();
result.delete();
}
</script>
<script id="codeSnippet5" type="text/code-snippet">
postProcess = function(result, labels) {
let canvasOutput = document.getElementById('canvasOutput');
const outputWidth = canvasOutput.width;
const outputHeight = canvasOutput.height;
const resultData = result.data32F;
// Get the boxes(with class and confidence) from the output
let boxes = [];
switch(outType) {
case "YOLO": {
const vecNum = result.matSize[0];
const vecLength = result.matSize[1];
const classNum = vecLength - 5;
for (let i = 0; i < vecNum; ++i) {
let vector = resultData.slice(i*vecLength, (i+1)*vecLength);
let scores = vector.slice(5, vecLength);
let classId = scores.indexOf(Math.max(...scores));
let confidence = scores[classId];
if (confidence > confThreshold) {
let center_x = Math.round(vector[0] * outputWidth);
let center_y = Math.round(vector[1] * outputHeight);
let width = Math.round(vector[2] * outputWidth);
let height = Math.round(vector[3] * outputHeight);
let left = Math.round(center_x - width / 2);
let top = Math.round(center_y - height / 2);
let box = {
scores: scores,
classId: classId,
confidence: confidence,
bounding: [left, top, width, height],
toDraw: true
}
boxes.push(box);
}
}
// NMS(Non Maximum Suppression) algorithm
let boxNum = boxes.length;
let tmp_boxes = [];
let sorted_boxes = [];
for (let c = 0; c < classNum; ++c) {
for (let i = 0; i < boxes.length; ++i) {
tmp_boxes[i] = [boxes[i], i];
}
sorted_boxes = tmp_boxes.sort((a, b) => { return (b[0].scores[c] - a[0].scores[c]); });
for (let i = 0; i < boxNum; ++i) {
if (sorted_boxes[i][0].scores[c] === 0) continue;
else {
for (let j = i + 1; j < boxNum; ++j) {
if (IOU(sorted_boxes[i][0], sorted_boxes[j][0]) >= nmsThreshold) {
boxes[sorted_boxes[j][1]].toDraw = false;
}
}
}
}
}
} break;
case "SSD": {
const vecNum = result.matSize[2];
const vecLength = 7;
for (let i = 0; i < vecNum; ++i) {
let vector = resultData.slice(i*vecLength, (i+1)*vecLength);
let confidence = vector[2];
if (confidence > confThreshold) {
let left, top, right, bottom, width, height;
left = Math.round(vector[3]);
top = Math.round(vector[4]);
right = Math.round(vector[5]);
bottom = Math.round(vector[6]);
width = right - left + 1;
height = bottom - top + 1;
if (width <= 2 || height <= 2) {
left = Math.round(vector[3] * outputWidth);
top = Math.round(vector[4] * outputHeight);
right = Math.round(vector[5] * outputWidth);
bottom = Math.round(vector[6] * outputHeight);
width = right - left + 1;
height = bottom - top + 1;
}
let box = {
classId: vector[1] - 1,
confidence: confidence,
bounding: [left, top, width, height],
toDraw: true
}
boxes.push(box);
}
}
} break;
default:
console.error(`Unsupported output type ${outType}`)
}
// Draw the saved box into the image
let image = cv.imread("canvasInput");
let output = new cv.Mat(outputWidth, outputHeight, cv.CV_8UC3);
cv.cvtColor(image, output, cv.COLOR_RGBA2RGB);
let boxNum = boxes.length;
for (let i = 0; i < boxNum; ++i) {
if (boxes[i].toDraw) {
drawBox(boxes[i]);
}
}
return output;
// Calculate the IOU(Intersection over Union) of two boxes
function IOU(box1, box2) {
let bounding1 = box1.bounding;
let bounding2 = box2.bounding;
let s1 = bounding1[2] * bounding1[3];
let s2 = bounding2[2] * bounding2[3];
let left1 = bounding1[0];
let right1 = left1 + bounding1[2];
let left2 = bounding2[0];
let right2 = left2 + bounding2[2];
let overlapW = calOverlap([left1, right1], [left2, right2]);
let top1 = bounding2[1];
let bottom1 = top1 + bounding1[3];
let top2 = bounding2[1];
let bottom2 = top2 + bounding2[3];
let overlapH = calOverlap([top1, bottom1], [top2, bottom2]);
let overlapS = overlapW * overlapH;
return overlapS / (s1 + s2 + overlapS);
}
// Calculate the overlap range of two vector
function calOverlap(range1, range2) {
let min1 = range1[0];
let max1 = range1[1];
let min2 = range2[0];
let max2 = range2[1];
if (min2 > min1 && min2 < max1) {
return max1 - min2;
} else if (max2 > min1 && max2 < max1) {
return max2 - min1;
} else {
return 0;
}
}
// Draw one predict box into the origin image
function drawBox(box) {
let bounding = box.bounding;
let left = bounding[0];
let top = bounding[1];
let width = bounding[2];
let height = bounding[3];
cv.rectangle(output, new cv.Point(left, top), new cv.Point(left + width, top + height),
new cv.Scalar(0, 255, 0));
cv.rectangle(output, new cv.Point(left, top), new cv.Point(left + width, top + 15),
new cv.Scalar(255, 255, 255), cv.FILLED);
let text = `${labels[box.classId]}: ${box.confidence.toFixed(4)}`;
cv.putText(output, text, new cv.Point(left, top + 10), cv.FONT_HERSHEY_SIMPLEX, 0.3,
new cv.Scalar(0, 0, 0));
}
}
</script>
<script type="text/javascript">
let jsonUrl = "js_object_detection_model_info.json";
drawInfoTable(jsonUrl, 'appendix');
let utils = new Utils('errorMessage');
utils.loadCode('codeSnippet', 'codeEditor');
utils.loadCode('codeSnippet1', 'codeEditor1');
let loadLablesCode = 'loadLables = ' + loadLables.toString();
document.getElementById('codeEditor2').value = loadLablesCode;
let getBlobFromImageCode = 'getBlobFromImage = ' + getBlobFromImage.toString();
document.getElementById('codeEditor3').value = getBlobFromImageCode;
let loadModelCode = 'loadModel = ' + loadModel.toString();
document.getElementById('codeEditor4').value = loadModelCode;
utils.loadCode('codeSnippet5', 'codeEditor5');
let canvas = document.getElementById('canvasInput');
let ctx = canvas.getContext('2d');
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'lena.png';
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
let tryIt = document.getElementById('tryIt');
tryIt.addEventListener('click', () => {
initStatus();
document.getElementById('status').innerHTML = 'Running function main()...';
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
if (modelPath === "") {
document.getElementById('status').innerHTML = 'Runing failed.';
utils.printError('Please upload model file by clicking the button first.');
} else {
setTimeout(main, 1);
}
});
let fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (e) => {
initStatus();
loadImageToCanvas(e, 'canvasInput');
});
let configPath = "";
let configFile = document.getElementById('configFile');
configFile.addEventListener('change', async (e) => {
initStatus();
configPath = await loadModel(e);
document.getElementById('status').innerHTML = `The config file '${configPath}' is created successfully.`;
});
let modelPath = "";
let modelFile = document.getElementById('modelFile');
modelFile.addEventListener('change', async (e) => {
initStatus();
modelPath = await loadModel(e);
document.getElementById('status').innerHTML = `The model file '${modelPath}' is created successfully.`;
configPath = "";
configFile.value = "";
});
utils.loadOpenCv(() => {
tryIt.removeAttribute('disabled');
});
var main = async function() {};
var postProcess = function(result, labels) {};
utils.executeCode('codeEditor1');
utils.executeCode('codeEditor2');
utils.executeCode('codeEditor3');
utils.executeCode('codeEditor4');
utils.executeCode('codeEditor5');
function updateResult(output, time) {
try{
let canvasOutput = document.getElementById('canvasOutput');
canvasOutput.style.visibility = "visible";
cv.imshow('canvasOutput', output);
document.getElementById('status').innerHTML = `<b>Model:</b> ${modelPath}<br>
<b>Inference time:</b> ${time.toFixed(2)} ms`;
} catch(e) {
console.log(e);
}
}
function initStatus() {
document.getElementById('status').innerHTML = '';
document.getElementById('canvasOutput').style.visibility = "hidden";
utils.clearError();
}
</script>
</body>
</html>
@@ -0,0 +1,39 @@
{
"caffe": [
{
"model": "mobilenet_SSD",
"inputSize": "300, 300",
"mean": "127.5, 127.5, 127.5",
"std": "0.007843",
"swapRB": "false",
"outType": "SSD",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/object_detection_classes_pascal_voc.txt",
"modelUrl": "https://raw.githubusercontent.com/chuanqi305/MobileNet-SSD/master/mobilenet_iter_73000.caffemodel",
"configUrl": "https://raw.githubusercontent.com/chuanqi305/MobileNet-SSD/master/deploy.prototxt"
},
{
"model": "VGG_SSD",
"inputSize": "300, 300",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"outType": "SSD",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/object_detection_classes_pascal_voc.txt",
"modelUrl": "https://drive.google.com/uc?id=0BzKzrI_SkD1_WVVTSmQxU0dVRzA&export=download",
"configUrl": "https://drive.google.com/uc?id=0BzKzrI_SkD1_WVVTSmQxU0dVRzA&export=download"
}
],
"darknet": [
{
"model": "yolov2_tiny",
"inputSize": "416, 416",
"mean": "0, 0, 0",
"std": "0.00392",
"swapRB": "false",
"outType": "YOLO",
"labelsUrl": "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/object_detection_classes_yolov3.txt",
"modelUrl": "https://pjreddie.com/media/files/yolov2-tiny.weights",
"configUrl": "https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov2-tiny.cfg"
}
]
}
@@ -0,0 +1,402 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Object Detection Example with Camera</title>
<link href="js_example_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Object Detection Example with Camera </h2>
<p>
This tutorial shows you how to write an object detection example with camera.<br>
To try the example you should click the <b>modelFile</b> button(and <b>configInput</b> button if needed) to upload inference model.
You can find the model URLs and parameters in the <a href="#appendix">model info</a> section.
Then You should change the parameters in the first code snippet according to the uploaded model.
Finally click <b>Start/Stop</b> button to start or stop the camera capture.<br>
</p>
<div class="control"><button id="startAndStop" disabled>Start</button></div>
<div>
<table cellpadding="0" cellspacing="0" width="0" border="0">
<tr>
<td>
<video id="videoInput" width="400" height="400"></video>
</td>
<td>
<canvas id="canvasOutput" style="visibility: hidden;" width="400" height="400"></canvas>
</td>
</tr>
<tr>
<td>
<div class="caption">
videoInput
</div>
</td>
<td>
<p id='status' align="left"></p>
</td>
</tr>
<tr>
<td>
<div class="caption">
modelFile <input type="file" id="modelFile" name="file">
</div>
</td>
</tr>
<tr>
<td>
<div class="caption">
configFile <input type="file" id="configFile">
</div>
</td>
</tr>
</table>
</div>
<div>
<p class="err" id="errorMessage"></p>
</div>
<div>
<h3>Help function</h3>
<p>1.The parameters for model inference which you can modify to investigate more models.</p>
<textarea class="code" rows="15" cols="100" id="codeEditor" spellcheck="false"></textarea>
<p>2.The function to capture video from camera, and the main loop in which will do inference once.</p>
<textarea class="code" rows="34" cols="100" id="codeEditor1" spellcheck="false"></textarea>
<p>3.Load labels from txt file and process it into an array.</p>
<textarea class="code" rows="7" cols="100" id="codeEditor2" spellcheck="false"></textarea>
<p>4.Get blob from image as input for net, and standardize it with <b>mean</b> and <b>std</b>.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor3" spellcheck="false"></textarea>
<p>5.Fetch model file and save to emscripten file system once click the input button.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor4" spellcheck="false"></textarea>
<p>6.The post-processing, including get boxes from output and draw boxes into the image.</p>
<textarea class="code" rows="35" cols="100" id="codeEditor5" spellcheck="false"></textarea>
</div>
<div id="appendix">
<h2>Model Info:</h2>
</div>
<script src="utils.js" type="text/javascript"></script>
<script src="js_dnn_example_helper.js" type="text/javascript"></script>
<script id="codeSnippet" type="text/code-snippet">
inputSize = [300, 300];
mean = [127.5, 127.5, 127.5];
std = 0.007843;
swapRB = false;
confThreshold = 0.5;
nmsThreshold = 0.4;
// the type of output, can be YOLO or SSD
outType = "SSD";
// url for label file, can from local or Internet
labelsUrl = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/dnn/object_detection_classes_pascal_voc.txt";
</script>
<script id="codeSnippet1" type="text/code-snippet">
let frame = new cv.Mat(videoInput.height, videoInput.width, cv.CV_8UC4);
let cap = new cv.VideoCapture(videoInput);
main = async function(frame) {
const labels = await loadLables(labelsUrl);
const input = getBlobFromImage(inputSize, mean, std, swapRB, frame);
let net = cv.readNet(configPath, modelPath);
net.setInput(input);
const start = performance.now();
const result = net.forward();
const time = performance.now()-start;
const output = postProcess(result, labels, frame);
updateResult(output, time);
setTimeout(processVideo, 0);
input.delete();
net.delete();
result.delete();
}
function processVideo() {
try {
if (!streaming) {
return;
}
cap.read(frame);
main(frame);
} catch (err) {
utils.printError(err);
}
}
setTimeout(processVideo, 0);
</script>
<script id="codeSnippet5" type="text/code-snippet">
postProcess = function(result, labels, frame) {
let canvasOutput = document.getElementById('canvasOutput');
const outputWidth = canvasOutput.width;
const outputHeight = canvasOutput.height;
const resultData = result.data32F;
// Get the boxes(with class and confidence) from the output
let boxes = [];
switch(outType) {
case "YOLO": {
const vecNum = result.matSize[0];
const vecLength = result.matSize[1];
const classNum = vecLength - 5;
for (let i = 0; i < vecNum; ++i) {
let vector = resultData.slice(i*vecLength, (i+1)*vecLength);
let scores = vector.slice(5, vecLength);
let classId = scores.indexOf(Math.max(...scores));
let confidence = scores[classId];
if (confidence > confThreshold) {
let center_x = Math.round(vector[0] * outputWidth);
let center_y = Math.round(vector[1] * outputHeight);
let width = Math.round(vector[2] * outputWidth);
let height = Math.round(vector[3] * outputHeight);
let left = Math.round(center_x - width / 2);
let top = Math.round(center_y - height / 2);
let box = {
scores: scores,
classId: classId,
confidence: confidence,
bounding: [left, top, width, height],
toDraw: true
}
boxes.push(box);
}
}
// NMS(Non Maximum Suppression) algorithm
let boxNum = boxes.length;
let tmp_boxes = [];
let sorted_boxes = [];
for (let c = 0; c < classNum; ++c) {
for (let i = 0; i < boxes.length; ++i) {
tmp_boxes[i] = [boxes[i], i];
}
sorted_boxes = tmp_boxes.sort((a, b) => { return (b[0].scores[c] - a[0].scores[c]); });
for (let i = 0; i < boxNum; ++i) {
if (sorted_boxes[i][0].scores[c] === 0) continue;
else {
for (let j = i + 1; j < boxNum; ++j) {
if (IOU(sorted_boxes[i][0], sorted_boxes[j][0]) >= nmsThreshold) {
boxes[sorted_boxes[j][1]].toDraw = false;
}
}
}
}
}
} break;
case "SSD": {
const vecNum = result.matSize[2];
const vecLength = 7;
for (let i = 0; i < vecNum; ++i) {
let vector = resultData.slice(i*vecLength, (i+1)*vecLength);
let confidence = vector[2];
if (confidence > confThreshold) {
let left, top, right, bottom, width, height;
left = Math.round(vector[3]);
top = Math.round(vector[4]);
right = Math.round(vector[5]);
bottom = Math.round(vector[6]);
width = right - left + 1;
height = bottom - top + 1;
if (width <= 2 || height <= 2) {
left = Math.round(vector[3] * outputWidth);
top = Math.round(vector[4] * outputHeight);
right = Math.round(vector[5] * outputWidth);
bottom = Math.round(vector[6] * outputHeight);
width = right - left + 1;
height = bottom - top + 1;
}
let box = {
classId: vector[1] - 1,
confidence: confidence,
bounding: [left, top, width, height],
toDraw: true
}
boxes.push(box);
}
}
} break;
default:
console.error(`Unsupported output type ${outType}`)
}
// Draw the saved box into the image
let output = new cv.Mat(outputWidth, outputHeight, cv.CV_8UC3);
cv.cvtColor(frame, output, cv.COLOR_RGBA2RGB);
let boxNum = boxes.length;
for (let i = 0; i < boxNum; ++i) {
if (boxes[i].toDraw) {
drawBox(boxes[i]);
}
}
return output;
// Calculate the IOU(Intersection over Union) of two boxes
function IOU(box1, box2) {
let bounding1 = box1.bounding;
let bounding2 = box2.bounding;
let s1 = bounding1[2] * bounding1[3];
let s2 = bounding2[2] * bounding2[3];
let left1 = bounding1[0];
let right1 = left1 + bounding1[2];
let left2 = bounding2[0];
let right2 = left2 + bounding2[2];
let overlapW = calOverlap([left1, right1], [left2, right2]);
let top1 = bounding2[1];
let bottom1 = top1 + bounding1[3];
let top2 = bounding2[1];
let bottom2 = top2 + bounding2[3];
let overlapH = calOverlap([top1, bottom1], [top2, bottom2]);
let overlapS = overlapW * overlapH;
return overlapS / (s1 + s2 + overlapS);
}
// Calculate the overlap range of two vector
function calOverlap(range1, range2) {
let min1 = range1[0];
let max1 = range1[1];
let min2 = range2[0];
let max2 = range2[1];
if (min2 > min1 && min2 < max1) {
return max1 - min2;
} else if (max2 > min1 && max2 < max1) {
return max2 - min1;
} else {
return 0;
}
}
// Draw one predict box into the origin image
function drawBox(box) {
let bounding = box.bounding;
let left = bounding[0];
let top = bounding[1];
let width = bounding[2];
let height = bounding[3];
cv.rectangle(output, new cv.Point(left, top), new cv.Point(left + width, top + height),
new cv.Scalar(0, 255, 0));
cv.rectangle(output, new cv.Point(left, top), new cv.Point(left + width, top + 15),
new cv.Scalar(255, 255, 255), cv.FILLED);
let text = `${labels[box.classId]}: ${box.confidence.toFixed(4)}`;
cv.putText(output, text, new cv.Point(left, top + 10), cv.FONT_HERSHEY_SIMPLEX, 0.3,
new cv.Scalar(0, 0, 0));
}
}
</script>
<script type="text/javascript">
let jsonUrl = "js_object_detection_model_info.json";
drawInfoTable(jsonUrl, 'appendix');
let utils = new Utils('errorMessage');
utils.loadCode('codeSnippet', 'codeEditor');
utils.loadCode('codeSnippet1', 'codeEditor1');
let loadLablesCode = 'loadLables = ' + loadLables.toString();
document.getElementById('codeEditor2').value = loadLablesCode;
let getBlobFromImageCode = 'getBlobFromImage = ' + getBlobFromImage.toString();
document.getElementById('codeEditor3').value = getBlobFromImageCode;
let loadModelCode = 'loadModel = ' + loadModel.toString();
document.getElementById('codeEditor4').value = loadModelCode;
utils.loadCode('codeSnippet5', 'codeEditor5');
let videoInput = document.getElementById('videoInput');
let streaming = false;
let startAndStop = document.getElementById('startAndStop');
startAndStop.addEventListener('click', () => {
if (!streaming) {
utils.clearError();
utils.startCamera('qvga', onVideoStarted, 'videoInput');
} else {
utils.stopCamera();
onVideoStopped();
}
});
let configPath = "";
let configFile = document.getElementById('configFile');
configFile.addEventListener('change', async (e) => {
initStatus();
configPath = await loadModel(e);
document.getElementById('status').innerHTML = `The config file '${configPath}' is created successfully.`;
});
let modelPath = "";
let modelFile = document.getElementById('modelFile');
modelFile.addEventListener('change', async (e) => {
initStatus();
modelPath = await loadModel(e);
document.getElementById('status').innerHTML = `The model file '${modelPath}' is created successfully.`;
configPath = "";
configFile.value = "";
});
utils.loadOpenCv(() => {
startAndStop.removeAttribute('disabled');
});
var main = async function(frame) {};
var postProcess = function(result, labels, frame) {};
utils.executeCode('codeEditor1');
utils.executeCode('codeEditor2');
utils.executeCode('codeEditor3');
utils.executeCode('codeEditor4');
utils.executeCode('codeEditor5');
function onVideoStarted() {
streaming = true;
startAndStop.innerText = 'Stop';
videoInput.width = videoInput.videoWidth;
videoInput.height = videoInput.videoHeight;
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
}
function onVideoStopped() {
streaming = false;
startAndStop.innerText = 'Start';
initStatus();
}
function updateResult(output, time) {
try{
let canvasOutput = document.getElementById('canvasOutput');
canvasOutput.style.visibility = "visible";
cv.imshow('canvasOutput', output);
document.getElementById('status').innerHTML = `<b>Model:</b> ${modelPath}<br>
<b>Inference time:</b> ${time.toFixed(2)} ms`;
} catch(e) {
console.log(e);
}
}
function initStatus() {
document.getElementById('status').innerHTML = '';
document.getElementById('canvasOutput').style.visibility = "hidden";
utils.clearError();
}
</script>
</body>
</html>
@@ -0,0 +1,327 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Pose Estimation Example</title>
<link href="js_example_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Pose Estimation Example</h2>
<p>
This tutorial shows you how to write an pose estimation example with OpenCV.js.<br>
To try the example you should click the <b>modelFile</b> button(and <b>configInput</b> button if needed) to upload inference model.
You can find the model URLs and parameters in the <a href="#appendix">model info</a> section.
Then You should change the parameters in the first code snippet according to the uploaded model.
Finally click <b>Try it</b> button to see the result. You can choose any other images.<br>
</p>
<div class="control"><button id="tryIt" disabled>Try it</button></div>
<div>
<table cellpadding="0" cellspacing="0" width="0" border="0">
<tr>
<td>
<canvas id="canvasInput" width="400" height="250"></canvas>
</td>
<td>
<canvas id="canvasOutput" style="visibility: hidden;" width="400" height="250"></canvas>
</td>
</tr>
<tr>
<td>
<div class="caption">
canvasInput <input type="file" id="fileInput" name="file" accept="image/*">
</div>
</td>
<td>
<p id='status' align="left"></p>
</td>
</tr>
<tr>
<td>
<div class="caption">
modelFile <input type="file" id="modelFile" name="file">
</div>
</td>
</tr>
<tr>
<td>
<div class="caption">
configFile <input type="file" id="configFile">
</div>
</td>
</tr>
</table>
</div>
<div>
<p class="err" id="errorMessage"></p>
</div>
<div>
<h3>Help function</h3>
<p>1.The parameters for model inference which you can modify to investigate more models.</p>
<textarea class="code" rows="9" cols="100" id="codeEditor" spellcheck="false"></textarea>
<p>2.Main loop in which will read the image from canvas and do inference once.</p>
<textarea class="code" rows="15" cols="100" id="codeEditor1" spellcheck="false"></textarea>
<p>3.Get blob from image as input for net, and standardize it with <b>mean</b> and <b>std</b>.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor2" spellcheck="false"></textarea>
<p>4.Fetch model file and save to emscripten file system once click the input button.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor3" spellcheck="false"></textarea>
<p>5.The pairs of keypoints of different dataset.</p>
<textarea class="code" rows="30" cols="100" id="codeEditor4" spellcheck="false"></textarea>
<p>6.The post-processing, including get the predicted points and draw lines into the image.</p>
<textarea class="code" rows="30" cols="100" id="codeEditor5" spellcheck="false"></textarea>
</div>
<div id="appendix">
<h2>Model Info:</h2>
</div>
<script src="utils.js" type="text/javascript"></script>
<script src="js_dnn_example_helper.js" type="text/javascript"></script>
<script id="codeSnippet" type="text/code-snippet">
inputSize = [368, 368];
mean = [0, 0, 0];
std = 0.00392;
swapRB = false;
threshold = 0.1;
// the pairs of keypoint, can be "COCO", "MPI" and "BODY_25"
dataset = "COCO";
</script>
<script id="codeSnippet1" type="text/code-snippet">
main = async function() {
const input = getBlobFromImage(inputSize, mean, std, swapRB, 'canvasInput');
let net = cv.readNet(configPath, modelPath);
net.setInput(input);
const start = performance.now();
const result = net.forward();
const time = performance.now()-start;
const output = postProcess(result);
updateResult(output, time);
input.delete();
net.delete();
result.delete();
}
</script>
<script id="codeSnippet4" type="text/code-snippet">
BODY_PARTS = {};
POSE_PAIRS = [];
if (dataset === 'COCO') {
BODY_PARTS = { "Nose": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
"LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
"RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "REye": 14,
"LEye": 15, "REar": 16, "LEar": 17, "Background": 18 };
POSE_PAIRS = [ ["Neck", "RShoulder"], ["Neck", "LShoulder"], ["RShoulder", "RElbow"],
["RElbow", "RWrist"], ["LShoulder", "LElbow"], ["LElbow", "LWrist"],
["Neck", "RHip"], ["RHip", "RKnee"], ["RKnee", "RAnkle"], ["Neck", "LHip"],
["LHip", "LKnee"], ["LKnee", "LAnkle"], ["Neck", "Nose"], ["Nose", "REye"],
["REye", "REar"], ["Nose", "LEye"], ["LEye", "LEar"] ]
} else if (dataset === 'MPI') {
BODY_PARTS = { "Head": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
"LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
"RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "Chest": 14,
"Background": 15 }
POSE_PAIRS = [ ["Head", "Neck"], ["Neck", "RShoulder"], ["RShoulder", "RElbow"],
["RElbow", "RWrist"], ["Neck", "LShoulder"], ["LShoulder", "LElbow"],
["LElbow", "LWrist"], ["Neck", "Chest"], ["Chest", "RHip"], ["RHip", "RKnee"],
["RKnee", "RAnkle"], ["Chest", "LHip"], ["LHip", "LKnee"], ["LKnee", "LAnkle"] ]
} else if (dataset === 'BODY_25') {
BODY_PARTS = { "Nose": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
"LShoulder": 5, "LElbow": 6, "LWrist": 7, "MidHip": 8, "RHip": 9,
"RKnee": 10, "RAnkle": 11, "LHip": 12, "LKnee": 13, "LAnkle": 14,
"REye": 15, "LEye": 16, "REar": 17, "LEar": 18, "LBigToe": 19,
"LSmallToe": 20, "LHeel": 21, "RBigToe": 22, "RSmallToe": 23,
"RHeel": 24, "Background": 25 }
POSE_PAIRS = [ ["Neck", "Nose"], ["Neck", "RShoulder"],
["Neck", "LShoulder"], ["RShoulder", "RElbow"],
["RElbow", "RWrist"], ["LShoulder", "LElbow"],
["LElbow", "LWrist"], ["Nose", "REye"],
["REye", "REar"], ["Neck", "LEye"],
["LEye", "LEar"], ["Neck", "MidHip"],
["MidHip", "RHip"], ["RHip", "RKnee"],
["RKnee", "RAnkle"], ["RAnkle", "RBigToe"],
["RBigToe", "RSmallToe"], ["RAnkle", "RHeel"],
["MidHip", "LHip"], ["LHip", "LKnee"],
["LKnee", "LAnkle"], ["LAnkle", "LBigToe"],
["LBigToe", "LSmallToe"], ["LAnkle", "LHeel"] ]
}
</script>
<script id="codeSnippet5" type="text/code-snippet">
postProcess = function(result) {
const resultData = result.data32F;
const matSize = result.matSize;
const size1 = matSize[1];
const size2 = matSize[2];
const size3 = matSize[3];
const mapSize = size2 * size3;
let canvasOutput = document.getElementById('canvasOutput');
const outputWidth = canvasOutput.width;
const outputHeight = canvasOutput.height;
let image = cv.imread("canvasInput");
let output = new cv.Mat(outputWidth, outputHeight, cv.CV_8UC3);
cv.cvtColor(image, output, cv.COLOR_RGBA2RGB);
// get position of keypoints from output
let points = [];
for (let i = 0; i < Object.keys(BODY_PARTS).length; ++i) {
heatMap = resultData.slice(i*mapSize, (i+1)*mapSize);
let maxIndex = 0;
let maxConf = heatMap[0];
for (index in heatMap) {
if (heatMap[index] > heatMap[maxIndex]) {
maxIndex = index;
maxConf = heatMap[index];
}
}
if (maxConf > threshold) {
indexX = maxIndex % size3;
indexY = maxIndex / size3;
x = outputWidth * indexX / size3;
y = outputHeight * indexY / size2;
points[i] = [Math.round(x), Math.round(y)];
}
}
// draw the points and lines into the image
for (pair of POSE_PAIRS) {
partFrom = pair[0];
partTo = pair[1];
idFrom = BODY_PARTS[partFrom];
idTo = BODY_PARTS[partTo];
pointFrom = points[idFrom];
pointTo = points[idTo];
if (points[idFrom] && points[idTo]) {
cv.line(output, new cv.Point(pointFrom[0], pointFrom[1]),
new cv.Point(pointTo[0], pointTo[1]), new cv.Scalar(0, 255, 0), 3);
cv.ellipse(output, new cv.Point(pointFrom[0], pointFrom[1]), new cv.Size(3, 3), 0, 0, 360,
new cv.Scalar(0, 0, 255), cv.FILLED);
cv.ellipse(output, new cv.Point(pointTo[0], pointTo[1]), new cv.Size(3, 3), 0, 0, 360,
new cv.Scalar(0, 0, 255), cv.FILLED);
}
}
return output;
}
</script>
<script type="text/javascript">
let jsonUrl = "js_pose_estimation_model_info.json";
drawInfoTable(jsonUrl, 'appendix');
let utils = new Utils('errorMessage');
utils.loadCode('codeSnippet', 'codeEditor');
utils.loadCode('codeSnippet1', 'codeEditor1');
let getBlobFromImageCode = 'getBlobFromImage = ' + getBlobFromImage.toString();
document.getElementById('codeEditor2').value = getBlobFromImageCode;
let loadModelCode = 'loadModel = ' + loadModel.toString();
document.getElementById('codeEditor3').value = loadModelCode;
utils.loadCode('codeSnippet4', 'codeEditor4');
utils.loadCode('codeSnippet5', 'codeEditor5');
let canvas = document.getElementById('canvasInput');
let ctx = canvas.getContext('2d');
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'roi.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
let tryIt = document.getElementById('tryIt');
tryIt.addEventListener('click', () => {
initStatus();
document.getElementById('status').innerHTML = 'Running function main()...';
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
if (modelPath === "") {
document.getElementById('status').innerHTML = 'Runing failed.';
utils.printError('Please upload model file by clicking the button first.');
} else {
setTimeout(main, 1);
}
});
let fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (e) => {
initStatus();
loadImageToCanvas(e, 'canvasInput');
});
let configPath = "";
let configFile = document.getElementById('configFile');
configFile.addEventListener('change', async (e) => {
initStatus();
configPath = await loadModel(e);
document.getElementById('status').innerHTML = `The config file '${configPath}' is created successfully.`;
});
let modelPath = "";
let modelFile = document.getElementById('modelFile');
modelFile.addEventListener('change', async (e) => {
initStatus();
modelPath = await loadModel(e);
document.getElementById('status').innerHTML = `The model file '${modelPath}' is created successfully.`;
configPath = "";
configFile.value = "";
});
utils.loadOpenCv(() => {
tryIt.removeAttribute('disabled');
});
var main = async function() {};
var postProcess = function(result) {};
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
utils.executeCode('codeEditor2');
utils.executeCode('codeEditor3');
utils.executeCode('codeEditor4');
utils.executeCode('codeEditor5');
function updateResult(output, time) {
try{
let canvasOutput = document.getElementById('canvasOutput');
canvasOutput.style.visibility = "visible";
let resized = new cv.Mat(canvasOutput.width, canvasOutput.height, cv.CV_8UC4);
cv.resize(output, resized, new cv.Size(canvasOutput.width, canvasOutput.height));
cv.imshow('canvasOutput', resized);
document.getElementById('status').innerHTML = `<b>Model:</b> ${modelPath}<br>
<b>Inference time:</b> ${time.toFixed(2)} ms`;
} catch(e) {
console.log(e);
}
}
function initStatus() {
document.getElementById('status').innerHTML = '';
document.getElementById('canvasOutput').style.visibility = "hidden";
utils.clearError();
}
</script>
</body>
</html>
@@ -0,0 +1,34 @@
{
"caffe": [
{
"model": "body_25",
"inputSize": "368, 368",
"mean": "0, 0, 0",
"std": "0.00392",
"swapRB": "false",
"dataset": "BODY_25",
"modelUrl": "http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/body_25/pose_iter_584000.caffemodel",
"configUrl": "https://raw.githubusercontent.com/CMU-Perceptual-Computing-Lab/openpose/master/models/pose/body_25/pose_deploy.prototxt"
},
{
"model": "coco",
"inputSize": "368, 368",
"mean": "0, 0, 0",
"std": "0.00392",
"swapRB": "false",
"dataset": "COCO",
"modelUrl": "http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/coco/pose_iter_440000.caffemodel",
"configUrl": "https://raw.githubusercontent.com/CMU-Perceptual-Computing-Lab/openpose/master/models/pose/coco/pose_deploy_linevec.prototxt"
},
{
"model": "mpi",
"inputSize": "368, 368",
"mean": "0, 0, 0",
"std": "0.00392",
"swapRB": "false",
"dataset": "MPI",
"modelUrl": "http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/mpi/pose_iter_160000.caffemodel",
"configUrl": "https://raw.githubusercontent.com/CMU-Perceptual-Computing-Lab/openpose/master/models/pose/mpi/pose_deploy_linevec.prototxt"
}
]
}
@@ -0,0 +1,243 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Semantic Segmentation Example</title>
<link href="js_example_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Semantic Segmentation Example</h2>
<p>
This tutorial shows you how to write an semantic segmentation example with OpenCV.js.<br>
To try the example you should click the <b>modelFile</b> button(and <b>configInput</b> button if needed) to upload inference model.
You can find the model URLs and parameters in the <a href="#appendix">model info</a> section.
Then You should change the parameters in the first code snippet according to the uploaded model.
Finally click <b>Try it</b> button to see the result. You can choose any other images.<br>
</p>
<div class="control"><button id="tryIt" disabled>Try it</button></div>
<div>
<table cellpadding="0" cellspacing="0" width="0" border="0">
<tr>
<td>
<canvas id="canvasInput" width="400" height="400"></canvas>
</td>
<td>
<canvas id="canvasOutput" style="visibility: hidden;" width="400" height="400"></canvas>
</td>
</tr>
<tr>
<td>
<div class="caption">
canvasInput <input type="file" id="fileInput" name="file" accept="image/*">
</div>
</td>
<td>
<p id='status' align="left"></p>
</td>
</tr>
<tr>
<td>
<div class="caption">
modelFile <input type="file" id="modelFile" name="file">
</div>
</td>
</tr>
<tr>
<td>
<div class="caption">
configFile <input type="file" id="configFile">
</div>
</td>
</tr>
</table>
</div>
<div>
<p class="err" id="errorMessage"></p>
</div>
<div>
<h3>Help function</h3>
<p>1.The parameters for model inference which you can modify to investigate more models.</p>
<textarea class="code" rows="5" cols="100" id="codeEditor" spellcheck="false"></textarea>
<p>2.Main loop in which will read the image from canvas and do inference once.</p>
<textarea class="code" rows="16" cols="100" id="codeEditor1" spellcheck="false"></textarea>
<p>3.Get blob from image as input for net, and standardize it with <b>mean</b> and <b>std</b>.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor2" spellcheck="false"></textarea>
<p>4.Fetch model file and save to emscripten file system once click the input button.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor3" spellcheck="false"></textarea>
<p>5.The post-processing, including gengerate colors for different classes and argmax to get the classes for each pixel.</p>
<textarea class="code" rows="34" cols="100" id="codeEditor4" spellcheck="false"></textarea>
</div>
<div id="appendix">
<h2>Model Info:</h2>
</div>
<script src="utils.js" type="text/javascript"></script>
<script src="js_dnn_example_helper.js" type="text/javascript"></script>
<script id="codeSnippet" type="text/code-snippet">
inputSize = [513, 513];
mean = [127.5, 127.5, 127.5];
std = 0.007843;
swapRB = false;
</script>
<script id="codeSnippet1" type="text/code-snippet">
main = async function() {
const input = getBlobFromImage(inputSize, mean, std, swapRB, 'canvasInput');
let net = cv.readNet(configPath, modelPath);
net.setInput(input);
const start = performance.now();
const result = net.forward();
const time = performance.now()-start;
const colors = generateColors(result);
const output = argmax(result, colors);
updateResult(output, time);
input.delete();
net.delete();
result.delete();
}
</script>
<script id="codeSnippet4" type="text/code-snippet">
generateColors = function(result) {
const numClasses = result.matSize[1];
let colors = [0,0,0];
while(colors.length < numClasses*3){
colors.push(Math.round((Math.random()*255 + colors[colors.length-3]) / 2));
}
return colors;
}
argmax = function(result, colors) {
const C = result.matSize[1];
const H = result.matSize[2];
const W = result.matSize[3];
const resultData = result.data32F;
const imgSize = H*W;
let classId = [];
for (i = 0; i<imgSize; ++i) {
let id = 0;
for (j = 0; j < C; ++j) {
if (resultData[j*imgSize+i] > resultData[id*imgSize+i]) {
id = j;
}
}
classId.push(colors[id*3]);
classId.push(colors[id*3+1]);
classId.push(colors[id*3+2]);
classId.push(255);
}
output = cv.matFromArray(H,W,cv.CV_8UC4,classId);
return output;
}
</script>
<script type="text/javascript">
let jsonUrl = "js_semantic_segmentation_model_info.json";
drawInfoTable(jsonUrl, 'appendix');
let utils = new Utils('errorMessage');
utils.loadCode('codeSnippet', 'codeEditor');
utils.loadCode('codeSnippet1', 'codeEditor1');
let getBlobFromImageCode = 'getBlobFromImage = ' + getBlobFromImage.toString();
document.getElementById('codeEditor2').value = getBlobFromImageCode;
let loadModelCode = 'loadModel = ' + loadModel.toString();
document.getElementById('codeEditor3').value = loadModelCode;
utils.loadCode('codeSnippet4', 'codeEditor4');
let canvas = document.getElementById('canvasInput');
let ctx = canvas.getContext('2d');
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'roi.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
let tryIt = document.getElementById('tryIt');
tryIt.addEventListener('click', () => {
initStatus();
document.getElementById('status').innerHTML = 'Running function main()...';
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
if (modelPath === "") {
document.getElementById('status').innerHTML = 'Runing failed.';
utils.printError('Please upload model file by clicking the button first.');
} else {
setTimeout(main, 1);
}
});
let fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (e) => {
initStatus();
loadImageToCanvas(e, 'canvasInput');
});
let configPath = "";
let configFile = document.getElementById('configFile');
configFile.addEventListener('change', async (e) => {
initStatus();
configPath = await loadModel(e);
document.getElementById('status').innerHTML = `The config file '${configPath}' is created successfully.`;
});
let modelPath = "";
let modelFile = document.getElementById('modelFile');
modelFile.addEventListener('change', async (e) => {
initStatus();
modelPath = await loadModel(e);
document.getElementById('status').innerHTML = `The model file '${modelPath}' is created successfully.`;
configPath = "";
configFile.value = "";
});
utils.loadOpenCv(() => {
tryIt.removeAttribute('disabled');
});
var main = async function() {};
var generateColors = function(result) {};
var argmax = function(result, colors) {};
utils.executeCode('codeEditor1');
utils.executeCode('codeEditor2');
utils.executeCode('codeEditor3');
utils.executeCode('codeEditor4');
function updateResult(output, time) {
try{
let canvasOutput = document.getElementById('canvasOutput');
canvasOutput.style.visibility = "visible";
let resized = new cv.Mat(canvasOutput.width, canvasOutput.height, cv.CV_8UC4);
cv.resize(output, resized, new cv.Size(canvasOutput.width, canvasOutput.height));
cv.imshow('canvasOutput', resized);
document.getElementById('status').innerHTML = `<b>Model:</b> ${modelPath}<br>
<b>Inference time:</b> ${time.toFixed(2)} ms`;
} catch(e) {
console.log(e);
}
}
function initStatus() {
document.getElementById('status').innerHTML = '';
document.getElementById('canvasOutput').style.visibility = "hidden";
utils.clearError();
}
</script>
</body>
</html>
@@ -0,0 +1,12 @@
{
"tensorflow": [
{
"model": "deeplabv3",
"inputSize": "513, 513",
"mean": "127.5, 127.5, 127.5",
"std": "0.007843",
"swapRB": "false",
"modelUrl": "https://drive.google.com/uc?id=1v-hfGenaE9tiGOzo5qdgMNG_gqQ5-Xn4&export=download"
}
]
}
@@ -0,0 +1,228 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Style Transfer Example</title>
<link href="js_example_style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Style Transfer Example</h2>
<p>
This tutorial shows you how to write an style transfer example with OpenCV.js.<br>
To try the example you should click the <b>modelFile</b> button(and <b>configFile</b> button if needed) to upload inference model.
You can find the model URLs and parameters in the <a href="#appendix">model info</a> section.
Then You should change the parameters in the first code snippet according to the uploaded model.
Finally click <b>Try it</b> button to see the result. You can choose any other images.<br>
</p>
<div class="control"><button id="tryIt" disabled>Try it</button></div>
<div>
<table cellpadding="0" cellspacing="0" width="0" border="0">
<tr>
<td>
<canvas id="canvasInput" width="400" height="400"></canvas>
</td>
<td>
<canvas id="canvasOutput" style="visibility: hidden;" width="400" height="400"></canvas>
</td>
</tr>
<tr>
<td>
<div class="caption">
canvasInput <input type="file" id="fileInput" name="file" accept="image/*">
</div>
</td>
<td>
<p id='status' align="left"></p>
</td>
</tr>
<tr>
<td>
<div class="caption">
modelFile <input type="file" id="modelFile" name="file">
</div>
</td>
</tr>
<tr>
<td>
<div class="caption">
configFile <input type="file" id="configFile">
</div>
</td>
</tr>
</table>
</div>
<div>
<p class="err" id="errorMessage"></p>
</div>
<div>
<h3>Help function</h3>
<p>1.The parameters for model inference which you can modify to investigate more models.</p>
<textarea class="code" rows="5" cols="100" id="codeEditor" spellcheck="false"></textarea>
<p>2.Main loop in which will read the image from canvas and do inference once.</p>
<textarea class="code" rows="15" cols="100" id="codeEditor1" spellcheck="false"></textarea>
<p>3.Get blob from image as input for net, and standardize it with <b>mean</b> and <b>std</b>.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor2" spellcheck="false"></textarea>
<p>4.Fetch model file and save to emscripten file system once click the input button.</p>
<textarea class="code" rows="17" cols="100" id="codeEditor3" spellcheck="false"></textarea>
<p>5.The post-processing, including scaling and reordering.</p>
<textarea class="code" rows="21" cols="100" id="codeEditor4" spellcheck="false"></textarea>
</div>
<div id="appendix">
<h2>Model Info:</h2>
</div>
<script src="utils.js" type="text/javascript"></script>
<script src="js_dnn_example_helper.js" type="text/javascript"></script>
<script id="codeSnippet" type="text/code-snippet">
inputSize = [224, 224];
mean = [104, 117, 123];
std = 1;
swapRB = false;
</script>
<script id="codeSnippet1" type="text/code-snippet">
main = async function() {
const input = getBlobFromImage(inputSize, mean, std, swapRB, 'canvasInput');
let net = cv.readNet(configPath, modelPath);
net.setInput(input);
const start = performance.now();
const result = net.forward();
const time = performance.now()-start;
const output = postProcess(result);
updateResult(output, time);
input.delete();
net.delete();
result.delete();
}
</script>
<script id="codeSnippet4" type="text/code-snippet">
postProcess = function(result) {
const resultData = result.data32F;
const C = result.matSize[1];
const H = result.matSize[2];
const W = result.matSize[3];
const mean = [104, 117, 123];
let normData = [];
for (let h = 0; h < H; ++h) {
for (let w = 0; w < W; ++w) {
for (let c = 0; c < C; ++c) {
normData.push(resultData[c*H*W + h*W + w] + mean[c]);
}
normData.push(255);
}
}
let output = new cv.matFromArray(H, W, cv.CV_8UC4, normData);
return output;
}
</script>
<script type="text/javascript">
let jsonUrl = "js_style_transfer_model_info.json";
drawInfoTable(jsonUrl, 'appendix');
let utils = new Utils('errorMessage');
utils.loadCode('codeSnippet', 'codeEditor');
utils.loadCode('codeSnippet1', 'codeEditor1');
let getBlobFromImageCode = 'getBlobFromImage = ' + getBlobFromImage.toString();
document.getElementById('codeEditor2').value = getBlobFromImageCode;
let loadModelCode = 'loadModel = ' + loadModel.toString();
document.getElementById('codeEditor3').value = loadModelCode;
utils.loadCode('codeSnippet4', 'codeEditor4');
let canvas = document.getElementById('canvasInput');
let ctx = canvas.getContext('2d');
let img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'lena.png';
img.onload = function() {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
let tryIt = document.getElementById('tryIt');
tryIt.addEventListener('click', () => {
initStatus();
document.getElementById('status').innerHTML = 'Running function main()...';
utils.executeCode('codeEditor');
utils.executeCode('codeEditor1');
if (modelPath === "") {
document.getElementById('status').innerHTML = 'Runing failed.';
utils.printError('Please upload model file by clicking the button first.');
} else {
setTimeout(main, 1);
}
});
let fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (e) => {
initStatus();
loadImageToCanvas(e, 'canvasInput');
});
let configPath = "";
let configFile = document.getElementById('configFile');
configFile.addEventListener('change', async (e) => {
initStatus();
configPath = await loadModel(e);
document.getElementById('status').innerHTML = `The config file '${configPath}' is created successfully.`;
});
let modelPath = "";
let modelFile = document.getElementById('modelFile');
modelFile.addEventListener('change', async (e) => {
initStatus();
modelPath = await loadModel(e);
document.getElementById('status').innerHTML = `The model file '${modelPath}' is created successfully.`;
configPath = "";
configFile.value = "";
});
utils.loadOpenCv(() => {
tryIt.removeAttribute('disabled');
});
var main = async function() {};
var postProcess = function(result) {};
utils.executeCode('codeEditor1');
utils.executeCode('codeEditor2');
utils.executeCode('codeEditor3');
utils.executeCode('codeEditor4');
function updateResult(output, time) {
try{
let canvasOutput = document.getElementById('canvasOutput');
canvasOutput.style.visibility = "visible";
let resized = new cv.Mat(canvasOutput.width, canvasOutput.height, cv.CV_8UC4);
cv.resize(output, resized, new cv.Size(canvasOutput.width, canvasOutput.height));
cv.imshow('canvasOutput', resized);
document.getElementById('status').innerHTML = `<b>Model:</b> ${modelPath}<br>
<b>Inference time:</b> ${time.toFixed(2)} ms`;
} catch(e) {
console.log(e);
}
}
function initStatus() {
document.getElementById('status').innerHTML = '';
document.getElementById('canvasOutput').style.visibility = "hidden";
utils.clearError();
}
</script>
</body>
</html>
@@ -0,0 +1,76 @@
{
"torch": [
{
"model": "candy.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/candy.t7"
},
{
"model": "composition_vii.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//eccv16/composition_vii.t7"
},
{
"model": "feathers.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/feathers.t7"
},
{
"model": "la_muse.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/la_muse.t7"
},
{
"model": "mosaic.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/mosaic.t7"
},
{
"model": "starry_night.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//eccv16/starry_night.t7"
},
{
"model": "the_scream.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/the_scream.t7"
},
{
"model": "the_wave.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//eccv16/the_wave.t7"
},
{
"model": "udnie.t7",
"inputSize": "224, 224",
"mean": "104, 117, 123",
"std": "1",
"swapRB": "false",
"modelUrl": "https://cs.stanford.edu/people/jcjohns/fast-neural-style/models//instance_norm/udnie.t7"
}
]
}
+8 -2
View File
@@ -7,7 +7,7 @@ function Utils(errorOutputId) { // eslint-disable-line no-unused-vars
let script = document.createElement('script');
script.setAttribute('async', '');
script.setAttribute('type', 'text/javascript');
script.addEventListener('load', () => {
script.addEventListener('load', async () => {
if (cv.getBuildInformation)
{
console.log(cv.getBuildInformation());
@@ -16,9 +16,15 @@ function Utils(errorOutputId) { // eslint-disable-line no-unused-vars
else
{
// WASM
cv['onRuntimeInitialized']=()=>{
if (cv instanceof Promise) {
cv = await cv;
console.log(cv.getBuildInformation());
onloadCallback();
} else {
cv['onRuntimeInitialized']=()=>{
console.log(cv.getBuildInformation());
onloadCallback();
}
}
}
});
@@ -0,0 +1,13 @@
Image Classification Example {#tutorial_js_image_classification}
=======================================
Goal
----
- In this tutorial you will learn how to use OpenCV.js dnn module for image classification.
\htmlonly
<iframe src="../../js_image_classification.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
@@ -0,0 +1,15 @@
Image Classification Example with Camera {#tutorial_js_image_classification_with_camera}
=======================================
Goal
----
- In this tutorial you will learn how to use OpenCV.js dnn module for image classification example with camera.
@note If you don't know how to capture video from camera, please review @ref tutorial_js_video_display.
\htmlonly
<iframe src="../../js_image_classification_with_camera.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
@@ -0,0 +1,13 @@
Object Detection Example {#tutorial_js_object_detection}
=======================================
Goal
----
- In this tutorial you will learn how to use OpenCV.js dnn module for object detection.
\htmlonly
<iframe src="../../js_object_detection.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
@@ -0,0 +1,13 @@
Object Detection Example with Camera{#tutorial_js_object_detection_with_camera}
=======================================
Goal
----
- In this tutorial you will learn how to use OpenCV.js dnn module for object detection with camera.
\htmlonly
<iframe src="../../js_object_detection_with_camera.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
@@ -0,0 +1,13 @@
Pose Estimation Example {#tutorial_js_pose_estimation}
=======================================
Goal
----
- In this tutorial you will learn how to use OpenCV.js dnn module for pose estimation.
\htmlonly
<iframe src="../../js_pose_estimation.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
@@ -0,0 +1,13 @@
Semantic Segmentation Example {#tutorial_js_semantic_segmentation}
=======================================
Goal
----
- In this tutorial you will learn how to use OpenCV.js dnn module for semantic segmentation.
\htmlonly
<iframe src="../../js_semantic_segmentation.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
@@ -0,0 +1,13 @@
Style Transfer Example {#tutorial_js_style_transfer}
=======================================
Goal
----
- In this tutorial you will learn how to use OpenCV.js dnn module for style transfer.
\htmlonly
<iframe src="../../js_style_transfer.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
@@ -0,0 +1,30 @@
Deep Neural Networks (dnn module) {#tutorial_js_table_of_contents_dnn}
============
- @subpage tutorial_js_image_classification
Image classification example
- @subpage tutorial_js_image_classification_with_camera
Image classification example with camera
- @subpage tutorial_js_object_detection
Object detection example
- @subpage tutorial_js_object_detection_with_camera
Object detection example with camera
- @subpage tutorial_js_semantic_segmentation
Semantic segmentation example
- @subpage tutorial_js_style_transfer
Style transfer example
- @subpage tutorial_js_pose_estimation
Pose estimation example
@@ -13,7 +13,7 @@ OpenCV.js: OpenCV for the JavaScript programmer
Web is the most ubiquitous open computing platform. With HTML5 standards implemented in every browser, web applications are able to render online video with HTML5 video tags, capture webcam video via WebRTC API, and access each pixel of a video frame via canvas API. With abundance of available multimedia content, web developers are in need of a wide array of image and vision processing algorithms in JavaScript to build innovative applications. This requirement is even more essential for emerging applications on the web, such as Web Virtual Reality (WebVR) and Augmented Reality (WebAR). All of these use cases demand efficient implementations of computation-intensive vision kernels on web.
[Emscripten](http://kripken.github.io/emscripten-site) is an LLVM-to-JavaScript compiler. It takes LLVM bitcode - which can be generated from C/C++ using clang, and compiles that into asm.js or WebAssembly that can execute directly inside the web browsers. . Asm.js is a highly optimizable, low-level subset of JavaScript. Asm.js enables ahead-of-time compilation and optimization in JavaScript engine that provide near-to-native execution speed. WebAssembly is a new portable, size- and load-time-efficient binary format suitable for compilation to the web. WebAssembly aims to execute at native speed. WebAssembly is currently being designed as an open standard by W3C.
[Emscripten](https://emscripten.org/) is an LLVM-to-JavaScript compiler. It takes LLVM bitcode - which can be generated from C/C++ using clang, and compiles that into asm.js or WebAssembly that can execute directly inside the web browsers. . Asm.js is a highly optimizable, low-level subset of JavaScript. Asm.js enables ahead-of-time compilation and optimization in JavaScript engine that provide near-to-native execution speed. WebAssembly is a new portable, size- and load-time-efficient binary format suitable for compilation to the web. WebAssembly aims to execute at native speed. WebAssembly is currently being designed as an open standard by W3C.
OpenCV.js is a JavaScript binding for selected subset of OpenCV functions for the web platform. It allows emerging web applications with multimedia processing to benefit from the wide variety of vision functions available in OpenCV. OpenCV.js leverages Emscripten to compile OpenCV functions into asm.js or WebAssembly targets, and provides a JavaScript APIs for web application to access them. The future versions of the library will take advantage of acceleration APIs that are available on the Web such as SIMD and multi-threaded execution.
@@ -42,4 +42,4 @@ Below is the list of contributors of OpenCV.js bindings and tutorials.
- Gang Song (GSoC student, Shanghai Jiao Tong University)
- Wenyao Gan (Student intern, Shanghai Jiao Tong University)
- Mohammad Reza Haghighat (Project initiator & sponsor, Intel Corporation)
- Ningxin Hu (Students' supervisor, Intel Corporation)
- Ningxin Hu (Students' supervisor, Intel Corporation)
@@ -7,12 +7,12 @@ You don't have to build your own copy if you simply want to start using it. Refe
Installing Emscripten
-----------------------------
[Emscripten](https://github.com/kripken/emscripten) is an LLVM-to-JavaScript compiler. We will use Emscripten to build OpenCV.js.
[Emscripten](https://github.com/emscripten-core/emscripten) is an LLVM-to-JavaScript compiler. We will use Emscripten to build OpenCV.js.
@note
While this describes installation of required tools from scratch, there's a section below also describing an alternative procedure to perform the same build using docker containers which is often easier.
To Install Emscripten, follow instructions of [Emscripten SDK](https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html).
To Install Emscripten, follow instructions of [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html).
For example:
@code{.bash}
@@ -21,24 +21,29 @@ For example:
./emsdk activate latest
@endcode
@note
To compile to [WebAssembly](http://webassembly.org), you need to install and activate [Binaryen](https://github.com/WebAssembly/binaryen) with the `emsdk` command. Please refer to [Developer's Guide](http://webassembly.org/getting-started/developers-guide/) for more details.
After install, ensure the `EMSCRIPTEN` environment is setup correctly.
After install, ensure the `EMSDK` environment is setup correctly.
For example:
@code{.bash}
source ./emsdk_env.sh
echo ${EMSCRIPTEN}
echo ${EMSDK}
@endcode
The version 1.39.16 of emscripten is verified for latest WebAssembly. Please check the version of emscripten to use the newest features of WebAssembly.
Modern versions of Emscripten requires to use `emcmake` / `emmake` launchers:
@code{.bash}
emcmake sh -c 'echo ${EMSCRIPTEN}'
@endcode
The version 2.0.10 of emscripten is verified for latest WebAssembly. Please check the version of Emscripten to use the newest features of WebAssembly.
For example:
@code{.bash}
./emsdk update
./emsdk install 1.39.16
./emsdk activate 1.39.16
./emsdk install 2.0.10
./emsdk activate 2.0.10
@endcode
Obtaining OpenCV Source Code
@@ -71,8 +76,7 @@ Building OpenCV.js from Source
For example, to build in `build_js` directory:
@code{.bash}
cd opencv
python ./platforms/js/build_js.py build_js
emcmake python ./opencv/platforms/js/build_js.py build_js
@endcode
@note
@@ -82,14 +86,14 @@ Building OpenCV.js from Source
For example, to build wasm version in `build_wasm` directory:
@code{.bash}
python ./platforms/js/build_js.py build_wasm --build_wasm
emcmake python ./opencv/platforms/js/build_js.py build_wasm --build_wasm
@endcode
-# [Optional] To build the OpenCV.js loader, append `--build_loader`.
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --build_loader
emcmake python ./opencv/platforms/js/build_js.py build_js --build_loader
@endcode
@note
@@ -114,7 +118,7 @@ Building OpenCV.js from Source
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --build_doc
emcmake python ./opencv/platforms/js/build_js.py build_js --build_doc
@endcode
@note
@@ -124,7 +128,21 @@ Building OpenCV.js from Source
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --build_test
emcmake python ./opencv/platforms/js/build_js.py build_js --build_test
@endcode
-# [optional] To enable OpenCV contrib modules append `--cmake_option="-DOPENCV_EXTRA_MODULES_PATH=/path/to/opencv_contrib/modules/"`
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --cmake_option="-DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules"
@endcode
-# [optional] To enable OpenCV contrib modules append `--cmake_option="-DOPENCV_EXTRA_MODULES_PATH=/path/to/opencv_contrib/modules/"`
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --cmake_option="-DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules"
@endcode
Running OpenCV.js Tests
@@ -186,7 +204,7 @@ node tests.js
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --build_wasm --threads
emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --threads
@endcode
The default threads number is the logic core number of your device. You can use `cv.parallel_pthreads_set_threads_num(number)` to set threads number by yourself and use `cv.parallel_pthreads_get_threads_num()` to get the current threads number.
@@ -198,7 +216,7 @@ node tests.js
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --build_wasm --simd
emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --simd
@endcode
The simd optimization is experimental as wasm simd is still in development.
@@ -222,7 +240,7 @@ node tests.js
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --build_wasm --simd --build_wasm_intrin_test
emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --simd --build_wasm_intrin_test
@endcode
For wasm intrinsics tests, you can use the following function to test all the cases:
@@ -250,7 +268,7 @@ node tests.js
For example:
@code{.bash}
python ./platforms/js/build_js.py build_js --build_perf
emcmake python ./opencv/platforms/js/build_js.py build_js --build_perf
@endcode
To run performance tests, launch a local web server in \<build_dir\>/bin folder. For example, node http-server which serves on `localhost:8080`.
@@ -271,25 +289,25 @@ Building OpenCV.js with Docker
Alternatively, the same build can be can be accomplished using [docker](https://www.docker.com/) containers which is often easier and more reliable, particularly in non linux systems. You only need to install [docker](https://www.docker.com/) on your system and use a popular container that provides a clean well tested environment for emscripten builds like this, that already has latest versions of all the necessary tools installed.
So, make sure [docker](https://www.docker.com/) is installed in your system and running. The following shell script should work in linux and MacOS:
So, make sure [docker](https://www.docker.com/) is installed in your system and running. The following shell script should work in Linux and MacOS:
@code{.bash}
git clone https://github.com/opencv/opencv.git
cd opencv
docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten:latest" python ./platforms/js/build_js.py build
docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emcmake python3 ./dev/platforms/js/build_js.py build_js
@endcode
In Windows use the following PowerShell command:
@code{.bash}
docker run --rm --workdir /code -v "$(get-location):/code" "trzeci/emscripten:latest" python ./platforms/js/build_js.py build
docker run --rm --workdir /src -v "$(get-location):/src" "emscripten/emsdk" emcmake python3 ./dev/platforms/js/build_js.py build_js
@endcode
@warning
The example uses latest version of emscripten. If the build fails you should try a version that is known to work fine which is `1.38.32` using the following command:
The example uses latest version of emscripten. If the build fails you should try a version that is known to work fine which is `2.0.10` using the following command:
@code{.bash}
docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten:sdk-tag-1.38.32-64bit" python ./platforms/js/build_js.py build
docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk:2.0.10 emcmake python3 ./dev/platforms/js/build_js.py build_js
@endcode
### Building the documentation with Docker
@@ -297,10 +315,11 @@ docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten:sdk-tag-1.38.
To build the documentation `doxygen` needs to be installed. Create a file named `Dockerfile` with the following content:
```
FROM trzeci/emscripten:sdk-tag-1.38.32-64bit
FROM emscripten/emsdk:2.0.10
RUN apt-get update -y
RUN apt-get install -y doxygen
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends doxygen \
&& rm -rf /var/lib/apt/lists/*
```
Then we build the docker image and name it `opencv-js-doc` with the following command (that needs to be run only once):
@@ -312,5 +331,5 @@ docker build . -t opencv-js-doc
Now run the build command again, this time using the new image and passing `--build_doc`:
@code{.bash}
docker run --rm --workdir /code -v "$PWD":/code "opencv-js-doc" python ./platforms/js/build_js.py build --build_doc
docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) "opencv-js-doc" emcmake python3 ./dev/platforms/js/build_js.py build_js --build_doc
@endcode
@@ -4,7 +4,7 @@ Using OpenCV.js {#tutorial_js_usage}
Steps
-----
In this tutorial, you will learn how to include and start to use `opencv.js` inside a web page. You can get a copy of `opencv.js` from `opencv-{VERSION_NUMBER}-docs.zip` in each [release](https://github.com/opencv/opencv/releases), or simply download the prebuilt script from the online documentations at "https://docs.opencv.org/{VERISON_NUMBER}/opencv.js" (For example, [https://docs.opencv.org/3.4.0/opencv.js](https://docs.opencv.org/3.4.0/opencv.js). Use `master` if you want the latest build). You can also build your own copy by following the tutorial on Build Opencv.js.
In this tutorial, you will learn how to include and start to use `opencv.js` inside a web page. You can get a copy of `opencv.js` from `opencv-{VERSION_NUMBER}-docs.zip` in each [release](https://github.com/opencv/opencv/releases), or simply download the prebuilt script from the online documentations at "https://docs.opencv.org/{VERSION_NUMBER}/opencv.js" (For example, [https://docs.opencv.org/3.4.0/opencv.js](https://docs.opencv.org/3.4.0/opencv.js). Use `master` if you want the latest build). You can also build your own copy by following the tutorial on Build Opencv.js.
### Create a web page
@@ -129,7 +129,7 @@ function onOpenCvReady() {
</html>
@endcode
@note You have to call delete method of cv.Mat to free memory allocated in Emscripten's heap. Please refer to [Memory management of Emscripten](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management) for details.
@note You have to call delete method of cv.Mat to free memory allocated in Emscripten's heap. Please refer to [Memory management of Emscripten](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management) for details.
Try it
------
@@ -137,4 +137,4 @@ Try it
<iframe src="../../js_setup_usage.html" width="100%"
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
\endhtmlonly
\endhtmlonly
+4
View File
@@ -26,3 +26,7 @@ OpenCV.js Tutorials {#tutorial_js_root}
In this section you
will object detection techniques like face detection etc.
- @subpage tutorial_js_table_of_contents_dnn
These tutorials show how to use dnn module in JavaScript
+23
View File
@@ -1261,3 +1261,26 @@
pages={281--305},
year={1987}
}
@inproceedings{liao2020real,
author={Liao, Minghui and Wan, Zhaoyi and Yao, Cong and Chen, Kai and Bai, Xiang},
title={Real-time Scene Text Detection with Differentiable Binarization},
booktitle={Proc. AAAI},
year={2020}
}
@article{shi2016end,
title={An end-to-end trainable neural network for image-based sequence recognition and its application to scene text recognition},
author={Shi, Baoguang and Bai, Xiang and Yao, Cong},
journal={IEEE transactions on pattern analysis and machine intelligence},
volume={39},
number={11},
pages={2298--2304},
year={2016},
publisher={IEEE}
}
@inproceedings{zhou2017east,
title={East: an efficient and accurate scene text detector},
author={Zhou, Xinyu and Yao, Cong and Wen, He and Wang, Yuzhi and Zhou, Shuchang and He, Weiran and Liang, Jiajun},
booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},
pages={5551--5560},
year={2017}
}
@@ -209,7 +209,7 @@ find the average error, we calculate the arithmetical mean of the errors calcula
calibration images.
@code{.py}
mean_error = 0
for i in xrange(len(objpoints)):
for i in range(len(objpoints)):
imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2)/len(imgpoints2)
mean_error += error
@@ -79,7 +79,7 @@ from matplotlib import pyplot as plt
img1 = cv.imread('myleft.jpg',0) #queryimage # left image
img2 = cv.imread('myright.jpg',0) #trainimage # right image
sift = cv.SIFT()
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
@@ -93,14 +93,12 @@ search_params = dict(checks=50)
flann = cv.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
good = []
pts1 = []
pts2 = []
# ratio test as per Lowe's paper
for i,(m,n) in enumerate(matches):
if m.distance < 0.8*n.distance:
good.append(m)
pts2.append(kp2[m.trainIdx].pt)
pts1.append(kp1[m.queryIdx].pt)
@endcode
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env python
from pathlib import Path
import re
# Tasks
# 1. Find all tutorials
# 2. Generate tree (@subpage)
# 3. Check prev/next nodes
class Tutorial(object):
def __init__(self, path):
self.path = path
self.title = None # doxygen title
self.children = [] # ordered titles
self.prev = None
self.next = None
with open(path, "rt") as f:
self.parse(f)
def parse(self, f):
rx_title = re.compile(r"\{#(\w+)\}")
rx_subpage = re.compile(r"@subpage\s+(\w+)")
rx_prev = re.compile(r"@prev_tutorial\{(\w+)\}")
rx_next = re.compile(r"@next_tutorial\{(\w+)\}")
for line in f:
if self.title is None:
m = rx_title.search(line)
if m:
self.title = m.group(1)
continue
if self.prev is None:
m = rx_prev.search(line)
if m:
self.prev = m.group(1)
continue
if self.next is None:
m = rx_next.search(line)
if m:
self.next = m.group(1)
continue
m = rx_subpage.search(line)
if m:
self.children.append(m.group(1))
continue
def verify_prev_next(self, storage):
res = True
if self.title is None:
print("[W] No title")
res = False
prev = None
for one in self.children:
c = storage[one]
if c.prev is not None and c.prev != prev:
print("[W] Wrong prev_tutorial: expected {} / actual {}".format(c.prev, prev))
res = False
prev = c.title
next = None
for one in reversed(self.children):
c = storage[one]
if c.next is not None and c.next != next:
print("[W] Wrong next_tutorial: expected {} / actual {}".format(c.next, next))
res = False
next = c.title
if len(self.children) == 0 and self.prev is None and self.next is None:
print("[W] No prev and next tutorials")
res = False
return res
if __name__ == "__main__":
p = Path('tutorials')
print("Looking for tutorials in: '{}'".format(p))
all_tutorials = dict()
for f in p.glob('**/*'):
if f.suffix.lower() in ('.markdown', '.md'):
t = Tutorial(f)
all_tutorials[t.title] = t
res = 0
print("Found: {}".format(len(all_tutorials)))
print("------")
for title, t in all_tutorials.items():
if not t.verify_prev_next(all_tutorials):
print("[E] Verification failed: {}".format(t.path))
print("------")
res = 1
exit(res)
@@ -0,0 +1,4 @@
High Level GUI and Media (highgui module) {#tutorial_table_of_content_highgui}
=========================================
Content has been moved to this page: @ref tutorial_table_of_content_app
@@ -0,0 +1,4 @@
Image Input and Output (imgcodecs module) {#tutorial_table_of_content_imgcodecs}
=========================================
Content has been moved to this page: @ref tutorial_table_of_content_app
@@ -0,0 +1,4 @@
Video Input and Output (videoio module) {#tutorial_table_of_content_videoio}
=========================================
Content has been moved to this page: @ref tutorial_table_of_content_app

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@@ -1,7 +1,9 @@
Using Creative Senz3D and other Intel RealSense SDK compatible depth sensors {#tutorial_intelperc}
=======================================================================================
@prev_tutorial{tutorial_kinect_openni}
@tableofcontents
@prev_tutorial{tutorial_orbbec_astra}
**Note**: This tutorial is partially obsolete since PerC SDK has been replaced with RealSense SDK
@@ -1,8 +1,10 @@
Using Kinect and other OpenNI compatible depth sensors {#tutorial_kinect_openni}
======================================================
@tableofcontents
@prev_tutorial{tutorial_video_write}
@next_tutorial{tutorial_intelperc}
@next_tutorial{tutorial_orbbec_astra}
Depth sensors compatible with OpenNI (Kinect, XtionPRO, ...) are supported through VideoCapture
+165
View File
@@ -0,0 +1,165 @@
Using Orbbec Astra 3D cameras {#tutorial_orbbec_astra}
======================================================
@tableofcontents
@prev_tutorial{tutorial_kinect_openni}
@next_tutorial{tutorial_intelperc}
### Introduction
This tutorial is devoted to the Astra Series of Orbbec 3D cameras (https://orbbec3d.com/product-astra-pro/).
That cameras have a depth sensor in addition to a common color sensor. The depth sensors can be read using
the open source OpenNI API with @ref cv::VideoCapture class. The video stream is provided through the regular
camera interface.
### Installation Instructions
In order to use a depth sensor with OpenCV you should do the following steps:
-# Download the latest version of Orbbec OpenNI SDK (from here <https://orbbec3d.com/develop/>).
Unzip the archive, choose the build according to your operating system and follow installation
steps provided in the Readme file. For instance, if you use 64bit GNU/Linux run:
@code{.bash}
$ cd Linux/OpenNI-Linux-x64-2.3.0.63/
$ sudo ./install.sh
@endcode
When you are done with the installation, make sure to replug your device for udev rules to take
effect. The camera should now work as a general camera device. Note that your current user should
belong to group `video` to have access to the camera. Also, make sure to source `OpenNIDevEnvironment` file:
@code{.bash}
$ source OpenNIDevEnvironment
@endcode
-# Run the following commands to verify that OpenNI library and header files can be found. You should see
something similar in your terminal:
@code{.bash}
$ echo $OPENNI2_INCLUDE
/home/user/OpenNI_2.3.0.63/Linux/OpenNI-Linux-x64-2.3.0.63/Include
$ echo $OPENNI2_REDIST
/home/user/OpenNI_2.3.0.63/Linux/OpenNI-Linux-x64-2.3.0.63/Redist
@endcode
If the above two variables are empty, then you need to source `OpenNIDevEnvironment` again. Now you can
configure OpenCV with OpenNI support enabled by setting the `WITH_OPENNI2` flag in CMake.
You may also like to enable the `BUILD_EXAMPLES` flag to get a code sample working with your Astra camera.
Run the following commands in the directory containing OpenCV source code to enable OpenNI support:
@code{.bash}
$ mkdir build
$ cd build
$ cmake -DWITH_OPENNI2=ON ..
@endcode
If the OpenNI library is found, OpenCV will be built with OpenNI2 support. You can see the status of OpenNI2
support in the CMake log:
@code{.text}
-- Video I/O:
-- DC1394: YES (2.2.6)
-- FFMPEG: YES
-- avcodec: YES (58.91.100)
-- avformat: YES (58.45.100)
-- avutil: YES (56.51.100)
-- swscale: YES (5.7.100)
-- avresample: NO
-- GStreamer: YES (1.18.1)
-- OpenNI2: YES (2.3.0)
-- v4l/v4l2: YES (linux/videodev2.h)
@endcode
-# Build OpenCV:
@code{.bash}
$ make
@endcode
### Code
The Astra Pro camera has two sensors -- a depth sensor and a color sensor. The depth sensors
can be read using the OpenNI interface with @ref cv::VideoCapture class. The video stream is
not available through OpenNI API and is only provided through the regular camera interface.
So, to get both depth and color frames, two @ref cv::VideoCapture objects should be created:
@snippetlineno samples/cpp/tutorial_code/videoio/orbbec_astra/orbbec_astra.cpp Open streams
The first object will use the Video4Linux2 interface to access the color sensor. The second one
is using OpenNI2 API to retrieve depth data.
Before using the created VideoCapture objects you may want to set up stream parameters by setting
objects' properties. The most important parameters are frame width, frame height and fps.
For this example, well configure width and height of both streams to VGA resolution as thats
the maximum resolution available for both sensors and wed like both stream parameters to be the same:
@snippetlineno samples/cpp/tutorial_code/videoio/orbbec_astra/orbbec_astra.cpp Setup streams
For setting and getting some property of sensor data generators use @ref cv::VideoCapture::set and
@ref cv::VideoCapture::get methods respectively, e.g. :
@snippetlineno samples/cpp/tutorial_code/videoio/orbbec_astra/orbbec_astra.cpp Get properties
The following properties of cameras available through OpenNI interfaces are supported for the depth
generator:
- @ref cv::CAP_PROP_FRAME_WIDTH -- Frame width in pixels.
- @ref cv::CAP_PROP_FRAME_HEIGHT -- Frame height in pixels.
- @ref cv::CAP_PROP_FPS -- Frame rate in FPS.
- @ref cv::CAP_PROP_OPENNI_REGISTRATION -- Flag that registers the remapping depth map to image map
by changing the depth generator's viewpoint (if the flag is "on") or sets this view point to
its normal one (if the flag is "off"). The registration process resulting images are
pixel-aligned, which means that every pixel in the image is aligned to a pixel in the depth
image.
- @ref cv::CAP_PROP_OPENNI2_MIRROR -- Flag to enable or disable mirroring for this stream. Set to 0
to disable mirroring
Next properties are available for getting only:
- @ref cv::CAP_PROP_OPENNI_FRAME_MAX_DEPTH -- A maximum supported depth of the camera in mm.
- @ref cv::CAP_PROP_OPENNI_BASELINE -- Baseline value in mm.
After the VideoCapture objects are set up you can start reading frames from them.
@note
OpenCV's VideoCapture provides synchronous API, so you have to grab frames in a new thread
to avoid one stream blocking while another stream is being read. VideoCapture is not a
thread-safe class, so you need to be careful to avoid any possible deadlocks or data races.
As there are two video sources that should be read simultaneously, its necessary to create two
threads to avoid blocking. Example implementation that gets frames from each sensor in a new thread
and stores them in a list along with their timestamps:
@snippetlineno samples/cpp/tutorial_code/videoio/orbbec_astra/orbbec_astra.cpp Read streams
VideoCapture can retrieve the following data:
-# data given from the depth generator:
- @ref cv::CAP_OPENNI_DEPTH_MAP - depth values in mm (CV_16UC1)
- @ref cv::CAP_OPENNI_POINT_CLOUD_MAP - XYZ in meters (CV_32FC3)
- @ref cv::CAP_OPENNI_DISPARITY_MAP - disparity in pixels (CV_8UC1)
- @ref cv::CAP_OPENNI_DISPARITY_MAP_32F - disparity in pixels (CV_32FC1)
- @ref cv::CAP_OPENNI_VALID_DEPTH_MASK - mask of valid pixels (not occluded, not shaded, etc.)
(CV_8UC1)
-# data given from the color sensor is a regular BGR image (CV_8UC3).
When new data are available a reading thread notifies the main thread using a condition variable.
A frame is stored in the ordered list -- the first frame is the latest one. As depth and color frames
are read from independent sources two video streams may become out of sync even when both streams
are set up for the same frame rate. A post-synchronization procedure can be applied to the streams
to combine depth and color frames into pairs. The sample code below demonstrates this procedure:
@snippetlineno samples/cpp/tutorial_code/videoio/orbbec_astra/orbbec_astra.cpp Pair frames
In the code snippet above the execution is blocked until there are some frames in both frame lists.
When there are new frames, their timestamps are being checked -- if they differ more than a half of
the frame period then one of the frames is dropped. If timestamps are close enough, then two frames
are paired. Now, we have two frames: one containing color information and another one -- depth information.
In the example above retrieved frames are simply shown with cv::imshow function, but you can insert
any other processing code here.
In the sample images below you can see the color frame and the depth frame representing the same scene.
Looking at the color frame it's hard to distinguish plant leaves from leaves painted on a wall,
but the depth data makes it easy.
![Color frame](images/astra_color.jpg)
![Depth frame](images/astra_depth.png)
The complete implementation can be found in
[orbbec_astra.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/videoio/orbbec_astra/orbbec_astra.cpp)
in `samples/cpp/tutorial_code/videoio` directory.
@@ -1,6 +1,16 @@
Reading Geospatial Raster files with GDAL {#tutorial_raster_io_gdal}
=========================================
@tableofcontents
@prev_tutorial{tutorial_trackbar}
@next_tutorial{tutorial_video_input_psnr_ssim}
| | |
| -: | :- |
| Original author | Marvin Smith |
| Compatibility | OpenCV >= 3.0 |
Geospatial raster data is a heavily used product in Geographic Information Systems and
Photogrammetry. Raster data typically can represent imagery and Digital Elevation Models (DEM). The
standard library for loading GIS imagery is the Geographic Data Abstraction Library [(GDAL)](http://www.gdal.org). In this
@@ -0,0 +1,10 @@
Application utils (highgui, imgcodecs, videoio modules) {#tutorial_table_of_content_app}
=======================================================
- @subpage tutorial_trackbar
- @subpage tutorial_raster_io_gdal
- @subpage tutorial_video_input_psnr_ssim
- @subpage tutorial_video_write
- @subpage tutorial_kinect_openni
- @subpage tutorial_orbbec_astra
- @subpage tutorial_intelperc
@@ -1,6 +1,16 @@
Adding a Trackbar to our applications! {#tutorial_trackbar}
======================================
@tableofcontents
@next_tutorial{tutorial_raster_io_gdal}
| | |
| -: | :- |
| Original author | Ana Huamán |
| Compatibility | OpenCV >= 3.0 |
- In the previous tutorials (about @ref tutorial_adding_images and the @ref tutorial_basic_linear_transform)
you might have noted that we needed to give some **input** to our programs, such
as \f$\alpha\f$ and \f$beta\f$. We accomplished that by entering this data using the Terminal.
@@ -1,8 +1,16 @@
Video Input with OpenCV and similarity measurement {#tutorial_video_input_psnr_ssim}
==================================================
@tableofcontents
@prev_tutorial{tutorial_raster_io_gdal}
@next_tutorial{tutorial_video_write}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 3.0 |
Goal
----
@@ -1,9 +1,16 @@
Creating a video with OpenCV {#tutorial_video_write}
============================
@tableofcontents
@prev_tutorial{tutorial_video_input_psnr_ssim}
@next_tutorial{tutorial_kinect_openni}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 3.0 |
Goal
----
@@ -109,7 +116,7 @@ const string NAME = source.substr(0, pAt) + argv[2][0] + ".avi"; // Form the n
@code{.cpp}
CV_FOURCC('P','I','M,'1') // this is an MPEG1 codec from the characters to integer
@endcode
If you pass for this argument minus one than a window will pop up at runtime that contains all
If you pass for this argument minus one then a window will pop up at runtime that contains all
the codec installed on your system and ask you to select the one to use:
![](images/videoCompressSelect.png)
@@ -1,9 +1,16 @@
Camera calibration With OpenCV {#tutorial_camera_calibration}
==============================
@tableofcontents
@prev_tutorial{tutorial_camera_calibration_square_chess}
@next_tutorial{tutorial_real_time_pose}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 4.0 |
Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole*
cameras in the late 20th century, they became a common occurrence in our everyday life.
@@ -1,8 +1,15 @@
Create calibration pattern {#tutorial_camera_calibration_pattern}
=========================================
@tableofcontents
@next_tutorial{tutorial_camera_calibration_square_chess}
| | |
| -: | :- |
| Original author | Laurent Berger |
| Compatibility | OpenCV >= 3.0 |
The goal of this tutorial is to learn how to create calibration pattern.
@@ -1,9 +1,16 @@
Camera calibration with square chessboard {#tutorial_camera_calibration_square_chess}
=========================================
@tableofcontents
@prev_tutorial{tutorial_camera_calibration_pattern}
@next_tutorial{tutorial_camera_calibration}
| | |
| -: | :- |
| Original author | Victor Eruhimov |
| Compatibility | OpenCV >= 4.0 |
The goal of this tutorial is to learn how to calibrate a camera given a set of chessboard images.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

@@ -1,8 +1,15 @@
Interactive camera calibration application {#tutorial_interactive_calibration}
==============================
@tableofcontents
@prev_tutorial{tutorial_real_time_pose}
| | |
| -: | :- |
| Original author | Vladislav Sovrasov |
| Compatibility | OpenCV >= 3.1 |
According to classical calibration technique user must collect all data first and when run @ref cv::calibrateCamera function
to obtain camera parameters. If average re-projection error is huge or if estimated parameters seems to be wrong, process of
@@ -1,9 +1,16 @@
Real Time pose estimation of a textured object {#tutorial_real_time_pose}
==============================================
@tableofcontents
@prev_tutorial{tutorial_camera_calibration}
@next_tutorial{tutorial_interactive_calibration}
| | |
| -: | :- |
| Original author | Edgar Riba |
| Compatibility | OpenCV >= 3.0 |
Nowadays, augmented reality is one of the top research topic in computer vision and robotics fields.
The most elemental problem in augmented reality is the estimation of the camera pose respect of an
@@ -1,58 +1,8 @@
Camera calibration and 3D reconstruction (calib3d module) {#tutorial_table_of_content_calib3d}
==========================================================
Although we get most of our images in a 2D format they do come from a 3D world. Here you will learn how to find out 3D world information from 2D images.
- @subpage tutorial_camera_calibration_pattern
*Languages:* Python
*Compatibility:* \> OpenCV 2.0
*Author:* Laurent Berger
You will learn how to create some calibration pattern.
- @subpage tutorial_camera_calibration_square_chess
*Languages:* C++
*Compatibility:* \> OpenCV 2.0
*Author:* Victor Eruhimov
You will use some chessboard images to calibrate your camera.
- @subpage tutorial_camera_calibration
*Languages:* C++
*Compatibility:* \> OpenCV 4.0
*Author:* Bernát Gábor
Camera calibration by using either the chessboard, circle or the asymmetrical circle
pattern. Get the images either from a camera attached, a video file or from an image
collection.
- @subpage tutorial_real_time_pose
*Languages:* C++
*Compatibility:* \> OpenCV 2.0
*Author:* Edgar Riba
Real time pose estimation of a textured object using ORB features, FlannBased matcher, PnP
approach plus Ransac and Linear Kalman Filter to reject possible bad poses.
- @subpage tutorial_interactive_calibration
*Compatibility:* \> OpenCV 3.1
*Author:* Vladislav Sovrasov
Camera calibration by using either the chessboard, chAruco, asymmetrical circle or dual asymmetrical circle
pattern. Calibration process is continuous, so you can see results after each new pattern shot.
As an output you get average reprojection error, intrinsic camera parameters, distortion coefficients and
confidence intervals for all of evaluated variables.
@@ -1,9 +1,17 @@
Adding (blending) two images using OpenCV {#tutorial_adding_images}
=========================================
@tableofcontents
@prev_tutorial{tutorial_mat_operations}
@next_tutorial{tutorial_basic_linear_transform}
| | |
| -: | :- |
| Original author | Ana Huamán |
| Compatibility | OpenCV >= 3.0 |
We will learn how to blend two images!
Goal
----
@@ -1,9 +1,16 @@
Changing the contrast and brightness of an image! {#tutorial_basic_linear_transform}
=================================================
@tableofcontents
@prev_tutorial{tutorial_adding_images}
@next_tutorial{tutorial_discrete_fourier_transform}
| | |
| -: | :- |
| Original author | Ana Huamán |
| Compatibility | OpenCV >= 3.0 |
Goal
----
@@ -1,9 +1,16 @@
Discrete Fourier Transform {#tutorial_discrete_fourier_transform}
==========================
@tableofcontents
@prev_tutorial{tutorial_basic_linear_transform}
@next_tutorial{tutorial_file_input_output_with_xml_yml}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 3.0 |
Goal
----
@@ -1,9 +1,16 @@
File Input and Output using XML and YAML files {#tutorial_file_input_output_with_xml_yml}
==============================================
@tableofcontents
@prev_tutorial{tutorial_discrete_fourier_transform}
@next_tutorial{tutorial_how_to_use_OpenCV_parallel_for_}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 3.0 |
Goal
----
@@ -1,9 +1,16 @@
How to scan images, lookup tables and time measurement with OpenCV {#tutorial_how_to_scan_images}
==================================================================
@tableofcontents
@prev_tutorial{tutorial_mat_the_basic_image_container}
@next_tutorial{tutorial_mat_mask_operations}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 3.0 |
Goal
----
@@ -1,8 +1,14 @@
How to use the OpenCV parallel_for_ to parallelize your code {#tutorial_how_to_use_OpenCV_parallel_for_}
==================================================================
@tableofcontents
@prev_tutorial{tutorial_file_input_output_with_xml_yml}
| | |
| -: | :- |
| Compatibility | OpenCV >= 3.0 |
Goal
----
@@ -32,7 +38,7 @@ automatically available with the platform (e.g. APPLE GCD) but chances are that
have access to a parallel framework either directly or by enabling the option in CMake and rebuild the library.
The second (weak) precondition is more related to the task you want to achieve as not all computations
are suitable / can be adatapted to be run in a parallel way. To remain simple, tasks that can be split
are suitable / can be adapted to be run in a parallel way. To remain simple, tasks that can be split
into multiple elementary operations with no memory dependency (no possible race condition) are easily
parallelizable. Computer vision processing are often easily parallelizable as most of the time the processing of
one pixel does not depend to the state of other pixels.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

@@ -1,9 +1,16 @@
Mask operations on matrices {#tutorial_mat_mask_operations}
===========================
@tableofcontents
@prev_tutorial{tutorial_how_to_scan_images}
@next_tutorial{tutorial_mat_operations}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 3.0 |
Mask operations on matrices are quite simple. The idea is that we recalculate each pixel's value in
an image according to a mask matrix (also known as kernel). This mask holds values that will adjust
how much influence neighboring pixels (and the current pixel) have on the new pixel value. From a
@@ -1,9 +1,15 @@
Operations with images {#tutorial_mat_operations}
======================
@tableofcontents
@prev_tutorial{tutorial_mat_mask_operations}
@next_tutorial{tutorial_adding_images}
| | |
| -: | :- |
| Compatibility | OpenCV >= 3.0 |
Input/Output
------------
@@ -1,8 +1,15 @@
Mat - The Basic Image Container {#tutorial_mat_the_basic_image_container}
===============================
@tableofcontents
@next_tutorial{tutorial_how_to_scan_images}
| | |
| -: | :- |
| Original author | Bernát Gábor |
| Compatibility | OpenCV >= 3.0 |
Goal
----

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