- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试用 OpenCL 编写一个简单的图像过滤器。滤镜应采用 32bpp 彩色图像(通过 LockBits(..)
从 System::Drawing::Bitmap
获得),将像素转换为灰度并应用 3x3过滤矩阵。生成的图像应该能够显示为 8bpp Bitmap
,即使用 Format8bppIndexed
。
我有一个内核可以做一些事情,还有一个我认为应该做同样事情的单线程 CPU 解决方案。然而,问题是生成的图像是不同的:OpenCL 处理的图像更亮,几乎全身都是白色,而 CPU 图像看起来还不错——几乎就像只转换为灰度图像一样。
这是 CPU 解决方案:
static float filter[] = { -1.0f, -1.0f, -1.0f, -1.0f, 9.0f, -1.0f, -1.0f, -1.0f, -1.0f };
static float filterNorm = 1.0f;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
float gray = 0.0f;
size_t ia = 0;
for (int yi = -1; yi <= 1; ++yi) {
for (int xi = -1; xi <= 1; ++xi) {
int xx = x + xi;
if (xx < 0) xx = 0;
if (xx >= width) xx = width - 1;
int yy = y + yi;
if (yy < 0) yy = 0;
if (yy >= height) yy = height - 1;
size_t idx = 4 * (yy * width + xx);
float r = ((float)inputData32bpp[idx + 0] / 255.0f);
float g = ((float)inputData32bpp[idx + 1] / 255.0f);
float b = ((float)inputData32bpp[idx + 2] / 255.0f);
gray += (filter[ia] * ((r + g + b)/3.0f));
++ia;
}
}
gray /= filterNorm;
if (gray < 0.0f) gray = 0.0f;
if (gray > 1.0f) gray = 1.0f;
size_t idx8 = y * width + x;
outputData8bpp[idx8] = (unsigned char)(gray * 255.0);
}
}
我正在转换为 float ,因为我想实现类似于 OpenCL 内核的行为,由于图像格式 (CL_UNORM_INT8
),它也适用于 floats
。我知道 channel 顺序可能是 BGR 而不是 RGB,但是在像这里这样转换为灰度时这应该无关紧要。
OpenCL 主机代码是这样的:
static cl::ImageFormat formatBGRA(CL_BGRA, CL_UNORM_INT8);
static cl::ImageFormat formatGray(CL_LUMINANCE, CL_UNORM_INT8);
cl_int err = 0;
cl::Image2D inputImage(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
formatBGRA, width, height, 0U, inputData32bpp, &err);
cl::Image2D outputImage(context, CL_MEM_READ_WRITE,
formatGray, width, height, 0U, NULL, &err);
cl::Kernel& imgKernel = kernels[1];
err = imgKernel.setArg(0, inputImage);
err = imgKernel.setArg(1, outputImage);
err = queue.enqueueNDRangeKernel(imgKernel, cl::NDRange(0, 0), cl::NDRange(width, height));
err = queue.enqueueReadImage(outputImage, true, cl::size_t<3>(), getRegion(width, height),
width * sizeof(unsigned char), 0, outputData8bpp);
我使用的是 C++ OpenCL API,而不是 C 语言 API。主机代码确实工作;我一直在成功地将它与更简单的内核一起使用。现在,这里的内核是这样的:
__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE |
CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
__kernel void sharpening(__read_only image2d_t inputImg, __write_only image2d_t outputImg) {
int2 coord0 = (int2)(get_global_id(0), get_global_id(1));
float matrix[9] = { -1.0f, -1.0f, -1.0f, -1.0f, 9.0f, -1.0f, -1.0f, 1.0f, 1.0f };
float gray = 0.0f;
int k = 0;
for (int y = -1; y <= 1; ++y) {
for (int x = -1; x <= 1; ++x) {
int2 coord = coord0 + (int2)(x, y);
float4 color = read_imagef(inputImg, sampler, coord);
gray += (matrix[k] * ((color.x + color.y + color.z) / 3.0f));
++k;
}
}
gray = clamp(gray, 0.0f, 1.0f);
write_imagef(outputImg, coord0, (float4)(gray, gray, gray, 1));
}
为什么这个和CPU版本不一样?我想有一个我现在看不到的低级问题。我看过that question ,这让我担心我在这里遇到了类似的问题?
以防万一:我在 Surface Pro 2(即 Intel HD Graphics)上运行代码。
抱歉这么长的问题,希望有人能帮忙!
最佳答案
好吧,抱歉,显然这只是一个愚蠢的错误:OpenCL 内核中的过滤器矩阵是错误的,即与 CPU 版本不同,因此存在亮度差异。
关于仅关于 32bpp 或整数/ float 问题的谣言:是的,在 OpenCL 中可能有 8bpp 灰度图像。格式必须是CL_UNORM_INT8
,这意味着像素必须通过read_imagef
读取。读取内核中的像素总是返回具有四个分量的 vector 这一事实并不意味着图像总是 32bpp。它可能在内部看起来是这样表示的,但也可以从 8bpp 灰度图像中输入或读取 - 我问题中的代码证明了这一点。
关于c++ - 图像过滤器 : Results with OpenCL differ from CPU version,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22755727/
我知道这类问题已经得到解答,但就我而言,我已经尝试了所有配置,但仍然不起作用。我需要对我的配置有一个新的看法(我确信我错过了一些东西)。两个附加程序都会记录所有级别 我想将所有包的信息 >= 记录到控
我正在对 Windows 移动设备上的代码性能进行一些基准测试,并注意到某些算法在某些主机上的表现明显更好,而在其他主机上则明显更差。当然,考虑到时钟速度的差异。 供引用的统计数据(所有结果均由同一个
我有一个程序可以计算多边形的面积和周长。程序还会确认面积和周长的计算结果是否与预期结果相同。 我不明白发生了什么,但确认面积和周长是否与预期相同的验证部分无法正常工作。 例如,我现在测试并在所有情况下
Codepen :(对于那些想直接进入的人来说,这是一个代码笔。在 Chrome 和 IE 中尝试一下,看看结果的不同) 我正在尝试使用 css3 转换/过渡,因为它们比 jquery 效果更流畅。
我有几个不同的正则表达式要在给定文本中匹配和替换。 regex1 :如果文本包含单词“Founder”,则将所有文本替换为首席执行官 正则表达式2:如果文本包含9位数字,则将其替换为NUM 我尝试使用
我编写了多线程应用程序,它从每个线程的数据库连接到一些电子邮件帐户。我知道 JavaMail 没有任何选项可以使用 SOCKS5 进行连接,因此我决定通过 System.setProperty 方法使
如您所见,这是我当前 Storyboard的不同设备预览。底部的透明绿色被另一个 View Controller 占用,但需要为每个不同的尺寸类固定间距。我尝试将 Storyboard 中的宽度和高度
我正在创建一个游戏,我需要能够改变玩家 Sprite 的速度。我认为最好的选择是通过重力影响 Sprite 。为了给用户运动的感觉,我希望背景以完全相同的速度向相反的方向移动。 我怎样才能给背景一个不
我正在查看BTrees库并注意到有多个 TreeSet (和其他)类,例如 BTrees.IOBTree.TreeSet BTrees.OOBTree.TreeSet BTrees.LFBTree.T
我有一个小型 C++ 库,必须为 armeabi 和 armeabi7a 编译。我还有一个非常大的 c++ 库,只需要为 armeabi 编译。现在正在为两种架构编译它们(使用 NDK),但这使我的
我需要根据站点的当前部分稍微更改主题。 似乎 MuiThemeProvider 只在加载时设置 muiTheme;但需要在 props 变化时更新。 如何做到这一点? 最佳答案 您可以尝试将主题放在包
如何创建两个每个都有自己的计数器的 lSTListing 环境? 如果我使用例如 \lstnewenvironment{algorithm}[2]{ \renewcommand\lstlist
我想使用 Travis-CI 和 Github 基于分支设置部署。 IE。 - 如果我们从 develop 构建- 然后执行 /deploy.rb使用 DEV 环境主机名,如果 master - 然后
我有一个带有数据验证的 WPF MVVM 数据表单窗口。很多控件都是文本框。目前,数据绑定(bind)触发器设置为默认值,即。 e.失去焦点。这意味着仅在可能完全填写字段时才对其进行验证。所以当删除一
我有许多应用程序的内容页面,并最终为每个内容页面编写了很多 View 模型。例如。如果我有一个包含项目组的列表,我将有一个 ShowAllViewModel并绑定(bind)到内容页面和列表中单个项目
我有一个通用 View 和 4 个其他 View 。我在通用 View 中使用 Bootstrap 选项卡(导航选项卡)。我希望其他 4 个 View 成为通用 View 中 4 个选项卡的内容。由于
我希望针对 Maven 发布插件的不同目标有不同的配置选项。故事是这样的: 我正在将 Git 用于 SCM。我希望release:prepare插件在本地完成所有操作,并让release:perfor
我正在为一个项目使用AbstractTableModel制作一个自定义TableModel,并且我需要找到一种方法让复选框显示在某些行上,而不是其他行上。我已经实现了 getColumn 方法,但我希
摘自《Javascript 忍者的 secret 》一书: EVENTS ARE ASYNCHRONOUS Events, when they happen, can occur at unpredi
我正在尝试配置我的第一个 GWT 记录器,到目前为止,我已经将日志消息打印到我的 JS 控制台(FF 的 Firebug): 最终,我希望非SEVERE 消息转到consoleHa
我是一名优秀的程序员,十分优秀!