perform_windowed_fourier_transform.m

来自「image denoising toolbox in matlab」· M 代码 · 共 210 行

M
210
字号
function y = perform_windowed_fourier_transform(x,w,q,n, options)% perform_windowed_fourier_transform - compute a local Fourier transform%% Forward transform:%   MF = perform_windowed_fourier_transform(M,w,q,n, options);% Backward transform:%   M  = perform_windowed_fourier_transform(MF,w,q,n, options);%%   w is the width of the window used to perform local computation.%   q is the spacing betwen each window.%%   MF(:,:,,i,j) contains the spectrum around point ((i-1)*q,(j-1)*q)+1.%%   A typical use, for an redundancy of 2x2 could be w=2*q+1%%   options.bound can be either 'per' or 'sym'%%   options.normalization can be set to%       'tightframe': tight frame transform, with energy conservation.%       'unit': unit norm basis vectors, usefull to do thresholding%%   Copyright (c) 2006 Gabriel Peyreoptions.null = 0;if size(x,3)>1    dir = -1;    if nargin<4        % assume power of 2 size        n = q*size(x,3);        n = 2^floor(log2(n));    endelse    dir = 1;    n = size(x,1);endif isfield(options, 'bound')    bound = options.bound;else    bound = 'sym';    bound = 'per';endif isfield(options, 'transform_type')    transform_type = options.transform_type;else    transform_type = 'fourier';endif isfield(options, 'normalization')    normalization = options.normalization;else    normalization = 'tightframe';end% perform samplingt = 1:q:n+1;[Y,X] = meshgrid(t,t);p = size(X,1);if mod(w,2)==1% w = ceil((w-1)/2)*2+1;    w1 = (w-1)/2;    t = -w1:w1;else    t = -w/2+1:w/2;end[dY,dX] = meshgrid(t,t);X = reshape(X,[1 1 p p]);Y = reshape(Y,[1 1 p p]);X = repmat( X, [w w 1 1] );Y = repmat( Y, [w w 1 1] );dX = repmat( dX, [1 1 p p] );dY = repmat( dY, [1 1 p p] );X1 = X+dX;Y1 = Y+dY;switch lower(bound)    case 'sym'        X1(X1<1) = 1-X1(X1<1);        X1(X1>n) = 2*n+1-X1(X1>n);        Y1(Y1<1) = 1-Y1(Y1<1);        Y1(Y1>n) = 2*n+1-Y1(Y1>n);    case 'per'        X1 = mod(X1-1,n)+1;        Y1 = mod(Y1-1,n)+1;end        % build a weight functionif isfield(options, 'window_type')    window_type = options.window_type;else    window_type = 'sin';endif isfield(options, 'eta')    eta = options.eta;else    eta = 1;endif strcmp(window_type, 'sin')    t = linspace(0,1,w);    W = sin(t(:)*pi).^2;    W = W * W';elseif strcmp(window_type, 'constant')    W = ones(w);else    error('Unkwnown winow.');endI = X1 + (Y1-1)*n;%% renormalize the windowsweight = zeros(n);for i=1:p    for j=1:p        weight(I(:,:,i,j)) = weight(I(:,:,i,j)) + W.^2;    endendweight = sqrt(weight);Weight = repmat(W, [1 1 p p]);for i=1:p    for j=1:p        Weight(:,:,i,j) = Weight(:,:,i,j) ./ weight(I(:,:,i,j));    endendif strcmp(normalization, 'unit')    if strcmp(transform_type, 'fourier')        % for Fourier it is easy        Renorm = sqrt( sum( sum( Weight.^2, 1 ), 2 ) )/w;    else        % for DCT it is less easy ...        % take a typical window in the middle of the image        weight = Weight(:,:,round(end/2),round(end/2));        % compute diracs        [X,Y,fX,fY] = ndgrid(0:w-1,0:w-1,0:w-1,0:w-1);        A = 2 * cos( pi/w * ( X+1/2 ).*fX ) .* cos( pi/w * ( Y+1/2 ).*fY ) / w;        A(:,:,1,:) = A(:,:,1,:) / sqrt(2); % scale zero frequency        A(:,:,:,1) = A(:,:,:,1) / sqrt(2);         A = A .* repmat( weight, [1 1 w w] );        Renorm = sqrt( sum( sum( abs(A).^2, 1 ),2  ) );    end    Renorm = reshape( Renorm, w,w );end    %% compute the transformif dir==1    y = zeros(eta*w,eta*w,p,p);    if mod(w,2)==1        m = (eta*w+1)/2; w1 = (w-1)/2;        sel = m-w1:m+w1;    else        m = (eta*w)/2+1; w1 = w/2;        sel = m-w1:m+w1-1;    end    y(sel,sel,:,:) = x(I) .* Weight;    % perform the transform    y = my_transform( y, +1, transform_type );    % renormalize if necessary    if strcmp(normalization, 'unit')        y = y ./ repmat( Renorm, [1 1 p p] );    endelse    if strcmp(normalization, 'unit')        x = x .* repmat( Renorm, [1 1 p p] );    end    x = my_transform( x, -1, transform_type );    x = real( x.*Weight );    y = zeros(n);    for i=1:p        for j=1:p            y(I(:,:,i,j)) = y(I(:,:,i,j)) + x(:,:,i,j);        end    endend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function y = my_transform(x,dir,transform_type)% my_transform - perform either FFT or DCT with energy conservation.%   Works on array of size (w,w,a,b) on the 2 first dimensions.w = size(x,1);if strcmp(transform_type, 'fourier')    % normalize for energy conservation    if dir==1        y = fftshift( fft2(x) ) / w;    else        y = ifft2( ifftshift(x*w) );    endelseif strcmp(transform_type, 'dct')    for i=1:size(x,3)        for j=1:size(x,4)            y(:,:,i,j) = perform_dct_transform(x(:,:,i,j),dir);        end    endelse    error('Unknown transform');end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?