Merge remote-tracking branch 'upstream/3.4' into merge-3.4

pull/17351/head
Alexander Alekhin 5 years ago
commit 21e28adb87
  1. 3
      3rdparty/quirc/include/quirc_internal.h
  2. 2
      3rdparty/quirc/src/decode.c
  3. 29
      3rdparty/quirc/src/quirc.c
  4. 11
      3rdparty/quirc/src/version_db.c
  5. 4
      doc/tutorials/calib3d/camera_calibration/camera_calibration.markdown
  6. 3
      doc/tutorials/calib3d/camera_calibration_pattern/camera_calibration_pattern.markdown
  7. 4
      doc/tutorials/calib3d/camera_calibration_square_chess/camera_calibration_square_chess.markdown
  8. 3
      doc/tutorials/calib3d/interactive_calibration/interactive_calibration.markdown
  9. 4
      doc/tutorials/calib3d/real_time_pose/real_time_pose.markdown
  10. 3
      doc/tutorials/dnn/dnn_android/dnn_android.markdown
  11. 2
      doc/tutorials/dnn/dnn_custom_layers/dnn_custom_layers.md
  12. 2
      doc/tutorials/dnn/dnn_googlenet/dnn_googlenet.markdown
  13. 3
      doc/tutorials/dnn/dnn_halide/dnn_halide.markdown
  14. 3
      doc/tutorials/dnn/dnn_halide_scheduling/dnn_halide_scheduling.markdown
  15. 3
      doc/tutorials/dnn/dnn_javascript/dnn_javascript.markdown
  16. 3
      doc/tutorials/dnn/dnn_yolo/dnn_yolo.markdown
  17. 3
      doc/tutorials/features2d/akaze_matching/akaze_matching.markdown
  18. 3
      doc/tutorials/features2d/akaze_tracking/akaze_tracking.markdown
  19. 4
      doc/tutorials/features2d/detection_of_planar_objects/detection_of_planar_objects.markdown
  20. 3
      doc/tutorials/features2d/feature_description/feature_description.markdown
  21. 3
      doc/tutorials/features2d/feature_detection/feature_detection.markdown
  22. 3
      doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.markdown
  23. 3
      doc/tutorials/features2d/feature_homography/feature_homography.markdown
  24. 2
      doc/tutorials/features2d/homography/homography.markdown
  25. 3
      doc/tutorials/features2d/trackingmotion/corner_subpixels/corner_subpixels.markdown
  26. 4
      doc/tutorials/features2d/trackingmotion/generic_corner_detector/generic_corner_detector.markdown
  27. 3
      doc/tutorials/features2d/trackingmotion/good_features_to_track/good_features_to_track.markdown
  28. 2
      doc/tutorials/features2d/trackingmotion/harris_detector/harris_detector.markdown
  29. 2
      doc/tutorials/gpu/gpu-basics-similarity/gpu_basics_similarity.markdown
  30. 2
      doc/tutorials/gpu/gpu-thrust-interop/gpu_thrust_interop.markdown
  31. 4
      doc/tutorials/introduction/android_binary_package/O4A_SDK.markdown
  32. 4
      doc/tutorials/introduction/android_binary_package/android_dev_intro.markdown
  33. 4
      doc/tutorials/introduction/android_binary_package/android_ocl_intro.markdown
  34. 4
      doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.markdown
  35. 4
      doc/tutorials/introduction/building_tegra_cuda/building_tegra_cuda.markdown
  36. 4
      doc/tutorials/introduction/clojure_dev_intro/clojure_dev_intro.markdown
  37. 3
      doc/tutorials/introduction/cross_referencing/tutorial_cross_referencing.markdown
  38. 4
      doc/tutorials/introduction/crosscompilation/arm_crosscompile_with_cmake.markdown
  39. 4
      doc/tutorials/introduction/desktop_java/java_dev_intro.markdown
  40. 3
      doc/tutorials/introduction/display_image/display_image.markdown
  41. 7
      doc/tutorials/introduction/documenting_opencv/documentation_tutorial.markdown
  42. 3
      doc/tutorials/introduction/ios_install/ios_install.markdown
  43. 4
      doc/tutorials/introduction/java_eclipse/java_eclipse.markdown
  44. 3
      doc/tutorials/introduction/linux_eclipse/linux_eclipse.markdown
  45. 4
      doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.markdown
  46. 3
      doc/tutorials/introduction/linux_install/linux_install.markdown
  47. 6
      doc/tutorials/introduction/macos_install/macos_install.markdown
  48. 4
      doc/tutorials/introduction/transition_guide/transition_guide.markdown
  49. 4
      doc/tutorials/introduction/windows_install/windows_install.markdown
  50. 4
      doc/tutorials/introduction/windows_visual_studio_image_watch/windows_visual_studio_image_watch.markdown
  51. 4
      doc/tutorials/introduction/windows_visual_studio_opencv/windows_visual_studio_opencv.markdown
  52. 2
      doc/tutorials/ios/hello/hello.markdown
  53. 3
      doc/tutorials/ios/image_manipulation/image_manipulation.markdown
  54. 3
      doc/tutorials/ios/video_processing/video_processing.markdown
  55. 2
      doc/tutorials/ml/introduction_to_pca/introduction_to_pca.markdown
  56. 2
      doc/tutorials/ml/introduction_to_svm/introduction_to_svm.markdown
  57. 3
      doc/tutorials/ml/non_linear_svms/non_linear_svms.markdown
  58. 2
      doc/tutorials/objdetect/cascade_classifier/cascade_classifier.markdown
  59. 2
      doc/tutorials/objdetect/traincascade.markdown
  60. 2
      doc/tutorials/video/background_subtraction/background_subtraction.markdown
  61. 3
      doc/tutorials/video/meanshift/meanshift.markdown
  62. 2
      doc/tutorials/video/optical_flow/optical_flow.markdown
  63. 2
      doc/tutorials/videoio/intelperc.markdown
  64. 4
      doc/tutorials/videoio/kinect_openni.markdown
  65. 2
      doc/tutorials/videoio/video-input-psnr-ssim/video_input_psnr_ssim.markdown
  66. 3
      doc/tutorials/videoio/video-write/video_write.markdown
  67. 24
      modules/dnn/include/opencv2/dnn/all_layers.hpp
  68. 29
      modules/dnn/src/caffe/caffe_importer.cpp
  69. 4
      modules/dnn/src/init.cpp
  70. 141
      modules/dnn/src/layers/accum_layer.cpp
  71. 11
      modules/dnn/src/layers/convolution_layer.cpp
  72. 207
      modules/dnn/src/layers/correlation_layer.cpp
  73. 117
      modules/dnn/src/layers/flow_warp_layer.cpp
  74. 11
      modules/dnn/src/layers/resize_layer.cpp
  75. 113
      modules/dnn/src/layers/scale_layer.cpp
  76. 111
      modules/dnn/test/test_layers.cpp
  77. 2
      modules/videoio/src/cap_avfoundation.mm
  78. 2
      modules/videoio/src/cap_ios_abstract_camera.mm
  79. 85
      samples/dnn/optical_flow.py

@ -32,8 +32,10 @@
#define QUIRC_PERSPECTIVE_PARAMS 8
#if QUIRC_MAX_REGIONS < UINT8_MAX
#define QUIRC_PIXEL_ALIAS_IMAGE 1
typedef uint8_t quirc_pixel_t;
#elif QUIRC_MAX_REGIONS < UINT16_MAX
#define QUIRC_PIXEL_ALIAS_IMAGE 0
typedef uint16_t quirc_pixel_t;
#else
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
@ -77,7 +79,6 @@ struct quirc_grid {
struct quirc {
uint8_t *image;
quirc_pixel_t *pixels;
int *row_average; /* used by threshold() */
int w;
int h;

@ -874,7 +874,7 @@ static quirc_decode_error_t decode_payload(struct quirc_data *data,
done:
/* Add nul terminator to all payloads */
if ((unsigned)data->payload_len >= sizeof(data->payload))
if (data->payload_len >= (int) sizeof(data->payload))
data->payload_len--;
data->payload[data->payload_len] = 0;

@ -27,10 +27,7 @@ struct quirc *quirc_new(void)
{
struct quirc *q = malloc(sizeof(*q));
if (!q)
return NULL;
memset(q, 0, sizeof(*q));
memset(q, 0, sizeof(*q));
return q;
}
@ -39,9 +36,8 @@ void quirc_destroy(struct quirc *q)
free(q->image);
/* q->pixels may alias q->image when their type representation is of the
same size, so we need to be careful here to avoid a double free */
if (sizeof(*q->image) != sizeof(*q->pixels))
if (!QUIRC_PIXEL_ALIAS_IMAGE)
free(q->pixels);
free(q->row_average);
free(q);
}
@ -49,7 +45,6 @@ int quirc_resize(struct quirc *q, int w, int h)
{
uint8_t *image = NULL;
quirc_pixel_t *pixels = NULL;
int *row_average = NULL;
/*
* XXX: w and h should be size_t (or at least unsigned) as negatives
@ -82,35 +77,27 @@ int quirc_resize(struct quirc *q, int w, int h)
(void)memcpy(image, q->image, min);
/* alloc a new buffer for q->pixels if needed */
if (sizeof(*q->image) != sizeof(*q->pixels)) {
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
pixels = calloc(newdim, sizeof(quirc_pixel_t));
if (!pixels)
goto fail;
}
/* alloc a new buffer for q->row_average */
row_average = calloc(w, sizeof(int));
if (!row_average)
goto fail;
/* alloc succeeded, update `q` with the new size and buffers */
q->w = w;
q->h = h;
free(q->image);
q->image = image;
if (sizeof(*q->image) != sizeof(*q->pixels)) {
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
free(q->pixels);
q->pixels = pixels;
}
free(q->row_average);
q->row_average = row_average;
return 0;
/* NOTREACHED */
fail:
free(image);
free(pixels);
free(row_average);
return -1;
}
@ -133,6 +120,10 @@ static const char *const error_table[] = {
const char *quirc_strerror(quirc_decode_error_t err)
{
if ((int)err < 8) { return error_table[err]; }
else { return "Unknown error"; }
if ((int) err >= 0) {
if ((unsigned long) err < (unsigned long) (sizeof(error_table) / sizeof(error_table[0])))
return error_table[err];
}
return "Unknown error";
}

@ -17,16 +17,7 @@
#include <quirc_internal.h>
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
{ /* 0 */
.data_bytes = 0,
.apat = {0},
.ecc = {
{.bs = 0, .dw = 0, .ns = 0},
{.bs = 0, .dw = 0, .ns = 0},
{.bs = 0, .dw = 0, .ns = 0},
{.bs = 0, .dw = 0, .ns = 0}
}
},
{0},
{ /* Version 1 */
.data_bytes = 26,
.apat = {0},

@ -1,6 +1,10 @@
Camera calibration With OpenCV {#tutorial_camera_calibration}
==============================
@prev_tutorial{tutorial_camera_calibration_square_chess}
@next_tutorial{tutorial_real_time_pose}
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.
Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are

@ -1,6 +1,9 @@
Create calibration pattern {#tutorial_camera_calibration_pattern}
=========================================
@next_tutorial{tutorial_camera_calibration_square_chess}
The goal of this tutorial is to learn how to create calibration pattern.
You can find a chessboard pattern in https://github.com/opencv/opencv/blob/master/doc/pattern.png

@ -1,6 +1,10 @@
Camera calibration with square chessboard {#tutorial_camera_calibration_square_chess}
=========================================
@prev_tutorial{tutorial_camera_calibration_pattern}
@next_tutorial{tutorial_camera_calibration}
The goal of this tutorial is to learn how to calibrate a camera given a set of chessboard images.
*Test data*: use images in your data/chess folder.

@ -1,6 +1,9 @@
Interactive camera calibration application {#tutorial_interactive_calibration}
==============================
@prev_tutorial{tutorial_real_time_pose}
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
selection or collecting data and starting of @ref cv::calibrateCamera repeats.

@ -1,6 +1,10 @@
Real Time pose estimation of a textured object {#tutorial_real_time_pose}
==============================================
@prev_tutorial{tutorial_camera_calibration}
@next_tutorial{tutorial_interactive_calibration}
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
object in the case of computer vision area to do later some 3D rendering or in the case of robotics

@ -1,5 +1,8 @@
# How to run deep networks on Android device {#tutorial_dnn_android}
@prev_tutorial{tutorial_dnn_halide_scheduling}
@next_tutorial{tutorial_dnn_yolo}
## Introduction
In this tutorial you'll know how to run deep learning networks on Android device
using OpenCV deep learning module.

@ -1,5 +1,7 @@
# Custom deep learning layers support {#tutorial_dnn_custom_layers}
@prev_tutorial{tutorial_dnn_javascript}
## Introduction
Deep learning is a fast growing area. The new approaches to build neural networks
usually introduce new types of layers. They could be modifications of existing

@ -1,6 +1,8 @@
Load Caffe framework models {#tutorial_dnn_googlenet}
===========================
@next_tutorial{tutorial_dnn_halide}
Introduction
------------

@ -1,5 +1,8 @@
# How to enable Halide backend for improve efficiency {#tutorial_dnn_halide}
@prev_tutorial{tutorial_dnn_googlenet}
@next_tutorial{tutorial_dnn_halide_scheduling}
## Introduction
This tutorial guidelines how to run your models in OpenCV deep learning module
using Halide language backend. Halide is an open-source project that let us

@ -1,5 +1,8 @@
# How to schedule your network for Halide backend {#tutorial_dnn_halide_scheduling}
@prev_tutorial{tutorial_dnn_halide}
@next_tutorial{tutorial_dnn_android}
## Introduction
Halide code is the same for every device we use. But for achieving the satisfied
efficiency we should schedule computations properly. In this tutorial we describe

@ -1,5 +1,8 @@
# How to run deep networks in browser {#tutorial_dnn_javascript}
@prev_tutorial{tutorial_dnn_yolo}
@next_tutorial{tutorial_dnn_custom_layers}
## Introduction
This tutorial will show us how to run deep learning models using OpenCV.js right
in a browser. Tutorial refers a sample of face detection and face recognition

@ -1,6 +1,9 @@
YOLO DNNs {#tutorial_dnn_yolo}
===============================
@prev_tutorial{tutorial_dnn_android}
@next_tutorial{tutorial_dnn_javascript}
Introduction
------------

@ -1,6 +1,9 @@
AKAZE local features matching {#tutorial_akaze_matching}
=============================
@prev_tutorial{tutorial_detection_of_planar_objects}
@next_tutorial{tutorial_akaze_tracking}
Introduction
------------

@ -1,6 +1,9 @@
AKAZE and ORB planar tracking {#tutorial_akaze_tracking}
=============================
@prev_tutorial{tutorial_akaze_matching}
@next_tutorial{tutorial_homography}
Introduction
------------

@ -1,6 +1,10 @@
Detection of planar objects {#tutorial_detection_of_planar_objects}
===========================
@prev_tutorial{tutorial_feature_homography}
@next_tutorial{tutorial_akaze_matching}
The goal of this tutorial is to learn how to use *features2d* and *calib3d* modules for detecting
known planar objects in scenes.

@ -1,6 +1,9 @@
Feature Description {#tutorial_feature_description}
===================
@prev_tutorial{tutorial_feature_detection}
@next_tutorial{tutorial_feature_flann_matcher}
Goal
----

@ -1,6 +1,9 @@
Feature Detection {#tutorial_feature_detection}
=================
@prev_tutorial{tutorial_corner_subpixels}
@next_tutorial{tutorial_feature_description}
Goal
----

@ -1,6 +1,9 @@
Feature Matching with FLANN {#tutorial_feature_flann_matcher}
===========================
@prev_tutorial{tutorial_feature_description}
@next_tutorial{tutorial_feature_homography}
Goal
----

@ -1,6 +1,9 @@
Features2D + Homography to find a known object {#tutorial_feature_homography}
==============================================
@prev_tutorial{tutorial_feature_flann_matcher}
@next_tutorial{tutorial_detection_of_planar_objects}
Goal
----

@ -1,6 +1,8 @@
Basic concepts of the homography explained with code {#tutorial_homography}
====================================================
@prev_tutorial{tutorial_akaze_tracking}
@tableofcontents
Introduction {#tutorial_homography_Introduction}

@ -1,6 +1,9 @@
Detecting corners location in subpixels {#tutorial_corner_subpixels}
=======================================
@prev_tutorial{tutorial_generic_corner_detector}
@next_tutorial{tutorial_feature_detection}
Goal
----

@ -1,6 +1,10 @@
Creating your own corner detector {#tutorial_generic_corner_detector}
=================================
@prev_tutorial{tutorial_good_features_to_track}
@next_tutorial{tutorial_corner_subpixels}
Goal
----

@ -1,6 +1,9 @@
Shi-Tomasi corner detector {#tutorial_good_features_to_track}
==========================
@prev_tutorial{tutorial_harris_detector}
@next_tutorial{tutorial_generic_corner_detector}
Goal
----

@ -1,6 +1,8 @@
Harris corner detector {#tutorial_harris_detector}
======================
@next_tutorial{tutorial_good_features_to_track}
Goal
----

@ -3,6 +3,8 @@ Similarity check (PNSR and SSIM) on the GPU {#tutorial_gpu_basics_similarity}
===========================================
@todo update this tutorial
@next_tutorial{tutorial_gpu_thrust_interop}
Goal
----

@ -2,6 +2,8 @@
Using a cv::cuda::GpuMat with thrust {#tutorial_gpu_thrust_interop}
===========================================
@prev_tutorial{tutorial_gpu_basics_similarity}
Goal
----

@ -1,6 +1,10 @@
OpenCV4Android SDK {#tutorial_O4A_SDK}
==================
@prev_tutorial{tutorial_android_dev_intro}
@next_tutorial{tutorial_dev_with_OCV_on_Android}
This tutorial was designed to help you with installation and configuration of OpenCV4Android SDK.
This guide was written with MS Windows 7 in mind, though it should work with GNU Linux and Apple Mac

@ -1,6 +1,10 @@
Introduction into Android Development {#tutorial_android_dev_intro}
=====================================
@prev_tutorial{tutorial_clojure_dev_intro}
@next_tutorial{tutorial_O4A_SDK}
This guide was designed to help you in learning Android development basics and setting up your
working environment quickly. It was written with Windows 7 in mind, though it would work with Linux
(Ubuntu), Mac OS X and any other OS supported by Android SDK.

@ -1,6 +1,10 @@
Use OpenCL in Android camera preview based CV application {#tutorial_android_ocl_intro}
=====================================
@prev_tutorial{tutorial_dev_with_OCV_on_Android}
@next_tutorial{tutorial_macos_install}
This guide was designed to help you in use of [OpenCL &trade;](https://www.khronos.org/opencl/) in Android camera preview based CV application.
It was written for [Eclipse-based ADT tools](http://developer.android.com/tools/help/adt.html)
(deprecated by Google now), but it easily can be reproduced with [Android Studio](http://developer.android.com/tools/studio/index.html).

@ -1,6 +1,10 @@
Android Development with OpenCV {#tutorial_dev_with_OCV_on_Android}
===============================
@prev_tutorial{tutorial_O4A_SDK}
@next_tutorial{tutorial_android_ocl_intro}
This tutorial has been created to help you use OpenCV library within your Android project.
This guide was written with Windows 7 in mind, though it should work with any other OS supported by

@ -1,6 +1,10 @@
Building OpenCV for Tegra with CUDA {#tutorial_building_tegra_cuda}
===================================
@prev_tutorial{tutorial_arm_crosscompile_with_cmake}
@next_tutorial{tutorial_display_image}
@tableofcontents
OpenCV with CUDA for Tegra

@ -1,6 +1,10 @@
Introduction to OpenCV Development with Clojure {#tutorial_clojure_dev_intro}
===============================================
@prev_tutorial{tutorial_java_eclipse}
@next_tutorial{tutorial_android_dev_intro}
As of OpenCV 2.4.4, OpenCV supports desktop Java development using nearly the same interface as for
Android development.

@ -1,6 +1,9 @@
Cross referencing OpenCV from other Doxygen projects {#tutorial_cross_referencing}
====================================================
@prev_tutorial{tutorial_transition_guide}
Cross referencing OpenCV
------------------------

@ -1,6 +1,10 @@
Cross compilation for ARM based Linux systems {#tutorial_arm_crosscompile_with_cmake}
=============================================
@prev_tutorial{tutorial_ios_install}
@next_tutorial{tutorial_building_tegra_cuda}
This steps are tested on Ubuntu Linux 12.04, but should work for other Linux distributions. I case
of other distributions package names and names of cross compilation tools may differ. There are
several popular EABI versions that are used on ARM platform. This tutorial is written for *gnueabi*

@ -1,6 +1,10 @@
Introduction to Java Development {#tutorial_java_dev_intro}
================================
@prev_tutorial{tutorial_windows_visual_studio_image_watch}
@next_tutorial{tutorial_java_eclipse}
As of OpenCV 2.4.4, OpenCV supports desktop Java development using nearly the same interface as for
Android development. This guide will help you to create your first Java (or Scala) application using
OpenCV. We will use either [Apache Ant](http://ant.apache.org/) or [Simple Build Tool

@ -1,6 +1,9 @@
Getting Started with Images {#tutorial_display_image}
===========================
@prev_tutorial{tutorial_building_tegra_cuda}
@next_tutorial{tutorial_documentation}
Goal
----

@ -1,6 +1,10 @@
Writing documentation for OpenCV {#tutorial_documentation}
================================
@prev_tutorial{tutorial_display_image}
@next_tutorial{tutorial_transition_guide}
@tableofcontents
Doxygen overview {#tutorial_documentation_overview}
@ -47,6 +51,9 @@ Generate documentation {#tutorial_documentation_generate}
@code{.sh}
make check_pylint
@endcode
@note [Pylint](https://www.pylint.org/#install) must be installed before running cmake to be
able to test Python code. You can install using your system's package manager, or with pip:
@code{.sh} pip install pylint @endcode
Quick start {#tutorial_documentation_quick_start}
===========

@ -1,6 +1,9 @@
Installation in iOS {#tutorial_ios_install}
===================
@prev_tutorial{tutorial_macos_install}
@next_tutorial{tutorial_arm_crosscompile_with_cmake}
Required Packages
-----------------

@ -1,6 +1,10 @@
Using OpenCV Java with Eclipse {#tutorial_java_eclipse}
==============================
@prev_tutorial{tutorial_java_dev_intro}
@next_tutorial{tutorial_clojure_dev_intro}
Since version 2.4.4 [OpenCV supports Java](http://opencv.org/opencv-java-api.html). In this tutorial
I will explain how to setup development environment for using OpenCV Java with Eclipse in
**Windows**, so you can enjoy the benefits of garbage collected, very refactorable (rename variable,

@ -1,6 +1,9 @@
Using OpenCV with Eclipse (plugin CDT) {#tutorial_linux_eclipse}
======================================
@prev_tutorial{tutorial_linux_gcc_cmake}
@next_tutorial{tutorial_windows_install}
Prerequisites
-------------
Two ways, one by forming a project directly, and another by CMake Prerequisites

@ -1,6 +1,10 @@
Using OpenCV with gcc and CMake {#tutorial_linux_gcc_cmake}
===============================
@prev_tutorial{tutorial_linux_install}
@next_tutorial{tutorial_linux_eclipse}
@note We assume that you have successfully installed OpenCV in your workstation.
- The easiest way of using OpenCV in your code is to use [CMake](http://www.cmake.org/). A few

@ -1,6 +1,9 @@
Installation in Linux {#tutorial_linux_install}
=====================
@next_tutorial{tutorial_linux_gcc_cmake}
The following steps have been tested for Ubuntu 10.04 but should work with other distros as well.
Required Packages

@ -1,6 +1,10 @@
Installation in MacOS {#tutorial_macos_install}
=====================
@prev_tutorial{tutorial_android_ocl_intro}
@next_tutorial{tutorial_ios_install}
The following steps have been tested for MacOSX (Mavericks) but should work with other versions as well.
Required Packages
@ -35,6 +39,8 @@ Installing CMake
cmake --version
@endcode
@note You can use [Homebrew](https://brew.sh/) to install CMake with @code{.bash} brew install cmake @endcode
Getting OpenCV Source Code
--------------------------

@ -1,6 +1,10 @@
Transition guide {#tutorial_transition_guide}
================
@prev_tutorial{tutorial_documentation}
@next_tutorial{tutorial_cross_referencing}
@tableofcontents
Changes overview {#tutorial_transition_overview}

@ -1,6 +1,10 @@
Installation in Windows {#tutorial_windows_install}
=======================
@prev_tutorial{tutorial_linux_eclipse}
@next_tutorial{tutorial_windows_visual_studio_opencv}
The description here was tested on Windows 7 SP1. Nevertheless, it should also work on any other
relatively modern version of Windows OS. If you encounter errors after following the steps described
below, feel free to contact us via our [OpenCV Q&A forum](http://answers.opencv.org). We'll do our

@ -1,6 +1,10 @@
Image Watch: viewing in-memory images in the Visual Studio debugger {#tutorial_windows_visual_studio_image_watch}
===================================================================
@prev_tutorial{tutorial_windows_visual_studio_opencv}
@next_tutorial{tutorial_java_dev_intro}
Image Watch is a plug-in for Microsoft Visual Studio that lets you to visualize in-memory images
(*cv::Mat* or *IplImage_* objects, for example) while debugging an application. This can be helpful
for tracking down bugs, or for simply understanding what a given piece of code is doing.

@ -1,6 +1,10 @@
How to build applications with OpenCV inside the "Microsoft Visual Studio" {#tutorial_windows_visual_studio_opencv}
==========================================================================
@prev_tutorial{tutorial_windows_install}
@next_tutorial{tutorial_windows_visual_studio_image_watch}
Everything I describe here will apply to the `C\C++` interface of OpenCV. I start out from the
assumption that you have read and completed with success the @ref tutorial_windows_install tutorial.
Therefore, before you go any further make sure you have an OpenCV directory that contains the OpenCV

@ -1,6 +1,8 @@
OpenCV iOS Hello {#tutorial_hello}
================
@next_tutorial{tutorial_image_manipulation}
Goal
----

@ -1,6 +1,9 @@
OpenCV iOS - Image Processing {#tutorial_image_manipulation}
=============================
@prev_tutorial{tutorial_hello}
@next_tutorial{tutorial_video_processing}
Goal
----

@ -1,6 +1,9 @@
OpenCV iOS - Video Processing {#tutorial_video_processing}
=============================
@prev_tutorial{tutorial_image_manipulation}
This tutorial explains how to process video frames using the iPhone's camera and OpenCV.
Prerequisites:

@ -1,6 +1,8 @@
Introduction to Principal Component Analysis (PCA) {#tutorial_introduction_to_pca}
=======================================
@prev_tutorial{tutorial_non_linear_svms}
Goal
----

@ -1,6 +1,8 @@
Introduction to Support Vector Machines {#tutorial_introduction_to_svm}
=======================================
@next_tutorial{tutorial_non_linear_svms}
Goal
----

@ -1,6 +1,9 @@
Support Vector Machines for Non-Linearly Separable Data {#tutorial_non_linear_svms}
=======================================================
@prev_tutorial{tutorial_introduction_to_svm}
@next_tutorial{tutorial_introduction_to_pca}
Goal
----

@ -1,6 +1,8 @@
Cascade Classifier {#tutorial_cascade_classifier}
==================
@next_tutorial{tutorial_traincascade}
Goal
----

@ -1,6 +1,8 @@
Cascade Classifier Training {#tutorial_traincascade}
===========================
@prev_tutorial{tutorial_cascade_classifier}
Introduction
------------

@ -1,6 +1,8 @@
How to Use Background Subtraction Methods {#tutorial_background_subtraction}
=========================================
@next_tutorial{tutorial_meanshift}
- Background subtraction (BS) is a common and widely used technique for generating a foreground
mask (namely, a binary image containing the pixels belonging to moving objects in the scene) by
using static cameras.

@ -1,6 +1,9 @@
Meanshift and Camshift {#tutorial_meanshift}
======================
@prev_tutorial{tutorial_background_subtraction}
@next_tutorial{tutorial_optical_flow}
Goal
----

@ -1,6 +1,8 @@
Optical Flow {#tutorial_optical_flow}
============
@prev_tutorial{tutorial_meanshift}
Goal
----

@ -1,6 +1,8 @@
Using Creative Senz3D and other Intel Perceptual Computing SDK compatible depth sensors {#tutorial_intelperc}
=======================================================================================
@prev_tutorial{tutorial_kinect_openni}
**Note**: this tutorial is partially obsolete since PerC SDK has been replaced with RealSense SDK
Depth sensors compatible with Intel Perceptual Computing SDK are supported through VideoCapture

@ -1,6 +1,10 @@
Using Kinect and other OpenNI compatible depth sensors {#tutorial_kinect_openni}
======================================================
@prev_tutorial{tutorial_video_write}
@next_tutorial{tutorial_intelperc}
Depth sensors compatible with OpenNI (Kinect, XtionPRO, ...) are supported through VideoCapture
class. Depth map, BGR image and some other formats of output can be retrieved by using familiar
interface of VideoCapture.

@ -1,6 +1,8 @@
Video Input with OpenCV and similarity measurement {#tutorial_video_input_psnr_ssim}
==================================================
@next_tutorial{tutorial_video_write}
Goal
----

@ -1,6 +1,9 @@
Creating a video with OpenCV {#tutorial_video_write}
============================
@prev_tutorial{tutorial_video_input_psnr_ssim}
@next_tutorial{tutorial_kinect_openni}
Goal
----

@ -556,6 +556,30 @@ CV__DNN_INLINE_NS_BEGIN
static Ptr<Layer> create(const LayerParams& params);
};
class CV_EXPORTS DataAugmentationLayer : public Layer
{
public:
static Ptr<DataAugmentationLayer> create(const LayerParams& params);
};
class CV_EXPORTS CorrelationLayer : public Layer
{
public:
static Ptr<CorrelationLayer> create(const LayerParams& params);
};
class CV_EXPORTS AccumLayer : public Layer
{
public:
static Ptr<AccumLayer> create(const LayerParams& params);
};
class CV_EXPORTS FlowWarpLayer : public Layer
{
public:
static Ptr<FlowWarpLayer> create(const LayerParams& params);
};
class CV_EXPORTS PriorBoxLayer : public Layer
{
public:

@ -465,6 +465,35 @@ public:
net.mutable_layer(li)->mutable_bottom()->RemoveLast();
type = "Eltwise";
}
else if (type == "Resample")
{
CV_Assert(layer.bottom_size() == 1 || layer.bottom_size() == 2);
type = "Resize";
String interp = toLowerCase(layerParams.get<String>("type"));
layerParams.set("interpolation", interp == "linear" ? "bilinear" : interp);
if (layerParams.has("factor"))
{
float factor = layerParams.get<float>("factor");
CV_Assert(layer.bottom_size() != 2 || factor == 1.0);
layerParams.set("zoom_factor", factor);
if ((interp == "linear" && factor != 1.0) ||
(interp == "nearest" && factor < 1.0))
CV_Error(Error::StsNotImplemented, "Unsupported Resample mode");
}
}
else if ("Convolution" == type)
{
CV_Assert(layer.bottom_size() == layer.top_size());
for (int i = 0; i < layer.bottom_size(); i++)
{
int conv_id = dstNet.addLayer(layer.top(i), type, layerParams);
addInput(layer.bottom(i), conv_id, 0, dstNet);
addedBlobs.push_back(BlobNote(layer.top(i), conv_id, 0));
}
continue;
}
else if ("ConvolutionDepthwise" == type)
{
type = "Convolution";

@ -132,6 +132,10 @@ void initializeLayerFactory()
CV_DNN_REGISTER_LAYER_CLASS(Padding, PaddingLayer);
CV_DNN_REGISTER_LAYER_CLASS(Proposal, ProposalLayer);
CV_DNN_REGISTER_LAYER_CLASS(Scale, ScaleLayer);
CV_DNN_REGISTER_LAYER_CLASS(DataAugmentation, DataAugmentationLayer);
CV_DNN_REGISTER_LAYER_CLASS(Correlation, CorrelationLayer);
CV_DNN_REGISTER_LAYER_CLASS(Accum, AccumLayer);
CV_DNN_REGISTER_LAYER_CLASS(FlowWarp, FlowWarpLayer);
CV_DNN_REGISTER_LAYER_CLASS(LSTM, LSTMLayer);
}

@ -0,0 +1,141 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2020, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "../precomp.hpp"
#include "layers_common.hpp"
namespace cv { namespace dnn {
class AccumLayerImpl CV_FINAL : public AccumLayer
{
public:
AccumLayerImpl(const LayerParams& params)
{
setParamsFrom(params);
top_height = params.get<int>("top_height", 0);
top_width = params.get<int>("top_width", 0);
divisor = params.get<int>("size_divisible_by", 0);
have_reference = params.get<String>("have_reference", "false") == "true";
}
virtual bool getMemoryShapes(const std::vector<MatShape> &inputs,
const int requiredOutputs,
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const CV_OVERRIDE
{
std::vector<int> outShape;
int batch = inputs[0][0];
outShape.push_back(batch);
if (have_reference)
{
CV_Assert(inputs.size() >= 2);
int totalchannels = 0;
for (int i = 0; i < inputs.size() - 1; i++) {
CV_Assert(inputs[i][0] == batch);
totalchannels += inputs[i][1];
}
outShape.push_back(totalchannels);
int height = inputs.back()[2];
int width = inputs.back()[3];
outShape.push_back(height);
outShape.push_back(width);
}
else
{
int maxwidth = -1;
int maxheight = -1;
int totalchannels = 0;
// Find largest blob size and count total channels
for (int i = 0; i < inputs.size(); ++i)
{
totalchannels += inputs[i][1];
maxheight = std::max(maxheight, inputs[i][2]);
maxwidth = std::max(maxwidth, inputs[i][3]);
CV_Assert(inputs[i][0] == batch);
}
outShape.push_back(totalchannels);
int out_h = divisor ? static_cast<int>(ceil(maxheight / divisor) * divisor) : top_height;
int out_w = divisor ? static_cast<int>(ceil(maxwidth / divisor) * divisor) : top_width;
// Layer can specify custom top size which is larger than default
if (out_h <= maxheight || out_w <= maxwidth)
{
out_h = maxheight;
out_w = maxwidth;
}
outShape.push_back(out_h);
outShape.push_back(out_w);
}
outputs.assign(1, outShape);
return false;
}
virtual void finalize(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr) CV_OVERRIDE
{
LayerParams resizeParams;
resizeParams.set("interpolation", "bilinear");
resizeParams.set("align_corners", true);
resize = ResizeLayer::create(resizeParams);
}
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
{
CV_TRACE_FUNCTION();
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
std::vector<Mat> inputs, outputs;
inputs_arr.getMatVector(inputs);
outputs_arr.getMatVector(outputs);
const int out_h = outputs[0].size[2];
const int out_w = outputs[0].size[3];
float* out_data = outputs[0].ptr<float>();
std::vector<int> sizes(&outputs[0].size[0], &outputs[0].size[0] + outputs[0].size.dims());
for (int i = 0; i < inputs.size() - have_reference; i++)
{
sizes[1] = inputs[i].size[1];
Mat outSlice(sizes, CV_32F, out_data);
if (out_h == inputs[i].size[2] && out_w == inputs[i].size[3])
{
inputs[i].copyTo(outSlice);
}
else
{
std::vector<Mat> inp_slices, out_slices;
inp_slices.push_back(inputs[i]);
out_slices.push_back(outSlice);
resize->finalize(inp_slices, out_slices);
resize->forward(inp_slices, out_slices, internals_arr);
}
out_data += outSlice.total(1);
}
}
private:
int top_height;
int top_width;
int divisor;
bool have_reference;
Ptr<ResizeLayer> resize;
};
Ptr<AccumLayer> AccumLayer::create(const LayerParams& params)
{
return Ptr<AccumLayer>(new AccumLayerImpl(params));
}
}} // namespace cv::dnn

@ -1389,6 +1389,13 @@ public:
CV_TRACE_FUNCTION();
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
#if CV_TRY_SSE
uint32_t ftzMode = _MM_GET_FLUSH_ZERO_MODE();
uint32_t dazMode = _MM_GET_DENORMALS_ZERO_MODE();
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
#endif
CV_OCL_RUN(IS_DNN_OPENCL_TARGET(preferableTarget),
forward_ocl(inputs_arr, outputs_arr, internals_arr))
@ -1471,6 +1478,10 @@ public:
ParallelConv::run(inputs[0], outputs[0], weightsMat, biasvec, reluslope,
kernel_size, strides, pads_begin, pads_end, dilations, activ.get(), ngroups, nstripes);
}
#if CV_TRY_SSE
_MM_SET_FLUSH_ZERO_MODE(ftzMode);
_MM_SET_DENORMALS_ZERO_MODE(dazMode);
#endif
}
#ifdef HAVE_CUDA

@ -0,0 +1,207 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2020, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "../precomp.hpp"
#include "layers_common.hpp"
namespace cv { namespace dnn {
class CorrelationLayerImpl CV_FINAL : public CorrelationLayer
{
public:
CorrelationLayerImpl(const LayerParams& params)
{
setParamsFrom(params);
pad = params.get<int>("pad", 0);
CV_Assert_N(params.has("kernel_size"), params.has("max_displacement"));
max_displacement = params.get<int>("max_displacement");
kernel = params.get<int>("kernel_size");
if (kernel % 2 == 0)
CV_Error(Error::StsNotImplemented, "Odd kernel size required.");
stride_1 = params.get<int>("stride_1", 1);
stride_2 = params.get<int>("stride_2", 1);
}
virtual bool getMemoryShapes(const std::vector<MatShape> &inputs,
const int requiredOutputs,
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const CV_OVERRIDE
{
CV_Assert_N(inputs.size() == 2, inputs[0].size() == 4, inputs[1].size() == 4);
int padded_height = inputs[0][2] + 2 * pad;
int padded_width = inputs[0][3] + 2 * pad;
int kernel_radius = (kernel - 1) / 2;
int border_size = max_displacement + kernel_radius;
int neighborhood_grid_radius = max_displacement / stride_2;
int neighborhood_grid_width = neighborhood_grid_radius * 2 + 1;
std::vector<int> outShape;
int num = inputs[0][0];
outShape.push_back(num);
int out_c = neighborhood_grid_width * neighborhood_grid_width;
outShape.push_back(out_c);
int out_h = ceil(static_cast<float>(padded_height - border_size * 2) / stride_1);
int out_w = ceil(static_cast<float>(padded_width - border_size * 2) / stride_1);
CV_Assert_N(out_h >= 1, out_w >= 1);
outShape.push_back(out_h);
outShape.push_back(out_w);
outputs.assign(1, outShape);
return false;
}
virtual void finalize(InputArrayOfArrays inputs_arr, OutputArrayOfArrays) CV_OVERRIDE
{
std::vector<Mat> inputs;
inputs_arr.getMatVector(inputs);
int padded_height = inputs[0].size[2] + 2 * pad;
int padded_width = inputs[0].size[3] + 2 * pad;
int size[] = {inputs[0].size[0], padded_height, padded_width, inputs[0].size[1]};
rbot0 = Mat(4, &size[0], CV_32F, float(0));
rbot1 = Mat(4, &size[0], CV_32F, float(0));
}
void blobRearrangeKernel2(const Mat& input, Mat& output)
{
const int num = input.size[0];
const int channels = input.size[1];
const int height = input.size[2];
const int width = input.size[3];
const int area = height * width;
const int pad_area = (width + 2 * pad) * (height + 2 * pad);
const float* in = input.ptr<float>();
float* out = output.ptr<float>();
for (int n = 0; n < num; n++)
{
for (int ch = 0; ch < channels; ch++)
{
for (int xy = 0; xy < area; xy++)
{
float value = in[(n * channels + ch) * area + xy];
int xpad = (xy % width + pad);
int ypad = (xy / width + pad);
int xypad = ypad * (width + 2 * pad) + xpad;
out[(n * pad_area + xypad) * channels + ch] = value;
}
}
}
}
void correlationKernelSubtraction(const Mat& input0, const Mat& input1, Mat& output, int item)
{
const int inp_h = input0.size[1];
const int inp_w = input0.size[2];
const int inp_c = input0.size[3];
const int out_c = output.size[1];
const int out_h = output.size[2];
const int out_w = output.size[3];
int topcount = output.total(1);
int neighborhood_grid_radius = max_displacement / stride_2;
int neighborhood_grid_width = neighborhood_grid_radius * 2 + 1;
const float* inp0_data = input0.ptr<float>();
const float* inp1_data = input1.ptr<float>();
float* out_data = output.ptr<float>();
int sumelems = kernel * kernel * inp_c;
std::vector<float> patch_data(sumelems, 0);
for (int y = 0; y < out_h; y++)
{
for (int x = 0; x < out_w; x++)
{
int x1 = x * stride_1 + max_displacement;
int y1 = y * stride_1 + max_displacement;
for (int j = 0; j < kernel; j++)
{
for (int i = 0; i < kernel; i++)
{
int ji_off = ((j * kernel) + i) * inp_c;
for (int ch = 0; ch < inp_c; ch++)
{
int idx1 = ((item * inp_h + y1 + j) * inp_w + x1 + i) * inp_c + ch;
int idxPatchData = ji_off + ch;
patch_data[idxPatchData] = inp0_data[idx1];
}
}
}
for (int out_ch = 0; out_ch < out_c; out_ch++)
{
float sum = 0;
int s2o = (out_ch % neighborhood_grid_width - neighborhood_grid_radius) * stride_2;
int s2p = (out_ch / neighborhood_grid_width - neighborhood_grid_radius) * stride_2;
int x2 = x1 + s2o;
int y2 = y1 + s2p;
for (int j = 0; j < kernel; j++)
{
for (int i = 0; i < kernel; i++)
{
int ji_off = ((j * kernel) + i) * inp_c;
for (int ch = 0; ch < inp_c; ch++)
{
int idxPatchData = ji_off + ch;
int idx2 = ((item * inp_h + y2 + j) * inp_w + x2 + i) * inp_c + ch;
sum += patch_data[idxPatchData] * inp1_data[idx2];
}
}
}
int index = ((out_ch * out_h + y) * out_w) + x;
out_data[index + item * topcount] = static_cast<float>(sum) / sumelems;
}
}
}
}
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
{
CV_TRACE_FUNCTION();
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
std::vector<Mat> inputs, outputs, internals;
inputs_arr.getMatVector(inputs);
outputs_arr.getMatVector(outputs);
internals_arr.getMatVector(internals);
blobRearrangeKernel2(inputs[0], rbot0);
blobRearrangeKernel2(inputs[1], rbot1);
for (int i = 0; i < inputs[0].size[0]; i++)
{
correlationKernelSubtraction(rbot0, rbot1, outputs[0], i);
}
}
private:
int pad;
int kernel;
int max_displacement;
int stride_1;
int stride_2;
Mat rbot0;
Mat rbot1;
};
Ptr<CorrelationLayer> CorrelationLayer::create(const LayerParams& params)
{
return Ptr<CorrelationLayer>(new CorrelationLayerImpl(params));
}
}} // namespace cv::dnn

@ -0,0 +1,117 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Copyright (C) 2020, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "../precomp.hpp"
#include "layers_common.hpp"
namespace cv { namespace dnn {
class FlowWarpLayerImpl CV_FINAL : public FlowWarpLayer
{
public:
FlowWarpLayerImpl(const LayerParams& params)
{
setParamsFrom(params);
String fill_string = toLowerCase(params.get<String>("FillParameter", "ZERO"));
if (fill_string != "zero")
CV_Error(Error::StsNotImplemented, "Only zero filling supported.");
fill_value = 0;
}
virtual bool getMemoryShapes(const std::vector<MatShape> &inputs,
const int requiredOutputs,
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const CV_OVERRIDE
{
CV_Assert(inputs.size() == 2);
CV_Assert_N(inputs[0][0] == inputs[1][0], inputs[1][1] == 2,
inputs[0][2] == inputs[1][2], inputs[0][3] == inputs[1][3]);
outputs.assign(1, inputs[0]);
return false;
}
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
{
CV_TRACE_FUNCTION();
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
std::vector<Mat> inputs, outputs;
inputs_arr.getMatVector(inputs);
outputs_arr.getMatVector(outputs);
const int out_n = outputs[0].size[0];
const int out_c = outputs[0].size[1];
const int out_h = outputs[0].size[2];
const int out_w = outputs[0].size[3];
const int area = out_w * out_h;
const int total = area * out_c;
const float* image_data = inputs[0].ptr<float>();
const float* flow_data = inputs[1].ptr<float>();
float* out_data = outputs[0].ptr<float>();
for (int n = 0; n < out_n; n++)
{
int off = total * n;
for (int x = 0; x < out_w; x++)
{
for (int y = 0; y < out_h; y++)
{
int idx = 2 * area * n + y * out_w + x;
float fx = flow_data[idx];
float fy = flow_data[idx + area];
float x2 = x + fx;
float y2 = y + fy;
if (x2 >= 0 && y2 >= 0 && x2 < out_w && y2 < out_h)
{
int ix2_L = x2;
float alpha = x2 - ix2_L;
int iy2_T = y2;
float beta = y2 - iy2_T;
int ix2_R = std::min(ix2_L + 1, out_w - 1);
int iy2_B = std::min(iy2_T + 1, out_h - 1);
for (int c = 0; c < out_c; c++)
{
float TL = image_data[off + c * area + iy2_T * out_w + ix2_L];
float TR = image_data[off + c * area + iy2_T * out_w + ix2_R];
float BL = image_data[off + c * area + iy2_B * out_w + ix2_L];
float BR = image_data[off + c * area + iy2_B * out_w + ix2_R];
out_data[off + c * area + y * out_w + x] = (1 - alpha) * (1 - beta) * TL +
(1 - alpha) * beta * BL +
alpha * (1 - beta) * TR +
alpha * beta * BR;
}
}
else
{
for (int c = 0; c < out_c; c++)
out_data[off + c * area + y * out_w + x] = fill_value;
}
}
}
}
}
private:
float fill_value;
};
Ptr<FlowWarpLayer> FlowWarpLayer::create(const LayerParams& params)
{
return Ptr<FlowWarpLayer>(new FlowWarpLayerImpl(params));
}
}} // namespace cv::dnn

@ -51,10 +51,15 @@ public:
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const CV_OVERRIDE
{
CV_Assert_N(inputs.size() == 1, inputs[0].size() == 4);
CV_Assert_N(inputs.size() == 1 || inputs.size() == 2, inputs[0].size() == 4);
outputs.resize(1, inputs[0]);
outputs[0][2] = zoomFactorHeight > 0 ? (outputs[0][2] * zoomFactorHeight) : outHeight;
outputs[0][3] = zoomFactorWidth > 0 ? (outputs[0][3] * zoomFactorWidth) : outWidth;
if (inputs.size() == 1) {
outputs[0][2] = zoomFactorHeight > 0 ? (outputs[0][2] * zoomFactorHeight) : outHeight;
outputs[0][3] = zoomFactorWidth > 0 ? (outputs[0][3] * zoomFactorWidth) : outWidth;
} else {
outputs[0][2] = inputs[1][2];
outputs[0][3] = inputs[1][3];
}
// We can work in-place (do nothing) if input shape == output shape.
return (outputs[0][2] == inputs[0][2]) && (outputs[0][3] == inputs[0][3]);
}

@ -372,5 +372,118 @@ Ptr<Layer> ShiftLayer::create(const LayerParams& params)
return Ptr<ScaleLayer>(new ScaleLayerImpl(scaleParams));
}
class DataAugmentationLayerImpl CV_FINAL : public DataAugmentationLayer
{
public:
DataAugmentationLayerImpl(const LayerParams& params)
{
setParamsFrom(params);
recompute_mean = params.get<int>("recompute_mean", 1);
CV_CheckGT(recompute_mean, 0, "");
mean_per_pixel = params.get<bool>("mean_per_pixel", false);
}
bool getMemoryShapes(const std::vector<MatShape> &inputs,
const int requiredOutputs,
std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const CV_OVERRIDE
{
CV_Assert_N(inputs.size() == 1, blobs.size() == 3);
CV_Assert_N(blobs[0].total() == 1, blobs[1].total() == total(inputs[0], 1),
blobs[2].total() == inputs[0][1]);
outputs.assign(1, inputs[0]);
return true;
}
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
{
CV_TRACE_FUNCTION();
CV_TRACE_ARG_VALUE(name, "name", name.c_str());
std::vector<Mat> inputs, outputs;
inputs_arr.getMatVector(inputs);
outputs_arr.getMatVector(outputs);
CV_Assert_N(outputs.size() == 1, blobs.size() == 3, inputs.size() == 1);
int num_iter = 0;
float* inpData = inputs[0].ptr<float>();
float* outData = outputs[0].ptr<float>();
Mat data_mean_cpu = blobs[1].clone();
Mat data_mean_per_channel_cpu = blobs[2].clone();
const int numWeights = data_mean_cpu.total();
CV_Assert(numWeights != 0);
++num_iter;
if (num_iter <= recompute_mean)
{
data_mean_cpu *= (num_iter - 1);
const int batch = inputs[0].size[0];
float alpha = 1.0 / batch;
for (int i = 0; i < batch; ++i)
{
Mat inpSlice(1, numWeights, CV_32F, inpData);
inpSlice = alpha * inpSlice;
add(data_mean_cpu.reshape(1, 1), inpSlice, data_mean_cpu.reshape(1, 1));
inpData += numWeights;
}
data_mean_cpu *= (1.0 / num_iter);
int newsize[] = {blobs[1].size[1], (int)blobs[1].total(2)};
reduce(data_mean_cpu.reshape(1, 2, &newsize[0]), data_mean_per_channel_cpu, 1, REDUCE_SUM, CV_32F);
int area = blobs[1].total(2);
data_mean_per_channel_cpu *= (1.0 / area);
}
MatShape inpShape = shape(inputs[0]);
inpData = inputs[0].ptr<float>();
if (mean_per_pixel)
{
int numSlices = inputs[0].size[0];
for (int i = 0; i < numSlices; ++i)
{
Mat inpSlice(1, numWeights, CV_32F, inpData);
Mat outSlice(1, numWeights, CV_32F, outData);
add(inpSlice, (-1) * data_mean_cpu, outSlice);
inpData += numWeights;
outData += numWeights;
}
}
else
{
int numSlices = inpShape[1];
int count = numWeights / numSlices;
for (int i = 0; i < numSlices; ++i)
{
Mat inpSlice(1, count, CV_32F, inpData);
Mat outSlice(1, count, CV_32F, outData);
float coeff = data_mean_per_channel_cpu.reshape(1, 1).at<float>(0, i);
outSlice = inpSlice - coeff;
inpData += count;
outData += count;
}
}
}
private:
int recompute_mean;
bool mean_per_pixel;
};
Ptr<DataAugmentationLayer> DataAugmentationLayer::create(const LayerParams& params)
{
return Ptr<DataAugmentationLayer>(new DataAugmentationLayerImpl(params));
}
} // namespace dnn
} // namespace cv

@ -97,29 +97,68 @@ class Test_Caffe_layers : public DNNTestLayer
{
public:
void testLayerUsingCaffeModels(const String& basename, bool useCaffeModel = false,
bool useCommonInputBlob = true, double l1 = 0.0,
double lInf = 0.0)
bool useCommonInputBlob = true, double l1 = 0.0, double lInf = 0.0,
int numInps = 1, int numOuts = 1)
{
CV_Assert_N(numInps >= 1, numInps <= 10, numOuts >= 1, numOuts <= 10);
String prototxt = _tf(basename + ".prototxt");
String caffemodel = _tf(basename + ".caffemodel");
String inpfile = (useCommonInputBlob) ? _tf("blob.npy") : _tf(basename + ".input.npy");
String outfile = _tf(basename + ".npy");
std::vector<Mat> inps, refs, outs;
Mat inp = blobFromNPY(inpfile);
Mat ref = blobFromNPY(outfile);
checkBackend(&inp, &ref);
if (numInps > 1)
{
for (int i = 0; i < numInps; i++)
{
String inpfile = _tf(basename + cv::format(".input_%d.npy", i));
inps.push_back(blobFromNPY(inpfile));
}
}
else
{
String inpfile = (useCommonInputBlob) ? _tf("blob.npy") : _tf(basename + ".input.npy");
inps.push_back(blobFromNPY(inpfile));
}
if (numOuts > 1)
{
for (int i = 0; i < numOuts; i++)
{
String outfile = _tf(basename + cv::format("_%d.npy", i));
refs.push_back(blobFromNPY(outfile));
}
}
else
{
String outfile = _tf(basename + ".npy");
refs.push_back(blobFromNPY(outfile));
}
Net net = readNetFromCaffe(prototxt, (useCaffeModel) ? caffemodel : String());
ASSERT_FALSE(net.empty());
checkBackend(&inps[0], &refs[0]);
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
net.setInput(inp, "input");
Mat out = net.forward("output");
String inp_name = "input";
if (numInps > 1)
{
for (int i = 0; i < numInps; i++)
{
net.setInput(inps[i], inp_name + cv::format("_%d", i));
}
}
else
{
net.setInput(inps.back(), inp_name);
}
normAssert(ref, out, "", l1 ? l1 : default_l1, lInf ? lInf : default_lInf);
net.forward(outs);
for (int i = 0; i < refs.size(); i++)
{
normAssert(refs[i], outs[i], "", l1 ? l1 : default_l1, lInf ? lInf : default_lInf);
}
}
};
@ -579,6 +618,58 @@ TEST_F(Layer_RNN_Test, get_set_test)
EXPECT_EQ(shape(outputs[1]), shape(nT, nS, nH));
}
TEST_P(Test_Caffe_layers, Accum)
{
if (backend == DNN_BACKEND_OPENCV && target != DNN_TARGET_CPU)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("accum", false, false, 0.0, 0.0, 2);
testLayerUsingCaffeModels("accum_ref", false, false, 0.0, 0.0, 2);
}
TEST_P(Test_Caffe_layers, FlowWarp)
{
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("flow_warp", false, false, 0.0, 0.0, 2);
}
TEST_P(Test_Caffe_layers, ChannelNorm)
{
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("channel_norm", false, false);
}
TEST_P(Test_Caffe_layers, DataAugmentation)
{
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("data_augmentation", true, false);
}
TEST_P(Test_Caffe_layers, Resample)
{
if (backend != DNN_BACKEND_OPENCV)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
testLayerUsingCaffeModels("nearest_2inps", false, false, 0.0, 0.0, 2);
testLayerUsingCaffeModels("nearest", false, false);
}
TEST_P(Test_Caffe_layers, Correlation)
{
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER,
CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("correlation", false, false, 0.0, 0.0, 2);
}
TEST_P(Test_Caffe_layers, Convolution2Inputs)
{
testLayerUsingCaffeModels("conv_2_inps", true, false, 0.0, 0.0, 2);
}
TEST_P(Test_Caffe_layers, ROIPooling_Accuracy)
{
Net net = readNetFromCaffe(_tf("net_roi_pooling.prototxt"));

@ -392,7 +392,7 @@ int CvCaptureCAM::startCaptureDevice(int cameraNum) {
[mCaptureDecompressedVideoOutput setVideoSettings:pixelBufferOptions];
mCaptureDecompressedVideoOutput.alwaysDiscardsLateVideoFrames = YES;
#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) && !TARGET_OS_MACCATALYST
#if (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) && (!defined(TARGET_OS_MACCATALYST) || !TARGET_OS_MACCATALYST)
mCaptureDecompressedVideoOutput.minFrameDuration = CMTimeMake(1, 30);
#endif

@ -299,7 +299,7 @@
}
else
{
#if !TARGET_OS_MACCATALYST
#if (!defined(TARGET_OS_MACCATALYST) || !TARGET_OS_MACCATALYST)
// Deprecated in 6.0; here for backward compatibility
if ([self.captureVideoPreviewLayer isOrientationSupported])
{

@ -0,0 +1,85 @@
#!/usr/bin/env python
'''
This sample using FlowNet v2 model to calculate optical flow.
Original paper: https://arxiv.org/abs/1612.01925.
Original repo: https://github.com/lmb-freiburg/flownet2.
Download the converted .caffemodel model from https://drive.google.com/open?id=16qvE9VNmU39NttpZwZs81Ga8VYQJDaWZ
and .prototxt from https://drive.google.com/open?id=19bo6SWU2p8ZKvjXqMKiCPdK8mghwDy9b.
Otherwise download original model from https://lmb.informatik.uni-freiburg.de/resources/binaries/flownet2/flownet2-models.tar.gz,
convert .h5 model to .caffemodel and modify original .prototxt using .prototxt from link above.
'''
import argparse
import os.path
import numpy as np
import cv2 as cv
class OpticalFlow(object):
def __init__(self, proto, model, height, width):
self.net = cv.dnn.readNet(proto, model)
self.net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)
self.height = height
self.width = width
def compute_flow(self, first_img, second_img):
inp0 = cv.dnn.blobFromImage(first_img, size=(self.width, self.height))
inp1 = cv.dnn.blobFromImage(second_img, size=(self.width, self.height))
self.net.setInput(inp0, "img0")
self.net.setInput(inp1, "img1")
flow = self.net.forward()
output = self.motion_to_color(flow)
return output
def motion_to_color(self, flow):
arr = np.arange(0, 255, dtype=np.uint8)
colormap = cv.applyColorMap(arr, cv.COLORMAP_HSV)
colormap = colormap.squeeze(1)
flow = flow.squeeze(0)
fx, fy = flow[0, ...], flow[1, ...]
rad = np.sqrt(fx**2 + fy**2)
maxrad = rad.max() if rad.max() != 0 else 1
ncols = arr.size
rad = rad[..., np.newaxis] / maxrad
a = np.arctan2(-fy / maxrad, -fx / maxrad) / np.pi
fk = (a + 1) / 2.0 * (ncols - 1)
k0 = fk.astype(np.int)
k1 = (k0 + 1) % ncols
f = fk[..., np.newaxis] - k0[..., np.newaxis]
col0 = colormap[k0] / 255.0
col1 = colormap[k1] / 255.0
col = (1 - f) * col0 + f * col1
col = np.where(rad <= 1, 1 - rad * (1 - col), col * 0.75)
output = (255.0 * col).astype(np.uint8)
return output
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Use this script to calculate optical flow using FlowNetv2',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-input', '-i', required=True, help='Path to input video file. Skip this argument to capture frames from a camera.')
parser.add_argument('--height', default=320, help='Input height')
parser.add_argument('--width', default=448, help='Input width')
parser.add_argument('--proto', '-p', default='FlowNet2_deploy.prototxt', help='Path to prototxt.')
parser.add_argument('--model', '-m', default='FlowNet2_weights.caffemodel', help='Path to caffemodel.')
args, _ = parser.parse_known_args()
if not os.path.isfile(args.model) or not os.path.isfile(args.proto):
raise OSError("Prototxt or caffemodel not exist")
winName = 'Calculation optical flow in OpenCV'
cv.namedWindow(winName, cv.WINDOW_NORMAL)
cap = cv.VideoCapture(args.input if args.input else 0)
hasFrame, first_frame = cap.read()
opt_flow = OpticalFlow(args.proto, args.model, args.height, args.width)
while cv.waitKey(1) < 0:
hasFrame, second_frame = cap.read()
if not hasFrame:
break
flow = opt_flow.compute_flow(first_frame, second_frame)
first_frame = second_frame
cv.imshow(winName, flow)
Loading…
Cancel
Save