IPSDK  4_1_0_2
IPSDK : Image Processing Software Development Kit
Launcing asynchronous processes

Launch asynchronous processes. More...

Launch asynchronous processes.

Introduction

First of all, it is advised to prefer synchronous IPSDK processors (or algorithms). Using synchronous algorithms means that we have to wait that a process finishes before the next one can start so that we know that the output is available when we have acces to it.

Nevertheless, IPSDK allows to call processors in an asynchronous way. The main reason to need asynchronous calls is that an IPSDK-based application has a Graphical User Interface (GUI). When heavy image processing calculations are launched, the GUI will not respond until the computation finishes whereas the user may want to interrupt it or load another image for instance while the process is still running.

Precautions

It is important to emphasize that asynchronous wrappers in IPSDK must be used only to satisfy specific needs.

Due to its asynchronous nature, it is possible to access to the processor output data before the calculation terminates. The best scenario is that the data are incomplete, i.e. only a part of the image is calculated. In the worst case, the application may crash because of aberrant values or two asynchronous processes attempting to access the same data at the same time.

For this reason, it is preferable to use synchronous calls to IPSDK, which satisfy almost all needs.

How to use asynchronous processes?

To asynchronously launch a processor, IPSDK provides the following functionnalities:

  1. Launch and asynchonous process: this can be done by calling a wrapper with the "_async" suffix. Each synchronous wrapper is duplicate in an asynchronous one. However, they differs not only by their name but also by the output type, which is a pointer to the launched processor. For instance, there are two synchronous wrappers for the absolute value calulation and their asynchronous alternatives:
    • image::ImagePtr ipsdk::imaproc::arithm::absImg(const image::ImageConstPtr &pInImg);
    • void ipsdk::imaproc::arithm::absImg(const image::ImageConstPtr &pInImg, const image::ImagePtr &pOutImg);
    • boost::shared_ptr<AbsImg2dLvl1> ipsdk::imaproc::arithm::absImg_async(const image::ImageConstPtr &pInImg);
    • boost::shared_ptr<AbsImg2dLvl1> ipsdk::imaproc::arithm::absImg_async(const image::ImageConstPtr &pInImg, const image::ImagePtr &pOutImg);
  2. With access to this processor, it is possible to wait for its completion or request for its cancellation.
  3. When the process is completed, the output data can be retrieved thanks to the function getAsyncProcessorOutput(), which returns the full output of the processor.

An example of cancellation request is given below:

// Launch asynchronous processor to calculate absolute value on each pixel
boost::shared_ptr<AbsImgLvl1> pProcessor = ipsdk::imaproc::arithm::absImg_async(pInImg);
// Wait 20 milliseconds
boost::this_thread::sleep(boost::posix_time::milliseconds(20));
// Request cancellation
pProcessor->requestCancellation();
// Wait for the processor completion
pProcessor->waitForCompletion();
// Retrieve the algorithm output (in this case, an image)
ImagePtr pOutImg = getAsyncProcessorOutput(pProcessor);
Note
Whether the processor is cancelled or not, the waitForCompletion() method must be called before retrieving the result.

In the case of multi-slice calculation (for instance with ipsdk::imaproc::glbmsr::StatsMsr2d), the processor output is a plan indexed data structure. In that case, the function getAsyncProcessorMultiSliceOutput() must be called instead of getAsyncProcessorOutput().

Python syntax

The same approach is used in a Python script. Here is a translation of the above C++ sample in Python.

import time
import PyIPSDK
import PyIPSDK.IPSDKIPLArithmetic as arithm
# Launch asynchronous processor to calculate absolute value on each pixel
processor = arithm.absImg_async(pInImg);
# Wait 20 milliseconds
time.sleep(0.02)
# Request cancellation
processor.requestCancellation()
# Wait for the processor completion
processor.waitForCompletion()
# Retrieve the algorithm output (in this case, an image)
outImg = arithm.getAsyncProcessorResult(processor)