perform_active_contour.m.svn-base

来自「fast marching method」· SVN-BASE 代码 · 共 203 行

SVN-BASE
203
字号
function D = perform_active_contour(D0, motion, options)% perform_active_contour - perform active contour resolution%%   D = perform_active_contour(D0, motion, options);%%   Level set implementation of various active contour, all related to%   motion by mean curvature.%%   The resolution is done by an explicit euler, the time sep is options.dt%   and should be quite small for stability. The maximum time is%   options.Tmax.%%   In the following, one denotes the curvature of the level sets of D as%       Curv(D) = div(grad(D)/|grad(D)|)%   and D' = d(D)/dt the time derivative.%%   motion can be:%       'mean': D' = |grad(D)| * Curv(D)%       'affine': D' = |grad(D)| * Curv(D)^(1/3)%       'errosion': D' = |grad(D)| * max(Curv(D),0)^(1/3)%       'snakes': D' = E * |grad(D)| * Curv(D) + <grad(E),grad(D)>%       'chan-vese': D' = |grad(D)| * ( Curv(D) - lambda*(D-c1)^2 + lambda*(D-c2)^2 )%%   You can provide the parameters in options.E, options.c1, options.c2,%   options.lambda. You can turn on the automatic update of c1/c2 using%   options.update_c.%%   The distance function D is redistanced every options.redistance_freq%   iterations.%%   To turn off the display, options.do_display=0. You can provide a%   background image in options.M.%%   See also: display_segmentation.%%   Copyright (c) 2007 Gabriel eyredt              = getoptions(options, 'dt', 1000);Tmax            = getoptions(options, 'Tmax', 1000);do_display      = getoptions(options, 'display', 1);display_freq    = getoptions(options, 'display_freq', 20);redistance_freq = getoptions(options, 'redistance_freq', 30);lambda          = getoptions(options, 'lambda', 0.8);update_c        = getoptions(options, 'update_c', 1);c1              = getoptions(options, 'c1', 0.1);c2              = getoptions(options, 'c2', 0.8);nb_svg          = getoptions(options, 'nb_svg', 0);solver          = getoptions(options, 'solver', 'cg');svg_path        = getoptions(options, 'svg_path', ''); % ['results/active-contour/' motion '/']);if strcmp(motion,'chan-vese') || strcmp(motion, 'snake') || strcmp(motion, 'chan-vese-user')    E           = getoptions(options, 'E', 0, 1);else    E = [];endM               = getoptions(options, 'M', E(:,:,1));options.bound = 'per';if not(isempty(svg_path)) && not(exist(svg_path))    mkdir(svg_path);endnb_phase = 1;if not(isempty(E))    nb_phase = 2 - (size(E,3)==1);end    if strcmp(motion, 'snake')    % pre compute gradient of the energy    dE = divgrad(E,options);endD = D0;n = size(D0,1);epsilon = 1e-3;niter = round(Tmax/dt);if nb_svg>0    % distribute more svg at the begining of the iterations    svg_list = round( 1 + linspace(0,1,nb_svg+2).^3*niter ); svg_list(1) = [];        % delta_svg = niter/nb_svg;    if not(exist(svg_path))        mkdir(svg_path);    endelse    delta_svg = Inf;endnext_svg = 0;nb = 0;for i=1:niter    progressbar(i,niter);    for k=1:nb_phase        g0(:,:,:,k) = divgrad(D(:,:,k),options);        d(:,:,k) = max(epsilon, sqrt(sum(g0(:,:,:,k).^2,3)) );        g(:,:,:,k) = g0(:,:,:,k) ./ repmat( d(:,:,k), [1 1 2] );    end    if strcmp(solver, 'grad')        %%%% gradient %%%%        switch lower(motion)            case 'mean'                dD = d .* divgrad( g,options );            case 'affine'                gg = divgrad(g,options);                dD = d .* sign(gg) .* abs(gg).^(1/3);            case 'errosion'                dD = d .* max(divgrad(g,options),0).^(1/3);            case 'snake'                dD = E .* d .* divgrad( g,options ) + sum(dE.*g0, 3);            case 'chan-vese'                % compute the inner / outer constant                if update_c                    c1 = mean( E(D>=0) );                    c2 = mean( E(D<0) );                end                dD = d .* ( divgrad( g,options ) - lambda*(E-c1).^2 + lambda*(E-c2).^2 );            case 'chan-vese-user'                if nb_phase==1                    % single phase                    dD = d .* ( divgrad( g,options ) + E );                else                    for k=1:nb_phase                        dG = divgrad( g(:,:,:,k),options );                        dD(:,:,k) = d(:,:,k) .* ( dG - E(:,:,2*k-1).*(D(:,:,3-k)>0) - E(:,:,2*k).*(D(:,:,3-k)<=0)  );                    end                                    end            otherwise                error('Unknown motion');        end        D = D + dt*dD;    else        options.E = [];        switch lower(motion)            case 'mean'                C = zeros(n);            case 'snake'                options.E = E;                C = sum(dE.*g0, 3);            case 'chan-vese'                % compute the inner / outer constant                if update_c                    c1 = mean( E(D>=0) );                    c2 = mean( E(D<0) );                end                C = - lambda*(E-c1).^2 + lambda*(E-c2).^2;            case 'chan-vese-user'                C = E;            otherwise                error('Unknown motion');        end                %%%% conjugate gradient %%%%        % right hand side        y = D + dt*C;        options.d = d;        options.dt = dt;        options.n = n; options.ncols = n^2;        options.niter_max = 20;        ptions.epsilon = 1e-8;        options.x = D(:);        [D,err,k] = perform_conjugate_gradient(@callback_active_contour,y(:),options);        D = reshape(D,n,n);    end            if mod(i,redistance_freq)==0        for k=1:nb_phase            D(:,:,k) = perform_redistancing(D(:,:,k), options);        end    end    if do_display && ( mod(i,display_freq)==1 || i>=next_svg )        A = prod(D,3);        if strcmp(motion, 'snake') || strcmp(motion, 'chan-vese') || strcmp(motion, 'chan-vese-user')            A = M;        end        clf;        display_segmentation(D,A);        drawnow;                if 0        clf;        hold on;        if strcmp(motion, 'snake') || strcmp(motion, 'chan-vese') || strcmp(motion, 'chan-vese-user')            imagesc(M); axis image; axis off; axis([1 n 1 n]);        else            imagesc(D); axis image; axis off; axis([1 n 1 n]);        end%        h = plot(c(1,:), c(2,:), 'r');        [c,h] = contour(D,[0 0], 'r');        set(h, 'LineWidth', 2);        drawnow;        hold off;        colormap gray(256);        end                if i>=next_svg            nb = nb+1;            % save image            saveas(gcf, [svg_path motion '-' num2string_fixeddigit(nb, 2) '.png'], 'png');            next_svg = svg_list(nb); % next_svg+delta_svg;        end    endend

⌨️ 快捷键说明

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