问题如下,如何使用Box Blur / Extended Box Blur对给定STD的高斯模糊滤波器进行近似。
更具体地说,我知道这是Photoshop应用其高斯模糊的方式。
首先,可以在此处看到一篇关于“扩展框模糊”的文章 - Theoretical Foundations of Gaussian Convolution by Extended Box Filtering。
我遇到的问题是文章中的图2 解释这个的最好方法是使用一个例子。
假设我们需要近似高斯模糊,STD为15.4 - > Var = 237.16。
为了得到一个很好的近似值,我们将使用Box Blur的6次迭代来做到这一点。
现在,如何选择Box Blur的长度(我们将以可分离的方式进行,即以1D工作)?
我应该选择不同的长度(似乎我必须)?
目标是匹配GB的Blur级别(这是它的STD / VAR)。
谢谢。
P.S。
我正在研究MATLAB,所以代码很简单: - )。
答案 0 :(得分:0)
这是我在文章中的MATLAB实现:
```
function [ vBoxBlurKernel ] = GenerateBoxBlurKernel( boxBlurVar, numIterations )
% ----------------------------------------------------------------------------------------------- %
% [ boxBlurKernel ] = GenerateBoxBlurKernel( boxBlurVar, numIterations )
% Approximates 1D Gaussian Kernel by iterative convolutions of "Extended Box Filter".
% Input:
% - boxBlurVar - BoxFilter Varaiance.
% The variance of the output Box Filter.
% Scalar, Floating Point (0, inf).
% - numIterations - Number of Iterations.
% The number of convolution iterations in order
% to produce the output Box Filter.
% Scalar, Floating Point [1, inf), Integer.
% Output:
% - vBoxBlurKernel - Output Box Filter.
% The Box Filter with 'boxBlurVar' Variance.
% Vector, Floating Point, (0, 1).
% Remarks:
% 1. The output Box Filter has a variance of '' as if it is treated as
% Discrete Probability Function.
% 2. References: "Theoretical Foundations of Gaussian Convolution by Extended Box Filtering"
% 3. Prefixes:
% - 'm' - Matrix.
% - 'v' - Vector.
% TODO:
% 1. F
% Release Notes:
% - 1.0.001 07/05/2014 xxxx xxxxxx
% * Accurate calculation of the "Extended Box Filter" length as in
% the reference.
% - 1.0.000 06/05/2014 xxxx xxxxxx
% * First release version.
% ----------------------------------------------------------------------------------------------- %
boxBlurLength = sqrt(((12 * boxBlurVar) / numIterations) + 1);
boxBlurRadius = (boxBlurLength - 1) / 2;
% 'boxBlurRadiusInt' -> 'l' in the reference
boxBlurRadiusInt = floor(boxBlurRadius);
% boxBlurRadiusFrac = boxBlurRadius - boxBlurRadiusInt;
% The length of the "Integer" part of the filter.
% 'boxBlurLengthInt' -> 'L' in the reference
boxBlurLengthInt = 2 * boxBlurRadiusInt + 1;
a1 = ((2 * boxBlurRadiusInt) + 1);
a2 = (boxBlurRadiusInt * (boxBlurRadiusInt + 1)) - ((3 * boxBlurVar) / numIterations);
a3 = (6 * ((boxBlurVar / numIterations) - ((boxBlurRadiusInt + 1) ^ 2)));
alpha = a1 * (a2 / a3);
ww = alpha / ((2 * boxBlurRadiusInt) + 1 + (2 * alpha));
% The length of the "Extended Box Filter".
% 'boxBlurLength' -> '\Gamma' in the reference.
boxBlurLength = (2 * (alpha + boxBlurRadiusInt)) + 1;
% The "Single Box Filter" with Varaince - boxBlurVar / numIterations
% It is normalized by definition.
vSingleBoxBlurKernel = [ww, (ones(1, boxBlurLengthInt) / boxBlurLength), ww];
% vBoxBlurKernel = vBoxBlurKernel / sum(vBoxBlurKernel);
vBoxBlurKernel = vSingleBoxBlurKernel;
% singleBoxKernelVar = sum(([-(boxBlurRadiusInt + 1):(boxBlurRadiusInt + 1)] .^ 2) .* boxBlurKernel)
% boxKernelVar = numIterations * singleBoxKernelVar
for iIter = 2:numIterations
vBoxBlurKernel = conv2(vBoxBlurKernel, vSingleBoxBlurKernel, 'full');
end
end
这是一个尝试它的演示:
% Box Blur Demo
gaussianKernelStd = 9.6;
gaussianKernelVar = gaussianKernelStd * gaussianKernelStd;
gaussianKernelRadius = ceil(6 * gaussianKernelStd);
gaussianKernel = exp(-([-gaussianKernelRadius:gaussianKernelRadius] .^ 2) / (2 * gaussianKernelVar));
gaussianKernel = gaussianKernel / sum(gaussianKernel);
boxBlurKernel = GenerateBoxBlurKernel(gaussianKernelVar, 6);
boxBlurKernelRadius = (length(boxBlurKernel) - 1) / 2;
figure();
plot([-gaussianKernelRadius:gaussianKernelRadius], gaussianKernel, [-boxBlurKernelRadius:boxBlurKernelRadius], boxBlurKernel);
sum(([-boxBlurKernelRadius:boxBlurKernelRadius] .^ 2) .* boxBlurKernel)
sum(([-gaussianKernelRadius:gaussianKernelRadius] .^ 2) .* gaussianKernel)
棘手的部分是计算"扩展盒过滤器的有效长度" 使用常规" Box Filter"的方差计算长度不是长度。
文章很棒,这种方法很棒。