Next tutorial: Reading geospatial raster files using GDAL
Original author | Ana Huamán |
---|---|
Compatibility | OpenCV >= 3.0 |
- In the previous tutorial (about Adding (blending) two images andchanging the contrast and brightness of the images using OpenCV! ), you may have noticed that we need to The program provides some inputs such as alpha and beta. We entered this data via a terminal.
- Now, it’s time to use some fancy GUI tools. OpenCV provides some graphical user interface tools (highgui module). Trackbar is one example.
- In this tutorial, we’ll modify two of our previous programs to take input from the track bar.
Goals
In this tutorial you will learn how to
- Use cv::createTrackbar to add a trackbar to the OpenCV window
Code
Let’s modify the program from the tutorial to add (blend) two images using OpenCV. We’ll let the user enter the alpha value using the Trackbar.
C++
The code for this tutorial is shown below. You can also download it from here
#include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp" #include <iostream> using namespace cv; using std::cout; const int alpha_slider_max = 100; int alpha_slider; double alpha; double beta; Mat src1; Mat src2; 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 ); } int main(void) {<!-- --> src1 = imread( samples::findFile("LinuxLogo.jpg") ); src2 = imread( samples::findFile("WindowsLogo.jpg") ); if( src1.empty() ) {<!-- --> cout << "Error loading src1 \ "; return -1; } if( src2.empty() ) {<!-- --> cout << "Error loading src2 \ "; return -1; } alpha_slider = 0; namedWindow("Linear Blend", WINDOW_AUTOSIZE); // Create Window char TrackbarName[50]; snprintf( TrackbarName, sizeof(TrackbarName), "Alpha x %d", alpha_slider_max ); createTrackbar( TrackbarName, "Linear Blend", & amp;alpha_slider, alpha_slider_max, on_trackbar ); on_trackbar( alpha_slider, 0 ); waitKey(0); return 0; }
Java
The code for this tutorial is shown below. You can also download it from here
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) {<!-- --> 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); if (matImgSrc1.empty()) {<!-- --> System.out.println("Empty image: " + imagePath1); System.exit(0); } if (matImgSrc2.empty()) {<!-- --> System.out.println("Empty image: " + imagePath2); System.exit(0); } // 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 border layout. No need // setLayout(new BorderLayout()); //Show the window. frame.pack(); frame.setVisible(true); } 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)); 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); slider.addChangeListener(new ChangeListener() {<!-- --> @Override public void stateChanged(ChangeEvent e) {<!-- --> JSlider source = (JSlider) e.getSource(); alphaVal = source.getValue(); update(); } }); 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 local OpenCV library System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // Arrange tasks for the event dispatch thread: // Create and display the graphical user interface for this application. javax.swing.SwingUtilities.invokeLater(new Runnable() {<!-- --> @Override public void run() {<!-- --> new AddingImagesTrackbar(args); } }); } }
Python
The code for this tutorial is shown below. You can also download it from here
from __future__ import print_function from __future__ import division import cv2 as cv import argparse alpha_slider_max = 100 title_window = 'Linear Blend' 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) 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='LinuxLogo.jpg') parser.add_argument('--input2', help='Path to the second input image.', default='WindowsLogo.jpg') args = parser.parse_args() src1 = cv.imread(cv.samples.findFile(args.input1)) src2 = cv.imread(cv.samples.findFile(args.input2)) 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) cv.namedWindow(title_window) trackbar_name = 'Alpha x %d' % alpha_slider_max cv.createTrackbar(trackbar_name, title_window, 0, alpha_slider_max, on_trackbar) # Show some content on_trackbar(0) # Wait for the user to press a key cv.waitKey()
Description
We only analyze the code related to Trackbar:
- First, we load the two images that will be blended.
C++
src1 = imread( samples::findFile("LinuxLogo.jpg") ); src2 = imread( samples::findFile("WindowsLogo.jpg") );
Java
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);
Python
# Read images ( both have to be of the same size and type ) src1 = cv.imread(cv.samples.findFile(args.input1)) src2 = cv.imread(cv.samples.findFile(args.input2))
- To create a track bar, you first need to create the window where the track bar resides. therefore
C++
namedWindow("Linear Blend", WINDOW_AUTOSIZE); // Create Window
Java
// 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);
Python
cv.namedWindow(title_window)
- Now we can create the Trackbar:
C++
char TrackbarName[50]; snprintf( TrackbarName, sizeof(TrackbarName), "Alpha x %d", alpha_slider_max ); createTrackbar( TrackbarName, "Linear Blend", & amp;alpha_slider, alpha_slider_max, on_trackbar );
Java
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);
Python
trackbar_name = 'Alpha x %d' % alpha_slider_max cv.createTrackbar(trackbar_name, title_window, 0, alpha_slider_max, on_trackbar)
Please note the following (C++ code):
- Our trackbar has a label TrackbarName
- The tracking bar is located in a window called Linear Blend
- Trackbar values range from 0 to alpha_slider_max (the minimum value is always 0).
- The Trackbar’s value 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 for C++ and Python code, using anonymous inner class listener in Java
C++
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 ); }
Java
slider.addChangeListener(new ChangeListener() {<!-- --> @Override public void stateChanged(ChangeEvent e) {<!-- --> JSlider source = (JSlider) e.getSource(); alphaVal = source.getValue(); update(); } });
Python
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)
Please note (C++ code):
- We use the value of alpha_slider (integer) to get the double value of alpha.
- alpha_slider updates every time the user moves the trackbar.
- We define src1, src2, dist, alpha, alpha_slider and beta as global variables so they can be used anywhere.
Run results
- Our program will produce the following output:
- As a way to practice, you can also add two track bars to the Change image contrast and brightness program one for setting α and one for setting β: