snake.m

advertisement
function [snake_pnts,e] = snake(pnts, alpha, beta, max_delta_x, resol_x, ...
max_delta_y, resol_y, feat_img)
% SNAKES
% By Chris Bregler and Malcolm Slaney, Interval Technical Report IRC 1995-017
% Copyright (c) 1995 Interval Research Corporation.
%
% Usage
%
% [snake_pnts,e] = snake(pnts, alpha, beta, ...
%
max_delta_y, resol_y, max_delta_x, resol_x, feat_img)
%
% This function computes one iteration of the energy-minimization of
% active contour models described in the paper "Using Dynamic Programming
% for Solving Variational Problems in Vision" by Amir A. Amini, Terry E.
% Weymouth, and Ramesh C. Jain, IEEE Transactions on Pattern Analysis and
% Machine Intelligence, Vol. 12, No. 9, September 1990, pp 855-867.
%
% Snakes align a contour to some feature maxima in an image (for example)
% image boundaries) using dynamic programming. The quality of the
% alignment is measured by an energy function consisting of an internal
% "contour-smoothness-term" and an external feature term (equation 50 in the
% paper). Minimizing this energy term leads to a contour that trade offs
% these two criterias (smoothness + maximal feature responses) in some desired
% way.
%
% Inputs:
%
pnts
Starting contour. Each row is a [x,y] coordinate.
%
alpha
Energy contributed by the distance between control points.
%
Set to zero if length of slope doesn't matter.
%
beta
Energy contributed by the curvature of the snake. Larger
%
values of beta cause bends in the snake to have a high cost
%
and lead to smoother snakes.
%
max_delta_y
Max number of pixels to move each contour point vertically
%
resol_y
Contour points will be moved by multiples of resol_y
%
max_delta_x
Analog to max_delta_y
%
resol_x
Analog to resol_y
%
feat_img
2D-Array of the feature responses in the image. For example
%
it can contain the magnitude of the image gradients
%
% Outputs:
%
snake_pnts
New contour points.
%
e
Energy value of these new contour points
%
%
%
%
%
%
SNAKES - A MatLab MEX file to demonstrate snake contour-following.
This Software was developed by Chris Bregler and Malcolm Slaney of
Interval Research Corporation.
Copyright (c) 1995 Interval Research Corporation.
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
This is experimental software and is being provided to Licensee
'AS IS.' Although the software has been tested on a PowerMac
8100 running version 4.2c of MatLab with MEX support and on an
SGI running version 4.2c, Interval makes no warranties relating
to the software's performance on these or any other platforms.
Disclaimer
THIS SOFTWARE IS BEING PROVIDED TO YOU 'AS IS.' INTERVAL MAKES
NO EXPRESS, IMPLIED OR STATUTORY WARRANTY OF ANY KIND FOR THE
SOFTWARE INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY OF
PERFORMANCE, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT WILL INTERVAL BE LIABLE TO LICENSEE OR ANY THIRD
PARTY FOR ANY DAMAGES, INCLUDING LOST PROFITS OR OTHER INCIDENTAL
OR CONSEQUENTIAL DAMAGES, EVEN IF INTERVAL HAS BEEN ADVISED OF
THE POSSIBLITY THEREOF.
This software program is owned by Interval Research
Corporation, but may be used, reproduced, modified and
distributed by Licensee. Licensee agrees that any copies of the
software program will contain the same proprietary notices and
warranty disclaimers which appear in this software program.
if resol_y < 1; resol_y = 1; end;
if resol_x < 1; resol_x = 1; end;
n = size(pnts,1);
[row,col] = size(feat_img);
target = reshape(feat_img,row*col,1);
scan_y = -max_delta_y:resol_y:max_delta_y;
scan_x = -max_delta_x:resol_x:max_delta_x;
num_scan_y = size(scan_y,2);
num_scan_x = size(scan_x,2);
num_states = num_scan_y * num_scan_x;
fprintf('n = %d; num_states = %d; ',n,num_states);
delta_x
delta_y
delta_x
delta_y
=
=
=
=
ones(num_scan_y,1)*scan_x;
scan_y'*ones(1,num_scan_x);
reshape(delta_x,1,num_states);
reshape(delta_y,1,num_states);
states_x = round(pnts(:,1))*ones(1,num_states) + ones(n,1)*delta_x;
states_y = round(pnts(:,2))*ones(1,num_states) + ones(n,1)*delta_y;
% take care of boundary cases
states_x = min(max(states_x,1),col);
states_y = min(max(states_y,1),row);
states_i = (states_x-1)*row + states_y;
Smat = zeros(n,num_states^2);
Imat = zeros(n,num_states^2);
% forward pass
for v2 = 1:num_states,
Smat(1,(v2-1)*num_states+1:v2*num_states) = ...
-target(states_i(1,:))';
end;
for k = 2:n-1,
fprintf('.'); % debug
for v2 = 1:num_states, for v1 = 1:num_states,
v0_domain = 1:num_states;
[y,i] = min( Smat(k-1,(v1-1)*num_states+v0_domain) ...
+ alpha*k*( (states_x(k,v1)-states_x(k-1,v0_domain)).^2 ...
+ (states_y(k,v1)-states_y(k-1,v0_domain)).^2) ...
+ beta*k*( (states_x(k+1,v2)-2*states_x(k,v1) ...
+ states_x(k-1,v0_domain)).^2 ...
+ (states_y(k+1,v2)-2*states_y(k,v1) ...
+ states_y(k-1,v0_domain)).^2) );
Smat(k,(v2-1)*num_states+v1) = ...
y-target(states_i(k,v1));
Imat(k,(v2-1)*num_states+v1) = i;
end; end;
end;
for v1 = 1:num_states,
v0_domain = 1:num_states;
[y,i] = min( Smat(n-1,(v1-1)*num_states+v0_domain) ...
+ alpha*n*( (states_x(n,v1)-states_x(n-1,v0_domain)).^2 ...
+ (states_y(n,v1)-states_y(n-1,v0_domain)).^2));
Smat(n,v1) = y-target(states_i(n,v1));
Imat(n,v1) = i;
end;
[e,final_i] = min(Smat(n,1:num_states));
% backward pass
snake_pnts = zeros(n,2);
snake_pnts(n,:) = [states_x(n,final_i),states_y(n,final_i)];
v1 = final_i; v2 = 1;
for k=n-1:-1:1,
v = Imat(k+1,(v2-1)*num_states+v1);
v2 = v1; v1 = v;
snake_pnts(k,:) = [states_x(k,v1),states_y(k,v1)];
end;
fprintf('\n');
Download