Merge pull request #10331 from arrybn:python_dnn_net
authorVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Wed, 20 Dec 2017 14:30:26 +0000 (14:30 +0000)
committerVadim Pisarevsky <vadim.pisarevsky@gmail.com>
Wed, 20 Dec 2017 14:30:27 +0000 (14:30 +0000)
81 files changed:
3rdparty/libtiff/CMakeLists.txt
3rdparty/libtiff/snprintf.c [new file with mode: 0644]
3rdparty/libwebp/src/enc/histogram_enc.c
doc/js_tutorials/js_assets/js_houghlines_HoughLines.html
doc/js_tutorials/js_assets/js_houghlines_HoughLinesP.html
doc/tutorials/features2d/homography/homography.markdown
doc/tutorials/features2d/homography/images/homography_stitch_Suzanne.jpg [new file with mode: 0644]
doc/tutorials/features2d/homography/images/homography_stitch_compare.jpg [new file with mode: 0644]
doc/tutorials/ml/introduction_to_pca/introduction_to_pca.markdown
doc/tutorials/ml/non_linear_svms/non_linear_svms.markdown
doc/tutorials/videoio/intelperc.markdown
doc/tutorials/videoio/kinect_openni.markdown
modules/calib3d/include/opencv2/calib3d.hpp
modules/core/src/ocl.cpp
modules/dnn/CMakeLists.txt
modules/dnn/include/opencv2/dnn/all_layers.hpp
modules/dnn/include/opencv2/dnn/dnn.hpp
modules/dnn/misc/caffe/opencv-caffe.pb.cc
modules/dnn/misc/caffe/opencv-caffe.pb.h
modules/dnn/perf/perf_caffe.cpp
modules/dnn/perf/perf_net.cpp
modules/dnn/src/caffe/caffe_importer.cpp
modules/dnn/src/caffe/opencv-caffe.proto
modules/dnn/src/darknet/darknet_importer.cpp
modules/dnn/src/dnn.cpp
modules/dnn/src/init.cpp
modules/dnn/src/layers/pooling_layer.cpp
modules/dnn/src/layers/prior_box_layer.cpp
modules/dnn/src/ocl4dnn/include/ocl4dnn.hpp
modules/dnn/src/ocl4dnn/src/ocl4dnn_conv_spatial.cpp
modules/dnn/src/opencl/conv_layer_spatial.cl
modules/dnn/src/opencl/prior_box.cl [new file with mode: 0644]
modules/dnn/src/tensorflow/tf_importer.cpp
modules/dnn/src/torch/THDiskFile.cpp
modules/dnn/src/torch/THFile.cpp
modules/dnn/src/torch/THFile.h
modules/dnn/src/torch/THGeneral.cpp
modules/dnn/src/torch/torch_importer.cpp
modules/dnn/test/test_tf_importer.cpp
modules/dnn/test/test_torch_importer.cpp
modules/imgproc/src/canny.cpp
modules/imgproc/src/hal_replacement.hpp
modules/ml/src/ann_mlp.cpp
modules/ml/src/inner_functions.cpp
samples/cpp/dbt_face_detection.cpp
samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp
samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp
samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp
samples/cpp/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.cpp
samples/cpp/tutorial_code/ImgTrans/CannyDetector_Demo.cpp
samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp
samples/cpp/tutorial_code/ImgTrans/houghcircles.cpp
samples/cpp/tutorial_code/ImgTrans/houghlines.cpp
samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp
samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp
samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp
samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp
samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp
samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp
samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp
samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp
samples/cpp/tutorial_code/TrackingMotion/goodFeaturesToTrack_Demo.cpp
samples/cpp/tutorial_code/features2D/AKAZE_match.cpp
samples/cpp/tutorial_code/features2D/Homography/decompose_homography.cpp [moved from samples/cpp/tutorial_code/features2D/Homography/tutorial_homography_ex4_decompose_homography.cpp with 89% similarity, mode: 0644]
samples/cpp/tutorial_code/features2D/Homography/homography_from_camera_displacement.cpp [moved from samples/cpp/tutorial_code/features2D/Homography/tutorial_homography_ex3_homography_from_camera_displacement.cpp with 89% similarity, mode: 0644]
samples/cpp/tutorial_code/features2D/Homography/left_intrinsics.yml [deleted file]
samples/cpp/tutorial_code/features2D/Homography/panorama_stitching_rotating_camera.cpp [new file with mode: 0755]
samples/cpp/tutorial_code/features2D/Homography/perspective_correction.cpp [moved from samples/cpp/tutorial_code/features2D/Homography/tutorial_homography_ex2_perspective_correction.cpp with 84% similarity, mode: 0644]
samples/cpp/tutorial_code/features2D/Homography/pose_from_homography.cpp [moved from samples/cpp/tutorial_code/features2D/Homography/tutorial_homography_ex1_pose_from_homography.cpp with 81% similarity, mode: 0644]
samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp
samples/cpp/tutorial_code/objectDetection/objectDetection.cpp
samples/cpp/tutorial_code/photo/decolorization/decolor.cpp
samples/cpp/tutorial_code/photo/non_photorealistic_rendering/npr_demo.cpp
samples/cpp/tutorial_code/viz/histo3D.cpp
samples/cpp/tutorial_code/viz/widget_pose.cpp
samples/cpp/tutorial_code/xfeatures2D/LATCH_match.cpp
samples/data/Blender_Suzanne1.jpg [new file with mode: 0644]
samples/data/Blender_Suzanne2.jpg [new file with mode: 0644]
samples/data/left_intrinsics.yml [new file with mode: 0644]
samples/dnn/faster_rcnn.cpp
samples/python/camera_calibration_show_extrinsics.py [new file with mode: 0755]

index 4665a0a..ae9914b 100644 (file)
@@ -35,31 +35,27 @@ if(NOT MSVC)
   check_include_file(unistd.h    HAVE_UNISTD_H)
 endif()
 
-if(MSVC)
-  set(INLINE_KEYWORD "inline")
-else()
-  # Inspired from /usr/share/autoconf/autoconf/c.m4
-  foreach(inline_keyword "inline" "__inline__" "__inline")
-    if(NOT DEFINED C_INLINE)
-      set(CMAKE_REQUIRED_DEFINITIONS_SAVE ${CMAKE_REQUIRED_DEFINITIONS})
-      set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
-          "-Dinline=${inline_keyword}")
-      check_c_source_compiles("
-          typedef int foo_t;
-          static inline foo_t static_foo() {return 0;}
-          foo_t foo(){return 0;}
-          int main(int argc, char *argv[]) {return 0;}"
-        C_HAS_${inline_keyword})
-      set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS_SAVE})
-      if(C_HAS_${inline_keyword})
-        set(C_INLINE TRUE)
-        set(INLINE_KEYWORD "${inline_keyword}")
-      endif()
-   endif()
-  endforeach()
+# Inspired from /usr/share/autoconf/autoconf/c.m4
+foreach(inline_keyword "inline" "__inline__" "__inline")
   if(NOT DEFINED C_INLINE)
-    set(INLINE_KEYWORD)
-  endif()
+    set(CMAKE_REQUIRED_DEFINITIONS_SAVE ${CMAKE_REQUIRED_DEFINITIONS})
+    set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+        "-Dinline=${inline_keyword}")
+    check_c_source_compiles("
+        typedef int foo_t;
+        static inline foo_t static_foo() {return 0;}
+        foo_t foo(){return 0;}
+        int main(int argc, char *argv[]) {return 0;}"
+      C_HAS_${inline_keyword})
+    set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS_SAVE})
+    if(C_HAS_${inline_keyword})
+      set(C_INLINE TRUE)
+      set(INLINE_KEYWORD "${inline_keyword}")
+    endif()
+ endif()
+endforeach()
+if(NOT DEFINED C_INLINE)
+  set(INLINE_KEYWORD)
 endif()
 
 
@@ -414,6 +410,7 @@ set(lib_srcs
     tif_write.c
     tif_zip.c
     tif_stream.cxx
+       snprintf.c
     t4.h
     tif_dir.h
     tif_fax3.h
diff --git a/3rdparty/libtiff/snprintf.c b/3rdparty/libtiff/snprintf.c
new file mode 100644 (file)
index 0000000..c46a6a8
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Workaround for lack of snprintf(3) in Visual Studio.  See
+ * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010/8712996#8712996
+ * It's a trivial wrapper around the builtin _vsnprintf_s and
+ * _vscprintf functions.
+ */
+
+#ifdef _MSC_VER
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int _TIFF_vsnprintf_f(char* str, size_t size, const char* format, va_list ap)
+{
+  int count = -1;
+
+  if (size != 0)
+    count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
+  if (count == -1)
+    count = _vscprintf(format, ap);
+
+  return count;
+}
+
+int _TIFF_snprintf_f(char* str, size_t size, const char* format, ...)
+{
+  int count;
+  va_list ap;
+
+  va_start(ap, format);
+  count = vsnprintf(str, size, format, ap);
+  va_end(ap);
+
+  return count;
+}
+
+#endif // _MSC_VER
+
index 056a972..4d13e19 100644 (file)
@@ -605,7 +605,7 @@ static void HistogramCombineEntropyBin(VP8LHistogramSet* const image_histo,
 }
 
 // Implement a Lehmer random number generator with a multiplicative constant of
-// 48271 and a modulo constant of 2^31 âˆ’ 1.
+// 48271 and a modulo constant of 2^31 - 1.
 static uint32_t MyRand(uint32_t* const seed) {
   *seed = (uint32_t)(((uint64_t)(*seed) * 48271u) % 2147483647u);
   assert(*seed > 0);
index 2edbe39..76aa6dc 100644 (file)
@@ -41,7 +41,7 @@
 <script src="utils.js" type="text/javascript"></script>
 <script id="codeSnippet" type="text/code-snippet">
 let src = cv.imread('canvasInput');
-let dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8U);
+let dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8UC3);
 let lines = new cv.Mat();
 cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
 cv.Canny(src, src, 50, 200, 3);
index e69bf54..fdda01d 100644 (file)
@@ -41,7 +41,7 @@
 <script src="utils.js" type="text/javascript"></script>
 <script id="codeSnippet" type="text/code-snippet">
 let src = cv.imread('canvasInput');
-let dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8U);
+let dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8UC3);
 let lines = new cv.Mat();
 let color = new cv.Scalar(255, 0, 0);
 cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
index 31aa402..020017f 100644 (file)
@@ -1,8 +1,10 @@
 Basic concepts of the homography explained with code {#tutorial_homography}
-=============================
+====================================================
 
-Introduction
-----
+@tableofcontents
+
+Introduction {#tutorial_homography_Introduction}
+============
 
 This tutorial will demonstrate the basic concepts of the homography with some codes.
 For detailed explanations about the theory, please refer to a computer vision course or a computer vision book, e.g.:
@@ -13,10 +15,10 @@ For detailed explanations about the theory, please refer to a computer vision co
 The tutorial code can be found [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/features2D/Homography).
 The images used in this tutorial can be found [here](https://github.com/opencv/opencv/tree/master/samples/data) (`left*.jpg`).
 
-Basic theory
-----
+Basic theory {#tutorial_homography_Basic_theory}
+------------
 
-### What is the homography matrix?
+### What is the homography matrix? {#tutorial_homography_What_is_the_homography_matrix}
 
 Briefly, the planar homography relates the transformation between two planes (up to a scale factor):
 
@@ -61,7 +63,7 @@ The following examples show different kinds of transformation but all relate a t
 
 ![](images/homography_transformation_example3.jpg)
 
-### How the homography transformation can be useful?
+### How the homography transformation can be useful? {#tutorial_homography_How_the_homography_transformation_can_be_useful}
 
 *   Camera pose estimation from coplanar points for augmented reality with marker for instance (see the previous first example)
 
@@ -75,10 +77,10 @@ The following examples show different kinds of transformation but all relate a t
 
 ![](images/homography_panorama_stitching.jpg)
 
-Demonstration codes
-----
+Demonstration codes {#tutorial_homography_Demonstration_codes}
+-------------------
 
-### Demo 1: Pose estimation from coplanar points
+### Demo 1: Pose estimation from coplanar points {#tutorial_homography_Demo1}
 
 \note Please note that the code to estimate the camera pose from the homography is an example and you should use instead @ref cv::solvePnP if you want to estimate the camera pose for a planar or an arbitrary object.
 
@@ -89,31 +91,31 @@ This can be tested easily using a chessboard object and `findChessboardCorners()
 
 The first thing consists to detect the chessboard corners, the chessboard size (`patternSize`), here `9x6`, is required:
 
-@snippet tutorial_homography_ex1_pose_from_homography.cpp find-chessboard-corners
+@snippet pose_from_homography.cpp find-chessboard-corners
 
 ![](images/homography_pose_chessboard_corners.jpg)
 
 The object points expressed in the object frame can be computed easily knowing the size of a chessboard square:
 
-@snippet tutorial_homography_ex1_pose_from_homography.cpp compute-chessboard-object-points
+@snippet pose_from_homography.cpp compute-chessboard-object-points
 
 The coordinate `Z=0` must be removed for the homography estimation part:
 
-@snippet tutorial_homography_ex1_pose_from_homography.cpp compute-object-points
+@snippet pose_from_homography.cpp compute-object-points
 
 The image points expressed in the normalized camera can be computed from the corner points and by applying a reverse perspective transformation using the camera intrinsics and the distortion coefficients:
 
-@snippet tutorial_homography_ex1_pose_from_homography.cpp load-intrinsics
+@snippet pose_from_homography.cpp load-intrinsics
 
-@snippet tutorial_homography_ex1_pose_from_homography.cpp compute-image-points
+@snippet pose_from_homography.cpp compute-image-points
 
 The homography can then be estimated with:
 
-@snippet tutorial_homography_ex1_pose_from_homography.cpp estimate-homography
+@snippet pose_from_homography.cpp estimate-homography
 
 A quick solution to retrieve the pose from the homography matrix is (see \ref pose_ar "5"):
 
-@snippet tutorial_homography_ex1_pose_from_homography.cpp pose-from-homography
+@snippet pose_from_homography.cpp pose-from-homography
 
 \f[
   \begin{align*}
@@ -151,11 +153,16 @@ A quick solution to retrieve the pose from the homography matrix is (see \ref po
 
 This is a quick solution (see also \ref projective_transformations "2") as this does not ensure that the resulting rotation matrix will be orthogonal and the scale is estimated roughly by normalize the first column to 1.
 
+A solution to have a proper rotation matrix (with the properties of a rotation matrix) consists to apply a polar decomposition
+(see \ref polar_decomposition "6" or \ref polar_decomposition_svd "7" for some information):
+
+@snippet pose_from_homography.cpp polar-decomposition-of-the-rotation-matrix
+
 To check the result, the object frame projected into the image with the estimated camera pose is displayed:
 
 ![](images/homography_pose.jpg)
 
-### Demo 2: Perspective correction
+### Demo 2: Perspective correction {#tutorial_homography_Demo2}
 
 In this example, a source image will be transformed into a desired perspective view by computing the homography that maps the source points into the desired points.
 The following image shows the source image (left) and the chessboard view that we want to transform into the desired chessboard view (right).
@@ -164,15 +171,15 @@ The following image shows the source image (left) and the chessboard view that w
 
 The first step consists to detect the chessboard corners in the source and desired images:
 
-@snippet tutorial_homography_ex2_perspective_correction.cpp find-corners
+@snippet perspective_correction.cpp find-corners
 
 The homography is estimated easily with:
 
-@snippet tutorial_homography_ex2_perspective_correction.cpp estimate-homography
+@snippet perspective_correction.cpp estimate-homography
 
 To warp the source chessboard view into the desired chessboard view, we use @ref cv::warpPerspective
 
-@snippet tutorial_homography_ex2_perspective_correction.cpp warp-chessboard
+@snippet perspective_correction.cpp warp-chessboard
 
 The result image is:
 
@@ -180,13 +187,13 @@ The result image is:
 
 To compute the coordinates of the source corners transformed by the homography:
 
-@snippet tutorial_homography_ex2_perspective_correction.cpp compute-transformed-corners
+@snippet perspective_correction.cpp compute-transformed-corners
 
 To check the correctness of the calculation, the matching lines are displayed:
 
 ![](images/homography_perspective_correction_chessboard_matches.jpg)
 
-### Demo 3: Homography from the camera displacement
+### Demo 3: Homography from the camera displacement {#tutorial_homography_Demo3}
 
 The homography relates the transformation between two planes and it is possible to retrieve the corresponding camera displacement that allows to go from the first to the second plane view (see @cite Malis for more information).
 Before going into the details that allow to compute the homography from the camera displacement, some recalls about camera pose and homogeneous transformation.
@@ -295,13 +302,13 @@ To transform a 3D point expressed in the camera 1 frame to the camera 2 frame:
 
 In this example, we will compute the camera displacement between two camera poses with respect to the chessboard object. The first step consists to compute the camera poses for the two images:
 
-@snippet tutorial_homography_ex3_homography_from_camera_displacement.cpp compute-poses
+@snippet homography_from_camera_displacement.cpp compute-poses
 
 ![](images/homography_camera_displacement_poses.jpg)
 
 The camera displacement can be computed from the camera poses using the formulas above:
 
-@snippet tutorial_homography_ex3_homography_from_camera_displacement.cpp compute-c2Mc1
+@snippet homography_from_camera_displacement.cpp compute-c2Mc1
 
 The homography related to a specific plane computed from the camera displacement is:
 
@@ -320,11 +327,11 @@ the translation vector between the two camera frames.
 
 Here the normal vector `n` is the plane normal expressed in the camera frame 1 and can be computed as the cross product of 2 vectors (using 3 non collinear points that lie on the plane) or in our case directly with:
 
-@snippet tutorial_homography_ex3_homography_from_camera_displacement.cpp compute-plane-normal-at-camera-pose-1
+@snippet homography_from_camera_displacement.cpp compute-plane-normal-at-camera-pose-1
 
 The distance `d` can be computed as the dot product between the plane normal and a point on the plane or by computing the [plane equation](http://mathworld.wolfram.com/Plane.html) and using the D coefficient:
 
-@snippet tutorial_homography_ex3_homography_from_camera_displacement.cpp compute-plane-distance-to-the-camera-frame-1
+@snippet homography_from_camera_displacement.cpp compute-plane-distance-to-the-camera-frame-1
 
 The projective homography matrix \f$ \textbf{G} \f$ can be computed from the Euclidean homography \f$ \textbf{H} \f$ using the intrinsic matrix \f$ \textbf{K} \f$ (see @cite Malis), here assuming the same camera between the two plane views:
 
@@ -332,7 +339,7 @@ The projective homography matrix \f$ \textbf{G} \f$ can be computed from the Euc
   \textbf{G} = \gamma \textbf{K} \textbf{H} \textbf{K}^{-1}
 \f]
 
-@snippet tutorial_homography_ex3_homography_from_camera_displacement.cpp compute-homography
+@snippet homography_from_camera_displacement.cpp compute-homography
 
 In our case, the Z-axis of the chessboard goes inside the object whereas in the homography figure it goes outside. This is just a matter of sign:
 
@@ -340,7 +347,7 @@ In our case, the Z-axis of the chessboard goes inside the object whereas in the
   ^{2}\textrm{H}_{1} = \hspace{0.2em} ^{2}\textrm{R}_{1} + \hspace{0.1em} \frac{^{2}\textrm{t}_{1} \cdot n^T}{d}
 \f]
 
-@snippet tutorial_homography_ex3_homography_from_camera_displacement.cpp compute-homography-from-camera-displacement
+@snippet homography_from_camera_displacement.cpp compute-homography-from-camera-displacement
 
 We will now compare the projective homography computed from the camera displacement with the one estimated with @ref cv::findHomography
 
@@ -363,16 +370,16 @@ The homography matrices are similar. If we compare the image 1 warped using both
 
 Visually, it is hard to distinguish a difference between the result image from the homography computed from the camera displacement and the one estimated with @ref cv::findHomography function.
 
-### Demo 4: Decompose the homography matrix
+### Demo 4: Decompose the homography matrix {#tutorial_homography_Demo4}
 
 OpenCV 3 contains the function @ref cv::decomposeHomographyMat which allows to decompose the homography matrix to a set of rotations, translations and plane normals.
 First we will decompose the homography matrix computed from the camera displacement:
 
-@snippet tutorial_homography_ex4_decompose_homography.cpp compute-homography-from-camera-displacement
+@snippet decompose_homography.cpp compute-homography-from-camera-displacement
 
 The results of @ref cv::decomposeHomographyMat are:
 
-@snippet tutorial_homography_ex4_decompose_homography.cpp decompose-homography-from-camera-displacement
+@snippet decompose_homography.cpp decompose-homography-from-camera-displacement
 
 ```
 Solution 0:
@@ -457,11 +464,66 @@ plane normal at camera 1 pose: [0.1973513139420654, -0.6283451996579068, 0.75248
 
 Again, there is also a solution that matches with the computed camera displacement.
 
-Additional references
-----
+### Demo 5: Basic panorama stitching from a rotating camera {#tutorial_homography_Demo5}
+
+\note This example is made to illustrate the concept of image stitching based on a pure rotational motion of the camera and should not be used to stitch panorama images.
+The [stitching module](@ref stitching) provides a complete pipeline to stitch images.
+
+The homography transformation applies only for planar structure. But in the case of a rotating camera (pure rotation around the camera axis of projection, no translation), an arbitrary world can be considered
+([see previously](@ref tutorial_homography_What_is_the_homography_matrix)).
+
+The homography can then be computed using the rotation transformation and the camera intrinsic parameters as (see for instance \ref homography_course "8"):
+
+\f[
+  s
+  \begin{bmatrix}
+  x^{'} \\
+  y^{'} \\
+  1
+  \end{bmatrix} =
+  \bf{K} \hspace{0.1em} \bf{R} \hspace{0.1em} \bf{K}^{-1}
+  \begin{bmatrix}
+  x \\
+  y \\
+  1
+  \end{bmatrix}
+\f]
+
+To illustrate, we used Blender, a free and open-source 3D computer graphics software, to generate two camera views with only a rotation transformation between each other.
+More information about how to retrieve the camera intrinsic parameters and the `3x4` extrinsic matrix with respect to the world can be found in \ref answer_blender "9" (an additional transformation
+is needed to get the transformation between the camera and the object frames) with Blender.
+
+The figure below shows the two generated views of the Suzanne model, with only a rotation transformation:
+
+![](images/homography_stitch_compare.jpg)
+
+With the known associated camera poses and the intrinsic parameters, the relative rotation between the two views can be computed:
+
+@snippet panorama_stitching_rotating_camera.cpp extract-rotation
+
+@snippet panorama_stitching_rotating_camera.cpp compute-rotation-displacement
+
+Here, the second image will be stitched with respect to the first image. The homography can be calculated using the formula above:
+
+@snippet panorama_stitching_rotating_camera.cpp compute-homography
+
+The stitching is made simply with:
+
+@snippet panorama_stitching_rotating_camera.cpp stitch
+
+The resulting image is:
+
+![](images/homography_stitch_Suzanne.jpg)
+
+Additional references {#tutorial_homography_Additional_references}
+---------------------
 
 *   \anchor lecture_16 1. [Lecture 16: Planar Homographies](http://www.cse.psu.edu/~rtc12/CSE486/lecture16.pdf), Robert Collins
 *   \anchor projective_transformations 2. [2D projective transformations (homographies)](https://ags.cs.uni-kl.de/fileadmin/inf_ags/3dcv-ws11-12/3DCV_WS11-12_lec04.pdf), Christiano Gava, Gabriele Bleser
 *   \anchor szeliski 3. [Computer Vision: Algorithms and Applications](http://szeliski.org/Book/drafts/SzeliskiBook_20100903_draft.pdf), Richard Szeliski
 *   \anchor answer_dsp 4. [Step by Step Camera Pose Estimation for Visual Tracking and Planar Markers](https://dsp.stackexchange.com/a/2737)
 *   \anchor pose_ar 5. [Pose from homography estimation](https://team.inria.fr/lagadic/camera_localization/tutorial-pose-dlt-planar-opencv.html)
+*   \anchor polar_decomposition 6. [Polar Decomposition (in Continuum Mechanics)](http://www.continuummechanics.org/polardecomposition.html)
+*   \anchor polar_decomposition_svd 7. [A Personal Interview with the Singular Value Decomposition](https://web.stanford.edu/~gavish/documents/SVD_ans_you.pdf), Matan Gavish
+*   \anchor homography_course 8. [Homography](http://people.scs.carleton.ca/~c_shu/Courses/comp4900d/notes/homography.pdf), Dr. Gerhard Roth
+*   \anchor answer_blender 9. [3x4 camera matrix from blender camera](https://blender.stackexchange.com/a/38210)
diff --git a/doc/tutorials/features2d/homography/images/homography_stitch_Suzanne.jpg b/doc/tutorials/features2d/homography/images/homography_stitch_Suzanne.jpg
new file mode 100644 (file)
index 0000000..5305a94
Binary files /dev/null and b/doc/tutorials/features2d/homography/images/homography_stitch_Suzanne.jpg differ
diff --git a/doc/tutorials/features2d/homography/images/homography_stitch_compare.jpg b/doc/tutorials/features2d/homography/images/homography_stitch_compare.jpg
new file mode 100644 (file)
index 0000000..257094c
Binary files /dev/null and b/doc/tutorials/features2d/homography/images/homography_stitch_compare.jpg differ
index 82274ef..d1fe50b 100644 (file)
@@ -92,10 +92,10 @@ Source Code
 -----------
 
 This tutorial code's is shown lines below. You can also download it from
-    [here](https://github.com/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp).
+    [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp).
 @include cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp
 
-@note Another example using PCA for dimensionality reduction while maintaining an amount of variance can be found at [opencv_source_code/samples/cpp/pca.cpp](https://github.com/opencv/tree/master/samples/cpp/pca.cpp)
+@note Another example using PCA for dimensionality reduction while maintaining an amount of variance can be found at [opencv_source_code/samples/cpp/pca.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/pca.cpp)
 
 Explanation
 -----------
index 242ef6e..4937943 100644 (file)
@@ -87,7 +87,7 @@ Source Code
 -----------
 
 You may also find the source code in `samples/cpp/tutorial_code/ml/non_linear_svms` folder of the OpenCV source library or
-[download it from here](https://github.com/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp).
+[download it from here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp).
 
 @note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code
 using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/non_linear_svms/non_linear_svms.html#nonlinearsvms)
index 188a69e..a36511a 100644 (file)
@@ -78,5 +78,5 @@ there are two flags that should be used to set/get property of the needed genera
     flag value is assumed by default if neither of the two possible values of the property is set.
 
 For more information please refer to the example of usage
-[intelperc_capture.cpp](https://github.com/opencv/tree/master/samples/cpp/intelperc_capture.cpp)
+[intelperc_capture.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/intelperc_capture.cpp)
 in opencv/samples/cpp folder.
index 82ec13e..aed4498 100644 (file)
@@ -134,5 +134,5 @@ property. The following properties of cameras available through OpenNI interface
     -   CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION = CAP_OPENNI_DEPTH_GENERATOR + CAP_PROP_OPENNI_REGISTRATION
 
 For more information please refer to the example of usage
-[openni_capture.cpp](https://github.com/opencv/tree/master/samples/cpp/openni_capture.cpp) in
+[openni_capture.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/openni_capture.cpp) in
 opencv/samples/cpp folder.
index 8d6fedf..74b63c6 100644 (file)
@@ -306,6 +306,12 @@ optimization procedures like calibrateCamera, stereoCalibrate, or solvePnP .
  */
 CV_EXPORTS_W void Rodrigues( InputArray src, OutputArray dst, OutputArray jacobian = noArray() );
 
+/** @example pose_from_homography.cpp
+  An example program about pose estimation from coplanar points
+
+  Check @ref tutorial_homography "the corresponding tutorial" for more details
+ */
+
 /** @brief Finds a perspective transformation between two planes.
 
 @param srcPoints Coordinates of the points in the original plane, a matrix of the type CV_32FC2
@@ -364,12 +370,6 @@ cannot be estimated, an empty one will be returned.
 @sa
 getAffineTransform, estimateAffine2D, estimateAffinePartial2D, getPerspectiveTransform, warpPerspective,
 perspectiveTransform
-
-
-@note
-   -   A example on calculating a homography for image matching can be found at
-        opencv_source_code/samples/cpp/video_homography.cpp
-
  */
 CV_EXPORTS_W Mat findHomography( InputArray srcPoints, InputArray dstPoints,
                                  int method = 0, double ransacReprojThreshold = 3,
@@ -525,6 +525,12 @@ CV_EXPORTS_W void projectPoints( InputArray objectPoints,
                                  OutputArray jacobian = noArray(),
                                  double aspectRatio = 0 );
 
+/** @example homography_from_camera_displacement.cpp
+  An example program about homography from the camera displacement
+
+  Check @ref tutorial_homography "the corresponding tutorial" for more details
+ */
+
 /** @brief Finds an object pose from 3D-2D point correspondences.
 
 @param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or
@@ -567,7 +573,97 @@ focal length.
 function requires exactly four object and image points.
 
 The function estimates the object pose given a set of object points, their corresponding image
-projections, as well as the camera matrix and the distortion coefficients.
+projections, as well as the camera matrix and the distortion coefficients, see the figure below
+(more precisely, the X-axis of the camera frame is pointing to the right, the Y-axis downward
+and the Z-axis forward).
+
+![](pnp.jpg)
+
+Points expressed in the world frame \f$ \bf{X}_w \f$ are projected into the image plane \f$ \left[ u, v \right] \f$
+using the perspective projection model \f$ \Pi \f$ and the camera intrinsic parameters matrix \f$ \bf{A} \f$:
+
+\f[
+  \begin{align*}
+  \begin{bmatrix}
+  u \\
+  v \\
+  1
+  \end{bmatrix} &=
+  \bf{A} \hspace{0.1em} \Pi \hspace{0.2em} ^{c}\bf{M}_w
+  \begin{bmatrix}
+  X_{w} \\
+  Y_{w} \\
+  Z_{w} \\
+  1
+  \end{bmatrix} \\
+  \begin{bmatrix}
+  u \\
+  v \\
+  1
+  \end{bmatrix} &=
+  \begin{bmatrix}
+  f_x & 0 & c_x \\
+  0 & f_y & c_y \\
+  0 & 0 & 1
+  \end{bmatrix}
+  \begin{bmatrix}
+  1 & 0 & 0 & 0 \\
+  0 & 1 & 0 & 0 \\
+  0 & 0 & 1 & 0
+  \end{bmatrix}
+  \begin{bmatrix}
+  r_{11} & r_{12} & r_{13} & t_x \\
+  r_{21} & r_{22} & r_{23} & t_y \\
+  r_{31} & r_{32} & r_{33} & t_z \\
+  0 & 0 & 0 & 1
+  \end{bmatrix}
+  \begin{bmatrix}
+  X_{w} \\
+  Y_{w} \\
+  Z_{w} \\
+  1
+  \end{bmatrix}
+  \end{align*}
+\f]
+
+The estimated pose is thus the rotation (`rvec`) and the translation (`tvec`) vectors that allow to transform
+a 3D point expressed in the world frame into the camera frame:
+
+\f[
+  \begin{align*}
+  \begin{bmatrix}
+  X_c \\
+  Y_c \\
+  Z_c \\
+  1
+  \end{bmatrix} &=
+  \hspace{0.2em} ^{c}\bf{M}_w
+  \begin{bmatrix}
+  X_{w} \\
+  Y_{w} \\
+  Z_{w} \\
+  1
+  \end{bmatrix} \\
+  \begin{bmatrix}
+  X_c \\
+  Y_c \\
+  Z_c \\
+  1
+  \end{bmatrix} &=
+  \begin{bmatrix}
+  r_{11} & r_{12} & r_{13} & t_x \\
+  r_{21} & r_{22} & r_{23} & t_y \\
+  r_{31} & r_{32} & r_{33} & t_z \\
+  0 & 0 & 0 & 1
+  \end{bmatrix}
+  \begin{bmatrix}
+  X_{w} \\
+  Y_{w} \\
+  Z_{w} \\
+  1
+  \end{bmatrix}
+  \end{align*}
+\f]
 
 @note
    -   An example of how to use solvePnP for planar augmented reality can be found at
@@ -1789,6 +1885,12 @@ CV_EXPORTS_W cv::Mat estimateAffinePartial2D(InputArray from, InputArray to, Out
                                   size_t maxIters = 2000, double confidence = 0.99,
                                   size_t refineIters = 10);
 
+/** @example decompose_homography.cpp
+  An example program with homography decomposition.
+
+  Check @ref tutorial_homography "the corresponding tutorial" for more details.
+ */
+
 /** @brief Decompose a homography matrix to rotation(s), translation(s) and plane normal(s).
 
 @param H The input homography matrix between two images.
index 15a2180..c6aefde 100644 (file)
@@ -3660,9 +3660,9 @@ struct Program::Impl
         CV_Assert(src_);
         CV_Assert(src_->kind_ == ProgramSource::Impl::PROGRAM_SOURCE_CODE);
         CV_Assert(handle == NULL);
-        CV_INSTRUMENT_REGION_OPENCL_COMPILE(cv::format("Build OpenCL program: %s/%s %" PRIx64 " options: %s",
+        CV_INSTRUMENT_REGION_OPENCL_COMPILE(cv::format("Build OpenCL program: %s/%s %s options: %s",
                 sourceModule_.c_str(), sourceName_.c_str(),
-                src.hash(), buildflags.c_str()).c_str());
+                src_->sourceHash_.c_str(), buildflags.c_str()).c_str());
 
         CV_LOG_VERBOSE(NULL, 0, "Compile... " << sourceModule_.c_str() << "/" << sourceName_.c_str());
 
index b36bfe5..77c6247 100644 (file)
@@ -97,15 +97,3 @@ if(BUILD_PERF_TESTS)
     endif()
   endif()
 endif()
-
-# ----------------------------------------------------------------------------
-# Torch7 importer of blobs and models, produced by Torch.nn module
-# ----------------------------------------------------------------------------
-OCV_OPTION(${the_module}_BUILD_TORCH_IMPORTER "Build Torch model importer" ON)
-if(${the_module}_BUILD_TORCH_IMPORTER)
-    message(STATUS "Torch importer has been enabled. To run the tests you have to install Torch "
-      "('th' executable should be available) "
-      "and generate testdata using opencv_extra/testdata/dnn/generate_torch_models.py script.")
-    add_definitions(-DENABLE_TORCH_IMPORTER=1)
-    ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4702 /wd4127 /wd4267) #supress warnings in original torch files
-endif()
index b0d78f5..da0e34a 100644 (file)
@@ -58,7 +58,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
   You can use both API, but factory API is less convinient for native C++ programming and basically designed for use inside importers (see @ref readNetFromCaffe(), @ref readNetFromTorch(), @ref readNetFromTensorflow()).
 
   Bult-in layers partially reproduce functionality of corresponding Caffe and Torch7 layers.
-  In partuclar, the following layers and Caffe @ref Importer were tested to reproduce <a href="http://caffe.berkeleyvision.org/tutorial/layers.html">Caffe</a> functionality:
+  In partuclar, the following layers and Caffe importer were tested to reproduce <a href="http://caffe.berkeleyvision.org/tutorial/layers.html">Caffe</a> functionality:
   - Convolution
   - Deconvolution
   - Pooling
@@ -242,6 +242,8 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
         // ROIPooling parameters.
         Size pooledSize;
         float spatialScale;
+        // PSROIPooling parameters.
+        int psRoiOutChannels;
 
         static Ptr<PoolingLayer> create(const LayerParams& params);
     };
index a0eca0a..7488351 100644 (file)
@@ -426,15 +426,6 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
         CV_WRAP_AS(forwardAndRetrieve) void forward(CV_OUT std::vector<std::vector<Mat> >& outputBlobs,
                                                     const std::vector<String>& outBlobNames);
 
-        //TODO:
-        /** @brief Optimized forward.
-         *  @warning Not implemented yet.
-         *  @details Makes forward only those layers which weren't changed after previous forward().
-         */
-        void forwardOpt(LayerId toLayer);
-        /** @overload */
-        void forwardOpt(const std::vector<LayerId> &toLayers);
-
         /**
          * @brief Compile Halide layers.
          * @param[in] scheduler Path to YAML file with scheduling directives.
@@ -609,38 +600,18 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
         Ptr<Impl> impl;
     };
 
-    /**
-     * @deprecated Deprecated as external interface. Will be for internal needs only.
-     * @brief Small interface class for loading trained serialized models of different dnn-frameworks. */
-    class CV_EXPORTS_W Importer : public Algorithm
-    {
-    public:
-
-        /** @brief Adds loaded layers into the @p net and sets connections between them. */
-        CV_DEPRECATED CV_WRAP virtual void populateNet(Net net) = 0;
-
-        virtual ~Importer();
-    };
-
     /** @brief Reads a network model stored in <a href="https://pjreddie.com/darknet/">Darknet</a> model files.
     *  @param cfgFile      path to the .cfg file with text description of the network architecture.
     *  @param darknetModel path to the .weights file with learned network.
     *  @returns Network object that ready to do forward, throw an exception in failure cases.
-    * @details This is shortcut consisting from DarknetImporter and Net::populateNet calls.
+    *  @returns Net object.
     */
     CV_EXPORTS_W Net readNetFromDarknet(const String &cfgFile, const String &darknetModel = String());
 
-    /**
-     *  @deprecated Use @ref readNetFromCaffe instead.
-     *  @brief Creates the importer of <a href="http://caffe.berkeleyvision.org">Caffe</a> framework network.
-     *  @param prototxt   path to the .prototxt file with text description of the network architecture.
-     *  @param caffeModel path to the .caffemodel file with learned network.
-     *  @returns Pointer to the created importer, NULL in failure cases.
-     */
-    CV_DEPRECATED CV_EXPORTS_W Ptr<Importer> createCaffeImporter(const String &prototxt, const String &caffeModel = String());
-
-    /** @brief Reads a network model stored in Caffe model files.
-      * @details This is shortcut consisting from createCaffeImporter and Net::populateNet calls.
+    /** @brief Reads a network model stored in <a href="http://caffe.berkeleyvision.org">Caffe</a> framework's format.
+      * @param prototxt   path to the .prototxt file with text description of the network architecture.
+      * @param caffeModel path to the .caffemodel file with learned network.
+      * @returns Net object.
       */
     CV_EXPORTS_W Net readNetFromCaffe(const String &prototxt, const String &caffeModel = String());
 
@@ -651,16 +622,21 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
       * @param lenProto length of bufferProto
       * @param bufferModel buffer containing the content of the .caffemodel file
       * @param lenModel length of bufferModel
+      * @returns Net object.
       */
     CV_EXPORTS Net readNetFromCaffe(const char *bufferProto, size_t lenProto,
                                     const char *bufferModel = NULL, size_t lenModel = 0);
 
-    /** @brief Reads a network model stored in Tensorflow model file.
-      * @details This is shortcut consisting from createTensorflowImporter and Net::populateNet calls.
+    /** @brief Reads a network model stored in <a href="https://www.tensorflow.org/">TensorFlow</a> framework's format.
+      * @param model  path to the .pb file with binary protobuf description of the network architecture
+      * @param config path to the .pbtxt file that contains text graph definition in protobuf format.
+      *               Resulting Net object is built by text graph using weights from a binary one that
+      *               let us make it more flexible.
+      * @returns Net object.
       */
     CV_EXPORTS_W Net readNetFromTensorflow(const String &model, const String &config = String());
 
-    /** @brief Reads a network model stored in Tensorflow model in memory.
+    /** @brief Reads a network model stored in <a href="https://www.tensorflow.org/">TensorFlow</a> framework's format.
       * @details This is an overloaded member function, provided for convenience.
       * It differs from the above function only in what argument(s) it accepts.
       * @param bufferModel buffer containing the content of the pb file
@@ -671,27 +647,11 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
     CV_EXPORTS Net readNetFromTensorflow(const char *bufferModel, size_t lenModel,
                                          const char *bufferConfig = NULL, size_t lenConfig = 0);
 
-    /** @brief Reads a network model stored in Torch model file.
-      * @details This is shortcut consisting from createTorchImporter and Net::populateNet calls.
-      */
-    CV_EXPORTS_W Net readNetFromTorch(const String &model, bool isBinary = true);
-
     /**
-     *  @deprecated Use @ref readNetFromTensorflow instead.
-     *  @brief Creates the importer of <a href="http://www.tensorflow.org">TensorFlow</a> framework network.
-     *  @param model   path to the .pb file with binary protobuf description of the network architecture.
-     *  @returns Pointer to the created importer, NULL in failure cases.
-     */
-    CV_DEPRECATED CV_EXPORTS_W Ptr<Importer> createTensorflowImporter(const String &model);
-
-    /**
-     *  @deprecated Use @ref readNetFromTorch instead.
-     *  @brief Creates the importer of <a href="http://torch.ch">Torch7</a> framework network.
-     *  @param filename path to the file, dumped from Torch by using torch.save() function.
+     *  @brief Reads a network model stored in <a href="http://torch.ch">Torch7</a> framework's format.
+     *  @param model    path to the file, dumped from Torch by using torch.save() function.
      *  @param isBinary specifies whether the network was serialized in ascii mode or binary.
-     *  @returns Pointer to the created importer, NULL in failure cases.
-     *
-     *  @warning Torch7 importer is experimental now, you need explicitly set CMake `opencv_dnn_BUILD_TORCH_IMPORTER` flag to compile its.
+     *  @returns Net object.
      *
      *  @note Ascii mode of Torch serializer is more preferable, because binary mode extensively use `long` type of C language,
      *  which has various bit-length on different systems.
@@ -712,10 +672,10 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
      *
      * Also some equivalents of these classes from cunn, cudnn, and fbcunn may be successfully imported.
      */
-    CV_DEPRECATED CV_EXPORTS_W Ptr<Importer> createTorchImporter(const String &filename, bool isBinary = true);
+     CV_EXPORTS_W Net readNetFromTorch(const String &model, bool isBinary = true);
 
     /** @brief Loads blob which was serialized as torch.Tensor object of Torch7 framework.
-     *  @warning This function has the same limitations as createTorchImporter().
+     *  @warning This function has the same limitations as readNetFromTorch().
      */
     CV_EXPORTS_W Mat readTorchBlob(const String &filename, bool isBinary = true);
     /** @brief Creates 4-dimensional blob from image. Optionally resizes and crops @p image from center,
index a7db718..a5272d2 100644 (file)
@@ -256,6 +256,9 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
 const ::google::protobuf::Descriptor* ProposalParameter_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   ProposalParameter_reflection_ = NULL;
+const ::google::protobuf::Descriptor* PSROIPoolingParameter_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  PSROIPoolingParameter_reflection_ = NULL;
 const ::google::protobuf::EnumDescriptor* Type_descriptor_ = NULL;
 const ::google::protobuf::EnumDescriptor* Phase_descriptor_ = NULL;
 
@@ -384,7 +387,7 @@ void protobuf_AssignDesc_opencv_2dcaffe_2eproto() {
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PriorBoxParameter, _internal_metadata_));
   PriorBoxParameter_CodeType_descriptor_ = PriorBoxParameter_descriptor_->enum_type(0);
   DetectionOutputParameter_descriptor_ = file->message_type(6);
-  static const int DetectionOutputParameter_offsets_[9] = {
+  static const int DetectionOutputParameter_offsets_[10] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DetectionOutputParameter, num_classes_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DetectionOutputParameter, share_location_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DetectionOutputParameter, background_label_id_),
@@ -394,6 +397,7 @@ void protobuf_AssignDesc_opencv_2dcaffe_2eproto() {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DetectionOutputParameter, variance_encoded_in_target_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DetectionOutputParameter, keep_top_k_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DetectionOutputParameter, confidence_threshold_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DetectionOutputParameter, normalized_bbox_),
   };
   DetectionOutputParameter_reflection_ =
     ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -595,7 +599,7 @@ void protobuf_AssignDesc_opencv_2dcaffe_2eproto() {
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ParamSpec, _internal_metadata_));
   ParamSpec_DimCheckMode_descriptor_ = ParamSpec_descriptor_->enum_type(0);
   LayerParameter_descriptor_ = file->message_type(15);
-  static const int LayerParameter_offsets_[64] = {
+  static const int LayerParameter_offsets_[65] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, name_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, type_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, bottom_),
@@ -645,6 +649,7 @@ void protobuf_AssignDesc_opencv_2dcaffe_2eproto() {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, prelu_param_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, prior_box_param_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, proposal_param_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, psroi_pooling_param_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, python_param_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, recurrent_param_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(LayerParameter, reduction_param_),
@@ -1687,6 +1692,22 @@ void protobuf_AssignDesc_opencv_2dcaffe_2eproto() {
       -1,
       sizeof(ProposalParameter),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ProposalParameter, _internal_metadata_));
+  PSROIPoolingParameter_descriptor_ = file->message_type(70);
+  static const int PSROIPoolingParameter_offsets_[3] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PSROIPoolingParameter, spatial_scale_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PSROIPoolingParameter, output_dim_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PSROIPoolingParameter, group_size_),
+  };
+  PSROIPoolingParameter_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      PSROIPoolingParameter_descriptor_,
+      PSROIPoolingParameter::internal_default_instance(),
+      PSROIPoolingParameter_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PSROIPoolingParameter, _has_bits_),
+      -1,
+      -1,
+      sizeof(PSROIPoolingParameter),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PSROIPoolingParameter, _internal_metadata_));
   Type_descriptor_ = file->enum_type(0);
   Phase_descriptor_ = file->enum_type(1);
 }
@@ -1842,6 +1863,8 @@ void protobuf_RegisterTypes(const ::std::string&) {
       ROIPoolingParameter_descriptor_, ROIPoolingParameter::internal_default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
       ProposalParameter_descriptor_, ProposalParameter::internal_default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      PSROIPoolingParameter_descriptor_, PSROIPoolingParameter::internal_default_instance());
 }
 
 }  // namespace
@@ -1992,6 +2015,8 @@ void protobuf_ShutdownFile_opencv_2dcaffe_2eproto() {
   delete ROIPoolingParameter_reflection_;
   ProposalParameter_default_instance_.Shutdown();
   delete ProposalParameter_reflection_;
+  PSROIPoolingParameter_default_instance_.Shutdown();
+  delete PSROIPoolingParameter_reflection_;
 }
 
 void protobuf_InitDefaults_opencv_2dcaffe_2eproto_impl() {
@@ -2098,6 +2123,7 @@ void protobuf_InitDefaults_opencv_2dcaffe_2eproto_impl() {
   NormalizedBBox_default_instance_.DefaultConstruct();
   ROIPoolingParameter_default_instance_.DefaultConstruct();
   ProposalParameter_default_instance_.DefaultConstruct();
+  PSROIPoolingParameter_default_instance_.DefaultConstruct();
   BlobShape_default_instance_.get_mutable()->InitAsDefaultInstance();
   BlobProto_default_instance_.get_mutable()->InitAsDefaultInstance();
   BlobProtoVector_default_instance_.get_mutable()->InitAsDefaultInstance();
@@ -2168,6 +2194,7 @@ void protobuf_InitDefaults_opencv_2dcaffe_2eproto_impl() {
   NormalizedBBox_default_instance_.get_mutable()->InitAsDefaultInstance();
   ROIPoolingParameter_default_instance_.get_mutable()->InitAsDefaultInstance();
   ProposalParameter_default_instance_.get_mutable()->InitAsDefaultInstance();
+  PSROIPoolingParameter_default_instance_.get_mutable()->InitAsDefaultInstance();
 }
 
 GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_InitDefaults_opencv_2dcaffe_2eproto_once_);
@@ -2203,7 +2230,7 @@ void protobuf_AddDesc_opencv_2dcaffe_2eproto_impl() {
     "\006step_h\030\013 \001(\002\022\016\n\006step_w\030\014 \001(\002\022\023\n\006offset\030"
     "\r \001(\002:\0030.5\022\020\n\010offset_h\030\016 \003(\002\022\020\n\010offset_w"
     "\030\017 \003(\002\022\r\n\005width\030\020 \003(\002\022\016\n\006height\030\021 \003(\002\"\'\n"
-    "\010CodeType\022\n\n\006CORNER\020\001\022\017\n\013CENTER_SIZE\020\002\"\222"
+    "\010CodeType\022\n\n\006CORNER\020\001\022\017\n\013CENTER_SIZE\020\002\"\261"
     "\003\n\030DetectionOutputParameter\022\023\n\013num_class"
     "es\030\001 \001(\r\022\034\n\016share_location\030\002 \001(\010:\004true\022\036"
     "\n\023background_label_id\030\003 \001(\005:\0010\022\?\n\tnms_pa"
@@ -2214,438 +2241,443 @@ void protobuf_AddDesc_opencv_2dcaffe_2eproto_impl() {
     "Parameter.CodeType:\006CORNER\022)\n\032variance_e"
     "ncoded_in_target\030\010 \001(\010:\005false\022\026\n\nkeep_to"
     "p_k\030\007 \001(\005:\002-1\022\034\n\024confidence_threshold\030\t "
-    "\001(\002\"\201\001\n\005Datum\022\020\n\010channels\030\001 \001(\005\022\016\n\006heigh"
-    "t\030\002 \001(\005\022\r\n\005width\030\003 \001(\005\022\014\n\004data\030\004 \001(\014\022\r\n\005"
-    "label\030\005 \001(\005\022\022\n\nfloat_data\030\006 \003(\002\022\026\n\007encod"
-    "ed\030\007 \001(\010:\005false\"\221\002\n\017FillerParameter\022\026\n\004t"
-    "ype\030\001 \001(\t:\010constant\022\020\n\005value\030\002 \001(\002:\0010\022\016\n"
-    "\003min\030\003 \001(\002:\0010\022\016\n\003max\030\004 \001(\002:\0011\022\017\n\004mean\030\005 "
-    "\001(\002:\0010\022\016\n\003std\030\006 \001(\002:\0011\022\022\n\006sparse\030\007 \001(\005:\002"
-    "-1\022I\n\rvariance_norm\030\010 \001(\0162*.opencv_caffe"
-    ".FillerParameter.VarianceNorm:\006FAN_IN\"4\n"
-    "\014VarianceNorm\022\n\n\006FAN_IN\020\000\022\013\n\007FAN_OUT\020\001\022\013"
-    "\n\007AVERAGE\020\002\"\252\002\n\014NetParameter\022\014\n\004name\030\001 \001"
-    "(\t\022\r\n\005input\030\003 \003(\t\022,\n\013input_shape\030\010 \003(\0132\027"
-    ".opencv_caffe.BlobShape\022\021\n\tinput_dim\030\004 \003"
-    "(\005\022\035\n\016force_backward\030\005 \001(\010:\005false\022%\n\005sta"
-    "te\030\006 \001(\0132\026.opencv_caffe.NetState\022\031\n\ndebu"
-    "g_info\030\007 \001(\010:\005false\022+\n\005layer\030d \003(\0132\034.ope"
-    "ncv_caffe.LayerParameter\022.\n\006layers\030\002 \003(\013"
-    "2\036.opencv_caffe.V1LayerParameter\"\332\n\n\017Sol"
-    "verParameter\022\013\n\003net\030\030 \001(\t\022-\n\tnet_param\030\031"
-    " \001(\0132\032.opencv_caffe.NetParameter\022\021\n\ttrai"
-    "n_net\030\001 \001(\t\022\020\n\010test_net\030\002 \003(\t\0223\n\017train_n"
-    "et_param\030\025 \001(\0132\032.opencv_caffe.NetParamet"
-    "er\0222\n\016test_net_param\030\026 \003(\0132\032.opencv_caff"
-    "e.NetParameter\022+\n\013train_state\030\032 \001(\0132\026.op"
-    "encv_caffe.NetState\022*\n\ntest_state\030\033 \003(\0132"
-    "\026.opencv_caffe.NetState\022\021\n\ttest_iter\030\003 \003"
-    "(\005\022\030\n\rtest_interval\030\004 \001(\005:\0010\022 \n\021test_com"
-    "pute_loss\030\023 \001(\010:\005false\022!\n\023test_initializ"
-    "ation\030  \001(\010:\004true\022\017\n\007base_lr\030\005 \001(\002\022\017\n\007di"
-    "splay\030\006 \001(\005\022\027\n\014average_loss\030! \001(\005:\0011\022\020\n\010"
-    "max_iter\030\007 \001(\005\022\024\n\titer_size\030$ \001(\005:\0011\022\021\n\t"
-    "lr_policy\030\010 \001(\t\022\r\n\005gamma\030\t \001(\002\022\r\n\005power\030"
-    "\n \001(\002\022\020\n\010momentum\030\013 \001(\002\022\024\n\014weight_decay\030"
-    "\014 \001(\002\022\037\n\023regularization_type\030\035 \001(\t:\002L2\022\020"
-    "\n\010stepsize\030\r \001(\005\022\021\n\tstepvalue\030\" \003(\005\022\032\n\016c"
-    "lip_gradients\030# \001(\002:\002-1\022\023\n\010snapshot\030\016 \001("
-    "\005:\0010\022\027\n\017snapshot_prefix\030\017 \001(\t\022\034\n\rsnapsho"
-    "t_diff\030\020 \001(\010:\005false\022R\n\017snapshot_format\030%"
-    " \001(\0162,.opencv_caffe.SolverParameter.Snap"
-    "shotFormat:\013BINARYPROTO\022B\n\013solver_mode\030\021"
-    " \001(\0162(.opencv_caffe.SolverParameter.Solv"
-    "erMode:\003GPU\022\024\n\tdevice_id\030\022 \001(\005:\0010\022\027\n\013ran"
-    "dom_seed\030\024 \001(\003:\002-1\022\021\n\004type\030( \001(\t:\003SGD\022\024\n"
-    "\005delta\030\037 \001(\002:\0051e-08\022\030\n\tmomentum2\030\' \001(\002:\005"
-    "0.999\022\027\n\trms_decay\030& \001(\002:\0040.99\022\031\n\ndebug_"
-    "info\030\027 \001(\010:\005false\022\"\n\024snapshot_after_trai"
-    "n\030\034 \001(\010:\004true\022B\n\013solver_type\030\036 \001(\0162(.ope"
-    "ncv_caffe.SolverParameter.SolverType:\003SG"
-    "D\"+\n\016SnapshotFormat\022\010\n\004HDF5\020\000\022\017\n\013BINARYP"
-    "ROTO\020\001\"\036\n\nSolverMode\022\007\n\003CPU\020\000\022\007\n\003GPU\020\001\"U"
-    "\n\nSolverType\022\007\n\003SGD\020\000\022\014\n\010NESTEROV\020\001\022\013\n\007A"
-    "DAGRAD\020\002\022\013\n\007RMSPROP\020\003\022\014\n\010ADADELTA\020\004\022\010\n\004A"
-    "DAM\020\005\"s\n\013SolverState\022\014\n\004iter\030\001 \001(\005\022\023\n\013le"
-    "arned_net\030\002 \001(\t\022(\n\007history\030\003 \003(\0132\027.openc"
-    "v_caffe.BlobProto\022\027\n\014current_step\030\004 \001(\005:"
-    "\0010\"U\n\010NetState\022(\n\005phase\030\001 \001(\0162\023.opencv_c"
-    "affe.Phase:\004TEST\022\020\n\005level\030\002 \001(\005:\0010\022\r\n\005st"
-    "age\030\003 \003(\t\"z\n\014NetStateRule\022\"\n\005phase\030\001 \001(\016"
-    "2\023.opencv_caffe.Phase\022\021\n\tmin_level\030\002 \001(\005"
-    "\022\021\n\tmax_level\030\003 \001(\005\022\r\n\005stage\030\004 \003(\t\022\021\n\tno"
-    "t_stage\030\005 \003(\t\"\252\001\n\tParamSpec\022\014\n\004name\030\001 \001("
-    "\t\0228\n\nshare_mode\030\002 \001(\0162$.opencv_caffe.Par"
-    "amSpec.DimCheckMode\022\022\n\007lr_mult\030\003 \001(\002:\0011\022"
-    "\025\n\ndecay_mult\030\004 \001(\002:\0011\"*\n\014DimCheckMode\022\n"
-    "\n\006STRICT\020\000\022\016\n\nPERMISSIVE\020\001\"\340\031\n\016LayerPara"
-    "meter\022\014\n\004name\030\001 \001(\t\022\014\n\004type\030\002 \001(\t\022\016\n\006bot"
-    "tom\030\003 \003(\t\022\013\n\003top\030\004 \003(\t\022\"\n\005phase\030\n \001(\0162\023."
-    "opencv_caffe.Phase\022\023\n\013loss_weight\030\005 \003(\002\022"
-    "&\n\005param\030\006 \003(\0132\027.opencv_caffe.ParamSpec\022"
-    "&\n\005blobs\030\007 \003(\0132\027.opencv_caffe.BlobProto\022"
-    "\026\n\016propagate_down\030\013 \003(\010\022+\n\007include\030\010 \003(\013"
-    "2\032.opencv_caffe.NetStateRule\022+\n\007exclude\030"
-    "\t \003(\0132\032.opencv_caffe.NetStateRule\022>\n\017tra"
-    "nsform_param\030d \001(\0132%.opencv_caffe.Transf"
-    "ormationParameter\022/\n\nloss_param\030e \001(\0132\033."
-    "opencv_caffe.LossParameter\0227\n\016accuracy_p"
-    "aram\030f \001(\0132\037.opencv_caffe.AccuracyParame"
-    "ter\0223\n\014argmax_param\030g \001(\0132\035.opencv_caffe"
-    ".ArgMaxParameter\022;\n\020batch_norm_param\030\213\001 "
-    "\001(\0132 .opencv_caffe.BatchNormParameter\0220\n"
-    "\nbias_param\030\215\001 \001(\0132\033.opencv_caffe.BiasPa"
-    "rameter\0223\n\014concat_param\030h \001(\0132\035.opencv_c"
-    "affe.ConcatParameter\022F\n\026contrastive_loss"
-    "_param\030i \001(\0132&.opencv_caffe.ContrastiveL"
-    "ossParameter\022=\n\021convolution_param\030j \001(\0132"
-    "\".opencv_caffe.ConvolutionParameter\0220\n\nc"
-    "rop_param\030\220\001 \001(\0132\033.opencv_caffe.CropPara"
-    "meter\022/\n\ndata_param\030k \001(\0132\033.opencv_caffe"
-    ".DataParameter\022G\n\026detection_output_param"
-    "\030\223\001 \001(\0132&.opencv_caffe.DetectionOutputPa"
-    "rameter\0225\n\rdropout_param\030l \001(\0132\036.opencv_"
-    "caffe.DropoutParameter\022:\n\020dummy_data_par"
-    "am\030m \001(\0132 .opencv_caffe.DummyDataParamet"
-    "er\0225\n\reltwise_param\030n \001(\0132\036.opencv_caffe"
-    ".EltwiseParameter\022.\n\telu_param\030\214\001 \001(\0132\032."
-    "opencv_caffe.ELUParameter\0222\n\013embed_param"
-    "\030\211\001 \001(\0132\034.opencv_caffe.EmbedParameter\022-\n"
-    "\texp_param\030o \001(\0132\032.opencv_caffe.ExpParam"
-    "eter\0226\n\rflatten_param\030\207\001 \001(\0132\036.opencv_ca"
-    "ffe.FlattenParameter\0228\n\017hdf5_data_param\030"
-    "p \001(\0132\037.opencv_caffe.HDF5DataParameter\022<"
-    "\n\021hdf5_output_param\030q \001(\0132!.opencv_caffe"
-    ".HDF5OutputParameter\022:\n\020hinge_loss_param"
-    "\030r \001(\0132 .opencv_caffe.HingeLossParameter"
-    "\022:\n\020image_data_param\030s \001(\0132 .opencv_caff"
-    "e.ImageDataParameter\022@\n\023infogain_loss_pa"
-    "ram\030t \001(\0132#.opencv_caffe.InfogainLossPar"
-    "ameter\022@\n\023inner_product_param\030u \001(\0132#.op"
-    "encv_caffe.InnerProductParameter\0222\n\013inpu"
-    "t_param\030\217\001 \001(\0132\034.opencv_caffe.InputParam"
-    "eter\022.\n\tlog_param\030\206\001 \001(\0132\032.opencv_caffe."
-    "LogParameter\022-\n\tlrn_param\030v \001(\0132\032.opencv"
-    "_caffe.LRNParameter\022<\n\021memory_data_param"
-    "\030w \001(\0132!.opencv_caffe.MemoryDataParamete"
-    "r\022-\n\tmvn_param\030x \001(\0132\032.opencv_caffe.MVNP"
-    "arameter\0229\n\nnorm_param\030\225\001 \001(\0132$.opencv_c"
-    "affe.NormalizeBBoxParameter\0226\n\rpermute_p"
-    "aram\030\224\001 \001(\0132\036.opencv_caffe.PermuteParame"
-    "ter\022:\n\017parameter_param\030\221\001 \001(\0132 .opencv_c"
-    "affe.ParameterParameter\0225\n\rpooling_param"
-    "\030y \001(\0132\036.opencv_caffe.PoolingParameter\0221"
-    "\n\013power_param\030z \001(\0132\034.opencv_caffe.Power"
-    "Parameter\0222\n\013prelu_param\030\203\001 \001(\0132\034.opencv"
-    "_caffe.PReLUParameter\0229\n\017prior_box_param"
-    "\030\226\001 \001(\0132\037.opencv_caffe.PriorBoxParameter"
-    "\0228\n\016proposal_param\030\311\001 \001(\0132\037.opencv_caffe"
-    ".ProposalParameter\0224\n\014python_param\030\202\001 \001("
-    "\0132\035.opencv_caffe.PythonParameter\022:\n\017recu"
-    "rrent_param\030\222\001 \001(\0132 .opencv_caffe.Recurr"
-    "entParameter\022:\n\017reduction_param\030\210\001 \001(\0132 "
-    ".opencv_caffe.ReductionParameter\022/\n\nrelu"
-    "_param\030{ \001(\0132\033.opencv_caffe.ReLUParamete"
-    "r\0226\n\rreshape_param\030\205\001 \001(\0132\036.opencv_caffe"
-    ".ReshapeParameter\022\?\n\021roi_pooling_param\030\327"
-    "\307\370\003 \001(\0132!.opencv_caffe.ROIPoolingParamet"
-    "er\0222\n\013scale_param\030\216\001 \001(\0132\034.opencv_caffe."
-    "ScaleParameter\0225\n\rsigmoid_param\030| \001(\0132\036."
-    "opencv_caffe.SigmoidParameter\0225\n\rsoftmax"
-    "_param\030} \001(\0132\036.opencv_caffe.SoftmaxParam"
-    "eter\022.\n\tspp_param\030\204\001 \001(\0132\032.opencv_caffe."
-    "SPPParameter\0221\n\013slice_param\030~ \001(\0132\034.open"
-    "cv_caffe.SliceParameter\022/\n\ntanh_param\030\177 "
-    "\001(\0132\033.opencv_caffe.TanHParameter\022:\n\017thre"
-    "shold_param\030\200\001 \001(\0132 .opencv_caffe.Thresh"
-    "oldParameter\0220\n\ntile_param\030\212\001 \001(\0132\033.open"
-    "cv_caffe.TileParameter\022=\n\021window_data_pa"
-    "ram\030\201\001 \001(\0132!.opencv_caffe.WindowDataPara"
-    "meter\"\266\001\n\027TransformationParameter\022\020\n\005sca"
-    "le\030\001 \001(\002:\0011\022\025\n\006mirror\030\002 \001(\010:\005false\022\024\n\tcr"
-    "op_size\030\003 \001(\r:\0010\022\021\n\tmean_file\030\004 \001(\t\022\022\n\nm"
-    "ean_value\030\005 \003(\002\022\032\n\013force_color\030\006 \001(\010:\005fa"
-    "lse\022\031\n\nforce_gray\030\007 \001(\010:\005false\"\311\001\n\rLossP"
-    "arameter\022\024\n\014ignore_label\030\001 \001(\005\022K\n\rnormal"
-    "ization\030\003 \001(\0162-.opencv_caffe.LossParamet"
-    "er.NormalizationMode:\005VALID\022\021\n\tnormalize"
-    "\030\002 \001(\010\"B\n\021NormalizationMode\022\010\n\004FULL\020\000\022\t\n"
-    "\005VALID\020\001\022\016\n\nBATCH_SIZE\020\002\022\010\n\004NONE\020\003\"L\n\021Ac"
-    "curacyParameter\022\020\n\005top_k\030\001 \001(\r:\0011\022\017\n\004axi"
-    "s\030\002 \001(\005:\0011\022\024\n\014ignore_label\030\003 \001(\005\"M\n\017ArgM"
-    "axParameter\022\032\n\013out_max_val\030\001 \001(\010:\005false\022"
-    "\020\n\005top_k\030\002 \001(\r:\0011\022\014\n\004axis\030\003 \001(\005\"9\n\017Conca"
-    "tParameter\022\017\n\004axis\030\002 \001(\005:\0011\022\025\n\nconcat_di"
-    "m\030\001 \001(\r:\0011\"j\n\022BatchNormParameter\022\030\n\020use_"
-    "global_stats\030\001 \001(\010\022&\n\027moving_average_fra"
-    "ction\030\002 \001(\002:\0050.999\022\022\n\003eps\030\003 \001(\002:\0051e-05\"d"
-    "\n\rBiasParameter\022\017\n\004axis\030\001 \001(\005:\0011\022\023\n\010num_"
-    "axes\030\002 \001(\005:\0011\022-\n\006filler\030\003 \001(\0132\035.opencv_c"
-    "affe.FillerParameter\"L\n\030ContrastiveLossP"
-    "arameter\022\021\n\006margin\030\001 \001(\002:\0011\022\035\n\016legacy_ve"
-    "rsion\030\002 \001(\010:\005false\"\221\004\n\024ConvolutionParame"
-    "ter\022\022\n\nnum_output\030\001 \001(\r\022\027\n\tbias_term\030\002 \001"
-    "(\010:\004true\022\013\n\003pad\030\003 \003(\r\022\023\n\013kernel_size\030\004 \003"
-    "(\r\022\016\n\006stride\030\006 \003(\r\022\020\n\010dilation\030\022 \003(\r\022\020\n\005"
-    "pad_h\030\t \001(\r:\0010\022\020\n\005pad_w\030\n \001(\r:\0010\022\020\n\010kern"
-    "el_h\030\013 \001(\r\022\020\n\010kernel_w\030\014 \001(\r\022\020\n\010stride_h"
-    "\030\r \001(\r\022\020\n\010stride_w\030\016 \001(\r\022\020\n\005group\030\005 \001(\r:"
-    "\0011\0224\n\rweight_filler\030\007 \001(\0132\035.opencv_caffe"
-    ".FillerParameter\0222\n\013bias_filler\030\010 \001(\0132\035."
-    "opencv_caffe.FillerParameter\022B\n\006engine\030\017"
-    " \001(\0162).opencv_caffe.ConvolutionParameter"
-    ".Engine:\007DEFAULT\022\017\n\004axis\030\020 \001(\005:\0011\022\036\n\017for"
-    "ce_nd_im2col\030\021 \001(\010:\005false\"+\n\006Engine\022\013\n\007D"
-    "EFAULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"0\n\rCropPa"
-    "rameter\022\017\n\004axis\030\001 \001(\005:\0012\022\016\n\006offset\030\002 \003(\r"
-    "\"\253\002\n\rDataParameter\022\016\n\006source\030\001 \001(\t\022\022\n\nba"
-    "tch_size\030\004 \001(\r\022\024\n\trand_skip\030\007 \001(\r:\0010\0228\n\007"
-    "backend\030\010 \001(\0162\036.opencv_caffe.DataParamet"
-    "er.DB:\007LEVELDB\022\020\n\005scale\030\002 \001(\002:\0011\022\021\n\tmean"
-    "_file\030\003 \001(\t\022\024\n\tcrop_size\030\005 \001(\r:\0010\022\025\n\006mir"
-    "ror\030\006 \001(\010:\005false\022\"\n\023force_encoded_color\030"
-    "\t \001(\010:\005false\022\023\n\010prefetch\030\n \001(\r:\0014\"\033\n\002DB\022"
-    "\013\n\007LEVELDB\020\000\022\010\n\004LMDB\020\001\"[\n\036NonMaximumSupp"
-    "ressionParameter\022\032\n\rnms_threshold\030\001 \001(\002:"
-    "\0030.3\022\r\n\005top_k\030\002 \001(\005\022\016\n\003eta\030\003 \001(\002:\0011\"\252\001\n\023"
-    "SaveOutputParameter\022\030\n\020output_directory\030"
-    "\001 \001(\t\022\032\n\022output_name_prefix\030\002 \001(\t\022\025\n\rout"
-    "put_format\030\003 \001(\t\022\026\n\016label_map_file\030\004 \001(\t"
-    "\022\026\n\016name_size_file\030\005 \001(\t\022\026\n\016num_test_ima"
-    "ge\030\006 \001(\r\"I\n\020DropoutParameter\022\032\n\rdropout_"
-    "ratio\030\001 \001(\002:\0030.5\022\031\n\013scale_train\030\002 \001(\010:\004t"
-    "rue\"\256\001\n\022DummyDataParameter\0222\n\013data_fille"
-    "r\030\001 \003(\0132\035.opencv_caffe.FillerParameter\022&"
-    "\n\005shape\030\006 \003(\0132\027.opencv_caffe.BlobShape\022\013"
-    "\n\003num\030\002 \003(\r\022\020\n\010channels\030\003 \003(\r\022\016\n\006height\030"
-    "\004 \003(\r\022\r\n\005width\030\005 \003(\r\"\254\001\n\020EltwiseParamete"
-    "r\022@\n\toperation\030\001 \001(\0162(.opencv_caffe.Eltw"
-    "iseParameter.EltwiseOp:\003SUM\022\r\n\005coeff\030\002 \003"
-    "(\002\022\036\n\020stable_prod_grad\030\003 \001(\010:\004true\"\'\n\tEl"
-    "twiseOp\022\010\n\004PROD\020\000\022\007\n\003SUM\020\001\022\007\n\003MAX\020\002\" \n\014E"
-    "LUParameter\022\020\n\005alpha\030\001 \001(\002:\0011\"\272\001\n\016EmbedP"
-    "arameter\022\022\n\nnum_output\030\001 \001(\r\022\021\n\tinput_di"
-    "m\030\002 \001(\r\022\027\n\tbias_term\030\003 \001(\010:\004true\0224\n\rweig"
-    "ht_filler\030\004 \001(\0132\035.opencv_caffe.FillerPar"
-    "ameter\0222\n\013bias_filler\030\005 \001(\0132\035.opencv_caf"
-    "fe.FillerParameter\"D\n\014ExpParameter\022\020\n\004ba"
-    "se\030\001 \001(\002:\002-1\022\020\n\005scale\030\002 \001(\002:\0011\022\020\n\005shift\030"
-    "\003 \001(\002:\0010\"9\n\020FlattenParameter\022\017\n\004axis\030\001 \001"
-    "(\005:\0011\022\024\n\010end_axis\030\002 \001(\005:\002-1\"O\n\021HDF5DataP"
-    "arameter\022\016\n\006source\030\001 \001(\t\022\022\n\nbatch_size\030\002"
-    " \001(\r\022\026\n\007shuffle\030\003 \001(\010:\005false\"(\n\023HDF5Outp"
-    "utParameter\022\021\n\tfile_name\030\001 \001(\t\"e\n\022HingeL"
-    "ossParameter\0227\n\004norm\030\001 \001(\0162%.opencv_caff"
-    "e.HingeLossParameter.Norm:\002L1\"\026\n\004Norm\022\006\n"
-    "\002L1\020\001\022\006\n\002L2\020\002\"\227\002\n\022ImageDataParameter\022\016\n\006"
-    "source\030\001 \001(\t\022\025\n\nbatch_size\030\004 \001(\r:\0011\022\024\n\tr"
-    "and_skip\030\007 \001(\r:\0010\022\026\n\007shuffle\030\010 \001(\010:\005fals"
-    "e\022\025\n\nnew_height\030\t \001(\r:\0010\022\024\n\tnew_width\030\n "
-    "\001(\r:\0010\022\026\n\010is_color\030\013 \001(\010:\004true\022\020\n\005scale\030"
-    "\002 \001(\002:\0011\022\021\n\tmean_file\030\003 \001(\t\022\024\n\tcrop_size"
-    "\030\005 \001(\r:\0010\022\025\n\006mirror\030\006 \001(\010:\005false\022\025\n\013root"
-    "_folder\030\014 \001(\t:\000\"\'\n\025InfogainLossParameter"
-    "\022\016\n\006source\030\001 \001(\t\"\331\001\n\025InnerProductParamet"
-    "er\022\022\n\nnum_output\030\001 \001(\r\022\027\n\tbias_term\030\002 \001("
-    "\010:\004true\0224\n\rweight_filler\030\003 \001(\0132\035.opencv_"
-    "caffe.FillerParameter\0222\n\013bias_filler\030\004 \001"
-    "(\0132\035.opencv_caffe.FillerParameter\022\017\n\004axi"
-    "s\030\005 \001(\005:\0011\022\030\n\ttranspose\030\006 \001(\010:\005false\"8\n\016"
-    "InputParameter\022&\n\005shape\030\001 \003(\0132\027.opencv_c"
-    "affe.BlobShape\"D\n\014LogParameter\022\020\n\004base\030\001"
-    " \001(\002:\002-1\022\020\n\005scale\030\002 \001(\002:\0011\022\020\n\005shift\030\003 \001("
-    "\002:\0010\"\306\002\n\014LRNParameter\022\025\n\nlocal_size\030\001 \001("
-    "\r:\0015\022\020\n\005alpha\030\002 \001(\002:\0011\022\022\n\004beta\030\003 \001(\002:\0040."
-    "75\022K\n\013norm_region\030\004 \001(\0162%.opencv_caffe.L"
-    "RNParameter.NormRegion:\017ACROSS_CHANNELS\022"
-    "\014\n\001k\030\005 \001(\002:\0011\022:\n\006engine\030\006 \001(\0162!.opencv_c"
-    "affe.LRNParameter.Engine:\007DEFAULT\"5\n\nNor"
-    "mRegion\022\023\n\017ACROSS_CHANNELS\020\000\022\022\n\016WITHIN_C"
-    "HANNEL\020\001\"+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE"
-    "\020\001\022\t\n\005CUDNN\020\002\"Z\n\023MemoryDataParameter\022\022\n\n"
-    "batch_size\030\001 \001(\r\022\020\n\010channels\030\002 \001(\r\022\016\n\006he"
-    "ight\030\003 \001(\r\022\r\n\005width\030\004 \001(\r\"d\n\014MVNParamete"
-    "r\022 \n\022normalize_variance\030\001 \001(\010:\004true\022\036\n\017a"
-    "cross_channels\030\002 \001(\010:\005false\022\022\n\003eps\030\003 \001(\002"
-    ":\0051e-09\"<\n\022ParameterParameter\022&\n\005shape\030\001"
-    " \001(\0132\027.opencv_caffe.BlobShape\"\311\003\n\020Poolin"
-    "gParameter\022<\n\004pool\030\001 \001(\0162).opencv_caffe."
-    "PoolingParameter.PoolMethod:\003MAX\022\016\n\003pad\030"
-    "\004 \001(\r:\0010\022\020\n\005pad_h\030\t \001(\r:\0010\022\020\n\005pad_w\030\n \001("
-    "\r:\0010\022\023\n\013kernel_size\030\002 \001(\r\022\020\n\010kernel_h\030\005 "
-    "\001(\r\022\020\n\010kernel_w\030\006 \001(\r\022\021\n\006stride\030\003 \001(\r:\0011"
-    "\022\020\n\010stride_h\030\007 \001(\r\022\020\n\010stride_w\030\010 \001(\r\022>\n\006"
-    "engine\030\013 \001(\0162%.opencv_caffe.PoolingParam"
-    "eter.Engine:\007DEFAULT\022\035\n\016global_pooling\030\014"
-    " \001(\010:\005false\022\027\n\tceil_mode\030\r \001(\010:\004true\".\n\n"
-    "PoolMethod\022\007\n\003MAX\020\000\022\007\n\003AVE\020\001\022\016\n\nSTOCHAST"
-    "IC\020\002\"+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t"
-    "\n\005CUDNN\020\002\"F\n\016PowerParameter\022\020\n\005power\030\001 \001"
-    "(\002:\0011\022\020\n\005scale\030\002 \001(\002:\0011\022\020\n\005shift\030\003 \001(\002:\001"
-    "0\"g\n\017PythonParameter\022\016\n\006module\030\001 \001(\t\022\r\n\005"
-    "layer\030\002 \001(\t\022\023\n\tparam_str\030\003 \001(\t:\000\022 \n\021shar"
-    "e_in_parallel\030\004 \001(\010:\005false\"\316\001\n\022Recurrent"
-    "Parameter\022\025\n\nnum_output\030\001 \001(\r:\0010\0224\n\rweig"
-    "ht_filler\030\002 \001(\0132\035.opencv_caffe.FillerPar"
-    "ameter\0222\n\013bias_filler\030\003 \001(\0132\035.opencv_caf"
-    "fe.FillerParameter\022\031\n\ndebug_info\030\004 \001(\010:\005"
-    "false\022\034\n\rexpose_hidden\030\005 \001(\010:\005false\"\264\001\n\022"
-    "ReductionParameter\022D\n\toperation\030\001 \001(\0162,."
-    "opencv_caffe.ReductionParameter.Reductio"
-    "nOp:\003SUM\022\017\n\004axis\030\002 \001(\005:\0010\022\020\n\005coeff\030\003 \001(\002"
-    ":\0011\"5\n\013ReductionOp\022\007\n\003SUM\020\001\022\010\n\004ASUM\020\002\022\t\n"
-    "\005SUMSQ\020\003\022\010\n\004MEAN\020\004\"\224\001\n\rReLUParameter\022\031\n\016"
-    "negative_slope\030\001 \001(\002:\0010\022;\n\006engine\030\002 \001(\0162"
-    "\".opencv_caffe.ReLUParameter.Engine:\007DEF"
-    "AULT\"+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t"
-    "\n\005CUDNN\020\002\"a\n\020ReshapeParameter\022&\n\005shape\030\001"
-    " \001(\0132\027.opencv_caffe.BlobShape\022\017\n\004axis\030\002 "
-    "\001(\005:\0010\022\024\n\010num_axes\030\003 \001(\005:\002-1\"\263\001\n\016ScalePa"
-    "rameter\022\017\n\004axis\030\001 \001(\005:\0011\022\023\n\010num_axes\030\002 \001"
-    "(\005:\0011\022-\n\006filler\030\003 \001(\0132\035.opencv_caffe.Fil"
-    "lerParameter\022\030\n\tbias_term\030\004 \001(\010:\005false\0222"
-    "\n\013bias_filler\030\005 \001(\0132\035.opencv_caffe.Fille"
-    "rParameter\"\177\n\020SigmoidParameter\022>\n\006engine"
-    "\030\001 \001(\0162%.opencv_caffe.SigmoidParameter.E"
-    "ngine:\007DEFAULT\"+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n"
-    "\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"L\n\016SliceParameter\022\017\n"
-    "\004axis\030\003 \001(\005:\0011\022\023\n\013slice_point\030\002 \003(\r\022\024\n\ts"
-    "lice_dim\030\001 \001(\r:\0011\"\220\001\n\020SoftmaxParameter\022>"
-    "\n\006engine\030\001 \001(\0162%.opencv_caffe.SoftmaxPar"
-    "ameter.Engine:\007DEFAULT\022\017\n\004axis\030\002 \001(\005:\0011\""
-    "+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUD"
-    "NN\020\002\"y\n\rTanHParameter\022;\n\006engine\030\001 \001(\0162\"."
-    "opencv_caffe.TanHParameter.Engine:\007DEFAU"
-    "LT\"+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005"
-    "CUDNN\020\002\"/\n\rTileParameter\022\017\n\004axis\030\001 \001(\005:\001"
-    "1\022\r\n\005tiles\030\002 \001(\005\"*\n\022ThresholdParameter\022\024"
-    "\n\tthreshold\030\001 \001(\002:\0010\"\301\002\n\023WindowDataParam"
-    "eter\022\016\n\006source\030\001 \001(\t\022\020\n\005scale\030\002 \001(\002:\0011\022\021"
-    "\n\tmean_file\030\003 \001(\t\022\022\n\nbatch_size\030\004 \001(\r\022\024\n"
-    "\tcrop_size\030\005 \001(\r:\0010\022\025\n\006mirror\030\006 \001(\010:\005fal"
-    "se\022\031\n\014fg_threshold\030\007 \001(\002:\0030.5\022\031\n\014bg_thre"
-    "shold\030\010 \001(\002:\0030.5\022\031\n\013fg_fraction\030\t \001(\002:\0040"
-    ".25\022\026\n\013context_pad\030\n \001(\r:\0010\022\027\n\tcrop_mode"
-    "\030\013 \001(\t:\004warp\022\033\n\014cache_images\030\014 \001(\010:\005fals"
-    "e\022\025\n\013root_folder\030\r \001(\t:\000\"\371\001\n\014SPPParamete"
-    "r\022\026\n\016pyramid_height\030\001 \001(\r\0228\n\004pool\030\002 \001(\0162"
-    "%.opencv_caffe.SPPParameter.PoolMethod:\003"
-    "MAX\022:\n\006engine\030\006 \001(\0162!.opencv_caffe.SPPPa"
-    "rameter.Engine:\007DEFAULT\".\n\nPoolMethod\022\007\n"
-    "\003MAX\020\000\022\007\n\003AVE\020\001\022\016\n\nSTOCHASTIC\020\002\"+\n\006Engin"
-    "e\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"\334\025\n"
-    "\020V1LayerParameter\022\016\n\006bottom\030\002 \003(\t\022\013\n\003top"
-    "\030\003 \003(\t\022\014\n\004name\030\004 \001(\t\022+\n\007include\030  \003(\0132\032."
-    "opencv_caffe.NetStateRule\022+\n\007exclude\030! \003"
-    "(\0132\032.opencv_caffe.NetStateRule\0226\n\004type\030\005"
-    " \001(\0162(.opencv_caffe.V1LayerParameter.Lay"
-    "erType\022&\n\005blobs\030\006 \003(\0132\027.opencv_caffe.Blo"
-    "bProto\022\016\n\005param\030\351\007 \003(\t\022E\n\017blob_share_mod"
-    "e\030\352\007 \003(\0162+.opencv_caffe.V1LayerParameter"
-    ".DimCheckMode\022\020\n\010blobs_lr\030\007 \003(\002\022\024\n\014weigh"
-    "t_decay\030\010 \003(\002\022\023\n\013loss_weight\030# \003(\002\0227\n\016ac"
-    "curacy_param\030\033 \001(\0132\037.opencv_caffe.Accura"
-    "cyParameter\0223\n\014argmax_param\030\027 \001(\0132\035.open"
-    "cv_caffe.ArgMaxParameter\0223\n\014concat_param"
-    "\030\t \001(\0132\035.opencv_caffe.ConcatParameter\022F\n"
-    "\026contrastive_loss_param\030( \001(\0132&.opencv_c"
-    "affe.ContrastiveLossParameter\022=\n\021convolu"
-    "tion_param\030\n \001(\0132\".opencv_caffe.Convolut"
-    "ionParameter\022/\n\ndata_param\030\013 \001(\0132\033.openc"
-    "v_caffe.DataParameter\0225\n\rdropout_param\030\014"
-    " \001(\0132\036.opencv_caffe.DropoutParameter\022:\n\020"
-    "dummy_data_param\030\032 \001(\0132 .opencv_caffe.Du"
-    "mmyDataParameter\0225\n\reltwise_param\030\030 \001(\0132"
-    "\036.opencv_caffe.EltwiseParameter\022-\n\texp_p"
-    "aram\030) \001(\0132\032.opencv_caffe.ExpParameter\0228"
-    "\n\017hdf5_data_param\030\r \001(\0132\037.opencv_caffe.H"
-    "DF5DataParameter\022<\n\021hdf5_output_param\030\016 "
-    "\001(\0132!.opencv_caffe.HDF5OutputParameter\022:"
-    "\n\020hinge_loss_param\030\035 \001(\0132 .opencv_caffe."
-    "HingeLossParameter\022:\n\020image_data_param\030\017"
-    " \001(\0132 .opencv_caffe.ImageDataParameter\022@"
-    "\n\023infogain_loss_param\030\020 \001(\0132#.opencv_caf"
-    "fe.InfogainLossParameter\022@\n\023inner_produc"
-    "t_param\030\021 \001(\0132#.opencv_caffe.InnerProduc"
-    "tParameter\022-\n\tlrn_param\030\022 \001(\0132\032.opencv_c"
-    "affe.LRNParameter\022<\n\021memory_data_param\030\026"
-    " \001(\0132!.opencv_caffe.MemoryDataParameter\022"
-    "-\n\tmvn_param\030\" \001(\0132\032.opencv_caffe.MVNPar"
-    "ameter\0225\n\rpooling_param\030\023 \001(\0132\036.opencv_c"
-    "affe.PoolingParameter\0221\n\013power_param\030\025 \001"
-    "(\0132\034.opencv_caffe.PowerParameter\022/\n\nrelu"
-    "_param\030\036 \001(\0132\033.opencv_caffe.ReLUParamete"
-    "r\0225\n\rsigmoid_param\030& \001(\0132\036.opencv_caffe."
-    "SigmoidParameter\0225\n\rsoftmax_param\030\' \001(\0132"
-    "\036.opencv_caffe.SoftmaxParameter\0221\n\013slice"
-    "_param\030\037 \001(\0132\034.opencv_caffe.SliceParamet"
-    "er\022/\n\ntanh_param\030% \001(\0132\033.opencv_caffe.Ta"
-    "nHParameter\0229\n\017threshold_param\030\031 \001(\0132 .o"
-    "pencv_caffe.ThresholdParameter\022<\n\021window"
-    "_data_param\030\024 \001(\0132!.opencv_caffe.WindowD"
-    "ataParameter\022>\n\017transform_param\030$ \001(\0132%."
-    "opencv_caffe.TransformationParameter\022/\n\n"
-    "loss_param\030* \001(\0132\033.opencv_caffe.LossPara"
-    "meter\022-\n\005layer\030\001 \001(\0132\036.opencv_caffe.V0La"
-    "yerParameter\"\330\004\n\tLayerType\022\010\n\004NONE\020\000\022\n\n\006"
-    "ABSVAL\020#\022\014\n\010ACCURACY\020\001\022\n\n\006ARGMAX\020\036\022\010\n\004BN"
-    "LL\020\002\022\n\n\006CONCAT\020\003\022\024\n\020CONTRASTIVE_LOSS\020%\022\017"
-    "\n\013CONVOLUTION\020\004\022\010\n\004DATA\020\005\022\021\n\rDECONVOLUTI"
-    "ON\020\'\022\013\n\007DROPOUT\020\006\022\016\n\nDUMMY_DATA\020 \022\022\n\016EUC"
-    "LIDEAN_LOSS\020\007\022\013\n\007ELTWISE\020\031\022\007\n\003EXP\020&\022\013\n\007F"
-    "LATTEN\020\010\022\r\n\tHDF5_DATA\020\t\022\017\n\013HDF5_OUTPUT\020\n"
-    "\022\016\n\nHINGE_LOSS\020\034\022\n\n\006IM2COL\020\013\022\016\n\nIMAGE_DA"
-    "TA\020\014\022\021\n\rINFOGAIN_LOSS\020\r\022\021\n\rINNER_PRODUCT"
-    "\020\016\022\007\n\003LRN\020\017\022\017\n\013MEMORY_DATA\020\035\022\035\n\031MULTINOM"
-    "IAL_LOGISTIC_LOSS\020\020\022\007\n\003MVN\020\"\022\013\n\007POOLING\020"
-    "\021\022\t\n\005POWER\020\032\022\010\n\004RELU\020\022\022\013\n\007SIGMOID\020\023\022\036\n\032S"
-    "IGMOID_CROSS_ENTROPY_LOSS\020\033\022\013\n\007SILENCE\020$"
-    "\022\013\n\007SOFTMAX\020\024\022\020\n\014SOFTMAX_LOSS\020\025\022\t\n\005SPLIT"
-    "\020\026\022\t\n\005SLICE\020!\022\010\n\004TANH\020\027\022\017\n\013WINDOW_DATA\020\030"
-    "\022\r\n\tTHRESHOLD\020\037\"*\n\014DimCheckMode\022\n\n\006STRIC"
-    "T\020\000\022\016\n\nPERMISSIVE\020\001\"\240\010\n\020V0LayerParameter"
-    "\022\014\n\004name\030\001 \001(\t\022\014\n\004type\030\002 \001(\t\022\022\n\nnum_outp"
-    "ut\030\003 \001(\r\022\026\n\010biasterm\030\004 \001(\010:\004true\0224\n\rweig"
-    "ht_filler\030\005 \001(\0132\035.opencv_caffe.FillerPar"
-    "ameter\0222\n\013bias_filler\030\006 \001(\0132\035.opencv_caf"
-    "fe.FillerParameter\022\016\n\003pad\030\007 \001(\r:\0010\022\022\n\nke"
-    "rnelsize\030\010 \001(\r\022\020\n\005group\030\t \001(\r:\0011\022\021\n\006stri"
-    "de\030\n \001(\r:\0011\022<\n\004pool\030\013 \001(\0162).opencv_caffe"
-    ".V0LayerParameter.PoolMethod:\003MAX\022\032\n\rdro"
-    "pout_ratio\030\014 \001(\002:\0030.5\022\025\n\nlocal_size\030\r \001("
-    "\r:\0015\022\020\n\005alpha\030\016 \001(\002:\0011\022\022\n\004beta\030\017 \001(\002:\0040."
-    "75\022\014\n\001k\030\026 \001(\002:\0011\022\016\n\006source\030\020 \001(\t\022\020\n\005scal"
-    "e\030\021 \001(\002:\0011\022\020\n\010meanfile\030\022 \001(\t\022\021\n\tbatchsiz"
-    "e\030\023 \001(\r\022\023\n\010cropsize\030\024 \001(\r:\0010\022\025\n\006mirror\030\025"
-    " \001(\010:\005false\022&\n\005blobs\0302 \003(\0132\027.opencv_caff"
-    "e.BlobProto\022\020\n\010blobs_lr\0303 \003(\002\022\024\n\014weight_"
-    "decay\0304 \003(\002\022\024\n\trand_skip\0305 \001(\r:\0010\022\035\n\020det"
-    "_fg_threshold\0306 \001(\002:\0030.5\022\035\n\020det_bg_thres"
-    "hold\0307 \001(\002:\0030.5\022\035\n\017det_fg_fraction\0308 \001(\002"
-    ":\0040.25\022\032\n\017det_context_pad\030: \001(\r:\0010\022\033\n\rde"
-    "t_crop_mode\030; \001(\t:\004warp\022\022\n\007new_num\030< \001(\005"
-    ":\0010\022\027\n\014new_channels\030= \001(\005:\0010\022\025\n\nnew_heig"
-    "ht\030> \001(\005:\0010\022\024\n\tnew_width\030\? \001(\005:\0010\022\035\n\016shu"
-    "ffle_images\030@ \001(\010:\005false\022\025\n\nconcat_dim\030A"
-    " \001(\r:\0011\022=\n\021hdf5_output_param\030\351\007 \001(\0132!.op"
-    "encv_caffe.HDF5OutputParameter\".\n\nPoolMe"
-    "thod\022\007\n\003MAX\020\000\022\007\n\003AVE\020\001\022\016\n\nSTOCHASTIC\020\002\"^"
-    "\n\016PReLUParameter\022-\n\006filler\030\001 \001(\0132\035.openc"
-    "v_caffe.FillerParameter\022\035\n\016channel_share"
-    "d\030\002 \001(\010:\005false\"\207\001\n\016NormalizedBBox\022\014\n\004xmi"
-    "n\030\001 \001(\002\022\014\n\004ymin\030\002 \001(\002\022\014\n\004xmax\030\003 \001(\002\022\014\n\004y"
-    "max\030\004 \001(\002\022\r\n\005label\030\005 \001(\005\022\021\n\tdifficult\030\006 "
-    "\001(\010\022\r\n\005score\030\007 \001(\002\022\014\n\004size\030\010 \001(\002\"Y\n\023ROIP"
-    "oolingParameter\022\023\n\010pooled_h\030\001 \001(\r:\0010\022\023\n\010"
-    "pooled_w\030\002 \001(\r:\0010\022\030\n\rspatial_scale\030\003 \001(\002"
-    ":\0011\"\310\001\n\021ProposalParameter\022\027\n\013feat_stride"
-    "\030\001 \001(\r:\00216\022\025\n\tbase_size\030\002 \001(\r:\00216\022\024\n\010min"
-    "_size\030\003 \001(\r:\00216\022\r\n\005ratio\030\004 \003(\002\022\r\n\005scale\030"
-    "\005 \003(\002\022\032\n\014pre_nms_topn\030\006 \001(\r:\0046000\022\032\n\rpos"
-    "t_nms_topn\030\007 \001(\r:\003300\022\027\n\nnms_thresh\030\010 \001("
-    "\002:\0030.7*=\n\004Type\022\n\n\006DOUBLE\020\000\022\t\n\005FLOAT\020\001\022\013\n"
-    "\007FLOAT16\020\002\022\007\n\003INT\020\003\022\010\n\004UINT\020\004*\034\n\005Phase\022\t"
-    "\n\005TRAIN\020\000\022\010\n\004TEST\020\001", 18619);
+    "\001(\002\022\035\n\017normalized_bbox\030\n \001(\010:\004true\"\201\001\n\005D"
+    "atum\022\020\n\010channels\030\001 \001(\005\022\016\n\006height\030\002 \001(\005\022\r"
+    "\n\005width\030\003 \001(\005\022\014\n\004data\030\004 \001(\014\022\r\n\005label\030\005 \001"
+    "(\005\022\022\n\nfloat_data\030\006 \003(\002\022\026\n\007encoded\030\007 \001(\010:"
+    "\005false\"\221\002\n\017FillerParameter\022\026\n\004type\030\001 \001(\t"
+    ":\010constant\022\020\n\005value\030\002 \001(\002:\0010\022\016\n\003min\030\003 \001("
+    "\002:\0010\022\016\n\003max\030\004 \001(\002:\0011\022\017\n\004mean\030\005 \001(\002:\0010\022\016\n"
+    "\003std\030\006 \001(\002:\0011\022\022\n\006sparse\030\007 \001(\005:\002-1\022I\n\rvar"
+    "iance_norm\030\010 \001(\0162*.opencv_caffe.FillerPa"
+    "rameter.VarianceNorm:\006FAN_IN\"4\n\014Variance"
+    "Norm\022\n\n\006FAN_IN\020\000\022\013\n\007FAN_OUT\020\001\022\013\n\007AVERAGE"
+    "\020\002\"\252\002\n\014NetParameter\022\014\n\004name\030\001 \001(\t\022\r\n\005inp"
+    "ut\030\003 \003(\t\022,\n\013input_shape\030\010 \003(\0132\027.opencv_c"
+    "affe.BlobShape\022\021\n\tinput_dim\030\004 \003(\005\022\035\n\016for"
+    "ce_backward\030\005 \001(\010:\005false\022%\n\005state\030\006 \001(\0132"
+    "\026.opencv_caffe.NetState\022\031\n\ndebug_info\030\007 "
+    "\001(\010:\005false\022+\n\005layer\030d \003(\0132\034.opencv_caffe"
+    ".LayerParameter\022.\n\006layers\030\002 \003(\0132\036.opencv"
+    "_caffe.V1LayerParameter\"\332\n\n\017SolverParame"
+    "ter\022\013\n\003net\030\030 \001(\t\022-\n\tnet_param\030\031 \001(\0132\032.op"
+    "encv_caffe.NetParameter\022\021\n\ttrain_net\030\001 \001"
+    "(\t\022\020\n\010test_net\030\002 \003(\t\0223\n\017train_net_param\030"
+    "\025 \001(\0132\032.opencv_caffe.NetParameter\0222\n\016tes"
+    "t_net_param\030\026 \003(\0132\032.opencv_caffe.NetPara"
+    "meter\022+\n\013train_state\030\032 \001(\0132\026.opencv_caff"
+    "e.NetState\022*\n\ntest_state\030\033 \003(\0132\026.opencv_"
+    "caffe.NetState\022\021\n\ttest_iter\030\003 \003(\005\022\030\n\rtes"
+    "t_interval\030\004 \001(\005:\0010\022 \n\021test_compute_loss"
+    "\030\023 \001(\010:\005false\022!\n\023test_initialization\030  \001"
+    "(\010:\004true\022\017\n\007base_lr\030\005 \001(\002\022\017\n\007display\030\006 \001"
+    "(\005\022\027\n\014average_loss\030! \001(\005:\0011\022\020\n\010max_iter\030"
+    "\007 \001(\005\022\024\n\titer_size\030$ \001(\005:\0011\022\021\n\tlr_policy"
+    "\030\010 \001(\t\022\r\n\005gamma\030\t \001(\002\022\r\n\005power\030\n \001(\002\022\020\n\010"
+    "momentum\030\013 \001(\002\022\024\n\014weight_decay\030\014 \001(\002\022\037\n\023"
+    "regularization_type\030\035 \001(\t:\002L2\022\020\n\010stepsiz"
+    "e\030\r \001(\005\022\021\n\tstepvalue\030\" \003(\005\022\032\n\016clip_gradi"
+    "ents\030# \001(\002:\002-1\022\023\n\010snapshot\030\016 \001(\005:\0010\022\027\n\017s"
+    "napshot_prefix\030\017 \001(\t\022\034\n\rsnapshot_diff\030\020 "
+    "\001(\010:\005false\022R\n\017snapshot_format\030% \001(\0162,.op"
+    "encv_caffe.SolverParameter.SnapshotForma"
+    "t:\013BINARYPROTO\022B\n\013solver_mode\030\021 \001(\0162(.op"
+    "encv_caffe.SolverParameter.SolverMode:\003G"
+    "PU\022\024\n\tdevice_id\030\022 \001(\005:\0010\022\027\n\013random_seed\030"
+    "\024 \001(\003:\002-1\022\021\n\004type\030( \001(\t:\003SGD\022\024\n\005delta\030\037 "
+    "\001(\002:\0051e-08\022\030\n\tmomentum2\030\' \001(\002:\0050.999\022\027\n\t"
+    "rms_decay\030& \001(\002:\0040.99\022\031\n\ndebug_info\030\027 \001("
+    "\010:\005false\022\"\n\024snapshot_after_train\030\034 \001(\010:\004"
+    "true\022B\n\013solver_type\030\036 \001(\0162(.opencv_caffe"
+    ".SolverParameter.SolverType:\003SGD\"+\n\016Snap"
+    "shotFormat\022\010\n\004HDF5\020\000\022\017\n\013BINARYPROTO\020\001\"\036\n"
+    "\nSolverMode\022\007\n\003CPU\020\000\022\007\n\003GPU\020\001\"U\n\nSolverT"
+    "ype\022\007\n\003SGD\020\000\022\014\n\010NESTEROV\020\001\022\013\n\007ADAGRAD\020\002\022"
+    "\013\n\007RMSPROP\020\003\022\014\n\010ADADELTA\020\004\022\010\n\004ADAM\020\005\"s\n\013"
+    "SolverState\022\014\n\004iter\030\001 \001(\005\022\023\n\013learned_net"
+    "\030\002 \001(\t\022(\n\007history\030\003 \003(\0132\027.opencv_caffe.B"
+    "lobProto\022\027\n\014current_step\030\004 \001(\005:\0010\"U\n\010Net"
+    "State\022(\n\005phase\030\001 \001(\0162\023.opencv_caffe.Phas"
+    "e:\004TEST\022\020\n\005level\030\002 \001(\005:\0010\022\r\n\005stage\030\003 \003(\t"
+    "\"z\n\014NetStateRule\022\"\n\005phase\030\001 \001(\0162\023.opencv"
+    "_caffe.Phase\022\021\n\tmin_level\030\002 \001(\005\022\021\n\tmax_l"
+    "evel\030\003 \001(\005\022\r\n\005stage\030\004 \003(\t\022\021\n\tnot_stage\030\005"
+    " \003(\t\"\252\001\n\tParamSpec\022\014\n\004name\030\001 \001(\t\0228\n\nshar"
+    "e_mode\030\002 \001(\0162$.opencv_caffe.ParamSpec.Di"
+    "mCheckMode\022\022\n\007lr_mult\030\003 \001(\002:\0011\022\025\n\ndecay_"
+    "mult\030\004 \001(\002:\0011\"*\n\014DimCheckMode\022\n\n\006STRICT\020"
+    "\000\022\016\n\nPERMISSIVE\020\001\"\243\032\n\016LayerParameter\022\014\n\004"
+    "name\030\001 \001(\t\022\014\n\004type\030\002 \001(\t\022\016\n\006bottom\030\003 \003(\t"
+    "\022\013\n\003top\030\004 \003(\t\022\"\n\005phase\030\n \001(\0162\023.opencv_ca"
+    "ffe.Phase\022\023\n\013loss_weight\030\005 \003(\002\022&\n\005param\030"
+    "\006 \003(\0132\027.opencv_caffe.ParamSpec\022&\n\005blobs\030"
+    "\007 \003(\0132\027.opencv_caffe.BlobProto\022\026\n\016propag"
+    "ate_down\030\013 \003(\010\022+\n\007include\030\010 \003(\0132\032.opencv"
+    "_caffe.NetStateRule\022+\n\007exclude\030\t \003(\0132\032.o"
+    "pencv_caffe.NetStateRule\022>\n\017transform_pa"
+    "ram\030d \001(\0132%.opencv_caffe.TransformationP"
+    "arameter\022/\n\nloss_param\030e \001(\0132\033.opencv_ca"
+    "ffe.LossParameter\0227\n\016accuracy_param\030f \001("
+    "\0132\037.opencv_caffe.AccuracyParameter\0223\n\014ar"
+    "gmax_param\030g \001(\0132\035.opencv_caffe.ArgMaxPa"
+    "rameter\022;\n\020batch_norm_param\030\213\001 \001(\0132 .ope"
+    "ncv_caffe.BatchNormParameter\0220\n\nbias_par"
+    "am\030\215\001 \001(\0132\033.opencv_caffe.BiasParameter\0223"
+    "\n\014concat_param\030h \001(\0132\035.opencv_caffe.Conc"
+    "atParameter\022F\n\026contrastive_loss_param\030i "
+    "\001(\0132&.opencv_caffe.ContrastiveLossParame"
+    "ter\022=\n\021convolution_param\030j \001(\0132\".opencv_"
+    "caffe.ConvolutionParameter\0220\n\ncrop_param"
+    "\030\220\001 \001(\0132\033.opencv_caffe.CropParameter\022/\n\n"
+    "data_param\030k \001(\0132\033.opencv_caffe.DataPara"
+    "meter\022G\n\026detection_output_param\030\223\001 \001(\0132&"
+    ".opencv_caffe.DetectionOutputParameter\0225"
+    "\n\rdropout_param\030l \001(\0132\036.opencv_caffe.Dro"
+    "poutParameter\022:\n\020dummy_data_param\030m \001(\0132"
+    " .opencv_caffe.DummyDataParameter\0225\n\relt"
+    "wise_param\030n \001(\0132\036.opencv_caffe.EltwiseP"
+    "arameter\022.\n\telu_param\030\214\001 \001(\0132\032.opencv_ca"
+    "ffe.ELUParameter\0222\n\013embed_param\030\211\001 \001(\0132\034"
+    ".opencv_caffe.EmbedParameter\022-\n\texp_para"
+    "m\030o \001(\0132\032.opencv_caffe.ExpParameter\0226\n\rf"
+    "latten_param\030\207\001 \001(\0132\036.opencv_caffe.Flatt"
+    "enParameter\0228\n\017hdf5_data_param\030p \001(\0132\037.o"
+    "pencv_caffe.HDF5DataParameter\022<\n\021hdf5_ou"
+    "tput_param\030q \001(\0132!.opencv_caffe.HDF5Outp"
+    "utParameter\022:\n\020hinge_loss_param\030r \001(\0132 ."
+    "opencv_caffe.HingeLossParameter\022:\n\020image"
+    "_data_param\030s \001(\0132 .opencv_caffe.ImageDa"
+    "taParameter\022@\n\023infogain_loss_param\030t \001(\013"
+    "2#.opencv_caffe.InfogainLossParameter\022@\n"
+    "\023inner_product_param\030u \001(\0132#.opencv_caff"
+    "e.InnerProductParameter\0222\n\013input_param\030\217"
+    "\001 \001(\0132\034.opencv_caffe.InputParameter\022.\n\tl"
+    "og_param\030\206\001 \001(\0132\032.opencv_caffe.LogParame"
+    "ter\022-\n\tlrn_param\030v \001(\0132\032.opencv_caffe.LR"
+    "NParameter\022<\n\021memory_data_param\030w \001(\0132!."
+    "opencv_caffe.MemoryDataParameter\022-\n\tmvn_"
+    "param\030x \001(\0132\032.opencv_caffe.MVNParameter\022"
+    "9\n\nnorm_param\030\225\001 \001(\0132$.opencv_caffe.Norm"
+    "alizeBBoxParameter\0226\n\rpermute_param\030\224\001 \001"
+    "(\0132\036.opencv_caffe.PermuteParameter\022:\n\017pa"
+    "rameter_param\030\221\001 \001(\0132 .opencv_caffe.Para"
+    "meterParameter\0225\n\rpooling_param\030y \001(\0132\036."
+    "opencv_caffe.PoolingParameter\0221\n\013power_p"
+    "aram\030z \001(\0132\034.opencv_caffe.PowerParameter"
+    "\0222\n\013prelu_param\030\203\001 \001(\0132\034.opencv_caffe.PR"
+    "eLUParameter\0229\n\017prior_box_param\030\226\001 \001(\0132\037"
+    ".opencv_caffe.PriorBoxParameter\0228\n\016propo"
+    "sal_param\030\311\001 \001(\0132\037.opencv_caffe.Proposal"
+    "Parameter\022A\n\023psroi_pooling_param\030\221N \001(\0132"
+    "#.opencv_caffe.PSROIPoolingParameter\0224\n\014"
+    "python_param\030\202\001 \001(\0132\035.opencv_caffe.Pytho"
+    "nParameter\022:\n\017recurrent_param\030\222\001 \001(\0132 .o"
+    "pencv_caffe.RecurrentParameter\022:\n\017reduct"
+    "ion_param\030\210\001 \001(\0132 .opencv_caffe.Reductio"
+    "nParameter\022/\n\nrelu_param\030{ \001(\0132\033.opencv_"
+    "caffe.ReLUParameter\0226\n\rreshape_param\030\205\001 "
+    "\001(\0132\036.opencv_caffe.ReshapeParameter\022\?\n\021r"
+    "oi_pooling_param\030\327\307\370\003 \001(\0132!.opencv_caffe"
+    ".ROIPoolingParameter\0222\n\013scale_param\030\216\001 \001"
+    "(\0132\034.opencv_caffe.ScaleParameter\0225\n\rsigm"
+    "oid_param\030| \001(\0132\036.opencv_caffe.SigmoidPa"
+    "rameter\0225\n\rsoftmax_param\030} \001(\0132\036.opencv_"
+    "caffe.SoftmaxParameter\022.\n\tspp_param\030\204\001 \001"
+    "(\0132\032.opencv_caffe.SPPParameter\0221\n\013slice_"
+    "param\030~ \001(\0132\034.opencv_caffe.SliceParamete"
+    "r\022/\n\ntanh_param\030\177 \001(\0132\033.opencv_caffe.Tan"
+    "HParameter\022:\n\017threshold_param\030\200\001 \001(\0132 .o"
+    "pencv_caffe.ThresholdParameter\0220\n\ntile_p"
+    "aram\030\212\001 \001(\0132\033.opencv_caffe.TileParameter"
+    "\022=\n\021window_data_param\030\201\001 \001(\0132!.opencv_ca"
+    "ffe.WindowDataParameter\"\266\001\n\027Transformati"
+    "onParameter\022\020\n\005scale\030\001 \001(\002:\0011\022\025\n\006mirror\030"
+    "\002 \001(\010:\005false\022\024\n\tcrop_size\030\003 \001(\r:\0010\022\021\n\tme"
+    "an_file\030\004 \001(\t\022\022\n\nmean_value\030\005 \003(\002\022\032\n\013for"
+    "ce_color\030\006 \001(\010:\005false\022\031\n\nforce_gray\030\007 \001("
+    "\010:\005false\"\311\001\n\rLossParameter\022\024\n\014ignore_lab"
+    "el\030\001 \001(\005\022K\n\rnormalization\030\003 \001(\0162-.opencv"
+    "_caffe.LossParameter.NormalizationMode:\005"
+    "VALID\022\021\n\tnormalize\030\002 \001(\010\"B\n\021Normalizatio"
+    "nMode\022\010\n\004FULL\020\000\022\t\n\005VALID\020\001\022\016\n\nBATCH_SIZE"
+    "\020\002\022\010\n\004NONE\020\003\"L\n\021AccuracyParameter\022\020\n\005top"
+    "_k\030\001 \001(\r:\0011\022\017\n\004axis\030\002 \001(\005:\0011\022\024\n\014ignore_l"
+    "abel\030\003 \001(\005\"M\n\017ArgMaxParameter\022\032\n\013out_max"
+    "_val\030\001 \001(\010:\005false\022\020\n\005top_k\030\002 \001(\r:\0011\022\014\n\004a"
+    "xis\030\003 \001(\005\"9\n\017ConcatParameter\022\017\n\004axis\030\002 \001"
+    "(\005:\0011\022\025\n\nconcat_dim\030\001 \001(\r:\0011\"j\n\022BatchNor"
+    "mParameter\022\030\n\020use_global_stats\030\001 \001(\010\022&\n\027"
+    "moving_average_fraction\030\002 \001(\002:\0050.999\022\022\n\003"
+    "eps\030\003 \001(\002:\0051e-05\"d\n\rBiasParameter\022\017\n\004axi"
+    "s\030\001 \001(\005:\0011\022\023\n\010num_axes\030\002 \001(\005:\0011\022-\n\006fille"
+    "r\030\003 \001(\0132\035.opencv_caffe.FillerParameter\"L"
+    "\n\030ContrastiveLossParameter\022\021\n\006margin\030\001 \001"
+    "(\002:\0011\022\035\n\016legacy_version\030\002 \001(\010:\005false\"\221\004\n"
+    "\024ConvolutionParameter\022\022\n\nnum_output\030\001 \001("
+    "\r\022\027\n\tbias_term\030\002 \001(\010:\004true\022\013\n\003pad\030\003 \003(\r\022"
+    "\023\n\013kernel_size\030\004 \003(\r\022\016\n\006stride\030\006 \003(\r\022\020\n\010"
+    "dilation\030\022 \003(\r\022\020\n\005pad_h\030\t \001(\r:\0010\022\020\n\005pad_"
+    "w\030\n \001(\r:\0010\022\020\n\010kernel_h\030\013 \001(\r\022\020\n\010kernel_w"
+    "\030\014 \001(\r\022\020\n\010stride_h\030\r \001(\r\022\020\n\010stride_w\030\016 \001"
+    "(\r\022\020\n\005group\030\005 \001(\r:\0011\0224\n\rweight_filler\030\007 "
+    "\001(\0132\035.opencv_caffe.FillerParameter\0222\n\013bi"
+    "as_filler\030\010 \001(\0132\035.opencv_caffe.FillerPar"
+    "ameter\022B\n\006engine\030\017 \001(\0162).opencv_caffe.Co"
+    "nvolutionParameter.Engine:\007DEFAULT\022\017\n\004ax"
+    "is\030\020 \001(\005:\0011\022\036\n\017force_nd_im2col\030\021 \001(\010:\005fa"
+    "lse\"+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t\n"
+    "\005CUDNN\020\002\"0\n\rCropParameter\022\017\n\004axis\030\001 \001(\005:"
+    "\0012\022\016\n\006offset\030\002 \003(\r\"\253\002\n\rDataParameter\022\016\n\006"
+    "source\030\001 \001(\t\022\022\n\nbatch_size\030\004 \001(\r\022\024\n\trand"
+    "_skip\030\007 \001(\r:\0010\0228\n\007backend\030\010 \001(\0162\036.opencv"
+    "_caffe.DataParameter.DB:\007LEVELDB\022\020\n\005scal"
+    "e\030\002 \001(\002:\0011\022\021\n\tmean_file\030\003 \001(\t\022\024\n\tcrop_si"
+    "ze\030\005 \001(\r:\0010\022\025\n\006mirror\030\006 \001(\010:\005false\022\"\n\023fo"
+    "rce_encoded_color\030\t \001(\010:\005false\022\023\n\010prefet"
+    "ch\030\n \001(\r:\0014\"\033\n\002DB\022\013\n\007LEVELDB\020\000\022\010\n\004LMDB\020\001"
+    "\"[\n\036NonMaximumSuppressionParameter\022\032\n\rnm"
+    "s_threshold\030\001 \001(\002:\0030.3\022\r\n\005top_k\030\002 \001(\005\022\016\n"
+    "\003eta\030\003 \001(\002:\0011\"\252\001\n\023SaveOutputParameter\022\030\n"
+    "\020output_directory\030\001 \001(\t\022\032\n\022output_name_p"
+    "refix\030\002 \001(\t\022\025\n\routput_format\030\003 \001(\t\022\026\n\016la"
+    "bel_map_file\030\004 \001(\t\022\026\n\016name_size_file\030\005 \001"
+    "(\t\022\026\n\016num_test_image\030\006 \001(\r\"I\n\020DropoutPar"
+    "ameter\022\032\n\rdropout_ratio\030\001 \001(\002:\0030.5\022\031\n\013sc"
+    "ale_train\030\002 \001(\010:\004true\"\256\001\n\022DummyDataParam"
+    "eter\0222\n\013data_filler\030\001 \003(\0132\035.opencv_caffe"
+    ".FillerParameter\022&\n\005shape\030\006 \003(\0132\027.opencv"
+    "_caffe.BlobShape\022\013\n\003num\030\002 \003(\r\022\020\n\010channel"
+    "s\030\003 \003(\r\022\016\n\006height\030\004 \003(\r\022\r\n\005width\030\005 \003(\r\"\254"
+    "\001\n\020EltwiseParameter\022@\n\toperation\030\001 \001(\0162("
+    ".opencv_caffe.EltwiseParameter.EltwiseOp"
+    ":\003SUM\022\r\n\005coeff\030\002 \003(\002\022\036\n\020stable_prod_grad"
+    "\030\003 \001(\010:\004true\"\'\n\tEltwiseOp\022\010\n\004PROD\020\000\022\007\n\003S"
+    "UM\020\001\022\007\n\003MAX\020\002\" \n\014ELUParameter\022\020\n\005alpha\030\001"
+    " \001(\002:\0011\"\272\001\n\016EmbedParameter\022\022\n\nnum_output"
+    "\030\001 \001(\r\022\021\n\tinput_dim\030\002 \001(\r\022\027\n\tbias_term\030\003"
+    " \001(\010:\004true\0224\n\rweight_filler\030\004 \001(\0132\035.open"
+    "cv_caffe.FillerParameter\0222\n\013bias_filler\030"
+    "\005 \001(\0132\035.opencv_caffe.FillerParameter\"D\n\014"
+    "ExpParameter\022\020\n\004base\030\001 \001(\002:\002-1\022\020\n\005scale\030"
+    "\002 \001(\002:\0011\022\020\n\005shift\030\003 \001(\002:\0010\"9\n\020FlattenPar"
+    "ameter\022\017\n\004axis\030\001 \001(\005:\0011\022\024\n\010end_axis\030\002 \001("
+    "\005:\002-1\"O\n\021HDF5DataParameter\022\016\n\006source\030\001 \001"
+    "(\t\022\022\n\nbatch_size\030\002 \001(\r\022\026\n\007shuffle\030\003 \001(\010:"
+    "\005false\"(\n\023HDF5OutputParameter\022\021\n\tfile_na"
+    "me\030\001 \001(\t\"e\n\022HingeLossParameter\0227\n\004norm\030\001"
+    " \001(\0162%.opencv_caffe.HingeLossParameter.N"
+    "orm:\002L1\"\026\n\004Norm\022\006\n\002L1\020\001\022\006\n\002L2\020\002\"\227\002\n\022Imag"
+    "eDataParameter\022\016\n\006source\030\001 \001(\t\022\025\n\nbatch_"
+    "size\030\004 \001(\r:\0011\022\024\n\trand_skip\030\007 \001(\r:\0010\022\026\n\007s"
+    "huffle\030\010 \001(\010:\005false\022\025\n\nnew_height\030\t \001(\r:"
+    "\0010\022\024\n\tnew_width\030\n \001(\r:\0010\022\026\n\010is_color\030\013 \001"
+    "(\010:\004true\022\020\n\005scale\030\002 \001(\002:\0011\022\021\n\tmean_file\030"
+    "\003 \001(\t\022\024\n\tcrop_size\030\005 \001(\r:\0010\022\025\n\006mirror\030\006 "
+    "\001(\010:\005false\022\025\n\013root_folder\030\014 \001(\t:\000\"\'\n\025Inf"
+    "ogainLossParameter\022\016\n\006source\030\001 \001(\t\"\331\001\n\025I"
+    "nnerProductParameter\022\022\n\nnum_output\030\001 \001(\r"
+    "\022\027\n\tbias_term\030\002 \001(\010:\004true\0224\n\rweight_fill"
+    "er\030\003 \001(\0132\035.opencv_caffe.FillerParameter\022"
+    "2\n\013bias_filler\030\004 \001(\0132\035.opencv_caffe.Fill"
+    "erParameter\022\017\n\004axis\030\005 \001(\005:\0011\022\030\n\ttranspos"
+    "e\030\006 \001(\010:\005false\"8\n\016InputParameter\022&\n\005shap"
+    "e\030\001 \003(\0132\027.opencv_caffe.BlobShape\"D\n\014LogP"
+    "arameter\022\020\n\004base\030\001 \001(\002:\002-1\022\020\n\005scale\030\002 \001("
+    "\002:\0011\022\020\n\005shift\030\003 \001(\002:\0010\"\306\002\n\014LRNParameter\022"
+    "\025\n\nlocal_size\030\001 \001(\r:\0015\022\020\n\005alpha\030\002 \001(\002:\0011"
+    "\022\022\n\004beta\030\003 \001(\002:\0040.75\022K\n\013norm_region\030\004 \001("
+    "\0162%.opencv_caffe.LRNParameter.NormRegion"
+    ":\017ACROSS_CHANNELS\022\014\n\001k\030\005 \001(\002:\0011\022:\n\006engin"
+    "e\030\006 \001(\0162!.opencv_caffe.LRNParameter.Engi"
+    "ne:\007DEFAULT\"5\n\nNormRegion\022\023\n\017ACROSS_CHAN"
+    "NELS\020\000\022\022\n\016WITHIN_CHANNEL\020\001\"+\n\006Engine\022\013\n\007"
+    "DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"Z\n\023Memor"
+    "yDataParameter\022\022\n\nbatch_size\030\001 \001(\r\022\020\n\010ch"
+    "annels\030\002 \001(\r\022\016\n\006height\030\003 \001(\r\022\r\n\005width\030\004 "
+    "\001(\r\"d\n\014MVNParameter\022 \n\022normalize_varianc"
+    "e\030\001 \001(\010:\004true\022\036\n\017across_channels\030\002 \001(\010:\005"
+    "false\022\022\n\003eps\030\003 \001(\002:\0051e-09\"<\n\022ParameterPa"
+    "rameter\022&\n\005shape\030\001 \001(\0132\027.opencv_caffe.Bl"
+    "obShape\"\311\003\n\020PoolingParameter\022<\n\004pool\030\001 \001"
+    "(\0162).opencv_caffe.PoolingParameter.PoolM"
+    "ethod:\003MAX\022\016\n\003pad\030\004 \001(\r:\0010\022\020\n\005pad_h\030\t \001("
+    "\r:\0010\022\020\n\005pad_w\030\n \001(\r:\0010\022\023\n\013kernel_size\030\002 "
+    "\001(\r\022\020\n\010kernel_h\030\005 \001(\r\022\020\n\010kernel_w\030\006 \001(\r\022"
+    "\021\n\006stride\030\003 \001(\r:\0011\022\020\n\010stride_h\030\007 \001(\r\022\020\n\010"
+    "stride_w\030\010 \001(\r\022>\n\006engine\030\013 \001(\0162%.opencv_"
+    "caffe.PoolingParameter.Engine:\007DEFAULT\022\035"
+    "\n\016global_pooling\030\014 \001(\010:\005false\022\027\n\tceil_mo"
+    "de\030\r \001(\010:\004true\".\n\nPoolMethod\022\007\n\003MAX\020\000\022\007\n"
+    "\003AVE\020\001\022\016\n\nSTOCHASTIC\020\002\"+\n\006Engine\022\013\n\007DEFA"
+    "ULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"F\n\016PowerPara"
+    "meter\022\020\n\005power\030\001 \001(\002:\0011\022\020\n\005scale\030\002 \001(\002:\001"
+    "1\022\020\n\005shift\030\003 \001(\002:\0010\"g\n\017PythonParameter\022\016"
+    "\n\006module\030\001 \001(\t\022\r\n\005layer\030\002 \001(\t\022\023\n\tparam_s"
+    "tr\030\003 \001(\t:\000\022 \n\021share_in_parallel\030\004 \001(\010:\005f"
+    "alse\"\316\001\n\022RecurrentParameter\022\025\n\nnum_outpu"
+    "t\030\001 \001(\r:\0010\0224\n\rweight_filler\030\002 \001(\0132\035.open"
+    "cv_caffe.FillerParameter\0222\n\013bias_filler\030"
+    "\003 \001(\0132\035.opencv_caffe.FillerParameter\022\031\n\n"
+    "debug_info\030\004 \001(\010:\005false\022\034\n\rexpose_hidden"
+    "\030\005 \001(\010:\005false\"\264\001\n\022ReductionParameter\022D\n\t"
+    "operation\030\001 \001(\0162,.opencv_caffe.Reduction"
+    "Parameter.ReductionOp:\003SUM\022\017\n\004axis\030\002 \001(\005"
+    ":\0010\022\020\n\005coeff\030\003 \001(\002:\0011\"5\n\013ReductionOp\022\007\n\003"
+    "SUM\020\001\022\010\n\004ASUM\020\002\022\t\n\005SUMSQ\020\003\022\010\n\004MEAN\020\004\"\224\001\n"
+    "\rReLUParameter\022\031\n\016negative_slope\030\001 \001(\002:\001"
+    "0\022;\n\006engine\030\002 \001(\0162\".opencv_caffe.ReLUPar"
+    "ameter.Engine:\007DEFAULT\"+\n\006Engine\022\013\n\007DEFA"
+    "ULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"a\n\020ReshapePa"
+    "rameter\022&\n\005shape\030\001 \001(\0132\027.opencv_caffe.Bl"
+    "obShape\022\017\n\004axis\030\002 \001(\005:\0010\022\024\n\010num_axes\030\003 \001"
+    "(\005:\002-1\"\263\001\n\016ScaleParameter\022\017\n\004axis\030\001 \001(\005:"
+    "\0011\022\023\n\010num_axes\030\002 \001(\005:\0011\022-\n\006filler\030\003 \001(\0132"
+    "\035.opencv_caffe.FillerParameter\022\030\n\tbias_t"
+    "erm\030\004 \001(\010:\005false\0222\n\013bias_filler\030\005 \001(\0132\035."
+    "opencv_caffe.FillerParameter\"\177\n\020SigmoidP"
+    "arameter\022>\n\006engine\030\001 \001(\0162%.opencv_caffe."
+    "SigmoidParameter.Engine:\007DEFAULT\"+\n\006Engi"
+    "ne\022\013\n\007DEFAULT\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"L\n"
+    "\016SliceParameter\022\017\n\004axis\030\003 \001(\005:\0011\022\023\n\013slic"
+    "e_point\030\002 \003(\r\022\024\n\tslice_dim\030\001 \001(\r:\0011\"\220\001\n\020"
+    "SoftmaxParameter\022>\n\006engine\030\001 \001(\0162%.openc"
+    "v_caffe.SoftmaxParameter.Engine:\007DEFAULT"
+    "\022\017\n\004axis\030\002 \001(\005:\0011\"+\n\006Engine\022\013\n\007DEFAULT\020\000"
+    "\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"y\n\rTanHParameter\022"
+    ";\n\006engine\030\001 \001(\0162\".opencv_caffe.TanHParam"
+    "eter.Engine:\007DEFAULT\"+\n\006Engine\022\013\n\007DEFAUL"
+    "T\020\000\022\t\n\005CAFFE\020\001\022\t\n\005CUDNN\020\002\"/\n\rTileParamet"
+    "er\022\017\n\004axis\030\001 \001(\005:\0011\022\r\n\005tiles\030\002 \001(\005\"*\n\022Th"
+    "resholdParameter\022\024\n\tthreshold\030\001 \001(\002:\0010\"\301"
+    "\002\n\023WindowDataParameter\022\016\n\006source\030\001 \001(\t\022\020"
+    "\n\005scale\030\002 \001(\002:\0011\022\021\n\tmean_file\030\003 \001(\t\022\022\n\nb"
+    "atch_size\030\004 \001(\r\022\024\n\tcrop_size\030\005 \001(\r:\0010\022\025\n"
+    "\006mirror\030\006 \001(\010:\005false\022\031\n\014fg_threshold\030\007 \001"
+    "(\002:\0030.5\022\031\n\014bg_threshold\030\010 \001(\002:\0030.5\022\031\n\013fg"
+    "_fraction\030\t \001(\002:\0040.25\022\026\n\013context_pad\030\n \001"
+    "(\r:\0010\022\027\n\tcrop_mode\030\013 \001(\t:\004warp\022\033\n\014cache_"
+    "images\030\014 \001(\010:\005false\022\025\n\013root_folder\030\r \001(\t"
+    ":\000\"\371\001\n\014SPPParameter\022\026\n\016pyramid_height\030\001 "
+    "\001(\r\0228\n\004pool\030\002 \001(\0162%.opencv_caffe.SPPPara"
+    "meter.PoolMethod:\003MAX\022:\n\006engine\030\006 \001(\0162!."
+    "opencv_caffe.SPPParameter.Engine:\007DEFAUL"
+    "T\".\n\nPoolMethod\022\007\n\003MAX\020\000\022\007\n\003AVE\020\001\022\016\n\nSTO"
+    "CHASTIC\020\002\"+\n\006Engine\022\013\n\007DEFAULT\020\000\022\t\n\005CAFF"
+    "E\020\001\022\t\n\005CUDNN\020\002\"\334\025\n\020V1LayerParameter\022\016\n\006b"
+    "ottom\030\002 \003(\t\022\013\n\003top\030\003 \003(\t\022\014\n\004name\030\004 \001(\t\022+"
+    "\n\007include\030  \003(\0132\032.opencv_caffe.NetStateR"
+    "ule\022+\n\007exclude\030! \003(\0132\032.opencv_caffe.NetS"
+    "tateRule\0226\n\004type\030\005 \001(\0162(.opencv_caffe.V1"
+    "LayerParameter.LayerType\022&\n\005blobs\030\006 \003(\0132"
+    "\027.opencv_caffe.BlobProto\022\016\n\005param\030\351\007 \003(\t"
+    "\022E\n\017blob_share_mode\030\352\007 \003(\0162+.opencv_caff"
+    "e.V1LayerParameter.DimCheckMode\022\020\n\010blobs"
+    "_lr\030\007 \003(\002\022\024\n\014weight_decay\030\010 \003(\002\022\023\n\013loss_"
+    "weight\030# \003(\002\0227\n\016accuracy_param\030\033 \001(\0132\037.o"
+    "pencv_caffe.AccuracyParameter\0223\n\014argmax_"
+    "param\030\027 \001(\0132\035.opencv_caffe.ArgMaxParamet"
+    "er\0223\n\014concat_param\030\t \001(\0132\035.opencv_caffe."
+    "ConcatParameter\022F\n\026contrastive_loss_para"
+    "m\030( \001(\0132&.opencv_caffe.ContrastiveLossPa"
+    "rameter\022=\n\021convolution_param\030\n \001(\0132\".ope"
+    "ncv_caffe.ConvolutionParameter\022/\n\ndata_p"
+    "aram\030\013 \001(\0132\033.opencv_caffe.DataParameter\022"
+    "5\n\rdropout_param\030\014 \001(\0132\036.opencv_caffe.Dr"
+    "opoutParameter\022:\n\020dummy_data_param\030\032 \001(\013"
+    "2 .opencv_caffe.DummyDataParameter\0225\n\rel"
+    "twise_param\030\030 \001(\0132\036.opencv_caffe.Eltwise"
+    "Parameter\022-\n\texp_param\030) \001(\0132\032.opencv_ca"
+    "ffe.ExpParameter\0228\n\017hdf5_data_param\030\r \001("
+    "\0132\037.opencv_caffe.HDF5DataParameter\022<\n\021hd"
+    "f5_output_param\030\016 \001(\0132!.opencv_caffe.HDF"
+    "5OutputParameter\022:\n\020hinge_loss_param\030\035 \001"
+    "(\0132 .opencv_caffe.HingeLossParameter\022:\n\020"
+    "image_data_param\030\017 \001(\0132 .opencv_caffe.Im"
+    "ageDataParameter\022@\n\023infogain_loss_param\030"
+    "\020 \001(\0132#.opencv_caffe.InfogainLossParamet"
+    "er\022@\n\023inner_product_param\030\021 \001(\0132#.opencv"
+    "_caffe.InnerProductParameter\022-\n\tlrn_para"
+    "m\030\022 \001(\0132\032.opencv_caffe.LRNParameter\022<\n\021m"
+    "emory_data_param\030\026 \001(\0132!.opencv_caffe.Me"
+    "moryDataParameter\022-\n\tmvn_param\030\" \001(\0132\032.o"
+    "pencv_caffe.MVNParameter\0225\n\rpooling_para"
+    "m\030\023 \001(\0132\036.opencv_caffe.PoolingParameter\022"
+    "1\n\013power_param\030\025 \001(\0132\034.opencv_caffe.Powe"
+    "rParameter\022/\n\nrelu_param\030\036 \001(\0132\033.opencv_"
+    "caffe.ReLUParameter\0225\n\rsigmoid_param\030& \001"
+    "(\0132\036.opencv_caffe.SigmoidParameter\0225\n\rso"
+    "ftmax_param\030\' \001(\0132\036.opencv_caffe.Softmax"
+    "Parameter\0221\n\013slice_param\030\037 \001(\0132\034.opencv_"
+    "caffe.SliceParameter\022/\n\ntanh_param\030% \001(\013"
+    "2\033.opencv_caffe.TanHParameter\0229\n\017thresho"
+    "ld_param\030\031 \001(\0132 .opencv_caffe.ThresholdP"
+    "arameter\022<\n\021window_data_param\030\024 \001(\0132!.op"
+    "encv_caffe.WindowDataParameter\022>\n\017transf"
+    "orm_param\030$ \001(\0132%.opencv_caffe.Transform"
+    "ationParameter\022/\n\nloss_param\030* \001(\0132\033.ope"
+    "ncv_caffe.LossParameter\022-\n\005layer\030\001 \001(\0132\036"
+    ".opencv_caffe.V0LayerParameter\"\330\004\n\tLayer"
+    "Type\022\010\n\004NONE\020\000\022\n\n\006ABSVAL\020#\022\014\n\010ACCURACY\020\001"
+    "\022\n\n\006ARGMAX\020\036\022\010\n\004BNLL\020\002\022\n\n\006CONCAT\020\003\022\024\n\020CO"
+    "NTRASTIVE_LOSS\020%\022\017\n\013CONVOLUTION\020\004\022\010\n\004DAT"
+    "A\020\005\022\021\n\rDECONVOLUTION\020\'\022\013\n\007DROPOUT\020\006\022\016\n\nD"
+    "UMMY_DATA\020 \022\022\n\016EUCLIDEAN_LOSS\020\007\022\013\n\007ELTWI"
+    "SE\020\031\022\007\n\003EXP\020&\022\013\n\007FLATTEN\020\010\022\r\n\tHDF5_DATA\020"
+    "\t\022\017\n\013HDF5_OUTPUT\020\n\022\016\n\nHINGE_LOSS\020\034\022\n\n\006IM"
+    "2COL\020\013\022\016\n\nIMAGE_DATA\020\014\022\021\n\rINFOGAIN_LOSS\020"
+    "\r\022\021\n\rINNER_PRODUCT\020\016\022\007\n\003LRN\020\017\022\017\n\013MEMORY_"
+    "DATA\020\035\022\035\n\031MULTINOMIAL_LOGISTIC_LOSS\020\020\022\007\n"
+    "\003MVN\020\"\022\013\n\007POOLING\020\021\022\t\n\005POWER\020\032\022\010\n\004RELU\020\022"
+    "\022\013\n\007SIGMOID\020\023\022\036\n\032SIGMOID_CROSS_ENTROPY_L"
+    "OSS\020\033\022\013\n\007SILENCE\020$\022\013\n\007SOFTMAX\020\024\022\020\n\014SOFTM"
+    "AX_LOSS\020\025\022\t\n\005SPLIT\020\026\022\t\n\005SLICE\020!\022\010\n\004TANH\020"
+    "\027\022\017\n\013WINDOW_DATA\020\030\022\r\n\tTHRESHOLD\020\037\"*\n\014Dim"
+    "CheckMode\022\n\n\006STRICT\020\000\022\016\n\nPERMISSIVE\020\001\"\240\010"
+    "\n\020V0LayerParameter\022\014\n\004name\030\001 \001(\t\022\014\n\004type"
+    "\030\002 \001(\t\022\022\n\nnum_output\030\003 \001(\r\022\026\n\010biasterm\030\004"
+    " \001(\010:\004true\0224\n\rweight_filler\030\005 \001(\0132\035.open"
+    "cv_caffe.FillerParameter\0222\n\013bias_filler\030"
+    "\006 \001(\0132\035.opencv_caffe.FillerParameter\022\016\n\003"
+    "pad\030\007 \001(\r:\0010\022\022\n\nkernelsize\030\010 \001(\r\022\020\n\005grou"
+    "p\030\t \001(\r:\0011\022\021\n\006stride\030\n \001(\r:\0011\022<\n\004pool\030\013 "
+    "\001(\0162).opencv_caffe.V0LayerParameter.Pool"
+    "Method:\003MAX\022\032\n\rdropout_ratio\030\014 \001(\002:\0030.5\022"
+    "\025\n\nlocal_size\030\r \001(\r:\0015\022\020\n\005alpha\030\016 \001(\002:\0011"
+    "\022\022\n\004beta\030\017 \001(\002:\0040.75\022\014\n\001k\030\026 \001(\002:\0011\022\016\n\006so"
+    "urce\030\020 \001(\t\022\020\n\005scale\030\021 \001(\002:\0011\022\020\n\010meanfile"
+    "\030\022 \001(\t\022\021\n\tbatchsize\030\023 \001(\r\022\023\n\010cropsize\030\024 "
+    "\001(\r:\0010\022\025\n\006mirror\030\025 \001(\010:\005false\022&\n\005blobs\0302"
+    " \003(\0132\027.opencv_caffe.BlobProto\022\020\n\010blobs_l"
+    "r\0303 \003(\002\022\024\n\014weight_decay\0304 \003(\002\022\024\n\trand_sk"
+    "ip\0305 \001(\r:\0010\022\035\n\020det_fg_threshold\0306 \001(\002:\0030"
+    ".5\022\035\n\020det_bg_threshold\0307 \001(\002:\0030.5\022\035\n\017det"
+    "_fg_fraction\0308 \001(\002:\0040.25\022\032\n\017det_context_"
+    "pad\030: \001(\r:\0010\022\033\n\rdet_crop_mode\030; \001(\t:\004war"
+    "p\022\022\n\007new_num\030< \001(\005:\0010\022\027\n\014new_channels\030= "
+    "\001(\005:\0010\022\025\n\nnew_height\030> \001(\005:\0010\022\024\n\tnew_wid"
+    "th\030\? \001(\005:\0010\022\035\n\016shuffle_images\030@ \001(\010:\005fal"
+    "se\022\025\n\nconcat_dim\030A \001(\r:\0011\022=\n\021hdf5_output"
+    "_param\030\351\007 \001(\0132!.opencv_caffe.HDF5OutputP"
+    "arameter\".\n\nPoolMethod\022\007\n\003MAX\020\000\022\007\n\003AVE\020\001"
+    "\022\016\n\nSTOCHASTIC\020\002\"^\n\016PReLUParameter\022-\n\006fi"
+    "ller\030\001 \001(\0132\035.opencv_caffe.FillerParamete"
+    "r\022\035\n\016channel_shared\030\002 \001(\010:\005false\"\207\001\n\016Nor"
+    "malizedBBox\022\014\n\004xmin\030\001 \001(\002\022\014\n\004ymin\030\002 \001(\002\022"
+    "\014\n\004xmax\030\003 \001(\002\022\014\n\004ymax\030\004 \001(\002\022\r\n\005label\030\005 \001"
+    "(\005\022\021\n\tdifficult\030\006 \001(\010\022\r\n\005score\030\007 \001(\002\022\014\n\004"
+    "size\030\010 \001(\002\"Y\n\023ROIPoolingParameter\022\023\n\010poo"
+    "led_h\030\001 \001(\r:\0010\022\023\n\010pooled_w\030\002 \001(\r:\0010\022\030\n\rs"
+    "patial_scale\030\003 \001(\002:\0011\"\310\001\n\021ProposalParame"
+    "ter\022\027\n\013feat_stride\030\001 \001(\r:\00216\022\025\n\tbase_siz"
+    "e\030\002 \001(\r:\00216\022\024\n\010min_size\030\003 \001(\r:\00216\022\r\n\005rat"
+    "io\030\004 \003(\002\022\r\n\005scale\030\005 \003(\002\022\032\n\014pre_nms_topn\030"
+    "\006 \001(\r:\0046000\022\032\n\rpost_nms_topn\030\007 \001(\r:\003300\022"
+    "\027\n\nnms_thresh\030\010 \001(\002:\0030.7\"V\n\025PSROIPooling"
+    "Parameter\022\025\n\rspatial_scale\030\001 \002(\002\022\022\n\noutp"
+    "ut_dim\030\002 \002(\005\022\022\n\ngroup_size\030\003 \002(\005*=\n\004Type"
+    "\022\n\n\006DOUBLE\020\000\022\t\n\005FLOAT\020\001\022\013\n\007FLOAT16\020\002\022\007\n\003"
+    "INT\020\003\022\010\n\004UINT\020\004*\034\n\005Phase\022\t\n\005TRAIN\020\000\022\010\n\004T"
+    "EST\020\001", 18805);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "opencv-caffe.proto", &protobuf_RegisterTypes);
   ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_opencv_2dcaffe_2eproto);
@@ -6602,6 +6634,7 @@ const int DetectionOutputParameter::kCodeTypeFieldNumber;
 const int DetectionOutputParameter::kVarianceEncodedInTargetFieldNumber;
 const int DetectionOutputParameter::kKeepTopKFieldNumber;
 const int DetectionOutputParameter::kConfidenceThresholdFieldNumber;
+const int DetectionOutputParameter::kNormalizedBboxFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 DetectionOutputParameter::DetectionOutputParameter()
@@ -6633,8 +6666,9 @@ void DetectionOutputParameter::SharedCtor() {
   ::memset(&num_classes_, 0, reinterpret_cast<char*>(&confidence_threshold_) -
     reinterpret_cast<char*>(&num_classes_) + sizeof(confidence_threshold_));
   keep_top_k_ = -1;
-  share_location_ = true;
   code_type_ = 1;
+  share_location_ = true;
+  normalized_bbox_ = true;
 }
 
 DetectionOutputParameter::~DetectionOutputParameter() {
@@ -6704,7 +6738,10 @@ void DetectionOutputParameter::Clear() {
     code_type_ = 1;
     keep_top_k_ = -1;
   }
-  confidence_threshold_ = 0;
+  if (_has_bits_[8 / 32] & 768u) {
+    confidence_threshold_ = 0;
+    normalized_bbox_ = true;
+  }
 
 #undef ZR_HELPER_
 #undef ZR_
@@ -6856,6 +6893,21 @@ bool DetectionOutputParameter::MergePartialFromCodedStream(
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(80)) goto parse_normalized_bbox;
+        break;
+      }
+
+      // optional bool normalized_bbox = 10 [default = true];
+      case 10: {
+        if (tag == 80) {
+         parse_normalized_bbox:
+          set_has_normalized_bbox();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &normalized_bbox_)));
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectAtEnd()) goto success;
         break;
       }
@@ -6933,6 +6985,11 @@ void DetectionOutputParameter::SerializeWithCachedSizes(
     ::google::protobuf::internal::WireFormatLite::WriteFloat(9, this->confidence_threshold(), output);
   }
 
+  // optional bool normalized_bbox = 10 [default = true];
+  if (has_normalized_bbox()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->normalized_bbox(), output);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
@@ -6994,6 +7051,11 @@ void DetectionOutputParameter::SerializeWithCachedSizes(
     target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(9, this->confidence_threshold(), target);
   }
 
+  // optional bool normalized_bbox = 10 [default = true];
+  if (has_normalized_bbox()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->normalized_bbox(), target);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
@@ -7059,11 +7121,18 @@ size_t DetectionOutputParameter::ByteSizeLong() const {
     }
 
   }
-  // optional float confidence_threshold = 9;
-  if (has_confidence_threshold()) {
-    total_size += 1 + 4;
-  }
+  if (_has_bits_[8 / 32] & 768u) {
+    // optional float confidence_threshold = 9;
+    if (has_confidence_threshold()) {
+      total_size += 1 + 4;
+    }
 
+    // optional bool normalized_bbox = 10 [default = true];
+    if (has_normalized_bbox()) {
+      total_size += 1 + 1;
+    }
+
+  }
   if (_internal_metadata_.have_unknown_fields()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -7132,6 +7201,9 @@ void DetectionOutputParameter::UnsafeMergeFrom(const DetectionOutputParameter& f
     if (from.has_confidence_threshold()) {
       set_confidence_threshold(from.confidence_threshold());
     }
+    if (from.has_normalized_bbox()) {
+      set_normalized_bbox(from.normalized_bbox());
+    }
   }
   if (from._internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::UnknownFieldSet::MergeToInternalMetdata(
@@ -7172,6 +7244,7 @@ void DetectionOutputParameter::InternalSwap(DetectionOutputParameter* other) {
   std::swap(variance_encoded_in_target_, other->variance_encoded_in_target_);
   std::swap(keep_top_k_, other->keep_top_k_);
   std::swap(confidence_threshold_, other->confidence_threshold_);
+  std::swap(normalized_bbox_, other->normalized_bbox_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -7447,6 +7520,30 @@ void DetectionOutputParameter::set_confidence_threshold(float value) {
   // @@protoc_insertion_point(field_set:opencv_caffe.DetectionOutputParameter.confidence_threshold)
 }
 
+// optional bool normalized_bbox = 10 [default = true];
+bool DetectionOutputParameter::has_normalized_bbox() const {
+  return (_has_bits_[0] & 0x00000200u) != 0;
+}
+void DetectionOutputParameter::set_has_normalized_bbox() {
+  _has_bits_[0] |= 0x00000200u;
+}
+void DetectionOutputParameter::clear_has_normalized_bbox() {
+  _has_bits_[0] &= ~0x00000200u;
+}
+void DetectionOutputParameter::clear_normalized_bbox() {
+  normalized_bbox_ = true;
+  clear_has_normalized_bbox();
+}
+bool DetectionOutputParameter::normalized_bbox() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.DetectionOutputParameter.normalized_bbox)
+  return normalized_bbox_;
+}
+void DetectionOutputParameter::set_normalized_bbox(bool value) {
+  set_has_normalized_bbox();
+  normalized_bbox_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.DetectionOutputParameter.normalized_bbox)
+}
+
 inline const DetectionOutputParameter* DetectionOutputParameter::internal_default_instance() {
   return &DetectionOutputParameter_default_instance_.get();
 }
@@ -9589,6 +9686,7 @@ void NetParameter::CopyFrom(const NetParameter& from) {
 
 bool NetParameter::IsInitialized() const {
 
+  if (!::google::protobuf::internal::AllAreInitialized(this->layer())) return false;
   return true;
 }
 
@@ -11910,6 +12008,13 @@ void SolverParameter::CopyFrom(const SolverParameter& from) {
 
 bool SolverParameter::IsInitialized() const {
 
+  if (has_net_param()) {
+    if (!this->net_param_->IsInitialized()) return false;
+  }
+  if (has_train_net_param()) {
+    if (!this->train_net_param_->IsInitialized()) return false;
+  }
+  if (!::google::protobuf::internal::AllAreInitialized(this->test_net_param())) return false;
   return true;
 }
 
@@ -15488,6 +15593,7 @@ const int LayerParameter::kPowerParamFieldNumber;
 const int LayerParameter::kPreluParamFieldNumber;
 const int LayerParameter::kPriorBoxParamFieldNumber;
 const int LayerParameter::kProposalParamFieldNumber;
+const int LayerParameter::kPsroiPoolingParamFieldNumber;
 const int LayerParameter::kPythonParamFieldNumber;
 const int LayerParameter::kRecurrentParamFieldNumber;
 const int LayerParameter::kReductionParamFieldNumber;
@@ -15589,6 +15695,8 @@ void LayerParameter::InitAsDefaultInstance() {
       ::opencv_caffe::PriorBoxParameter::internal_default_instance());
   proposal_param_ = const_cast< ::opencv_caffe::ProposalParameter*>(
       ::opencv_caffe::ProposalParameter::internal_default_instance());
+  psroi_pooling_param_ = const_cast< ::opencv_caffe::PSROIPoolingParameter*>(
+      ::opencv_caffe::PSROIPoolingParameter::internal_default_instance());
   python_param_ = const_cast< ::opencv_caffe::PythonParameter*>(
       ::opencv_caffe::PythonParameter::internal_default_instance());
   recurrent_param_ = const_cast< ::opencv_caffe::RecurrentParameter*>(
@@ -15630,6 +15738,7 @@ LayerParameter::LayerParameter(const LayerParameter& from)
 }
 
 void LayerParameter::SharedCtor() {
+  _cached_size_ = 0;
   name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   transform_param_ = NULL;
@@ -15670,6 +15779,7 @@ void LayerParameter::SharedCtor() {
   prelu_param_ = NULL;
   prior_box_param_ = NULL;
   proposal_param_ = NULL;
+  psroi_pooling_param_ = NULL;
   python_param_ = NULL;
   recurrent_param_ = NULL;
   reduction_param_ = NULL;
@@ -15686,7 +15796,6 @@ void LayerParameter::SharedCtor() {
   tile_param_ = NULL;
   window_data_param_ = NULL;
   phase_ = 0;
-  _cached_size_ = 0;
 }
 
 LayerParameter::~LayerParameter() {
@@ -15736,6 +15845,7 @@ void LayerParameter::SharedDtor() {
     delete prelu_param_;
     delete prior_box_param_;
     delete proposal_param_;
+    delete psroi_pooling_param_;
     delete python_param_;
     delete recurrent_param_;
     delete reduction_param_;
@@ -15915,6 +16025,9 @@ void LayerParameter::Clear() {
     if (has_proposal_param()) {
       if (proposal_param_ != NULL) proposal_param_->::opencv_caffe::ProposalParameter::Clear();
     }
+    if (has_psroi_pooling_param()) {
+      if (psroi_pooling_param_ != NULL) psroi_pooling_param_->::opencv_caffe::PSROIPoolingParameter::Clear();
+    }
     if (has_python_param()) {
       if (python_param_ != NULL) python_param_->::opencv_caffe::PythonParameter::Clear();
     }
@@ -15933,11 +16046,11 @@ void LayerParameter::Clear() {
     if (has_roi_pooling_param()) {
       if (roi_pooling_param_ != NULL) roi_pooling_param_->::opencv_caffe::ROIPoolingParameter::Clear();
     }
+  }
+  if (_has_bits_[56 / 32] & 4278190080u) {
     if (has_scale_param()) {
       if (scale_param_ != NULL) scale_param_->::opencv_caffe::ScaleParameter::Clear();
     }
-  }
-  if (_has_bits_[56 / 32] & 4278190080u) {
     if (has_sigmoid_param()) {
       if (sigmoid_param_ != NULL) sigmoid_param_->::opencv_caffe::SigmoidParameter::Clear();
     }
@@ -15959,9 +16072,9 @@ void LayerParameter::Clear() {
     if (has_tile_param()) {
       if (tile_param_ != NULL) tile_param_->::opencv_caffe::TileParameter::Clear();
     }
-    if (has_window_data_param()) {
-      if (window_data_param_ != NULL) window_data_param_->::opencv_caffe::WindowDataParameter::Clear();
-    }
+  }
+  if (has_window_data_param()) {
+    if (window_data_param_ != NULL) window_data_param_->::opencv_caffe::WindowDataParameter::Clear();
   }
   bottom_.Clear();
   top_.Clear();
@@ -16853,6 +16966,19 @@ bool LayerParameter::MergePartialFromCodedStream(
         } else {
           goto handle_unusual;
         }
+        if (input->ExpectTag(80010)) goto parse_psroi_pooling_param;
+        break;
+      }
+
+      // optional .opencv_caffe.PSROIPoolingParameter psroi_pooling_param = 10001;
+      case 10001: {
+        if (tag == 80010) {
+         parse_psroi_pooling_param:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_psroi_pooling_param()));
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectTag(66133690)) goto parse_roi_pooling_param;
         break;
       }
@@ -17289,6 +17415,12 @@ void LayerParameter::SerializeWithCachedSizes(
       201, *this->proposal_param_, output);
   }
 
+  // optional .opencv_caffe.PSROIPoolingParameter psroi_pooling_param = 10001;
+  if (has_psroi_pooling_param()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      10001, *this->psroi_pooling_param_, output);
+  }
+
   // optional .opencv_caffe.ROIPoolingParameter roi_pooling_param = 8266711;
   if (has_roi_pooling_param()) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -17758,6 +17890,13 @@ void LayerParameter::SerializeWithCachedSizes(
         201, *this->proposal_param_, false, target);
   }
 
+  // optional .opencv_caffe.PSROIPoolingParameter psroi_pooling_param = 10001;
+  if (has_psroi_pooling_param()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageNoVirtualToArray(
+        10001, *this->psroi_pooling_param_, false, target);
+  }
+
   // optional .opencv_caffe.ROIPoolingParameter roi_pooling_param = 8266711;
   if (has_roi_pooling_param()) {
     target = ::google::protobuf::internal::WireFormatLite::
@@ -18076,6 +18215,13 @@ size_t LayerParameter::ByteSizeLong() const {
           *this->proposal_param_);
     }
 
+    // optional .opencv_caffe.PSROIPoolingParameter psroi_pooling_param = 10001;
+    if (has_psroi_pooling_param()) {
+      total_size += 3 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          *this->psroi_pooling_param_);
+    }
+
     // optional .opencv_caffe.PythonParameter python_param = 130;
     if (has_python_param()) {
       total_size += 2 +
@@ -18118,6 +18264,8 @@ size_t LayerParameter::ByteSizeLong() const {
           *this->roi_pooling_param_);
     }
 
+  }
+  if (_has_bits_[56 / 32] & 4278190080u) {
     // optional .opencv_caffe.ScaleParameter scale_param = 142;
     if (has_scale_param()) {
       total_size += 2 +
@@ -18125,8 +18273,6 @@ size_t LayerParameter::ByteSizeLong() const {
           *this->scale_param_);
     }
 
-  }
-  if (_has_bits_[56 / 32] & 4278190080u) {
     // optional .opencv_caffe.SigmoidParameter sigmoid_param = 124;
     if (has_sigmoid_param()) {
       total_size += 2 +
@@ -18176,14 +18322,14 @@ size_t LayerParameter::ByteSizeLong() const {
           *this->tile_param_);
     }
 
-    // optional .opencv_caffe.WindowDataParameter window_data_param = 129;
-    if (has_window_data_param()) {
-      total_size += 2 +
-        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
-          *this->window_data_param_);
-    }
-
   }
+  // optional .opencv_caffe.WindowDataParameter window_data_param = 129;
+  if (has_window_data_param()) {
+    total_size += 2 +
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        *this->window_data_param_);
+  }
+
   // repeated string bottom = 3;
   total_size += 1 *
       ::google::protobuf::internal::FromIntSize(this->bottom_size());
@@ -18448,6 +18594,9 @@ void LayerParameter::UnsafeMergeFrom(const LayerParameter& from) {
     if (from.has_proposal_param()) {
       mutable_proposal_param()->::opencv_caffe::ProposalParameter::MergeFrom(from.proposal_param());
     }
+    if (from.has_psroi_pooling_param()) {
+      mutable_psroi_pooling_param()->::opencv_caffe::PSROIPoolingParameter::MergeFrom(from.psroi_pooling_param());
+    }
     if (from.has_python_param()) {
       mutable_python_param()->::opencv_caffe::PythonParameter::MergeFrom(from.python_param());
     }
@@ -18466,11 +18615,11 @@ void LayerParameter::UnsafeMergeFrom(const LayerParameter& from) {
     if (from.has_roi_pooling_param()) {
       mutable_roi_pooling_param()->::opencv_caffe::ROIPoolingParameter::MergeFrom(from.roi_pooling_param());
     }
+  }
+  if (from._has_bits_[56 / 32] & (0xffu << (56 % 32))) {
     if (from.has_scale_param()) {
       mutable_scale_param()->::opencv_caffe::ScaleParameter::MergeFrom(from.scale_param());
     }
-  }
-  if (from._has_bits_[56 / 32] & (0xffu << (56 % 32))) {
     if (from.has_sigmoid_param()) {
       mutable_sigmoid_param()->::opencv_caffe::SigmoidParameter::MergeFrom(from.sigmoid_param());
     }
@@ -18492,6 +18641,8 @@ void LayerParameter::UnsafeMergeFrom(const LayerParameter& from) {
     if (from.has_tile_param()) {
       mutable_tile_param()->::opencv_caffe::TileParameter::MergeFrom(from.tile_param());
     }
+  }
+  if (from._has_bits_[64 / 32] & (0xffu << (64 % 32))) {
     if (from.has_window_data_param()) {
       mutable_window_data_param()->::opencv_caffe::WindowDataParameter::MergeFrom(from.window_data_param());
     }
@@ -18518,6 +18669,9 @@ void LayerParameter::CopyFrom(const LayerParameter& from) {
 
 bool LayerParameter::IsInitialized() const {
 
+  if (has_psroi_pooling_param()) {
+    if (!this->psroi_pooling_param_->IsInitialized()) return false;
+  }
   return true;
 }
 
@@ -18575,6 +18729,7 @@ void LayerParameter::InternalSwap(LayerParameter* other) {
   std::swap(prelu_param_, other->prelu_param_);
   std::swap(prior_box_param_, other->prior_box_param_);
   std::swap(proposal_param_, other->proposal_param_);
+  std::swap(psroi_pooling_param_, other->psroi_pooling_param_);
   std::swap(python_param_, other->python_param_);
   std::swap(recurrent_param_, other->recurrent_param_);
   std::swap(reduction_param_, other->reduction_param_);
@@ -18592,6 +18747,7 @@ void LayerParameter::InternalSwap(LayerParameter* other) {
   std::swap(window_data_param_, other->window_data_param_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   std::swap(_has_bits_[1], other->_has_bits_[1]);
+  std::swap(_has_bits_[2], other->_has_bits_[2]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
 }
@@ -20740,15 +20896,60 @@ void LayerParameter::set_allocated_proposal_param(::opencv_caffe::ProposalParame
   // @@protoc_insertion_point(field_set_allocated:opencv_caffe.LayerParameter.proposal_param)
 }
 
+// optional .opencv_caffe.PSROIPoolingParameter psroi_pooling_param = 10001;
+bool LayerParameter::has_psroi_pooling_param() const {
+  return (_has_bits_[1] & 0x00020000u) != 0;
+}
+void LayerParameter::set_has_psroi_pooling_param() {
+  _has_bits_[1] |= 0x00020000u;
+}
+void LayerParameter::clear_has_psroi_pooling_param() {
+  _has_bits_[1] &= ~0x00020000u;
+}
+void LayerParameter::clear_psroi_pooling_param() {
+  if (psroi_pooling_param_ != NULL) psroi_pooling_param_->::opencv_caffe::PSROIPoolingParameter::Clear();
+  clear_has_psroi_pooling_param();
+}
+const ::opencv_caffe::PSROIPoolingParameter& LayerParameter::psroi_pooling_param() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.LayerParameter.psroi_pooling_param)
+  return psroi_pooling_param_ != NULL ? *psroi_pooling_param_
+                         : *::opencv_caffe::PSROIPoolingParameter::internal_default_instance();
+}
+::opencv_caffe::PSROIPoolingParameter* LayerParameter::mutable_psroi_pooling_param() {
+  set_has_psroi_pooling_param();
+  if (psroi_pooling_param_ == NULL) {
+    psroi_pooling_param_ = new ::opencv_caffe::PSROIPoolingParameter;
+  }
+  // @@protoc_insertion_point(field_mutable:opencv_caffe.LayerParameter.psroi_pooling_param)
+  return psroi_pooling_param_;
+}
+::opencv_caffe::PSROIPoolingParameter* LayerParameter::release_psroi_pooling_param() {
+  // @@protoc_insertion_point(field_release:opencv_caffe.LayerParameter.psroi_pooling_param)
+  clear_has_psroi_pooling_param();
+  ::opencv_caffe::PSROIPoolingParameter* temp = psroi_pooling_param_;
+  psroi_pooling_param_ = NULL;
+  return temp;
+}
+void LayerParameter::set_allocated_psroi_pooling_param(::opencv_caffe::PSROIPoolingParameter* psroi_pooling_param) {
+  delete psroi_pooling_param_;
+  psroi_pooling_param_ = psroi_pooling_param;
+  if (psroi_pooling_param) {
+    set_has_psroi_pooling_param();
+  } else {
+    clear_has_psroi_pooling_param();
+  }
+  // @@protoc_insertion_point(field_set_allocated:opencv_caffe.LayerParameter.psroi_pooling_param)
+}
+
 // optional .opencv_caffe.PythonParameter python_param = 130;
 bool LayerParameter::has_python_param() const {
-  return (_has_bits_[1] & 0x00020000u) != 0;
+  return (_has_bits_[1] & 0x00040000u) != 0;
 }
 void LayerParameter::set_has_python_param() {
-  _has_bits_[1] |= 0x00020000u;
+  _has_bits_[1] |= 0x00040000u;
 }
 void LayerParameter::clear_has_python_param() {
-  _has_bits_[1] &= ~0x00020000u;
+  _has_bits_[1] &= ~0x00040000u;
 }
 void LayerParameter::clear_python_param() {
   if (python_param_ != NULL) python_param_->::opencv_caffe::PythonParameter::Clear();
@@ -20787,13 +20988,13 @@ void LayerParameter::set_allocated_python_param(::opencv_caffe::PythonParameter*
 
 // optional .opencv_caffe.RecurrentParameter recurrent_param = 146;
 bool LayerParameter::has_recurrent_param() const {
-  return (_has_bits_[1] & 0x00040000u) != 0;
+  return (_has_bits_[1] & 0x00080000u) != 0;
 }
 void LayerParameter::set_has_recurrent_param() {
-  _has_bits_[1] |= 0x00040000u;
+  _has_bits_[1] |= 0x00080000u;
 }
 void LayerParameter::clear_has_recurrent_param() {
-  _has_bits_[1] &= ~0x00040000u;
+  _has_bits_[1] &= ~0x00080000u;
 }
 void LayerParameter::clear_recurrent_param() {
   if (recurrent_param_ != NULL) recurrent_param_->::opencv_caffe::RecurrentParameter::Clear();
@@ -20832,13 +21033,13 @@ void LayerParameter::set_allocated_recurrent_param(::opencv_caffe::RecurrentPara
 
 // optional .opencv_caffe.ReductionParameter reduction_param = 136;
 bool LayerParameter::has_reduction_param() const {
-  return (_has_bits_[1] & 0x00080000u) != 0;
+  return (_has_bits_[1] & 0x00100000u) != 0;
 }
 void LayerParameter::set_has_reduction_param() {
-  _has_bits_[1] |= 0x00080000u;
+  _has_bits_[1] |= 0x00100000u;
 }
 void LayerParameter::clear_has_reduction_param() {
-  _has_bits_[1] &= ~0x00080000u;
+  _has_bits_[1] &= ~0x00100000u;
 }
 void LayerParameter::clear_reduction_param() {
   if (reduction_param_ != NULL) reduction_param_->::opencv_caffe::ReductionParameter::Clear();
@@ -20877,13 +21078,13 @@ void LayerParameter::set_allocated_reduction_param(::opencv_caffe::ReductionPara
 
 // optional .opencv_caffe.ReLUParameter relu_param = 123;
 bool LayerParameter::has_relu_param() const {
-  return (_has_bits_[1] & 0x00100000u) != 0;
+  return (_has_bits_[1] & 0x00200000u) != 0;
 }
 void LayerParameter::set_has_relu_param() {
-  _has_bits_[1] |= 0x00100000u;
+  _has_bits_[1] |= 0x00200000u;
 }
 void LayerParameter::clear_has_relu_param() {
-  _has_bits_[1] &= ~0x00100000u;
+  _has_bits_[1] &= ~0x00200000u;
 }
 void LayerParameter::clear_relu_param() {
   if (relu_param_ != NULL) relu_param_->::opencv_caffe::ReLUParameter::Clear();
@@ -20922,13 +21123,13 @@ void LayerParameter::set_allocated_relu_param(::opencv_caffe::ReLUParameter* rel
 
 // optional .opencv_caffe.ReshapeParameter reshape_param = 133;
 bool LayerParameter::has_reshape_param() const {
-  return (_has_bits_[1] & 0x00200000u) != 0;
+  return (_has_bits_[1] & 0x00400000u) != 0;
 }
 void LayerParameter::set_has_reshape_param() {
-  _has_bits_[1] |= 0x00200000u;
+  _has_bits_[1] |= 0x00400000u;
 }
 void LayerParameter::clear_has_reshape_param() {
-  _has_bits_[1] &= ~0x00200000u;
+  _has_bits_[1] &= ~0x00400000u;
 }
 void LayerParameter::clear_reshape_param() {
   if (reshape_param_ != NULL) reshape_param_->::opencv_caffe::ReshapeParameter::Clear();
@@ -20967,13 +21168,13 @@ void LayerParameter::set_allocated_reshape_param(::opencv_caffe::ReshapeParamete
 
 // optional .opencv_caffe.ROIPoolingParameter roi_pooling_param = 8266711;
 bool LayerParameter::has_roi_pooling_param() const {
-  return (_has_bits_[1] & 0x00400000u) != 0;
+  return (_has_bits_[1] & 0x00800000u) != 0;
 }
 void LayerParameter::set_has_roi_pooling_param() {
-  _has_bits_[1] |= 0x00400000u;
+  _has_bits_[1] |= 0x00800000u;
 }
 void LayerParameter::clear_has_roi_pooling_param() {
-  _has_bits_[1] &= ~0x00400000u;
+  _has_bits_[1] &= ~0x00800000u;
 }
 void LayerParameter::clear_roi_pooling_param() {
   if (roi_pooling_param_ != NULL) roi_pooling_param_->::opencv_caffe::ROIPoolingParameter::Clear();
@@ -21012,13 +21213,13 @@ void LayerParameter::set_allocated_roi_pooling_param(::opencv_caffe::ROIPoolingP
 
 // optional .opencv_caffe.ScaleParameter scale_param = 142;
 bool LayerParameter::has_scale_param() const {
-  return (_has_bits_[1] & 0x00800000u) != 0;
+  return (_has_bits_[1] & 0x01000000u) != 0;
 }
 void LayerParameter::set_has_scale_param() {
-  _has_bits_[1] |= 0x00800000u;
+  _has_bits_[1] |= 0x01000000u;
 }
 void LayerParameter::clear_has_scale_param() {
-  _has_bits_[1] &= ~0x00800000u;
+  _has_bits_[1] &= ~0x01000000u;
 }
 void LayerParameter::clear_scale_param() {
   if (scale_param_ != NULL) scale_param_->::opencv_caffe::ScaleParameter::Clear();
@@ -21057,13 +21258,13 @@ void LayerParameter::set_allocated_scale_param(::opencv_caffe::ScaleParameter* s
 
 // optional .opencv_caffe.SigmoidParameter sigmoid_param = 124;
 bool LayerParameter::has_sigmoid_param() const {
-  return (_has_bits_[1] & 0x01000000u) != 0;
+  return (_has_bits_[1] & 0x02000000u) != 0;
 }
 void LayerParameter::set_has_sigmoid_param() {
-  _has_bits_[1] |= 0x01000000u;
+  _has_bits_[1] |= 0x02000000u;
 }
 void LayerParameter::clear_has_sigmoid_param() {
-  _has_bits_[1] &= ~0x01000000u;
+  _has_bits_[1] &= ~0x02000000u;
 }
 void LayerParameter::clear_sigmoid_param() {
   if (sigmoid_param_ != NULL) sigmoid_param_->::opencv_caffe::SigmoidParameter::Clear();
@@ -21102,13 +21303,13 @@ void LayerParameter::set_allocated_sigmoid_param(::opencv_caffe::SigmoidParamete
 
 // optional .opencv_caffe.SoftmaxParameter softmax_param = 125;
 bool LayerParameter::has_softmax_param() const {
-  return (_has_bits_[1] & 0x02000000u) != 0;
+  return (_has_bits_[1] & 0x04000000u) != 0;
 }
 void LayerParameter::set_has_softmax_param() {
-  _has_bits_[1] |= 0x02000000u;
+  _has_bits_[1] |= 0x04000000u;
 }
 void LayerParameter::clear_has_softmax_param() {
-  _has_bits_[1] &= ~0x02000000u;
+  _has_bits_[1] &= ~0x04000000u;
 }
 void LayerParameter::clear_softmax_param() {
   if (softmax_param_ != NULL) softmax_param_->::opencv_caffe::SoftmaxParameter::Clear();
@@ -21147,13 +21348,13 @@ void LayerParameter::set_allocated_softmax_param(::opencv_caffe::SoftmaxParamete
 
 // optional .opencv_caffe.SPPParameter spp_param = 132;
 bool LayerParameter::has_spp_param() const {
-  return (_has_bits_[1] & 0x04000000u) != 0;
+  return (_has_bits_[1] & 0x08000000u) != 0;
 }
 void LayerParameter::set_has_spp_param() {
-  _has_bits_[1] |= 0x04000000u;
+  _has_bits_[1] |= 0x08000000u;
 }
 void LayerParameter::clear_has_spp_param() {
-  _has_bits_[1] &= ~0x04000000u;
+  _has_bits_[1] &= ~0x08000000u;
 }
 void LayerParameter::clear_spp_param() {
   if (spp_param_ != NULL) spp_param_->::opencv_caffe::SPPParameter::Clear();
@@ -21192,13 +21393,13 @@ void LayerParameter::set_allocated_spp_param(::opencv_caffe::SPPParameter* spp_p
 
 // optional .opencv_caffe.SliceParameter slice_param = 126;
 bool LayerParameter::has_slice_param() const {
-  return (_has_bits_[1] & 0x08000000u) != 0;
+  return (_has_bits_[1] & 0x10000000u) != 0;
 }
 void LayerParameter::set_has_slice_param() {
-  _has_bits_[1] |= 0x08000000u;
+  _has_bits_[1] |= 0x10000000u;
 }
 void LayerParameter::clear_has_slice_param() {
-  _has_bits_[1] &= ~0x08000000u;
+  _has_bits_[1] &= ~0x10000000u;
 }
 void LayerParameter::clear_slice_param() {
   if (slice_param_ != NULL) slice_param_->::opencv_caffe::SliceParameter::Clear();
@@ -21237,13 +21438,13 @@ void LayerParameter::set_allocated_slice_param(::opencv_caffe::SliceParameter* s
 
 // optional .opencv_caffe.TanHParameter tanh_param = 127;
 bool LayerParameter::has_tanh_param() const {
-  return (_has_bits_[1] & 0x10000000u) != 0;
+  return (_has_bits_[1] & 0x20000000u) != 0;
 }
 void LayerParameter::set_has_tanh_param() {
-  _has_bits_[1] |= 0x10000000u;
+  _has_bits_[1] |= 0x20000000u;
 }
 void LayerParameter::clear_has_tanh_param() {
-  _has_bits_[1] &= ~0x10000000u;
+  _has_bits_[1] &= ~0x20000000u;
 }
 void LayerParameter::clear_tanh_param() {
   if (tanh_param_ != NULL) tanh_param_->::opencv_caffe::TanHParameter::Clear();
@@ -21282,13 +21483,13 @@ void LayerParameter::set_allocated_tanh_param(::opencv_caffe::TanHParameter* tan
 
 // optional .opencv_caffe.ThresholdParameter threshold_param = 128;
 bool LayerParameter::has_threshold_param() const {
-  return (_has_bits_[1] & 0x20000000u) != 0;
+  return (_has_bits_[1] & 0x40000000u) != 0;
 }
 void LayerParameter::set_has_threshold_param() {
-  _has_bits_[1] |= 0x20000000u;
+  _has_bits_[1] |= 0x40000000u;
 }
 void LayerParameter::clear_has_threshold_param() {
-  _has_bits_[1] &= ~0x20000000u;
+  _has_bits_[1] &= ~0x40000000u;
 }
 void LayerParameter::clear_threshold_param() {
   if (threshold_param_ != NULL) threshold_param_->::opencv_caffe::ThresholdParameter::Clear();
@@ -21327,13 +21528,13 @@ void LayerParameter::set_allocated_threshold_param(::opencv_caffe::ThresholdPara
 
 // optional .opencv_caffe.TileParameter tile_param = 138;
 bool LayerParameter::has_tile_param() const {
-  return (_has_bits_[1] & 0x40000000u) != 0;
+  return (_has_bits_[1] & 0x80000000u) != 0;
 }
 void LayerParameter::set_has_tile_param() {
-  _has_bits_[1] |= 0x40000000u;
+  _has_bits_[1] |= 0x80000000u;
 }
 void LayerParameter::clear_has_tile_param() {
-  _has_bits_[1] &= ~0x40000000u;
+  _has_bits_[1] &= ~0x80000000u;
 }
 void LayerParameter::clear_tile_param() {
   if (tile_param_ != NULL) tile_param_->::opencv_caffe::TileParameter::Clear();
@@ -21372,13 +21573,13 @@ void LayerParameter::set_allocated_tile_param(::opencv_caffe::TileParameter* til
 
 // optional .opencv_caffe.WindowDataParameter window_data_param = 129;
 bool LayerParameter::has_window_data_param() const {
-  return (_has_bits_[1] & 0x80000000u) != 0;
+  return (_has_bits_[2] & 0x00000001u) != 0;
 }
 void LayerParameter::set_has_window_data_param() {
-  _has_bits_[1] |= 0x80000000u;
+  _has_bits_[2] |= 0x00000001u;
 }
 void LayerParameter::clear_has_window_data_param() {
-  _has_bits_[1] &= ~0x80000000u;
+  _has_bits_[2] &= ~0x00000001u;
 }
 void LayerParameter::clear_window_data_param() {
   if (window_data_param_ != NULL) window_data_param_->::opencv_caffe::WindowDataParameter::Clear();
@@ -55746,6 +55947,450 @@ inline const ProposalParameter* ProposalParameter::internal_default_instance() {
 }
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int PSROIPoolingParameter::kSpatialScaleFieldNumber;
+const int PSROIPoolingParameter::kOutputDimFieldNumber;
+const int PSROIPoolingParameter::kGroupSizeFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+PSROIPoolingParameter::PSROIPoolingParameter()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  if (this != internal_default_instance()) protobuf_InitDefaults_opencv_2dcaffe_2eproto();
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:opencv_caffe.PSROIPoolingParameter)
+}
+
+void PSROIPoolingParameter::InitAsDefaultInstance() {
+}
+
+PSROIPoolingParameter::PSROIPoolingParameter(const PSROIPoolingParameter& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  UnsafeMergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:opencv_caffe.PSROIPoolingParameter)
+}
+
+void PSROIPoolingParameter::SharedCtor() {
+  _cached_size_ = 0;
+  ::memset(&spatial_scale_, 0, reinterpret_cast<char*>(&group_size_) -
+    reinterpret_cast<char*>(&spatial_scale_) + sizeof(group_size_));
+}
+
+PSROIPoolingParameter::~PSROIPoolingParameter() {
+  // @@protoc_insertion_point(destructor:opencv_caffe.PSROIPoolingParameter)
+  SharedDtor();
+}
+
+void PSROIPoolingParameter::SharedDtor() {
+}
+
+void PSROIPoolingParameter::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* PSROIPoolingParameter::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return PSROIPoolingParameter_descriptor_;
+}
+
+const PSROIPoolingParameter& PSROIPoolingParameter::default_instance() {
+  protobuf_InitDefaults_opencv_2dcaffe_2eproto();
+  return *internal_default_instance();
+}
+
+::google::protobuf::internal::ExplicitlyConstructed<PSROIPoolingParameter> PSROIPoolingParameter_default_instance_;
+
+PSROIPoolingParameter* PSROIPoolingParameter::New(::google::protobuf::Arena* arena) const {
+  PSROIPoolingParameter* n = new PSROIPoolingParameter;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void PSROIPoolingParameter::Clear() {
+// @@protoc_insertion_point(message_clear_start:opencv_caffe.PSROIPoolingParameter)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+  _Pragma("clang diagnostic push") \
+  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+  __builtin_offsetof(PSROIPoolingParameter, f) \
+  _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+  &reinterpret_cast<PSROIPoolingParameter*>(16)->f)
+#endif
+
+#define ZR_(first, last) do {\
+  ::memset(&(first), 0,\
+           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
+
+  ZR_(spatial_scale_, group_size_);
+
+#undef ZR_HELPER_
+#undef ZR_
+
+  _has_bits_.Clear();
+  if (_internal_metadata_.have_unknown_fields()) {
+    mutable_unknown_fields()->Clear();
+  }
+}
+
+bool PSROIPoolingParameter::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:opencv_caffe.PSROIPoolingParameter)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // required float spatial_scale = 1;
+      case 1: {
+        if (tag == 13) {
+          set_has_spatial_scale();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+                 input, &spatial_scale_)));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_output_dim;
+        break;
+      }
+
+      // required int32 output_dim = 2;
+      case 2: {
+        if (tag == 16) {
+         parse_output_dim:
+          set_has_output_dim();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &output_dim_)));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(24)) goto parse_group_size;
+        break;
+      }
+
+      // required int32 group_size = 3;
+      case 3: {
+        if (tag == 24) {
+         parse_group_size:
+          set_has_group_size();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &group_size_)));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:opencv_caffe.PSROIPoolingParameter)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:opencv_caffe.PSROIPoolingParameter)
+  return false;
+#undef DO_
+}
+
+void PSROIPoolingParameter::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:opencv_caffe.PSROIPoolingParameter)
+  // required float spatial_scale = 1;
+  if (has_spatial_scale()) {
+    ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->spatial_scale(), output);
+  }
+
+  // required int32 output_dim = 2;
+  if (has_output_dim()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->output_dim(), output);
+  }
+
+  // required int32 group_size = 3;
+  if (has_group_size()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->group_size(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:opencv_caffe.PSROIPoolingParameter)
+}
+
+::google::protobuf::uint8* PSROIPoolingParameter::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
+  (void)deterministic; // Unused
+  // @@protoc_insertion_point(serialize_to_array_start:opencv_caffe.PSROIPoolingParameter)
+  // required float spatial_scale = 1;
+  if (has_spatial_scale()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->spatial_scale(), target);
+  }
+
+  // required int32 output_dim = 2;
+  if (has_output_dim()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->output_dim(), target);
+  }
+
+  // required int32 group_size = 3;
+  if (has_group_size()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->group_size(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:opencv_caffe.PSROIPoolingParameter)
+  return target;
+}
+
+size_t PSROIPoolingParameter::RequiredFieldsByteSizeFallback() const {
+// @@protoc_insertion_point(required_fields_byte_size_fallback_start:opencv_caffe.PSROIPoolingParameter)
+  size_t total_size = 0;
+
+  if (has_spatial_scale()) {
+    // required float spatial_scale = 1;
+    total_size += 1 + 4;
+  }
+
+  if (has_output_dim()) {
+    // required int32 output_dim = 2;
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->output_dim());
+  }
+
+  if (has_group_size()) {
+    // required int32 group_size = 3;
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->group_size());
+  }
+
+  return total_size;
+}
+size_t PSROIPoolingParameter::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:opencv_caffe.PSROIPoolingParameter)
+  size_t total_size = 0;
+
+  if (((_has_bits_[0] & 0x00000007) ^ 0x00000007) == 0) {  // All required fields are present.
+    // required float spatial_scale = 1;
+    total_size += 1 + 4;
+
+    // required int32 output_dim = 2;
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->output_dim());
+
+    // required int32 group_size = 3;
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->group_size());
+
+  } else {
+    total_size += RequiredFieldsByteSizeFallback();
+  }
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = cached_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void PSROIPoolingParameter::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:opencv_caffe.PSROIPoolingParameter)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const PSROIPoolingParameter* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const PSROIPoolingParameter>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:opencv_caffe.PSROIPoolingParameter)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:opencv_caffe.PSROIPoolingParameter)
+    UnsafeMergeFrom(*source);
+  }
+}
+
+void PSROIPoolingParameter::MergeFrom(const PSROIPoolingParameter& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:opencv_caffe.PSROIPoolingParameter)
+  if (GOOGLE_PREDICT_TRUE(&from != this)) {
+    UnsafeMergeFrom(from);
+  } else {
+    MergeFromFail(__LINE__);
+  }
+}
+
+void PSROIPoolingParameter::UnsafeMergeFrom(const PSROIPoolingParameter& from) {
+  GOOGLE_DCHECK(&from != this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_spatial_scale()) {
+      set_spatial_scale(from.spatial_scale());
+    }
+    if (from.has_output_dim()) {
+      set_output_dim(from.output_dim());
+    }
+    if (from.has_group_size()) {
+      set_group_size(from.group_size());
+    }
+  }
+  if (from._internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::UnknownFieldSet::MergeToInternalMetdata(
+      from.unknown_fields(), &_internal_metadata_);
+  }
+}
+
+void PSROIPoolingParameter::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:opencv_caffe.PSROIPoolingParameter)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void PSROIPoolingParameter::CopyFrom(const PSROIPoolingParameter& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:opencv_caffe.PSROIPoolingParameter)
+  if (&from == this) return;
+  Clear();
+  UnsafeMergeFrom(from);
+}
+
+bool PSROIPoolingParameter::IsInitialized() const {
+  if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;
+
+  return true;
+}
+
+void PSROIPoolingParameter::Swap(PSROIPoolingParameter* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void PSROIPoolingParameter::InternalSwap(PSROIPoolingParameter* other) {
+  std::swap(spatial_scale_, other->spatial_scale_);
+  std::swap(output_dim_, other->output_dim_);
+  std::swap(group_size_, other->group_size_);
+  std::swap(_has_bits_[0], other->_has_bits_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata PSROIPoolingParameter::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = PSROIPoolingParameter_descriptor_;
+  metadata.reflection = PSROIPoolingParameter_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// PSROIPoolingParameter
+
+// required float spatial_scale = 1;
+bool PSROIPoolingParameter::has_spatial_scale() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void PSROIPoolingParameter::set_has_spatial_scale() {
+  _has_bits_[0] |= 0x00000001u;
+}
+void PSROIPoolingParameter::clear_has_spatial_scale() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+void PSROIPoolingParameter::clear_spatial_scale() {
+  spatial_scale_ = 0;
+  clear_has_spatial_scale();
+}
+float PSROIPoolingParameter::spatial_scale() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.PSROIPoolingParameter.spatial_scale)
+  return spatial_scale_;
+}
+void PSROIPoolingParameter::set_spatial_scale(float value) {
+  set_has_spatial_scale();
+  spatial_scale_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.PSROIPoolingParameter.spatial_scale)
+}
+
+// required int32 output_dim = 2;
+bool PSROIPoolingParameter::has_output_dim() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void PSROIPoolingParameter::set_has_output_dim() {
+  _has_bits_[0] |= 0x00000002u;
+}
+void PSROIPoolingParameter::clear_has_output_dim() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+void PSROIPoolingParameter::clear_output_dim() {
+  output_dim_ = 0;
+  clear_has_output_dim();
+}
+::google::protobuf::int32 PSROIPoolingParameter::output_dim() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.PSROIPoolingParameter.output_dim)
+  return output_dim_;
+}
+void PSROIPoolingParameter::set_output_dim(::google::protobuf::int32 value) {
+  set_has_output_dim();
+  output_dim_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.PSROIPoolingParameter.output_dim)
+}
+
+// required int32 group_size = 3;
+bool PSROIPoolingParameter::has_group_size() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+void PSROIPoolingParameter::set_has_group_size() {
+  _has_bits_[0] |= 0x00000004u;
+}
+void PSROIPoolingParameter::clear_has_group_size() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+void PSROIPoolingParameter::clear_group_size() {
+  group_size_ = 0;
+  clear_has_group_size();
+}
+::google::protobuf::int32 PSROIPoolingParameter::group_size() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.PSROIPoolingParameter.group_size)
+  return group_size_;
+}
+void PSROIPoolingParameter::set_group_size(::google::protobuf::int32 value) {
+  set_has_group_size();
+  group_size_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.PSROIPoolingParameter.group_size)
+}
+
+inline const PSROIPoolingParameter* PSROIPoolingParameter::internal_default_instance() {
+  return &PSROIPoolingParameter_default_instance_.get();
+}
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
 // @@protoc_insertion_point(namespace_scope)
 
 }  // namespace opencv_caffe
index 74b3532..63c8a1e 100644 (file)
@@ -80,6 +80,7 @@ class NonMaximumSuppressionParameter;
 class NormalizeBBoxParameter;
 class NormalizedBBox;
 class PReLUParameter;
+class PSROIPoolingParameter;
 class ParamSpec;
 class ParameterParameter;
 class PermuteParameter;
@@ -1781,6 +1782,13 @@ class DetectionOutputParameter : public ::google::protobuf::Message /* @@protoc_
   float confidence_threshold() const;
   void set_confidence_threshold(float value);
 
+  // optional bool normalized_bbox = 10 [default = true];
+  bool has_normalized_bbox() const;
+  void clear_normalized_bbox();
+  static const int kNormalizedBboxFieldNumber = 10;
+  bool normalized_bbox() const;
+  void set_normalized_bbox(bool value);
+
   // @@protoc_insertion_point(class_scope:opencv_caffe.DetectionOutputParameter)
  private:
   inline void set_has_num_classes();
@@ -1801,6 +1809,8 @@ class DetectionOutputParameter : public ::google::protobuf::Message /* @@protoc_
   inline void clear_has_keep_top_k();
   inline void set_has_confidence_threshold();
   inline void clear_has_confidence_threshold();
+  inline void set_has_normalized_bbox();
+  inline void clear_has_normalized_bbox();
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
@@ -1812,8 +1822,9 @@ class DetectionOutputParameter : public ::google::protobuf::Message /* @@protoc_
   bool variance_encoded_in_target_;
   float confidence_threshold_;
   ::google::protobuf::int32 keep_top_k_;
-  bool share_location_;
   int code_type_;
+  bool share_location_;
+  bool normalized_bbox_;
   friend void  protobuf_InitDefaults_opencv_2dcaffe_2eproto_impl();
   friend void  protobuf_AddDesc_opencv_2dcaffe_2eproto_impl();
   friend void protobuf_AssignDesc_opencv_2dcaffe_2eproto();
@@ -4148,6 +4159,15 @@ class LayerParameter : public ::google::protobuf::Message /* @@protoc_insertion_
   ::opencv_caffe::ProposalParameter* release_proposal_param();
   void set_allocated_proposal_param(::opencv_caffe::ProposalParameter* proposal_param);
 
+  // optional .opencv_caffe.PSROIPoolingParameter psroi_pooling_param = 10001;
+  bool has_psroi_pooling_param() const;
+  void clear_psroi_pooling_param();
+  static const int kPsroiPoolingParamFieldNumber = 10001;
+  const ::opencv_caffe::PSROIPoolingParameter& psroi_pooling_param() const;
+  ::opencv_caffe::PSROIPoolingParameter* mutable_psroi_pooling_param();
+  ::opencv_caffe::PSROIPoolingParameter* release_psroi_pooling_param();
+  void set_allocated_psroi_pooling_param(::opencv_caffe::PSROIPoolingParameter* psroi_pooling_param);
+
   // optional .opencv_caffe.PythonParameter python_param = 130;
   bool has_python_param() const;
   void clear_python_param();
@@ -4367,6 +4387,8 @@ class LayerParameter : public ::google::protobuf::Message /* @@protoc_insertion_
   inline void clear_has_prior_box_param();
   inline void set_has_proposal_param();
   inline void clear_has_proposal_param();
+  inline void set_has_psroi_pooling_param();
+  inline void clear_has_psroi_pooling_param();
   inline void set_has_python_param();
   inline void clear_has_python_param();
   inline void set_has_recurrent_param();
@@ -4399,7 +4421,8 @@ class LayerParameter : public ::google::protobuf::Message /* @@protoc_insertion_
   inline void clear_has_window_data_param();
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
-  ::google::protobuf::internal::HasBits<2> _has_bits_;
+  ::google::protobuf::internal::HasBits<3> _has_bits_;
+  mutable int _cached_size_;
   ::google::protobuf::RepeatedPtrField< ::std::string> bottom_;
   ::google::protobuf::RepeatedPtrField< ::std::string> top_;
   ::google::protobuf::RepeatedField< float > loss_weight_;
@@ -4448,6 +4471,7 @@ class LayerParameter : public ::google::protobuf::Message /* @@protoc_insertion_
   ::opencv_caffe::PReLUParameter* prelu_param_;
   ::opencv_caffe::PriorBoxParameter* prior_box_param_;
   ::opencv_caffe::ProposalParameter* proposal_param_;
+  ::opencv_caffe::PSROIPoolingParameter* psroi_pooling_param_;
   ::opencv_caffe::PythonParameter* python_param_;
   ::opencv_caffe::RecurrentParameter* recurrent_param_;
   ::opencv_caffe::ReductionParameter* reduction_param_;
@@ -4464,7 +4488,6 @@ class LayerParameter : public ::google::protobuf::Message /* @@protoc_insertion_
   ::opencv_caffe::TileParameter* tile_param_;
   ::opencv_caffe::WindowDataParameter* window_data_param_;
   int phase_;
-  mutable int _cached_size_;
   friend void  protobuf_InitDefaults_opencv_2dcaffe_2eproto_impl();
   friend void  protobuf_AddDesc_opencv_2dcaffe_2eproto_impl();
   friend void protobuf_AssignDesc_opencv_2dcaffe_2eproto();
@@ -13111,6 +13134,127 @@ class ProposalParameter : public ::google::protobuf::Message /* @@protoc_inserti
 };
 extern ::google::protobuf::internal::ExplicitlyConstructed<ProposalParameter> ProposalParameter_default_instance_;
 
+// -------------------------------------------------------------------
+
+class PSROIPoolingParameter : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:opencv_caffe.PSROIPoolingParameter) */ {
+ public:
+  PSROIPoolingParameter();
+  virtual ~PSROIPoolingParameter();
+
+  PSROIPoolingParameter(const PSROIPoolingParameter& from);
+
+  inline PSROIPoolingParameter& operator=(const PSROIPoolingParameter& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _internal_metadata_.unknown_fields();
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _internal_metadata_.mutable_unknown_fields();
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const PSROIPoolingParameter& default_instance();
+
+  static const PSROIPoolingParameter* internal_default_instance();
+
+  void Swap(PSROIPoolingParameter* other);
+
+  // implements Message ----------------------------------------------
+
+  inline PSROIPoolingParameter* New() const { return New(NULL); }
+
+  PSROIPoolingParameter* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const PSROIPoolingParameter& from);
+  void MergeFrom(const PSROIPoolingParameter& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  size_t ByteSizeLong() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(PSROIPoolingParameter* other);
+  void UnsafeMergeFrom(const PSROIPoolingParameter& from);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // required float spatial_scale = 1;
+  bool has_spatial_scale() const;
+  void clear_spatial_scale();
+  static const int kSpatialScaleFieldNumber = 1;
+  float spatial_scale() const;
+  void set_spatial_scale(float value);
+
+  // required int32 output_dim = 2;
+  bool has_output_dim() const;
+  void clear_output_dim();
+  static const int kOutputDimFieldNumber = 2;
+  ::google::protobuf::int32 output_dim() const;
+  void set_output_dim(::google::protobuf::int32 value);
+
+  // required int32 group_size = 3;
+  bool has_group_size() const;
+  void clear_group_size();
+  static const int kGroupSizeFieldNumber = 3;
+  ::google::protobuf::int32 group_size() const;
+  void set_group_size(::google::protobuf::int32 value);
+
+  // @@protoc_insertion_point(class_scope:opencv_caffe.PSROIPoolingParameter)
+ private:
+  inline void set_has_spatial_scale();
+  inline void clear_has_spatial_scale();
+  inline void set_has_output_dim();
+  inline void clear_has_output_dim();
+  inline void set_has_group_size();
+  inline void clear_has_group_size();
+
+  // helper for ByteSizeLong()
+  size_t RequiredFieldsByteSizeFallback() const;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::HasBits<1> _has_bits_;
+  mutable int _cached_size_;
+  float spatial_scale_;
+  ::google::protobuf::int32 output_dim_;
+  ::google::protobuf::int32 group_size_;
+  friend void  protobuf_InitDefaults_opencv_2dcaffe_2eproto_impl();
+  friend void  protobuf_AddDesc_opencv_2dcaffe_2eproto_impl();
+  friend void protobuf_AssignDesc_opencv_2dcaffe_2eproto();
+  friend void protobuf_ShutdownFile_opencv_2dcaffe_2eproto();
+
+  void InitAsDefaultInstance();
+};
+extern ::google::protobuf::internal::ExplicitlyConstructed<PSROIPoolingParameter> PSROIPoolingParameter_default_instance_;
+
 // ===================================================================
 
 
@@ -14411,6 +14555,30 @@ inline void DetectionOutputParameter::set_confidence_threshold(float value) {
   // @@protoc_insertion_point(field_set:opencv_caffe.DetectionOutputParameter.confidence_threshold)
 }
 
+// optional bool normalized_bbox = 10 [default = true];
+inline bool DetectionOutputParameter::has_normalized_bbox() const {
+  return (_has_bits_[0] & 0x00000200u) != 0;
+}
+inline void DetectionOutputParameter::set_has_normalized_bbox() {
+  _has_bits_[0] |= 0x00000200u;
+}
+inline void DetectionOutputParameter::clear_has_normalized_bbox() {
+  _has_bits_[0] &= ~0x00000200u;
+}
+inline void DetectionOutputParameter::clear_normalized_bbox() {
+  normalized_bbox_ = true;
+  clear_has_normalized_bbox();
+}
+inline bool DetectionOutputParameter::normalized_bbox() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.DetectionOutputParameter.normalized_bbox)
+  return normalized_bbox_;
+}
+inline void DetectionOutputParameter::set_normalized_bbox(bool value) {
+  set_has_normalized_bbox();
+  normalized_bbox_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.DetectionOutputParameter.normalized_bbox)
+}
+
 inline const DetectionOutputParameter* DetectionOutputParameter::internal_default_instance() {
   return &DetectionOutputParameter_default_instance_.get();
 }
@@ -19163,15 +19331,60 @@ inline void LayerParameter::set_allocated_proposal_param(::opencv_caffe::Proposa
   // @@protoc_insertion_point(field_set_allocated:opencv_caffe.LayerParameter.proposal_param)
 }
 
+// optional .opencv_caffe.PSROIPoolingParameter psroi_pooling_param = 10001;
+inline bool LayerParameter::has_psroi_pooling_param() const {
+  return (_has_bits_[1] & 0x00020000u) != 0;
+}
+inline void LayerParameter::set_has_psroi_pooling_param() {
+  _has_bits_[1] |= 0x00020000u;
+}
+inline void LayerParameter::clear_has_psroi_pooling_param() {
+  _has_bits_[1] &= ~0x00020000u;
+}
+inline void LayerParameter::clear_psroi_pooling_param() {
+  if (psroi_pooling_param_ != NULL) psroi_pooling_param_->::opencv_caffe::PSROIPoolingParameter::Clear();
+  clear_has_psroi_pooling_param();
+}
+inline const ::opencv_caffe::PSROIPoolingParameter& LayerParameter::psroi_pooling_param() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.LayerParameter.psroi_pooling_param)
+  return psroi_pooling_param_ != NULL ? *psroi_pooling_param_
+                         : *::opencv_caffe::PSROIPoolingParameter::internal_default_instance();
+}
+inline ::opencv_caffe::PSROIPoolingParameter* LayerParameter::mutable_psroi_pooling_param() {
+  set_has_psroi_pooling_param();
+  if (psroi_pooling_param_ == NULL) {
+    psroi_pooling_param_ = new ::opencv_caffe::PSROIPoolingParameter;
+  }
+  // @@protoc_insertion_point(field_mutable:opencv_caffe.LayerParameter.psroi_pooling_param)
+  return psroi_pooling_param_;
+}
+inline ::opencv_caffe::PSROIPoolingParameter* LayerParameter::release_psroi_pooling_param() {
+  // @@protoc_insertion_point(field_release:opencv_caffe.LayerParameter.psroi_pooling_param)
+  clear_has_psroi_pooling_param();
+  ::opencv_caffe::PSROIPoolingParameter* temp = psroi_pooling_param_;
+  psroi_pooling_param_ = NULL;
+  return temp;
+}
+inline void LayerParameter::set_allocated_psroi_pooling_param(::opencv_caffe::PSROIPoolingParameter* psroi_pooling_param) {
+  delete psroi_pooling_param_;
+  psroi_pooling_param_ = psroi_pooling_param;
+  if (psroi_pooling_param) {
+    set_has_psroi_pooling_param();
+  } else {
+    clear_has_psroi_pooling_param();
+  }
+  // @@protoc_insertion_point(field_set_allocated:opencv_caffe.LayerParameter.psroi_pooling_param)
+}
+
 // optional .opencv_caffe.PythonParameter python_param = 130;
 inline bool LayerParameter::has_python_param() const {
-  return (_has_bits_[1] & 0x00020000u) != 0;
+  return (_has_bits_[1] & 0x00040000u) != 0;
 }
 inline void LayerParameter::set_has_python_param() {
-  _has_bits_[1] |= 0x00020000u;
+  _has_bits_[1] |= 0x00040000u;
 }
 inline void LayerParameter::clear_has_python_param() {
-  _has_bits_[1] &= ~0x00020000u;
+  _has_bits_[1] &= ~0x00040000u;
 }
 inline void LayerParameter::clear_python_param() {
   if (python_param_ != NULL) python_param_->::opencv_caffe::PythonParameter::Clear();
@@ -19210,13 +19423,13 @@ inline void LayerParameter::set_allocated_python_param(::opencv_caffe::PythonPar
 
 // optional .opencv_caffe.RecurrentParameter recurrent_param = 146;
 inline bool LayerParameter::has_recurrent_param() const {
-  return (_has_bits_[1] & 0x00040000u) != 0;
+  return (_has_bits_[1] & 0x00080000u) != 0;
 }
 inline void LayerParameter::set_has_recurrent_param() {
-  _has_bits_[1] |= 0x00040000u;
+  _has_bits_[1] |= 0x00080000u;
 }
 inline void LayerParameter::clear_has_recurrent_param() {
-  _has_bits_[1] &= ~0x00040000u;
+  _has_bits_[1] &= ~0x00080000u;
 }
 inline void LayerParameter::clear_recurrent_param() {
   if (recurrent_param_ != NULL) recurrent_param_->::opencv_caffe::RecurrentParameter::Clear();
@@ -19255,13 +19468,13 @@ inline void LayerParameter::set_allocated_recurrent_param(::opencv_caffe::Recurr
 
 // optional .opencv_caffe.ReductionParameter reduction_param = 136;
 inline bool LayerParameter::has_reduction_param() const {
-  return (_has_bits_[1] & 0x00080000u) != 0;
+  return (_has_bits_[1] & 0x00100000u) != 0;
 }
 inline void LayerParameter::set_has_reduction_param() {
-  _has_bits_[1] |= 0x00080000u;
+  _has_bits_[1] |= 0x00100000u;
 }
 inline void LayerParameter::clear_has_reduction_param() {
-  _has_bits_[1] &= ~0x00080000u;
+  _has_bits_[1] &= ~0x00100000u;
 }
 inline void LayerParameter::clear_reduction_param() {
   if (reduction_param_ != NULL) reduction_param_->::opencv_caffe::ReductionParameter::Clear();
@@ -19300,13 +19513,13 @@ inline void LayerParameter::set_allocated_reduction_param(::opencv_caffe::Reduct
 
 // optional .opencv_caffe.ReLUParameter relu_param = 123;
 inline bool LayerParameter::has_relu_param() const {
-  return (_has_bits_[1] & 0x00100000u) != 0;
+  return (_has_bits_[1] & 0x00200000u) != 0;
 }
 inline void LayerParameter::set_has_relu_param() {
-  _has_bits_[1] |= 0x00100000u;
+  _has_bits_[1] |= 0x00200000u;
 }
 inline void LayerParameter::clear_has_relu_param() {
-  _has_bits_[1] &= ~0x00100000u;
+  _has_bits_[1] &= ~0x00200000u;
 }
 inline void LayerParameter::clear_relu_param() {
   if (relu_param_ != NULL) relu_param_->::opencv_caffe::ReLUParameter::Clear();
@@ -19345,13 +19558,13 @@ inline void LayerParameter::set_allocated_relu_param(::opencv_caffe::ReLUParamet
 
 // optional .opencv_caffe.ReshapeParameter reshape_param = 133;
 inline bool LayerParameter::has_reshape_param() const {
-  return (_has_bits_[1] & 0x00200000u) != 0;
+  return (_has_bits_[1] & 0x00400000u) != 0;
 }
 inline void LayerParameter::set_has_reshape_param() {
-  _has_bits_[1] |= 0x00200000u;
+  _has_bits_[1] |= 0x00400000u;
 }
 inline void LayerParameter::clear_has_reshape_param() {
-  _has_bits_[1] &= ~0x00200000u;
+  _has_bits_[1] &= ~0x00400000u;
 }
 inline void LayerParameter::clear_reshape_param() {
   if (reshape_param_ != NULL) reshape_param_->::opencv_caffe::ReshapeParameter::Clear();
@@ -19390,13 +19603,13 @@ inline void LayerParameter::set_allocated_reshape_param(::opencv_caffe::ReshapeP
 
 // optional .opencv_caffe.ROIPoolingParameter roi_pooling_param = 8266711;
 inline bool LayerParameter::has_roi_pooling_param() const {
-  return (_has_bits_[1] & 0x00400000u) != 0;
+  return (_has_bits_[1] & 0x00800000u) != 0;
 }
 inline void LayerParameter::set_has_roi_pooling_param() {
-  _has_bits_[1] |= 0x00400000u;
+  _has_bits_[1] |= 0x00800000u;
 }
 inline void LayerParameter::clear_has_roi_pooling_param() {
-  _has_bits_[1] &= ~0x00400000u;
+  _has_bits_[1] &= ~0x00800000u;
 }
 inline void LayerParameter::clear_roi_pooling_param() {
   if (roi_pooling_param_ != NULL) roi_pooling_param_->::opencv_caffe::ROIPoolingParameter::Clear();
@@ -19435,13 +19648,13 @@ inline void LayerParameter::set_allocated_roi_pooling_param(::opencv_caffe::ROIP
 
 // optional .opencv_caffe.ScaleParameter scale_param = 142;
 inline bool LayerParameter::has_scale_param() const {
-  return (_has_bits_[1] & 0x00800000u) != 0;
+  return (_has_bits_[1] & 0x01000000u) != 0;
 }
 inline void LayerParameter::set_has_scale_param() {
-  _has_bits_[1] |= 0x00800000u;
+  _has_bits_[1] |= 0x01000000u;
 }
 inline void LayerParameter::clear_has_scale_param() {
-  _has_bits_[1] &= ~0x00800000u;
+  _has_bits_[1] &= ~0x01000000u;
 }
 inline void LayerParameter::clear_scale_param() {
   if (scale_param_ != NULL) scale_param_->::opencv_caffe::ScaleParameter::Clear();
@@ -19480,13 +19693,13 @@ inline void LayerParameter::set_allocated_scale_param(::opencv_caffe::ScaleParam
 
 // optional .opencv_caffe.SigmoidParameter sigmoid_param = 124;
 inline bool LayerParameter::has_sigmoid_param() const {
-  return (_has_bits_[1] & 0x01000000u) != 0;
+  return (_has_bits_[1] & 0x02000000u) != 0;
 }
 inline void LayerParameter::set_has_sigmoid_param() {
-  _has_bits_[1] |= 0x01000000u;
+  _has_bits_[1] |= 0x02000000u;
 }
 inline void LayerParameter::clear_has_sigmoid_param() {
-  _has_bits_[1] &= ~0x01000000u;
+  _has_bits_[1] &= ~0x02000000u;
 }
 inline void LayerParameter::clear_sigmoid_param() {
   if (sigmoid_param_ != NULL) sigmoid_param_->::opencv_caffe::SigmoidParameter::Clear();
@@ -19525,13 +19738,13 @@ inline void LayerParameter::set_allocated_sigmoid_param(::opencv_caffe::SigmoidP
 
 // optional .opencv_caffe.SoftmaxParameter softmax_param = 125;
 inline bool LayerParameter::has_softmax_param() const {
-  return (_has_bits_[1] & 0x02000000u) != 0;
+  return (_has_bits_[1] & 0x04000000u) != 0;
 }
 inline void LayerParameter::set_has_softmax_param() {
-  _has_bits_[1] |= 0x02000000u;
+  _has_bits_[1] |= 0x04000000u;
 }
 inline void LayerParameter::clear_has_softmax_param() {
-  _has_bits_[1] &= ~0x02000000u;
+  _has_bits_[1] &= ~0x04000000u;
 }
 inline void LayerParameter::clear_softmax_param() {
   if (softmax_param_ != NULL) softmax_param_->::opencv_caffe::SoftmaxParameter::Clear();
@@ -19570,13 +19783,13 @@ inline void LayerParameter::set_allocated_softmax_param(::opencv_caffe::SoftmaxP
 
 // optional .opencv_caffe.SPPParameter spp_param = 132;
 inline bool LayerParameter::has_spp_param() const {
-  return (_has_bits_[1] & 0x04000000u) != 0;
+  return (_has_bits_[1] & 0x08000000u) != 0;
 }
 inline void LayerParameter::set_has_spp_param() {
-  _has_bits_[1] |= 0x04000000u;
+  _has_bits_[1] |= 0x08000000u;
 }
 inline void LayerParameter::clear_has_spp_param() {
-  _has_bits_[1] &= ~0x04000000u;
+  _has_bits_[1] &= ~0x08000000u;
 }
 inline void LayerParameter::clear_spp_param() {
   if (spp_param_ != NULL) spp_param_->::opencv_caffe::SPPParameter::Clear();
@@ -19615,13 +19828,13 @@ inline void LayerParameter::set_allocated_spp_param(::opencv_caffe::SPPParameter
 
 // optional .opencv_caffe.SliceParameter slice_param = 126;
 inline bool LayerParameter::has_slice_param() const {
-  return (_has_bits_[1] & 0x08000000u) != 0;
+  return (_has_bits_[1] & 0x10000000u) != 0;
 }
 inline void LayerParameter::set_has_slice_param() {
-  _has_bits_[1] |= 0x08000000u;
+  _has_bits_[1] |= 0x10000000u;
 }
 inline void LayerParameter::clear_has_slice_param() {
-  _has_bits_[1] &= ~0x08000000u;
+  _has_bits_[1] &= ~0x10000000u;
 }
 inline void LayerParameter::clear_slice_param() {
   if (slice_param_ != NULL) slice_param_->::opencv_caffe::SliceParameter::Clear();
@@ -19660,13 +19873,13 @@ inline void LayerParameter::set_allocated_slice_param(::opencv_caffe::SliceParam
 
 // optional .opencv_caffe.TanHParameter tanh_param = 127;
 inline bool LayerParameter::has_tanh_param() const {
-  return (_has_bits_[1] & 0x10000000u) != 0;
+  return (_has_bits_[1] & 0x20000000u) != 0;
 }
 inline void LayerParameter::set_has_tanh_param() {
-  _has_bits_[1] |= 0x10000000u;
+  _has_bits_[1] |= 0x20000000u;
 }
 inline void LayerParameter::clear_has_tanh_param() {
-  _has_bits_[1] &= ~0x10000000u;
+  _has_bits_[1] &= ~0x20000000u;
 }
 inline void LayerParameter::clear_tanh_param() {
   if (tanh_param_ != NULL) tanh_param_->::opencv_caffe::TanHParameter::Clear();
@@ -19705,13 +19918,13 @@ inline void LayerParameter::set_allocated_tanh_param(::opencv_caffe::TanHParamet
 
 // optional .opencv_caffe.ThresholdParameter threshold_param = 128;
 inline bool LayerParameter::has_threshold_param() const {
-  return (_has_bits_[1] & 0x20000000u) != 0;
+  return (_has_bits_[1] & 0x40000000u) != 0;
 }
 inline void LayerParameter::set_has_threshold_param() {
-  _has_bits_[1] |= 0x20000000u;
+  _has_bits_[1] |= 0x40000000u;
 }
 inline void LayerParameter::clear_has_threshold_param() {
-  _has_bits_[1] &= ~0x20000000u;
+  _has_bits_[1] &= ~0x40000000u;
 }
 inline void LayerParameter::clear_threshold_param() {
   if (threshold_param_ != NULL) threshold_param_->::opencv_caffe::ThresholdParameter::Clear();
@@ -19750,13 +19963,13 @@ inline void LayerParameter::set_allocated_threshold_param(::opencv_caffe::Thresh
 
 // optional .opencv_caffe.TileParameter tile_param = 138;
 inline bool LayerParameter::has_tile_param() const {
-  return (_has_bits_[1] & 0x40000000u) != 0;
+  return (_has_bits_[1] & 0x80000000u) != 0;
 }
 inline void LayerParameter::set_has_tile_param() {
-  _has_bits_[1] |= 0x40000000u;
+  _has_bits_[1] |= 0x80000000u;
 }
 inline void LayerParameter::clear_has_tile_param() {
-  _has_bits_[1] &= ~0x40000000u;
+  _has_bits_[1] &= ~0x80000000u;
 }
 inline void LayerParameter::clear_tile_param() {
   if (tile_param_ != NULL) tile_param_->::opencv_caffe::TileParameter::Clear();
@@ -19795,13 +20008,13 @@ inline void LayerParameter::set_allocated_tile_param(::opencv_caffe::TileParamet
 
 // optional .opencv_caffe.WindowDataParameter window_data_param = 129;
 inline bool LayerParameter::has_window_data_param() const {
-  return (_has_bits_[1] & 0x80000000u) != 0;
+  return (_has_bits_[2] & 0x00000001u) != 0;
 }
 inline void LayerParameter::set_has_window_data_param() {
-  _has_bits_[1] |= 0x80000000u;
+  _has_bits_[2] |= 0x00000001u;
 }
 inline void LayerParameter::clear_has_window_data_param() {
-  _has_bits_[1] &= ~0x80000000u;
+  _has_bits_[2] &= ~0x00000001u;
 }
 inline void LayerParameter::clear_window_data_param() {
   if (window_data_param_ != NULL) window_data_param_->::opencv_caffe::WindowDataParameter::Clear();
@@ -29392,6 +29605,85 @@ inline void ProposalParameter::set_nms_thresh(float value) {
 inline const ProposalParameter* ProposalParameter::internal_default_instance() {
   return &ProposalParameter_default_instance_.get();
 }
+// -------------------------------------------------------------------
+
+// PSROIPoolingParameter
+
+// required float spatial_scale = 1;
+inline bool PSROIPoolingParameter::has_spatial_scale() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void PSROIPoolingParameter::set_has_spatial_scale() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void PSROIPoolingParameter::clear_has_spatial_scale() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void PSROIPoolingParameter::clear_spatial_scale() {
+  spatial_scale_ = 0;
+  clear_has_spatial_scale();
+}
+inline float PSROIPoolingParameter::spatial_scale() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.PSROIPoolingParameter.spatial_scale)
+  return spatial_scale_;
+}
+inline void PSROIPoolingParameter::set_spatial_scale(float value) {
+  set_has_spatial_scale();
+  spatial_scale_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.PSROIPoolingParameter.spatial_scale)
+}
+
+// required int32 output_dim = 2;
+inline bool PSROIPoolingParameter::has_output_dim() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void PSROIPoolingParameter::set_has_output_dim() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void PSROIPoolingParameter::clear_has_output_dim() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void PSROIPoolingParameter::clear_output_dim() {
+  output_dim_ = 0;
+  clear_has_output_dim();
+}
+inline ::google::protobuf::int32 PSROIPoolingParameter::output_dim() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.PSROIPoolingParameter.output_dim)
+  return output_dim_;
+}
+inline void PSROIPoolingParameter::set_output_dim(::google::protobuf::int32 value) {
+  set_has_output_dim();
+  output_dim_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.PSROIPoolingParameter.output_dim)
+}
+
+// required int32 group_size = 3;
+inline bool PSROIPoolingParameter::has_group_size() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void PSROIPoolingParameter::set_has_group_size() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void PSROIPoolingParameter::clear_has_group_size() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void PSROIPoolingParameter::clear_group_size() {
+  group_size_ = 0;
+  clear_has_group_size();
+}
+inline ::google::protobuf::int32 PSROIPoolingParameter::group_size() const {
+  // @@protoc_insertion_point(field_get:opencv_caffe.PSROIPoolingParameter.group_size)
+  return group_size_;
+}
+inline void PSROIPoolingParameter::set_group_size(::google::protobuf::int32 value) {
+  set_has_group_size();
+  group_size_ = value;
+  // @@protoc_insertion_point(field_set:opencv_caffe.PSROIPoolingParameter.group_size)
+}
+
+inline const PSROIPoolingParameter* PSROIPoolingParameter::internal_default_instance() {
+  return &PSROIPoolingParameter_default_instance_.get();
+}
 #endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
 // -------------------------------------------------------------------
 
@@ -29531,6 +29823,8 @@ inline const ProposalParameter* ProposalParameter::internal_default_instance() {
 
 // -------------------------------------------------------------------
 
+// -------------------------------------------------------------------
+
 
 // @@protoc_insertion_point(namespace_scope)
 
index c8817b9..35b2870 100644 (file)
@@ -68,18 +68,18 @@ static caffe::Net<float>* initNet(std::string proto, std::string weights)
     return net;
 }
 
-PERF_TEST(GoogLeNet_caffe, CaffePerfTest)
+PERF_TEST(AlexNet_caffe, CaffePerfTest)
 {
-    caffe::Net<float>* net = initNet("dnn/bvlc_googlenet.prototxt",
-                                     "dnn/bvlc_googlenet.caffemodel");
+    caffe::Net<float>* net = initNet("dnn/bvlc_alexnet.prototxt",
+                                     "dnn/bvlc_alexnet.caffemodel");
     TEST_CYCLE() net->Forward();
     SANITY_CHECK_NOTHING();
 }
 
-PERF_TEST(AlexNet_caffe, CaffePerfTest)
+PERF_TEST(GoogLeNet_caffe, CaffePerfTest)
 {
-    caffe::Net<float>* net = initNet("dnn/bvlc_alexnet.prototxt",
-                                     "dnn/bvlc_alexnet.caffemodel");
+    caffe::Net<float>* net = initNet("dnn/bvlc_googlenet.prototxt",
+                                     "dnn/bvlc_googlenet.caffemodel");
     TEST_CYCLE() net->Forward();
     SANITY_CHECK_NOTHING();
 }
@@ -100,6 +100,14 @@ PERF_TEST(SqueezeNet_v1_1_caffe, CaffePerfTest)
     SANITY_CHECK_NOTHING();
 }
 
+PERF_TEST(MobileNet_SSD, CaffePerfTest)
+{
+    caffe::Net<float>* net = initNet("dnn/MobileNetSSD_deploy.prototxt",
+                                     "dnn/MobileNetSSD_deploy.caffemodel");
+    TEST_CYCLE() net->Forward();
+    SANITY_CHECK_NOTHING();
+}
+
 }  // namespace cvtest
 
 #endif  // HAVE_CAFFE
index 0d6d257..219c702 100644 (file)
@@ -70,7 +70,7 @@ public:
         }
         else if (framework == "tensorflow")
         {
-            net = cv::dnn::readNetFromTensorflow(weights);
+            net = cv::dnn::readNetFromTensorflow(weights, proto);
         }
         else
             CV_Error(Error::StsNotImplemented, "Unknown framework " + framework);
@@ -148,6 +148,24 @@ PERF_TEST_P_(DNNTestNetwork, SSD)
             Mat(cv::Size(300, 300), CV_32FC3), "detection_out", "caffe");
 }
 
+PERF_TEST_P_(DNNTestNetwork, OpenFace)
+{
+    processNet("dnn/openface_nn4.small2.v1.t7", "", "",
+            Mat(cv::Size(96, 96), CV_32FC3), "", "torch");
+}
+
+PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_Caffe)
+{
+    processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt", "",
+            Mat(cv::Size(300, 300), CV_32FC3), "detection_out", "caffe");
+}
+
+PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_TensorFlow)
+{
+    processNet("dnn/ssd_mobilenet_v1_coco.pb", "ssd_mobilenet_v1_coco.pbtxt", "",
+            Mat(cv::Size(300, 300), CV_32FC3), "", "tensorflow");
+}
+
 INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork,
     testing::Combine(
         ::testing::Values(TEST_DNN_BACKEND),
index a219bd5..106793c 100644 (file)
@@ -75,7 +75,7 @@ static cv::String toString(const T &v)
     return ss.str();
 }
 
-class CaffeImporter : public Importer
+class CaffeImporter
 {
     caffe::NetParameter net;
     caffe::NetParameter netBinary;
@@ -390,21 +390,10 @@ public:
 
         dstNet.connect(addedBlobs[idx].layerId, addedBlobs[idx].outNum, layerId, inNum);
     }
-
-    ~CaffeImporter()
-    {
-
-    }
-
 };
 
 }
 
-Ptr<Importer> createCaffeImporter(const String &prototxt, const String &caffeModel)
-{
-    return Ptr<Importer>(new CaffeImporter(prototxt.c_str(), caffeModel.c_str()));
-}
-
 Net readNetFromCaffe(const String &prototxt, const String &caffeModel /*= String()*/)
 {
     CaffeImporter caffeImporter(prototxt.c_str(), caffeModel.c_str());
index 8fde102..fa7fe1d 100644 (file)
@@ -179,6 +179,8 @@ message DetectionOutputParameter {
   // Only consider detections whose confidences are larger than a threshold.
   // If not provided, consider all boxes.
   optional float confidence_threshold = 9;
+  // If prior boxes are normalized to [0, 1] or not.
+  optional bool normalized_bbox = 10 [default = true];
 }
 
 message Datum {
@@ -548,6 +550,7 @@ message LayerParameter {
   optional PReLUParameter prelu_param = 131;
   optional PriorBoxParameter prior_box_param = 150;
   optional ProposalParameter proposal_param = 201;
+  optional PSROIPoolingParameter psroi_pooling_param = 10001;  // https://github.com/daijifeng001/caffe-rfcn
   optional PythonParameter python_param = 130;
   optional RecurrentParameter recurrent_param = 146;
   optional ReductionParameter reduction_param = 136;
@@ -1633,3 +1636,10 @@ message ProposalParameter {
   optional uint32 post_nms_topn = 7 [default = 300];
   optional float nms_thresh = 8 [default = 0.7];
 }
+
+// origin: https://github.com/daijifeng001/caffe-rfcn
+message PSROIPoolingParameter {
+  required float spatial_scale = 1;
+  required int32 output_dim = 2; // output channel number
+  required int32 group_size = 3; // equal to pooled_size
+}
index 18a7bc9..8bd64d0 100644 (file)
@@ -58,7 +58,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
 namespace
 {
 
-class DarknetImporter : public Importer
+class DarknetImporter
 {
     darknet::NetParameter net;
 
@@ -173,12 +173,6 @@ public:
 
         dstNet.connect(addedBlobs[idx].layerId, addedBlobs[idx].outNum, layerId, inNum);
     }
-
-    ~DarknetImporter()
-    {
-
-    }
-
 };
 
 }
index b9cb154..b9360b1 100644 (file)
@@ -2294,8 +2294,6 @@ int64 Net::getPerfProfile(std::vector<double>& timings)
 
 //////////////////////////////////////////////////////////////////////////
 
-Importer::~Importer() {}
-
 Layer::Layer() { preferableTarget = DNN_TARGET_CPU; }
 
 Layer::Layer(const LayerParams &params)
index ba1a10d..28759da 100644 (file)
@@ -89,6 +89,7 @@ void initializeLayerFactory()
     CV_DNN_REGISTER_LAYER_CLASS(Deconvolution,  DeconvolutionLayer);
     CV_DNN_REGISTER_LAYER_CLASS(Pooling,        PoolingLayer);
     CV_DNN_REGISTER_LAYER_CLASS(ROIPooling,     PoolingLayer);
+    CV_DNN_REGISTER_LAYER_CLASS(PSROIPooling,   PoolingLayer);
     CV_DNN_REGISTER_LAYER_CLASS(LRN,            LRNLayer);
     CV_DNN_REGISTER_LAYER_CLASS(InnerProduct,   InnerProductLayer);
     CV_DNN_REGISTER_LAYER_CLASS(Softmax,        SoftmaxLayer);
index 0574458..8e5faf9 100644 (file)
@@ -57,9 +57,9 @@ namespace cv
 {
 namespace dnn
 {
-static inline int scaleAndRoundRoi(float f, float scale)
+static inline int roundRoiSize(float v)
 {
-    return (int)(f * scale + (f >= 0.f ? 0.5f : -0.5f));
+    return (int)(v + (v >= 0.f ? 0.5f : -0.5f));
 }
 
 class PoolingLayerImpl : public PoolingLayer
@@ -67,13 +67,14 @@ class PoolingLayerImpl : public PoolingLayer
 public:
     PoolingLayerImpl(const LayerParams& params)
     {
-        type = MAX;
         computeMaxIdx = true;
         globalPooling = false;
+        stride = Size(1, 1);
 
-        if (params.has("pool"))
+        if (params.has("pool") || params.has("kernel_size") ||
+            params.has("kernel_w") || params.has("kernel_h"))
         {
-            String pool = params.get<String>("pool").toLowerCase();
+            String pool = params.get<String>("pool", "max").toLowerCase();
             if (pool == "max")
                 type = MAX;
             else if (pool == "ave")
@@ -85,15 +86,24 @@ public:
             getPoolingKernelParams(params, kernel.height, kernel.width, globalPooling,
                                    pad.height, pad.width, stride.height, stride.width, padMode);
         }
-        else if (params.has("pooled_w") || params.has("pooled_h") || params.has("spatial_scale"))
+        else if (params.has("pooled_w") || params.has("pooled_h"))
         {
             type = ROI;
             computeMaxIdx = false;
+            pooledSize.width = params.get<uint32_t>("pooled_w", 1);
+            pooledSize.height = params.get<uint32_t>("pooled_h", 1);
         }
+        else if (params.has("output_dim") && params.has("group_size"))
+        {
+            type = PSROI;
+            pooledSize.width = params.get<int>("group_size");
+            pooledSize.height = pooledSize.width;
+            psRoiOutChannels = params.get<int>("output_dim");
+        }
+        else
+            CV_Error(Error::StsBadArg, "Cannot determine pooling type");
         setParamsFrom(params);
         ceilMode = params.get<bool>("ceil_mode", true);
-        pooledSize.width = params.get<uint32_t>("pooled_w", 1);
-        pooledSize.height = params.get<uint32_t>("pooled_h", 1);
         spatialScale = params.get<float>("spatial_scale", 1);
     }
 
@@ -192,7 +202,7 @@ public:
                 CV_Assert(inputs.size() == 1, outputs.size() == 1);
                 avePooling(*inputs[0], outputs[0]);
                 break;
-            case ROI:
+            case ROI: case PSROI:
                 CV_Assert(inputs.size() == 2, outputs.size() == 1);
                 roiPooling(*inputs[0], *inputs[1], outputs[0]);
                 break;
@@ -231,11 +241,11 @@ public:
                         Size stride, Size pad, int poolingType, float spatialScale,
                         bool computeMaxIdx, int nstripes)
         {
-            CV_Assert(src.isContinuous() && dst.isContinuous() &&
-                      src.type() == CV_32F && src.type() == dst.type() &&
-                      src.dims == 4 && dst.dims == 4 &&
-                      (poolingType == ROI && dst.size[0] == rois.size[0] ||
-                       src.size[0] == dst.size[0]) && src.size[1] == dst.size[1] &&
+            CV_Assert(src.isContinuous(), dst.isContinuous(),
+                      src.type() == CV_32F, src.type() == dst.type(),
+                      src.dims == 4, dst.dims == 4,
+                      ((poolingType == ROI || poolingType == PSROI) && dst.size[0] ==rois.size[0] || src.size[0] == dst.size[0]),
+                       poolingType == PSROI || src.size[1] == dst.size[1],
                       (mask.empty() || (mask.type() == src.type() && mask.size == dst.size)));
 
             PoolingInvoker p;
@@ -294,12 +304,12 @@ public:
                 int n = (int)(ofs / channels);
                 int ystart, yend;
 
-                const float *srcData;
+                const float *srcData = 0;
                 if (poolingType == ROI)
                 {
                     const float *roisData = rois->ptr<float>(n);
-                    int ystartROI = scaleAndRoundRoi(roisData[2], spatialScale);
-                    int yendROI = scaleAndRoundRoi(roisData[4], spatialScale);
+                    int ystartROI = roundRoiSize(roisData[2] * spatialScale);
+                    int yendROI = roundRoiSize(roisData[4] * spatialScale);
                     int roiHeight = std::max(yendROI - ystartROI + 1, 1);
                     float roiRatio = (float)roiHeight / height;
 
@@ -309,6 +319,17 @@ public:
                     CV_Assert(roisData[0] < src->size[0]);
                     srcData = src->ptr<float>(roisData[0], c);
                 }
+                else if (poolingType == PSROI)
+                {
+                    const float *roisData = rois->ptr<float>(n);
+                    float ystartROI = roundRoiSize(roisData[2]) * spatialScale;
+                    float yendROI = roundRoiSize(roisData[4] + 1) * spatialScale;
+                    float roiHeight = std::max(yendROI - ystartROI, 0.1f);
+                    float roiRatio = roiHeight / height;
+
+                    ystart = (int)std::floor(ystartROI + y0 * roiRatio);
+                    yend = (int)std::ceil(ystartROI + (y0 + 1) * roiRatio);
+                }
                 else
                 {
                     ystart = y0 * stride_h - pad_h;
@@ -527,11 +548,11 @@ public:
                         }
                     }
                 }
-                else  // ROI
+                else if (poolingType == ROI)
                 {
                     const float *roisData = rois->ptr<float>(n);
-                    int xstartROI = scaleAndRoundRoi(roisData[1], spatialScale);
-                    int xendROI = scaleAndRoundRoi(roisData[3], spatialScale);
+                    int xstartROI = roundRoiSize(roisData[1] * spatialScale);
+                    int xendROI = roundRoiSize(roisData[3] * spatialScale);
                     int roiWidth = std::max(xendROI - xstartROI + 1, 1);
                     float roiRatio = (float)roiWidth / width;
                     for( ; x0 < x1; x0++ )
@@ -558,6 +579,38 @@ public:
                         dstData[x0] = max_val;
                     }
                 }
+                else  // PSROI
+                {
+                    const float *roisData = rois->ptr<float>(n);
+                    CV_Assert(roisData[0] < src->size[0]);
+                    float xstartROI = roundRoiSize(roisData[1]) * spatialScale;
+                    float xendROI = roundRoiSize(roisData[3] + 1) * spatialScale;
+                    float roiWidth = std::max(xendROI - xstartROI, 0.1f);
+                    float roiRatio = roiWidth / width;
+                    for( ; x0 < x1; x0++ )
+                    {
+                        int xstart = (int)std::floor(xstartROI + x0 * roiRatio);
+                        int xend = (int)std::ceil(xstartROI + (x0 + 1) * roiRatio);
+                        xstart = max(xstart, 0);
+                        xend = min(xend, inp_width);
+                        if (xstart >= xend || ystart >= yend)
+                        {
+                            dstData[x0] = 0;
+                            continue;
+                        }
+
+                        srcData = src->ptr<float>(roisData[0], (c * height + y0) * width + x0);
+                        float sum_val = 0.f;
+                        for (int y = ystart; y < yend; ++y)
+                            for (int x = xstart; x < xend; ++x)
+                            {
+                                const int index = y * inp_width + x;
+                                float val = srcData[index];
+                                sum_val += val;
+                            }
+                        dstData[x0] = sum_val / ((yend - ystart) * (xend - xstart));
+                    }
+                }
             }
         }
     };
@@ -716,7 +769,7 @@ public:
             out.height = 1;
             out.width = 1;
         }
-        else if (type == ROI)
+        else if (type == ROI || type == PSROI)
         {
             out.height = pooledSize.height;
             out.width = pooledSize.width;
@@ -751,6 +804,13 @@ public:
             CV_Assert(inputs.size() == 2);
             dims[0] = inputs[1][0];  // Number of proposals;
         }
+        else if (type == PSROI)
+        {
+            CV_Assert(inputs.size() == 2);
+            CV_Assert(psRoiOutChannels * pooledSize.width * pooledSize.height == inputs[0][1]);
+            dims[0] = inputs[1][0];  // Number of proposals;
+            dims[1] = psRoiOutChannels;
+        }
         outputs.assign(type == MAX ? 2 : 1, shape(dims));
         return false;
     }
@@ -781,7 +841,8 @@ private:
         MAX,
         AVE,
         STOCHASTIC,
-        ROI
+        ROI,   // RoI pooling, https://arxiv.org/pdf/1504.08083.pdf
+        PSROI  // Position-sensitive RoI pooling, https://arxiv.org/pdf/1605.06409.pdf
     };
 };
 
index 5fc852a..575ac5e 100644 (file)
@@ -45,6 +45,7 @@
 #include <float.h>
 #include <algorithm>
 #include <cmath>
+#include "opencl_kernels_dnn.hpp"
 
 namespace cv
 {
@@ -270,11 +271,108 @@ public:
         return false;
     }
 
+#ifdef HAVE_OPENCL
+    bool forward_ocl(InputArrayOfArrays inps, OutputArrayOfArrays outs, OutputArrayOfArrays internals)
+    {
+        std::vector<UMat> inputs;
+        std::vector<UMat> outputs;
+
+        inps.getUMatVector(inputs);
+        outs.getUMatVector(outputs);
+
+        int _layerWidth = inputs[0].size[3];
+        int _layerHeight = inputs[0].size[2];
+
+        int _imageWidth = inputs[1].size[3];
+        int _imageHeight = inputs[1].size[2];
+
+        float stepX, stepY;
+        if (_stepX == 0 || _stepY == 0)
+        {
+            stepX = static_cast<float>(_imageWidth) / _layerWidth;
+            stepY = static_cast<float>(_imageHeight) / _layerHeight;
+        } else {
+            stepX = _stepX;
+            stepY = _stepY;
+        }
+
+        if (umat_offsetsX.empty())
+        {
+            Mat offsetsX(1, _offsetsX.size(), CV_32FC1, &_offsetsX[0]);
+            Mat offsetsY(1, _offsetsX.size(), CV_32FC1, &_offsetsY[0]);
+            Mat aspectRatios(1, _aspectRatios.size(), CV_32FC1, &_aspectRatios[0]);
+            Mat variance(1, _variance.size(), CV_32FC1, &_variance[0]);
+
+            offsetsX.copyTo(umat_offsetsX);
+            offsetsY.copyTo(umat_offsetsY);
+            aspectRatios.copyTo(umat_aspectRatios);
+            variance.copyTo(umat_variance);
+
+            int real_numPriors = _numPriors / pow(2, _offsetsX.size() - 1);
+            umat_scales = UMat(1, &real_numPriors, CV_32F, 1.0f);
+        }
+
+        size_t nthreads = _layerHeight * _layerWidth;
+
+        ocl::Kernel kernel("prior_box", ocl::dnn::prior_box_oclsrc);
+        kernel.set(0, (int)nthreads);
+        kernel.set(1, (float)stepX);
+        kernel.set(2, (float)stepY);
+        kernel.set(3, (float)_minSize);
+        kernel.set(4, (float)_maxSize);
+        kernel.set(5, ocl::KernelArg::PtrReadOnly(umat_offsetsX));
+        kernel.set(6, ocl::KernelArg::PtrReadOnly(umat_offsetsY));
+        kernel.set(7, (int)_offsetsX.size());
+        kernel.set(8, ocl::KernelArg::PtrReadOnly(umat_aspectRatios));
+        kernel.set(9, (int)_aspectRatios.size());
+        kernel.set(10, ocl::KernelArg::PtrReadOnly(umat_scales));
+        kernel.set(11, ocl::KernelArg::PtrWriteOnly(outputs[0]));
+        kernel.set(12, (int)_layerHeight);
+        kernel.set(13, (int)_layerWidth);
+        kernel.set(14, (int)_imageHeight);
+        kernel.set(15, (int)_imageWidth);
+        kernel.run(1, &nthreads, NULL, false);
+
+        // clip the prior's coordidate such that it is within [0, 1]
+        if (_clip)
+        {
+            Mat mat = outputs[0].getMat(ACCESS_READ);
+            int aspect_count = (_maxSize > 0) ? 1 : 0;
+            int offset = nthreads * 4 * _offsetsX.size() * (1 + aspect_count + _aspectRatios.size());
+            float* outputPtr = mat.ptr<float>() + offset;
+            int _outChannelSize = _layerHeight * _layerWidth * _numPriors * 4;
+            for (size_t d = 0; d < _outChannelSize; ++d)
+            {
+                outputPtr[d] = std::min<float>(std::max<float>(outputPtr[d], 0.), 1.);
+            }
+        }
+
+        // set the variance.
+        {
+            ocl::Kernel kernel("set_variance", ocl::dnn::prior_box_oclsrc);
+            int offset = total(shape(outputs[0]), 2);
+            size_t nthreads = _layerHeight * _layerWidth * _numPriors;
+            kernel.set(0, (int)nthreads);
+            kernel.set(1, (int)offset);
+            kernel.set(2, (int)_variance.size());
+            kernel.set(3, ocl::KernelArg::PtrReadOnly(umat_variance));
+            kernel.set(4, ocl::KernelArg::PtrWriteOnly(outputs[0]));
+            if (!kernel.run(1, &nthreads, NULL, false))
+                return false;
+        }
+        return true;
+    }
+#endif
+
     void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr)
     {
         CV_TRACE_FUNCTION();
         CV_TRACE_ARG_VALUE(name, "name", name.c_str());
 
+        CV_OCL_RUN((preferableTarget == DNN_TARGET_OPENCL) &&
+                   OCL_PERFORMANCE_CHECK(ocl::Device::getDefault().isIntel()),
+                   forward_ocl(inputs_arr, outputs_arr, internals_arr))
+
         Layer::forward_fallback(inputs_arr, outputs_arr, internals_arr);
     }
 
@@ -441,6 +539,14 @@ private:
     std::vector<float> _offsetsX;
     std::vector<float> _offsetsY;
 
+#ifdef HAVE_OPENCL
+    UMat umat_offsetsX;
+    UMat umat_offsetsY;
+    UMat umat_aspectRatios;
+    UMat umat_scales;
+    UMat umat_variance;
+#endif
+
     bool _flip;
     bool _clip;
     bool _explicitSizes;
index b137896..f9a74ae 100644 (file)
@@ -215,6 +215,9 @@ class OCL4DNNConvSpatial
         bool createGEMMLikeConvKernel(int32_t blockWidth,
                                       int32_t blockHeight,
                                       int32_t blockDepth);
+        bool createDWConvKernel(int32_t blockWidth,
+                                int32_t blockHeight,
+                                int32_t blockDepth);
         void CreateSubBuffer(const UMat& buffer, UMat& sub_buffer,
                              int32_t offset, int32_t size, bool write_only);
         bool convolve(const UMat &bottom, UMat &top,
@@ -282,6 +285,8 @@ class OCL4DNNConvSpatial
         int32_t M_;
 
         bool tuned_;
+        bool dwconv_;
+
         std::string key_, key_sanitized_;
         std::string short_key_;
         std::string kernel_name_;
index 6a30555..ae188f7 100644 (file)
@@ -103,6 +103,7 @@ OCL4DNNConvSpatial<Dtype>::OCL4DNNConvSpatial(OCL4DNNConvConfig config)
     top_dim_ = num_output_ * output_w_ * output_h_;
 
     cache_path_ = utils::getConfigurationParameterString("OPENCV_OCL4DNN_CONFIG_PATH", "");
+    dwconv_ = (num_output_ == channels_ && channels_ == group_);
 
     use_cache_path_ = false;
     if (!cache_path_.empty())
@@ -203,7 +204,8 @@ void OCL4DNNConvSpatial<Dtype>::collectCommonInformation()
 typedef enum {
     KERNEL_TYPE_INTEL_IDLF = 2,
     KERNEL_TYPE_BASIC = 4,
-    KERNEL_TYPE_GEMM_LIKE = 5
+    KERNEL_TYPE_GEMM_LIKE = 5,
+    KERNEL_TYPE_DWCONV = 6
 } ocl4dnnConvSpatialKernelType_t;
 
 template<typename Dtype>
@@ -313,6 +315,7 @@ void OCL4DNNConvSpatial<Dtype>::setupKernelDetails(int32_t kernelType,
         if (clOptionSupport("-cl-no-subgroup-ifp"))
             options_ << " -cl-no-subgroup-ifp ";
 
+        addDef("KERNEL_GEMM_LIKE");
         addDef("INPUT_DEPTH", channels_);
         addDef("WIDTH1", M_);
         addDef("OUT_PADDING_LEFT", 0);
@@ -329,6 +332,28 @@ void OCL4DNNConvSpatial<Dtype>::setupKernelDetails(int32_t kernelType,
         setFusionDefine(fused_activ_, fused_eltwise_);
         src_ = ocl::dnn::conv_layer_spatial_oclsrc;
     }
+    else if (kernelType == KERNEL_TYPE_DWCONV)
+    {
+        kernelUKey = generateSpecificKey(KERNEL_TYPE_DWCONV, blockM, blockK, blockN);
+        kernel_name_ = "DWCONV_";
+        kernel_name_ += kernelUKey.c_str();
+
+        options_ << " -cl-fast-relaxed-math ";
+        if (clOptionSupport("-cl-no-subgroup-ifp"))
+            options_ << " -cl-no-subgroup-ifp ";
+
+        addDef("KERNEL_DWCONV");
+        addDef("KERNEL_SIZE", kernel_w_ * kernel_h_);
+        addDef("KERNEL_W", kernel_w_);
+        addDef("KERNEL_H", kernel_h_);
+        addDef("APPLY_BIAS", bias_term_);
+        addDef("OUTPUT_Z", num_output_ * num_);
+        addDef("CHANNELS", num_output_);
+        setFusionDefine(fused_activ_, fused_eltwise_);
+
+        options_ << " -D DWCONV=" << kernel_name_;
+        src_ = cv::ocl::dnn::conv_layer_spatial_oclsrc;
+    }
 }
 
 template<typename Dtype>
@@ -906,6 +931,33 @@ bool OCL4DNNConvSpatial<float>::convolve(const UMat &bottom, UMat &top,
                 return false;
             }
         }
+    } else if (config->kernelType == KERNEL_TYPE_DWCONV) {
+        ocl::Kernel kernel(config->kernelName.c_str(), program);
+        if (kernel.empty())
+            return false;
+
+        cl_uint argIdx = 0;
+        setFusionArg(fused_activ_, fused_eltwise_, kernel, argIdx);
+        kernel.set(argIdx++, ocl::KernelArg::PtrReadOnly(bottom));
+        kernel.set(argIdx++, ocl::KernelArg::PtrReadOnly(weight));
+        if (bias_term_)
+            kernel.set(argIdx++, ocl::KernelArg::PtrReadOnly(bias));
+        kernel.set(argIdx++, ocl::KernelArg::PtrWriteOnly(top));
+        kernel.set(argIdx++, (uint16_t)width_);
+        kernel.set(argIdx++, (uint16_t)height_);
+        kernel.set(argIdx++, (uint16_t)output_w_);
+        kernel.set(argIdx++, (uint16_t)output_h_);
+
+        size_t global_size[3];
+        global_size[0] = output_w_;
+        global_size[1] = output_h_;
+        global_size[2] = num_output_ * num_;
+
+        if (!kernel.run(3, global_size, NULL, false))
+        {
+            std::cout << "DWCONV kernel run failed." << std::endl;
+            return false;
+        }
     } else {
         for (int32_t n = 0; n < numImages; ++n) {
             for (int32_t g = 0; g < group_; ++g) {
@@ -1223,6 +1275,39 @@ bool OCL4DNNConvSpatial<float>::createIDLFKernel(int32_t blockWidth,
 }
 
 template<>
+bool OCL4DNNConvSpatial<float>::createDWConvKernel(int32_t blockWidth,
+                                                   int32_t blockHeight,
+                                                   int32_t blockDepth)
+{
+    if (!dwconv_)
+        return false;
+
+    int workItemOutput[3] = { 1, 1, 1 };
+    size_t local_size[3] = { 1, 1, 1 };
+    size_t global_size[3];
+    global_size[0] = divUp(output_w_, workItemOutput[0]);
+    global_size[1] = divUp(output_h_, workItemOutput[1]);
+    global_size[2] = divUp(M_ * num_, workItemOutput[2]);
+
+    kernelType_ = KERNEL_TYPE_DWCONV;
+    blockM_ = blockWidth;
+    blockK_ = blockHeight;
+    blockN_ = blockDepth;
+
+    setupKernel();
+
+    ocl::Program program = compileKernel();
+    if (program.ptr())
+    {
+        kernelQueue.push_back(makePtr<kernelConfig>(kernel_name_, &global_size[0], &local_size[0],
+                              &workItemOutput[0], false, KERNEL_TYPE_DWCONV));
+        return true;
+    }
+    else
+        return false;
+}
+
+template<>
 bool OCL4DNNConvSpatial<float>::createConvolutionKernel(int32_t kernelType,
                                                         int32_t blockWidth,
                                                         int32_t blockHeight,
@@ -1238,6 +1323,8 @@ bool OCL4DNNConvSpatial<float>::createConvolutionKernel(int32_t kernelType,
         return createBasicKernel(blockWidth, blockHeight, blockDepth);
     else if (kernelType == KERNEL_TYPE_GEMM_LIKE)
         return createGEMMLikeConvKernel(blockWidth, blockHeight, blockDepth);
+    else if (kernelType == KERNEL_TYPE_DWCONV)
+        return createDWConvKernel(blockWidth, blockHeight, blockDepth);
     else
         CV_Assert(0 && "Internal error");
     return false;
@@ -1246,7 +1333,16 @@ bool OCL4DNNConvSpatial<float>::createConvolutionKernel(int32_t kernelType,
 template<>
 void OCL4DNNConvSpatial<float>::generateTunerItems(std::vector< cv::Ptr<tunerParam> > &tunerItems)
 {
-    if (ocl::Device::getDefault().intelSubgroupsSupport()) {
+    if (ocl::Device::getDefault().intelSubgroupsSupport())
+    {
+        //depth_wise kernels
+        if (dwconv_)
+        {
+            tunerItems.push_back(makePtr<tunerParam>(KERNEL_TYPE_DWCONV, 1, 1, 1));
+            if (group_ > 8)
+                return;
+        }
+
         /* IDLF kernels are using Intel specific extension which make
            them intel only. */
         // Generates static key_
index 91066bd..2457cf7 100644 (file)
@@ -383,7 +383,7 @@ convolve_simd(
   }
 }
 
-#else // KERNEL_GEMM_LIKE
+#elif defined KERNEL_GEMM_LIKE
 
 #if APPLY_BIAS
 // Dtype bias[4];
@@ -1501,4 +1501,59 @@ __kernel void Conv_Interleaved(GEMM_LIKE_KERNEL_ARGS)
     INTERLEAVED_SIMD16_OUTPUT(dst, out_offset, 0);
 }
 #endif
-#endif // KERNEL_BASIC/IDLF/GEMM_LIKE
+
+#elif defined KERNEL_DWCONV
+
+__kernel void DWCONV(
+    ELTWISE_DATA_ARG
+    NEGATIVE_SLOPE_ARG
+    __global Dtype* image_data,
+    __global Dtype* kernel_data,
+    BIAS_KERNEL_ARG
+    __global Dtype* convolved_image,
+    const ushort input_width,
+    const ushort input_height,
+    const ushort output_width,
+    const ushort output_height) {
+
+  const int outputX = get_global_id(0);
+  const int outputY = get_global_id(1);
+  const int outputZ = get_global_id(2);
+  if(outputX < output_width && outputY < output_height)
+  {
+    Dtype sum = 0.;
+
+    const int org_y = outputY * STRIDE_Y - INPUT_PAD_H;
+    const int org_x = outputX * STRIDE_X - INPUT_PAD_W;
+    const int currentKernelOffset = KERNEL_SIZE*(outputZ%CHANNELS);
+    const int biasIndex=outputZ%CHANNELS;
+    const int local_image_offset = org_y*input_width + org_x;
+    const int imageSize = input_width*input_height;
+
+    __global Dtype* image_dataPtrFloat = (image_data + (imageSize*outputZ + local_image_offset));
+    __global Dtype* kernel_dataPtrFloat = (kernel_data + (currentKernelOffset));
+
+    for(int y = 0; y < KERNEL_H; y++)
+    {
+      for(int x = 0; x < KERNEL_W; x++)
+      {
+        if(!(org_y + y * DILATION_Y >= 0 && org_y + y * DILATION_Y < input_height && org_x + x * DILATION_X >= 0 && org_x + x * DILATION_X < input_width))
+        {
+          continue;
+        }
+        sum += image_dataPtrFloat[x * DILATION_X] * kernel_dataPtrFloat[x];
+      }
+      image_dataPtrFloat += input_width * DILATION_Y;
+      kernel_dataPtrFloat += KERNEL_W;
+    }
+
+    #if APPLY_BIAS
+    int offset = outputZ*output_height*output_width + outputY*output_width + outputX;
+    ACTIVATION_FUNCTION(convolved_image, offset, sum + biases_base[biasIndex], biasIndex);
+    #else
+    int offset = outputZ*output_height*output_width + outputY*output_width + outputX;
+    ACTIVATION_FUNCTION(convolved_image, offset, sum, biasIndex);
+    #endif
+  }
+}
+#endif // KERNEL_BASIC/IDLF/GEMM_LIKE/DWCONV
diff --git a/modules/dnn/src/opencl/prior_box.cl b/modules/dnn/src/opencl/prior_box.cl
new file mode 100644 (file)
index 0000000..660ccb6
--- /dev/null
@@ -0,0 +1,148 @@
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+//  By downloading, copying, installing or using the software you agree to this license.
+//  If you do not agree to this license, do not download, install,
+//  copy or use the software.
+//
+//
+//                           License Agreement
+//                For Open Source Computer Vision Library
+//
+// Copyright (c) 2016-2017 Fabian David Tschopp, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//   * Redistribution's of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//
+//   * Redistribution's in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//
+//   * The name of the copyright holders may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#define Dtype float
+#define Dtype4 float4
+
+__kernel void prior_box(const int nthreads,
+                        const Dtype stepX,
+                        const Dtype stepY,
+                        const Dtype _minSize,
+                        const Dtype _maxSize,
+                        __global const Dtype* _offsetsX,
+                        __global const Dtype* _offsetsY,
+                        const int offsetsX_size,
+                        __global const Dtype* _aspectRatios,
+                        const int aspectRatios_size,
+                        __global const Dtype* scales,
+                        __global Dtype* dst,
+                        const int _layerHeight,
+                        const int _layerWidth,
+                        const int imgHeight,
+                        const int imgWidth)
+{
+    for (int index = get_global_id(0); index < nthreads; index += get_global_size(0))
+    {
+        int w = index % _layerWidth;
+        int h = index / _layerWidth;
+        __global Dtype* outputPtr;
+        int aspect_count = (_maxSize > 0) ? 1 : 0;
+        outputPtr = dst + index * 4 * offsetsX_size * (1 + aspect_count + aspectRatios_size);
+
+        Dtype _boxWidth, _boxHeight;
+        Dtype4 vec;
+        _boxWidth = _boxHeight = _minSize * scales[0];
+        for (int i = 0; i < offsetsX_size; ++i)
+        {
+            float center_x = (w + _offsetsX[i]) * stepX;
+            float center_y = (h + _offsetsY[i]) * stepY;
+
+            vec.x = (center_x - _boxWidth * 0.5f) / imgWidth;    // xmin
+            vec.y = (center_y - _boxHeight * 0.5f) / imgHeight;  // ymin
+            vec.z = (center_x + _boxWidth * 0.5f) / imgWidth;    // xmax
+            vec.w = (center_y + _boxHeight * 0.5f) / imgHeight;  // ymax
+            vstore4(vec, 0, outputPtr);
+
+            outputPtr += 4;
+        }
+
+        if (_maxSize > 0)
+        {
+            _boxWidth = _boxHeight = native_sqrt(_minSize * _maxSize) * scales[1];
+
+            for (int i = 0; i < offsetsX_size; ++i)
+            {
+                float center_x = (w + _offsetsX[i]) * stepX;
+                float center_y = (h + _offsetsY[i]) * stepY;
+
+                vec.x = (center_x - _boxWidth * 0.5f) / imgWidth;    // xmin
+                vec.y = (center_y - _boxHeight * 0.5f) / imgHeight;  // ymin
+                vec.z = (center_x + _boxWidth * 0.5f) / imgWidth;    // xmax
+                vec.w = (center_y + _boxHeight * 0.5f) / imgHeight;  // ymax
+                vstore4(vec, 0, outputPtr);
+
+                outputPtr += 4;
+            }
+        }
+
+        for (int r = 0; r < aspectRatios_size; ++r)
+        {
+            float ar = native_sqrt(_aspectRatios[r]);
+            float scale = scales[(_maxSize > 0 ? 2 : 1) + r];
+
+            _boxWidth = _minSize * ar * scale;
+            _boxHeight = _minSize / ar * scale;
+
+            for (int i = 0; i < offsetsX_size; ++i)
+            {
+                float center_x = (w + _offsetsX[i]) * stepX;
+                float center_y = (h + _offsetsY[i]) * stepY;
+
+                vec.x = (center_x - _boxWidth * 0.5f) / imgWidth;    // xmin
+                vec.y = (center_y - _boxHeight * 0.5f) / imgHeight;  // ymin
+                vec.z = (center_x + _boxWidth * 0.5f) / imgWidth;    // xmax
+                vec.w = (center_y + _boxHeight * 0.5f) / imgHeight;  // ymax
+                vstore4(vec, 0, outputPtr);
+
+                outputPtr += 4;
+            }
+        }
+    }
+}
+
+__kernel void set_variance(const int nthreads,
+                           const int offset,
+                           const int variance_size,
+                           __global const Dtype* variance,
+                           __global Dtype* dst)
+{
+    for (int index = get_global_id(0); index < nthreads; index += get_global_size(0))
+    {
+        Dtype4 var_vec;
+
+        if (variance_size == 1)
+            var_vec = (Dtype4)(variance[0]);
+        else
+            var_vec = vload4(0, variance);
+
+        vstore4(var_vec, 0, dst + offset + index * 4);
+    }
+}
index 0cecd4d..202958d 100644 (file)
@@ -446,14 +446,13 @@ void ExcludeLayer(tensorflow::GraphDef& net, const int layer_index, const int in
         net.mutable_node()->DeleteSubrange(layer_index, 1);
 }
 
-class TFImporter : public Importer {
+class TFImporter {
 public:
     TFImporter(const char *model, const char *config = NULL);
     TFImporter(const char *dataModel, size_t lenModel,
                const char *dataConfig = NULL, size_t lenConfig = 0);
 
     void populateNet(Net dstNet);
-    ~TFImporter() {}
 
 private:
     void kernelFromTensor(const tensorflow::TensorProto &tensor, Mat &dstBlob);
@@ -1315,19 +1314,6 @@ void TFImporter::populateNet(Net dstNet)
 
 } // namespace
 
-Ptr<Importer> createTensorflowImporter(const String &model)
-{
-    return Ptr<Importer>(new TFImporter(model.c_str()));
-}
-
-#else //HAVE_PROTOBUF
-
-Ptr<Importer> createTensorflowImporter(const String&)
-{
-    CV_Error(cv::Error::StsNotImplemented, "libprotobuf required to import data from TensorFlow models");
-    return Ptr<Importer>();
-}
-
 #endif //HAVE_PROTOBUF
 
 Net readNetFromTensorflow(const String &model, const String &config)
index 192680e..aad9ecc 100644 (file)
@@ -1,5 +1,4 @@
 #include "../precomp.hpp"
-#if defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
 #include "THGeneral.h"
 #include "THDiskFile.h"
 #include "THFilePrivate.h"
@@ -517,4 +516,3 @@ THFile *THDiskFile_new(const std::string &name, const char *mode, int isQuiet)
 }
 
 }
-#endif
index 081873f..5f7fe1c 100644 (file)
@@ -1,5 +1,4 @@
 #include "../precomp.hpp"
-#if defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
 #include "THFile.h"
 #include "THFilePrivate.h"
 
@@ -119,4 +118,3 @@ IMPLEMENT_THFILE_SCALAR(Float, float)
 IMPLEMENT_THFILE_SCALAR(Double, double)
 
 } // namespace
-#endif
index 5ac3af2..14e3fbf 100644 (file)
@@ -2,7 +2,6 @@
 #define TH_FILE_INC
 
 //#include "THStorage.h"
-#if defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
 #include "opencv2/core/hal/interface.h"
 #include "THGeneral.h"
 
@@ -51,5 +50,4 @@ TH_API long THFile_position(THFile *self);
 TH_API void THFile_close(THFile *self);
 TH_API void THFile_free(THFile *self);
 } // namespace
-#endif //defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
 #endif //TH_FILE_INC
index b0f38e0..8a52745 100644 (file)
@@ -1,5 +1,4 @@
 #include "../precomp.hpp"
-#if defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
 
 #if defined(TH_DISABLE_HEAP_TRACKING)
 #elif (defined(__unix) || defined(_WIN32))
@@ -9,5 +8,3 @@
 #endif
 
 #include "THGeneral.h"
-
-#endif
index df5f1db..b664d79 100644 (file)
 #include <iostream>
 #include <fstream>
 
-#if defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
 #include "THDiskFile.h"
-#endif
 
 namespace cv {
 namespace dnn {
 CV__DNN_EXPERIMENTAL_NS_BEGIN
 
-#if defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
 using namespace TH;
 
 //#ifdef NDEBUG
@@ -95,7 +92,7 @@ static inline bool endsWith(const String &str, const char *substr)
     return str.rfind(substr) == str.length() - strlen(substr);
 }
 
-struct TorchImporter : public ::cv::dnn::Importer
+struct TorchImporter
 {
     typedef std::map<String, std::pair<int, Mat> > TensorsMap;
     Net net;
@@ -1191,19 +1188,13 @@ struct TorchImporter : public ::cv::dnn::Importer
     }
 };
 
-Ptr<Importer> createTorchImporter(const String &filename, bool isBinary)
-{
-    return Ptr<Importer>(new TorchImporter(filename, isBinary));
-}
-
-
 Mat readTorchBlob(const String &filename, bool isBinary)
 {
-    Ptr<TorchImporter> importer(new TorchImporter(filename, isBinary));
-    importer->readObject();
-    CV_Assert(importer->tensors.size() == 1);
+    TorchImporter importer(filename, isBinary);
+    importer.readObject();
+    CV_Assert(importer.tensors.size() == 1);
 
-    return importer->tensors.begin()->second;
+    return importer.tensors.begin()->second;
 }
 
 Net readNetFromTorch(const String &model, bool isBinary)
@@ -1216,27 +1207,5 @@ Net readNetFromTorch(const String &model, bool isBinary)
     return net;
 }
 
-#else
-
-Ptr<Importer> createTorchImporter(const String&, bool)
-{
-    CV_Error(Error::StsNotImplemented, "Torch importer is disabled in current build");
-    return Ptr<Importer>();
-}
-
-Mat readTorchBlob(const String&, bool)
-{
-    CV_Error(Error::StsNotImplemented, "Torch importer is disabled in current build");
-    return Mat();
-}
-
-Net readNetFromTorch(const String &model, bool isBinary)
-{
-    CV_Error(Error::StsNotImplemented, "Torch importer is disabled in current build");
-    return Net();
-}
-
-#endif //defined(ENABLE_TORCH_IMPORTER) && ENABLE_TORCH_IMPORTER
-
 CV__DNN_EXPERIMENTAL_NS_END
 }} // namespace
index fbb90a7..1badf74 100644 (file)
@@ -11,6 +11,8 @@ Test for Tensorflow models loading
 
 #include "test_precomp.hpp"
 #include "npy_blob.hpp"
+#include <opencv2/core/ocl.hpp>
+#include <opencv2/ts/ocl_test.hpp>
 
 namespace cvtest
 {
@@ -219,6 +221,43 @@ TEST(Test_TensorFlow, MobileNet_SSD)
     normAssert(target[2].reshape(1, 1), output[2].reshape(1, 1), "", 4e-5, 1e-2);
 }
 
+OCL_TEST(Test_TensorFlow, MobileNet_SSD)
+{
+    std::string netPath = findDataFile("dnn/ssd_mobilenet_v1_coco.pb", false);
+    std::string netConfig = findDataFile("dnn/ssd_mobilenet_v1_coco.pbtxt", false);
+    std::string imgPath = findDataFile("dnn/street.png", false);
+
+    Mat inp;
+    resize(imread(imgPath), inp, Size(300, 300));
+    inp = blobFromImage(inp, 1.0f / 127.5, Size(), Scalar(127.5, 127.5, 127.5), true);
+
+    std::vector<String> outNames(3);
+    outNames[0] = "concat";
+    outNames[1] = "concat_1";
+    outNames[2] = "detection_out";
+
+    std::vector<Mat> target(outNames.size());
+    for (int i = 0; i < outNames.size(); ++i)
+    {
+        std::string path = findDataFile("dnn/tensorflow/ssd_mobilenet_v1_coco." + outNames[i] + ".npy", false);
+        target[i] = blobFromNPY(path);
+    }
+
+    Net net = readNetFromTensorflow(netPath, netConfig);
+
+    net.setPreferableBackend(DNN_BACKEND_DEFAULT);
+    net.setPreferableTarget(DNN_TARGET_OPENCL);
+
+    net.setInput(inp);
+
+    std::vector<Mat> output;
+    net.forward(output, outNames);
+
+    normAssert(target[0].reshape(1, 1), output[0].reshape(1, 1));
+    normAssert(target[1].reshape(1, 1), output[1].reshape(1, 1), "", 1e-5, 2e-4);
+    normAssert(target[2].reshape(1, 1), output[2].reshape(1, 1), "", 4e-5, 1e-2);
+}
+
 TEST(Test_TensorFlow, lstm)
 {
     runTensorFlowNet("lstm", true);
index c90ddeb..cbac6c5 100644 (file)
@@ -39,8 +39,6 @@
 //
 //M*/
 
-#ifdef ENABLE_TORCH_IMPORTER
-
 #include "test_precomp.hpp"
 #include "npy_blob.hpp"
 #include <opencv2/dnn/shape_utils.hpp>
@@ -316,9 +314,8 @@ OCL_TEST(Torch_Importer, ENet_accuracy)
     Net net;
     {
         const string model = findDataFile("dnn/Enet-model-best.net", false);
-        Ptr<Importer> importer = createTorchImporter(model, true);
-        ASSERT_TRUE(importer != NULL);
-        importer->populateNet(net);
+        net = readNetFromTorch(model, true);
+        ASSERT_TRUE(!net.empty());
     }
 
     net.setPreferableBackend(DNN_BACKEND_DEFAULT);
@@ -421,5 +418,3 @@ OCL_TEST(Torch_Importer, FastNeuralStyle_accuracy)
 }
 
 }
-
-#endif
index 6558f16..23bb40e 100644 (file)
@@ -956,7 +956,11 @@ void Canny( InputArray _src, OutputArray _dst,
     CV_OCL_RUN(_dst.isUMat() && (_src.channels() == 1 || _src.channels() == 3),
                ocl_Canny<false>(_src, UMat(), UMat(), _dst, (float)low_thresh, (float)high_thresh, aperture_size, L2gradient, _src.channels(), size))
 
-    Mat src = _src.getMat(), dst = _dst.getMat();
+    Mat src0 = _src.getMat(), dst = _dst.getMat();
+    Mat src(src0.size(), src0.type(), src0.data, src0.step);
+
+    CALL_HAL(canny, cv_hal_canny, src.data, src.step, dst.data, dst.step, src.cols, src.rows, src.channels(),
+             low_thresh, high_thresh, aperture_size, L2gradient);
 
     CV_OVX_RUN(
         false && /* disabling due to accuracy issues */
index 0921a84..d6b1d78 100644 (file)
@@ -756,6 +756,22 @@ inline int hal_ni_pyrdown(const uchar* src_data, size_t src_step, int src_width,
 #define cv_hal_pyrdown hal_ni_pyrdown
 //! @endcond
 
+/**
+   @brief Canny edge detector
+   @param src_data,src_step Source image
+   @param dst_data,dst_step Destination image
+   @param width,height Source image dimensions
+   @param cn Number of channels
+   @param lowThreshold, highThreshold Thresholds value
+   @param ksize Kernel size for Sobel operator.
+   @param L2gradient Flag, indicating use L2 or L1 norma.
+*/
+inline int hal_ni_canny(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int cn, double lowThreshold, double highThreshold, int ksize, bool L2gradient) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
+
+//! @cond IGNORED
+#define cv_hal_canny hal_ni_canny
+//! @endcond
+
 //! @}
 
 #if defined __GNUC__
index 5652da2..cd10c0d 100644 (file)
@@ -155,7 +155,7 @@ int SimulatedAnnealingSolver::run()
             if (newEnergy < previousEnergy)
             {
                 previousEnergy = newEnergy;
-                //??? exchange++;
+                exchange++;
             }
             else
             {
@@ -405,21 +405,6 @@ public:
                 param2 = 0.1;
             params.bpMomentScale = std::min(param2, 1.);
         }
-/*        else if (method == ANN_MLP::ANNEAL)
-        {
-            if (param1 <= 0)
-                param1 = 10;
-            if (param2 <= 0 || param2>param1)
-                param2 = 0.1;
-            if (param3 <= 0 || param3 >=1)
-                param3 = 0.95;
-            if (param4 <= 0)
-                param4 = 10;
-            params.initialT = param1;
-            params.finalT = param2;
-            params.coolingRatio = param3;
-            params.itePerStep = param4;
-        }*/
     }
 
     int getTrainMethod() const
index dc03e38..e95674a 100644 (file)
@@ -94,26 +94,29 @@ public:
         int idxErr = range.start;
         CV_TRACE_FUNCTION_SKIP_NESTED();
         Mat samples = data->getSamples();
+        Mat weights=testerr? data->getTestSampleWeights() : data->getTrainSampleWeights();
         int layout = data->getLayout();
         Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
         const int* sidx_ptr = sidx.ptr<int>();
         bool isclassifier = s.isClassifier();
         Mat responses = data->getResponses();
         int responses_type = responses.type();
-
         double err = 0;
 
+
+        const float* sw = weights.empty() ? 0 : weights.ptr<float>();
         for (int i = range.start; i < range.end; i++)
         {
             int si = sidx_ptr ? sidx_ptr[i] : i;
+            double sweight = sw ? static_cast<double>(sw[i]) : 1.;
             Mat sample = layout == ROW_SAMPLE ? samples.row(si) : samples.col(si);
             float val = s.predict(sample);
             float val0 = (responses_type == CV_32S) ? (float)responses.at<int>(si) : responses.at<float>(si);
 
             if (isclassifier)
-                err += fabs(val - val0) > FLT_EPSILON;
+                err += sweight * fabs(val - val0) > FLT_EPSILON;
             else
-                err += (val - val0)*(val - val0);
+                err += sweight * (val - val0)*(val - val0);
             if (!resp.empty())
                 resp.at<float>(i) = val;
         }
@@ -133,12 +136,17 @@ float StatModel::calcError(const Ptr<TrainData>& data, bool testerr, OutputArray
     CV_TRACE_FUNCTION_SKIP_NESTED();
     Mat samples = data->getSamples();
     Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
+    Mat weights = testerr ? data->getTestSampleWeights() : data->getTrainSampleWeights();
     int n = (int)sidx.total();
     bool isclassifier = isClassifier();
     Mat responses = data->getResponses();
 
     if (n == 0)
+    {
         n = data->getNSamples();
+        weights = data->getTrainSampleWeights();
+        testerr =false;
+    }
 
     if (n == 0)
         return -FLT_MAX;
@@ -155,11 +163,11 @@ float StatModel::calcError(const Ptr<TrainData>& data, bool testerr, OutputArray
 
     for (size_t i = 0; i < errStrip.size(); i++)
         err += errStrip[i];
-
+    float weightSum= weights.empty() ? n: static_cast<float>(sum(weights)(0));
     if (_resp.needed())
         resp.copyTo(_resp);
 
-    return (float)(err / n * (isclassifier ? 100 : 1));
+    return (float)(err/ weightSum * (isclassifier ? 100 : 1));
 }
 
 /* Calculates upper triangular matrix S, where A is a symmetrical matrix A=S'*S */
index be61b87..a46ec12 100644 (file)
@@ -8,8 +8,6 @@
 #include <opencv2/objdetect.hpp>
 
 #include <stdio.h>
-#include <string>
-#include <vector>
 
 using namespace std;
 using namespace cv;
@@ -84,7 +82,7 @@ int main(int , char** )
     do
     {
         VideoStream >> ReferenceFrame;
-        cvtColor(ReferenceFrame, GrayFrame, COLOR_RGB2GRAY);
+        cvtColor(ReferenceFrame, GrayFrame, COLOR_BGR2GRAY);
         Detector.process(GrayFrame);
         Detector.getObjects(Faces);
 
index 80d4d46..7c7f4d4 100644 (file)
@@ -15,7 +15,7 @@ using namespace std;
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   Mat src, dst;
 
@@ -23,12 +23,14 @@ int main( int, char** argv )
   const char* equalized_window = "Equalized Image";
 
   /// Load image
-  src = imread( argv[1], IMREAD_COLOR );
-
+  CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
   if( src.empty() )
-    { cout<<"Usage: ./EqualizeHist_Demo <path_to_image>"<<endl;
-      return -1;
-    }
+  {
+    cout << "Could not open or find the image!\n" << endl;
+    cout << "Usage: " << argv[0] << " <Input image>" << endl;
+    return -1;
+  }
 
   /// Convert to grayscale
   cvtColor( src, src, COLOR_BGR2GRAY );
index cfcd755..14526ae 100644 (file)
@@ -5,10 +5,11 @@
  */
 
 #include "opencv2/imgproc.hpp"
-#include "opencv2/imgcodecs.hpp"
 #include "opencv2/highgui.hpp"
+#include <iostream>
 
 using namespace cv;
+using namespace std;
 
 /// Global variables
 Mat src, erosion_dst, dilation_dst;
@@ -27,13 +28,17 @@ void Dilation( int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load an image
-  src = imread( argv[1], IMREAD_COLOR );
-
+  CommandLineParser parser( argc, argv, "{@input | ../data/chicky_512.png | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
   if( src.empty() )
-    { return -1; }
+  {
+    cout << "Could not open or find the image!\n" << endl;
+    cout << "Usage: " << argv[0] << " <Input image>" << endl;
+    return -1;
+  }
 
   /// Create windows
   namedWindow( "Erosion Demo", WINDOW_AUTOSIZE );
index 6f843f6..ce71a3b 100644 (file)
@@ -7,6 +7,7 @@
 #include "opencv2/imgproc.hpp"
 #include "opencv2/imgcodecs.hpp"
 #include "opencv2/highgui.hpp"
+#include <iostream>
 
 using namespace cv;
 
@@ -32,15 +33,14 @@ void Morphology_Operations( int, void* );
 int main( int argc, char** argv )
 {
   //![load]
-  String imageName("../data/baboon.jpg"); // by default
-  if (argc > 1)
+  CommandLineParser parser( argc, argv, "{@input | ../data/baboon.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if (src.empty())
   {
-  imageName = argv[1];
+    std::cout << "Could not open or find the image!\n" << std::endl;
+    std::cout << "Usage: " << argv[0] << " <Input image>" << std::endl;
+    return -1;
   }
-  src = imread(imageName, IMREAD_COLOR); // Load an image
-
-  if( src.empty() )
-    { return -1; }
   //![load]
 
   //![window]
index 1b0b4b7..31b3687 100644 (file)
@@ -11,16 +11,15 @@ void show_wait_destroy(const char* winname, cv::Mat img);
 using namespace std;
 using namespace cv;
 
-int main(int, char** argv)
+int main(int argc, char** argv)
 {
     //! [load_image]
-    // Load the image
-    Mat src = imread(argv[1]);
-
-    // Check if image is loaded fine
-    if(src.empty()){
-        printf(" Error opening image\n");
-        printf(" Program Arguments: [image_path]\n");
+    CommandLineParser parser(argc, argv, "{@input | ../data/notes.png | input image}");
+    Mat src = imread(parser.get<String>("@input"), IMREAD_COLOR);
+    if (src.empty())
+    {
+        cout << "Could not open or find the image!\n" << endl;
+        cout << "Usage: " << argv[0] << " <Input image>" << endl;
         return -1;
     }
 
index efdeca1..e77ef7b 100644 (file)
@@ -5,8 +5,8 @@
  */
 
 #include "opencv2/imgproc.hpp"
-#include "opencv2/imgcodecs.hpp"
 #include "opencv2/highgui.hpp"
+#include <iostream>
 
 using namespace cv;
 
@@ -56,13 +56,18 @@ static void CannyThreshold(int, void*)
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   //![load]
-  src = imread( argv[1], IMREAD_COLOR ); // Load an image
+  CommandLineParser parser( argc, argv, "{@input | ../data/fruits.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR ); // Load an image
 
   if( src.empty() )
-    { return -1; }
+  {
+    std::cout << "Could not open or find the image!\n" << std::endl;
+    std::cout << "Usage: " << argv[0] << " <Input image>" << std::endl;
+    return -1;
+  }
   //![load]
 
   //![create_mat]
index edbb1e7..93250a5 100644 (file)
@@ -20,7 +20,7 @@ const char* warp_rotate_window = "Warp + Rotate";
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   Point2f srcTri[3];
   Point2f dstTri[3];
@@ -30,7 +30,14 @@ int main( int, char** argv )
   Mat src, warp_dst, warp_rotate_dst;
 
   /// Load the image
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/lena.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if( src.empty() )
+  {
+      cout << "Could not open or find the image!\n" << endl;
+      cout << "Usage: " << argv[0] << " <Input image>" << endl;
+      return -1;
+  }
 
   /// Set the dst image the same type and size as src
   warp_dst = Mat::zeros( src.rows, src.cols, src.type() );
index bd07220..2a86941 100644 (file)
@@ -12,7 +12,7 @@ using namespace std;
 int main(int argc, char** argv)
 {
     //![load]
-    const char* filename = argc >=2 ? argv[1] : "../../../data/smarties.png";
+    const char* filename = argc >=2 ? argv[1] : "../data/smarties.png";
 
     // Loads an image
     Mat src = imread( filename, IMREAD_COLOR );
index 57f64c6..8180b9d 100644 (file)
@@ -16,7 +16,7 @@ int main(int argc, char** argv)
     Mat dst, cdst, cdstP;
 
     //![load]
-    const char* default_file = "../../../data/sudoku.png";
+    const char* default_file = "../data/sudoku.png";
     const char* filename = argc >=2 ? argv[1] : default_file;
 
     // Loads an image
index 1e5585a..ea0b2a4 100644 (file)
@@ -23,11 +23,18 @@ void thresh_callback(int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   //![setup]
   /// Load source image
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if( src.empty() )
+    {
+      cout << "Could not open or find the image!\n" << endl;
+      cout << "usage: " << argv[0] << " <Input image>" << endl;
+      return -1;
+    }
 
   /// Convert image to gray and blur it
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
@@ -84,8 +91,8 @@ void thresh_callback(int, void* )
   //![allthework]
   for( size_t i = 0; i < contours.size(); i++ )
   {
-    approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
-    boundRect[i] = boundingRect( Mat(contours_poly[i]) );
+    approxPolyDP( contours[i], contours_poly[i], 3, true );
+    boundRect[i] = boundingRect( contours_poly[i] );
     minEnclosingCircle( contours_poly[i], center[i], radius[i] );
   }
   //![allthework]
index 742c6cf..169f8bf 100644 (file)
@@ -23,10 +23,17 @@ void thresh_callback(int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load source image and convert it to gray
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if( src.empty() )
+    {
+      cout << "Could not open or find the image!\n" << endl;
+      cout << "Usage: " << argv[0] << " <Input image>" << endl;
+      return -1;
+    }
 
   /// Convert image to gray and blur it
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
@@ -63,9 +70,9 @@ void thresh_callback(int, void* )
   vector<RotatedRect> minEllipse( contours.size() );
 
   for( size_t i = 0; i < contours.size(); i++ )
-     { minRect[i] = minAreaRect( Mat(contours[i]) );
+     { minRect[i] = minAreaRect( contours[i] );
        if( contours[i].size() > 5 )
-         { minEllipse[i] = fitEllipse( Mat(contours[i]) ); }
+         { minEllipse[i] = fitEllipse( contours[i] ); }
      }
 
   /// Draw contours + rotated rects + ellipses
index e583791..c155908 100644 (file)
@@ -23,10 +23,17 @@ void thresh_callback(int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load source image and convert it to gray
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if( src.empty() )
+  {
+    cout << "Could not open or find the image!\n" << endl;
+    cout << "Usage: " << argv[0] << " <Input image>" << endl;
+    return -1;
+  }
 
   /// Convert image to gray and blur it
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
@@ -62,7 +69,7 @@ void thresh_callback(int, void* )
   /// Find the convex hull object for each contour
   vector<vector<Point> >hull( contours.size() );
   for( size_t i = 0; i < contours.size(); i++ )
-     {   convexHull( Mat(contours[i]), hull[i], false ); }
+     {   convexHull( contours[i], hull[i], false ); }
 
   /// Draw contours + hull results
   Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
index 4064048..6741cc6 100644 (file)
@@ -23,10 +23,18 @@ void thresh_callback(int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load source image and convert it to gray
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+
+  if( src.empty() )
+  {
+      cout << "Could not open or find the image!\n" << endl;
+      cout << "usage: " << argv[0] << " <Input image>" << endl;
+      exit(0);
+  }
 
   /// Convert image to gray and blur it
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
@@ -51,12 +59,11 @@ void thresh_callback(int, void* )
 {
   Mat canny_output;
   vector<vector<Point> > contours;
-  vector<Vec4i> hierarchy;
 
   /// Detect edges using canny
   Canny( src_gray, canny_output, thresh, thresh*2, 3 );
   /// Find contours
-  findContours( canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
+  findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
 
   /// Get the moments
   vector<Moments> mu(contours.size() );
@@ -73,7 +80,7 @@ void thresh_callback(int, void* )
   for( size_t i = 0; i< contours.size(); i++ )
      {
        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
-       drawContours( drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point() );
+       drawContours( drawing, contours, (int)i, color, 2, LINE_8 );
        circle( drawing, mc[i], 4, color, -1, 8, 0 );
      }
 
@@ -87,7 +94,7 @@ void thresh_callback(int, void* )
      {
        printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", (int)i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );
        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
-       drawContours( drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point() );
+       drawContours( drawing, contours, (int)i, color, 2, LINE_8 );
        circle( drawing, mc[i], 4, color, -1, 8, 0 );
      }
 }
index 757b8dc..efc481a 100644 (file)
@@ -35,10 +35,9 @@ int main( void )
      { line( src, vert[j],  vert[(j+1)%6], Scalar( 255 ), 3, 8 ); }
 
   /// Get the contours
-  vector<vector<Point> > contours; vector<Vec4i> hierarchy;
-  Mat src_copy = src.clone();
+  vector<vector<Point> > contours;
 
-  findContours( src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
+  findContours( src, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);
 
   /// Calculate the distances to the contour
   Mat raw_dist( src.size(), CV_32FC1 );
@@ -67,11 +66,8 @@ int main( void )
           }
      }
 
-  /// Create Window and show your results
-  const char* source_window = "Source";
-  namedWindow( source_window, WINDOW_AUTOSIZE );
-  imshow( source_window, src );
-  namedWindow( "Distance", WINDOW_AUTOSIZE );
+  /// Show your results
+  imshow( "Source", src );
   imshow( "Distance", drawing );
 
   waitKey(0);
index 52d7561..2b8471d 100644 (file)
@@ -4,7 +4,6 @@
  * @author OpenCV team
  */
 
-#include "opencv2/imgcodecs.hpp"
 #include "opencv2/highgui.hpp"
 #include "opencv2/imgproc.hpp"
 #include <iostream>
@@ -36,10 +35,17 @@ void myHarris_function( int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load source image and convert it to gray
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if ( src.empty() )
+  {
+    cout << "Could not open or find the image!\n" << endl;
+    cout << "Usage: " << argv[0] << " <Input image>" << endl;
+    return -1;
+  }
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
 
   /// Set some parameters
index 4f1df4b..2d44eeb 100644 (file)
@@ -4,7 +4,6 @@
  * @author OpenCV team
  */
 
-#include "opencv2/imgcodecs.hpp"
 #include "opencv2/highgui.hpp"
 #include "opencv2/imgproc.hpp"
 #include <iostream>
@@ -26,10 +25,17 @@ void cornerHarris_demo( int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load source image and convert it to gray
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/building.jpg | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if ( src.empty() )
+  {
+    cout << "Could not open or find the image!\n" << endl;
+    cout << "Usage: " << argv[0] << " <Input image>" << endl;
+    return -1;
+  }
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
 
   /// Create a window and a trackbar
index e58faea..daadf41 100644 (file)
@@ -4,7 +4,6 @@
  * @author OpenCV team
  */
 
-#include "opencv2/imgcodecs.hpp"
 #include "opencv2/highgui.hpp"
 #include "opencv2/imgproc.hpp"
 #include <iostream>
@@ -27,10 +26,17 @@ void goodFeaturesToTrack_Demo( int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load source image and convert it to gray
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/pic3.png | input image}" );
+  src = imread(parser.get<String>( "@input" ), IMREAD_COLOR);
+  if ( src.empty() )
+  {
+    cout << "Could not open or find the image!\n" << endl;
+    cout << "Usage: " << argv[0] << " <Input image>" << endl;
+    return -1;
+  }
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
 
   /// Create Window
index 1626646..e72653f 100644 (file)
@@ -27,10 +27,17 @@ void goodFeaturesToTrack_Demo( int, void* );
 /**
  * @function main
  */
-int main( int, char** argv )
+int main( int argc, char** argv )
 {
   /// Load source image and convert it to gray
-  src = imread( argv[1], IMREAD_COLOR );
+  CommandLineParser parser( argc, argv, "{@input | ../data/pic3.png | input image}" );
+  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+  if( src.empty() )
+  {
+    cout << "Could not open or find the image!\n" << endl;
+    cout << "Usage: " << argv[0] << " <Input image>" << endl;
+    return -1;
+  }
   cvtColor( src, src_gray, COLOR_BGR2GRAY );
 
   /// Create Window
index f0e0ff1..1eb1df6 100755 (executable)
@@ -1,7 +1,6 @@
 #include <opencv2/features2d.hpp>
-#include <opencv2/imgcodecs.hpp>
-#include <opencv2/opencv.hpp>
-#include <vector>
+#include <opencv2/imgproc.hpp>
+#include <opencv2/highgui.hpp>
 #include <iostream>
 
 using namespace std;
@@ -10,13 +9,17 @@ using namespace cv;
 const float inlier_threshold = 2.5f; // Distance threshold to identify inliers
 const float nn_match_ratio = 0.8f;   // Nearest neighbor matching ratio
 
-int main(void)
+int main(int argc, char* argv[])
 {
-    Mat img1 = imread("../data/graf1.png", IMREAD_GRAYSCALE);
-    Mat img2 = imread("../data/graf3.png", IMREAD_GRAYSCALE);
+    CommandLineParser parser(argc, argv,
+                             "{@img1 | ../data/graf1.png | input image 1}"
+                             "{@img2 | ../data/graf3.png | input image 2}"
+                             "{@homography | ../data/H1to3p.xml | homography matrix}");
+    Mat img1 = imread(parser.get<String>("@img1"), IMREAD_GRAYSCALE);
+    Mat img2 = imread(parser.get<String>("@img2"), IMREAD_GRAYSCALE);
 
     Mat homography;
-    FileStorage fs("../data/H1to3p.xml", FileStorage::READ);
+    FileStorage fs(parser.get<String>("@homography"), FileStorage::READ);
     fs.getFirstTopLevelNode() >> homography;
 
     vector<KeyPoint> kpts1, kpts2;
@@ -153,16 +153,13 @@ void decomposeHomography(const string &img1Path, const string &img2Path, const S
     //! [decompose-homography-estimated-by-findHomography]
 }
 
-const char* about = "Code for homography tutorial.\n"
-                    "Example 4: decompose the homography matrix.\n";
-
 const char* params
-    = "{ h help         | false | print usage }"
-      "{ image1         |       | path to the source chessboard image (left02.jpg) }"
-      "{ image2         |       | path to the desired chessboard image (left01.jpg) }"
-      "{ intrinsics     |       | path to camera intrinsics (left_intrinsics.yml) }"
-      "{ width        | 9     | chessboard width }"
-      "{ height       | 6     | chessboard height }"
+    = "{ help h         |       | print usage }"
+      "{ image1         | ../data/left02.jpg | path to the source chessboard image }"
+      "{ image2         | ../data/left01.jpg | path to the desired chessboard image }"
+      "{ intrinsics     | ../data/left_intrinsics.yml | path to camera intrinsics }"
+      "{ width bw       | 9     | chessboard width }"
+      "{ height bh      | 6     | chessboard height }"
       "{ square_size    | 0.025 | chessboard square size }";
 }
 
@@ -170,19 +167,20 @@ int main(int argc, char *argv[])
 {
     CommandLineParser parser(argc, argv, params);
 
-    if (parser.get<bool>("help"))
+    if ( parser.has("help") )
     {
-        cout << about << endl;
+        parser.about( "Code for homography tutorial.\n"
+                      "Example 4: decompose the homography matrix.\n" );
         parser.printMessage();
         return 0;
     }
 
     Size patternSize(parser.get<int>("width"), parser.get<int>("height"));
     float squareSize = (float) parser.get<double>("square_size");
-    decomposeHomography(parser.get<string>("image1"),
-                        parser.get<string>("image2"),
+    decomposeHomography(parser.get<String>("image1"),
+                        parser.get<String>("image2"),
                         patternSize, squareSize,
-                        parser.get<string>("intrinsics"));
+                        parser.get<String>("intrinsics"));
 
     return 0;
 }
@@ -168,16 +168,13 @@ void homographyFromCameraDisplacement(const string &img1Path, const string &img2
     waitKey();
 }
 
-const char* about = "Code for homography tutorial.\n"
-                    "Example 3: homography from the camera displacement.\n";
-
 const char* params
-    = "{ h help         | false | print usage }"
-      "{ image1         |       | path to the source chessboard image (left02.jpg) }"
-      "{ image2         |       | path to the desired chessboard image (left01.jpg) }"
-      "{ intrinsics     |       | path to camera intrinsics (left_intrinsics.yml) }"
-      "{ width        | 9     | chessboard width }"
-      "{ height       | 6     | chessboard height }"
+    = "{ help h         |       | print usage }"
+      "{ image1         | ../data/left02.jpg | path to the source chessboard image }"
+      "{ image2         | ../data/left01.jpg | path to the desired chessboard image }"
+      "{ intrinsics     | ../data/left_intrinsics.yml | path to camera intrinsics }"
+      "{ width bw       | 9     | chessboard width }"
+      "{ height bh      | 6     | chessboard height }"
       "{ square_size    | 0.025 | chessboard square size }";
 }
 
@@ -185,19 +182,20 @@ int main(int argc, char *argv[])
 {
     CommandLineParser parser(argc, argv, params);
 
-    if (parser.get<bool>("help"))
+    if (parser.has("help"))
     {
-        cout << about << endl;
+        parser.about("Code for homography tutorial.\n"
+            "Example 3: homography from the camera displacement.\n");
         parser.printMessage();
         return 0;
     }
 
     Size patternSize(parser.get<int>("width"), parser.get<int>("height"));
     float squareSize = (float) parser.get<double>("square_size");
-    homographyFromCameraDisplacement(parser.get<string>("image1"),
-                                     parser.get<string>("image2"),
+    homographyFromCameraDisplacement(parser.get<String>("image1"),
+                                     parser.get<String>("image2"),
                                      patternSize, squareSize,
-                                     parser.get<string>("intrinsics"));
+                                     parser.get<String>("intrinsics"));
 
     return 0;
 }
diff --git a/samples/cpp/tutorial_code/features2D/Homography/left_intrinsics.yml b/samples/cpp/tutorial_code/features2D/Homography/left_intrinsics.yml
deleted file mode 100644 (file)
index 36ca56c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-%YAML:1.0
----
-image_width: 640
-image_height: 480
-board_width: 9
-board_height: 6
-square_size: 1.
-aspectRatio: 1.
-flags: 2
-camera_matrix: !!opencv-matrix
-   rows: 3
-   cols: 3
-   dt: d
-   data: [ 5.3591575307485539e+02, 0., 3.4228314953752817e+02, 0.,
-       5.3591575307485539e+02, 2.3557082321320789e+02, 0., 0., 1. ]
-distortion_coefficients: !!opencv-matrix
-   rows: 5
-   cols: 1
-   dt: d
-   data: [ -2.6637290673868386e-01, -3.8586722644459073e-02,
-       1.7831841406179300e-03, -2.8122035403651473e-04,
-       2.3838760574917545e-01 ]
-avg_reprojection_error: 3.9259109564815858e-01
diff --git a/samples/cpp/tutorial_code/features2D/Homography/panorama_stitching_rotating_camera.cpp b/samples/cpp/tutorial_code/features2D/Homography/panorama_stitching_rotating_camera.cpp
new file mode 100755 (executable)
index 0000000..c2eedc5
--- /dev/null
@@ -0,0 +1,88 @@
+#include <iostream>
+#include <opencv2/opencv.hpp>
+
+using namespace std;
+using namespace cv;
+
+namespace
+{
+void basicPanoramaStitching(const string &img1Path, const string &img2Path)
+{
+    Mat img1 = imread(img1Path);
+    Mat img2 = imread(img2Path);
+
+    //! [camera-pose-from-Blender-at-location-1]
+    Mat c1Mo = (Mat_<double>(4,4) << 0.9659258723258972, 0.2588190734386444, 0.0, 1.5529145002365112,
+                                     0.08852133899927139, -0.3303661346435547, -0.9396926164627075, -0.10281121730804443,
+                                     -0.24321036040782928, 0.9076734185218811, -0.342020183801651, 6.130080699920654,
+                                     0, 0, 0, 1);
+    //! [camera-pose-from-Blender-at-location-1]
+
+    //! [camera-pose-from-Blender-at-location-2]
+    Mat c2Mo = (Mat_<double>(4,4) << 0.9659258723258972, -0.2588190734386444, 0.0, -1.5529145002365112,
+                                     -0.08852133899927139, -0.3303661346435547, -0.9396926164627075, -0.10281121730804443,
+                                     0.24321036040782928, 0.9076734185218811, -0.342020183801651, 6.130080699920654,
+                                     0, 0, 0, 1);
+    //! [camera-pose-from-Blender-at-location-2]
+
+    //! [camera-intrinsics-from-Blender]
+    Mat cameraMatrix = (Mat_<double>(3,3) << 700.0, 0.0, 320.0,
+                                             0.0, 700.0, 240.0,
+                                             0, 0, 1);
+    //! [camera-intrinsics-from-Blender]
+
+    //! [extract-rotation]
+    Mat R1 = c1Mo(Range(0,3), Range(0,3));
+    Mat R2 = c2Mo(Range(0,3), Range(0,3));
+    //! [extract-rotation]
+
+    //! [compute-rotation-displacement]
+    //c1Mo * oMc2
+    Mat R_2to1 = R1*R2.t();
+    //! [compute-rotation-displacement]
+
+    //! [compute-homography]
+    Mat H = cameraMatrix * R_2to1 * cameraMatrix.inv();
+    H /= H.at<double>(2,2);
+    cout << "H:\n" << H << endl;
+    //! [compute-homography]
+
+    //! [stitch]
+    Mat img_stitch;
+    warpPerspective(img2, img_stitch, H, Size(img2.cols*2, img2.rows));
+    Mat half = img_stitch(Rect(0, 0, img1.cols, img1.rows));
+    img1.copyTo(half);
+    //! [stitch]
+
+    Mat img_compare;
+    Mat img_space = Mat::zeros(Size(50, img1.rows), CV_8UC3);
+    hconcat(img1, img_space, img_compare);
+    hconcat(img_compare, img2, img_compare);
+    imshow("Compare images", img_compare);
+
+    imshow("Panorama stitching", img_stitch);
+    waitKey();
+}
+
+const char* params
+    = "{ help h         |                              | print usage }"
+      "{ image1         | ../data/Blender_Suzanne1.jpg | path to the first Blender image }"
+      "{ image2         | ../data/Blender_Suzanne2.jpg | path to the second Blender image }";
+}
+
+int main(int argc, char *argv[])
+{
+    CommandLineParser parser(argc, argv, params);
+
+    if (parser.has("help"))
+    {
+        parser.about( "Code for homography tutorial.\n"
+                      "Example 5: basic panorama stitching from a rotating camera.\n" );
+        parser.printMessage();
+        return 0;
+    }
+
+    basicPanoramaStitching(parser.get<String>("image1"), parser.get<String>("image2"));
+
+    return 0;
+}
@@ -92,15 +92,12 @@ void perspectiveCorrection(const string &img1Path, const string &img2Path, const
     //! [compute-transformed-corners]
 }
 
-const char* about = "Code for homography tutorial.\n"
-                    "Example 2: perspective correction.\n";
-
 const char* params
-    = "{ h help         | false | print usage }"
-      "{ image1         |       | path to the source chessboard image (left02.jpg) }"
-      "{ image2         |       | path to the desired chessboard image (left01.jpg) }"
-      "{ width        | 9     | chessboard width }"
-      "{ height       | 6     | chessboard height }";
+    = "{ help h         |       | print usage }"
+      "{ image1         | ../data/left02.jpg | path to the source chessboard image }"
+      "{ image2         | ../data/left01.jpg | path to the desired chessboard image }"
+      "{ width bw       | 9     | chessboard width }"
+      "{ height bh      | 6     | chessboard height }";
 }
 
 int main(int argc, char *argv[])
@@ -108,16 +105,17 @@ int main(int argc, char *argv[])
     cv::RNG rng( 0xFFFFFFFF );
     CommandLineParser parser(argc, argv, params);
 
-    if (parser.get<bool>("help"))
+    if (parser.has("help"))
     {
-        cout << about << endl;
+        parser.about("Code for homography tutorial.\n"
+            "Example 2: perspective correction.\n");
         parser.printMessage();
         return 0;
     }
 
     Size patternSize(parser.get<int>("width"), parser.get<int>("height"));
-    perspectiveCorrection(parser.get<string>("image1"),
-                          parser.get<string>("image2"),
+    perspectiveCorrection(parser.get<String>("image1"),
+                          parser.get<String>("image2"),
                           patternSize, rng);
 
     return 0;
@@ -107,6 +107,14 @@ void poseEstimationFromCoplanarPoints(const string &imgPath, const string &intri
     }
     //! [pose-from-homography]
 
+    //! [polar-decomposition-of-the-rotation-matrix]
+    cout << "R (before polar decomposition):\n" << R << "\ndet(R): " << determinant(R) << endl;
+    Mat W, U, Vt;
+    SVDecomp(R, W, U, Vt);
+    R = U*Vt;
+    cout << "R (after polar decomposition):\n" << R << "\ndet(R): " << determinant(R) << endl;
+    //! [polar-decomposition-of-the-rotation-matrix]
+
     //! [display-pose]
     Mat rvec;
     Rodrigues(R, rvec);
@@ -116,15 +124,12 @@ void poseEstimationFromCoplanarPoints(const string &imgPath, const string &intri
     //! [display-pose]
 }
 
-const char* about = "Code for homography tutorial.\n"
-                    "Example 1: pose from homography with coplanar points.\n";
-
 const char* params
-    = "{ h help         | false | print usage }"
-      "{ image          |       | path to a chessboard image (left04.jpg) }"
-      "{ intrinsics     |       | path to camera intrinsics (left_intrinsics.yml) }"
-      "{ width        | 9     | chessboard width }"
-      "{ height       | 6     | chessboard height }"
+    = "{ help h         |       | print usage }"
+      "{ image          | ../data/left04.jpg | path to a chessboard image }"
+      "{ intrinsics     | ../data/left_intrinsics.yml | path to camera intrinsics }"
+      "{ width bw       | 9     | chessboard width }"
+      "{ height bh      | 6     | chessboard height }"
       "{ square_size    | 0.025 | chessboard square size }";
 }
 
@@ -132,17 +137,18 @@ int main(int argc, char *argv[])
 {
     CommandLineParser parser(argc, argv, params);
 
-    if (parser.get<bool>("help"))
+    if (parser.has("help"))
     {
-        cout << about << endl;
+        parser.about("Code for homography tutorial.\n"
+            "Example 1: pose from homography with coplanar points.\n");
         parser.printMessage();
         return 0;
     }
 
     Size patternSize(parser.get<int>("width"), parser.get<int>("height"));
     float squareSize = (float) parser.get<double>("square_size");
-    poseEstimationFromCoplanarPoints(parser.get<string>("image"),
-                                     parser.get<string>("intrinsics"),
+    poseEstimationFromCoplanarPoints(parser.get<String>("image"),
+                                     parser.get<String>("intrinsics"),
                                      patternSize, squareSize);
 
     return 0;
index 851b32c..489bb88 100644 (file)
@@ -4,8 +4,10 @@
  * @author OpenCV team
  */
 
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/highgui.hpp"
 #include <iostream>
-#include <opencv2/opencv.hpp>
 
 using namespace std;
 using namespace cv;
@@ -30,16 +32,16 @@ void drawAxis(Mat& img, Point p, Point q, Scalar colour, const float scale = 0.2
     // Here we lengthen the arrow by a factor of scale
     q.x = (int) (p.x - scale * hypotenuse * cos(angle));
     q.y = (int) (p.y - scale * hypotenuse * sin(angle));
-    line(img, p, q, colour, 1, CV_AA);
+    line(img, p, q, colour, 1, LINE_AA);
 
     // create the arrow hooks
     p.x = (int) (q.x + 9 * cos(angle + CV_PI / 4));
     p.y = (int) (q.y + 9 * sin(angle + CV_PI / 4));
-    line(img, p, q, colour, 1, CV_AA);
+    line(img, p, q, colour, 1, LINE_AA);
 
     p.x = (int) (q.x + 9 * cos(angle - CV_PI / 4));
     p.y = (int) (q.y + 9 * sin(angle - CV_PI / 4));
-    line(img, p, q, colour, 1, CV_AA);
+    line(img, p, q, colour, 1, LINE_AA);
 //! [visualization1]
 }
 
@@ -59,7 +61,7 @@ double getOrientation(const vector<Point> &pts, Mat &img)
     }
 
     //Perform PCA analysis
-    PCA pca_analysis(data_pts, Mat(), CV_PCA_DATA_AS_ROW);
+    PCA pca_analysis(data_pts, Mat(), PCA::DATA_AS_ROW);
 
     //Store the center of the object
     Point cntr = Point(static_cast<int>(pca_analysis.mean.at<double>(0, 0)),
@@ -98,15 +100,14 @@ int main(int argc, char** argv)
 {
 //! [pre-process]
     // Load image
-    String imageName("../data/pca_test1.jpg"); // by default
-    if (argc > 1)
-    {
-        imageName = argv[1];
-    }
-    Mat src = imread( imageName );
+    CommandLineParser parser(argc, argv, "{@input | ../data/pca_test1.jpg | input image}");
+    parser.about( "This program demonstrates how to use OpenCV PCA to extract the orienation of an object.\n" );
+    parser.printMessage();
+
+    Mat src = imread(parser.get<String>("@input"));
 
     // Check if image is loaded successfully
-    if(!src.data || src.empty())
+    if(src.empty())
     {
         cout << "Problem loading image!!!" << endl;
         return EXIT_FAILURE;
@@ -120,14 +121,13 @@ int main(int argc, char** argv)
 
     // Convert image to binary
     Mat bw;
-    threshold(gray, bw, 50, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
+    threshold(gray, bw, 50, 255, THRESH_BINARY | THRESH_OTSU);
 //! [pre-process]
 
 //! [contours]
     // Find all the contours in the thresholded image
-    vector<Vec4i> hierarchy;
     vector<vector<Point> > contours;
-    findContours(bw, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
+    findContours(bw, contours, RETR_LIST, CHAIN_APPROX_NONE);
 
     for (size_t i = 0; i < contours.size(); ++i)
     {
@@ -137,7 +137,7 @@ int main(int argc, char** argv)
         if (area < 1e2 || 1e5 < area) continue;
 
         // Draw each contour only for visualisation purposes
-        drawContours(src, contours, static_cast<int>(i), Scalar(0, 0, 255), 2, 8, hierarchy, 0);
+        drawContours(src, contours, static_cast<int>(i), Scalar(0, 0, 255), 2, LINE_8);
         // Find the orientation of each shape
         getOrientation(contours[i], src);
     }
index 71097a8..6aa3f91 100644 (file)
@@ -1,9 +1,7 @@
 #include "opencv2/objdetect.hpp"
-#include "opencv2/videoio.hpp"
 #include "opencv2/highgui.hpp"
 #include "opencv2/imgproc.hpp"
 
-#include <iostream>
 #include <stdio.h>
 
 using namespace std;
@@ -26,12 +24,12 @@ int main( int argc, const char** argv )
         "{face_cascade|../../data/haarcascades/haarcascade_frontalface_alt.xml|}"
         "{eyes_cascade|../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}");
 
-    cout << "\nThis program demonstrates using the cv::CascadeClassifier class to detect objects (Face + eyes) in a video stream.\n"
-            "You can use Haar or LBP features.\n\n";
+    parser.about( "\nThis program demonstrates using the cv::CascadeClassifier class to detect objects (Face + eyes) in a video stream.\n"
+                  "You can use Haar or LBP features.\n\n" );
     parser.printMessage();
 
-    face_cascade_name = parser.get<string>("face_cascade");
-    eyes_cascade_name = parser.get<string>("eyes_cascade");
+    face_cascade_name = parser.get<String>("face_cascade");
+    eyes_cascade_name = parser.get<String>("eyes_cascade");
     VideoCapture capture;
     Mat frame;
 
@@ -54,8 +52,7 @@ int main( int argc, const char** argv )
         //-- 3. Apply the classifier to the frame
         detectAndDisplay( frame );
 
-        char c = (char)waitKey(10);
-        if( c == 27 ) { break; } // escape
+        if( waitKey(10) == 27 ) { break; } // escape
     }
     return 0;
 }
@@ -70,7 +67,7 @@ void detectAndDisplay( Mat frame )
     equalizeHist( frame_gray, frame_gray );
 
     //-- Detect faces
-    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );
+    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(60, 60) );
 
     for ( size_t i = 0; i < faces.size(); i++ )
     {
index 13c1b0c..c566dc7 100644 (file)
 using namespace std;
 using namespace cv;
 
-int main(int argc, char *argv[])
+int main( int argc, char *argv[] )
 {
-    CV_Assert(argc == 2);
-    Mat src;
-    src = imread(argv[1], IMREAD_COLOR);
+    CommandLineParser parser( argc, argv, "{@input | ../data/HappyFish.jpg | input image}" );
+    Mat src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
+    if ( src.empty() )
+    {
+        cout << "Could not open or find the image!\n" << endl;
+        cout << "Usage: " << argv[0] << " <Input image>" << endl;
+        return -1;
+    }
+    Mat gray = Mat( src.size(), CV_8UC1 );
+    Mat color_boost = Mat( src.size(), CV_8UC3 );
 
-    Mat gray = Mat(src.size(),CV_8UC1);
-    Mat color_boost = Mat(src.size(),CV_8UC3);
-
-    decolor(src,gray,color_boost);
-    imshow("grayscale",gray);
-    imshow("color_boost",color_boost);
+    decolor( src, gray, color_boost );
+    imshow( "grayscale", gray );
+    imshow( "color_boost", color_boost );
     waitKey(0);
 }
index 8a24ddb..244e31a 100644 (file)
 *
 */
 
-#include <signal.h>
 #include "opencv2/photo.hpp"
 #include "opencv2/imgproc.hpp"
 #include "opencv2/highgui.hpp"
-#include "opencv2/core.hpp"
 #include <iostream>
-#include <stdlib.h>
 
 using namespace std;
 using namespace cv;
 
 int main(int argc, char* argv[])
 {
-    if(argc < 2)
-    {
-        cout << "usage: " << argv[0] << " <Input image> "  << endl;
-        exit(0);
-    }
-
     int num,type;
-
-    Mat src = imread(argv[1], IMREAD_COLOR);
+    CommandLineParser parser(argc, argv, "{@input | ../data/lena.jpg | input image}");
+    Mat src = imread(parser.get<String>("@input"), IMREAD_COLOR);
 
     if(src.empty())
     {
-        cout <<  "Image not found" << endl;
+        cout << "Could not open or find the image!\n" << endl;
+        cout << "Usage: " << argv[0] << " <Input image>" << endl;
         exit(0);
     }
 
index 1b15737..0fb3735 100644 (file)
@@ -32,10 +32,10 @@ void  KeyboardViz3d(const viz::KeyboardEvent &w, void *t);
 void DrawHistogram3D(Histo3DData &h)
 {
     //! [get_cube_size]
-    int planSize = h.histogram.step1(0);
-    int cols = h.histogram.step1(1);
-    int rows = planSize / cols;
-    int plans = h.histogram.total() / planSize;
+    int planSize = (int)h.histogram.step1(0);
+    int cols = (int)h.histogram.step1(1);
+    int rows = (int)planSize / cols;
+    int plans = (int)h.histogram.total() / planSize;
     h.fen3D->removeAllWidgets();
     h.nbWidget=0;
     if (h.nbWidget==0)
index 529a842..5de82bd 100644 (file)
@@ -56,12 +56,12 @@ int main()
     {
         /* Rotation using rodrigues */
         /// Rotate around (1,1,1)
-        rot_vec.at<float>(0,0) += CV_PI * 0.01f;
-        rot_vec.at<float>(0,1) += CV_PI * 0.01f;
-        rot_vec.at<float>(0,2) += CV_PI * 0.01f;
+        rot_vec.at<float>(0,0) += (float)CV_PI * 0.01f;
+        rot_vec.at<float>(0,1) += (float)CV_PI * 0.01f;
+        rot_vec.at<float>(0,2) += (float)CV_PI * 0.01f;
 
         /// Shift on (1,1,1)
-        translation_phase += CV_PI * 0.01f;
+        translation_phase += (float)CV_PI * 0.01f;
         translation = sin(translation_phase);
 
         Mat rot_mat;
index c118b76..04f2c3c 100644 (file)
@@ -19,15 +19,17 @@ using namespace cv;
 const float inlier_threshold = 2.5f; // Distance threshold to identify inliers
 const float nn_match_ratio = 0.8f;   // Nearest neighbor matching ratio
 
-int main(void)
+int main(int argc, char* argv[])
 {
-    Mat img1 = imread("../data/graf1.png", IMREAD_GRAYSCALE);
-    Mat img2 = imread("../data/graf3.png", IMREAD_GRAYSCALE);
-
+    CommandLineParser parser(argc, argv,
+                             "{@img1 | ../data/graf1.png | input image 1}"
+                             "{@img2 | ../data/graf3.png | input image 2}"
+                             "{@homography | ../data/H1to3p.xml | homography matrix}");
+    Mat img1 = imread(parser.get<String>("@img1"), IMREAD_GRAYSCALE);
+    Mat img2 = imread(parser.get<String>("@img2"), IMREAD_GRAYSCALE);
 
     Mat homography;
-    FileStorage fs("../data/H1to3p.xml", FileStorage::READ);
-
+    FileStorage fs(parser.get<String>("@homography"), FileStorage::READ);
     fs.getFirstTopLevelNode() >> homography;
 
     vector<KeyPoint> kpts1, kpts2;
diff --git a/samples/data/Blender_Suzanne1.jpg b/samples/data/Blender_Suzanne1.jpg
new file mode 100644 (file)
index 0000000..e4f370e
Binary files /dev/null and b/samples/data/Blender_Suzanne1.jpg differ
diff --git a/samples/data/Blender_Suzanne2.jpg b/samples/data/Blender_Suzanne2.jpg
new file mode 100644 (file)
index 0000000..ff665eb
Binary files /dev/null and b/samples/data/Blender_Suzanne2.jpg differ
diff --git a/samples/data/left_intrinsics.yml b/samples/data/left_intrinsics.yml
new file mode 100644 (file)
index 0000000..a90a02e
--- /dev/null
@@ -0,0 +1,75 @@
+%YAML:1.0
+---
+nframes: 13
+image_width: 640
+image_height: 480
+board_width: 9
+board_height: 6
+square_size: 2.5000000372529030e-02
+aspectRatio: 1.
+flags: 2
+camera_matrix: !!opencv-matrix
+   rows: 3
+   cols: 3
+   dt: d
+   data: [ 5.3591573396163199e+02, 0., 3.4228315473308373e+02, 0.,
+       5.3591573396163199e+02, 2.3557082909788173e+02, 0., 0., 1. ]
+distortion_coefficients: !!opencv-matrix
+   rows: 5
+   cols: 1
+   dt: d
+   data: [ -2.6637260909660682e-01, -3.8588898922304653e-02,
+       1.7831947042852964e-03, -2.8122100441115472e-04,
+       2.3839153080878486e-01 ]
+avg_reprojection_error: 3.9259098975581364e-01
+per_view_reprojection_errors: !!opencv-matrix
+   rows: 13
+   cols: 1
+   dt: f
+   data: [ 1.92965463e-01, 1.18204820e+00, 1.73180386e-01,
+       1.93417311e-01, 1.59574091e-01, 1.79683909e-01, 2.30989486e-01,
+       2.41952404e-01, 2.96267658e-01, 1.67184874e-01, 2.02002615e-01,
+       3.81039530e-01, 1.74401343e-01 ]
+extrinsic_parameters: !!opencv-matrix
+   rows: 13
+   cols: 6
+   dt: d
+   data: [ 1.6866673097722978e-01, 2.7567195383689680e-01,
+       1.3463666677617407e-02, -7.5217911266918208e-02,
+       -1.0895943925991841e-01, 3.9970206949907272e-01,
+       4.1331287656496363e-01, 6.4989015618432178e-01,
+       -1.3371537960145106e+00, -5.8571677080547203e-02,
+       8.2925805670236566e-02, 3.5381014833230601e-01,
+       -2.7703695013795054e-01, 1.8693309320100124e-01,
+       3.5485225341087834e-01, -3.9846501015652937e-02,
+       -1.0041611109510440e-01, 3.1815947023777164e-01,
+       -1.1090615673109079e-01, 2.3965970843402720e-01,
+       -2.1135637810781923e-03, -9.8410654744228568e-02,
+       -6.7330010965873974e-02, 3.3085237266887146e-01,
+       -2.9186914919266310e-01, 4.2838824536930098e-01,
+       1.3127376448141377e+00, 5.8492717894568363e-02,
+       -1.1531702553211766e-01, 3.1718597226747441e-01,
+       4.0775746983982769e-01, 3.0372749654555553e-01,
+       1.6490540383167107e+00, 1.6727077792571535e-01,
+       -6.5571043573575183e-02, 3.3646131272177648e-01,
+       1.7933504280050525e-01, 3.4558984092172601e-01,
+       1.8685292421609112e+00, 1.9533408668697443e-02,
+       -7.1821904367276174e-02, 3.8942937075181105e-01,
+       -9.0969163793927624e-02, 4.7978599772080688e-01,
+       1.7534054022831906e+00, 7.9050417654120575e-02,
+       -8.7941963150599309e-02, 3.1666076957685929e-01,
+       2.0297932232462285e-01, -4.2392077549829726e-01,
+       1.3241327935810543e-01, -6.6346241810532544e-02,
+       -8.1019305580944570e-02, 2.7830224494208888e-01,
+       -4.1905731583840156e-01, -4.9969284527936553e-01,
+       1.3355787183928016e+00, 4.6902734761583582e-02,
+       -1.1100626108196045e-01, 3.3805630488128308e-01,
+       -2.3853178487346252e-01, 3.4785724405059820e-01,
+       1.5307655926865789e+00, 5.0764487316281588e-02,
+       -1.0259706994505384e-01, 3.2220131320183526e-01,
+       4.6395663682204152e-01, -2.8347019688901215e-01,
+       1.2385662249906069e+00, 3.3699309698414767e-02,
+       -9.1617248179872074e-02, 2.9144614839683858e-01,
+       -1.6997848268735108e-01, -4.7116903885245226e-01,
+       1.3459942250907577e+00, 4.5015523494596366e-02,
+       -1.0817857239600029e-01, 3.1243767202759759e-01 ]
index 67193d9..5d92021 100644 (file)
@@ -1,24 +1,3 @@
-// Faster-RCNN models use custom layer called 'Proposal' written in Python. To
-// map it into OpenCV's layer replace a layer node with [type: 'Python'] to the
-// following definition:
-// layer {
-//   name: 'proposal'
-//   type: 'Proposal'
-//   bottom: 'rpn_cls_prob_reshape'
-//   bottom: 'rpn_bbox_pred'
-//   bottom: 'im_info'
-//   top: 'rois'
-//   proposal_param {
-//     ratio: 0.5
-//     ratio: 1.0
-//     ratio: 2.0
-//     scale: 8
-//     scale: 16
-//     scale: 32
-//   }
-// }
-#include <iostream>
-
 #include <opencv2/dnn.hpp>
 #include <opencv2/dnn/all_layers.hpp>
 #include <opencv2/imgproc.hpp>
@@ -27,9 +6,6 @@
 using namespace cv;
 using namespace dnn;
 
-const char* about = "This sample is used to run Faster-RCNN object detection "
-                    "models from https://github.com/rbgirshick/py-faster-rcnn with OpenCV.";
-
 const char* keys =
     "{ help  h |     | print help message  }"
     "{ proto p |     | path to .prototxt   }"
@@ -53,9 +29,14 @@ int main(int argc, char** argv)
 {
     // Parse command line arguments.
     CommandLineParser parser(argc, argv, keys);
+    parser.about("This sample is used to run Faster-RCNN and R-FCN object detection "
+                 "models with OpenCV. You can get required models from "
+                 "https://github.com/rbgirshick/py-faster-rcnn (Faster-RCNN) and from "
+                 "https://github.com/YuwenXiong/py-R-FCN (R-FCN). Corresponding .prototxt "
+                 "files may be found at https://github.com/opencv/opencv_extra/tree/master/testdata/dnn.");
     if (argc == 1 || parser.has("help"))
     {
-        std::cout << about << std::endl;
+        parser.printMessage();
         return 0;
     }
 
@@ -68,19 +49,6 @@ int main(int argc, char** argv)
     // Load a model.
     Net net = readNetFromCaffe(protoPath, modelPath);
 
-    // Create a preprocessing layer that does final bounding boxes applying predicted
-    // deltas to objects locations proposals and doing non-maximum suppression over it.
-    LayerParams lp;
-    lp.set("code_type", "CENTER_SIZE");               // An every bounding box is [xmin, ymin, xmax, ymax]
-    lp.set("num_classes", 21);
-    lp.set("share_location", (int)false);             // Separate predictions for different classes.
-    lp.set("background_label_id", 0);
-    lp.set("variance_encoded_in_target", (int)true);
-    lp.set("keep_top_k", 100);
-    lp.set("nms_threshold", 0.3);
-    lp.set("normalized_bbox", (int)false);
-    Ptr<Layer> detectionOutputLayer = DetectionOutputLayer::create(lp);
-
     Mat img = imread(imagePath);
     resize(img, img, Size(kInpWidth, kInpHeight));
     Mat blob = blobFromImage(img, 1.0, Size(), Scalar(102.9801, 115.9465, 122.7717), false, false);
@@ -89,31 +57,8 @@ int main(int argc, char** argv)
     net.setInput(blob, "data");
     net.setInput(imInfo, "im_info");
 
-    std::vector<Mat> outs;
-    std::vector<String> outNames(3);
-    outNames[0] = "proposal";
-    outNames[1] = "bbox_pred";
-    outNames[2] = "cls_prob";
-    net.forward(outs, outNames);
-
-    Mat proposals = outs[0].colRange(1, 5).clone();  // Only last 4 columns.
-    Mat& deltas = outs[1];
-    Mat& scores = outs[2];
-
-    // Reshape proposals from Nx4 to 1x1xN*4
-    std::vector<int> shape(3, 1);
-    shape[2] = (int)proposals.total();
-    proposals = proposals.reshape(1, shape);
-
-    // Run postprocessing layer.
-    std::vector<Mat> layerInputs(3), layerOutputs(1), layerInternals;
-    layerInputs[0] = deltas.reshape(1, 1);
-    layerInputs[1] = scores.reshape(1, 1);
-    layerInputs[2] = proposals;
-    detectionOutputLayer->forward(layerInputs, layerOutputs, layerInternals);
-
     // Draw detections.
-    Mat detections = layerOutputs[0];
+    Mat detections = net.forward();
     const float* data = (float*)detections.data;
     for (size_t i = 0; i < detections.total(); i += 7)
     {
diff --git a/samples/python/camera_calibration_show_extrinsics.py b/samples/python/camera_calibration_show_extrinsics.py
new file mode 100755 (executable)
index 0000000..7b1b0cf
--- /dev/null
@@ -0,0 +1,216 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from mpl_toolkits.mplot3d import Axes3D
+import matplotlib.pyplot as plt
+import numpy as np
+from matplotlib import cm
+from numpy import linspace
+import argparse
+import cv2 as cv
+
+def inverse_homogeneoux_matrix(M):
+    R = M[0:3, 0:3]
+    T = M[0:3, 3]
+    M_inv = np.identity(4)
+    M_inv[0:3, 0:3] = R.T
+    M_inv[0:3, 3] = -(R.T).dot(T)
+
+    return M_inv
+
+def transform_to_matplotlib_frame(cMo, X, inverse=False):
+    M = np.identity(4)
+    M[1,1] = 0
+    M[1,2] = 1
+    M[2,1] = -1
+    M[2,2] = 0
+
+    if inverse:
+        return M.dot(inverse_homogeneoux_matrix(cMo).dot(X))
+    else:
+        return M.dot(cMo.dot(X))
+
+def create_camera_model(camera_matrix, width, height, scale_focal, draw_frame_axis=False):
+    fx = camera_matrix[0,0]
+    fy = camera_matrix[1,1]
+    focal = 2 / (fx + fy)
+    f_scale = scale_focal * focal
+
+    # draw image plane
+    X_img_plane = np.ones((4,5))
+    X_img_plane[0:3,0] = [-width, height, f_scale]
+    X_img_plane[0:3,1] = [width, height, f_scale]
+    X_img_plane[0:3,2] = [width, -height, f_scale]
+    X_img_plane[0:3,3] = [-width, -height, f_scale]
+    X_img_plane[0:3,4] = [-width, height, f_scale]
+
+    # draw triangle above the image plane
+    X_triangle = np.ones((4,3))
+    X_triangle[0:3,0] = [-width, -height, f_scale]
+    X_triangle[0:3,1] = [0, -2*height, f_scale]
+    X_triangle[0:3,2] = [width, -height, f_scale]
+
+    # draw camera
+    X_center1 = np.ones((4,2))
+    X_center1[0:3,0] = [0, 0, 0]
+    X_center1[0:3,1] = [-width, height, f_scale]
+
+    X_center2 = np.ones((4,2))
+    X_center2[0:3,0] = [0, 0, 0]
+    X_center2[0:3,1] = [width, height, f_scale]
+
+    X_center3 = np.ones((4,2))
+    X_center3[0:3,0] = [0, 0, 0]
+    X_center3[0:3,1] = [width, -height, f_scale]
+
+    X_center4 = np.ones((4,2))
+    X_center4[0:3,0] = [0, 0, 0]
+    X_center4[0:3,1] = [-width, -height, f_scale]
+
+    # draw camera frame axis
+    X_frame1 = np.ones((4,2))
+    X_frame1[0:3,0] = [0, 0, 0]
+    X_frame1[0:3,1] = [f_scale/2, 0, 0]
+
+    X_frame2 = np.ones((4,2))
+    X_frame2[0:3,0] = [0, 0, 0]
+    X_frame2[0:3,1] = [0, f_scale/2, 0]
+
+    X_frame3 = np.ones((4,2))
+    X_frame3[0:3,0] = [0, 0, 0]
+    X_frame3[0:3,1] = [0, 0, f_scale/2]
+
+    if draw_frame_axis:
+        return [X_img_plane, X_triangle, X_center1, X_center2, X_center3, X_center4, X_frame1, X_frame2, X_frame3]
+    else:
+        return [X_img_plane, X_triangle, X_center1, X_center2, X_center3, X_center4]
+
+def create_board_model(extrinsics, board_width, board_height, square_size, draw_frame_axis=False):
+    width = board_width*square_size
+    height = board_height*square_size
+
+    # draw calibration board
+    X_board = np.ones((4,5))
+    X_board_cam = np.ones((extrinsics.shape[0],4,5))
+    X_board[0:3,0] = [0,0,0]
+    X_board[0:3,1] = [width,0,0]
+    X_board[0:3,2] = [width,height,0]
+    X_board[0:3,3] = [0,height,0]
+    X_board[0:3,4] = [0,0,0]
+
+    # draw board frame axis
+    X_frame1 = np.ones((4,2))
+    X_frame1[0:3,0] = [0, 0, 0]
+    X_frame1[0:3,1] = [height/2, 0, 0]
+
+    X_frame2 = np.ones((4,2))
+    X_frame2[0:3,0] = [0, 0, 0]
+    X_frame2[0:3,1] = [0, height/2, 0]
+
+    X_frame3 = np.ones((4,2))
+    X_frame3[0:3,0] = [0, 0, 0]
+    X_frame3[0:3,1] = [0, 0, height/2]
+
+    if draw_frame_axis:
+        return [X_board, X_frame1, X_frame2, X_frame3]
+    else:
+        return [X_board]
+
+def draw_camera_boards(ax, camera_matrix, cam_width, cam_height, scale_focal,
+                       extrinsics, board_width, board_height, square_size,
+                       patternCentric):
+    min_values = np.zeros((3,1))
+    min_values = np.inf
+    max_values = np.zeros((3,1))
+    max_values = -np.inf
+
+    if patternCentric:
+        X_moving = create_camera_model(camera_matrix, cam_width, cam_height, scale_focal)
+        X_static = create_board_model(extrinsics, board_width, board_height, square_size)
+    else:
+        X_static = create_camera_model(camera_matrix, cam_width, cam_height, scale_focal, True)
+        X_moving = create_board_model(extrinsics, board_width, board_height, square_size)
+
+    cm_subsection = linspace(0.0, 1.0, extrinsics.shape[0])
+    colors = [ cm.jet(x) for x in cm_subsection ]
+
+    for i in range(len(X_static)):
+        X = np.zeros(X_static[i].shape)
+        for j in range(X_static[i].shape[1]):
+            X[:,j] = transform_to_matplotlib_frame(np.eye(4), X_static[i][:,j])
+        ax.plot3D(X[0,:], X[1,:], X[2,:], color='r')
+        min_values = np.minimum(min_values, X[0:3,:].min(1))
+        max_values = np.maximum(max_values, X[0:3,:].max(1))
+
+    for idx in range(extrinsics.shape[0]):
+        R, _ = cv.Rodrigues(extrinsics[idx,0:3])
+        cMo = np.eye(4,4)
+        cMo[0:3,0:3] = R
+        cMo[0:3,3] = extrinsics[idx,3:6]
+        for i in range(len(X_moving)):
+            X = np.zeros(X_moving[i].shape)
+            for j in range(X_moving[i].shape[1]):
+                X[0:4,j] = transform_to_matplotlib_frame(cMo, X_moving[i][0:4,j], patternCentric)
+            ax.plot3D(X[0,:], X[1,:], X[2,:], color=colors[idx])
+            min_values = np.minimum(min_values, X[0:3,:].min(1))
+            max_values = np.maximum(max_values, X[0:3,:].max(1))
+
+    return min_values, max_values
+
+def main():
+    parser = argparse.ArgumentParser(description='Plot camera calibration extrinsics.',
+                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+    parser.add_argument('--calibration', type=str, default="../data/left_intrinsics.yml",
+                        help='YAML camera calibration file.')
+    parser.add_argument('--cam_width', type=float, default=0.064/2,
+                        help='Width/2 of the displayed camera.')
+    parser.add_argument('--cam_height', type=float, default=0.048/2,
+                        help='Height/2 of the displayed camera.')
+    parser.add_argument('--scale_focal', type=float, default=40,
+                        help='Value to scale the focal length.')
+    parser.add_argument('--patternCentric', action='store_true',
+                        help='The calibration board is static and the camera is moving.')
+    args = parser.parse_args()
+
+    fs = cv.FileStorage(args.calibration, cv.FILE_STORAGE_READ)
+    board_width = int(fs.getNode('board_width').real())
+    board_height = int(fs.getNode('board_height').real())
+    square_size = fs.getNode('square_size').real()
+    camera_matrix = fs.getNode('camera_matrix').mat()
+    extrinsics = fs.getNode('extrinsic_parameters').mat()
+
+    fig = plt.figure()
+    ax = fig.gca(projection='3d')
+    ax.set_aspect("equal")
+
+    cam_width = args.cam_width
+    cam_height = args.cam_height
+    scale_focal = args.scale_focal
+    min_values, max_values = draw_camera_boards(ax, camera_matrix, cam_width, cam_height,
+                                                scale_focal, extrinsics, board_width,
+                                                board_height, square_size, args.patternCentric)
+
+    X_min = min_values[0]
+    X_max = max_values[0]
+    Y_min = min_values[1]
+    Y_max = max_values[1]
+    Z_min = min_values[2]
+    Z_max = max_values[2]
+    max_range = np.array([X_max-X_min, Y_max-Y_min, Z_max-Z_min]).max() / 2.0
+
+    mid_x = (X_max+X_min) * 0.5
+    mid_y = (Y_max+Y_min) * 0.5
+    mid_z = (Z_max+Z_min) * 0.5
+    ax.set_xlim(mid_x - max_range, mid_x + max_range)
+    ax.set_ylim(mid_y - max_range, mid_y + max_range)
+    ax.set_zlim(mid_z - max_range, mid_z + max_range)
+
+    ax.set_xlabel('x')
+    ax.set_ylabel('z')
+    ax.set_zlabel('-y')
+    ax.set_title('Extrinsic Parameters Visualization')
+
+    plt.show()
+
+if __name__ == "__main__":
+    main()