From 3250f11f0cdafa282f3d9ee29cad329a2b21f6c5 Mon Sep 17 00:00:00 2001 From: tribta Date: Tue, 22 Aug 2017 00:17:09 +0100 Subject: [PATCH] Tutorial Laplace Operator --- .../laplace_operator.markdown | 135 +++++++++++++++--- .../imgproc/table_of_content_imgproc.markdown | 2 + .../tutorial_code/ImgTrans/Laplace_Demo.cpp | 79 +++++----- .../ImgTrans/LaPlace/LaplaceDemo.java | 73 ++++++++++ .../ImgTrans/LaPlace/laplace_demo.py | 59 ++++++++ 5 files changed, 292 insertions(+), 56 deletions(-) create mode 100644 samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java create mode 100644 samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py diff --git a/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown b/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown index f1781706cb..63aed356b2 100644 --- a/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown +++ b/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.markdown @@ -1,12 +1,15 @@ Laplace Operator {#tutorial_laplace_operator} ================ +@prev_tutorial{tutorial_sobel_derivatives} +@next_tutorial{tutorial_canny_detector} + Goal ---- In this tutorial you will learn how to: -- Use the OpenCV function @ref cv::Laplacian to implement a discrete analog of the *Laplacian +- Use the OpenCV function **Laplacian()** to implement a discrete analog of the *Laplacian operator*. Theory @@ -37,7 +40,7 @@ Theory \f[Laplace(f) = \dfrac{\partial^{2} f}{\partial x^{2}} + \dfrac{\partial^{2} f}{\partial y^{2}}\f] --# The Laplacian operator is implemented in OpenCV by the function @ref cv::Laplacian . In fact, +-# The Laplacian operator is implemented in OpenCV by the function **Laplacian()** . In fact, since the Laplacian uses the gradient of images, it calls internally the *Sobel* operator to perform its computation. @@ -50,25 +53,98 @@ Code - Applies a Laplacian operator to the grayscale image and stores the output image - Display the result in a window +@add_toggle_cpp -# 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/Laplace_Demo.cpp) + [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp) @include samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp +@end_toggle + +@add_toggle_java +-# The tutorial code's is shown lines below. You can also download it from + [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java) + @include samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java +@end_toggle + +@add_toggle_python +-# The tutorial code's is shown lines below. You can also download it from + [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py) + @include samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py +@end_toggle Explanation ----------- --# Create some needed variables: - @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp variables --# Loads the source image: - @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp load --# Apply a Gaussian blur to reduce noise: - @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp reduce_noise --# Convert the image to grayscale using @ref cv::cvtColor - @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp convert_to_gray --# Apply the Laplacian operator to the grayscale image: - @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp laplacian - where the arguments are: +#### Declare variables + +@add_toggle_cpp +@snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp variables +@end_toggle + +@add_toggle_java +@snippet samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java variables +@end_toggle + +@add_toggle_python +@snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py variables +@end_toggle + +#### Load source image + +@add_toggle_cpp +@snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp load +@end_toggle + +@add_toggle_java +@snippet samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java load +@end_toggle + +@add_toggle_python +@snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py load +@end_toggle + +#### Reduce noise + +@add_toggle_cpp +@snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp reduce_noise +@end_toggle + +@add_toggle_java +@snippet samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java reduce_noise +@end_toggle + +@add_toggle_python +@snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py reduce_noise +@end_toggle +#### Grayscale + +@add_toggle_cpp +@snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp convert_to_gray +@end_toggle + +@add_toggle_java +@snippet samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java convert_to_gray +@end_toggle + +@add_toggle_python +@snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py convert_to_gray +@end_toggle + +#### Laplacian operator + +@add_toggle_cpp +@snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp laplacian +@end_toggle + +@add_toggle_java +@snippet samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java laplacian +@end_toggle + +@add_toggle_python +@snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py laplacian +@end_toggle + +- The arguments are: - *src_gray*: The input image. - *dst*: Destination (output) image - *ddepth*: Depth of the destination image. Since our input is *CV_8U* we define *ddepth* = @@ -77,10 +153,33 @@ Explanation this example. - *scale*, *delta* and *BORDER_DEFAULT*: We leave them as default values. --# Convert the output from the Laplacian operator to a *CV_8U* image: - @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp convert --# Display the result in a window: - @snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp display +#### Convert output to a *CV_8U* image + +@add_toggle_cpp +@snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp convert +@end_toggle + +@add_toggle_java +@snippet samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java convert +@end_toggle + +@add_toggle_python +@snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py convert +@end_toggle + +#### Display the result + +@add_toggle_cpp +@snippet cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp display +@end_toggle + +@add_toggle_java +@snippet samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java display +@end_toggle + +@add_toggle_python +@snippet samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py display +@end_toggle Results ------- diff --git a/doc/tutorials/imgproc/table_of_content_imgproc.markdown b/doc/tutorials/imgproc/table_of_content_imgproc.markdown index b83d0a63e3..5ee75f3118 100644 --- a/doc/tutorials/imgproc/table_of_content_imgproc.markdown +++ b/doc/tutorials/imgproc/table_of_content_imgproc.markdown @@ -99,6 +99,8 @@ In this section you will learn about the image processing (manipulation) functio - @subpage tutorial_laplace_operator + *Languages:* C++, Java, Python + *Compatibility:* \> OpenCV 2.0 *Author:* Ana Huamán diff --git a/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp index 0f56c49df7..80b6e84344 100644 --- a/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp @@ -15,50 +15,53 @@ using namespace cv; */ int main( int argc, char** argv ) { - //![variables] - Mat src, src_gray, dst; - int kernel_size = 3; - int scale = 1; - int delta = 0; - int ddepth = CV_16S; - const char* window_name = "Laplace Demo"; - //![variables] + //![variables] + // Declare the variables we are going to use + Mat src, src_gray, dst; + int kernel_size = 3; + int scale = 1; + int delta = 0; + int ddepth = CV_16S; + const char* window_name = "Laplace Demo"; + //![variables] - //![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] + src = imread( imageName, IMREAD_COLOR ); // Load an image - //![reduce_noise] - /// Reduce noise by blurring with a Gaussian filter - GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT ); - //![reduce_noise] + // Check if image is loaded fine + if(src.empty()){ + printf(" Error opening image\n"); + printf(" Program Arguments: [image_name -- default ../data/lena.jpg] \n"); + return -1; + } + //![load] - //![convert_to_gray] - cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to grayscale - //![convert_to_gray] + //![reduce_noise] + // Reduce noise by blurring with a Gaussian filter ( kernel size = 3 ) + GaussianBlur( src, src, Size(3, 3), 0, 0, BORDER_DEFAULT ); + //![reduce_noise] - /// Apply Laplace function - Mat abs_dst; - //![laplacian] - Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT ); - //![laplacian] + //![convert_to_gray] + cvtColor( src, src_gray, COLOR_BGR2GRAY ); // Convert the image to grayscale + //![convert_to_gray] - //![convert] - convertScaleAbs( dst, abs_dst ); - //![convert] + /// Apply Laplace function + Mat abs_dst; + //![laplacian] + Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT ); + //![laplacian] - //![display] - imshow( window_name, abs_dst ); - waitKey(0); - //![display] + //![convert] + // converting back to CV_8U + convertScaleAbs( dst, abs_dst ); + //![convert] - return 0; + //![display] + imshow( window_name, abs_dst ); + waitKey(0); + //![display] + + return 0; } diff --git a/samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java b/samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java new file mode 100644 index 0000000000..d9dba705fe --- /dev/null +++ b/samples/java/tutorial_code/ImgTrans/LaPlace/LaplaceDemo.java @@ -0,0 +1,73 @@ +/** + * @file LaplaceDemo.java + * @brief Sample code showing how to detect edges using the Laplace operator + */ + +import org.opencv.core.*; +import org.opencv.highgui.HighGui; +import org.opencv.imgcodecs.Imgcodecs; +import org.opencv.imgproc.Imgproc; + +class LaplaceDemoRun { + + public void run(String[] args) { + //! [variables] + // Declare the variables we are going to use + Mat src, src_gray = new Mat(), dst = new Mat(); + int kernel_size = 3; + int scale = 1; + int delta = 0; + int ddepth = CvType.CV_16S; + String window_name = "Laplace Demo"; + //! [variables] + + //! [load] + String imageName = ((args.length > 0) ? args[0] : "../data/lena.jpg"); + + src = Imgcodecs.imread(imageName, Imgcodecs.IMREAD_COLOR); // Load an image + + // 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] + + //! [reduce_noise] + // Reduce noise by blurring with a Gaussian filter ( kernel size = 3 ) + Imgproc.GaussianBlur( src, src, new Size(3, 3), 0, 0, Core.BORDER_DEFAULT ); + //! [reduce_noise] + + //! [convert_to_gray] + // Convert the image to grayscale + Imgproc.cvtColor( src, src_gray, Imgproc.COLOR_RGB2GRAY ); + //! [convert_to_gray] + + /// Apply Laplace function + Mat abs_dst = new Mat(); + //! [laplacian] + Imgproc.Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, Core.BORDER_DEFAULT ); + //! [laplacian] + + //! [convert] + // converting back to CV_8U + Core.convertScaleAbs( dst, abs_dst ); + //! [convert] + + //! [display] + HighGui.imshow( window_name, abs_dst ); + HighGui.waitKey(0); + //! [display] + + System.exit(0); + } +} + +public class LaplaceDemo { + public static void main(String[] args) { + // Load the native library. + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + new LaplaceDemoRun().run(args); + } +} diff --git a/samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py b/samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py new file mode 100644 index 0000000000..5776e445fc --- /dev/null +++ b/samples/python/tutorial_code/ImgTrans/LaPlace/laplace_demo.py @@ -0,0 +1,59 @@ +""" +@file laplace_demo.py +@brief Sample code showing how to detect edges using the Laplace operator +""" +import sys +import cv2 + +def main(argv): + # [variables] + # Declare the variables we are going to use + ddepth = cv2.CV_16S + kernel_size = 3 + window_name = "Laplace Demo" + # [variables] + + # [load] + imageName = argv[0] if len(argv) > 0 else "../data/lena.jpg" + + src = cv2.imread(imageName, cv2.IMREAD_COLOR) # Load an image + + # Check if image is loaded fine + if src is None: + print ('Error opening image') + print ('Program Arguments: [image_name -- default ../data/lena.jpg]') + return -1 + # [load] + + # [reduce_noise] + # Remove noise by blurring with a Gaussian filter + src = cv2.GaussianBlur(src, (3, 3), 0) + # [reduce_noise] + + # [convert_to_gray] + # Convert the image to grayscale + src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) + # [convert_to_gray] + + # Create Window + cv2.namedWindow(window_name, cv2.WINDOW_AUTOSIZE) + + # [laplacian] + # Apply Laplace function + dst = cv2.Laplacian(src_gray, ddepth, kernel_size) + # [laplacian] + + # [convert] + # converting back to uint8 + abs_dst = cv2.convertScaleAbs(dst) + # [convert] + + # [display] + cv2.imshow(window_name, abs_dst) + cv2.waitKey(0) + # [display] + + return 0 + +if __name__ == "__main__": + main(sys.argv[1:])