#include #include #include #include #include #include "ConfigExamples.h" #include #include #include #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// using namespace std; using namespace DGtal; struct hueFct{ inline unsigned int operator() (unsigned int aVal) const { HueShadeColorMap hueShade(0,255); Color col = hueShade((unsigned int)aVal); return (((unsigned int) col.red()) << 16)| (((unsigned int) col.green()) << 8)|((unsigned int) col.blue()); } }; // Définition du type de viewer à utiliser. typedef Viewer3D<> ViewerType ; // Définition du type de conteneur à utiliser pour l'image du premier exercice. typedef ImageContainerBySTLVector Image3D; // Définition du type de conteneur à utiliser pour l'image de la transformée en distance. typedef ImageSelector::Type Image; // Parcours et traitement d'un volume. void imageSandbox(ViewerType& viewer, std::string filename); // Tranformée en distance. void transformeeEnDistance(ViewerType& viewer, std::string filename); // Méthode pour générer des voxels de manière aléatoire. template void randomSeeds(Image &image, const unsigned int nb, const int value); /////////////////////////////////////////////////////////////////////////////// int main( int argc, char** argv ) { QApplication application(argc,argv); ViewerType viewer; // Appel aux méthodes des exercices. if (argc > 2) { std::stringstream ssAlgo; ssAlgo << std::string(argv[1]); std::stringstream ssFile; ssFile << std::string(argv[2]); if (ssAlgo.str() == "Sandbox") imageSandbox(viewer, ssFile.str()); else if (ssAlgo.str() == "DT") transformeeEnDistance(viewer, ssFile.str()); } else { std::cout << "Les paramètres n'a pas été fourni." << std::endl; std::cout << "startCode " << std::endl; return 0; } return application.exec(); } /** * Cette fonction vous permettra de commencer à pratiquer avec le chargement d'objets * volumiques. Les parcourir, retrouver les valeurs affectées à chaque voxel et les * les modifier. * \param Visualisateur à utiliser. * \param Nom du fichier. * */ void imageSandbox(ViewerType& viewer, std::string filename) { // Lance le visusalisateur. viewer.show(); //Chargement d'une image dans une structure de données ImageContainerBySTLVector. std::string inputFilename = examplesPath + "/" + filename; Image3D image = GenericReader::import(inputFilename); // Obtention du domaine (taille) de l'image chargée. Z3i::Domain initialDomain = image.domain(); // Définition du gradient des couleurs. GradientColorMap gradient( 0,30); gradient.addColor(Color::Red); gradient.addColor(Color::Yellow); gradient.addColor(Color::Green); gradient.addColor(Color::Cyan); gradient.addColor(Color::Blue); gradient.addColor(Color::Magenta); gradient.addColor(Color::Red); float min = 0.0; float max = 0.0; for(Z3i::Domain::ConstIterator it= image.domain().begin(), itend = image.domain().end(); it != itend; ++it) { if (image(*it) > 0) viewer << *it; } viewer << SetMode3D(image.className(), "BoundingBox"); viewer << ViewerType::updateDisplay; } /** * Fonction de la transformée en distance à partir de quelques points germes. * La distance est calculée à partir de chaque point. Donc, la distance dans un * voxel est la distance minimale à tous les points germes. * \param le visualisateur à utiliser. * \param Nom du fichier. * */ void transformeeEnDistance(ViewerType& viewer, std::string filename) { // Affichage de la visualisation. viewer.show(); // Nombre du fichier à charger. std::string inputFilename = examplesPath + "/" + filename; // Création du type d'image. //Default image selector = STLVector typedef ImageSelector::Type Image; //Chargement du fichier image dans la structure. Image image = VolReader::importVol( inputFilename ); // Obtention du domaine (taille) de l'image. Z3i::Domain domain = image.domain(); Image imageSeeds ( domain); for ( Image::Iterator it = imageSeeds.begin(), itend = imageSeeds.end();it != itend; ++it) (*it)=1; //imageSeeds.setValue(p0, 0 ); randomSeeds(imageSeeds, 70, 0); typedef functors::SimpleThresholdForegroundPredicate Predicate; Predicate aPredicate(imageSeeds,0); // Création de type et de l'objet pour appliquer la transformée. typedef DistanceTransformation DTL2; DTL2 dtL2(&domain, &aPredicate, &Z3i::l2Metric); // Detection des distances minimales et maximales. unsigned int min = 0; unsigned int max = 0; for(DTL2::ConstRange::ConstIterator it = dtL2.constRange().begin(), itend=dtL2.constRange().end(); it!=itend; ++it) { if( (*it) < min ) min=(*it); if( (*it) > max ) max=(*it); } //Spécification des gradients de couleur pour la visualisation. GradientColorMap gradient( 0,30); gradient.addColor(Color::Red); gradient.addColor(Color::Yellow); gradient.addColor(Color::Green); gradient.addColor(Color::Cyan); gradient.addColor(Color::Blue); gradient.addColor(Color::Magenta); gradient.addColor(Color::Red); // Affectation du mode de visualisation 3D. viewer << SetMode3D( (*(domain.begin())).className(), "Paving" ); // Parcours de tous les voxels de l'image avec un iterateur sur le domaine. for(Z3i::Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it) { // Calcul de la transformée en distance pour le voxel courant. double valDist= dtL2( (*it) ); // Calcul du gradient de couleur pour cette distance. Color c= gradient(valDist); viewer << CustomColors3D(Color((float)(c.red()), (float)(c.green()), (float)(c.blue(),205)), Color((float)(c.red()), (float)(c.green()), (float)(c.blue()),205)); // Le viewer reçoit le prochain voxel pour visualisation. if (image(*it) > 0) viewer << *it ; } //viewer << ClippingPlane(0,1,0, -40) << Viewer3D<>::updateDisplay; // Mise à jour du visualisateur après le parcours de tous le voxels. viewer<< Viewer3D<>::updateDisplay; } /** * Cette fonction genère un ensemble de points afin de les placer * dans le volume comme les germes de la transformée en distance. * \param image. * \param nombre de germes. * \param value à affecter comme seuil. * */ template void randomSeeds(Image &image, const unsigned int nb, const int value) { typename Image::Point p, low = image.domain().lowerBound(); typename Image::Vector ext; srand ( time(NULL) ); ext = image.extent(); for (unsigned int k = 0 ; k < nb; k++) { for (unsigned int dim = 0; dim < Image::dimension; dim++) p[dim] = rand() % (ext[dim]) + low[dim]; image.setValue(p, value); } } // // ///////////////////////////////////////////////////////////////////////////////