Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ graphics OpenMP
This is the first time that I use C++. A part of my project is to convert a given image (rgb) of any type (ex:bmp) to grayscale using c++ OpenMp.
 
I did some google search online and found on code project a function that does the conversion in c++ and openMP as follows:
 
    omp_set_num_threads(threads);
    #pragma omp parallel for
    for(int z = 0; z < height*width; z++)
    {
    pDest[z] = (pSrc[z*4+0]*3735 + pSrc[z*4 + 1]*19234+ pSrc[z*4+ 2]*9797)>>15;
    }
 
or
 
#pragma omp parallel for
for (i=0; i < numPixels; i++)
 
{
   pGrayScaleBitmap[i] = (unsigned BYTE)
            (pRGBBitmap[i].red * 0.299 +
             pRGBBitmap[i].green * 0.587 +
             pRGBBitmap[i].blue * 0.114);
}
 
But since I am new to C++, I want from any one who has experience in it, to guide with with the steps needed to just load the image, and then call any of the functions above and later on Save it back to hard disk.
 
I would be very thankful because I tried so hard to do it but didn't work with me
Posted 22-Jan-13 3:13am
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I am not sure if you are having trouble with the coding part or the parallelization part. In the code you have given here, you could linearize the code by commenting out the "omp_set_num_threads()" and "#pragma omp parallel for" statements to debug the program. These directives take (supposedly) working code and make it usable in a multiprocessor context. Before using these directives, you should come up with working code.
 
tl;dr: You are taking too big a bite. Write single stream code that works before trying to parallelize it.
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Hello,
Here is the brief description of what you need:
#include <gdiplus.h>
#pragma comment(lib,"gdiplus.lib")
// Initialize GDI+
ULONG _token;
Gdiplus::GdiplusStartupInput _input;
Gdiplus::GdiplusStartup(&_token, &_input, NULL);
// Shutdown GDI+
Gdiplus::GdiplusShutdown(_token);
// Loading Image 
Gdiplus::Bitmap * LoadImage(LPCWSTR pszFilePath)
{
    return Gdiplus::Bitmap::FromFile(pszFilePath);
}
// OMP image processing
void RGB24GrayOMP(LPBYTE pRGB,CONST INT _width,CONST INT _height)
{
    // Makes parrallels foravailable threads
    omp_set_num_threads(omp_get_max_threads());
    #pragma omp parallel firstprivate(pRGB,_width,_height) default(none)
    {
        // Divide height for processing according actaul thread
        // Current OMP thread
        const int _thread	= omp_get_thread_num();
        // Total OMP treads
        const int _count	= omp_get_num_threads();
        // number of rows to process
        int _last = (_height / _count); 
        // first row
        const int _first = _last * _thread;
        // Correct last thread height
        if (_thread == _count - 1) _last += _height % _count;
        // Processing stride width * 3 as we are convert RGB24 - 3 bytes per pixel
        const int nStride = _width * 3;
        // Target Data for processing in current thread
        LPBYTE pTarget	= pRGB + _first * nStride;
        double luma;
        // 2 loops - for better understanding
        for (int y = 0; y < _last; y++) // here we loop in rows
        {
            for (int x = 0; x < _width; x++) // here we loop in columns
            {
                // RGB position as we convert RGB24 - 3 bytes per pixel
                int pos = x * 3; 
                // Calculate luma
                luma  =  (0.257 * pTarget[pos + 2]) + (0.504 * pTarget[pos + 1]) + (0.098 * pTarget[pos + 0]) + 16;
                // Necessary to correct it 
                if (luma > 255) luma = 255;
                // Set all RGB to that value so on output you have gray image
                pTarget[pos + 0] = (BYTE)luma;
                pTarget[pos + 1] = (BYTE)luma;
                pTarget[pos + 2] = (BYTE)luma;
            }
            pTarget += nStride;
        }
    }
    #pragma omp barrier
}
// Locking Image for update
void UpdateImage(Gdiplus::Bitmap * _bitmap)
{
    using namespace Gdiplus;
    BitmapData * _data = new BitmapData();
    Rect _rect(0,0,_bitmap->GetWidth(),_bitmap->GetHeight());
    if (Ok == _bitmap->LockBits(&_rect,ImageLockModeRead | ImageLockModeWrite,PixelFormat24bppRGB,_data))
    {
        RGB24GrayOMP((LPBYTE)_data->Scan0,_data->Width,_data->Height);
        _bitmap->UnlockBits(_data);
    }
    delete _data;
}
 
Regards,
Maxim.
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 24 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid