OpenCL 学习step by step (8) 灰度图Histogram计算(2)

来源:互联网 发布:明朝生活知乎 编辑:程序博客网 时间:2024/05/16 02:00

现在我们利用上一篇教程的方法,来统计一副RGBA图像中,有多少个像素点(该像素点满足R, G, B, A任意分量>=5)?我考虑的方法是建立256 bin的直方图,对于一个像素,求max(R, G,B,A),用该值决定该像素点进入那个bin,这样求出直方图后,width*height - hostBin[0] - hostBin[1] - hostBin[2] - hostBin[3] - hostBin[4],即为我们要的结果。

     本教程代码基本上和上一篇教程中代码是一样的,区别主要包括以下2点:

1、我们装入的是RGBA 彩色图。

//装入图像 
unsigned char *src_image=0; 
gFreeImage img; 
if(!img.LoadImage("../lenna.jpg")) 
    { 
    printf("can‘t load lenna.jpg\n"); 
    exit(0); 
    } 
src_image = img.getImageData(width,height); 

2、在kernel代码中,有点小变化,kernel代码如下:

#define LINEAR_MEM_ACCESS#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable #define BIN_SIZE 256/** * 计算直方图,bins是256 * data  输入数据 * 一个workgroup内所有thread共享的内存, * 每个workgroup的直方图 */__kernelvoid histogram256(__global const uchar4* data,                  __local uchar* sharedArray,                  __global uint* binResult){    size_t localId = get_local_id(0);    size_t globalId = get_global_id(0);    size_t groupId = get_group_id(0);    size_t groupSize = get_local_size(0);    //初始化共享内存    for(int i = 0; i < BIN_SIZE; ++i)        sharedArray[localId * BIN_SIZE + i] = 0;    barrier(CLK_LOCAL_MEM_FENCE);        uchar R, G, B, A, T;    //计算thread直方图    for(int i = 0; i < BIN_SIZE; ++i)    {#ifdef LINEAR_MEM_ACCESS        R =  (uint)data[groupId * groupSize * BIN_SIZE + i * groupSize + localId].x;        G =  (uint)data[groupId * groupSize * BIN_SIZE + i * groupSize + localId].y;        B =  (uint)data[groupId * groupSize * BIN_SIZE + i * groupSize + localId].z;        A =  (uint)data[groupId * groupSize * BIN_SIZE + i * groupSize + localId].w;        uint value = (uint)max(max(R,G),max(B,A));#else        uint value = data[globalId * BIN_SIZE + i];#endif // LINEAR_MEM_ACCESS        sharedArray[localId * BIN_SIZE + value]++;    }        barrier(CLK_LOCAL_MEM_FENCE);        //合并workgroup中所有线程的直方图,产生workgroup直方图    for(int i = 0; i < BIN_SIZE / groupSize; ++i)    {        uint binCount = 0;        for(int j = 0; j < groupSize; ++j)            binCount += sharedArray[j * BIN_SIZE + i * groupSize + localId];                    binResult[groupId * BIN_SIZE + i * groupSize + localId] = binCount;    }}

 

完整的代码请参考:

工程文件gclTutorial8

代码下载:

http://files.cnblogs.com/mikewolf2002/gclTutorial.zip

0 0