PARP Research Group University of Murcia, Spain


User interface

Graphical user interface blocks

Creating powerful graphical user interfaces in QVision applications is quite simple.

The framework includes a versatile set of graphical blocks, which can perform several tasks while the application is running: offer the user control over several aspects of application, show resulting output data from the processing blocks (like images, point lists, etc...), inspect the execution performance, etc...

The group Graphical User Interface contains these ready-to-use graphical blocks. Some of the most important are:

  • QVDefaultGUI Offers control and inspection for several aspects of the application for the user at execution time:
    • Control on the input parameters for the processing blocks.
    • Control on the flow of the video input sources.
    • Inspect the execution performance of the different blocks and algorithms.
  • QVImageCanvas Can display images, lists of 2D points, lines and polylines.
  • QVNumericPlot Plot the output numerical values produced by one or several processing blocks through time.
  • QVHistogramPlot Plot 2D histograms, or display lists of numerical values as an histogram display.

Command line parameters

Dynamic properties of certain types, contained in processing blocks or camera objects in a QVision application, are automatically detected by the QVApplication object before the call to the QVApplication::exec() method, again thanks to their self introspection capabilities. The QVApplication object also parses the input console command line used to launch the application. By doing both things, this object allows the user to establish initial values for those input dynamic properties through parameters in the command line. These command line assignable dynamic properties line must be input properties of type integer (int), double (double), boolean (bool), or character strings (QString).

Using the --help command line parameter, every QVision application displays an usage reference text (equivalent to that shown in the on-line help of the application, as mentioned at the beginning of this chapter), including a description of the command line assignable dynamic properties detected in the application, including their valid value range, their default value, and a short description for them. The properties are displayed grouped with other properties contained in the same block object.

For example, a QVision application named qvapplication could be executed with the following command line:

 ./test --help 

Which will make it display the following message:

Usage: ./qvapplication [OPTIONS]
QVision application which... (some sort description here, as given to the QVApplication constructor by the programmer).

Input parameters for Video:
  --max block iterations=[int] (def. -1) ............Maximal number of iterations to execute block.
  --stats enabled=[true,false] (def. true) ....................Block CPU stats are enabled/disabled.
  --stats printing frequency=[int] (def. 0) .......Frequency to print CPU statistics (in iterations).
  --NoLoop=[true,false](def. false) ..................If the camera should be opened in no loop mode.
  --URL=[text] (def. '') ............................................URL of the video source to read.
  --Cols=[int] (def. 0) ....................................Suggested number of columns of the video.
  --Rows=[int] (def. 0) .......................................Suggested number of rows of the video.
  --RealTime=[true,false](def. false) ..............If the camera should be opened in real time mode.
  --Deinterlaced=[true,false](def. false) .......If the camera should be opened in deinterlaced mode.

Input parameters for Canny Operator Block:
  --max block iterations=[int] (def. -1) ............Maximal number of iterations to execute block.
  --stats enabled=[true,false] (def. true) ....................Block CPU stats are enabled/disabled.
  --stats printing frequency=[int] (def. 0) .......Frequency to print CPU statistics (in iterations).
  --cannyHigh=[50...1000] (def. 150) ..............................High threshold for Canny operator.
  --cannyLow=[10...500] (def. 50) ..................................Low threshold for Canny operator.
  --applyIPE=[true,false](def. false) .........................If we want to apply the IPE algorithm.
  --paramIPE=[1...25] (def. 5) ........................IPE parameter (max. allowed distance to line).
  --intersectLines=[true,false] (def. true) If we want IPE to postprocess polyline (intersecting lines).
  --minLengthContour=[1...150] (def. 25) ...............Minimal length of a contour to be considered.

  [...]

[...Some other input parameters corresponding to other processing blocks...]

We can see, for example, that the Canny Operator Block includes an input property named cannyHigh, of double type. This property has a valid range of values between 50 and 1000, and its default value is 150. Along with a short text definition for the property (High threshold for Canny operator), all these characteristics are specified in the call to the method QVPropertyContainer::addProperty which adds the property in the constructor of the processing block object:

class QVCannyEdgeDetector: public QVProcessingBlock
        {
        public:
                QVCannyEdgeDetector(QString name): QVProcessingBlock(name)
                        {
                        addProperty<double>("cannyHigh", inputFlag, 150, "High threshold for Canny operator", 50, 1000);
                        [...]
                        }
        [...]
        }

The following command line starts the application, specifying some initial values for the property URL in the camera object (with a given video source URL, see section Video source identifier URL formats for details), and the property cannyHigh in the Canny Operator Block object:

 ./qvapplication --URL=http://perception.inf.um.es/videos/misc/penguin.dv --cannyHigh=300 

The command line parameters specifying values for the processing block properties must be separated by spaces in the command line. They must start with a double dash, followed by the name of the property (which must itself be quoted if it contains spaces; for example, --"some property"=1000). Next must follow an = (equal sign), and the value we want to initially store in the property.

Optionally, the name of the processing block can be specified in the parameter, between the double dash and the property name, to resolve name conflicts, when two processing blocks have a property referenced with the same name. For example, the previous command would be equivalent to the following:

./qvapplication --Video:URL=http://perception.inf.um.es/public_data/videos/misc/penguin.dv --"Canny Operator Block":"cannyHigh"=100 

In case of unresolved name conflict, every property with the given name of every processing block in the application will be initialized with the given value.

CPU performance measurement

The developer of a processing block class can divide the processing of each call to the QVProcessingBlock::iterate() function in a sequence of different stages whose computing times he wants to measure. The programmer must simply use calls to the QVProcessingBlock::timeFlag() function to mark the desired computing stages. For example, the following code of the iterate method of a processing block

MyBlock::iterate()
        {
        [...]
        timeFlag("Read parameters");
        [...]
        timeFlag("Call to getComponentTree for low areas");
        [...]
        timeFlag("Prune low areas from image");
        [...some other processing stages and corresponding timeFlag's...]
        }

will set some performance breakpoints in the function. The QVProcessingBlock::timeFlag() function logs the time elapsed between each two of those breakpoints, and stores the time statistics in the processing block. The performance times can be later displayed by simply pressing the CPU statistics button in the tab of the desired processing block, at the default GUI window. Of course, the computational load of these timeFlags is extremely low, and they can be used ubiquitously without almost affecting global performance.

Here is a screen-shot for the above coding example:

componenttree_cpustat.png

For advanced users, which could not be interested in using the default GUI, the class QVCPUPlot can still be used to display the CPU usage statistics of a processing block. For example, the following main function

void main()
        {
        [...]
        MyBlock myBlock("name");
        [...]
        QVCPUPlot cpuPlot("CPU Plot", true, 10);
        cpuPlot.linkProperty(myBlock);  
        }

will create in execution time the following window, displaying time statistics for the different time segments specified with the QVProcessingBlock::timeFlag() method, just as before.

Note:
CPU stat plot depends on real execution time between time flags, so when two or more processing blocks compete for one CPU, times can differ a lot with respect to executions in environments in which each processing block runs on its own CPU.



QVision framework. PARP research group, copyright 2007, 2008.