FRACTALMORPH - Fractal morphological decomposition.

Contents

Syntax

     S = FRACTALMORPH(I);

See also

Ressembles: FRACTALWAVE, Requires: FRACTALMORPH_BASE,

Function implementation

function [S, varargout] = fractalmorph(I, varargin)
if isempty(ver('images'))
    error('fractalmorph:errortoolbox', 'Image Processing toolbox required');
end

parsing parameters

error(nargchk(1, 35, nargin, 'struct'));
error(nargoutchk(0, 10, nargout, 'struct'));

% mandatory parameter
if ~isnumeric(I)
    error('fractalmorph:inputerror','a matrix is required in input');
end

% optional parameters
p = createParser('FRACTALMORPH');

% additional parameters regarding numerical estimation
p.addOptional('measure', 'oc', @(x)ischar(x) && ...
    any(strcmpi(x,{'o','c','oco','coc','co','co'...
    % 'rco','roc','ro','rc','roco','rcoc'
    })));

% principal scale parameters
p.addOptional('rho', [], @(x)isfloat(x) && length(x)>=1 && any(x)>=0);

% options for multiscale analysis
p.addParamValue('sc0', 1, @(x)isscalar(x) && x>0);  % output.sc0
p.addParamValue('scr', 10, @(x)isscalar(x) && x>0); % WAV_RANGE
p.addParamValue('scn', 7, @(x)isscalar(x) && x>1);  % WPOINTS
% minimum and maximum singularity values considered in the histogram
p.addParamValue('hmin', -1, @(x)isscalar(x) && isfloat(x) && x<=0);
p.addParamValue('hmax', 2, @(x)isscalar(x) && isfloat(x) && x>=0 );
p.addParamValue('hstep', 100, @(x)isscalar(x) && ...
    (isfloat(x) && x>0 && x<=1) || (x>1 && round(x)==x));
% goodness for singularity analysis regression
p.addParamValue('hcorr', 0.999, @(x)isscalar(x) && isfloat(x) && x>=0 && x<=1);
p.addParamValue('shape', 'disk', @(x) ischar(x) && ...
    any(strcmpi(x,{'disk','rectangle','square','diamond', ...
    'line','periodicline','arbitrary','octagon','pair'})));

% windex = 0
% ord_der = 0
% sc0 [0][0] = 1
% wavrange = 10
% wavpoints = 7
% scale_wavelet = sw / max(x,y)
% qs = wavrange^(1/(wavpoints-1))
% (sc=1, ip=0; ip<=wavpoints; ip++, sc=sc*qs)
% xx = 1 / log(sc * sc0)
% generate_wavelet_normalize at scale sc
% convolve(T)
% yy = log(abs(T))
% yy *= xx
% log(T) = log(alpha) + h*log(r)

% parse and validate all input arguments
p.parse(varargin{:});
p = getvarParser(p);

checking/setting parameters

C = size(I,3);
%n_x = X*Y;

% if ...
%         (strcmp(p.method,'grain') && ...
%         any(strcmp(p.measure,{'rocmax','ocmax','e','d','edmax'}))) || ...
%         (strcmp(p.method,'prof') && ...
%         any(strcmp(p.measure,{'oco','coc','co','rco','roco','rcoc'})))
%     error('fractalmorph:errorinput',...
%         ['incompatible method ' p.method ' and measure ' p.measure]);
% end

compute the multifractal decomposition

[S, Histoh, H, H_r, DH, ErrDh, scales, edges, Tpsi, R] = ...
    fractalmorph_base(I, p.measure, p.rho, p.sc0, p.scr, p.scn, ...
    p.hmin, p.hmax, p.hstep, p.shape);
% note: the last element of scales is sc0

if nargout>=2, varargout{1} = Histoh;
    if nargout>=3, varargout{2} = H;
        if nargout>=4, varargout{3} = H_r;
            if nargout>=5, varargout{4} = DH;
                if nargout>=6,  varargout{5} = ErrDh;
                    if nargout>=7, varargout{6} = scales;
                        if nargout>=8, varargout{7} = edges;
                            if nargout>=9,  varargout{8} = Tpsi;
                                if nargout==10,  varargout{9} = R;  end
                            end
                        end
                    end
                end
            end
        end
    end
end

display

if p.disp

    ndisp = 3; mdisp = ceil((length(scales)-1)/ndisp);

    % we distinguish the cases 'riemann' and 'scalar'
    if C>1
        n_x = numel(S{1});
        for c=1:C
            % display the wavelet transform
            figure % open a display window
            for r=1:length(scales)-1
                subplot(mdisp, ndisp, r),  imagesc(rescale(Tpsi{c}(:,:,r))),
                colormap gray, title(['WT at \sigma=' num2str(scales(r))])
            end
            S{c}(S{c}>p.hmax) = p.hmax;
            h0 = min(S{c}(:));     h1 = max(S{c}(:));
            %delta_h = 0.01;      range_h = (h1 - h0) / delta_h;
            % output range of singularities
            disp_sing = ['Singularity range for channel ' num2str(c)];
            disp([disp_sing ': [ ' num2str(h0) ' - ' num2str(h1) ' ]']);
            figure, % open another window
            % display the singularity exponents
            title_sing = ['singularity exponents for channel ' num2str(c)];
            subplot(1,2,1), imagesc(S{c}), axis image off, colormap gray,
            title(title_sing);
            % output regression rate
            disp_reg = ['Good regression points for channel ' num2str(c)];
            disp([disp_reg ': ' num2str(100*sum(abs(R{c}(:))>=p.hcorr)/n_x) ' %']);
            subplot(1,2,2),imagesc(abs(R{c})>=p.hcorr), axis image off, colormap gray,
            title('''good regression'' map');
            % display its histogram
            title_exp = ['exponents distribution for channel ' num2str(c)];
            figure, bar(edges,Histoh{c},'histc'), % hist(S{c}(:),range_h)
            title(title_exp)
            title_spec = ['multifractal spectrum for channel ' num2str(c)];
            figure, errorbar(H_r{c}, DH{c}, ErrDh{c}/2, ErrDh{c}/2), title(title_spec);
        end

    else
        n_x = numel(S);
        figure;
        for r=1:length(scales)-1
            subplot(mdisp, ndisp, r),  imagesc(rescale(Tpsi(:,:,r))),
            colormap gray, title(['WT at \sigma=' num2str(scales(r))]);
        end
        S(S>p.hmax) = p.hmax;
        h0 = min(S(:));    h1 = max(S(:));
        disp(['Singularity range: [ ' num2str(h0) ' - ' num2str(h1) ' ]']);
        figure, subplot(1,2,1), imagesc(S), axis image off, colormap gray,
        title('singularity exponents');
        disp(['Good regression points: ' ...
            num2str(100*sum(abs(R(:))>=p.hcorr) / n_x) ' %']);
        subplot(1,2,2), imagesc(abs(R)>=p.hcorr), axis image off, colormap gray,
        title('''good regression'' map');
        figure, bar(edges,Histoh,'histc'), title('exponents distribution');
        figure, errorbar(H_r, DH, ErrDh/2, ErrDh/2), title('multifractal spectrum');
    end
end
end % end of fractalmorph