File Exchange

image thumbnail

Snakes: Active Contour Models

version 1.0 (326 KB) by

Implements snakes or active contour models for image segmentation.

4.07143
15 Ratings

71 Downloads

Updated

View License

This demo implements the Active Contour Models as proposed by Kass et al.

To run it with GUI
1. Type guide on the matlab prompt.
2. Click on "Go to Existing GUI"
3. Select the snk.fig file in the same directory as this file
4. Click the green arrow at the top to launch the GUI

Once the GUI has been launched, you can use snakes by
1. Click on "New Image" and load an input image. Samples image are provided.
2. Set the smoothing parameter "sigma" or leave it at its default value and click "Filter". This will smooth the image.
3. As soon as you click "Filter", cross hairs would appear and using them and left click of you mouse you can pick initial contour location on the image. A red circle would appear everywhere you click and in most cases you should click all the way around the object you want to segment. The last point must be picked using a right-click in order to stop matlab for asking for more points.
4. Set the various snake parameters (relative weights of energy terms in the snake objective function) or leave them with their default value and click "Iterate" button. The snake would appear and move as it converges to its low energy state.

Copyright (c) Ritwik Kumar, Harvard University 2010
www.seas.harvard.edu/~rkkumar

This code implements “Snakes: Active Contour Models” by Kass, Witkin and Terzopolous incorporating Eline, Eedge and Eterm energy factors. See the included report and the paper to learn more.

If you find this useful, also look at Radon-Like Features based segmentation in the following paper:
Ritwik Kumar, Amelio V. Reina & Hanspeter Pfister, Radon-Like Features and their Application to Connectomics”, IEEE Computer Society Workshop on Mathematical Methods in Biomedical Image Analysis (MMBIA) 2010
http://seas.harvard.edu/~rkkumar
Its code is also available on MATLAB Central

Comments and Ratings (28)

Marlon

Marlon (view profile)

very useful,thank you

Samuel Geurts

For me, the 'double' problem was solved by taking grayscale images. The algorithm does not work for color images.

robber john

I used srad filter for speckle reduction in breast ultrasound images, during this process I converted the image into double and normalized it and for segmentation I am using active contour but I am having trouble in segmenting it as image is in double can anyone help?

Pim

Pim (view profile)

@anuja Initially, I had the same problem. Loading a uint8, .pgm image worked to solve the problem.

Rashid Hamid

Rashid Hamid

anuja

anuja (view profile)

I'm having the same problem as Susan and Somy. I tried using uint8 images as suggested by Deepak, but I still got the same error. Did any of you successfully try this on your own images? If yes, please help with this error.

Daniel

Daniel (view profile)

This algorithm looks like just what I need for a project I'm working on, but I'm having a problem in the step where interp2 executes. Specifically,

interp2(fx,xs,ys)

returns a vector where the interior elements are all NaN while the first few and last few are what could be reasonable values.

I'm feeding the function a solid binary block that has been converted to double (so all 1's are now 127 and all 0's are still 0), could this be a problem in that the gradient is very sudden?

ankita

ankita (view profile)

hi...can anyone please guide me how to get the segmented image as a separate plot after the snake has run....

jiyo

jiyo (view profile)

@ susan.. The image must be in grayscale..your's would've been a color image with 3rd dimension and hence the program fails

moha

moha (view profile)

jia jiankui

@Sean Lawson:
The problem is command "xys = spline(t,xy,ts);" in getsnake.m . Because spline may got the negative value ,when using iterp2(),it will become error. so we can avoid those using
xs=interp1(t,xy(1,:),ts);
ys=interp1(t,xy(2,:),ts); instead of

xs = xys(1,:)
ys = xys(2,:) and xys = spline(t,xy,ts);

Deepak

Deepak (view profile)

@somy : try changing ur input image datatype from double to uint8

Somy

Somy (view profile)

I am trying to use your program for my images, but i get the same error than Susan

Priyanka

Is there a way i can save the image after the snake is implemented? Please let me know. Thanks

Susan

Susan (view profile)

Hi, I am trying to see how well your program works for my MRI kidney images, but I keep getting an error. The GUI will load the image fine, but has a problem when I click filter. This is the error I get:

Undefined function 'conv2' for input arguments of type 'double'
and attributes 'full 3d real'.

Error in filter2 (line 60)
y = conv2(hcol, hrow, x, shape);

Error in filter_function (line 48)
smth = filter2(smask, image, 'same');
Error in snk>pushbutton1_Callback (line 357)
y = filter_function(handles.image,sigma_val); % smooths the
image

Error in gui_mainfcn (line 96)
feval(varargin{:});

Error in snk (line 85)
gui_mainfcn(gui_State, varargin{:});

Error while evaluating uicontrol Callback

Please help! Thanks!

Nathanael

Lacey

Lacey (view profile)

Great work, and thanks for commenting so well! I am looking to use your code, or something like it, to extract the contour of a face from the background. However, I don't want to have to do this manually for every face image. Is there a way to use your code to train a model on a few images, to then use on other images? I'd like to not have to manually click the points on the image every time.

Adam

Adam (view profile)

Good day
I am a student of Biomedical Engineering.

Should I request to you, I do not understand the function used Interam. The
specific location:

%masks for taking various derivatives
m1 = [-1 1];
m2 = [-1;1];
m3 = [1 -2 1];
m4 = [1;-2;1];
m5 = [1 -1;-1 1];

cx = conv2(smth,m1,'same');
cy = conv2(smth,m2,'same');
cxx = conv2(smth,m3,'same');
cyy = conv2(smth,m4,'same');
cxy = conv2(smth,m5,'same');

and

%populating the penta diagonal matrix
A = zeros(m,m);
b = [(2*alpha + 6 *beta) -(alpha + 4*beta) beta];
brow = zeros(1,m);
brow(1,1:3) = brow(1,1:3) + b;
brow(1,m-1:m) = brow(1,m-1:m) + [beta -(alpha + 4*beta)]; % populating a
template row
for i=1:m
A(i,: ) = brow;
brow = circshift(brow',1)'; % Template row being rotated to egenrate
different rows in pentadiagonal matrix
end

[L U] = lu(A + gamma .* eye(m,m));
Ainv = inv(U) * inv(L); % Computing Ainv using LU factorization

Many times I thank

Jeremy

Jeremy (view profile)

@ omar. The type of segmentation algorithm that you are describing is possible, but this program was not designed for it. I suggest you read about the gradient vector flow (GVF) on page 15 of "Biomedical Image Analysis: Segmentation" by Acton and Ray http://www.morganclaypool.com/doi/abs/10.2200/S00133ED1V01Y200807IVM009?prevSearch=allfield%253A%2528segmentation%2529&searchHistoryKey=

Additionally, I don't believe that the algorithm used in this program tries to minimize the area of the contour. Notice how the snake will expand to fill an area bounded by an edge.

Sean Lawson

I have the same problem as Fan Lin.

Also, in the eterm part in interation.m, I notice that the original paper gives the formula (discarded the i,j here): eterm = (cyy.*cx.*cx -2.*cxy.*cx.*cy + cxx.*cy.*cy)./((cx.*cx + cy.*cy).^1.5); while you are using: eterm = (cyy.*cx.*cx -2.*cxy.*cx.*cy + cxx.*cy.*cy)./((1 + cx.*cx + cy.*cy).^1.5), could you please explain a little bit why you have a "1+" part in the denominator? Thank you

omar

omar (view profile)

good work man, but I have a problem in using snakes algorithm.

what I want is to get the contour of a mountain given only the top of the mountain.
I tried it using your implementation and gave it the surrounding indices of the top pixel but it was keeping smaller and smaller till vanishing. I know that is the idea of the algorithm, minimizing the area of the snake.

I want to give it the surrounding pixels of the top of the mountain and the region grows up till the stoppage point.

Is what I want feasible?

Junghun

Fan Lin

Fan Lin (view profile)

sometimes it work,but sometimes something bad happen:

??? Subscript indices must either be real positive integers or logicals.

Error in ==> interp2>linear at 336
F = ( arg3(ndx).*(onemt) + arg3(ndx+1).*t ).*(1-s) + ...

Error in ==> interp2 at 215
zi = linear(ExtrapVal,x,y,z,xi,yi);

Error in ==> interate at 124
ssx = gamma*xs - kappa*interp2(fx,xs,ys);

Error in ==> snk>pushbutton2_Callback at 531
interate(handles.smth, handles.xs, handles.ys, alpha_val, beta_val, gamma_val, kappa_val,
weline_val, weedge_val, weterm_val, inter_val);

Error in ==> gui_mainfcn at 96
feval(varargin{:});

Error in ==> snk at 85
gui_mainfcn(gui_State, varargin{:});

Error in ==>
@(hObject,eventdata)snk('pushbutton2_Callback',hObject,eventdata,guidata(hObject))


??? Error while evaluating uicontrol Callback

Keith

Keith (view profile)

I received an error loading an image in the GUI using Mac OSX.

To fix this I removed the second argument of the strcat function on line 547 of snk.m - the '\' character.

Kirsty

Kirsty (view profile)

Quick point - you can speed up interate.m significantly if you take the expression for eterm out of the loop... i.e. replace with single calculation:

eterm = (cyy.*cx.*cx -2.*cxy.*cx.*cy + cxx.*cy.*cy)./((1+cx.*cx + cy.*cy).^1.5);

MATLAB Release
MATLAB 6.5 (R13)

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video