diff --git a/doc/tutorials/core/adding_images/adding_images.markdown b/doc/tutorials/core/adding_images/adding_images.markdown index 012a2480fa..95cc19e124 100644 --- a/doc/tutorials/core/adding_images/adding_images.markdown +++ b/doc/tutorials/core/adding_images/adding_images.markdown @@ -1,13 +1,16 @@ Adding (blending) two images using OpenCV {#tutorial_adding_images} ========================================= +@prev_tutorial{tutorial_mat_operations} +@next_tutorial{tutorial_basic_linear_transform} + Goal ---- In this tutorial you will learn: - what is *linear blending* and why it is useful; -- how to add two images using @ref cv::addWeighted +- how to add two images using **addWeighted()** Theory ------ @@ -28,33 +31,83 @@ eh?) Source Code ----------- +@add_toggle_cpp Download the source code from -[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/core/AddingImages/AddingImages.cpp). +[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/core/AddingImages/AddingImages.cpp). @include cpp/tutorial_code/core/AddingImages/AddingImages.cpp +@end_toggle + +@add_toggle_java +Download the source code from +[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/core/AddingImages/AddingImages.java). +@include java/tutorial_code/core/AddingImages/AddingImages.java +@end_toggle + +@add_toggle_python +Download the source code from +[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/core/AddingImages/adding_images.py). +@include python/tutorial_code/core/AddingImages/adding_images.py +@end_toggle Explanation ----------- --# Since we are going to perform: +Since we are going to perform: + +\f[g(x) = (1 - \alpha)f_{0}(x) + \alpha f_{1}(x)\f] + +We need two source images (\f$f_{0}(x)\f$ and \f$f_{1}(x)\f$). So, we load them in the usual way: +@add_toggle_cpp +@snippet cpp/tutorial_code/core/AddingImages/AddingImages.cpp load +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/core/AddingImages/AddingImages.java load +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/core/AddingImages/adding_images.py load +@end_toggle + +We used the following images: [LinuxLogo.jpg](https://raw.githubusercontent.com/opencv/opencv/master/samples/data/LinuxLogo.jpg) and [WindowsLogo.jpg](https://raw.githubusercontent.com/opencv/opencv/master/samples/data/WindowsLogo.jpg) + +@warning Since we are *adding* *src1* and *src2*, they both have to be of the same size +(width and height) and type. + +Now we need to generate the `g(x)` image. For this, the function **addWeighted()** comes quite handy: + +@add_toggle_cpp +@snippet cpp/tutorial_code/core/AddingImages/AddingImages.cpp blend_images +@end_toggle - \f[g(x) = (1 - \alpha)f_{0}(x) + \alpha f_{1}(x)\f] +@add_toggle_java +@snippet java/tutorial_code/core/AddingImages/AddingImages.java blend_images +@end_toggle - We need two source images (\f$f_{0}(x)\f$ and \f$f_{1}(x)\f$). So, we load them in the usual way: - @snippet cpp/tutorial_code/core/AddingImages/AddingImages.cpp load +@add_toggle_python +@snippet python/tutorial_code/core/AddingImages/adding_images.py blend_images +Numpy version of above line (but cv2 function is around 2x faster): +\code{.py} + dst = np.uint8(alpha*(img1)+beta*(img2)) +\endcode +@end_toggle - **warning** +since **addWeighted()** produces: +\f[dst = \alpha \cdot src1 + \beta \cdot src2 + \gamma\f] +In this case, `gamma` is the argument \f$0.0\f$ in the code above. - Since we are *adding* *src1* and *src2*, they both have to be of the same size (width and - height) and type. +Create windows, show the images and wait for the user to end the program. +@add_toggle_cpp +@snippet cpp/tutorial_code/core/AddingImages/AddingImages.cpp display +@end_toggle --# Now we need to generate the `g(x)` image. For this, the function @ref cv::addWeighted comes quite handy: - @snippet cpp/tutorial_code/core/AddingImages/AddingImages.cpp blend_images - since @ref cv::addWeighted produces: - \f[dst = \alpha \cdot src1 + \beta \cdot src2 + \gamma\f] - In this case, `gamma` is the argument \f$0.0\f$ in the code above. +@add_toggle_java +@snippet java/tutorial_code/core/AddingImages/AddingImages.java display +@end_toggle --# Create windows, show the images and wait for the user to end the program. - @snippet cpp/tutorial_code/core/AddingImages/AddingImages.cpp display +@add_toggle_python +@snippet python/tutorial_code/core/AddingImages/adding_images.py display +@end_toggle Result ------ diff --git a/doc/tutorials/core/table_of_content_core.markdown b/doc/tutorials/core/table_of_content_core.markdown index 2b9afb8b19..c0453dd611 100644 --- a/doc/tutorials/core/table_of_content_core.markdown +++ b/doc/tutorials/core/table_of_content_core.markdown @@ -40,6 +40,8 @@ understanding how to manipulate the images on a pixel level. - @subpage tutorial_adding_images + *Languages:* C++, Java, Python + *Compatibility:* \> OpenCV 2.0 *Author:* Ana Huamán diff --git a/samples/cpp/tutorial_code/core/AddingImages/AddingImages.cpp b/samples/cpp/tutorial_code/core/AddingImages/AddingImages.cpp index 4ddb6f0b02..1dd1d09546 100644 --- a/samples/cpp/tutorial_code/core/AddingImages/AddingImages.cpp +++ b/samples/cpp/tutorial_code/core/AddingImages/AddingImages.cpp @@ -3,7 +3,6 @@ * @brief Simple linear blender ( dst = alpha*src1 + beta*src2 ) * @author OpenCV team */ - #include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp" #include @@ -24,7 +23,7 @@ int main( void ) /// Ask the user enter alpha cout << " Simple Linear Blender " << endl; cout << "-----------------------" << endl; - cout << "* Enter alpha [0-1]: "; + cout << "* Enter alpha [0.0-1.0]: "; cin >> input; // We use the alpha provided by the user if it is between 0 and 1 diff --git a/samples/java/tutorial_code/core/AddingImages/AddingImages.java b/samples/java/tutorial_code/core/AddingImages/AddingImages.java new file mode 100644 index 0000000000..238c5eeec4 --- /dev/null +++ b/samples/java/tutorial_code/core/AddingImages/AddingImages.java @@ -0,0 +1,51 @@ +import org.opencv.core.*; +import org.opencv.highgui.HighGui; +import org.opencv.imgcodecs.Imgcodecs; + +import java.util.Locale; +import java.util.Scanner; + +class AddingImagesRun{ + public void run() { + double alpha = 0.5; double beta; double input; + + Mat src1, src2, dst = new Mat(); + + System.out.println(" Simple Linear Blender "); + System.out.println("-----------------------"); + System.out.println("* Enter alpha [0.0-1.0]: "); + Scanner scan = new Scanner( System.in ).useLocale(Locale.US); + input = scan.nextDouble(); + + if( input >= 0.0 && input <= 1.0 ) + alpha = input; + + //! [load] + src1 = Imgcodecs.imread("../../images/LinuxLogo.jpg"); + src2 = Imgcodecs.imread("../../images/WindowsLogo.jpg"); + //! [load] + + if( src1.empty() == true ){ System.out.println("Error loading src1"); return;} + if( src2.empty() == true ){ System.out.println("Error loading src2"); return;} + + //! [blend_images] + beta = ( 1.0 - alpha ); + Core.addWeighted( src1, alpha, src2, beta, 0.0, dst); + //! [blend_images] + + //![display] + HighGui.imshow("Linear Blend", dst); + HighGui.waitKey(0); + //![display] + + System.exit(0); + } +} + +public class AddingImages { + public static void main(String[] args) { + // Load the native library. + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + new AddingImagesRun().run(); + } +} diff --git a/samples/python/tutorial_code/core/AddingImages/adding_images.py b/samples/python/tutorial_code/core/AddingImages/adding_images.py new file mode 100644 index 0000000000..62abb3e4bb --- /dev/null +++ b/samples/python/tutorial_code/core/AddingImages/adding_images.py @@ -0,0 +1,35 @@ +from __future__ import print_function +import sys + +import cv2 + +alpha = 0.5 + +print(''' Simple Linear Blender +----------------------- +* Enter alpha [0.0-1.0]: ''') +if sys.version_info >= (3, 0): # If Python 3.x + input_alpha = float(input()) +else: + input_alpha = float(raw_input()) +if 0 <= alpha <= 1: + alpha = input_alpha +## [load] +src1 = cv2.imread('../../../../data/LinuxLogo.jpg') +src2 = cv2.imread('../../../../data/WindowsLogo.jpg') +## [load] +if src1 is None: + print ("Error loading src1") + exit(-1) +elif src2 is None: + print ("Error loading src2") + exit(-1) +## [blend_images] +beta = (1.0 - alpha) +dst = cv2.addWeighted(src1, alpha, src2, beta, 0.0) +## [blend_images] +## [display] +cv2.imshow('dst', dst) +cv2.waitKey(0) +## [display] +cv2.destroyAllWindows()