使用C ++ openMP将图像转换为灰度(简单) [英] convert image to grayscale using C++ openMP (simple)

查看:103
本文介绍了使用C ++ openMP将图像转换为灰度(简单)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次使用C ++。我的项目的一部分是使用c ++ OpenMp将任何类型的给定图像(rgb)(例如:bmp)转换为灰度。



我在网上做了一些谷歌搜索并在代码项目中找到了一个在c ++和openMP中进行转换的函数,如下所示:



 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 )GT;→15;
}









< pre lang =cs> #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 );
}





但是因为我是C ++的新手,所以我想要任何有经验的人来指导使用加载图像所需的步骤,然后调用上面的任何函数,稍后将其保存回硬盘。



我会非常感激,因为我努力做到这一点但是没有和我一起工作

解决方案

我不确定你是否遇到编码部分或并行化部分的问题。在这里给出的代码中,您可以通过注释掉omp_set_num_threads()和#pragma omp parallel for语句来调整程序来线性化代码。这些指令采用(假设)工作代码并使其可用于多处理器上下文。在使用这些指令之前,你应该提出工作代码。



tl;博士:你吃的太大了。在尝试并行化之前编写单个流代码。


您好,

以下是您需要的简要说明:

  #include   <   gdiplus.h  >  
#pragma comment(lib,gdiplus.lib)
// 初始化GDI +
ULONG _token;
Gdiplus :: GdiplusStartupInput _input;
Gdiplus :: GdiplusStartup(& _token,& _input,NULL);
// 关闭GDI +
Gdiplus :: GdiplusShutdown(_token);
// 加载图片
Gdiplus :: Bitmap * LoadImage(LPCWSTR pszFilePath)
{
return Gdiplus :: Bitmap :: FromFile(pszFilePath);
}
// OMP图像处理
void RGB24GrayOMP(LPBYTE pRGB,CONST INT _width,CONST INT _height)
{
// < span class =code-comment>使并行可用的线程
omp_set_num_threads(omp_get_max_threads());
#pragma omp parallel firstprivate(pRGB,_width,_height)default(none)
{
// 根据actaul线程划分处理高度
// 当前OMP线程
const int _thread = omp_get_thread_num();
// 总OMP踏板
const int _count = omp_get_num_threads();
// 要处理的行数
int _last =(_ height / _count);
// 第一行
const int _first = _last * _thread;
// 更正最后一个线程高度
if (_thread == _count - 1 )_last + = _height%_count;
// 处理步幅宽度* 3,因为我们转换RGB24 - 每像素3个字节
const int nStride = _width * 3 ;
// 目标数据在当前线程中处理
LPBYTE pTarget = pRGB + _first * nStride;
double luma;
// 2个循环 - 为了更好地理解
for int y = 0 ; y< _last; y ++) // 这里我们循环行
{
for int x = 0 ; x< _width; x ++) // 此处我们循环列
{
// 我们转换RGB24的RGB位置 - 每像素3个字节
int pos = x * 3 ;
// 计算亮度
luma =( 0 257 * pTarget [pos + 2 ])+( 0 504 * pTarget [pos + 1 ] )+( 0 098 * pTarget [pos + 0 ])+ 16 ;
// 需要更正
if (luma> 255 )luma = 255 ;
// 将所有RGB设置为该值,以便输出您有灰色图像
pTarget [pos + 0 ] =(BYTE)luma;
pTarget [pos + 1 ] =(BYTE)luma;
pTarget [pos + 2 ] =(BYTE)luma;
}
pTarget + = nStride;
}
}
#pragma omp barrier
}
// 锁定图像以进行更新
void UpdateImage(Gdiplus :: Bitmap * _bitmap)
{
使用 命名空间 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->宽度,_数据 - >高度);
_bitmap-> UnlockBits(_data);
}
delete _data;
}





问候,

Maxim。


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

解决方案

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.


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.


这篇关于使用C ++ openMP将图像转换为灰度(简单)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆