如何模糊UIImage,但保留锐利的物体边界? [英] How do I blur a UIImage, but preserve sharp object boundaries?

查看:109
本文介绍了如何模糊UIImage,但保留锐利的物体边界?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对UIImage执行智能模糊,其中内容模糊,但边缘仍然清晰。

I would like to perform a "smart" blur to a UIImage, where the contents are blurred, but the edges remain sharp.

例如,这是我的原始图片:

For example, here is my original image:

以下是应用此模糊后我想看到的内容:

and here is what I would like to see after this blur is applied:

如何在UIImage上做这样的智能模糊?

How can I do a "smart" blur like this on a UIImage?

推荐答案

您在这里寻找的模糊被称为双边模糊。与标准高斯模糊不同,周围像素颜色基于它们与中心像素的相似程度与中心像素颜色平均。这模糊了对象的内部区域,但保留了清晰的轮廓。

The blur you're looking for here is called a bilateral blur. Unlike a standard Gaussian blur, surrounding pixel colors are averaged with the center pixel color based on how similar they are to the central pixel. This blurs interior regions of objects, but preserves a sharp outline.

在我的开源中 GPUImage 框架,我有一个过滤器来执行此操作,称为GPUImageBilateralFilter。这是应用于您的图像时的输出(使用blurSize为1.0且distanceNormalizationFactor为1.6):

In my open source GPUImage framework, I have a filter that does this, called a GPUImageBilateralFilter. This is the output of that when applied to your image (using a blurSize of 1.0 and a distanceNormalizationFactor of 1.6):

我的结果和你的目标之间有一些细微差别,但那是可能是由于我使用的具体权重。通过在这里调整参数,你应该能够更接近上面的那些。

There are some slight differences between my result and your target, but that's probably due to the specific weightings I use. By tweaking the parameters here, you should be able to get this closer to the above.

OpenCV也有双边模糊过滤器,你可以把源代码带到我的片段shader并使用它来构建自己的OpenGL ES实现,如果你想在这个框架之外使用它:

OpenCV also has bilateral blur filters, and you could take the source code to my fragment shader and use this to construct your own OpenGL ES implementation if you'd like to use it outside of this framework:

 uniform sampler2D inputImageTexture;

 const lowp int GAUSSIAN_SAMPLES = 9;

 varying highp vec2 textureCoordinate;
 varying highp vec2 blurCoordinates[GAUSSIAN_SAMPLES];

 uniform mediump float distanceNormalizationFactor;

 void main()
 {
     lowp vec4 centralColor;
     lowp float gaussianWeightTotal;
     lowp vec4 sum;
     lowp vec4 sampleColor;
     lowp float distanceFromCentralColor;
     lowp float gaussianWeight;

     centralColor = texture2D(inputImageTexture, blurCoordinates[4]);
     gaussianWeightTotal = 0.18;
     sum = centralColor * 0.18;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[0]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[1]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[2]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[3]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[5]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[6]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[7]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     sampleColor = texture2D(inputImageTexture, blurCoordinates[8]);
     distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
     gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);
     gaussianWeightTotal += gaussianWeight;
     sum += sampleColor * gaussianWeight;

     gl_FragColor = sum / gaussianWeightTotal;
 }

这篇关于如何模糊UIImage,但保留锐利的物体边界?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆