如何实现iOS上框或高斯模糊如何实现iOS上框或高斯模糊(How to implement a bo

2019-05-12 22:29发布

我希望能够拍摄图像和相对快速地对其进行模糊处理(说在0.1秒)。 图像大小几乎从不会是大于256×256像素。

我一定要环通每一个像素,并与邻居取它们的平均值或者是有更高级别的办法,我能做到这一点?

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

Answer 1:

我发现了一个非常快非常糟糕的方式为iOS3.2 +应用程序

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

这种光栅化视图到4×4像素块,然后使用双线性过滤扩展回来了......这是非常快,看起来不错,如果你只是想模糊下一个模态视图背景视图。

要取消它,只需设置光栅化规模回到1.0或关闭光栅化。



Answer 2:

从怎么办,我创建模糊的文本,在-AN-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);
}


Answer 3:

如果你总是或至少经常使用相同的模糊设置你可能会做在频域而不是空间域滤波获得速度。

  1. Precaclulate您的滤波图像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的专家,真的不能给任何实际的意见,如何做到这一点。



Answer 4:

这里有两个技巧对穷人的模糊:

  1. 取图像,在不同的方向在部分不透明度5或6(或然而,许多要)次,每次offseting绘制它由一对像素。 在多个方向上吸引更多的时间让你更好的模糊,但你显然折衷处理时间。 如果你想用一个相对较小半径的模糊这种运作良好。

  2. 对于单色图像,实际上你可以在阴影使用构建一个简单的模糊。



Answer 5:

你可能想看看马里奥·克林格曼的StakBlur算法。 这不是很高斯,但八九不离十。



Answer 6:

上通过OpenGL像素级modifys图像的任何算法将是慢一点点; 像素的逐像素上的openGL的纹理操作,然后更新它的每一个帧是在可悲-足够的性能。

花一些时间编写一个测试台,并致力于实现一个复杂的模糊程序之前与像素处理试验。



Answer 7:

非常基本的模糊的(或者更多的是软化),是平均2个相邻像素和平均同时适用于像素。 这个迭代整个图像,你会得到一个轻微的模糊(柔和)。



文章来源: How to implement a box or gaussian blur on iOS