Advertisement
Guest User

Untitled

a guest
Jul 12th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 3.61 KB | None | 0 0
  1. %  Solve:
  2. %                min_u  mu*TV(u)+1/2*||u-im||^2
  3. %   where "im" is a noisy image or any dimension (1D, 2D, 3D, or higher),
  4. %   and "TV" represents the total-variation seminorm.  This code forms the
  5. %   dual problem, which is of the form
  6. %         min_p || div(grad(p)) - im/mu ||^2
  7. %           subject to ||p||_infinity<=1
  8. %  Inputs:
  9. %    im      : An N-D array with noisy image data
  10. %    mu      : A scaling parameter that controls the strength of TV penalty
  11. %    opts    : Optional inputs to FASTA
  12. %
  13. %   For this code to run, the solver "fasta.m" must be in your path.
  14. %
  15. %   For more details, see the FASTA user guide, or the paper "A field guide
  16. %   to forward-backward splitting with a FASTA implementation."
  17. %
  18. %   Copyright: Tom Goldstein, 2014.
  19.  
  20. function [ denoised, outs ] = fasta_totalVariation( im, mu, opts )
  21.  
  22.  
  23. %  Check for 'opts'  struct
  24. if ~exist('opts','var') % if user didn't pass this arg, then create it
  25.     opts = [];
  26. end
  27.  
  28. %%  Define ingredients for FASTA
  29. %  Note: fasta solves min f(Ax)+g(x).
  30. %  f(z) = .5 ||z - (1.0/mu)*im||^2
  31. lim = (1.0/mu)*im;
  32. f    = @(z) .5*norm(z(:)-lim(:),'fro')^2;
  33. fgrad = @(z) z-lim;
  34. % g(z) = 0 for all feasible z, and infinity otherwise.  However, iterations
  35. % always end with a feasbile z, so we need not consider the infinity case.
  36. g = @(x) 0;
  37. gprox = @(z,t) projectIsotropic(z);%min(max(z,-1),1);
  38.  
  39.  
  40. %guess
  41. x0 = zeros(size(grad(im)));
  42.  
  43. %% Call solver
  44. [solution, outs] = fasta(@(x)div(x),@(x)grad(x),f,fgrad,g,gprox,x0,opts);
  45.  
  46. denoised =  im - div(solution)*mu;
  47.  
  48. end
  49.  
  50.  
  51. function g = projectIsotropic( g )
  52. dims = size(g);
  53. %  Find the norm of the gradient at each point in space
  54. normalizer = sqrt(sum(g.*g,ndims(g)));
  55. %  Create a normalizer that will shrink the gradients to have magnitude at
  56. %  most 1
  57. normalizer = max(normalizer,1);
  58. %  Make copies of this normalization so it can divide every entry in the
  59. %  gradient
  60. expander = ones(1,ndims(g));
  61. expander(end) = dims(end);
  62. normalizer = repmat(normalizer, expander);
  63. %  Perform the normalization
  64. g = g./normalizer;
  65. end
  66.  
  67. %  The gradient of an N-dimensional array. The output array has size
  68. %  [size(x) ndims(x)].  Note that this output array has one more dimension
  69. %  that the input array. This array contains all of the partial derivatives
  70. %  (i.e., forward first-order differences) of x.  The partial derivatives
  71. %  are indexed by the last dimension of the returned array.  For example,
  72. %  if x was 3 dimensional, the returned value of g has 4 dimensions.  The
  73. %  x-derivative is stored in g(:,:,:,1), the y-derivative is g(:,:,:,2),
  74. %  and the z-derivative is g(:,:,:,3).
  75. %   Note:  This method uses circular boundary conditions for simplicity.
  76. function [ g ] = grad( x )
  77.     numdims = ndims(x);
  78.     numEntries = numel(x);
  79.     g = zeros(numEntries*numdims,1);
  80.     for d = 1:numdims
  81.         shift = zeros(1,numdims);
  82.         shift(d) = 1;
  83.         delta = circshift(x,shift)-x;
  84.         g((d-1)*numEntries+1:d*numEntries) = delta(:);
  85.     end
  86.     g = reshape(g,[size(x), numdims]);
  87. end
  88.  
  89.  
  90. %  The divergence operator.  This method performs backward differences on
  91. %  the input vector x.  It then sums these differences, and returns an
  92. %  array with 1 dimension less than the input.  Note:  this operator is the
  93. %  adjoint/transpose of "grad."
  94. function [ out ] = div( x )
  95.     s = size(x);
  96.     dims = s(end);
  97.     outdims = s(1:end-1);
  98.     out = zeros(outdims);
  99.     x = x(:);
  100.     block = numel(out);
  101.     for d = 1:dims
  102.         slice = reshape(x(block*(d-1)+1:block*d), outdims);
  103.         shift = zeros(1,dims);
  104.         shift(d) = -1;
  105.         out = out + circshift(slice,shift)-slice;
  106.     end
  107. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement