PTdecode/CImg-1.3.0/examples/use_skeleton.cpp

Wed, 05 Aug 2009 15:02:31 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Wed, 05 Aug 2009 15:02:31 +0100
changeset 13
a933b13e087f
parent 5
1204ebf9340d
permissions
-rwxr-xr-x

PTdecode: add support for uncompressed data (NOTE: *NOT* supported by the PT-2450DX)

philpem@5 1 /*
philpem@5 2 #
philpem@5 3 # File : use_skeleton.cpp
philpem@5 4 # ( C++ source file )
philpem@5 5 #
philpem@5 6 # Description : Example of use for the CImg plugin 'plugins/skeleton.h'.
philpem@5 7 # This file is a part of the CImg Library project.
philpem@5 8 # ( http://cimg.sourceforge.net )
philpem@5 9 #
philpem@5 10 # Copyright : Francois-Xavier Dupe
philpem@5 11 # ( http://www.greyc.ensicaen.fr/~fdupe/ )
philpem@5 12 #
philpem@5 13 # License : CeCILL v2.0
philpem@5 14 # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
philpem@5 15 #
philpem@5 16 # This software is governed by the CeCILL license under French law and
philpem@5 17 # abiding by the rules of distribution of free software. You can use,
philpem@5 18 # modify and/ or redistribute the software under the terms of the CeCILL
philpem@5 19 # license as circulated by CEA, CNRS and INRIA at the following URL
philpem@5 20 # "http://www.cecill.info".
philpem@5 21 #
philpem@5 22 # As a counterpart to the access to the source code and rights to copy,
philpem@5 23 # modify and redistribute granted by the license, users are provided only
philpem@5 24 # with a limited warranty and the software's author, the holder of the
philpem@5 25 # economic rights, and the successive licensors have only limited
philpem@5 26 # liability.
philpem@5 27 #
philpem@5 28 # In this respect, the user's attention is drawn to the risks associated
philpem@5 29 # with loading, using, modifying and/or developing or reproducing the
philpem@5 30 # software by the user in light of its specific status of free software,
philpem@5 31 # that may mean that it is complicated to manipulate, and that also
philpem@5 32 # therefore means that it is reserved for developers and experienced
philpem@5 33 # professionals having in-depth computer knowledge. Users are therefore
philpem@5 34 # encouraged to load and test the software's suitability as regards their
philpem@5 35 # requirements in conditions enabling the security of their systems and/or
philpem@5 36 # data to be ensured and, more generally, to use and operate it in the
philpem@5 37 # same conditions as regards security.
philpem@5 38 #
philpem@5 39 # The fact that you are presently reading this means that you have had
philpem@5 40 # knowledge of the CeCILL license and that you accept its terms.
philpem@5 41 #
philpem@5 42 */
philpem@5 43
philpem@5 44 #include <queue>
philpem@5 45 #define cimg_plugin "plugins/skeleton.h"
philpem@5 46 #include "../CImg.h"
philpem@5 47 using namespace cimg_library;
philpem@5 48
philpem@5 49 #ifndef cimg_imagepath
philpem@5 50 #define cimg_imagepath "img/"
philpem@5 51 #endif
philpem@5 52
philpem@5 53 int main (int argc, char **argv) {
philpem@5 54
philpem@5 55 cimg_usage("Compute the skeleton of a shape, using Hamilton-Jacobi equations");
philpem@5 56
philpem@5 57 // Read command line arguments
philpem@5 58 cimg_help("Input/Output options\n"
philpem@5 59 "--------------------");
philpem@5 60 const char* file_i = cimg_option("-i",cimg_imagepath "milla.bmp","Input (black&white) image");
philpem@5 61 const int median = cimg_option("-median",0,"Apply median filter");
philpem@5 62 const bool invert = cimg_option("-inv",false,"Invert image values");
philpem@5 63 const char* file_o = cimg_option("-o",(char*)0,"Output skeleton image");
philpem@5 64 const bool display = cimg_option("-visu",true,"Display results");
philpem@5 65
philpem@5 66 cimg_help("Skeleton computation parameters\n"
philpem@5 67 "-------------------------------");
philpem@5 68 const float thresh = cimg_option("-t",-0.3f,"Threshold");
philpem@5 69 const bool curve = cimg_option("-curve",false,"Create medial curve");
philpem@5 70
philpem@5 71 cimg_help("Torsello correction parameters\n"
philpem@5 72 "------------------------------");
philpem@5 73 const bool correction = cimg_option("-corr",false,"Torsello correction");
philpem@5 74 const float dlt1 = 2;
philpem@5 75 const float dlt2 = cimg_option("-dlt",1.0f,"Discrete step");
philpem@5 76
philpem@5 77 cimg_help("Sampling parameters\n"
philpem@5 78 "-------------------");
philpem@5 79 const float sX = cimg_option("-sizeX",1.0f,"X-Size of the pixel/voxel");
philpem@5 80 const float sY = cimg_option("-sizeY",1.0f,"Y-Size of the pixel/voxel");
philpem@5 81 const float sZ = cimg_option("-sizeZ",1.0f,"Z-Size of the pixel/voxel");
philpem@5 82
philpem@5 83 // Load the image (forcing it to be scalar with 2 values { 0,1 }).
philpem@5 84 CImg<unsigned int> image0(file_i), image = image0.get_pointwise_norm().quantize(2).normalize(0,1);
philpem@5 85 if (median) image.blur_median(median);
philpem@5 86 if (invert) (image-=1)*=-1;
philpem@5 87 if (display) (image0.get_normalize(0,255)<<image.get_normalize(0,255)).display("Input image - Binary image");
philpem@5 88
philpem@5 89 // Compute distance map.
philpem@5 90 CImgList<float> visu;
philpem@5 91 CImg<float> distance = image.get_distance(0,sX,sY,sZ);
philpem@5 92 if (display) visu.insert(distance);
philpem@5 93
philpem@5 94 // Compute the gradient of the distance function, and the flux (divergence) of the gradient field.
philpem@5 95 const CImgList<float> grad = distance.get_gradient("xyz");
philpem@5 96 CImg<float> flux = image.get_flux(grad,sY,sZ);
philpem@5 97 if (display) visu.insert(flux);
philpem@5 98
philpem@5 99 // Use the Torsello correction of the flux if necessary.
philpem@5 100 if (correction) {
philpem@5 101 CImg<float>
philpem@5 102 logdensity = image.get_logdensity(distance,grad,flux,dlt1),
philpem@5 103 nflux = image.get_corrected_flux(logdensity,grad,flux,dlt2);
philpem@5 104 if (display) visu.insert(logdensity).insert(nflux);
philpem@5 105 flux = nflux;
philpem@5 106 }
philpem@5 107
philpem@5 108 if (visu) {
philpem@5 109 cimglist_apply(visu,normalize)(0,255);
philpem@5 110 visu.display(visu.size==2?"Distance function - Flux":"Distance function - Flux - Log-density - Corrected flux");
philpem@5 111 }
philpem@5 112
philpem@5 113 // Compute the skeleton
philpem@5 114 const CImg<unsigned int> skel = image.get_skeleton(flux,distance,curve,thresh);
philpem@5 115 if (display) {
philpem@5 116 (image0.resize(-100,-100,1,3)*=0.7f).get_shared_channel(1)|=skel*255.0;
philpem@5 117 image0.draw_image(0,0,0,0,image*255.0,0.5f).display("Image + Skeleton");
philpem@5 118 }
philpem@5 119
philpem@5 120 // Save output image if necessary.
philpem@5 121 if (file_o) skel.save(file_o);
philpem@5 122
philpem@5 123 return 0;
philpem@5 124 }