# 双边滤波算法原理：

mark下双边滤波里的两个权重域的概念：空间域（spatial domain S）和像素范围域（range domain R）,这个是它跟高斯滤波等方法的最大不同点。下面是我找到的对比说明，更好地理解双边滤波，首先是高斯滤波的情况：

# 双边滤波算法实现：

matlab实现方法，这里也附一下核心代码：

function output = bilateralFilter( data, edge, sigmaSpatial, sigmaRange, ...
samplingSpatial, samplingRange )

if ~exist( 'edge', 'var' ),
edge = data;
end

inputHeight = size( data, 1 );
inputWidth = size( data, 2 );

if ~exist( 'sigmaSpatial', 'var' ),
sigmaSpatial = min( inputWidth, inputHeight ) / 16;
end

edgeMin = min( edge( : ) );
edgeMax = max( edge( : ) );
edgeDelta = edgeMax - edgeMin;

if ~exist( 'sigmaRange', 'var' ),
sigmaRange = 0.1 * edgeDelta;
end

if ~exist( 'samplingSpatial', 'var' ),
samplingSpatial = sigmaSpatial;
end

if ~exist( 'samplingRange', 'var' ),
samplingRange = sigmaRange;
end

if size( data ) ~= size( edge ),
error( 'data and edge must be of the same size' );
end

% parameters
derivedSigmaSpatial = sigmaSpatial / samplingSpatial;
derivedSigmaRange = sigmaRange / samplingRange;

paddingXY = floor( 2 * derivedSigmaSpatial ) + 1;
paddingZ = floor( 2 * derivedSigmaRange ) + 1;

% allocate 3D grid
downsampledWidth = floor( ( inputWidth - 1 ) / samplingSpatial ) + 1 + 2 * paddingXY;
downsampledHeight = floor( ( inputHeight - 1 ) / samplingSpatial ) + 1 + 2 * paddingXY;
downsampledDepth = floor( edgeDelta / samplingRange ) + 1 + 2 * paddingZ;

gridData = zeros( downsampledHeight, downsampledWidth, downsampledDepth );
gridWeights = zeros( downsampledHeight, downsampledWidth, downsampledDepth );

% compute downsampled indices
[ jj, ii ] = meshgrid( 0 : inputWidth - 1, 0 : inputHeight - 1 );

di = round( ii / samplingSpatial ) + paddingXY + 1;
dj = round( jj / samplingSpatial ) + paddingXY + 1;
dz = round( ( edge - edgeMin ) / samplingRange ) + paddingZ + 1;

% perform scatter (there's probably a faster way than this)
% normally would do downsampledWeights( di, dj, dk ) = 1, but we have to
% perform a summation to do box downsampling
for k = 1 : numel( dz ),

dataZ = data( k ); % traverses the image column wise, same as di( k )
if ~isnan( dataZ  ),

dik = di( k );
djk = dj( k );
dzk = dz( k );

gridData( dik, djk, dzk ) = gridData( dik, djk, dzk ) + dataZ;
gridWeights( dik, djk, dzk ) = gridWeights( dik, djk, dzk ) + 1;

end
end

% make gaussian kernel
kernelWidth = 2 * derivedSigmaSpatial + 1;
kernelHeight = kernelWidth;
kernelDepth = 2 * derivedSigmaRange + 1;

halfKernelWidth = floor( kernelWidth / 2 );
halfKernelHeight = floor( kernelHeight / 2 );
halfKernelDepth = floor( kernelDepth / 2 );

[gridX, gridY, gridZ] = meshgrid( 0 : kernelWidth - 1, 0 : kernelHeight - 1, 0 : kernelDepth - 1 );
gridX = gridX - halfKernelWidth;
gridY = gridY - halfKernelHeight;
gridZ = gridZ - halfKernelDepth;
gridRSquared = ( gridX .* gridX + gridY .* gridY ) / ( derivedSigmaSpatial * derivedSigmaSpatial ) + ( gridZ .* gridZ ) / ( derivedSigmaRange * derivedSigmaRange );
kernel = exp( -0.5 * gridRSquared );

% convolve
blurredGridData = convn( gridData, kernel, 'same' );
blurredGridWeights = convn( gridWeights, kernel, 'same' );

% divide
blurredGridWeights( blurredGridWeights == 0 ) = -2; % avoid divide by 0, won't read there anyway
normalizedBlurredGrid = blurredGridData ./ blurredGridWeights;
normalizedBlurredGrid( blurredGridWeights < -1 ) = 0; % put 0s where it's undefined
blurredGridWeights( blurredGridWeights < -1 ) = 0; % put zeros back

% upsample
[ jj, ii ] = meshgrid( 0 : inputWidth - 1, 0 : inputHeight - 1 ); % meshgrid does x, then y, so output arguments need to be reversed
% no rounding
di = ( ii / samplingSpatial ) + paddingXY + 1;
dj = ( jj / samplingSpatial ) + paddingXY + 1;
dz = ( edge - edgeMin ) / samplingRange + paddingZ + 1;

% interpn takes rows, then cols, etc
% i.e. size(v,1), then size(v,2), ...
output = interpn( normalizedBlurredGrid, di, dj, dz );

# 双边滤波算法实例：

%% 测试函数，其中参数设置请参见函数注释
clc,clear all,close all;
ori=double(rgb2gray(ori))/255.0;
[width, height]=size(ori);
sigmaSpatial  = min( width, height ) / 30;
samplingSpatial=sigmaSpatial;
sigmaRange = ( max( ori( : ) ) - min( ori( : ) ) ) / 30;
samplingRange= sigmaRange;
output = bilateralFilter( ori, ori, sigmaSpatial, sigmaRange, ...
samplingSpatial, samplingRange );
figure,
subplot(1,2,1),imshow(ori,[]);title('input image');
subplot(1,2,2),imshow(output,[]);title('output image');

1. https://en.wikipedia.org/wiki/Bilateral_filtering
2. http://people.csail.mit.edu/sparis/bf_course/
3. http://people.csail.mit.edu/sparis/bf/
4. http://blog.csdn.net/fightingforcv/article/details/52723376
5. http://blog.csdn.net/mumusan2016/article/details/54578038
6. http://blog.csdn.net/majinlei121/article/details/50463514
7. http://kaiminghe.com/eccv10/index.html  （Guided Image Filtering
8. http://blog.csdn.net/dangchangying/article/details/14451963

05-30 12万+

11-26 3908

09-23 1万+

05-15 2万+

03-23 8102

08-25 534

05-04 1万+

08-18 1万+

10-28 2万+

03-26 4万+

01-05 1万+

10-29 1万+

10-12 1万+

04-10 789

12-18 2万+

01-05 8305

10-30 1万+

01-08 4983

06-23 356

11-11 17万+

04-07 3万+

11-25 831

06-12 740

01-01 5万+

05-02 1215

03-23 2万+

03-27 1万+

06-21 7107

03-25 4万+

02-06 19万+

04-17 5万+

04-30 3万+

07-26 4392

03-08 2万+

03-08 2万+

03-19 4万+

01-16 6909

05-13 2204

03-22 5万+

04-07 6万+

05-07 3万+

12-19 7792

11-04 205

01-05 4150

10-30 3万+

10-10 426

07-15 416

10-30 17万+

03-07 1万+

09-06 2842

03-11 2万+

08-01 7289

03-13 4979

03-23 4万+

02-11 1万+

03-21 1037

08-22 1万+

05-03 7299

04-17 9703

02-17 8891

12-25 1万+

03-26 4万+

03-09 5066

10-30 9万+

09-26 198

03-18 8865

05-06 4万+

09-23 65

08-27 9万+

08-24 930

11-06 14万+

03-10 2万+

05-08 5万+

03-16 10万+

01-21 28万+

#### Java校招入职华为，半年后我跑路了

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客