Home > Academic, Featured, Matlab, Vision > Sparse Field Active Contours

Sparse Field Active Contours

April 21st, 2009 Leave a comment Go to comments

Active contour methods for image segmentation allow a contour to deform iteratively to partition an image into regions. Active contours are often implemented with level sets. The primary drawback, however, is that they are slow to compute. This post presents a technical report describing, in detail, the sparse field method (SFM) proposed by Ross Whitaker, which allows one to implement level set active contours very efficiently. The algorithm is described in detail, specific notes are given about implementation, and source code is provided.

Fast Level Sets Demo

The links below point to the technical report and a demo written in C++/MEX that can be run directly in MATLAB. The demo implements the Chan-Vese segmentation energy, but many energies can be minimized using the provided framework.

Sparse Field Method – Technical Report [pdf]
Sparse Field Method – Matlab Demo [zip]

To run the MATLAB demo, simply unzip the file and run:
>>sfm_chanvese_demo
at the command line. On the first run, this will compile the MEX code on your machine and then run the demo. If the MEX compile fails, please check your MEX setup. The demo is for a 2D image, but the codes work for 3D images as well.

My hope is that other researchers wishing to quickly implement Whitaker’s method can use this information to easily understand the intricacies of the algorithm which, in my opinion, were not presented clearly in Whitaker’s original paper. Personally, these codes have SUBSTANTIALLY sped up my segmentations, and are allowing me to make much faster progress towards completing my PhD!

Thanks to Ernst Schwartz and Andy for helping to find small bugs in the codes and documentation. (they’re fixed now!)

For more information regarding active contour, segmentation, and computer vision, check here: Computer Vision Posts

  1. haijun
    May 23rd, 2009 at 07:59 | #1

    good! I make it!

  2. Jeff
    June 9th, 2009 at 09:47 | #2

    Thanks for the detailed implementation. I’ve been trying to implement the sparse field method based on Whitaker’s paper which is not very detailed. You’re technical report is perfect! Thanks.

  3. Andy
    June 30th, 2009 at 08:02 | #3

    Thanks Shawn, this is really helpful.

    I’ve been frustrated for a while that Whitaker’s original explanation of SFM is confusingly brief, and that every subsequent description I’ve managed to find is a Copy-And-Paste job (even in “Insight into Images”, ed Yoo).

    I’ve not tried your code, but your tech report is perfect for me: I knew it would be straightforward, but just couldn’t get there myself.

    Thanks again.

  4. Andy
    July 4th, 2009 at 05:08 | #4

    I think there is a tiny tiny typo in Procedure 1: in line 10, the label(q) should be set to -1 rather than 1, I think!

  5. July 5th, 2009 at 09:33 | #5

    @Andy
    Yes, you’re right. Thanks! FIXED now.

  6. Andy
    July 6th, 2009 at 04:14 | #6

    @Shawn, sorry, I’m really not trying to find typos, I promise – I’ve just been implementing it and I spotted another one :D Procedure 2, lines 27-28: the conditions are the wrong way around. It should be ‘>’ on line 27 and ‘<=' on line 28.

    Also, for the sake of consistency, I think it would make the description more robust if you standardized the way that a layer's membership is defined: sometimes it is [ (x-0.5)..(x+0.5) ), other times it is ( (x-0.5)..(x+0.5) ], other times it is [ (x-0.5)..(x+0.5) ]. I say this only because I've implemented an 'N layers' version of your code, and I spotted that sometimes you flip your convention.

    Regards,
    Andy.

  7. July 6th, 2009 at 07:45 | #7

    Thanks again for finding more typos! They are fixed now.

    The way the list membership works is consistent if you put the layers on a number line. Basically, “exterior” bounds are inclusive and “interior” bounds are exclusive. This gives points a (slight) preference towards being on interior layers. However, I expect that the convention doesn’t matter much.

  8. Jun.C
    September 16th, 2009 at 08:07 | #8

    hi,i have read your publication about [Localizing Region]-Based Active Contours and the code. But i was confused when i read the part of “Multiple Interacting Contours” of the article, i did not know how it works. I will appreciate greatly If you can send the code to my E-Mail(jun.c81@gmail.com)to show me “how two contours can interact with each other to find the correct segmentation”.

  9. Luis M
    September 21st, 2009 at 08:52 | #9

    hi, i have read your publication spear field method, and its very clear and helpful, i only have a doubt. How are the pixels of the image divided for this 5 level sets lists? how can we get these values between -2.5 and 2.5 for the pixels?? thank you

  10. September 28th, 2009 at 10:36 | #10

    @Jun.C
    Hi Jun. The formulas are given quite clearly in the paper. Essentially, the two contours compare their “evolution force” to all “evolution forces” nearby. That way, curve segments near each other will move together, toward the best joint energy, and curve segments that are far apart move individually. -cheers!

  11. September 28th, 2009 at 10:38 | #11

    @Luis M
    The pixels of the image are not placed in the 5 lists [-2 -1 0 1 2]. Instead, the lists represent the surface $\phi$ that embeds the contour. The image pixels are left in their original domain, and remain unaltered throughout the segmentation.

  12. Prashanth
    October 14th, 2009 at 08:58 | #12

    Hi.. I am a student who is trying to implement your coding. Can you plz tell me what mu1 and m2 in the Chan-Vese Energy equation are? I seem to have got stuck there. It would be helpful if you can tell me how to code that in c#

  13. October 14th, 2009 at 09:00 | #13

    @Prashanth
    mu_1 and mu_2 refer to the mean of image points inside and outside of the contour as stated in the Chan-Vese paper “Active Contours Without Edges.”

  14. Anonymous
    October 14th, 2009 at 09:54 | #14

    Also, in Procedure 2, line 9, what do you mean by maximum of points q within N(p). By points, you refer to a coordinate if I am correct? If that is the case, how can you choose the maximum of 3 coordinates?

  15. October 14th, 2009 at 12:21 | #15

    Here I mean the maximum of I(q) for q within N(p).

  16. Eran
    October 20th, 2009 at 16:47 | #16

    Hi Shawn, Nice work, thanks.

    I have one question. Could we implement images gradient based energies into this framework. Could I do this by implementing the functions (yezzi energy for example) given in “energy3c.h”.

    Thanks,
    Eranga

  17. October 21st, 2009 at 12:20 | #17

    @Eran
    Absolutely you can use this framework to implement other energies!

    In fact, I plan to release an energy3c.cpp soon with many well-known energies.
    However, the Yezzi Energy: E = (u-v)^2
    is a region-based energy. Caselles is a good example of an image-gradient-based energy.

  18. farshad
    October 30th, 2009 at 06:03 | #18

    Dear Shawn,

    First of all allow me to thank you for your nice work. I am applying your MATLAB code based on active contoure without edges on my project.
    Could you please say why you did not use the Dirace function in your MATLAB code?

    Best Regards,
    Farshad

  19. November 2nd, 2009 at 10:41 | #19

    @farshad. Instead of using a “smooth” dirac as described in the paper, I use a discrete approximation. Specifically,
    d(0) = 1, and
    d(anything else) = 0.

  20. Sen
    November 3rd, 2009 at 20:52 | #20

    Dear Shawn,

    I am very grateful to you for this code. It is great work. Could I use this active contour to drive based on image edge information as well. If so Could you please tell me which function to call.

    Thanks a bunch..
    Sen Gen

  21. November 9th, 2009 at 03:01 | #21

    @sen You can definitely use the codes to perform edge-based segmentation, but you must write your the new energy in the energy3c.cpp file.

  22. Monica
    November 12th, 2009 at 17:53 | #22

    Hi Shawn,

    First of all thanks for sharing your code. I’m using it to track migrating cells and it works great. However, it could be better for my application if the contour lines weren’t allowed to merge. Is there a way to modify your code so that contours lines can’t merge? Any advice/suggestions are greatly appreciated.

    Thanks,
    Monica

  23. Quinn
    November 21st, 2009 at 09:44 | #23

    Hi Shawn,
    I am very interested in sparse field Active Contour, and I want to do something with it. It all codes in the above files(Sparse Field Method – Matlab Demo [zip] ), If I want to do something ,Can I only write something new in energy3c.cpp or other file of C, then I create the DLL to replace the old DLL??

  24. November 24th, 2009 at 09:48 | #24

    @Quinn All of the source is provided. You can feel free to modify any of the files to implement specific behaviors, but typically new energies can be implemented by modifying solely energy3c.cpp.

  25. Naveen
    December 9th, 2009 at 04:32 | #25

    Shawn,
    Have this question: I need to segment out a region surrounded by multiple shades of boundary. That would mean we need multiple uout (mean of exterior pixels intensity). Or is there a way to restrict uout to a localised region?How do I use your code?

  26. December 9th, 2009 at 09:16 | #26

    I had the same thought! Please see this paper: Localizing Region-Based Active Contours (publications page). I hope to publish my codes for this soon.

  27. Wliao
    December 22nd, 2009 at 18:15 | #27

    Thank you very much for sharing with us, it is very good job!

  28. January 22nd, 2010 at 08:01 | #28

    Hi Shawn,

    Thanks for sharing the Sparse Field Active Contours algo.

    Since bulk of the algo is written in C++ and the .m files are only used as wrappers, I am trying to convert this algo as a standalone Windows application – i.e. trying to remove all the Matlab dependencies.

    For this I’m plan on compiling the C++ code in VC++ 2008 and then convert all the Matlab .m files to C++ code.

    However, when I compile the C++ code (energy3c.cpp, llist.cpp, lsops3c.cpp, and sfm_local_chanvese_mex.cpp) in VC++ 2008, the compiler gives an error where it reports a dependency on “matrix.h” – which is a Matlab header file. (used for “mxArray” in “Sparse3c.h”).

    Would you know how to remove the dependency of “matrix.h” and other Matlab specific dependencies, so that one can compile and execute the entire algo as a stanadalone VC++ application?

    Thanks again.

    Rajeev

  29. January 24th, 2010 at 19:51 | #29

    @Rajeev Thanks for your interest. There are several Matlab libraries used in the code. In general, Matlab MEX programs use the internal Matlab “Matrix” data-structures. You can easily strip these out and use simple data arrays. This is the underlying data-type in the data-structures in the “Matrix” element.

  30. January 26th, 2010 at 02:53 | #30

    Thanks Shawn – appreciate your quick response.

    I had wanted to know if there were any other dependencies other than the “Matrix” data structure (I haven’t looked exhaustively at the C++ code). From your response it seems there aren’t, which answers my question.

    I’ll post the converted code soon.

    Rajeev

  1. No trackbacks yet.