diff --git a/doc/tutorials/highgui/table_of_content_highgui.markdown b/doc/tutorials/highgui/table_of_content_highgui.markdown index a8f1d4e3441743d7c10198c04cf56ae07b6b178f..fb5a3436644577387eb32634c78e7493d3c93f26 100644 --- a/doc/tutorials/highgui/table_of_content_highgui.markdown +++ b/doc/tutorials/highgui/table_of_content_highgui.markdown @@ -5,6 +5,8 @@ This section contains tutorials about how to use the built-in graphical user int - @subpage tutorial_trackbar + *Languages:* C++, Java, Python + *Compatibility:* \> OpenCV 2.0 *Author:* Ana Huamán diff --git a/doc/tutorials/highgui/trackbar/trackbar.markdown b/doc/tutorials/highgui/trackbar/trackbar.markdown index 13898712ab8d0c027774a2a06ee0fc119dbb147c..d6700d63871d6312e2b3982935b4ddccbb86a8d8 100644 --- a/doc/tutorials/highgui/trackbar/trackbar.markdown +++ b/doc/tutorials/highgui/trackbar/trackbar.markdown @@ -1,11 +1,11 @@ Adding a Trackbar to our applications! {#tutorial_trackbar} ====================================== -- In the previous tutorials (about *linear blending* and the *brightness and contrast - adjustments*) you might have noted that we needed to give some **input** to our programs, such - as \f$\alpha\f$ and \f$beta\f$. We accomplished that by entering this data using the Terminal -- Well, it is time to use some fancy GUI tools. OpenCV provides some GUI utilities (*highgui.hpp*) - for you. An example of this is a **Trackbar** +- In the previous tutorials (about @ref tutorial_adding_images and the @ref tutorial_basic_linear_transform) + you might have noted that we needed to give some **input** to our programs, such + as \f$\alpha\f$ and \f$beta\f$. We accomplished that by entering this data using the Terminal. +- Well, it is time to use some fancy GUI tools. OpenCV provides some GUI utilities (**highgui** module) + for you. An example of this is a **Trackbar**. ![](images/Adding_Trackbars_Tutorial_Trackbar.png) @@ -24,26 +24,73 @@ Code Let's modify the program made in the tutorial @ref tutorial_adding_images. We will let the user enter the \f$\alpha\f$ value by using the Trackbar. + +@add_toggle_cpp 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/HighGUI/AddingImagesTrackbar.cpp) @include cpp/tutorial_code/HighGUI/AddingImagesTrackbar.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/master/samples/java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java) +@include java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.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/master/samples/python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py) +@include python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py +@end_toggle Explanation ----------- We only analyze the code that is related to Trackbar: --# First, we load two images, which are going to be blended. - @snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp load +- First, we load two images, which are going to be blended. + +@add_toggle_cpp +@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp load +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java load +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py load +@end_toggle --# To create a trackbar, first we have to create the window in which it is going to be located. So: - @snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp window +- To create a trackbar, first we have to create the window in which it is going to be located. So: --# Now we can create the Trackbar: - @snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp create_trackbar +@add_toggle_cpp +@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp window +@end_toggle - Note the following: +@add_toggle_java +@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java window +@end_toggle +@add_toggle_python +@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py window +@end_toggle + +- Now we can create the Trackbar: + +@add_toggle_cpp +@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp create_trackbar +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java create_trackbar +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py create_trackbar +@end_toggle + +Note the following (C++ code): - Our Trackbar has a label **TrackbarName** - The Trackbar is located in the window named **Linear Blend** - The Trackbar values will be in the range from \f$0\f$ to **alpha_slider_max** (the minimum @@ -51,10 +98,21 @@ We only analyze the code that is related to Trackbar: - The numerical value of Trackbar is stored in **alpha_slider** - Whenever the user moves the Trackbar, the callback function **on_trackbar** is called --# Finally, we have to define the callback function **on_trackbar** - @snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp on_trackbar +Finally, we have to define the callback function **on_trackbar** for C++ and Python code, using an anonymous inner class listener in Java + +@add_toggle_cpp +@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp on_trackbar +@end_toggle + +@add_toggle_java +@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java on_trackbar +@end_toggle + +@add_toggle_python +@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py on_trackbar +@end_toggle - Note that: +Note that (C++ code): - We use the value of **alpha_slider** (integer) to get a double value for **alpha**. - **alpha_slider** is updated each time the trackbar is displaced by the user. - We define *src1*, *src2*, *dist*, *alpha*, *alpha_slider* and *beta* as global variables, diff --git a/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp b/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp index 51522fa5ca1e8a7e0860a70e9704f0d5d3a6dd61..dce34e7eb445aaed00d3a2a5d408b11a2bcf5982 100644 --- a/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp +++ b/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp @@ -6,9 +6,10 @@ #include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp" -#include +#include using namespace cv; +using std::cout; /** Global Variables */ const int alpha_slider_max = 100; @@ -29,11 +30,8 @@ Mat dst; static void on_trackbar( int, void* ) { alpha = (double) alpha_slider/alpha_slider_max ; - beta = ( 1.0 - alpha ); - addWeighted( src1, alpha, src2, beta, 0.0, dst); - imshow( "Linear Blend", dst ); } //![on_trackbar] @@ -50,8 +48,8 @@ int main( void ) src2 = imread("../data/WindowsLogo.jpg"); //![load] - if( src1.empty() ) { printf("Error loading src1 \n"); return -1; } - if( src2.empty() ) { printf("Error loading src2 \n"); return -1; } + if( src1.empty() ) { cout << "Error loading src1 \n"; return -1; } + if( src2.empty() ) { cout << "Error loading src2 \n"; return -1; } /// Initialize values alpha_slider = 0; diff --git a/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java b/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java index 386f94a5530baf17309b2b9389ac73229dd3d09f..8a5288498471c947b0a0838ee6a96a05b4a1786e 100644 --- a/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java +++ b/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java @@ -25,7 +25,7 @@ import org.opencv.imgproc.Imgproc; public class MorphologyDemo1 { private static final String[] ELEMENT_TYPE = { "Rectangle", "Cross", "Ellipse" }; private static final String[] MORPH_OP = { "Erosion", "Dilatation" }; - private static int maxKernelSize = 21; + private static final int MAX_KERNEL_SIZE = 21; private Mat matImgSrc; private Mat matImgDst = new Mat(); private int elementType = Imgproc.CV_SHAPE_RECT; @@ -83,7 +83,11 @@ public class MorphologyDemo1 { sliderPanel.add(elementTypeBox); sliderPanel.add(new JLabel("Kernel size: 2n + 1")); - JSlider slider = new JSlider(0, maxKernelSize, 0); + JSlider slider = new JSlider(0, MAX_KERNEL_SIZE, 0); + slider.setMajorTickSpacing(5); + slider.setMinorTickSpacing(5); + slider.setPaintTicks(true); + slider.setPaintLabels(true); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { diff --git a/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java b/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java index e5d80280a9c38d2182394b6f4c9d3978d3cc4458..07d2f6e44d22d44bd4eefba4b41bc5fbc579c82b 100644 --- a/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java +++ b/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java @@ -27,7 +27,7 @@ public class MorphologyDemo2 { private static final int[] MORPH_OP_TYPE = { Imgproc.MORPH_OPEN, Imgproc.MORPH_CLOSE, Imgproc.MORPH_GRADIENT, Imgproc.MORPH_TOPHAT, Imgproc.MORPH_BLACKHAT }; private static final String[] ELEMENT_TYPE = { "Rectangle", "Cross", "Ellipse" }; - private static int maxKernelSize = 21; + private static final int MAX_KERNEL_SIZE = 21; private Mat matImgSrc; private Mat matImgDst = new Mat(); private int morphOpType = Imgproc.MORPH_OPEN; @@ -97,7 +97,11 @@ public class MorphologyDemo2 { sliderPanel.add(elementTypeBox); sliderPanel.add(new JLabel("Kernel size: 2n + 1")); - JSlider slider = new JSlider(0, maxKernelSize, 0); + JSlider slider = new JSlider(0, MAX_KERNEL_SIZE, 0); + slider.setMajorTickSpacing(5); + slider.setMinorTickSpacing(5); + slider.setPaintTicks(true); + slider.setPaintLabels(true); slider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { diff --git a/samples/java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java b/samples/java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java new file mode 100644 index 0000000000000000000000000000000000000000..5eda2198dad6e6664c372e5d5ba6a89fadad77a3 --- /dev/null +++ b/samples/java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java @@ -0,0 +1,119 @@ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Image; + +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.Mat; +import org.opencv.highgui.HighGui; +import org.opencv.imgcodecs.Imgcodecs; + +public class AddingImagesTrackbar { + private static final int ALPHA_SLIDER_MAX = 100; + private int alphaVal = 0; + private Mat matImgSrc1; + private Mat matImgSrc2; + private Mat matImgDst = new Mat(); + private JFrame frame; + private JLabel imgLabel; + + public AddingImagesTrackbar(String[] args) { + //! [load] + String imagePath1 = "../data/LinuxLogo.jpg"; + String imagePath2 = "../data/WindowsLogo.jpg"; + if (args.length > 1) { + imagePath1 = args[0]; + imagePath2 = args[1]; + } + matImgSrc1 = Imgcodecs.imread(imagePath1); + matImgSrc2 = Imgcodecs.imread(imagePath2); + //! [load] + if (matImgSrc1.empty()) { + System.out.println("Empty image: " + imagePath1); + System.exit(0); + } + if (matImgSrc2.empty()) { + System.out.println("Empty image: " + imagePath2); + System.exit(0); + } + + //! [window] + // Create and set up the window. + frame = new JFrame("Linear Blend"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + // Set up the content pane. + Image img = HighGui.toBufferedImage(matImgSrc2); + 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); + //! [window] + } + + 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)); + + //! [create_trackbar] + sliderPanel.add(new JLabel(String.format("Alpha x %d", ALPHA_SLIDER_MAX))); + JSlider slider = new JSlider(0, ALPHA_SLIDER_MAX, 0); + slider.setMajorTickSpacing(20); + slider.setMinorTickSpacing(5); + slider.setPaintTicks(true); + slider.setPaintLabels(true); + //! [create_trackbar] + //! [on_trackbar] + slider.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + JSlider source = (JSlider) e.getSource(); + alphaVal = source.getValue(); + update(); + } + }); + //! [on_trackbar] + sliderPanel.add(slider); + + pane.add(sliderPanel, BorderLayout.PAGE_START); + imgLabel = new JLabel(new ImageIcon(img)); + pane.add(imgLabel, BorderLayout.CENTER); + } + + private void update() { + double alpha = alphaVal / (double) ALPHA_SLIDER_MAX; + double beta = 1.0 - alpha; + Core.addWeighted(matImgSrc1, alpha, matImgSrc2, beta, 0, matImgDst); + Image img = HighGui.toBufferedImage(matImgDst); + imgLabel.setIcon(new ImageIcon(img)); + frame.repaint(); + } + + 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 AddingImagesTrackbar(args); + } + }); + } +} diff --git a/samples/python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py b/samples/python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py new file mode 100644 index 0000000000000000000000000000000000000000..2ccc978a8ebc63e737bc4ec5044c6c0abdb31999 --- /dev/null +++ b/samples/python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py @@ -0,0 +1,48 @@ +from __future__ import print_function +from __future__ import division +import cv2 as cv +import argparse + +alpha_slider_max = 100 +title_window = 'Linear Blend' + +## [on_trackbar] +def on_trackbar(val): + alpha = val / alpha_slider_max + beta = ( 1.0 - alpha ) + dst = cv.addWeighted(src1, alpha, src2, beta, 0.0) + cv.imshow(title_window, dst) +## [on_trackbar] + +parser = argparse.ArgumentParser(description='Code for Adding a Trackbar to our applications tutorial.') +parser.add_argument('--input1', help='Path to the first input image.', default='../data/LinuxLogo.jpg') +parser.add_argument('--input2', help='Path to the second input image.', default='../data/WindowsLogo.jpg') +args = parser.parse_args() + +## [load] +# Read images ( both have to be of the same size and type ) +src1 = cv.imread(args.input1) +src2 = cv.imread(args.input2) +## [load] +if src1 is None: + print('Could not open or find the image: ', args.input1) + exit(0) + +if src2 is None: + print('Could not open or find the image: ', args.input2) + exit(0) + +## [window] +cv.namedWindow(title_window) +## [window] + +## [create_trackbar] +trackbar_name = 'Alpha x %d' % alpha_slider_max +cv.createTrackbar(trackbar_name, title_window , 0, alpha_slider_max, on_trackbar) +## [create_trackbar] + +# Show some stuff +on_trackbar(0) + +# Wait until user press some key +cv.waitKey()