Merge remote-tracking branch 'upstream/3.4' into merge-3.4
authorAlexander Alekhin <alexander.alekhin@intel.com>
Mon, 20 Aug 2018 16:29:39 +0000 (19:29 +0300)
committerAlexander Alekhin <alexander.alekhin@intel.com>
Mon, 20 Aug 2018 16:30:18 +0000 (19:30 +0300)
40 files changed:
1  2 
doc/tutorials/core/basic_linear_transform/basic_linear_transform.markdown
doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.markdown
doc/tutorials/core/file_input_output_with_xml_yml/file_input_output_with_xml_yml.markdown
doc/tutorials/core/how_to_scan_images/how_to_scan_images.markdown
doc/tutorials/core/how_to_use_OpenCV_parallel_for_/how_to_use_OpenCV_parallel_for_.markdown
doc/tutorials/core/how_to_use_ippa_conversion/how_to_use_ippa_conversion.markdown
doc/tutorials/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.markdown
doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.markdown
doc/tutorials/imgproc/basic_geometric_drawing/basic_geometric_drawing.markdown
doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown
doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.markdown
doc/tutorials/imgproc/histograms/back_projection/back_projection.markdown
doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.markdown
doc/tutorials/imgproc/histograms/histogram_comparison/histogram_comparison.markdown
doc/tutorials/imgproc/histograms/histogram_equalization/histogram_equalization.markdown
doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.markdown
doc/tutorials/imgproc/imgtrans/distance_transformation/distance_transform.markdown
doc/tutorials/imgproc/imgtrans/remap/remap.markdown
doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.markdown
doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.markdown
doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.markdown
doc/tutorials/imgproc/shapedescriptors/bounding_rotated_ellipses/bounding_rotated_ellipses.markdown
doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.markdown
doc/tutorials/imgproc/shapedescriptors/hull/hull.markdown
doc/tutorials/imgproc/shapedescriptors/moments/moments.markdown
doc/tutorials/imgproc/shapedescriptors/point_polygon_test/point_polygon_test.markdown
doc/tutorials/imgproc/threshold/threshold.markdown
doc/tutorials/imgproc/threshold_inRange/threshold_inRange.markdown
doc/tutorials/stitching/stitcher/stitcher.markdown
modules/calib3d/include/opencv2/calib3d.hpp
modules/core/include/opencv2/core.hpp
modules/core/include/opencv2/core/mat.hpp
modules/core/include/opencv2/core/persistence.hpp
modules/highgui/include/opencv2/highgui.hpp
modules/imgproc/include/opencv2/imgproc.hpp
modules/ml/include/opencv2/ml.hpp
modules/ml/src/data.cpp
modules/ml/test/test_mltests2.cpp
modules/objdetect/include/opencv2/objdetect.hpp
modules/photo/include/opencv2/photo.hpp

index 0000000000000000000000000000000000000000,70543cf14f3f496d20dda8f6f5a5f58201752a1e..77c44219f9bd971bd818cd568ee7bd61f2461eda
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,263 +1,263 @@@
 -    [here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp)
+ Basic Drawing {#tutorial_basic_geometric_drawing}
+ =============
+ @next_tutorial{tutorial_random_generator_and_text}
+ Goals
+ -----
+ In this tutorial you will learn how to:
+ -   Draw a **line** by using the OpenCV function **line()**
+ -   Draw an **ellipse** by using the OpenCV function **ellipse()**
+ -   Draw a **rectangle** by using the OpenCV function **rectangle()**
+ -   Draw a **circle** by using the OpenCV function **circle()**
+ -   Draw a **filled polygon** by using the OpenCV function **fillPoly()**
+ @add_toggle_cpp
+ OpenCV Theory
+ -------------
+ For this tutorial, we will heavily use two structures: @ref cv::Point and @ref cv::Scalar :
+ ### Point
+ It represents a 2D point, specified by its image coordinates \f$x\f$ and \f$y\f$. We can define it as:
+ @code{.cpp}
+ Point pt;
+ pt.x = 10;
+ pt.y = 8;
+ @endcode
+ or
+ @code{.cpp}
+ Point pt =  Point(10, 8);
+ @endcode
+ ### Scalar
+ -   Represents a 4-element vector. The type Scalar is widely used in OpenCV for passing pixel
+     values.
+ -   In this tutorial, we will use it extensively to represent BGR color values (3 parameters). It is
+     not necessary to define the last argument if it is not going to be used.
+ -   Let's see an example, if we are asked for a color argument and we give:
+     @code{.cpp}
+     Scalar( a, b, c )
+     @endcode
+     We would be defining a BGR color such as: *Blue = a*, *Green = b* and *Red = c*
+ @end_toggle
+ @add_toggle_java
+ OpenCV Theory
+ -------------
+ For this tutorial, we will heavily use two structures: @ref cv::Point and @ref cv::Scalar :
+ ### Point
+ It represents a 2D point, specified by its image coordinates \f$x\f$ and \f$y\f$. We can define it as:
+ @code{.java}
+ Point pt = new Point();
+ pt.x = 10;
+ pt.y = 8;
+ @endcode
+ or
+ @code{.java}
+ Point pt = new Point(10, 8);
+ @endcode
+ ### Scalar
+ -   Represents a 4-element vector. The type Scalar is widely used in OpenCV for passing pixel
+     values.
+ -   In this tutorial, we will use it extensively to represent BGR color values (3 parameters). It is
+     not necessary to define the last argument if it is not going to be used.
+ -   Let's see an example, if we are asked for a color argument and we give:
+     @code{.java}
+     Scalar( a, b, c )
+     @endcode
+     We would be defining a BGR color such as: *Blue = a*, *Green = b* and *Red = c*
+ @end_toggle
+ Code
+ ----
+ @add_toggle_cpp
+ -   This code is in your OpenCV sample folder. Otherwise you can grab it from
 -    [here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java)
++    [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp)
+     @include samples/cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp
+ @end_toggle
+ @add_toggle_java
+ -   This code is in your OpenCV sample folder. Otherwise you can grab it from
 -    [here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py)
++    [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java)
+     @include samples/java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java
+ @end_toggle
+ @add_toggle_python
+ -   This code is in your OpenCV sample folder. Otherwise you can grab it from
++    [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py)
+     @include samples/python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py
+ @end_toggle
+ Explanation
+ -----------
+ Since we plan to draw two examples (an atom and a rook), we have to create two images and two
+ windows to display them.
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp create_images
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java create_images
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py create_images
+ @end_toggle
+ We created functions to draw different geometric shapes. For instance, to draw the atom we used
+ **MyEllipse** and **MyFilledCircle**:
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp draw_atom
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java draw_atom
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py draw_atom
+ @end_toggle
+ And to draw the rook we employed **MyLine**, **rectangle** and a **MyPolygon**:
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp draw_rook
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java draw_rook
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py draw_rook
+ @end_toggle
+ Let's check what is inside each of these functions:
+ @add_toggle_cpp
+ @end_toggle
+ <H4>MyLine</H4>
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_line
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_line
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_line
+ @end_toggle
+ -   As we can see, **MyLine** just call the function **line()** , which does the following:
+     -   Draw a line from Point **start** to Point **end**
+     -   The line is displayed in the image **img**
+     -   The line color is defined by <B>( 0, 0, 0 )</B> which is the RGB value correspondent
+         to **Black**
+     -   The line thickness is set to **thickness** (in this case 2)
+     -   The line is a 8-connected one (**lineType** = 8)
+ <H4>MyEllipse</H4>
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_ellipse
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_ellipse
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_ellipse
+ @end_toggle
+ -   From the code above, we can observe that the function **ellipse()** draws an ellipse such
+     that:
+     -   The ellipse is displayed in the image **img**
+     -   The ellipse center is located in the point <B>(w/2, w/2)</B> and is enclosed in a box
+         of size <B>(w/4, w/16)</B>
+     -   The ellipse is rotated **angle** degrees
+     -   The ellipse extends an arc between **0** and **360** degrees
+     -   The color of the figure will be <B>( 255, 0, 0 )</B> which means blue in BGR value.
+     -   The ellipse's **thickness** is 2.
+ <H4>MyFilledCircle</H4>
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_filled_circle
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_filled_circle
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_filled_circle
+ @end_toggle
+ -   Similar to the ellipse function, we can observe that *circle* receives as arguments:
+     -   The image where the circle will be displayed (**img**)
+     -   The center of the circle denoted as the point **center**
+     -   The radius of the circle: **w/32**
+     -   The color of the circle: <B>( 0, 0, 255 )</B> which means *Red* in BGR
+     -   Since **thickness** = -1, the circle will be drawn filled.
+ <H4>MyPolygon</H4>
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_polygon
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_polygon
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_polygon
+ @end_toggle
+ -   To draw a filled polygon we use the function **fillPoly()** . We note that:
+     -   The polygon will be drawn on **img**
+     -   The vertices of the polygon are the set of points in **ppt**
+     -   The color of the polygon is defined by <B>( 255, 255, 255 )</B>, which is the BGR
+         value for *white*
+ <H4>rectangle</H4>
+ @add_toggle_cpp
+ @snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp rectangle
+ @end_toggle
+ @add_toggle_java
+ @snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java rectangle
+ @end_toggle
+ @add_toggle_python
+ @snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py rectangle
+ @end_toggle
+ -   Finally we have the @ref cv::rectangle function (we did not create a special function for
+     this guy). We note that:
+     -   The rectangle will be drawn on **rook_image**
+     -   Two opposite vertices of the rectangle are defined by <B>( 0, 7*w/8 )</B>
+         and <B>( w, w )</B>
+     -   The color of the rectangle is given by <B>( 0, 255, 255 )</B> which is the BGR value
+         for *yellow*
+     -   Since the thickness value is given by **FILLED (-1)**, the rectangle will be filled.
+ Result
+ ------
+ Compiling and running your program should give you a result like this:
+ ![](images/Drawing_1_Tutorial_Result_0.png)
Simple merge
index 357aac146c5cbfb4ced232a349922113961f3052,f2ca78fe9165bd34fdabb9109e4a577dc0461f7d..1d8889cbcf6f003d2a5601fe291bafd04233f316
@@@ -234,12 -234,23 +234,23 @@@ public
      CV_WRAP virtual void shuffleTrainTest() = 0;
  
      /** @brief Returns matrix of test samples */
 -    CV_WRAP Mat getTestSamples() const;
 +    CV_WRAP virtual Mat getTestSamples() const = 0;
  
      /** @brief Returns vector of symbolic names captured in loadFromCSV() */
 -    CV_WRAP void getNames(std::vector<String>& names) const;
 +    CV_WRAP virtual void getNames(std::vector<String>& names) const = 0;
  
-     CV_WRAP static Mat getSubVector(const Mat& vec, const Mat& idx);
+     /** @brief Extract from 1D vector elements specified by passed indexes.
+     @param vec input vector (supported types: CV_32S, CV_32F, CV_64F)
+     @param idx 1D index vector
+      */
+     static CV_WRAP Mat getSubVector(const Mat& vec, const Mat& idx);
+     /** @brief Extract from matrix rows/cols specified by passed indexes.
+     @param matrix input matrix (supported types: CV_32S, CV_32F, CV_64F)
+     @param idx 1D index vector
+     @param layout specifies to extract rows (cv::ml::ROW_SAMPLES) or to extract columns (cv::ml::COL_SAMPLES)
+      */
+     static CV_WRAP Mat getSubMatrix(const Mat& matrix, const Mat& idx, int layout);
  
      /** @brief Reads the dataset from a .csv file and returns the ready-to-use training data.
  
index ae378381260bdcf4831a0096aa7882f29562b18f,a5dd101f1d00c5be0ed0227e90e4ffb385bd784b..daf39b9a330f36a0694e986d57dbfb6544f22ad5
@@@ -50,69 -52,71 +52,65 @@@ static const int VAR_MISSED = VAR_ORDER
  
  TrainData::~TrainData() {}
  
 -Mat TrainData::getTestSamples() const
 -{
 -    Mat idx = getTestSampleIdx();
 -    Mat samples = getSamples();
 -    return idx.empty() ? Mat() : getSubMatrix(samples, idx, getLayout());
 -}
 -
  Mat TrainData::getSubVector(const Mat& vec, const Mat& idx)
  {
-     if( idx.empty() )
-         return vec;
-     int i, j, n = idx.checkVector(1, CV_32S);
-     int type = vec.type();
-     CV_Assert( type == CV_32S || type == CV_32F || type == CV_64F );
-     int dims = 1, m;
+     if (!(vec.cols == 1 || vec.rows == 1))
+         CV_LOG_WARNING(NULL, "'getSubVector(const Mat& vec, const Mat& idx)' call with non-1D input is deprecated. It is not designed to work with 2D matrixes (especially with 'cv::ml::COL_SAMPLE' layout).");
+     return getSubMatrix(vec, idx, vec.rows == 1 ? cv::ml::COL_SAMPLE : cv::ml::ROW_SAMPLE);
+ }
+ template<typename T>
+ Mat getSubMatrixImpl(const Mat& m, const Mat& idx, int layout)
+ {
+     int nidx = idx.checkVector(1, CV_32S);
+     int dims = m.cols, nsamples = m.rows;
  
-     if( vec.cols == 1 || vec.rows == 1 )
+     Mat subm;
+     if (layout == COL_SAMPLE)
      {
-         dims = 1;
-         m = vec.cols + vec.rows - 1;
+         std::swap(dims, nsamples);
+         subm.create(dims, nidx, m.type());
      }
      else
      {
-         dims = vec.cols;
-         m = vec.rows;
+         subm.create(nidx, dims, m.type());
      }
  
-     Mat subvec;
-     if( vec.cols == m )
-         subvec.create(dims, n, type);
-     else
-         subvec.create(n, dims, type);
-     if( type == CV_32S )
-         for( i = 0; i < n; i++ )
+     for (int i = 0; i < nidx; i++)
+     {
+         int k = idx.at<int>(i); CV_CheckGE(k, 0, "Bad idx"); CV_CheckLT(k, nsamples, "Bad idx or layout");
+         if (dims == 1)
          {
-             int k = idx.at<int>(i);
-             CV_Assert( 0 <= k && k < m );
-             if( dims == 1 )
-                 subvec.at<int>(i) = vec.at<int>(k);
-             else
-                 for( j = 0; j < dims; j++ )
-                     subvec.at<int>(i, j) = vec.at<int>(k, j);
+             subm.at<T>(i) = m.at<T>(k);  // at() has "transparent" access for 1D col-based / row-based vectors.
          }
-     else if( type == CV_32F )
-         for( i = 0; i < n; i++ )
+         else if (layout == COL_SAMPLE)
          {
-             int k = idx.at<int>(i);
-             CV_Assert( 0 <= k && k < m );
-             if( dims == 1 )
-                 subvec.at<float>(i) = vec.at<float>(k);
-             else
-                 for( j = 0; j < dims; j++ )
-                     subvec.at<float>(i, j) = vec.at<float>(k, j);
+             for (int j = 0; j < dims; j++)
+                 subm.at<T>(j, i) = m.at<T>(j, k);
          }
-     else
-         for( i = 0; i < n; i++ )
+         else
          {
-             int k = idx.at<int>(i);
-             CV_Assert( 0 <= k && k < m );
-             if( dims == 1 )
-                 subvec.at<double>(i) = vec.at<double>(k);
-             else
-                 for( j = 0; j < dims; j++ )
-                     subvec.at<double>(i, j) = vec.at<double>(k, j);
+             for (int j = 0; j < dims; j++)
+                 subm.at<T>(i, j) = m.at<T>(k, j);
          }
-     return subvec;
+     }
+     return subm;
+ }
+ Mat TrainData::getSubMatrix(const Mat& m, const Mat& idx, int layout)
+ {
+     if (idx.empty())
+         return m;
+     int type = m.type();
+     CV_CheckType(type, type == CV_32S || type == CV_32F || type == CV_64F, "");
+     if (type == CV_32S || type == CV_32F)  // 32-bit
+         return getSubMatrixImpl<int>(m, idx, layout);
+     if (type == CV_64F)  // 64-bit
+         return getSubMatrixImpl<double>(m, idx, layout);
+     CV_Error(Error::StsInternal, "");
  }
  
 +
  class TrainDataImpl CV_FINAL : public TrainData
  {
  public:
          return layout == ROW_SAMPLE ? samples.cols : samples.rows;
      }
  
-         return idx.empty() ? Mat() : getSubVector(samples, idx);
 +    Mat getTestSamples() const CV_OVERRIDE
 +    {
 +        Mat idx = getTestSampleIdx();
++        return idx.empty() ? Mat() : getSubMatrix(samples, idx, getLayout());
 +    }
 +
      Mat getSamples() const CV_OVERRIDE { return samples; }
      Mat getResponses() const CV_OVERRIDE { return responses; }
      Mat getMissing() const CV_OVERRIDE { return missing; }
Simple merge