Tutorial Filter2D
authortribta <joaocartuchoo@gmail.com>
Thu, 24 Aug 2017 15:22:27 +0000 (16:22 +0100)
committertribta <joaocartuchoo@gmail.com>
Thu, 5 Oct 2017 11:17:38 +0000 (14:17 +0300)
doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.markdown
doc/tutorials/imgproc/table_of_content_imgproc.markdown
samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp
samples/java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java [new file with mode: 0644]
samples/python/tutorial_code/ImgTrans/Filter2D/filter2D.py [new file with mode: 0644]

index 5716410..454f745 100644 (file)
@@ -1,12 +1,15 @@
 Making your own linear filters! {#tutorial_filter_2d}
 ===============================
 
+@prev_tutorial{tutorial_threshold_inRange}
+@next_tutorial{tutorial_copyMakeBorder}
+
 Goal
 ----
 
 In this tutorial you will learn how to:
 
--   Use the OpenCV function @ref cv::filter2D to create your own linear filters.
+-   Use the OpenCV function **filter2D()** to create your own linear filters.
 
 Theory
 ------
@@ -40,61 +43,127 @@ Expressing the procedure above in the form of an equation we would have:
 
 \f[H(x,y) = \sum_{i=0}^{M_{i} - 1} \sum_{j=0}^{M_{j}-1} I(x+i - a_{i}, y + j - a_{j})K(i,j)\f]
 
-Fortunately, OpenCV provides you with the function @ref cv::filter2D so you do not have to code all
+Fortunately, OpenCV provides you with the function **filter2D()** so you do not have to code all
 these operations.
 
-Code
-----
-
--#  **What does this program do?**
-    -   Loads an image
-    -   Performs a *normalized box filter*. For instance, for a kernel of size \f$size = 3\f$, the
-        kernel would be:
+###  What does this program do?
+-   Loads an image
+-   Performs a *normalized box filter*. For instance, for a kernel of size \f$size = 3\f$, the
+    kernel would be:
 
-        \f[K = \dfrac{1}{3 \cdot 3} \begin{bmatrix}
-        1 & 1 & 1  \\
+\f[K = \dfrac{1}{3 \cdot 3} \begin{bmatrix}
+1 & 1 & 1  \\
         1 & 1 & 1  \\
         1 & 1 & 1
-        \end{bmatrix}\f]
+\end{bmatrix}\f]
+
+The program will perform the filter operation with kernels of sizes 3, 5, 7, 9 and 11.
 
-        The program will perform the filter operation with kernels of sizes 3, 5, 7, 9 and 11.
+-   The filter output (with each kernel) will be shown during 500 milliseconds
 
-    -   The filter output (with each kernel) will be shown during 500 milliseconds
+Code
+----
 
--#  The 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/ImgTrans/filter2D_demo.cpp)
-    @include cpp/tutorial_code/ImgTrans/filter2D_demo.cpp
+The tutorial code's is shown in the lines below.
+
+@add_toggle_cpp
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp)
+@include cpp/tutorial_code/ImgTrans/filter2D_demo.cpp
+@end_toggle
+
+@add_toggle_java
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java)
+@include java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java
+@end_toggle
+
+@add_toggle_python
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/ImgTrans/Filter2D/filter2D.py)
+@include python/tutorial_code/ImgTrans/Filter2D/filter2D.py
+@end_toggle
 
 Explanation
 -----------
 
--#  Load an image
-    @snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp load
--#  Initialize the arguments for the linear filter
-    @snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp init_arguments
--#  Perform an infinite loop updating the kernel size and applying our linear filter to the input
-    image. Let's analyze that more in detail:
--#  First we define the kernel our filter is going to use. Here it is:
-    @snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp update_kernel
-    The first line is to update the *kernel_size* to odd values in the range: \f$[3,11]\f$. The second
-    line actually builds the kernel by setting its value to a matrix filled with \f$1's\f$ and
-    normalizing it by dividing it between the number of elements.
-
--#  After setting the kernel, we can generate the filter by using the function @ref cv::filter2D :
-    @snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp apply_filter
-    The arguments denote:
-
-    -#  *src*: Source image
-    -#  *dst*: Destination image
-    -#  *ddepth*: The depth of *dst*. A negative value (such as \f$-1\f$) indicates that the depth is
+####  Load an image
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp load
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java load
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/Filter2D/filter2D.py load
+@end_toggle
+
+####  Initialize the arguments
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp init_arguments
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java init_arguments
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/Filter2D/filter2D.py init_arguments
+@end_toggle
+
+##### Loop
+
+Perform an infinite loop updating the kernel size and applying our linear filter to the input
+image. Let's analyze that more in detail:
+
+-  First we define the kernel our filter is going to use. Here it is:
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp update_kernel
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java update_kernel
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/Filter2D/filter2D.py update_kernel
+@end_toggle
+
+The first line is to update the *kernel_size* to odd values in the range: \f$[3,11]\f$.
+The second line actually builds the kernel by setting its value to a matrix filled with
+\f$1's\f$ and normalizing it by dividing it between the number of elements.
+
+-  After setting the kernel, we can generate the filter by using the function **filter2D()** :
+
+@add_toggle_cpp
+@snippet cpp/tutorial_code/ImgTrans/filter2D_demo.cpp apply_filter
+@end_toggle
+
+@add_toggle_java
+@snippet java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java apply_filter
+@end_toggle
+
+@add_toggle_python
+@snippet python/tutorial_code/ImgTrans/Filter2D/filter2D.py apply_filter
+@end_toggle
+
+-  The arguments denote:
+       -  *src*: Source image
+       -  *dst*: Destination image
+       -  *ddepth*: The depth of *dst*. A negative value (such as \f$-1\f$) indicates that the depth is
         the same as the source.
-    -#  *kernel*: The kernel to be scanned through the image
-    -#  *anchor*: The position of the anchor relative to its kernel. The location *Point(-1, -1)*
-        indicates the center by default.
-    -#  *delta*: A value to be added to each pixel during the correlation. By default it is \f$0\f$
-    -#  *BORDER_DEFAULT*: We let this value by default (more details in the following tutorial)
+       -  *kernel*: The kernel to be scanned through the image
+       -  *anchor*: The position of the anchor relative to its kernel. The location *Point(-1, -1)*
+       indicates the center by default.
+       -  *delta*: A value to be added to each pixel during the correlation. By default it is \f$0\f$
+       -  *BORDER_DEFAULT*: We let this value by default (more details in the following tutorial)
 
--#  Our program will effectuate a *while* loop, each 500 ms the kernel size of our filter will be
+-  Our program will effectuate a *while* loop, each 500 ms the kernel size of our filter will be
     updated in the range indicated.
 
 Results
@@ -104,4 +173,4 @@ Results
     result should be a window that shows an image blurred by a normalized filter. Each 0.5 seconds
     the kernel size should change, as can be seen in the series of snapshots below:
 
-    ![](images/filter_2d_tutorial_result.jpg)
+![](images/filter_2d_tutorial_result.jpg)
index d255023..5dd3d57 100644 (file)
@@ -77,6 +77,8 @@ In this section you will learn about the image processing (manipulation) functio
 
 -   @subpage tutorial_filter_2d
 
+    *Languages:* C++, Java, Python
+
     *Compatibility:* \> OpenCV 2.0
 
     *Author:* Ana Huamán
index 24aef46..3b7f3a9 100644 (file)
@@ -15,56 +15,60 @@ using namespace cv;
  */
 int main ( int argc, char** argv )
 {
-  /// Declare variables
-  Mat src, dst;
+    // Declare variables
+    Mat src, dst;
 
-  Mat kernel;
-  Point anchor;
-  double delta;
-  int ddepth;
-  int kernel_size;
-  const char* window_name = "filter2D Demo";
+    Mat kernel;
+    Point anchor;
+    double delta;
+    int ddepth;
+    int kernel_size;
+    const char* window_name = "filter2D Demo";
 
-  //![load]
-  String imageName("../data/lena.jpg"); // by default
-  if (argc > 1)
-  {
-    imageName = argv[1];
-  }
-  src = imread( imageName, IMREAD_COLOR ); // Load an image
+    //![load]
+    const char* imageName = argc >=2 ? argv[1] : "../data/lena.jpg";
 
-  if( src.empty() )
-    { return -1; }
-  //![load]
+    // Loads an image
+    src = imread( imageName, IMREAD_COLOR ); // Load an image
 
-  //![init_arguments]
-  /// Initialize arguments for the filter
-  anchor = Point( -1, -1 );
-  delta = 0;
-  ddepth = -1;
-  //![init_arguments]
+    if( src.empty() )
+    {
+        printf(" Error opening image\n");
+        printf(" Program Arguments: [image_name -- default ../data/lena.jpg] \n");
+        return -1;
+    }
+    //![load]
 
-  /// Loop - Will filter the image with different kernel sizes each 0.5 seconds
-  int ind = 0;
-  for(;;)
-       {
-         char c = (char)waitKey(500);
-         /// Press 'ESC' to exit the program
-         if( c == 27 )
-           { break; }
+    //![init_arguments]
+    // Initialize arguments for the filter
+    anchor = Point( -1, -1 );
+    delta = 0;
+    ddepth = -1;
+    //![init_arguments]
 
-         //![update_kernel]
-         /// Update kernel size for a normalized box filter
-         kernel_size = 3 + 2*( ind%5 );
-         kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
-         //![update_kernel]
+    // Loop - Will filter the image with different kernel sizes each 0.5 seconds
+    int ind = 0;
+    for(;;)
+    {
+        //![update_kernel]
+        // Update kernel size for a normalized box filter
+        kernel_size = 3 + 2*( ind%5 );
+        kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);
+        //![update_kernel]
 
-         //![apply_filter]
-         filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
-         //![apply_filter]
-         imshow( window_name, dst );
-         ind++;
-       }
+        //![apply_filter]
+        // Apply filter
+        filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
+        //![apply_filter]
+        imshow( window_name, dst );
 
-  return 0;
+        char c = (char)waitKey(500);
+        // Press 'ESC' to exit the program
+        if( c == 27 )
+        { break; }
+
+        ind++;
+    }
+
+    return 0;
 }
diff --git a/samples/java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java b/samples/java/tutorial_code/ImgTrans/Filter2D/Filter2D_Demo.java
new file mode 100644 (file)
index 0000000..aa685d9
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * @file Filter2D_demo.java
+ * @brief Sample code that shows how to implement your own linear filters by using filter2D function
+ */
+
+import org.opencv.core.*;
+import org.opencv.core.Point;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgcodecs.Imgcodecs;
+import org.opencv.imgproc.Imgproc;
+
+class Filter2D_DemoRun {
+
+    public void run(String[] args) {
+        // Declare variables
+        Mat src, dst = new Mat();
+
+        Mat kernel = new Mat();
+        Point anchor;
+        double delta;
+        int ddepth;
+        int kernel_size;
+        String window_name = "filter2D Demo";
+
+        //! [load]
+        String imageName = ((args.length > 0) ? args[0] : "../data/lena.jpg");
+
+        // Load an image
+        src = Imgcodecs.imread(imageName, Imgcodecs.IMREAD_COLOR);
+
+        // Check if image is loaded fine
+        if( src.empty() ) {
+            System.out.println("Error opening image!");
+            System.out.println("Program Arguments: [image_name -- default ../data/lena.jpg] \n");
+            System.exit(-1);
+        }
+        //! [load]
+
+        //! [init_arguments]
+        // Initialize arguments for the filter
+        anchor = new Point( -1, -1);
+        delta = 0.0;
+        ddepth = -1;
+        //! [init_arguments]
+
+        // Loop - Will filter the image with different kernel sizes each 0.5 seconds
+        int ind = 0;
+        while( true )
+        {
+            //! [update_kernel]
+            // Update kernel size for a normalized box filter
+            kernel_size = 3 + 2*( ind%5 );
+            Mat ones = Mat.ones( kernel_size, kernel_size, CvType.CV_32F );
+            Core.multiply(ones, new Scalar(1/(double)(kernel_size*kernel_size)), kernel);
+            //! [update_kernel]
+
+            //! [apply_filter]
+            // Apply filter
+            Imgproc.filter2D(src, dst, ddepth , kernel, anchor, delta, Core.BORDER_DEFAULT );
+            //! [apply_filter]
+            HighGui.imshow( window_name, dst );
+
+            int c = HighGui.waitKey(500);
+            // Press 'ESC' to exit the program
+            if( c == 27 )
+            { break; }
+
+            ind++;
+        }
+
+        System.exit(0);
+    }
+}
+
+public class Filter2D_Demo {
+    public static void main(String[] args) {
+        // Load the native library.
+        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+        new Filter2D_DemoRun().run(args);
+    }
+}
diff --git a/samples/python/tutorial_code/ImgTrans/Filter2D/filter2D.py b/samples/python/tutorial_code/ImgTrans/Filter2D/filter2D.py
new file mode 100644 (file)
index 0000000..e4d1afe
--- /dev/null
@@ -0,0 +1,54 @@
+"""
+@file filter2D.py
+@brief Sample code that shows how to implement your own linear filters by using filter2D function
+"""
+import sys
+import cv2
+import numpy as np
+
+
+def main(argv):
+    window_name = 'filter2D Demo'
+
+    ## [load]
+    imageName = argv[0] if len(argv) > 0 else "../data/lena.jpg"
+
+    # Loads an image
+    src = cv2.imread(imageName, cv2.IMREAD_COLOR)
+
+    # Check if image is loaded fine
+    if src is None:
+        print ('Error opening image!')
+        print ('Usage: filter2D.py [image_name -- default ../data/lena.jpg] \n')
+        return -1
+    ## [load]
+    ## [init_arguments]
+    # Initialize ddepth argument for the filter
+    ddepth = -1
+    ## [init_arguments]
+    # Loop - Will filter the image with different kernel sizes each 0.5 seconds
+    ind = 0
+    while True:
+        ## [update_kernel]
+        # Update kernel size for a normalized box filter
+        kernel_size = 3 + 2 * (ind % 5)
+        kernel = np.ones((kernel_size, kernel_size), dtype=np.float32)
+        kernel /= (kernel_size * kernel_size)
+        ## [update_kernel]
+        ## [apply_filter]
+        # Apply filter
+        dst = cv2.filter2D(src, ddepth, kernel)
+        ## [apply_filter]
+        cv2.imshow(window_name, dst)
+
+        c = cv2.waitKey(500)
+        if c == 27:
+            break
+
+        ind += 1
+
+    return 0
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])