Skip to content
Andrés Solís Montero edited this page Nov 10, 2015 · 4 revisions

Processing Multiple Frames at Once

Let's start with a vivalib program that access the default camera, extract multiple images from the camera and display the result in a window.

All the vivalib classes and functions are placed into the viva namespace. Therefore, to access this functionality from your code, use the viva:: specifier or using namespace viva; directive:

#include "viva.h"

using namespace viva;

int main(int argc, const char * argv[])
{
    
    BatchProcessor processor(2);
    processor.run();
    
    return 0;
}

The BatchProcessor class is the core of the vivalib API for batch processing. We will create an instance of this class, initialize some of its members and finally call the run() routine. Note the number 2 as an argument to the class, this number specifies the number of frames to process in one iteration (i.e. default value is 10 if not specified);

To stop the program select the main window (i.e. "Process Output") and press the ESC key.

Create your algorithm

There are several options to pass a routine to the BatchProcessor class in the vivalib framework. To showcase the possibilities let's implement an Image Blending routine that process every two frame from the default webcam and displays the result in a window.

###Using a lambda function:

#include "viva.h"

using namespace viva;

int main(int argc, const char * argv[])
{
    
    auto processFrame = [](const size_t frameN, const vector<Mat> &input, Mat &output){
        addWeighted( input[0], 0.5, input[1], 0.5, 0.0, output);
    };
    
    BatchProcessor processor(2);
    processor.setBatchProcess(processFrame);
    processor.run();
    
    return 0;
}

The processFrame function is a lambda function that takes three arguments

auto processFrame = [](const size_t frameN,const vector<Mat> &input, Mat &output){...}

The BatchProcessor class will extract 2 (i.e., passed as an argument, it could be any positive number) frames from the webcam and pass them to the processFrame lambda function as a vector input of images. The frameN number (i.e. number identifying the number of the first frame passed to the function). Your algorithm should write the results to the output image. Note that you don't need to display the image in your code. The BatchProcessor class will display it from your output in a "Process Output" window.

Using a pointer to a function

#include "viva.h"

using namespace viva;

void blend(const size_t frameN,const vector<Mat> &input, Mat &output)
{
    addWeighted( input[0], 0.5, input[1], 0.5, 0.0, output);
}


int main(int argc, const char * argv[])
{

    BatchProcessor processor(2);
    processor.setBatchProcess(&blend);
    processor.run();
    
    return 0;
}

Similar to the lambda function, you just need to define a function with the same three parameters: frameN(const size_t), input (vector&), and output (Mat&).

The lambda function and function pointer are a handy and fast way to prototype your algorithms.

Using a functor class

#include "viva.h"

using namespace viva;

class Blending
{
public:
    void operator()(const size_t frameN, vector<Mat> &input, Mat &output)
    {
        addWeighted( input[0], 0.5, input[1], 0.5, 0.0, output);
    }
};

int main(int argc, const char * argv[])
{

    Blending blend;
    BatchProcessor processor;
    processor.setBatchProcess(blend);
    processor.run();
    
    return 0;
}

For more elaborated and modular algorithms we recomend to encapsulate your code in a functor class. You just need to overload the operator() (i.e. the "function call" operator) with the same three parameters explained in previous methods. This way, your class could hold configurations parameters or other members that are only revenant to your solution and not the main.cpp file.

Using the BatchProcessFrame interface

The BatchProcessFrame interface is a functor class that implements the MouseListener and KeyboardListener classes from the vivalib framework. The BatchProcessFrame class is available in the vivalib library once you include the "viva.h" header in your file. This method is useful when your application needs to handle mouse or keyboard events.

#include "viva.h"

using namespace viva;

class Blending : public BatchProcessFrame
{
public:
    Blending(size_t batchSize):BatchProcessFrame(batchSize){}
    void operator()(const size_t frameN, vector<Mat> &input, Mat &output)
    {
        addWeighted( input[0], 0.5, input[1], 0.5, 0.0, output);
    }
 
    void leftButtonDown(int x, int y, int flags)
    {
        cout << "left click at: "<< x << ", " << y << endl;
    };
    void keyboardInput(int key)
    {
        cout << "key " << key << " pressed" << endl;
    };
    
};

int main(int argc, const char * argv[])
{

    Ptr<BatchProcessFrame> blend = new Blending(2);
    BatchProcessor processor;
    processor.setBatchProcess(blend);
    processor.listenToMouseEvents();
    processor.listenToKeyboardEvents();
    processor.run();
    
    return 0;
}

More information about handling mouse and keyboard events can be found in the Handling Mouse and Keyboard Events page.

Continue learning the framework by selecting different inputs and saving your results to disk:

Clone this wiki locally