GUI-Applications

One of ICL’s main features is it’s tight integration with the GUI creation framework, which allows for intuitive and simple creation of GUI-applications. In this section we will develop a simple viewer application that grabs images from arbitrary image sources and displays the image.

For a more general overview about the GUI framework, we recommend to also study GUI Creation and Visualization Framework.

Simple Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <ICLQt/Common.h>

GUI gui;
GenericGrabber grabber;

void init(){
   grabber.init(pa("-i"));
   gui << Image().handle("image") << Show();
}
void run(){
   gui["image"] = grabber.grab();
}
int main(int n, char **args){
   return ICLApp(n,args,"-input|-i(2)",init,run).exec();
}

Note

a documented version of this source code can be found below

A basic ICL GUI-application can be structured into three major functions: main, init and run

main

This function simply creates an instance of type ICLApplication (or short ICLApp). The ICLApp instance always gets the following arguments:

  • the program argument count the program

  • argument list the program

  • argument definition string (which can be set to “”, if program argument support shall not be supported)

  • an initialization function

  • further functions, that are automatically distributed to extra threads

In fact, The ICLApp instances does a lot of work for you.

  • it creates a QApplication

  • it calls your initialization function before the QApplications event-loop is entered

  • it parses all program arguments (and notifies errors)

  • it creates working threads for each given run-function

  • it joins all threads before the internal Qt-event loop is shut down.

init

This function is automatically invoked by the ICLApp instance that was created in main. Here, the application and in particular the GUI can be initialized. Program arguments can also be used here.

run

This function is called in a loop in the applications working thread. Normally run has the steps

  1. image acquisition

  2. image processing

  3. restult visualization

In the examples the images are visualized without any processing

Documented Example

First, we include the ‘care-free’-header ICLQt/Common.h which includes all most common ICL-headers. Please note, this header also includes all icl sub-namespaces icl::utils, icl::math, etc. as well as the std-namespace

#include <ICLQt/Common.h>

GUI gui;
GenericGrabber grabber;

We need a global GUI instance that is visible from your init- and from your run-function. As you application normally has only one global GUI instance, the use of a global variable is justifiable and natural here.

#include <ICLQt/Common.h>

GUI gui;
GenericGrabber grabber;

The same is true for the image source of your application. Here, we use an instance of type GenericGrabber, which can be configured simply using program arguments

#include <ICLQt/Common.h>

GUI gui;
GenericGrabber grabber;

We use the init function for initialization of the grabber and the GUI instance

void init(){
   grabber.init(pa("-i"));
   gui << Image().handle("image") << Show();
}

The grabber can be initialized directly with the given program argument, which can be accessed by the utils::pa function. pa gets one of the program argument’s name aliases and optionally also the sub-argument index.

void init(){
   grabber.init(pa("-i"));
   gui << Image().handle("image") << Show();
}

now we have to create a GUI component for image visualization. To this ends, we use ICL’s powerful Qt-based GUI creation framework. Here, GUI components can conveniently streamed into each other to create complex GUIs, but also for simple GUI as necessary in this example, it is convenient to use.

void init(){
   grabber.init(pa("-i"));
   gui << Image().handle("image") << Show();
}

The run function contains our processing loop which is acutually very simple in this case. It just grabs a new image and visualizes it with our image visualization GUI component.

void run(){
   gui["image"] = grabber.grab();
}

Here, we pass the next grabbed image from the grabber instance directly to the visualization component

void run(){
   gui["image"] = grabber.grab();
}

Finally, the main function creates an ICLApp instance and returns the result of its ICLApplication::exec()-function. It also specifies the list of allowed program arguments. In this case, only a single argument is allowed, that gets two sub-arguments. The “[m]”-prefix makes the argument mandatory

int main(int n, char **args){
   return ICLApp(n,args,"-input|-i(2)",init,run).exec();
}

Compiling and Running

Again, you can set up you build-environment as described before. If your used ICL build does at least support Qt and libjepg, you can run your application with

./application-name -input create lena

The program argument -input device-type device-info is used for most ICL-applications. In combination with an instance of type GenericGrabber, this enables you to create applications that are able to work with arbitrary image sources. Here are some further examples:

-input create parrot

uses a static hard-coded test image showing a parrot as input. Each time, the GenericGrabber’s grab-function is called, the same image is returned.

-input file image.pnm

uses a constant image file as input

-input file ‘images/*.jpg’

uses all images as input that match the given pattern. Note: the pattern is expanded internally, so you have to set it into tics (‘) to avoid that the pattern is already expanded by your bash

-input v4l 0

This will use the first Video4Linux2-based camera (usually used for webcams and builtin cameras) that is available 1

-input dc 0

This will use the first firewire-camera that is connected to your PC as input 2

-input video myvideo.avi

This will grab images frame by frame from the given video file 3

Note

A complete list of supported device-types and their device selection parameters is given in the GenericGrabber reference (TODO: a link would be better here!).

Footnotes

1

needs ICL built with v4l2 support

2

needs ICL built with libdc support

3

needs ICL built with opencv support, and the video codec must be compatible