首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenCL "read_image“返回空白像素

OpenCL "read_image“返回空白像素
EN

Stack Overflow用户
提问于 2014-05-01 22:43:25
回答 2查看 1.9K关注 0票数 1

问题说明和实例

我正在与OpenCL一起工作,我正在努力使图像调整大小的工作。我已经完成了几个教程,并且我已经尝试编写了我自己的内核。

我的问题是,我无法让OpenCL从传输到它的图像中读取像素。

下面是OpenCL中的内核:

代码语言:javascript
复制
const sampler_t SMPL_PREF = CLK_NORMALIZED_COORDS_TRUE |
                            CLK_ADDRESS_CLAMP |
                            CLK_FILTER_LINEAR;

__kernel void image_scaling( __read_only  image2d_t src_img,
                             __write_only image2d_t dest_img,
                                              float WRATIO,
                                              float HRATIO )
{
    int2       coor = (int2)( get_global_id(0), get_global_id(1) );

    float2 origCoor = (float2)(convert_float2(coor).x * WRATIO,
                               convert_float2(coor).y * HRATIO );

    uint4     color = read_imageui( src_img, SMPL_PREF, origCoor );

    // Test write_imageui -- THIS WORKS!!! :(
    //color = (uint4)(20, 255, 20, 255);

    write_imageui( dest_img, coor, color );
}

我正在使用OpenCL.Net,但我不认为这是导致问题的原因。我就是这样将图像从主机传输到设备内存的:

代码语言:javascript
复制
ImageFormat clImageFormat = new ImageFormat( ChannelOrder.RGBA,
                                             ChannelType.Unsigned_Int8 );

// Allocate Memory on Device
IMem inputImage2DBuffer = Cl.CreateImage2D( env.Context,
                                            MemFlags.AllocHostPtr |
                                                MemFlags.ReadOnly,
                                            clImageFormat,
                                   (IntPtr) originalWidth,
                                   (IntPtr) originalHeight,
                                   (IntPtr) 0,
                                   (IntPtr) 0, //imageData,
                                        out error );

// Copy the host data to the device
error = Cl.EnqueueWriteImage( env.CommandQueues[ 0 ],  // OpenCL Command Queue
                              inputImage2DBuffer,      // Ptr on device for image
                              Bool.True,               // Blocking write
                              originPtr,               // origin x,y (0,0)
                              regionPtrInput,          // dimension w,h
                     (IntPtr) 0,                       // rowPitch
                     (IntPtr) 0,                       // rowSlice
                              imageData,               // Ptr to byte[] host data
                              0,                       // Number of wait events
                              null,                    // array of wait events
                          out clEvent );

Cl.WaitForEvents( (uint) 1, new Event[] { clEvent } );
CheckError( error, "EnqueueWriteImage" );
clEvent.Dispose( );

我需要帮助

如果我没有将图像正确地传输到设备上,或者我的设备上有什么问题,我很希望有人能提出一种调试的方法。我有点死路一条。就像我说的,我不认为这是OpenCL.Net的问题,但我现在几乎愿意尝试任何事情。我想我可能在传输主机内存时做了一些愚蠢的事情,但是我已经看了100多次,并且重写了差不多十几次。我看不出有什么能引起这个问题。

我知道这样一个事实:我可以将一个常规的缓冲区传输到设备上并将其读取回来,读取图像是我唯一的问题。如果您查看我的OpenCL代码,您将看到一条注释行。通过取消注释,我可以将数据返回到我的主机(一个石灰绿色)。这让人相信问题出在read_image身上。

我正在开发一款2013年MacBook Air,使用英特尔5000 GPU运行我的OpenCL代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-01 23:04:18

根据您为WRATIO和HRATIO传递的值,问题非常类似于您正在使用CLK_NORMALIZED_COORDS_TRUE,并且应该使用CLK_NORMALIZED_COORDS_FALSE。后者允许您使用像素坐标而不是0.0到1.0“规范化”坐标。

此外,当您正在进行时,请注意,使用CLK_FILTER_LINEAR和float2坐标,积分坐标将给出过滤后的结果。添加(float2)(0.5f,0.5f)以获得未经过滤的值。换句话说,将像素在(2,6)处改为(2.5,6.5)。这将是重要的,当你的比率接近1.0,所以你不会得到一个模糊的图像。

票数 2
EN

Stack Overflow用户

发布于 2014-05-06 00:12:32

因此,在Dithermaster的帮助下(谢谢!),我已经解决了这个问题。问题是,当读取回像素时,我没有使用归一化坐标。下面是我当前的内核,它运行得非常棒!

Resize.cl

代码语言:javascript
复制
const sampler_t SMPL_PREF = CLK_NORMALIZED_COORDS_TRUE |
                            CLK_FILTER_LINEAR |
                            CLK_ADDRESS_NONE ;

__kernel void image_scaling( __read_only  image2d_t src_img,
                             __write_only image2d_t dest_img,
                                               uint WIDTH,     // resized width
                                               uint HEIGHT )   // resized height
{
    int2       coor = (int2)( get_global_id(0), get_global_id(1) );
    float2 normCoor = convert_float2(coor) / (float2)( WIDTH, HEIGHT );

    float4    color = read_imagef( src_img, SMPL_PREF, normCoor );

    write_imagef( dest_img, coor, color );
}

再次感谢Dithermaster指出规格表。当涉及到过滤器标志和您正在使用的read_image时,read_image非常具体。我很高兴我终于把这个修好了:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23417927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档