【发布时间】:2010-11-11 12:36:45
【问题描述】:
我希望能够以相对较快的速度拍摄图像并对其进行模糊处理(例如 0.1 秒)。图片尺寸几乎永远不会大于 256 x 256 像素。
我是否必须遍历每个像素并与相邻像素进行平均,还是有更高级别的方法可以做到这一点?
PS:我知道多个框模糊可以近似于高斯模糊。
【问题讨论】:
标签: ios image-processing blur
我希望能够以相对较快的速度拍摄图像并对其进行模糊处理(例如 0.1 秒)。图片尺寸几乎永远不会大于 256 x 256 像素。
我是否必须遍历每个像素并与相邻像素进行平均,还是有更高级别的方法可以做到这一点?
PS:我知道多个框模糊可以近似于高斯模糊。
【问题讨论】:
标签: ios image-processing blur
您可能想看看 Mario Klingemann 的 StakBlur 算法。它不是高斯分布,但非常接近。
【讨论】:
这里有两个解决穷人模糊的技巧:
拍摄图像,以部分不透明度绘制 5 或 6 次(或任意多次),每次在不同方向偏移几个像素。在更多方向上绘制更多次可以让您获得更好的模糊效果,但您显然会权衡处理时间。如果您想要半径相对较小的模糊,这很有效。
对于单色图像,您实际上可以使用内置阴影作为简单的模糊。
【讨论】:
如果您总是或至少经常使用相同的模糊设置,您可能会通过在频域而不是空间域中进行过滤来提高速度。
这种方法的优点是与平均邻域相比,逐像素乘法应该非常快。因此,如果您处理大量图像,这可能会有所帮助。
缺点是我不知道在 iPhone 上执行傅立叶变换的速度有多快,所以这很可能比其他实现慢得多。
除此之外,我猜由于 iPhone 支持 OpenGL,您也许可以使用它的纹理功能/绘图来做到这一点。很抱歉,虽然我不是 OpenGL 专家,也不能真正给出任何实用的建议。
【讨论】:
任何通过 OpenGL 在像素级别上修改图像的算法都会有点慢;对 OpenGL 纹理进行逐像素操作,然后每帧更新它,遗憾的是性能不足。
在实施复杂的模糊例程之前,请花一些时间编写测试装置并尝试像素操作。
【讨论】:
来自how-do-i-create-blurred-text-in-an-iphone-view:
查看 Apple 的 GLImageProcessing iPhone 示例。除其他外,它会进行一些模糊处理。
相关代码包括:
static void blur(V2fT2f *quad, float t) // t = 1
{
GLint tex;
V2fT2f tmpquad[4];
float offw = t / Input.wide;
float offh = t / Input.high;
int i;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);
// Three pass small blur, using rotated pattern to sample 17 texels:
//
// .\/..
// ./\\/
// \/X/\ rotated samples filter across texel corners
// /\\/.
// ../\.
// Pass one: center nearest sample
glVertexPointer (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f(1.0/5, 1.0/5, 1.0/5, 1.0);
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Pass two: accumulate two rotated linear samples
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
for (i = 0; i < 4; i++)
{
tmpquad[i].x = quad[i].s + 1.5 * offw;
tmpquad[i].y = quad[i].t + 0.5 * offh;
tmpquad[i].s = quad[i].s - 1.5 * offw;
tmpquad[i].t = quad[i].t - 0.5 * offh;
}
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].x);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].s);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, tex);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR);
glColor4f(0.5, 0.5, 0.5, 2.0/5);
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Pass three: accumulate two rotated linear samples
for (i = 0; i < 4; i++)
{
tmpquad[i].x = quad[i].s - 0.5 * offw;
tmpquad[i].y = quad[i].t + 1.5 * offh;
tmpquad[i].s = quad[i].s + 0.5 * offw;
tmpquad[i].t = quad[i].t - 1.5 * offh;
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Restore state
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Half.texID);
glDisable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glDisable(GL_BLEND);
}
【讨论】:
最基本的模糊(或者更多的柔化)是平均 2 个相邻像素并将平均值应用于两个像素。在整个图像中重复此操作,您会得到轻微的模糊(柔化)。
【讨论】:
我为 iOS3.2+ 应用程序找到了一个非常快速但非常糟糕的方法
UIView *myView = [self view];
CALayer *layer = [myView layer];
[layer setRasterizationScale:0.25];
[layer setShouldRasterize:YES];
这会将视图光栅化为 4x4 像素块,然后使用双线性过滤将其放大……如果您只是想在模态视图下模糊背景视图,它的速度非常快而且看起来还不错。
要撤消它,只需将光栅化比例设置回 1.0 或关闭光栅化。
【讨论】: