0

UIImageに対して「スマート」ブラーを実行したいのですが、コンテンツはブラーされていますが、エッジはシャープのままです。

たとえば、これが私の元の画像です。

シャープなオリジナル画像

そして、このぼかしが適用された後に私が見たいものは次のとおりです。

ぼやけた画像

UIImageでこのような「スマート」ブラーを実行するにはどうすればよいですか?

4

1 に答える 1

7

ここで探しているブラーは、バイラテラルブラーと呼ばれます。標準のガウスぼかしとは異なり、周囲のピクセルの色は、中央のピクセルとの類似度に基づいて、中央のピクセルの色で平均化されます。これにより、オブジェクトの内部領域がぼやけますが、シャープな輪郭は維持されます。

私のオープンソースGPUImageフレームワークには、GPUImageBilateralFilterと呼ばれるこれを行うフィルターがあります。これは、画像に適用した場合の出力です(blurSizeを1.0、distanceNormalizationFactorを1.6を使用)。

両側ぼかしを使用してフィルタリングされたオレンジ

私の結果とあなたの目標の間には若干の違いがありますが、それはおそらく私が使用している特定の重み付けによるものです。ここでパラメータを微調整することにより、これを上記に近づけることができるはずです。

OpenCVにはバイラテラルブラーフィルターもあります。このフレームワークの外部で使用する場合は、ソースコードをフラグメントシェーダーに移動し、これを使用して独自のOpenGLES実装を構築できます。

 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;
 }
于 2013-01-23T20:37:03.557 に答える