2013-01-22 66 views

回答

7

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

在我的开放源代码GPUImage框架中,我有一个过滤器可以做到这一点,称为GPUImageBilateralFilter。这是该输出时应用到图像(使用1.0 blurSize和1.6 distanceNormalizationFactor):

Filtered orange using a bilateral blur

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

OpenCV的也有双边模糊滤镜,你可以采取的源代码,我的片段着色器并使用它来构建自己的OpenGL ES的实现,如果你想使用它这个框架之外:

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; 
} 
+0

很棒的回答。喜欢包含开源项目和示例代码。 –

+0

@Brad Larson:谢谢我得到了解决方案 –

+0

@Brad Larson:我可以将滤镜效果单独应用于图像的特定部分吗?不适用于整个图像 假设我的图像宽度是320.所以,我想添加滤镜效果从60到70像素,然后从200-220像素单独。所以,滤镜效果并不适用于整个图像 –