Application Utility – Add trackbar to application OpenCV v4.8.0

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 β: