关于Sylvain Paris ,Fr´edo Durand的快速双边滤波算法

2019-07-17 13:37发布

本帖最后由 lxzxj_chan 于 2015-10-23 12:07 编辑

这段代总体思路是什么,怎样实现双边滤波?




  1. %
  2. % output = bilateralFilter( data, edge, sigmaSpatial, sigmaRange, ...
  3. %                          samplingSpatial, samplingRange )
  4. %
  5. % Bilateral and Cross-Bilateral Filter
  6. %
  7. % Bilaterally filters the image 'data' using the edges in the image 'edge'.
  8. % If 'data' == 'edge', then it the normal bilateral filter.
  9. % Else, then it is the "cross" or "joint" bilateral filter.
  10. %
  11. % Note that for the cross bilateral filter, data does not need to be
  12. % defined everywhere.  Undefined values can be set to 'NaN'.  However, edge
  13. % *does* need to be defined everywhere.
  14. %
  15. % data and edge should be of the same size and greyscale.
  16. % (i.e. they should be ( height x width x 1 matrices ))
  17. %
  18. % data is the only required argument
  19. %
  20. % By default:
  21. % edge = data
  22. % sigmaSpatial = samplingSpatial = min( width, height ) / 16;
  23. % sigmaRange = samplingRange = ( max( edge( : ) ) - min( edge( : ) ) ) / 10
  24. %
  25. %

  26. % Copyright (c) <2007> <Jiawen Chen, Sylvain Paris, and Fredo Durand>
  27. %
  28. % Permission is hereby granted, free of charge, to any person obtaining a copy
  29. % of this software and associated documentation files (the "Software"), to deal
  30. % in the Software without restriction, including without limitation the rights
  31. % to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  32. % copies of the Software, and to permit persons to whom the Software is
  33. % furnished to do so, subject to the following conditions:
  34. %
  35. % The above copyright notice and this permission notice shall be included in
  36. % all copies or substantial portions of the Software.
  37. %
  38. % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  39. % IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  40. % FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  41. % AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  42. % LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  43. % OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  44. % THE SOFTWARE.
  45. %

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

  48. if ~exist( 'edge', 'var' ),
  49.     edge = data;
  50. end

  51. inputHeight = size( data, 1 );
  52. inputWidth = size( data, 2 );

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

  56. edgeMin = min( edge( : ) );
  57. edgeMax = max( edge( : ) );
  58. edgeDelta = edgeMax - edgeMin;

  59. if ~exist( 'sigmaRange', 'var' ),
  60.     sigmaRange = 0.1 * edgeDelta;
  61. end

  62. if ~exist( 'samplingSpatial', 'var' ),
  63.     samplingSpatial = sigmaSpatial;
  64. end

  65. if ~exist( 'samplingRange', 'var' ),
  66.     samplingRange = sigmaRange;
  67. end

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

  71. % parameters
  72. derivedSigmaSpatial = sigmaSpatial / samplingSpatial;
  73. derivedSigmaRange = sigmaRange / samplingRange;

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

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

  80. gridData = zeros( downsampledHeight, downsampledWidth, downsampledDepth );
  81. gridWeights = zeros( downsampledHeight, downsampledWidth, downsampledDepth );

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

  84. % ii =
  85. % 0 0 0 0 0
  86. % 1 1 1 1 1
  87. % 2 2 2 2 2

  88. % jj =
  89. % 0 1 2 3 4
  90. % 0 1 2 3 4
  91. % 0 1 2 3 4

  92. % so when iterating over ii( k ), jj( k )
  93. % get: ( 0, 0 ), ( 1, 0 ), ( 2, 0 ), ... (down columns first)

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

  97. % perform scatter (there's probably a faster way than this)
  98. % normally would do downsampledWeights( di, dj, dk ) = 1, but we have to
  99. % perform a summation to do box downsampling
  100. for k = 1 : numel( dz ),
  101.       
  102.     dataZ = data( k ); % traverses the image column wise, same as di( k )
  103.     if ~isnan( dataZ  ),
  104.         
  105.         dik = di( k );
  106.         djk = dj( k );
  107.         dzk = dz( k );

  108.         gridData( dik, djk, dzk ) = gridData( dik, djk, dzk ) + dataZ;
  109.         gridWeights( dik, djk, dzk ) = gridWeights( dik, djk, dzk ) + 1;
  110.         
  111.     end
  112. end

  113. % make gaussian kernel
  114. kernelWidth = 2 * derivedSigmaSpatial + 1;
  115. kernelHeight = kernelWidth;
  116. kernelDepth = 2 * derivedSigmaRange + 1;

  117. halfKernelWidth = floor( kernelWidth / 2 );
  118. halfKernelHeight = floor( kernelHeight / 2 );
  119. halfKernelDepth = floor( kernelDepth / 2 );

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

  126. % convolve
  127. blurredGridData = convn( gridData, kernel, 'same' );
  128. blurredGridWeights = convn( gridWeights, kernel, 'same' );

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

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

  140. % interpn takes rows, then cols, etc
  141. % i.e. size(v,1), then size(v,2), ...
  142. output = interpn( normalizedBlurredGrid, di, dj, dz );
复制代码

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
2条回答
lxzxj_chan
2019-07-17 17:46
haohaoren 发表于 2015-10-23 10:15
我觉得啊,作为一个提问题的人,应该不要那么懒,你提出一个问题,直接问人家怎么理解,你都没交代这个是什么问题,你都没告诉我你怎么理解的,我也没有义乌给你说吧,所以,我觉得现代人最大的问题啊,就是不懂得怎样虚心求教。

从我个人角度看,你这种学习态度,也很难学习很好吧!

好的,谢谢提醒

一周热门 更多>