如何在iOS上实现方块或高斯模糊
image-processing
ios
11
0

我希望能够拍摄图像并使图像相对较快地模糊(例如在0.1秒内)。图片大小几乎永远不会大于256 x 256像素。

我是否必须遍历每个像素并将其与邻居平均,还是有更高的方法可以做到这一点?

PS :我知道多个框模糊可以近似为高斯模糊。

参考资料:
Stack Overflow
收藏
评论
共 5 个回答
高赞 时间 活跃

我为iOS3.2 +应用程序找到了一种非常快的糟糕方法

  UIView *myView = [self view];
  CALayer *layer = [myView layer];
  [layer setRasterizationScale:0.25];
  [layer setShouldRasterize:YES];

这样可以将视图栅格化为4x4像素块,然后使用双线性过滤将其缩放回原位...非常快,如果您只想在模态视图下模糊背景视图,则看起来还可以。

要撤消它,只需将栅格化比例设置回1.0或关闭栅格化。

收藏
评论

这是穷人模糊的两个技巧:

  1. 拍摄图像,每次以不透明度5或6(或您想要的许多不透明度)绘制一次,并在不同方向上偏移几个像素。在更多的方向上绘制更多的时间可以使您获得更好的模糊效果,但是显然您需要权衡处理时间。如果您想要半径较小的模糊效果,则此方法效果很好。

  2. 对于单色图像,实际上可以将内置阴影用作简单的模糊。

收藏
评论

我如何在iPhone的视图中创建模糊的文本:

看一下苹果的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);
}
收藏
评论

您可能想看看Mario Klingemann的StakBlur算法。它不是完全高斯的,但是非常接近。

收藏
评论

如果您始终或至少经常使用相同的模糊设置,则可以通过在频域而不是空间域中进行滤波来提高速度。

  1. 预先计算2D高斯滤波器图像G(u,v)
  2. 将傅立叶变换应用于输入图像f(x,y)-> F(u,v)
  3. 按乘法过滤:H(u,v)= F(u,v)。* G(u,v)(逐像素乘法,不是矩阵乘法)
  4. 通过逆傅立叶变换将滤波后的图像变换回空间域:H(u,v)-> h(x,y)

这种方法的优点是,与平均邻域相比,逐像素乘法应该非常快。因此,如果您处理大量图像,这可能会有所帮助。

缺点是我不知道您可以在iPhone上进行傅立叶变换的速度有多快,因此这可能比其他实现要慢得多。

除此之外,我猜想由于iPhone具有OpenGL支持,您可以使用其纹理功能/绘图来实现。抱歉地说我不是OpenGL专家,在完成过程中并不能给出任何实际建议。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题