Skip to content

brotherofken/chan_vese

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PM+CSV segmentation in C++

This is a quick implementation of Perona-Malik + Chan-Sandberg-Vese segmentation in C++.

The idea is to reduce noise in the image with Perona-Malik before segmenting the region with Chan-Sandberg-Vese algorithm, as the latter is relatively sensitive to noise. The resulting contour is used to cut out ROI from the original image.

Details

Implementation relies on (version number the code was tested with)

  • OpenCV (2.4.8) (opencv_core, opencv_imgproc and opencv_highgui libs);
  • Boost libraries (1.59.0) (program_options, system and filesystem libs);
  • OpenMP (4.0);

The compiler must be compatible with the latest C++14 standard (clang 3.6+ or gcc 5.0+ will do ok).

Build options

To build, just do make but make sure that your compiler sees the libs and headers listed above; to read the documentation, do make doc; to see all possible command line arguments, do bin/chan_vese -h.

If you want to enable debugging symbols in the binary, build it with DEBUG variable defined, e.g. DEBUG=1 make; If you want to build it with multithreaded boost libraries, build the project with MT variable defined, e.g. MT=1 make; or you could edit the library names by hand in the Makefile.

Theory

Both methods summed up in a couple of sentences:

  • Perona-Malik segmentation is an improvement from classical Gaussian blur, the kernel of which is a solution to heat equation. Perona and Malik improved upon it by promoting the diffusion constant c in the heat equation to a function of the image I gradient magnitude aka edge detection function 1:

    perona_malik

    Thus, when a region contains no edges (image gradient small), it will be Gaussian-smoothed; when the edge detection function encounters an edge it will not be smoothed but even enhanced.

  • Chan-Sandberg-Vese (or Chan-Vese for a single-channel image) formulates optimal contour in the image by defining a functional dependant on zero-level set u

    csv_functional

    where the 1st term penalizes length of the contour; the 2nd term area enclosed by the contour; the 3rd and 4th terms penalize discrepancy between the intensity averages inside and outside of the contour 2 3. The corresponding equation of motion for the zero level set can be solved implicitly (read: fast).

For further information, see the documentation or check the references given below.

Results

Original image (top left), smoothed with Perona-Malik (top right), segmented with Chan-Sandberg-Vese (bottom left), PM+CSV (bottom right).

seastar_united

Image courtesy: Wikimedia Commons (original).

Command used:

bin/chan_vese -i seastar.png  -s -N 70 -S -L 0.25 -T 100 -K 30

Zero level set evolution and the final result, obtained with the following command:

bin/chan_vese -i 640px-Europe_night.png \
-N 132 --dt 0.001 -t 0.000001 --nu -293 --lambda1 1 1 0.1 \
-S -L 0.1 -T 1.5 -K 1000 \
-s -V -f 12 -l red

anim

640px-europe_night_selection

Image courtesy: Wikimedia Commons (original).


An alternative to initializing the level set with a checkerboard pattern seen above is to let users specify either rectangular or circular contour:

screenshot from 2015-11-29 18 20 56

Image courtesy: Wikimedia Commons (original)

References

[1] Scale-space and edge detection using anisotropic diffusion

[2] Active Contours without Edges for Vector-Valued Images

[3] Chan-Vese Segmentation

About

Scientific Computing course project

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 96.7%
  • Makefile 3.3%