Tutorial Image Pyramids
authortribta <joaocartuchoo@gmail.com>
Wed, 23 Aug 2017 14:37:11 +0000 (15:37 +0100)
committertribta <joaocartuchoo@gmail.com>
Thu, 5 Oct 2017 11:17:38 +0000 (14:17 +0300)
doc/tutorials/imgproc/pyramids/pyramids.markdown
doc/tutorials/imgproc/table_of_content_imgproc.markdown
samples/cpp/tutorial_code/ImgProc/Pyramids.cpp [deleted file]
samples/cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp [new file with mode: 0644]
samples/java/tutorial_code/ImgProc/Pyramids/Pyramids.java [new file with mode: 0644]
samples/python/tutorial_code/imgProc/Pyramids/pyramids.py [new file with mode: 0644]

index 5210ec0..b832b22 100644 (file)
@@ -1,12 +1,15 @@
 Image Pyramids {#tutorial_pyramids}
 ==============
 
+@prev_tutorial{tutorial_morph_lines_detection}
+@next_tutorial{tutorial_threshold}
+
 Goal
 ----
 
 In this tutorial you will learn how to:
 
--   Use the OpenCV functions @ref cv::pyrUp and @ref cv::pyrDown to downsample or upsample a given
+-   Use the OpenCV functions **pyrUp()** and **pyrDown()** to downsample or upsample a given
     image.
 
 Theory
@@ -19,7 +22,7 @@ Theory
     -#  *Upsize* the image (zoom in) or
     -#  *Downsize* it (zoom out).
 -   Although there is a *geometric transformation* function in OpenCV that -literally- resize an
-    image (@ref cv::resize , which we will show in a future tutorial), in this section we analyze
+    image (**resize** , which we will show in a future tutorial), in this section we analyze
     first the use of **Image Pyramids**, which are widely applied in a huge range of vision
     applications.
 
@@ -52,12 +55,12 @@ Theory
     predecessor. Iterating this process on the input image \f$G_{0}\f$ (original image) produces the
     entire pyramid.
 -   The procedure above was useful to downsample an image. What if we want to make it bigger?:
-    columns filled with zeros (\f$0\f$)
+    columns filled with zeros (\f$0 \f$)
     -   First, upsize the image to twice the original in each dimension, wit the new even rows and
     -   Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the
         values of the "missing pixels"
 -   These two procedures (downsampling and upsampling as explained above) are implemented by the
-    OpenCV functions @ref cv::pyrUp and @ref cv::pyrDown , as we will see in an example with the
+    OpenCV functions **pyrUp()** and **pyrDown()** , as we will see in an example with the
     code below:
 
 @note When we reduce the size of an image, we are actually *losing* information of the image.
@@ -65,76 +68,134 @@ Theory
 Code
 ----
 
-This tutorial code's is shown lines below. You can also download it from
-[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp)
+This tutorial code's is shown lines below.
+
+@add_toggle_cpp
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp)
+@include samples/cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp
+@end_toggle
+
+@add_toggle_java
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgProc/Pyramids/Pyramids.java)
+@include samples/java/tutorial_code/ImgProc/Pyramids/Pyramids.java
+@end_toggle
 
-@include samples/cpp/tutorial_code/ImgProc/Pyramids.cpp
+@add_toggle_python
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/imgProc/Pyramids/pyramids.py)
+@include samples/python/tutorial_code/imgProc/Pyramids/pyramids.py
+@end_toggle
 
 Explanation
 -----------
 
 Let's check the general structure of the program:
 
--   Load an image (in this case it is defined in the program, the user does not have to enter it
-    as an argument)
-    @snippet cpp/tutorial_code/ImgProc/Pyramids.cpp load
+#### Load an image
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp load
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgProc/Pyramids/Pyramids.java load
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/imgProc/Pyramids/pyramids.py load
+@end_toggle
+
+#### Create window
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp show_image
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgProc/Pyramids/Pyramids.java show_image
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/imgProc/Pyramids/pyramids.py show_image
+@end_toggle
 
--   Create a Mat object to store the result of the operations (*dst*) and one to save temporal
-    results (*tmp*).
-    @code{.cpp}
-    Mat src, dst, tmp;
-    /* ... */
-    tmp = src;
-    dst = tmp;
-    @endcode
+#### Loop
 
--   Create a window to display the result
-    @snippet cpp/tutorial_code/ImgProc/Pyramids.cpp create_window
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp loop
+@end_toggle
 
--   Perform an infinite loop waiting for user input.
-    @snippet cpp/tutorial_code/ImgProc/Pyramids.cpp infinite_loop
+@add_toggle_java
+@snippet java/tutorial_code/ImgProc/Pyramids/Pyramids.java loop
+@end_toggle
 
-    Our program exits if the user presses *ESC*. Besides, it has two options:
+@add_toggle_python
+@snippet python/tutorial_code/imgProc/Pyramids/pyramids.py loop
+@end_toggle
 
-    -   **Perform upsampling (after pressing 'u')**
-        @snippet cpp/tutorial_code/ImgProc/Pyramids.cpp pyrup
-        We use the function @ref cv::pyrUp with three arguments:
+Perform an infinite loop waiting for user input.
+Our program exits if the user presses **ESC**. Besides, it has two options:
 
-        -   *tmp*: The current image, it is initialized with the *src* original image.
-        -   *dst*: The destination image (to be shown on screen, supposedly the double of the
+-   **Perform upsampling - Zoom 'i'n (after pressing 'i')**
+
+    We use the function **pyrUp()** with three arguments:
+        -   *src*: The current and destination image (to be shown on screen, supposedly the double of the
             input image)
-        -   *Size( tmp.cols*2, tmp.rows\*2 )\* : The destination size. Since we are upsampling,
-            @ref cv::pyrUp expects a size double than the input image (in this case *tmp*).
-    -   **Perform downsampling (after pressing 'd')**
-        @snippet cpp/tutorial_code/ImgProc/Pyramids.cpp pyrdown
-        Similarly as with @ref cv::pyrUp , we use the function @ref cv::pyrDown with three arguments:
-
-        -   *tmp*: The current image, it is initialized with the *src* original image.
-        -   *dst*: The destination image (to be shown on screen, supposedly half the input
-            image)
-        -   *Size( tmp.cols/2, tmp.rows/2 )* : The destination size. Since we are upsampling,
-            @ref cv::pyrDown expects half the size the input image (in this case *tmp*).
-    -   Notice that it is important that the input image can be divided by a factor of two (in
-        both dimensions). Otherwise, an error will be shown.
-    -   Finally, we update the input image **tmp** with the current image displayed, so the
-        subsequent operations are performed on it.
-        @snippet cpp/tutorial_code/ImgProc/Pyramids.cpp update_tmp
+        -   *Size( tmp.cols*2, tmp.rows\*2 )* : The destination size. Since we are upsampling,
+            **pyrUp()** expects a size double than the input image (in this case *src*).
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp pyrup
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgProc/Pyramids/Pyramids.java pyrup
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/imgProc/Pyramids/pyramids.py pyrup
+@end_toggle
+
+-   **Perform downsampling - Zoom 'o'ut (after pressing 'o')**
+
+    We use the function **pyrDown()** with three arguments (similarly to **pyrUp()**):
+            -   *src*: The current and destination image  (to be shown on screen, supposedly half the input
+                image)
+            -   *Size( tmp.cols/2, tmp.rows/2 )* : The destination size. Since we are upsampling,
+                **pyrDown()** expects half the size the input image (in this case *src*).
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp pyrdown
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgProc/Pyramids/Pyramids.java pyrdown
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/imgProc/Pyramids/pyramids.py pyrdown
+@end_toggle
+
+Notice that it is important that the input image can be divided by a factor of two (in both dimensions).
+Otherwise, an error will be shown.
 
 Results
 -------
 
--   After compiling the code above we can test it. The program calls an image **chicky_512.jpg**
-    that comes in the *samples/data* folder. Notice that this image is \f$512 \times 512\f$,
+-   The program calls by default an image [chicky_512.png](https://raw.githubusercontent.com/opencv/opencv/master/samples/data/chicky_512.png)
+    that comes in the `samples/data` folder. Notice that this image is \f$512 \times 512\f$,
     hence a downsample won't generate any error (\f$512 = 2^{9}\f$). The original image is shown below:
 
     ![](images/Pyramids_Tutorial_Original_Image.jpg)
 
--   First we apply two successive @ref cv::pyrDown operations by pressing 'd'. Our output is:
+-   First we apply two successive **pyrDown()** operations by pressing 'd'. Our output is:
 
     ![](images/Pyramids_Tutorial_PyrDown_Result.jpg)
 
 -   Note that we should have lost some resolution due to the fact that we are diminishing the size
-    of the image. This is evident after we apply @ref cv::pyrUp twice (by pressing 'u'). Our output
+    of the image. This is evident after we apply **pyrUp()** twice (by pressing 'u'). Our output
     is now:
 
     ![](images/Pyramids_Tutorial_PyrUp_Result.jpg)
index f4c57cd..d255023 100644 (file)
@@ -51,6 +51,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -   @subpage tutorial_pyramids
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
diff --git a/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp b/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp
deleted file mode 100644 (file)
index 62c2fe5..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file Pyramids.cpp
- * @brief Sample code of image pyramids (pyrDown and pyrUp)
- * @author OpenCV team
- */
-
-#include "opencv2/imgproc.hpp"
-#include "opencv2/imgcodecs.hpp"
-#include "opencv2/highgui.hpp"
-
-using namespace cv;
-
-/// Global variables
-Mat src, dst, tmp;
-
-const char* window_name = "Pyramids Demo";
-
-
-/**
- * @function main
- */
-int main( void )
-{
-  /// General instructions
-  printf( "\n Zoom In-Out demo  \n " );
-  printf( "------------------ \n" );
-  printf( " * [u] -> Zoom in  \n" );
-  printf( " * [d] -> Zoom out \n" );
-  printf( " * [ESC] -> Close program \n \n" );
-
-  //![load]
-  src = imread( "../data/chicky_512.png" ); // Loads the test image
-  if( src.empty() )
-    { printf(" No data! -- Exiting the program \n");
-      return -1; }
-  //![load]
-
-  tmp = src;
-  dst = tmp;
-
-  //![create_window]
-  imshow( window_name, dst );
-  //![create_window]
-
-  //![infinite_loop]
-  for(;;)
-  {
-    char c = (char)waitKey(0);
-
-    if( c == 27 )
-      { break; }
-    //![pyrup]
-    if( c == 'u' )
-      { pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
-        printf( "** Zoom In: Image x 2 \n" );
-      }
-    //![pyrup]
-    //![pyrdown]
-    else if( c == 'd' )
-      { pyrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) );
-        printf( "** Zoom Out: Image / 2 \n" );
-      }
-    //![pyrdown]
-    imshow( window_name, dst );
-
-    //![update_tmp]
-    tmp = dst;
-    //![update_tmp]
-   }
-   //![infinite_loop]
-
-   return 0;
-}
diff --git a/samples/cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp b/samples/cpp/tutorial_code/ImgProc/Pyramids/Pyramids.cpp
new file mode 100644 (file)
index 0000000..1cc7bf2
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * @file Pyramids.cpp
+ * @brief Sample code of image pyramids (pyrDown and pyrUp)
+ * @author OpenCV team
+ */
+
+#include "iostream"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/imgcodecs.hpp"
+#include "opencv2/highgui.hpp"
+
+using namespace std;
+using namespace cv;
+
+const char* window_name = "Pyramids Demo";
+
+/**
+ * @function main
+ */
+int main( int argc, char** argv )
+{
+    /// General instructions
+    cout << "\n Zoom In-Out demo \n "
+            "------------------  \n"
+            " * [i] -> Zoom in   \n"
+            " * [o] -> Zoom out  \n"
+            " * [ESC] -> Close program \n" << endl;
+
+    //![load]
+    const char* filename = argc >=2 ? argv[1] : "../data/chicky_512.png";
+
+    // Loads an image
+    Mat src = imread( filename );
+
+    // Check if image is loaded fine
+    if(src.empty()){
+        printf(" Error opening image\n");
+        printf(" Program Arguments: [image_name -- default ../data/chicky_512.png] \n");
+        return -1;
+    }
+    //![load]
+
+    //![loop]
+    for(;;)
+    {
+        //![show_image]
+        imshow( window_name, src );
+        //![show_image]
+        char c = (char)waitKey(0);
+
+        if( c == 27 )
+        { break; }
+        //![pyrup]
+        else if( c == 'i' )
+        { pyrUp( src, src, Size( src.cols*2, src.rows*2 ) );
+            printf( "** Zoom In: Image x 2 \n" );
+        }
+        //![pyrup]
+        //![pyrdown]
+        else if( c == 'o' )
+        { pyrDown( src, src, Size( src.cols/2, src.rows/2 ) );
+            printf( "** Zoom Out: Image / 2 \n" );
+        }
+        //![pyrdown]
+    }
+    //![loop]
+
+    return 0;
+}
diff --git a/samples/java/tutorial_code/ImgProc/Pyramids/Pyramids.java b/samples/java/tutorial_code/ImgProc/Pyramids/Pyramids.java
new file mode 100644 (file)
index 0000000..b4ada16
--- /dev/null
@@ -0,0 +1,67 @@
+import org.opencv.core.*;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+class PyramidsRun {
+
+    String window_name = "Pyramids Demo";
+
+    public void run(String[] args) {
+        /// General instructions
+        System.out.println("\n" +
+                " Zoom In-Out demo    \n" +
+                "------------------   \n" +
+                " * [i] -> Zoom [i]n  \n" +
+                " * [o] -> Zoom [o]ut \n" +
+                " * [ESC] -> Close program \n");
+
+        //! [load]
+        String filename = ((args.length > 0) ? args[0] : "../data/chicky_512.png");
+
+        // Load the image
+        Mat src = Imgcodecs.imread(filename);
+
+        // Check if image is loaded fine
+        if( src.empty() ) {
+            System.out.println("Error opening image!");
+            System.out.println("Program Arguments: [image_name -- default ../data/chicky_512.png] \n");
+            System.exit(-1);
+        }
+        //! [load]
+
+        //! [loop]
+        while (true){
+            //! [show_image]
+            HighGui.imshow( window_name, src );
+            //! [show_image]
+            char c = (char) HighGui.waitKey(0);
+            c = Character.toLowerCase(c);
+
+            if( c == 27 ){
+                break;
+                //![pyrup]
+            }else if( c == 'i'){
+                Imgproc.pyrUp( src, src, new Size( src.cols()*2, src.rows()*2 ) );
+                System.out.println( "** Zoom In: Image x 2" );
+                //![pyrup]
+                //![pyrdown]
+            }else if( c == 'o'){
+                Imgproc.pyrDown( src, src, new Size( src.cols()/2, src.rows()/2 ) );
+                System.out.println( "** Zoom Out: Image / 2" );
+                //![pyrdown]
+            }
+        }
+        //! [loop]
+
+        System.exit(0);
+    }
+}
+
+public class Pyramids {
+    public static void main(String[] args) {
+        // Load the native library.
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+        new PyramidsRun().run(args);
+    }
+}
diff --git a/samples/python/tutorial_code/imgProc/Pyramids/pyramids.py b/samples/python/tutorial_code/imgProc/Pyramids/pyramids.py
new file mode 100644 (file)
index 0000000..127345a
--- /dev/null
@@ -0,0 +1,51 @@
+import sys
+import cv2
+
+
+def main(argv):
+    print("""
+    Zoom In-Out demo
+    ------------------
+    * [i] -> Zoom [i]n
+    * [o] -> Zoom [o]ut
+    * [ESC] -> Close program
+    """)
+    ## [load]
+    filename = argv[0] if len(argv) > 0 else "../data/chicky_512.png"
+
+    # Load the image
+    src = cv2.imread(filename)
+
+    # Check if image is loaded fine
+    if src is None:
+        print ('Error opening image!')
+        print ('Usage: pyramids.py [image_name -- default ../data/chicky_512.png] \n')
+        return -1
+    ## [load]
+    ## [loop]
+    while 1:
+        rows, cols, _channels = map(int, src.shape)
+        ## [show_image]
+        cv2.imshow('Pyramids Demo', src)
+        ## [show_image]
+        k = cv2.waitKey(0)
+
+        if k == 27:
+            break
+            ## [pyrup]
+        elif chr(k) == 'i':
+            src = cv2.pyrUp(src, dstsize=(2 * cols, 2 * rows))
+            print ('** Zoom In: Image x 2')
+            ## [pyrup]
+            ## [pyrdown]
+        elif chr(k) == 'o':
+            src = cv2.pyrDown(src, dstsize=(cols // 2, rows // 2))
+            print ('** Zoom Out: Image / 2')
+            ## [pyrdown]
+    ## [loop]
+
+    cv2.destroyAllWindows()
+    return 0
+
+if __name__ == "__main__":
+    main(sys.argv[1:])