Alex Rivera | Logout

Multithreaded image processing in C++

Asked 2008-11-28T19:24:49.690
11

I am working on a program which manipulates images of different sizes. Many of these manipulations read pixel data from an input and write to a separate output (e.g. blur). This is done on a per-pixel basis.

Such image mapulations are very stressful on the CPU. I would like to use multithreading to speed things up. How would I do this? I was thinking of creating one thread per row of pixels.

I have several requirements:

  • Executable size must be minimized. In other words, I can't use massive libraries. What's the most light-weight, portable threading library for C/C++?
  • Executable size must be minimized. I was thinking of having a function forEachRow(fp* ) which runs a thread for each row, or even a forEachPixel(fp* ) where fp operates on a single pixel in its own thread. Which is best?
    • Should I use normal functions or functors or functionoids or some lambda functions or ... something else?
    • Some operations use optimizations which require information from the previous pixel processed. This makes forEachRow favorable. Would using forEachPixel be better even considering this?
  • Would I need to lock my read-only and write-only arrays?
    • The input is only read from, but many operations require input from more than one pixel in the array.
    • The ouput is only written once per pixel.
  • Speed is also important (of course), but optimize executable size takes precedence.

Thanks.

More information on this topic for the curious: C++ Parallelization Libraries: OpenMP vs. Thread Building Blocks

Edit
Report

3 Answers

1

Your compiler doesn't support OpenMP. Another option is to use a library approach, both Intel's Threading Building Blocks and Microsoft Concurrency Runtime are available (VS 2010).

There is also a set of interfaces called the Parallel Pattern Library which are supported by both libraries and in these have a templated parallel_for library call. so instead of:

#pragma omp parallel for 
for (i=0; i < numPixels; i++) 
{ ...} 

you would write:

parallel_for(0,numPixels,1,ToGrayScale());

where ToGrayScale is a functor or pointer to function. (Note if your compiler supports lambda expressions which it likely doesn't you can inline the functor as a lambda expression).

parallel_for(0,numPixels,1,[&](int i)
{  
   pGrayScaleBitmap[i] = (unsigned BYTE)  
       (pRGBBitmap[i].red * 0.299 +  
        pRGBBitmap[i].green * 0.587 +  
        pRGBBitmap[i].blue * 0.114);  
});

-Rick

answered 2010-01-15T15:55:26.847
1

Check the Creating an Image-Processing Network walkthrough on MSDN, which explains how to use Parallel Patterns Library to compose a concurrent image processing pipeline.

I'd also suggest Boost.GIL, which generates highly efficient code. For simple multi-threaded example, check gil_threaded by Victor Bogado. The An image processing network using Dataflow.Signals and Boost.GIL explains an interestnig dataflow model too.

answered 2012-09-28T15:02:10.327
0

I think map/reduce framework will be the ideal thing to use in this situation. You can use Hadoop streaming to use your existing C++ application.

Just implement the map and reduce jobs.

As you said, you can use row-level maniputations as a map task and combine the row level manipulations to the final image in the reduce task.

Hope this is useful.

answered 2010-01-15T16:00:12.973

Your Answer