HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Image Processing Pipeline

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
processingimagepipeline

Problem

I'm currently toying around with some Computer Vision algorithms and always wanted to learn more about templates, so I came up with the idea to build a templated Image Processing Pipeline.

I want the pipeline to be built of several task blocks which I want to plug into each other sequentially. For a specific block, its input and output types are fixed. I ultimately want to be able to inherently control for a block to only accept the next block if the output type of the current is identical to the input type of the next.

Block_N Block_N+1
_______________ _________________
int | | str | | float
--->| str = f1(int) |------>| float = f2(str) |------->
|_______________| |_________________|


Consequently, Block_N+2 would have to accept float as input and may have an arbitrary output type.

This is what I was able to come up with:

Abstract base classes:

template
class AbstractInput {

public:
virtual ~AbstractInput() { }

virtual void call( I _input ) = 0;
};

template
class AbstractPipelineTask : public AbstractInput {

public:
typedef AbstractInput* Ptr;

AbstractPipelineTask( AbstractInput* _nextTask = NULL)
: m_nextTask ( _nextTask ) { }

virtual void call( I _input ) {

m_input = _input;
m_output = executeTask( m_input );

if ( m_nextTask )
m_nextTask->call( m_output );
}

virtual O executeTask( I& _input ) = 0;

protected:
AbstractInput* m_nextTask;

I m_input;
O m_output;
};


Example implementation:

`class Str2IntPipelineTask : public AbstractPipelineTask {

public:
Str2IntPipelineTask( AbstractInput* _nextTask = NULL )
: AbstractPipelineTask( _nextTask ) { }
virtual ~Str2IntPipelineTask() { }

virtual int executeTask( std::string& _input ) {

return atoi( _input.c_str() );
}
};

class Int2IntPipelineTask : public AbstractPipelineTask {

public:
Int

Solution

-
Since none of these classes have private members, they can be structs instead. As such, you'll no longer need to explicitly give them public inheritance.

-
Consider making the magic number 42.f a constant so that its intent is known.

-
This is specific to Visual Studio, thus is non-portable:

int _tmain(int argc, _TCHAR* argv[])


It should be changed to this to fit the standard:

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


-
In your various executeTask() functions, I believe you're meaning to pass by const&, not just by reference. You're not modifying the argument, so const is best with them.

Code Snippets

int _tmain(int argc, _TCHAR* argv[])
int main(int argc, char* argv[])

Context

StackExchange Code Review Q#64988, answer score: 3

Revisions (0)

No revisions yet.