% SOLVEINTEG
%
% This function is used by INTEGGAUSFILT to solve for the multiple averaging
% filter widths needed to approximate a Gaussian of desired standard deviation.
%
% Usage: [wl, wu, m, sigmaActual] = solveinteg(sigma, n)
%
% Arguments: sigma - Desired standard deviation of Gaussian. This should not
% be less than one.
% n - Number of averaging passes that will be used. I
% suggest using a value that is at least 4, use at least
% 5, perhaps 6 if you will be taking derivatives.
%
% Returns: wl - Width of smaller averaging filter to use
% wu - Width of larger averaging filter to use
% (Note wu = wl + 2 and wl is always odd)
% m - The number of filterings to be done with the smaller
% averaging filter. The number of filterings to be done
% with the larger filter is n-m
% sigmaActual - The actual standard deviation of the approximated
% Gaussian that is achieved.
%
% Note that the desired standard deviation will not be achieved exactly. A
% combination of different sized averaging filters are applied to approximate it
% as closely as possible. If n is 5 the deviation from the desired standard
% deviation will be at most about 0.15 pixels
%
% To acheive a filtering that approximates a Gaussian with the desired
% standard deviation perform:
% m filterings with an averaging filter of width wl, followed by
% n-m filterings with an averaging filter of width wu
%
% See also: INTEGGAUSSFILT, INTEGAVERAGE, INTEGRALIMAGE
% Copyright (c) 2009 Peter Kovesi
% www.peterkovesi.com/matlabfns/
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
%
% The Software is provided "as is", without warranty of any kind.
% September 2009
function [wl, wu, m, sigmaActual] = solveinteg(sigma, n)
if sigma < 0.8
warning('Sigma values below about 0.8 cannot be represented');
end
wIdeal = sqrt(12*sigma^2/n + 1); % Ideal averaging filter width
% wl is first odd valued integer less than wIdeal
wl = floor(wIdeal);
if ~mod(wl,2)
wl = wl-1;
end
% wu is the next odd value > wl
wu = wl+2;
% Compute m. Refer to the tech note for derivation of this formula
mIdeal = (12*sigma^2 - n*wl^2 - 4*n*wl - 3*n)/(-4*wl - 4);
m = round(mIdeal);
if m > n || m < 0
error('calculation of m has failed');
end
% Compute actual sigma that will be achieved
sigmaActual = sqrt((m*wl^2 + (n-m)*wu^2 - n)/12);
% fprintf('wl %d wu %d m %d actual sigma %.3f\n', wl, wu, m, sigmaActual);