Add Java and Python code for the following imgproc tutorials: Finding contours in...
authorcatree <catree.catreus@outlook.com>
Sun, 10 Jun 2018 21:57:11 +0000 (23:57 +0200)
committercatree <catree.catreus@outlook.com>
Sun, 10 Jun 2018 21:57:11 +0000 (23:57 +0200)
25 files changed:
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/table_of_content_imgproc.markdown
samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.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/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java [new file with mode: 0644]
samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java [new file with mode: 0644]
samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java [new file with mode: 0644]
samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java [new file with mode: 0644]
samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java [new file with mode: 0644]
samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java [new file with mode: 0644]
samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py [new file with mode: 0644]
samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py [new file with mode: 0644]
samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py [new file with mode: 0644]
samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py [new file with mode: 0644]
samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py [new file with mode: 0644]
samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py [new file with mode: 0644]

index 978b900..99cc2c1 100644 (file)
@@ -15,55 +15,167 @@ Theory
 Code
 ----
 
 Code
 ----
 
+@add_toggle_cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp
+@end_toggle
+
+@add_toggle_java
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java)
+@include samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java
+@end_toggle
+
+@add_toggle_python
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py)
+@include samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py
+@end_toggle
 
 Explanation
 -----------
 
 The main function is rather simple, as follows from the comments we do the following:
 
 Explanation
 -----------
 
 The main function is rather simple, as follows from the comments we do the following:
--#  Open the image, convert it into grayscale and blur it to get rid of the noise.
-    @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
--# Create a window with header "Source" and display the source file in it.
-    @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow
--# Create a trackbar on the source_window and assign a callback function to it
+-   Open the image, convert it into grayscale and blur it to get rid of the noise.
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java setup
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py setup
+@end_toggle
+
+-  Create a window with header "Source" and display the source file in it.
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java createWindow
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py createWindow
+@end_toggle
+
+-  Create a trackbar on the `source_window` and assign a callback function to it.
    In general callback functions are used to react to some kind of signal, in our
    case it's trackbar's state change.
    In general callback functions are used to react to some kind of signal, in our
    case it's trackbar's state change.
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp taskbar
--# Explicit one-time call of `thresh_callback` is necessary to display
+   Explicit one-time call of `thresh_callback` is necessary to display
    the "Contours" window simultaniously with the "Source" window.
    the "Contours" window simultaniously with the "Source" window.
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp callback00
--# Wait for user to close the windows.
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp waitForIt
 
 
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp trackbar
+@end_toggle
 
 
-The callback function `thresh_callback` does all the interesting job.
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java trackbar
+@end_toggle
 
 
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py trackbar
+@end_toggle
 
 
--# Writes to `threshold_output` the threshold of the grayscale picture (you can check out about thresholding @ref tutorial_threshold "here").
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp threshold
--# Finds contours and saves them to the vectors `contour` and `hierarchy`.
-    @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
--# For every found contour we now apply approximation to polygons
-   with accuracy +-3 and stating that the curve must me closed.
+The callback function does all the interesting job.
 
 
-   After that we find a bounding rect for every polygon and save it to `boundRect`.
+-  Use @ref cv::Canny to detect edges in the images.
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp Canny
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java Canny
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py Canny
+@end_toggle
+
+-  Finds contours and saves them to the vectors `contour` and `hierarchy`.
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
+@end_toggle
 
 
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java findContours
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py findContours
+@end_toggle
+
+-  For every found contour we now apply approximation to polygons
+   with accuracy +-3 and stating that the curve must be closed.
+   After that we find a bounding rect for every polygon and save it to `boundRect`.
    At last we find a minimum enclosing circle for every polygon and
    save it to `center` and `radius` vectors.
    At last we find a minimum enclosing circle for every polygon and
    save it to `center` and `radius` vectors.
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java allthework
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py allthework
+@end_toggle
 
 We found everything we need, all we have to do is to draw.
 
 
 We found everything we need, all we have to do is to draw.
 
--# Create new Mat of unsigned 8-bit chars, filled with zeros.
+-  Create new Mat of unsigned 8-bit chars, filled with zeros.
    It will contain all the drawings we are going to make (rects and circles).
    It will contain all the drawings we are going to make (rects and circles).
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
--# For every contour: pick a random color, draw the contour, the bounding rectangle and
-   the minimal enclosing circle with it,
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour
--# Display the results: create a new window "Contours" and show everything we added to drawings on it.
-   @snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java zeroMat
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py zeroMat
+@end_toggle
+
+-  For every contour: pick a random color, draw the contour, the bounding rectangle and
+   the minimal enclosing circle with it.
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java forContour
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py forContour
+@end_toggle
+
+-  Display the results: create a new window "Contours" and show everything we added to drawings on it.
+
+@add_toggle_cpp
+@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings
+@end_toggle
+
+@add_toggle_java
+@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java showDrawings
+@end_toggle
+
+@add_toggle_python
+@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py showDrawings
+@end_toggle
 
 Result
 ------
 
 Result
 ------
index eb21cf5..a482936 100644 (file)
@@ -15,9 +15,23 @@ Theory
 Code
 ----
 
 Code
 ----
 
+@add_toggle_cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp
+@end_toggle
+
+@add_toggle_java
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java)
+@include samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java
+@end_toggle
+
+@add_toggle_python
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py)
+@include samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py
+@end_toggle
 
 Explanation
 -----------
 
 Explanation
 -----------
index af467bd..c1171bb 100644 (file)
@@ -15,9 +15,23 @@ Theory
 Code
 ----
 
 Code
 ----
 
+@add_toggle_cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp
+@end_toggle
+
+@add_toggle_java
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java)
+@include samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java
+@end_toggle
+
+@add_toggle_python
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py)
+@include samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py
+@end_toggle
 
 Explanation
 -----------
 
 Explanation
 -----------
index cfb9241..7d7fae1 100644 (file)
@@ -14,10 +14,23 @@ Theory
 Code
 ----
 
 Code
 ----
 
+@add_toggle_cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp)
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp)
-
 @include samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp
 @include samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp
+@end_toggle
+
+@add_toggle_java
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java)
+@include samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java
+@end_toggle
+
+@add_toggle_python
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py)
+@include samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py
+@end_toggle
 
 Explanation
 -----------
 
 Explanation
 -----------
index 231ff37..de9e79c 100644 (file)
@@ -16,9 +16,23 @@ Theory
 Code
 ----
 
 Code
 ----
 
+@add_toggle_cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp
+@end_toggle
+
+@add_toggle_java
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java)
+@include samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java
+@end_toggle
+
+@add_toggle_python
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py)
+@include samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py
+@end_toggle
 
 Explanation
 -----------
 
 Explanation
 -----------
index 1f50410..4a42eea 100644 (file)
@@ -14,9 +14,23 @@ Theory
 Code
 ----
 
 Code
 ----
 
+@add_toggle_cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp
 This tutorial code's is shown lines below. You can also download it from
 [here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp)
 @include samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp
+@end_toggle
+
+@add_toggle_java
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java)
+@include samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java
+@end_toggle
+
+@add_toggle_python
+This tutorial code's is shown lines below. You can also download it from
+[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py)
+@include samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py
+@end_toggle
 
 Explanation
 -----------
 
 Explanation
 -----------
index fc93ae0..e3fac55 100644 (file)
@@ -225,6 +225,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -   @subpage tutorial_find_contours
 
 
 -   @subpage tutorial_find_contours
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
@@ -233,6 +235,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -    @subpage tutorial_hull
 
 
 -    @subpage tutorial_hull
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
@@ -241,6 +245,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -   @subpage tutorial_bounding_rects_circles
 
 
 -   @subpage tutorial_bounding_rects_circles
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
@@ -249,6 +255,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -   @subpage tutorial_bounding_rotated_ellipses
 
 
 -   @subpage tutorial_bounding_rotated_ellipses
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
@@ -257,6 +265,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -   @subpage tutorial_moments
 
 
 -   @subpage tutorial_moments
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
@@ -265,6 +275,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -   @subpage tutorial_point_polygon_test
 
 
 -   @subpage tutorial_point_polygon_test
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
index 233800e..1083657 100644 (file)
@@ -12,9 +12,8 @@
 using namespace cv;
 using namespace std;
 
 using namespace cv;
 using namespace std;
 
-Mat src; Mat src_gray;
+Mat src_gray;
 int thresh = 100;
 int thresh = 100;
-int max_thresh = 255;
 RNG rng(12345);
 
 /// Function header
 RNG rng(12345);
 
 /// Function header
@@ -25,34 +24,31 @@ void thresh_callback(int, void* );
  */
 int main( int argc, char** argv )
 {
  */
 int main( int argc, char** argv )
 {
-  /// Load source image
-  String imageName("../data/happyfish.jpg"); // by default
-  if (argc > 1)
-  {
-    imageName = argv[1];
-  }
-  src = imread(imageName, IMREAD_COLOR);
+    /// Load source image
+    CommandLineParser parser( argc, argv, "{@input | ../data/HappyFish.jpg | input image}" );
+    Mat src = imread( parser.get<String>( "@input" ) );
+    if( src.empty() )
+    {
+      cout << "Could not open or find the image!\n" << endl;
+      cout << "Usage: " << argv[0] << " <Input image>" << endl;
+      return -1;
+    }
 
 
-  if (src.empty())
-  {
-    cerr << "No image supplied ..." << endl;
-    return -1;
-  }
+    /// Convert image to gray and blur it
+    cvtColor( src, src_gray, COLOR_BGR2GRAY );
+    blur( src_gray, src_gray, Size(3,3) );
 
 
-  /// Convert image to gray and blur it
-  cvtColor( src, src_gray, COLOR_BGR2GRAY );
-  blur( src_gray, src_gray, Size(3,3) );
+    /// Create Window
+    const char* source_window = "Source";
+    namedWindow( source_window );
+    imshow( source_window, src );
 
 
-  /// Create Window
-  const char* source_window = "Source";
-  namedWindow( source_window, WINDOW_AUTOSIZE );
-  imshow( source_window, src );
+    const int max_thresh = 255;
+    createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
+    thresh_callback( 0, 0 );
 
 
-  createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
-  thresh_callback( 0, 0 );
-
-  waitKey(0);
-  return(0);
+    waitKey();
+    return 0;
 }
 
 /**
 }
 
 /**
@@ -60,24 +56,23 @@ int main( int argc, char** argv )
  */
 void thresh_callback(int, void* )
 {
  */
 void thresh_callback(int, void* )
 {
-  Mat canny_output;
-  vector<vector<Point> > contours;
-  vector<Vec4i> hierarchy;
+    /// Detect edges using Canny
+    Mat canny_output;
+    Canny( src_gray, canny_output, thresh, thresh*2 );
 
 
-  /// 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) );
+    /// Find contours
+    vector<vector<Point> > contours;
+    vector<Vec4i> hierarchy;
+    findContours( canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE );
 
 
-  /// Draw contours
-  Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
-  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() );
-     }
+    /// Draw contours
+    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
+    for( size_t i = 0; i< contours.size(); i++ )
+    {
+        Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
+        drawContours( drawing, contours, (int)i, color, 2, LINE_8, hierarchy, 0 );
+    }
 
 
-  /// Show in a window
-  namedWindow( "Contours", WINDOW_AUTOSIZE );
-  imshow( "Contours", drawing );
+    /// Show in a window
+    imshow( "Contours", drawing );
 }
 }
index ea0b2a4..f8eb194 100644 (file)
@@ -12,9 +12,8 @@
 using namespace cv;
 using namespace std;
 
 using namespace cv;
 using namespace std;
 
-Mat src; Mat src_gray;
+Mat src_gray;
 int thresh = 100;
 int thresh = 100;
-int max_thresh = 255;
 RNG rng(12345);
 
 /// Function header
 RNG rng(12345);
 
 /// Function header
@@ -25,42 +24,37 @@ void thresh_callback(int, void* );
  */
 int main( int argc, char** argv )
 {
  */
 int main( int argc, char** argv )
 {
-  //![setup]
-  /// Load source image
-  CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
-  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
-  if( src.empty() )
+    //! [setup]
+    /// Load source image
+    CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+    Mat src = imread( parser.get<String>( "@input" ) );
+    if( src.empty() )
     {
     {
-      cout << "Could not open or find the image!\n" << endl;
-      cout << "usage: " << argv[0] << " <Input image>" << endl;
-      return -1;
+        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 );
-  blur( src_gray, src_gray, Size(3,3) );
-  //![setup]
-
-  //![createWindow]
-  /// Create Window
-  const char* source_window = "Source";
-  namedWindow( source_window, WINDOW_AUTOSIZE );
-  imshow( source_window, src );
-  //![createWindow]
-
-  //![taskbar]
-  createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
-  //![taskbar]
-
-  //![callback00]
-  thresh_callback( 0, 0 );
-  //![callback00]
-
-  //![waitForIt]
-  waitKey(0);
-  //![waitForIt]
-
-  return(0);
+    /// Convert image to gray and blur it
+    cvtColor( src, src_gray, COLOR_BGR2GRAY );
+    blur( src_gray, src_gray, Size(3,3) );
+    //! [setup]
+
+    //! [createWindow]
+    /// Create Window
+    const char* source_window = "Source";
+    namedWindow( source_window );
+    imshow( source_window, src );
+    //! [createWindow]
+
+    //! [trackbar]
+    const int max_thresh = 255;
+    createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
+    thresh_callback( 0, 0 );
+    //! [trackbar]
+
+    waitKey();
+    return 0;
 }
 
 /**
 }
 
 /**
@@ -68,53 +62,50 @@ int main( int argc, char** argv )
  */
 void thresh_callback(int, void* )
 {
  */
 void thresh_callback(int, void* )
 {
-  Mat threshold_output;
-  vector<vector<Point> > contours;
-  vector<Vec4i> hierarchy;
-
-  //![threshold]
-  /// Detect edges using Threshold
-  threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
-  //![threshold]
-
-  //![findContours]
-  /// Find contours
-  findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
-  //![findContours]
-
-  /// Approximate contours to polygons + get bounding rects and circles
-  vector<vector<Point> > contours_poly( contours.size() );
-  vector<Rect> boundRect( contours.size() );
-  vector<Point2f>center( contours.size() );
-  vector<float>radius( contours.size() );
-
-  //![allthework]
-  for( size_t i = 0; i < contours.size(); i++ )
-  {
-    approxPolyDP( contours[i], contours_poly[i], 3, true );
-    boundRect[i] = boundingRect( contours_poly[i] );
-    minEnclosingCircle( contours_poly[i], center[i], radius[i] );
-  }
-  //![allthework]
-
-  //![zeroMat]
-  /// Draw polygonal contour + bonding rects + circles
-  Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
-  //![zeroMat]
-
-  //![forContour]
-  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_poly, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
-    rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
-    circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 );
-  }
-  //![forContour]
-
-  //![showDrawings]
-  /// Show in a window
-  namedWindow( "Contours", WINDOW_AUTOSIZE );
-  imshow( "Contours", drawing );
-  //![showDrawings]
+    //! [Canny]
+    /// Detect edges using Canny
+    Mat canny_output;
+    Canny( src_gray, canny_output, thresh, thresh*2 );
+    //! [Canny]
+
+    //! [findContours]
+    /// Find contours
+    vector<vector<Point> > contours;
+    findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
+    //! [findContours]
+
+    //! [allthework]
+    /// Approximate contours to polygons + get bounding rects and circles
+    vector<vector<Point> > contours_poly( contours.size() );
+    vector<Rect> boundRect( contours.size() );
+    vector<Point2f>centers( contours.size() );
+    vector<float>radius( contours.size() );
+
+    for( size_t i = 0; i < contours.size(); i++ )
+    {
+        approxPolyDP( contours[i], contours_poly[i], 3, true );
+        boundRect[i] = boundingRect( contours_poly[i] );
+        minEnclosingCircle( contours_poly[i], centers[i], radius[i] );
+    }
+    //! [allthework]
+
+    //! [zeroMat]
+    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
+    //! [zeroMat]
+
+    //! [forContour]
+    /// Draw polygonal contour + bonding rects + circles
+    for( size_t i = 0; i< contours.size(); i++ )
+    {
+        Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
+        drawContours( drawing, contours_poly, (int)i, color );
+        rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2 );
+        circle( drawing, centers[i], (int)radius[i], color, 2 );
+    }
+    //! [forContour]
+
+    //! [showDrawings]
+    /// Show in a window
+    imshow( "Contours", drawing );
+    //! [showDrawings]
 }
 }
index 169f8bf..2018b64 100644 (file)
@@ -12,9 +12,8 @@
 using namespace cv;
 using namespace std;
 
 using namespace cv;
 using namespace std;
 
-Mat src; Mat src_gray;
+Mat src_gray;
 int thresh = 100;
 int thresh = 100;
-int max_thresh = 255;
 RNG rng(12345);
 
 /// Function header
 RNG rng(12345);
 
 /// Function header
@@ -25,30 +24,31 @@ void thresh_callback(int, void* );
  */
 int main( int argc, char** argv )
 {
  */
 int main( int argc, char** argv )
 {
-  /// Load source image and convert it to gray
-  CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
-  src = imread( parser.get<String>( "@input" ), IMREAD_COLOR );
-  if( src.empty() )
+    /// Load source image and convert it to gray
+    CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+    Mat src = imread( parser.get<String>( "@input" ) );
+    if( src.empty() )
     {
     {
-      cout << "Could not open or find the image!\n" << endl;
-      cout << "Usage: " << argv[0] << " <Input image>" << endl;
-      return -1;
+        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 );
-  blur( src_gray, src_gray, Size(3,3) );
+    /// Convert image to gray and blur it
+    cvtColor( src, src_gray, COLOR_BGR2GRAY );
+    blur( src_gray, src_gray, Size(3,3) );
 
 
-  /// Create Window
-  const char* source_window = "Source";
-  namedWindow( source_window, WINDOW_AUTOSIZE );
-  imshow( source_window, src );
+    /// Create Window
+    const char* source_window = "Source";
+    namedWindow( source_window );
+    imshow( source_window, src );
 
 
-  createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
-  thresh_callback( 0, 0 );
+    const int max_thresh = 255;
+    createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
+    thresh_callback( 0, 0 );
 
 
-  waitKey(0);
-  return(0);
+    waitKey();
+    return 0;
 }
 
 /**
 }
 
 /**
@@ -56,41 +56,43 @@ int main( int argc, char** argv )
  */
 void thresh_callback(int, void* )
 {
  */
 void thresh_callback(int, void* )
 {
-  Mat threshold_output;
-  vector<vector<Point> > contours;
-  vector<Vec4i> hierarchy;
+    /// Detect edges using Canny
+    Mat canny_output;
+    Canny( src_gray, canny_output, thresh, thresh*2 );
+    /// Find contours
+    vector<vector<Point> > contours;
+    findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
 
 
-  /// Detect edges using Threshold
-  threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
-  /// Find contours
-  findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
-
-  /// Find the rotated rectangles and ellipses for each contour
-  vector<RotatedRect> minRect( contours.size() );
-  vector<RotatedRect> minEllipse( contours.size() );
-
-  for( size_t i = 0; i < contours.size(); i++ )
-     { minRect[i] = minAreaRect( contours[i] );
-       if( contours[i].size() > 5 )
-         { minEllipse[i] = fitEllipse( contours[i] ); }
-     }
+    /// Find the rotated rectangles and ellipses for each contour
+    vector<RotatedRect> minRect( contours.size() );
+    vector<RotatedRect> minEllipse( contours.size() );
+    for( size_t i = 0; i < contours.size(); i++ )
+    {
+        minRect[i] = minAreaRect( contours[i] );
+        if( contours[i].size() > 5 )
+        {
+            minEllipse[i] = fitEllipse( contours[i] );
+        }
+    }
 
 
-  /// Draw contours + rotated rects + ellipses
-  Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
-  for( size_t i = 0; i< contours.size(); i++ )
-     {
-       Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
-       // contour
-       drawContours( drawing, contours, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
-       // ellipse
-       ellipse( drawing, minEllipse[i], color, 2, 8 );
-       // rotated rectangle
-       Point2f rect_points[4]; minRect[i].points( rect_points );
-       for( int j = 0; j < 4; j++ )
-          line( drawing, rect_points[j], rect_points[(j+1)%4], color, 1, 8 );
-     }
+    /// Draw contours + rotated rects + ellipses
+    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
+    for( size_t i = 0; i< contours.size(); i++ )
+    {
+        Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
+        // contour
+        drawContours( drawing, contours, (int)i, color );
+        // ellipse
+        ellipse( drawing, minEllipse[i], color, 2 );
+        // rotated rectangle
+        Point2f rect_points[4];
+        minRect[i].points( rect_points );
+        for ( int j = 0; j < 4; j++ )
+        {
+            line( drawing, rect_points[j], rect_points[(j+1)%4], color );
+        }
+    }
 
 
-  /// Show in a window
-  namedWindow( "Contours", WINDOW_AUTOSIZE );
-  imshow( "Contours", drawing );
+    /// Show in a window
+    imshow( "Contours", drawing );
 }
 }
index c155908..6640286 100644 (file)
@@ -12,9 +12,8 @@
 using namespace cv;
 using namespace std;
 
 using namespace cv;
 using namespace std;
 
-Mat src; Mat src_gray;
+Mat src_gray;
 int thresh = 100;
 int thresh = 100;
-int max_thresh = 255;
 RNG rng(12345);
 
 /// Function header
 RNG rng(12345);
 
 /// Function header
@@ -25,30 +24,31 @@ void thresh_callback(int, void* );
  */
 int main( int argc, char** argv )
 {
  */
 int main( int argc, char** argv )
 {
-  /// Load source image and convert it to gray
-  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;
-  }
+    /// Load source image and convert it to gray
+    CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+    Mat src = imread( parser.get<String>( "@input" ) );
+    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 );
-  blur( src_gray, src_gray, Size(3,3) );
+    /// Convert image to gray and blur it
+    cvtColor( src, src_gray, COLOR_BGR2GRAY );
+    blur( src_gray, src_gray, Size(3,3) );
 
 
-  /// Create Window
-  const char* source_window = "Source";
-  namedWindow( source_window, WINDOW_AUTOSIZE );
-  imshow( source_window, src );
+    /// Create Window
+    const char* source_window = "Source";
+    namedWindow( source_window );
+    imshow( source_window, src );
 
 
-  createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
-  thresh_callback( 0, 0 );
+    const int max_thresh = 255;
+    createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
+    thresh_callback( 0, 0 );
 
 
-  waitKey(0);
-  return(0);
+    waitKey();
+    return 0;
 }
 
 /**
 }
 
 /**
@@ -56,31 +56,30 @@ int main( int argc, char** argv )
  */
 void thresh_callback(int, void* )
 {
  */
 void thresh_callback(int, void* )
 {
-  Mat threshold_output;
-  vector<vector<Point> > contours;
-  vector<Vec4i> hierarchy;
+    /// Detect edges using Canny
+    Mat canny_output;
+    Canny( src_gray, canny_output, thresh, thresh*2 );
 
 
-  /// Detect edges using Threshold
-  threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
+    /// Find contours
+    vector<vector<Point> > contours;
+    findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
 
 
-  /// Find contours
-  findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
+    /// Find the convex hull object for each contour
+    vector<vector<Point> >hull( contours.size() );
+    for( size_t i = 0; i < contours.size(); i++ )
+    {
+        convexHull( contours[i], hull[i] );
+    }
 
 
-  /// Find the convex hull object for each contour
-  vector<vector<Point> >hull( contours.size() );
-  for( size_t i = 0; i < contours.size(); i++ )
-     {   convexHull( contours[i], hull[i], false ); }
+    /// Draw contours + hull results
+    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
+    for( size_t i = 0; i< contours.size(); i++ )
+    {
+        Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
+        drawContours( drawing, contours, (int)i, color );
+        drawContours( drawing, hull, (int)i, color );
+    }
 
 
-  /// Draw contours + hull results
-  Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
-  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, 1, 8, vector<Vec4i>(), 0, Point() );
-       drawContours( drawing, hull, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
-     }
-
-  /// Show in a window
-  namedWindow( "Hull demo", WINDOW_AUTOSIZE );
-  imshow( "Hull demo", drawing );
+    /// Show in a window
+    imshow( "Hull demo", drawing );
 }
 }
index 6741cc6..eaccd14 100644 (file)
@@ -8,13 +8,13 @@
 #include "opencv2/highgui.hpp"
 #include "opencv2/imgproc.hpp"
 #include <iostream>
 #include "opencv2/highgui.hpp"
 #include "opencv2/imgproc.hpp"
 #include <iostream>
+#include <iomanip>
 
 using namespace cv;
 using namespace std;
 
 
 using namespace cv;
 using namespace std;
 
-Mat src; Mat src_gray;
+Mat src_gray;
 int thresh = 100;
 int thresh = 100;
-int max_thresh = 255;
 RNG rng(12345);
 
 /// Function header
 RNG rng(12345);
 
 /// Function header
@@ -25,31 +25,32 @@ void thresh_callback(int, void* );
  */
 int main( int argc, char** argv )
 {
  */
 int main( int argc, char** argv )
 {
-  /// Load source image and convert it to gray
-  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 );
-  blur( src_gray, src_gray, Size(3,3) );
-
-  /// Create Window
-  const char* source_window = "Source";
-  namedWindow( source_window, WINDOW_AUTOSIZE );
-  imshow( source_window, src );
-
-  createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
-  thresh_callback( 0, 0 );
-
-  waitKey(0);
-  return(0);
+    /// Load source image
+    CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
+    Mat src = imread( parser.get<String>( "@input" ) );
+
+    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 );
+    blur( src_gray, src_gray, Size(3,3) );
+
+    /// Create Window
+    const char* source_window = "Source";
+    namedWindow( source_window );
+    imshow( source_window, src );
+
+    const int max_thresh = 255;
+    createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
+    thresh_callback( 0, 0 );
+
+    waitKey();
+    return 0;
 }
 
 /**
 }
 
 /**
@@ -57,44 +58,47 @@ int main( int argc, char** argv )
  */
 void thresh_callback(int, void* )
 {
  */
 void thresh_callback(int, void* )
 {
-  Mat canny_output;
-  vector<vector<Point> > contours;
-
-  /// Detect edges using canny
-  Canny( src_gray, canny_output, thresh, thresh*2, 3 );
-  /// Find contours
-  findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
-
-  /// Get the moments
-  vector<Moments> mu(contours.size() );
-  for( size_t i = 0; i < contours.size(); i++ )
-     { mu[i] = moments( contours[i], false ); }
-
-  ///  Get the mass centers:
-  vector<Point2f> mc( contours.size() );
-  for( size_t i = 0; i < contours.size(); i++ )
-     { mc[i] = Point2f( static_cast<float>(mu[i].m10/mu[i].m00) , static_cast<float>(mu[i].m01/mu[i].m00) ); }
-
-  /// Draw contours
-  Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
-  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, LINE_8 );
-       circle( drawing, mc[i], 4, color, -1, 8, 0 );
-     }
-
-  /// Show in a window
-  namedWindow( "Contours", WINDOW_AUTOSIZE );
-  imshow( "Contours", drawing );
-
-  /// Calculate the area with the moments 00 and compare with the result of the OpenCV function
-  printf("\t Info: Area and Contour Length \n");
-  for( size_t i = 0; i< contours.size(); i++ )
-     {
-       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, LINE_8 );
-       circle( drawing, mc[i], 4, color, -1, 8, 0 );
-     }
+    /// Detect edges using canny
+    Mat canny_output;
+    Canny( src_gray, canny_output, thresh, thresh*2, 3 );
+    /// Find contours
+    vector<vector<Point> > contours;
+    findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
+
+    /// Get the moments
+    vector<Moments> mu(contours.size() );
+    for( size_t i = 0; i < contours.size(); i++ )
+    {
+        mu[i] = moments( contours[i] );
+    }
+
+    ///  Get the mass centers
+    vector<Point2f> mc( contours.size() );
+    for( size_t i = 0; i < contours.size(); i++ )
+    {
+        //add 1e-5 to avoid division by zero
+        mc[i] = Point2f( static_cast<float>(mu[i].m10 / (mu[i].m00 + 1e-5)),
+                         static_cast<float>(mu[i].m01 / (mu[i].m00 + 1e-5)) );
+        cout << "mc[" << i << "]=" << mc[i] << endl;
+    }
+
+    /// Draw contours
+    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
+    for( size_t i = 0; i< contours.size(); i++ )
+    {
+        Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
+        drawContours( drawing, contours, (int)i, color, 2 );
+        circle( drawing, mc[i], 4, color, -1 );
+    }
+
+    /// Show in a window
+    imshow( "Contours", drawing );
+
+    /// Calculate the area with the moments 00 and compare with the result of the OpenCV function
+    cout << "\t Info: Area and Contour Length \n";
+    for( size_t i = 0; i < contours.size(); i++ )
+    {
+        cout << " * Contour[" << i << "] - Area (M_00) = " << std::fixed << std::setprecision(2) << mu[i].m00
+             << " - Area OpenCV: " << contourArea(contours[i]) << " - Length: " << arcLength( contours[i], true ) << endl;
+    }
 }
 }
index efc481a..da3feed 100644 (file)
@@ -16,60 +16,71 @@ using namespace std;
  */
 int main( void )
 {
  */
 int main( void )
 {
-  /// Create an image
-  const int r = 100;
-  Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8UC1 );
+    /// Create an image
+    const int r = 100;
+    Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8U );
 
 
-  /// Create a sequence of points to make a contour:
-  vector<Point2f> vert(6);
+    /// Create a sequence of points to make a contour
+    vector<Point2f> vert(6);
+    vert[0] = Point( 3*r/2, static_cast<int>(1.34*r) );
+    vert[1] = Point( 1*r, 2*r );
+    vert[2] = Point( 3*r/2, static_cast<int>(2.866*r) );
+    vert[3] = Point( 5*r/2, static_cast<int>(2.866*r) );
+    vert[4] = Point( 3*r, 2*r );
+    vert[5] = Point( 5*r/2, static_cast<int>(1.34*r) );
 
 
-  vert[0] = Point( 3*r/2, static_cast<int>(1.34*r) );
-  vert[1] = Point( 1*r, 2*r );
-  vert[2] = Point( 3*r/2, static_cast<int>(2.866*r) );
-  vert[3] = Point( 5*r/2, static_cast<int>(2.866*r) );
-  vert[4] = Point( 3*r, 2*r );
-  vert[5] = Point( 5*r/2, static_cast<int>(1.34*r) );
+    /// Draw it in src
+    for( int i = 0; i < 6; i++ )
+    {
+        line( src, vert[i],  vert[(i+1)%6], Scalar( 255 ), 3 );
+    }
 
 
-  /// Draw it in src
-  for( int j = 0; j < 6; j++ )
-     { line( src, vert[j],  vert[(j+1)%6], Scalar( 255 ), 3, 8 ); }
+    /// Get the contours
+    vector<vector<Point> > contours;
+    findContours( src, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);
 
 
-  /// Get the contours
-  vector<vector<Point> > contours;
+    /// Calculate the distances to the contour
+    Mat raw_dist( src.size(), CV_32F );
+    for( int i = 0; i < src.rows; i++ )
+    {
+        for( int j = 0; j < src.cols; j++ )
+        {
+            raw_dist.at<float>(i,j) = (float)pointPolygonTest( contours[0], Point2f((float)j, (float)i), true );
+        }
+    }
 
 
-  findContours( src, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);
+    double minVal, maxVal;
+    minMaxLoc( raw_dist, &minVal, &maxVal );
+    minVal = abs(minVal);
+    maxVal = abs(maxVal);
 
 
-  /// Calculate the distances to the contour
-  Mat raw_dist( src.size(), CV_32FC1 );
-
-  for( int j = 0; j < src.rows; j++ )
-     { for( int i = 0; i < src.cols; i++ )
-          { raw_dist.at<float>(j,i) = (float)pointPolygonTest( contours[0], Point2f((float)i,(float)j), true ); }
-     }
-
-  double minVal; double maxVal;
-  minMaxLoc( raw_dist, &minVal, &maxVal, 0, 0, Mat() );
-  minVal = abs(minVal); maxVal = abs(maxVal);
-
-  /// Depicting the  distances graphically
-  Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
-
-  for( int j = 0; j < src.rows; j++ )
-     { for( int i = 0; i < src.cols; i++ )
-          {
-            if( raw_dist.at<float>(j,i) < 0 )
-              { drawing.at<Vec3b>(j,i)[0] = (uchar)(255 - abs(raw_dist.at<float>(j,i))*255/minVal); }
-            else if( raw_dist.at<float>(j,i) > 0 )
-              { drawing.at<Vec3b>(j,i)[2] = (uchar)(255 - raw_dist.at<float>(j,i)*255/maxVal); }
+    /// Depicting the  distances graphically
+    Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
+    for( int i = 0; i < src.rows; i++ )
+    {
+        for( int j = 0; j < src.cols; j++ )
+        {
+            if( raw_dist.at<float>(i,j) < 0 )
+            {
+                drawing.at<Vec3b>(i,j)[0] = (uchar)(255 - abs(raw_dist.at<float>(i,j)) * 255 / minVal);
+            }
+            else if( raw_dist.at<float>(i,j) > 0 )
+            {
+                drawing.at<Vec3b>(i,j)[2] = (uchar)(255 - raw_dist.at<float>(i,j) * 255 / maxVal);
+            }
             else
             else
-              { drawing.at<Vec3b>(j,i)[0] = 255; drawing.at<Vec3b>(j,i)[1] = 255; drawing.at<Vec3b>(j,i)[2] = 255; }
-          }
-     }
+            {
+                drawing.at<Vec3b>(i,j)[0] = 255;
+                drawing.at<Vec3b>(i,j)[1] = 255;
+                drawing.at<Vec3b>(i,j)[2] = 255;
+            }
+        }
+    }
 
 
-  /// Show your results
-  imshow( "Source", src );
-  imshow( "Distance", drawing );
+    /// Show your results
+    imshow( "Source", src );
+    imshow( "Distance", drawing );
 
 
-  waitKey(0);
-  return(0);
+    waitKey();
+    return 0;
 }
 }
diff --git a/samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java b/samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java
new file mode 100644 (file)
index 0000000..85bbf45
--- /dev/null
@@ -0,0 +1,179 @@
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.MatOfPoint2f;
+import org.opencv.core.Point;
+import org.opencv.core.Rect;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+class GeneralContours1 {
+    private Mat srcGray = new Mat();
+    private JFrame frame;
+    private JLabel imgSrcLabel;
+    private JLabel imgContoursLabel;
+    private static final int MAX_THRESHOLD = 255;
+    private int threshold = 100;
+    private Random rng = new Random(12345);
+
+    public GeneralContours1(String[] args) {
+        //! [setup]
+        /// Load source image
+        String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
+        Mat src = Imgcodecs.imread(filename);
+        if (src.empty()) {
+            System.err.println("Cannot read image: " + filename);
+            System.exit(0);
+        }
+
+        /// Convert image to gray and blur it
+        Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
+        Imgproc.blur(srcGray, srcGray, new Size(3, 3));
+        //! [setup]
+
+        //! [createWindow]
+        // Create and set up the window.
+        frame = new JFrame("Creating Bounding boxes and circles for contours demo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        // Set up the content pane.
+        Image img = HighGui.toBufferedImage(src);
+        addComponentsToPane(frame.getContentPane(), img);
+        //! [createWindow]
+        // Use the content pane's default BorderLayout. No need for
+        // setLayout(new BorderLayout());
+        // Display the window.
+        frame.pack();
+        frame.setVisible(true);
+        update();
+    }
+
+    private void addComponentsToPane(Container pane, Image img) {
+        if (!(pane.getLayout() instanceof BorderLayout)) {
+            pane.add(new JLabel("Container doesn't use BorderLayout!"));
+            return;
+        }
+
+        JPanel sliderPanel = new JPanel();
+        sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
+
+        //! [trackbar]
+        sliderPanel.add(new JLabel("Canny threshold: "));
+        JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
+        slider.setMajorTickSpacing(20);
+        slider.setMinorTickSpacing(10);
+        slider.setPaintTicks(true);
+        slider.setPaintLabels(true);
+        slider.addChangeListener(new ChangeListener() {
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JSlider source = (JSlider) e.getSource();
+                threshold = source.getValue();
+                update();
+            }
+        });
+        //! [trackbar]
+        sliderPanel.add(slider);
+        pane.add(sliderPanel, BorderLayout.PAGE_START);
+
+        JPanel imgPanel = new JPanel();
+        imgSrcLabel = new JLabel(new ImageIcon(img));
+        imgPanel.add(imgSrcLabel);
+
+        Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
+        imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
+        imgPanel.add(imgContoursLabel);
+
+        pane.add(imgPanel, BorderLayout.CENTER);
+    }
+
+    private void update() {
+        //! [Canny]
+        /// Detect edges using Canny
+        Mat cannyOutput = new Mat();
+        Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
+        //! [Canny]
+
+        //! [findContours]
+        /// Find contours
+        List<MatOfPoint> contours = new ArrayList<>();
+        Mat hierarchy = new Mat();
+        Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
+        //! [findContours]
+
+        //! [allthework]
+        /// Approximate contours to polygons + get bounding rects and circles
+        MatOfPoint2f[] contoursPoly  = new MatOfPoint2f[contours.size()];
+        Rect[] boundRect = new Rect[contours.size()];
+        Point[] centers = new Point[contours.size()];
+        float[][] radius = new float[contours.size()][1];
+
+        for (int i = 0; i < contours.size(); i++) {
+            contoursPoly[i] = new MatOfPoint2f();
+            Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(i).toArray()), contoursPoly[i], 3, true);
+            boundRect[i] = Imgproc.boundingRect(new MatOfPoint(contoursPoly[i].toArray()));
+            centers[i] = new Point();
+            Imgproc.minEnclosingCircle(contoursPoly[i], centers[i], radius[i]);
+        }
+        //! [allthework]
+
+        //! [zeroMat]
+        Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
+        //! [zeroMat]
+        //! [forContour]
+        /// Draw polygonal contour + bonding rects + circles
+        List<MatOfPoint> contoursPolyList = new ArrayList<>(contoursPoly.length);
+        for (MatOfPoint2f poly : contoursPoly) {
+            contoursPolyList.add(new MatOfPoint(poly.toArray()));
+        }
+
+        for (int i = 0; i < contours.size(); i++) {
+            Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
+            Imgproc.drawContours(drawing, contoursPolyList, i, color);
+            Imgproc.rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2);
+            Imgproc.circle(drawing, centers[i], (int) radius[i][0], color, 2);
+        }
+        //! [forContour]
+
+        //! [showDrawings]
+        /// Show in a window
+        imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
+        frame.repaint();
+        //! [showDrawings]
+    }
+}
+
+public class GeneralContoursDemo1 {
+    public static void main(String[] args) {
+        // Load the native OpenCV library
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+
+        // Schedule a job for the event dispatch thread:
+        // creating and showing this application's GUI.
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                new GeneralContours1(args);
+            }
+        });
+    }
+}
diff --git a/samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java b/samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java
new file mode 100644 (file)
index 0000000..c7b13dd
--- /dev/null
@@ -0,0 +1,176 @@
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.MatOfPoint2f;
+import org.opencv.core.Point;
+import org.opencv.core.RotatedRect;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+class GeneralContours2 {
+    private Mat srcGray = new Mat();
+    private JFrame frame;
+    private JLabel imgSrcLabel;
+    private JLabel imgContoursLabel;
+    private static final int MAX_THRESHOLD = 255;
+    private int threshold = 100;
+    private Random rng = new Random(12345);
+
+    public GeneralContours2(String[] args) {
+        //! [setup]
+        /// Load source image
+        String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
+        Mat src = Imgcodecs.imread(filename);
+        if (src.empty()) {
+            System.err.println("Cannot read image: " + filename);
+            System.exit(0);
+        }
+
+        /// Convert image to gray and blur it
+        Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
+        Imgproc.blur(srcGray, srcGray, new Size(3, 3));
+        //! [setup]
+
+        //! [createWindow]
+        // Create and set up the window.
+        frame = new JFrame("Creating Bounding rotated boxes and ellipses for contours demo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        // Set up the content pane.
+        Image img = HighGui.toBufferedImage(src);
+        addComponentsToPane(frame.getContentPane(), img);
+        //! [createWindow]
+        // Use the content pane's default BorderLayout. No need for
+        // setLayout(new BorderLayout());
+        // Display the window.
+        frame.pack();
+        frame.setVisible(true);
+        update();
+    }
+
+    private void addComponentsToPane(Container pane, Image img) {
+        if (!(pane.getLayout() instanceof BorderLayout)) {
+            pane.add(new JLabel("Container doesn't use BorderLayout!"));
+            return;
+        }
+
+        JPanel sliderPanel = new JPanel();
+        sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
+
+        //! [trackbar]
+        sliderPanel.add(new JLabel("Canny threshold: "));
+        JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
+        slider.setMajorTickSpacing(20);
+        slider.setMinorTickSpacing(10);
+        slider.setPaintTicks(true);
+        slider.setPaintLabels(true);
+        slider.addChangeListener(new ChangeListener() {
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JSlider source = (JSlider) e.getSource();
+                threshold = source.getValue();
+                update();
+            }
+        });
+        //! [trackbar]
+        sliderPanel.add(slider);
+        pane.add(sliderPanel, BorderLayout.PAGE_START);
+
+        JPanel imgPanel = new JPanel();
+        imgSrcLabel = new JLabel(new ImageIcon(img));
+        imgPanel.add(imgSrcLabel);
+
+        Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
+        imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
+        imgPanel.add(imgContoursLabel);
+
+        pane.add(imgPanel, BorderLayout.CENTER);
+    }
+
+    private void update() {
+        //! [Canny]
+        /// Detect edges using Canny
+        Mat cannyOutput = new Mat();
+        Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
+        //! [Canny]
+
+        //! [findContours]
+        /// Find contours
+        List<MatOfPoint> contours = new ArrayList<>();
+        Mat hierarchy = new Mat();
+        Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
+        //! [findContours]
+
+        /// Find the rotated rectangles and ellipses for each contour
+        RotatedRect[] minRect = new RotatedRect[contours.size()];
+        RotatedRect[] minEllipse = new RotatedRect[contours.size()];
+        for (int i = 0; i < contours.size(); i++) {
+            minRect[i] = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
+            minEllipse[i] = new RotatedRect();
+            if (contours.get(i).rows() > 5) {
+                minEllipse[i] = Imgproc.fitEllipse(new MatOfPoint2f(contours.get(i).toArray()));
+            }
+        }
+
+        //! [zeroMat]
+        /// Draw contours + rotated rects + ellipses
+        Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
+        //! [zeroMat]
+        //! [forContour]
+        for (int i = 0; i < contours.size(); i++) {
+            Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
+            // contour
+            Imgproc.drawContours(drawing, contours, i, color);
+            // ellipse
+            Imgproc.ellipse(drawing, minEllipse[i], color, 2);
+            // rotated rectangle
+            Point[] rectPoints = new Point[4];
+            minRect[i].points(rectPoints);
+            for (int j = 0; j < 4; j++) {
+                Imgproc.line(drawing, rectPoints[j], rectPoints[(j+1) % 4], color);
+            }
+        }
+        //! [forContour]
+
+        //! [showDrawings]
+        /// Show in a window
+        imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
+        frame.repaint();
+        //! [showDrawings]
+    }
+}
+
+public class GeneralContoursDemo2 {
+    public static void main(String[] args) {
+        // Load the native OpenCV library
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+
+        // Schedule a job for the event dispatch thread:
+        // creating and showing this application's GUI.
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                new GeneralContours2(args);
+            }
+        });
+    }
+}
diff --git a/samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java b/samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java
new file mode 100644 (file)
index 0000000..5eec4f8
--- /dev/null
@@ -0,0 +1,137 @@
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.Point;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+class FindContours {
+    private Mat srcGray = new Mat();
+    private JFrame frame;
+    private JLabel imgSrcLabel;
+    private JLabel imgContoursLabel;
+    private static final int MAX_THRESHOLD = 255;
+    private int threshold = 100;
+    private Random rng = new Random(12345);
+
+    public FindContours(String[] args) {
+        /// Load source image
+        String filename = args.length > 0 ? args[0] : "../data/HappyFish.jpg";
+        Mat src = Imgcodecs.imread(filename);
+        if (src.empty()) {
+            System.err.println("Cannot read image: " + filename);
+            System.exit(0);
+        }
+
+        /// Convert image to gray and blur it
+        Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
+        Imgproc.blur(srcGray, srcGray, new Size(3, 3));
+
+        // Create and set up the window.
+        frame = new JFrame("Finding contours in your image demo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        // Set up the content pane.
+        Image img = HighGui.toBufferedImage(src);
+        addComponentsToPane(frame.getContentPane(), img);
+        // Use the content pane's default BorderLayout. No need for
+        // setLayout(new BorderLayout());
+        // Display the window.
+        frame.pack();
+        frame.setVisible(true);
+        update();
+    }
+
+    private void addComponentsToPane(Container pane, Image img) {
+        if (!(pane.getLayout() instanceof BorderLayout)) {
+            pane.add(new JLabel("Container doesn't use BorderLayout!"));
+            return;
+        }
+
+        JPanel sliderPanel = new JPanel();
+        sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
+
+        sliderPanel.add(new JLabel("Canny threshold: "));
+        JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
+        slider.setMajorTickSpacing(20);
+        slider.setMinorTickSpacing(10);
+        slider.setPaintTicks(true);
+        slider.setPaintLabels(true);
+        slider.addChangeListener(new ChangeListener() {
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JSlider source = (JSlider) e.getSource();
+                threshold = source.getValue();
+                update();
+            }
+        });
+        sliderPanel.add(slider);
+        pane.add(sliderPanel, BorderLayout.PAGE_START);
+
+        JPanel imgPanel = new JPanel();
+        imgSrcLabel = new JLabel(new ImageIcon(img));
+        imgPanel.add(imgSrcLabel);
+
+        Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
+        imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
+        imgPanel.add(imgContoursLabel);
+
+        pane.add(imgPanel, BorderLayout.CENTER);
+    }
+
+    private void update() {
+        /// Detect edges using Canny
+        Mat cannyOutput = new Mat();
+        Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
+
+        /// Find contours
+        List<MatOfPoint> contours = new ArrayList<>();
+        Mat hierarchy = new Mat();
+        Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
+
+        /// Draw contours
+        Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
+        for (int i = 0; i < contours.size(); i++) {
+            Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
+            Imgproc.drawContours(drawing, contours, i, color, 2, Core.LINE_8, hierarchy, 0, new Point());
+        }
+
+        imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
+        frame.repaint();
+    }
+}
+
+public class FindContoursDemo {
+    public static void main(String[] args) {
+        // Load the native OpenCV library
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+
+        // Schedule a job for the event dispatch thread:
+        // creating and showing this application's GUI.
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                new FindContours(args);
+            }
+        });
+    }
+}
diff --git a/samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java b/samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java
new file mode 100644 (file)
index 0000000..0e2104f
--- /dev/null
@@ -0,0 +1,154 @@
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfInt;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.Point;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+class Hull {
+    private Mat srcGray = new Mat();
+    private JFrame frame;
+    private JLabel imgSrcLabel;
+    private JLabel imgContoursLabel;
+    private static final int MAX_THRESHOLD = 255;
+    private int threshold = 100;
+    private Random rng = new Random(12345);
+
+    public Hull(String[] args) {
+        /// Load source image
+        String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
+        Mat src = Imgcodecs.imread(filename);
+        if (src.empty()) {
+            System.err.println("Cannot read image: " + filename);
+            System.exit(0);
+        }
+
+        /// Convert image to gray and blur it
+        Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
+        Imgproc.blur(srcGray, srcGray, new Size(3, 3));
+
+        // Create and set up the window.
+        frame = new JFrame("Convex Hull demo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        // Set up the content pane.
+        Image img = HighGui.toBufferedImage(src);
+        addComponentsToPane(frame.getContentPane(), img);
+        // Use the content pane's default BorderLayout. No need for
+        // setLayout(new BorderLayout());
+        // Display the window.
+        frame.pack();
+        frame.setVisible(true);
+        update();
+    }
+
+    private void addComponentsToPane(Container pane, Image img) {
+        if (!(pane.getLayout() instanceof BorderLayout)) {
+            pane.add(new JLabel("Container doesn't use BorderLayout!"));
+            return;
+        }
+
+        JPanel sliderPanel = new JPanel();
+        sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
+
+        sliderPanel.add(new JLabel("Canny threshold: "));
+        JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
+        slider.setMajorTickSpacing(20);
+        slider.setMinorTickSpacing(10);
+        slider.setPaintTicks(true);
+        slider.setPaintLabels(true);
+        slider.addChangeListener(new ChangeListener() {
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JSlider source = (JSlider) e.getSource();
+                threshold = source.getValue();
+                update();
+            }
+        });
+        sliderPanel.add(slider);
+        pane.add(sliderPanel, BorderLayout.PAGE_START);
+
+        JPanel imgPanel = new JPanel();
+        imgSrcLabel = new JLabel(new ImageIcon(img));
+        imgPanel.add(imgSrcLabel);
+
+        Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
+        imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
+        imgPanel.add(imgContoursLabel);
+
+        pane.add(imgPanel, BorderLayout.CENTER);
+    }
+
+    private void update() {
+        /// Detect edges using Canny
+        Mat cannyOutput = new Mat();
+        Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
+
+        /// Find contours
+        List<MatOfPoint> contours = new ArrayList<>();
+        Mat hierarchy = new Mat();
+        Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
+
+        /// Find the convex hull object for each contour
+        List<MatOfPoint> hullList = new ArrayList<>();
+        for (MatOfPoint contour : contours) {
+            MatOfInt hull = new MatOfInt();
+            Imgproc.convexHull(contour, hull);
+
+            Point[] contourArray = contour.toArray();
+            Point[] hullPoints = new Point[hull.rows()];
+            List<Integer> hullContourIdxList = hull.toList();
+            for (int i = 0; i < hullContourIdxList.size(); i++) {
+                hullPoints[i] = contourArray[hullContourIdxList.get(i)];
+            }
+            hullList.add(new MatOfPoint(hullPoints));
+        }
+
+        /// Draw contours + hull results
+        Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
+        for (int i = 0; i < contours.size(); i++) {
+            Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
+            Imgproc.drawContours(drawing, contours, i, color);
+            Imgproc.drawContours(drawing, hullList, i, color );
+        }
+
+        imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
+        frame.repaint();
+    }
+}
+
+public class HullDemo {
+    public static void main(String[] args) {
+        // Load the native OpenCV library
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+
+        // Schedule a job for the event dispatch thread:
+        // creating and showing this application's GUI.
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                new Hull(args);
+            }
+        });
+    }
+}
diff --git a/samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java b/samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java
new file mode 100644 (file)
index 0000000..ffc2420
--- /dev/null
@@ -0,0 +1,178 @@
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.MatOfPoint2f;
+import org.opencv.core.Point;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+import org.opencv.imgproc.Moments;
+
+class MomentsClass {
+    private Mat srcGray = new Mat();
+    private JFrame frame;
+    private JLabel imgSrcLabel;
+    private JLabel imgContoursLabel;
+    private static final int MAX_THRESHOLD = 255;
+    private int threshold = 100;
+    private Random rng = new Random(12345);
+
+    public MomentsClass(String[] args) {
+        //! [setup]
+        /// Load source image
+        String filename = args.length > 0 ? args[0] : "../data/stuff.jpg";
+        Mat src = Imgcodecs.imread(filename);
+        if (src.empty()) {
+            System.err.println("Cannot read image: " + filename);
+            System.exit(0);
+        }
+
+        /// Convert image to gray and blur it
+        Imgproc.cvtColor(src, srcGray, Imgproc.COLOR_BGR2GRAY);
+        Imgproc.blur(srcGray, srcGray, new Size(3, 3));
+        //! [setup]
+
+        //! [createWindow]
+        // Create and set up the window.
+        frame = new JFrame("Image Moments demo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        // Set up the content pane.
+        Image img = HighGui.toBufferedImage(src);
+        addComponentsToPane(frame.getContentPane(), img);
+        //! [createWindow]
+        // Use the content pane's default BorderLayout. No need for
+        // setLayout(new BorderLayout());
+        // Display the window.
+        frame.pack();
+        frame.setVisible(true);
+        update();
+    }
+
+    private void addComponentsToPane(Container pane, Image img) {
+        if (!(pane.getLayout() instanceof BorderLayout)) {
+            pane.add(new JLabel("Container doesn't use BorderLayout!"));
+            return;
+        }
+
+        JPanel sliderPanel = new JPanel();
+        sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.PAGE_AXIS));
+
+        //! [trackbar]
+        sliderPanel.add(new JLabel("Canny threshold: "));
+        JSlider slider = new JSlider(0, MAX_THRESHOLD, threshold);
+        slider.setMajorTickSpacing(20);
+        slider.setMinorTickSpacing(10);
+        slider.setPaintTicks(true);
+        slider.setPaintLabels(true);
+        slider.addChangeListener(new ChangeListener() {
+            @Override
+            public void stateChanged(ChangeEvent e) {
+                JSlider source = (JSlider) e.getSource();
+                threshold = source.getValue();
+                update();
+            }
+        });
+        //! [trackbar]
+        sliderPanel.add(slider);
+        pane.add(sliderPanel, BorderLayout.PAGE_START);
+
+        JPanel imgPanel = new JPanel();
+        imgSrcLabel = new JLabel(new ImageIcon(img));
+        imgPanel.add(imgSrcLabel);
+
+        Mat blackImg = Mat.zeros(srcGray.size(), CvType.CV_8U);
+        imgContoursLabel = new JLabel(new ImageIcon(HighGui.toBufferedImage(blackImg)));
+        imgPanel.add(imgContoursLabel);
+
+        pane.add(imgPanel, BorderLayout.CENTER);
+    }
+
+    private void update() {
+        //! [Canny]
+        /// Detect edges using Canny
+        Mat cannyOutput = new Mat();
+        Imgproc.Canny(srcGray, cannyOutput, threshold, threshold * 2);
+        //! [Canny]
+
+        //! [findContours]
+        /// Find contours
+        List<MatOfPoint> contours = new ArrayList<>();
+        Mat hierarchy = new Mat();
+        Imgproc.findContours(cannyOutput, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
+        //! [findContours]
+
+        /// Get the moments
+        List<Moments> mu = new ArrayList<>(contours.size());
+        for (int i = 0; i < contours.size(); i++) {
+            mu.add(Imgproc.moments(contours.get(i)));
+        }
+
+        /// Get the mass centers
+        List<Point> mc = new ArrayList<>(contours.size());
+        for (int i = 0; i < contours.size(); i++) {
+            //add 1e-5 to avoid division by zero
+            mc.add(new Point(mu.get(i).m10 / (mu.get(i).m00 + 1e-5), mu.get(i).m01 / (mu.get(i).m00 + 1e-5)));
+        }
+
+        //! [zeroMat]
+        /// Draw contours
+        Mat drawing = Mat.zeros(cannyOutput.size(), CvType.CV_8UC3);
+        //! [zeroMat]
+        //! [forContour]
+        for (int i = 0; i < contours.size(); i++) {
+            Scalar color = new Scalar(rng.nextInt(256), rng.nextInt(256), rng.nextInt(256));
+            Imgproc.drawContours(drawing, contours, i, color, 2);
+            Imgproc.circle(drawing, mc.get(i), 4, color, -1);
+        }
+        //! [forContour]
+
+        //! [showDrawings]
+        /// Show in a window
+        imgContoursLabel.setIcon(new ImageIcon(HighGui.toBufferedImage(drawing)));
+        frame.repaint();
+        //! [showDrawings]
+
+        /// Calculate the area with the moments 00 and compare with the result of the OpenCV function
+        System.out.println("\t Info: Area and Contour Length \n");
+        for (int i = 0; i < contours.size(); i++) {
+            System.out.format(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f\n", i,
+                    mu.get(i).m00, Imgproc.contourArea(contours.get(i)),
+                    Imgproc.arcLength(new MatOfPoint2f(contours.get(i).toArray()), true));
+        }
+    }
+}
+
+public class MomentsDemo {
+    public static void main(String[] args) {
+        // Load the native OpenCV library
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+
+        // Schedule a job for the event dispatch thread:
+        // creating and showing this application's GUI.
+        javax.swing.SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                new MomentsClass(args);
+            }
+        });
+    }
+}
diff --git a/samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java b/samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java
new file mode 100644 (file)
index 0000000..2d0a542
--- /dev/null
@@ -0,0 +1,93 @@
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opencv.core.Core;
+import org.opencv.core.Core.MinMaxLocResult;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.MatOfPoint2f;
+import org.opencv.core.Point;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgproc.Imgproc;
+
+class PointPolygonTest {
+    public void run() {
+        /// Create an image
+        int r = 100;
+        Mat src = Mat.zeros(new Size(4 * r, 4 * r), CvType.CV_8U);
+
+        /// Create a sequence of points to make a contour
+        List<Point> vert = new ArrayList<>(6);
+        vert.add(new Point(3 * r / 2, 1.34 * r));
+        vert.add(new Point(1 * r, 2 * r));
+        vert.add(new Point(3 * r / 2, 2.866 * r));
+        vert.add(new Point(5 * r / 2, 2.866 * r));
+        vert.add(new Point(3 * r, 2 * r));
+        vert.add(new Point(5 * r / 2, 1.34 * r));
+
+        /// Draw it in src
+        for (int i = 0; i < 6; i++) {
+            Imgproc.line(src, vert.get(i), vert.get((i + 1) % 6), new Scalar(255), 3);
+        }
+
+        /// Get the contours
+        List<MatOfPoint> contours = new ArrayList<>();
+        Mat hierarchy = new Mat();
+        Imgproc.findContours(src, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
+
+        /// Calculate the distances to the contour
+        Mat rawDist = new Mat(src.size(), CvType.CV_32F);
+        float[] rawDistData = new float[(int) (rawDist.total() * rawDist.channels())];
+        for (int i = 0; i < src.rows(); i++) {
+            for (int j = 0; j < src.cols(); j++) {
+                rawDistData[i * src.cols() + j] = (float) Imgproc
+                        .pointPolygonTest(new MatOfPoint2f(contours.get(0).toArray()), new Point(j, i), true);
+            }
+        }
+        rawDist.put(0, 0, rawDistData);
+
+        MinMaxLocResult res = Core.minMaxLoc(rawDist);
+        double minVal = Math.abs(res.minVal);
+        double maxVal = Math.abs(res.maxVal);
+
+        /// Depicting the distances graphically
+        Mat drawing = Mat.zeros(src.size(), CvType.CV_8UC3);
+        byte[] drawingData = new byte[(int) (drawing.total() * drawing.channels())];
+        for (int i = 0; i < src.rows(); i++) {
+            for (int j = 0; j < src.cols(); j++) {
+                if (rawDistData[i * src.cols() + j] < 0) {
+                    drawingData[(i * src.cols() + j) * 3] =
+                            (byte) (255 - Math.abs(rawDistData[i * src.cols() + j]) * 255 / minVal);
+                } else if (rawDistData[i * src.cols() + j] > 0) {
+                    drawingData[(i * src.cols() + j) * 3 + 2] =
+                            (byte) (255 - rawDistData[i * src.cols() + j] * 255 / maxVal);
+                } else {
+                    drawingData[(i * src.cols() + j) * 3] = (byte) 255;
+                    drawingData[(i * src.cols() + j) * 3 + 1] = (byte) 255;
+                    drawingData[(i * src.cols() + j) * 3 + 2] = (byte) 255;
+                }
+            }
+        }
+        drawing.put(0, 0, drawingData);
+
+        /// Show your results
+        HighGui.imshow("Source", src);
+        HighGui.imshow("Distance", drawing);
+
+        HighGui.waitKey();
+        System.exit(0);
+    }
+}
+
+public class PointPolygonTestDemo {
+    public static void main(String[] args) {
+        // Load the native OpenCV library
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+
+        new PointPolygonTest().run();
+    }
+
+}
diff --git a/samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py b/samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py
new file mode 100644 (file)
index 0000000..0601674
--- /dev/null
@@ -0,0 +1,82 @@
+from __future__ import print_function
+import cv2 as cv
+import numpy as np
+import argparse
+import random as rng
+
+rng.seed(12345)
+
+def thresh_callback(val):
+    threshold = val
+
+    ## [Canny]
+    # Detect edges using Canny
+    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
+    ## [Canny]
+
+    ## [findContours]
+    # Find contours
+    _, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
+    ## [findContours]
+
+    ## [allthework]
+    # Approximate contours to polygons + get bounding rects and circles
+    contours_poly = [None]*len(contours)
+    boundRect = [None]*len(contours)
+    centers = [None]*len(contours)
+    radius = [None]*len(contours)
+    for i in range(len(contours)):
+        contours_poly[i] = cv.approxPolyDP(contours[i], 3, True)
+        boundRect[i] = cv.boundingRect(contours_poly[i])
+        centers[i], radius[i] = cv.minEnclosingCircle(contours_poly[i])
+    ## [allthework]
+
+    ## [zeroMat]
+    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
+    ## [zeroMat]
+
+    ## [forContour]
+    # Draw polygonal contour + bonding rects + circles
+    for i in range(len(contours)):
+        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
+        cv.drawContours(drawing, contours_poly, i, color)
+        cv.rectangle(drawing, (int(boundRect[i][0]), int(boundRect[i][1])), \
+          (int(boundRect[i][0]+boundRect[i][2]), int(boundRect[i][1]+boundRect[i][3])), color, 2)
+        cv.circle(drawing, (int(centers[i][0]), int(centers[i][1])), int(radius[i]), color, 2)
+    ## [forContour]
+
+    ## [showDrawings]
+    # Show in a window
+    cv.imshow('Contours', drawing)
+    ## [showDrawings]
+
+## [setup]
+# Load source image
+parser = argparse.ArgumentParser(description='Code for Creating Bounding boxes and circles for contours tutorial.')
+parser.add_argument('--input', help='Path to input image.', default='../data/stuff.jpg')
+args = parser.parse_args()
+
+src = cv.imread(args.input)
+if src is None:
+    print('Could not open or find the image:', args.input)
+    exit(0)
+
+# Convert image to gray and blur it
+src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
+src_gray = cv.blur(src_gray, (3,3))
+## [setup]
+
+## [createWindow]
+# Create Window
+source_window = 'Source'
+cv.namedWindow(source_window)
+cv.imshow(source_window, src)
+## [createWindow]
+## [trackbar]
+max_thresh = 255
+thresh = 100 # initial threshold
+cv.createTrackbar('Canny thresh:', source_window, thresh, max_thresh, thresh_callback)
+thresh_callback(thresh)
+## [trackbar]
+
+cv.waitKey()
diff --git a/samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py b/samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py
new file mode 100644 (file)
index 0000000..a461aba
--- /dev/null
@@ -0,0 +1,82 @@
+from __future__ import print_function
+import cv2 as cv
+import numpy as np
+import argparse
+import random as rng
+
+rng.seed(12345)
+
+def thresh_callback(val):
+    threshold = val
+
+    ## [Canny]
+    # Detect edges using Canny
+    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
+    ## [Canny]
+
+    ## [findContours]
+    # Find contours
+    _, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
+    ## [findContours]
+
+    # Find the rotated rectangles and ellipses for each contour
+    minRect = [None]*len(contours)
+    minEllipse = [None]*len(contours)
+    for i in range(len(contours)):
+        minRect[i] = cv.minAreaRect(contours[i])
+        if contours[i].shape[0] > 5:
+            minEllipse[i] = cv.fitEllipse(contours[i])
+
+    # Draw contours + rotated rects + ellipses
+    ## [zeroMat]
+    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
+    ## [zeroMat]
+    ## [forContour]
+    for i in range(len(contours)):
+        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
+        # contour
+        cv.drawContours(drawing, contours, i, color)
+        # ellipse
+        if contours[i].shape[0] > 5:
+            cv.ellipse(drawing, minEllipse[i], color, 2)
+        # rotated rectangle
+        box = cv.boxPoints(minRect[i])
+        box = np.intp(box) #np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)
+        cv.drawContours(drawing, [box], 0, color)
+    ## [forContour]
+
+    ## [showDrawings]
+    # Show in a window
+    cv.imshow('Contours', drawing)
+    ## [showDrawings]
+
+## [setup]
+# Load source image
+parser = argparse.ArgumentParser(description='Code for Creating Bounding rotated boxes and ellipses for contours tutorial.')
+parser.add_argument('--input', help='Path to input image.', default='../data/stuff.jpg')
+args = parser.parse_args()
+
+src = cv.imread(args.input)
+if src is None:
+    print('Could not open or find the image:', args.input)
+    exit(0)
+
+# Convert image to gray and blur it
+src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
+src_gray = cv.blur(src_gray, (3,3))
+## [setup]
+
+## [createWindow]
+# Create Window
+source_window = 'Source'
+cv.namedWindow(source_window)
+cv.imshow(source_window, src)
+## [createWindow]
+## [trackbar]
+max_thresh = 255
+thresh = 100 # initial threshold
+cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
+thresh_callback(thresh)
+## [trackbar]
+
+cv.waitKey()
diff --git a/samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py b/samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py
new file mode 100644 (file)
index 0000000..f4cbb5f
--- /dev/null
@@ -0,0 +1,50 @@
+from __future__ import print_function
+import cv2 as cv
+import numpy as np
+import argparse
+import random as rng
+
+rng.seed(12345)
+
+def thresh_callback(val):
+    threshold = val
+
+    # Detect edges using Canny
+    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
+
+    # Find contours
+    _, contours, hierarchy = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
+
+    # Draw contours
+    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
+    for i in range(len(contours)):
+        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
+        cv.drawContours(drawing, contours, i, color, 2, cv.LINE_8, hierarchy, 0)
+
+    # Show in a window
+    cv.imshow('Contours', drawing)
+
+# Load source image
+parser = argparse.ArgumentParser(description='Code for Finding contours in your image tutorial.')
+parser.add_argument('--input', help='Path to input image.', default='../data/HappyFish.jpg')
+args = parser.parse_args()
+
+src = cv.imread(args.input)
+if src is None:
+    print('Could not open or find the image:', args.input)
+    exit(0)
+
+# Convert image to gray and blur it
+src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
+src_gray = cv.blur(src_gray, (3,3))
+
+# Create Window
+source_window = 'Source'
+cv.namedWindow(source_window)
+cv.imshow(source_window, src)
+max_thresh = 255
+thresh = 100 # initial threshold
+cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
+thresh_callback(thresh)
+
+cv.waitKey()
diff --git a/samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py b/samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py
new file mode 100644 (file)
index 0000000..3254941
--- /dev/null
@@ -0,0 +1,57 @@
+from __future__ import print_function
+import cv2 as cv
+import numpy as np
+import argparse
+import random as rng
+
+rng.seed(12345)
+
+def thresh_callback(val):
+    threshold = val
+
+    # Detect edges using Canny
+    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
+
+    # Find contours
+    _, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
+
+    # Find the convex hull object for each contour
+    hull_list = []
+    for i in range(len(contours)):
+        hull = cv.convexHull(contours[i])
+        hull_list.append(hull)
+
+    # Draw contours + hull results
+    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
+    for i in range(len(contours)):
+        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
+        cv.drawContours(drawing, contours, i, color)
+        cv.drawContours(drawing, hull_list, i, color)
+
+    # Show in a window
+    cv.imshow('Contours', drawing)
+
+# Load source image
+parser = argparse.ArgumentParser(description='Code for Convex Hull tutorial.')
+parser.add_argument('--input', help='Path to input image.', default='../data/stuff.jpg')
+args = parser.parse_args()
+
+src = cv.imread(args.input)
+if src is None:
+    print('Could not open or find the image:', args.input)
+    exit(0)
+
+# Convert image to gray and blur it
+src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
+src_gray = cv.blur(src_gray, (3,3))
+
+# Create Window
+source_window = 'Source'
+cv.namedWindow(source_window)
+cv.imshow(source_window, src)
+max_thresh = 255
+thresh = 100 # initial threshold
+cv.createTrackbar('Canny thresh:', source_window, thresh, max_thresh, thresh_callback)
+thresh_callback(thresh)
+
+cv.waitKey()
diff --git a/samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py b/samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py
new file mode 100644 (file)
index 0000000..c528110
--- /dev/null
@@ -0,0 +1,83 @@
+from __future__ import print_function
+from __future__ import division
+import cv2 as cv
+import numpy as np
+import argparse
+import random as rng
+
+rng.seed(12345)
+
+def thresh_callback(val):
+    threshold = val
+
+    ## [Canny]
+    # Detect edges using Canny
+    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
+    ## [Canny]
+
+    ## [findContours]
+    # Find contours
+    _, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
+    ## [findContours]
+
+    # Get the moments
+    mu = [None]*len(contours)
+    for i in range(len(contours)):
+        mu[i] = cv.moments(contours[i])
+
+    # Get the mass centers
+    mc = [None]*len(contours)
+    for i in range(len(contours)):
+        # add 1e-5 to avoid division by zero
+        mc[i] = (mu[i]['m10'] / (mu[i]['m00'] + 1e-5), mu[i]['m01'] / (mu[i]['m00'] + 1e-5))
+
+    # Draw contours
+    ## [zeroMat]
+    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
+    ## [zeroMat]
+    ## [forContour]
+    for i in range(len(contours)):
+        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
+        cv.drawContours(drawing, contours, i, color, 2)
+        cv.circle(drawing, (int(mc[i][0]), int(mc[i][1])), 4, color, -1)
+    ## [forContour]
+
+    ## [showDrawings]
+    # Show in a window
+    cv.imshow('Contours', drawing)
+    ## [showDrawings]
+
+    # Calculate the area with the moments 00 and compare with the result of the OpenCV function
+    for i in range(len(contours)):
+        print(' * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f' % (i, mu[i]['m00'], cv.contourArea(contours[i]), cv.arcLength(contours[i], True)))
+
+## [setup]
+# Load source image
+parser = argparse.ArgumentParser(description='Code for Image Moments tutorial.')
+parser.add_argument('--input', help='Path to input image.', default='../data/stuff.jpg')
+args = parser.parse_args()
+
+src = cv.imread(args.input)
+if src is None:
+    print('Could not open or find the image:', args.input)
+    exit(0)
+
+# Convert image to gray and blur it
+src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
+src_gray = cv.blur(src_gray, (3,3))
+## [setup]
+
+## [createWindow]
+# Create Window
+source_window = 'Source'
+cv.namedWindow(source_window)
+cv.imshow(source_window, src)
+## [createWindow]
+## [trackbar]
+max_thresh = 255
+thresh = 100 # initial threshold
+cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
+thresh_callback(thresh)
+## [trackbar]
+
+cv.waitKey()
diff --git a/samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py b/samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py
new file mode 100644 (file)
index 0000000..150727e
--- /dev/null
@@ -0,0 +1,51 @@
+from __future__ import print_function
+from __future__ import division
+import cv2 as cv
+import numpy as np
+
+# Create an image
+r = 100
+src = np.zeros((4*r, 4*r), dtype=np.uint8)
+
+# Create a sequence of points to make a contour
+vert = [None]*6
+vert[0] = (3*r//2, int(1.34*r))
+vert[1] = (1*r, 2*r)
+vert[2] = (3*r//2, int(2.866*r))
+vert[3] = (5*r//2, int(2.866*r))
+vert[4] = (3*r, 2*r)
+vert[5] = (5*r//2, int(1.34*r))
+
+# Draw it in src
+for i in range(6):
+    cv.line(src, vert[i],  vert[(i+1)%6], ( 255 ), 3)
+
+# Get the contours
+_, contours, _ = cv.findContours(src, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
+
+# Calculate the distances to the contour
+raw_dist = np.empty(src.shape, dtype=np.float32)
+for i in range(src.shape[0]):
+    for j in range(src.shape[1]):
+        raw_dist[i,j] = cv.pointPolygonTest(contours[0], (j,i), True)
+
+minVal, maxVal, _, _ = cv.minMaxLoc(raw_dist)
+minVal = abs(minVal)
+maxVal = abs(maxVal)
+
+# Depicting the  distances graphically
+drawing = np.zeros((src.shape[0], src.shape[1], 3), dtype=np.uint8)
+for i in range(src.shape[0]):
+    for j in range(src.shape[1]):
+        if raw_dist[i,j] < 0:
+            drawing[i,j,0] = 255 - abs(raw_dist[i,j]) * 255 / minVal
+        elif raw_dist[i,j] > 0:
+            drawing[i,j,2] = 255 - raw_dist[i,j] * 255 / maxVal
+        else:
+            drawing[i,j,0] = 255
+            drawing[i,j,1] = 255
+            drawing[i,j,2] = 255
+
+cv.imshow('Source', src)
+cv.imshow('Distance', drawing)
+cv.waitKey()