int main( ) { typedef ImageSelector < Z3i::Domain, unsigned char>::Type Image3D; typedef ImageSelector < Z2i::Domain, unsigned char>::Type Image2D; typedef DGtal::ConstImageAdapter<Image3D, Image2D::Domain, DGtal::functors::Projector<Z3i::Space>, Image3D::Value, DGtal::functors::Identity > SliceImageAdapter; DGtal::functors::Projector<Z2i::Space > proj(2); // Importing a 3D image std::string filename = examplesPath + "samples/lobster.vol"; Image3D image = VolReader<Image3D>::importVol( filename ); DGtal::Z2i::Domain domain(proj(image.domain().lowerBound()), proj(image.domain().upperBound())); DGtal::functors::Identity idV; trace.beginBlock ( "Example extract2DImagesFrom3D" ); // Extracting 2D slices ... and export them in the pgm format. for (unsigned int i=0; i<30; i+=10){ std::stringstream name; name << "lobsterSliceZ_" << i << ".pgm"; DGtal::functors::Projector<Z3i::Space> aSliceFunctor(i); aSliceFunctor.initAddOneDim(2); SliceImageAdapter sliceImageZ(image, domain, aSliceFunctor, idV); PGMWriter<SliceImageAdapter>::exportPGM(name.str(), sliceImageZ); } // trace.endBlock(); return 0; }
int main( int /*argc*/, char** /*argv*/ ) { //! [extract2DImagesFrom3DType] typedef ImageSelector < Z3i::Domain, unsigned char>::Type Image3D; typedef ImageSelector < Z2i::Domain, unsigned char>::Type Image2D; typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain>, Image3D::Value, DGtal::DefaultFunctor > ImageAdapterExtractor; //! [extract2DImagesFrom3DType] //! [extract2DImagesFrom3DOrigin3D] DGtal::Z3i::Point origin(150, 150, 10); DGtal::Z3i::Point ptUpper1(220, 220, 10); DGtal::Z3i::Point ptUpper2(150, 150, 50); DGtal::Z2i::Domain domainImage2D (DGtal::Z2i::Point(0,0), DGtal::Z2i::Point((ptUpper1-origin).norm(), (ptUpper2-origin).norm())); //! [extract2DImagesFrom3DOrigin3D] DGtal::Z3i::Point ptCenter(175, 175, 20); DGtal::Z2i::Domain domainImage2D2 (DGtal::Z2i::Point(0,0), DGtal::Z2i::Point(IMAGE_PATCH_WIDTH, IMAGE_PATCH_WIDTH)); // Importing a 3D image std::string filename = examplesPath + "samples/lobster.vol"; Image3D image = VolReader<Image3D>::importVol( filename ); DGtal::Z3i::Domain domainImage3D = image.domain(); DGtal::DefaultFunctor idV; trace.beginBlock ( "Example extract2DImagesFrom3D" ); // Extracting 2D images ... and export them in the pgm format. for (unsigned int i=0; i<30; i+=10){ std::stringstream name; name << "lobsterExtracted_" << i << ".pgm"; std::stringstream name2; name2 << "lobsterExtracted_" << i << "V2.pgm"; //! [extract2DImagesFrom3DOExtract] DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(domainImage3D, origin+DGtal::Z3i::Point(i,i,0), ptUpper1+DGtal::Z3i::Point(i,i,0), ptUpper2+DGtal::Z3i::Point(i,i,0)); ImageAdapterExtractor extractedImage(image, domainImage2D, embedder, idV); //! [extract2DImagesFrom3DOExtract] //! [extract2DImagesFrom3DOExtract2] DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder2(domainImage3D, ptCenter+DGtal::Z3i::Point(i,i,0), DGtal::Z3i::RealPoint(1,-1,0), IMAGE_PATCH_WIDTH); ImageAdapterExtractor extractedImage2(image, domainImage2D2, embedder2, idV); //! [extract2DImagesFrom3DOExtract2] PGMWriter< ImageAdapterExtractor>::exportPGM(name.str(), extractedImage); PGMWriter< ImageAdapterExtractor>::exportPGM(name2.str(), extractedImage2); } // trace.endBlock(); return 0; }
int main( int argc, char** argv ) { typedef DGtal::ImageContainerBySTLVector<DGtal::Z3i::Domain, unsigned char > Image3D; //! [ExampleViewer3D2DImagesExtractImagesNonSliceType] typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain>, Image3D::Value, DGtal::functors::Identity > ImageAdapterExtractor; //! [ExampleViewer3D2DImagesExtractImagesNonSliceType] QApplication application(argc,argv); typedef Viewer3D<> MyViewer; MyViewer viewer; viewer.show(); std::string inputFilename = examplesPath + "samples/lobster.vol"; Image3D imageVol = VolReader<Image3D>::importVol(inputFilename); DGtal::functors::Identity idV; //! [ExampleViewer3D2DImagesExtractImagesNonSliceParam] DGtal::Z3i::Point ptCenter(50, 62, 28); const int IMAGE_PATCH_WIDTH = 20; // Setting the image domain of the resulting image to be displayed in 3D: DGtal::Z2i::Domain domainImage2D (DGtal::Z2i::Point(0,0), DGtal::Z2i::Point(IMAGE_PATCH_WIDTH, IMAGE_PATCH_WIDTH)); //! [ExampleViewer3D2DImagesExtractImagesNonSliceParam] unsigned int pos=0; for (double alpha = 0; alpha< 1.54; alpha+= 0.01){ //! [ExampleViewer3D2DImagesExtractImagesNonSliceExtract] // Extracting images from 3D embeder DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(imageVol.domain(), ptCenter+DGtal::Z3i::Point(static_cast<int>(200.0*cos(alpha)),static_cast<int>(100.0*sin(alpha))), DGtal::Z3i::RealPoint(cos(alpha),sin(alpha),cos(2.0*alpha)), IMAGE_PATCH_WIDTH); ImageAdapterExtractor extractedImage(imageVol, domainImage2D, embedder, idV); //! [ExampleViewer3D2DImagesExtractImagesNonSliceExtract] //! [ExampleViewer3D2DImagesExtractImagesNonSliceDisplay] //Display image and update its position with embeder viewer << extractedImage; viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(pos, embedder(Z2i::RealPoint(0,0)), embedder(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0)), embedder(domainImage2D.upperBound()), embedder(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH))); //! [ExampleViewer3D2DImagesExtractImagesNonSliceDisplay] pos++; } viewer << MyViewer::updateDisplay; return application.exec(); }
void getVoxelsStats(const Image3D &imageA, int aMin, int aMax, const Image3D &imageB, int bMin, int bMax, bool exportStatVoxels, std::vector<Point> &vectPtBinA, std::vector<Point> &vectPtCompBinCompA, std::vector<Point> &vectPtBnotInA, std::vector<Point> &vectPtnotBInA, bool precisionRecallFMean ){ int numBinA = 0; // true positif with A as ref shape. int numCompBinCompA = 0; // true neg with A as ref shape. int numBnotInA = 0; // false pos with A as ref shape int numNotBinA = 0; // false neg with A as ref shape int numTotalInA = 0; // total pos in reference shape int numTotalInB = 0; // total pos in compared shape int numTotalinCompA = 0; //total in complement A int numTotalinCompB = 0; //total in complement B for(Image3D::Domain::ConstIterator it = imageA.domain().begin(); it!=imageA.domain().end(); it++){ // voxels in A if(imageA(*it) <= aMax && imageA(*it) >= aMin){ numTotalInA++; //voxels in B if(imageB(*it) <= bMax && imageB(*it) >= bMin){ numTotalInB++; numBinA++; if(exportStatVoxels) vectPtBinA.push_back(*it); }else{ numTotalinCompB++; numNotBinA++; if(exportStatVoxels) vectPtnotBInA.push_back(*it); } // voxels outside A }else{ numTotalinCompA++; // voxels in B if(imageB(*it) <= bMax && imageB(*it) >= bMin){ numBnotInA++; numTotalInB++; if(exportStatVoxels) vectPtBnotInA.push_back(*it); }else{ numTotalinCompB++; numCompBinCompA++; if(exportStatVoxels) vectPtCompBinCompA.push_back(*it); } } } std::cout << numBinA << " " << numCompBinCompA << " " << numBnotInA << " " << numNotBinA << " " << numTotalInA << " " << numTotalInB << " " << numTotalinCompA << " " << numTotalinCompB; if(precisionRecallFMean){ double precision = (double)numBinA/(numBinA + numBnotInA); double recall = (double)numBinA/(numBinA+numNotBinA); double fmean = (2.0*precision*recall)/(precision+recall); std::cout << " " << precision<< " " << recall << " " << fmean ; } }
TextureID Renderer::addTexture3D(const char *fileName, unsigned int flags){ Image3D *img = new Image3D(); if (img->loadFromFile(fileName)){ return addTexture3D(img, flags); } else { addToLog(String("Couldn't load \"") + fileName + "\""); delete img; return TEXTURE_NONE; } }
void embeddMeshInVol(const Image3D &anImage, My3DViewer &aViewer, DGtal::Mesh<DGtal::Z3i::RealPoint> &aMesh, DGtal::Z3i::RealPoint vectTranslationNonMesh=DGtal::Z3i::RealPoint(0,0,0) ) { unsigned int numImageDisplayed = aViewer.getCurrentGLImageNumber (); for (unsigned int i =0 ; i < aMesh.nbFaces(); i++){ DGtal::Mesh<Z3i::RealPoint>::MeshFace aFace = aMesh.getFace(i); Z3i::RealPoint point1 = aMesh.getVertex(aFace.at(0)); Z3i::RealPoint point2 = aMesh.getVertex(aFace.at(1)); Z3i::RealPoint point3 = aMesh.getVertex(aFace.at(2)); Z3i::RealPoint point4 = aMesh.getVertex(aFace.at(3)); DGtal::Z2i::Domain domainImage2D (DGtal::Z2i::RealPoint(0,0), DGtal::Z2i::RealPoint((point2-point1).norm(), (point4-point1).norm() )); DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(anImage.domain(), point1, point2, point4, DGtal::Z3i::Point(0,0,0)); ImageAdapterExtractor extractedImage(anImage, domainImage2D, embedder, idV); aViewer << extractedImage; aViewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(numImageDisplayed, point1+vectTranslationNonMesh, point2+vectTranslationNonMesh, point3+vectTranslationNonMesh, point4+vectTranslationNonMesh); numImageDisplayed++; } }
int main( int argc, char** argv ) { typedef ImageContainerBySTLVector<Z3i::Domain, unsigned char > Image3D; QApplication application(argc,argv); typedef Viewer3D<> MyViewer ; MyViewer viewer; viewer.show(); std::string inputFilename = examplesPath + "samples/lobster.vol"; Image3D imageVol = GenericReader<Image3D>::import(inputFilename); Z3i::Point ptLow (100, 100, 20); Z3i::Point ptUpp (200, 200, 40); Z3i::Domain subDomain(ptLow, ptUpp); Z3i::Point ptLow2 (220, 50, 10); Z3i::Point ptUpp2 (260, 100, 20); Z3i::Domain subDomain2(ptLow2, ptUpp2); Image3D imageCrop(subDomain); Image3D imageCrop2(subDomain2); for(Z3i::Domain::ConstIterator it= imageVol.domain().begin(), itend = imageVol.domain().end(); it != itend; ++it){ if(imageVol(*it)>140) viewer << *it; Z3i::Point pt = *it; if(pt[0]>=ptLow[0] && pt[1] >= ptLow[1] && pt[2] >= ptLow[2] && pt[0]<=ptUpp[0] && pt[1] <= ptUpp[1] && pt[2] <= ptUpp[2]){ imageCrop.setValue(*it, imageVol(*it)); } if(pt[0]>=ptLow2[0] && pt[1] >= ptLow2[1] && pt[2] >= ptLow2[2] && pt[0]<=ptUpp2[0] && pt[1] <= ptUpp2[1] && pt[2] <= ptUpp2[2]){ imageCrop2.setValue(*it, imageVol(*it)); } } viewer << imageCrop; viewer << SetMode3D(imageCrop.className(), "BoundingBox"); //! [ExampleViewer3D3DImagesDisplayImagesColor] viewer << AddTextureImage3DWithFunctor<Image3D, hueFct, Z3i::Space, Z3i::KSpace> (imageCrop2, hueFct(), MyViewer::RGBMode); viewer << MyViewer::updateDisplay; //! [ExampleViewer3D3DImagesDisplayImagesColor] return application.exec(); }
// ---------------------------------------------------------------------------- // Generates a opacity map from the transfer function specification // ---------------------------------------------------------------------------- void mapOpacity(Image3D<float> & map, std::list<std::shared_ptr<Node>> transfer) { float samples = static_cast<float>(map.width()) - 1; auto buffer = map.data(); memset(buffer, 0, map.size()*sizeof(float)); auto iter = transfer.begin(); auto curr = *iter; iter++; while (iter != transfer.end()) { auto next = *iter; size_t x1 = static_cast<size_t>(curr->density * samples); if (x1 >= map.width()) x1 = map.width()-1; size_t x2 = static_cast<size_t>(next->density * samples); if (x2 >= map.width()) x2 = map.width()-1; float y1 = curr->material->opticalThickness; float y2 = next->material->opticalThickness; for (size_t i = x1; i <= x2; i++) { float px = i / samples - curr->density; float py = next->density - curr->density; float part = low( high(px / py, 0.0f), 1.0f ); buffer[i] = - logf( 1.f - (1.f - part) * y1 - part * y2 ); } curr = next; iter++; } }
void CubeMapTextureGLTest::imageFull() { if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported.")); CubeMapTexture texture; texture.setStorage(1, TextureFormat::RGBA8, Vector2i{2, 2}) .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, Vector3i{2, 2, 6}, DataFull}); MAGNUM_VERIFY_NO_ERROR(); Image3D image = texture.image(0, {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2, 2, 6)); CORRADE_COMPARE_AS( Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()), Containers::ArrayReference<const UnsignedByte>{DataFull}, TestSuite::Compare::Container); }
void getStatsFromDistanceMap(Statistic<double> & stats, const Image3D &imageA, int aMin, int aMax, const Image3D & imageB, int bMin, int bMax, bool statOnFalsePositiveOnly=false, Point *ptMax=0){ // Get the digital set from ref image by computing the surface (use -1 and +1 since the interval of append function are open) Z3i::DigitalSet set3dRef (imageA.domain()); SetFromImage<Z3i::DigitalSet>::append<Image3D>(set3dRef, imageA, aMin-1,aMax); typedef functors::NotPointPredicate<Z3i::DigitalSet> NegPredicate; // Applying the distance transform on the digital surface of the set: typedef DistanceTransformation<Z3i::Space, NegPredicate, Z3i::L2Metric> DTL2; const NegPredicate aPredicate( set3dRef ); DTL2 dtL2( imageA.domain(), aPredicate, Z3i::l2Metric ); // Get the set of point of imageB: (use -1 and +1 since the interval of append function are open) Z3i::DigitalSet set3dComp (imageB.domain()); SetFromImage<Z3i::DigitalSet>::append<Image3D>(set3dComp, imageB, bMin-1, bMax); unsigned int nbAdded=0; double maxDist=0; //Applying stats from the set to be compared (from imageB) for(Z3i::DigitalSet::ConstIterator it= set3dComp.begin(); it!= set3dComp.end(); ++it){ if((!statOnFalsePositiveOnly) || (isDiff(imageA, aMin, aMax, imageB, bMin, bMax, *it))){ DTL2::Value distance = dtL2(*it); stats.addValue(distance); nbAdded++; if(maxDist<distance){ maxDist=distance; if(ptMax!=0){ (*ptMax)[0]=(*it)[0]; (*ptMax)[1]=(*it)[1]; (*ptMax)[2]=(*it)[2]; } } } } if(nbAdded==0) trace.error() << "No point added to statistics, will failed..." << endl; }
void fillImage3D( Image3D & img, typename Image3D::Point low, typename Image3D::Point up, typename Image3D::Value value ) { typedef typename Image3D::Point Point; typedef typename Image3D::Integer Integer; for ( Integer z = low[ 2 ]; z <= up[ 2 ]; ++z ) for ( Integer y = low[ 1 ]; y <= up[ 1 ]; ++y ) for ( Integer x = low[ 0 ]; x <= up[ 0 ]; ++x ) img.setValue( Point( x, y, z ), value ); }
/** * Example of a test. To be completed. * */ bool testDicomReader() { //Default image selector = STLVector typedef ImageContainerBySTLVector<Z3i::Domain, unsigned char > Image3D; std::string filename = testPath + "samples/dicomSample/1629.dcm"; Image3D image = DicomReader< Image3D >::importDicom( filename ); trace.info() << image <<endl; unsigned int nbVal=0, nbPos = 0; for ( Image3D::ConstIterator it=image.begin(), itend=image.end() ; it != itend ; ++it ) { nbVal++; if ( (*it) > 0 ) nbPos++; } trace.info() << "Number of points with (val>0) = " << nbVal << endl; return nbVal==2130048 && nbPos==296030; }
void CubeMapTextureGLTest::subImageQuery() { if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::get_texture_sub_image>()) CORRADE_SKIP(Extensions::GL::ARB::get_texture_sub_image::string() + std::string(" is not supported.")); /* I'm too lazy to call setSubImage() six times */ if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) CORRADE_SKIP(Extensions::GL::ARB::direct_state_access::string() + std::string(" is not supported.")); CubeMapTexture texture; texture.setStorage(1, TextureFormat::RGBA8, Vector2i{4}) .setSubImage(0, {}, ImageReference3D{ColorFormat::RGBA, ColorType::UnsignedByte, {4, 4, 1}, SubDataComplete}); MAGNUM_VERIFY_NO_ERROR(); Image3D image = texture.subImage(0, Range3Di::fromSize({1, 1, 0}, {2, 2, 1}), {ColorFormat::RGBA, ColorType::UnsignedByte}); MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(image.size(), Vector3i(2, 2, 1)); CORRADE_COMPARE_AS( Containers::ArrayReference<const UnsignedByte>(image.data<UnsignedByte>(), image.pixelSize()*image.size().product()), Containers::ArrayReference<const UnsignedByte>{Data}, TestSuite::Compare::Container); }
Event CommandQueue::enqueueUnmap(const Image3D& image, void *mappedPtr, const Epic::Core::Array<Event>& eventWaitList) const { Event ret; cl_int err = 0; Array<cl_event> events = eventArrayToCLEventArray(eventWaitList); err = clEnqueueUnmapMemObject(queueHandle(), image.imageHandle(), mappedPtr, events.count(), events.data(), ret.eventPointer()); EPIC_OPENCL_CHECK_ERROR(err) return ret; }
Event CommandQueue::enqueueWriteImage(const Image3D& image, bool blockingRead, const size_t origin[3], const size_t region[3], size_t rowPitch, size_t slicePitch, void *pointer, const Epic::Core::Array<Event>& eventWaitList) const { Event ret; cl_int err = 0; Array<cl_event> events = eventArrayToCLEventArray(eventWaitList); err = clEnqueueWriteImage(queueHandle(), image.imageHandle(), blockingRead, origin, region, rowPitch, slicePitch, pointer, events.count(), events.data(), ret.eventPointer()); EPIC_OPENCL_CHECK_ERROR(err) return ret; }
// ---------------------------------------------------------------------------- // Generates an emissive map from the tranfer specification // ---------------------------------------------------------------------------- void mapEmissive(Image3D<Vector4f> & map, std::list<std::shared_ptr<Node>> transfer) { float samples = static_cast<float>(map.width()) - 1; auto buffer = map.data(); memset(buffer, 0, map.size()*sizeof(Vector4f)); auto iter = transfer.begin(); auto curr = *iter; iter++; while (iter != transfer.end()) { auto next = *iter; size_t x1 = static_cast<size_t>(curr->density * samples); if (x1 >= map.width()) x1 = map.width()-1; size_t x2 = static_cast<size_t>(next->density * samples); if (x2 >= map.width()) x2 = map.width()-1; Vector3f s1 = Vector3f(curr->material->emissive) / 255.0f * curr->material->emissiveStrength; Vector3f s2 = Vector3f(next->material->emissive) / 255.0f * curr->material->emissiveStrength; Vector4f y1(s1[0], s1[1], s1[2], 0.0f); Vector4f y2(s2[0], s2[1], s2[2], 0.0f); for (size_t i = x1; i <= x2; i++) { float px = i / samples - curr->density; float py = next->density - curr->density; float part = low( high(px / py, 0.0f), 1.0f ); buffer[i] = y1*(1.f - part) + y2*part; } curr = next; iter++; } }
// ---------------------------------------------------------------------------- // Generates a diffuse map from the transfer function specification // ---------------------------------------------------------------------------- void mapSpecular(Image3D<Vector<UInt8,4>> & map, std::list<std::shared_ptr<Node>> transfer) { float samples = static_cast<float>(map.width()) - 1; auto buffer = map.data(); memset(buffer, 0, map.size()*sizeof(Vector<UInt8,4>)); auto iter = transfer.begin(); auto curr = *iter; iter++; while (iter != transfer.end()) { auto next = *iter; size_t x1 = static_cast<size_t>(curr->density * samples); if (x1 >= map.width()) x1 = map.width()-1; size_t x2 = static_cast<size_t>(next->density * samples); if (x2 >= map.width()) x2 = map.width()-1; Vector3f s1(curr->material->specular); Vector3f s2(next->material->specular); Vector4f y1(s1[0], s1[1], s1[2], curr->material->glossiness*255.0f); Vector4f y2(s2[0], s2[1], s2[2], next->material->glossiness*255.0f); for (size_t i = x1; i <= x2; i++) { float px = i / samples - curr->density; float py = next->density - curr->density; float part = low( high(px / py, 0.0f), 1.0f ); buffer[i] = static_cast<Vector<UInt8,4>>(y1*(1.f - part) + y2*part); } curr = next; iter++; } }
int main( int argc, char** argv ) { typedef DGtal::ImageContainerBySTLVector<DGtal::Z3i::Domain, unsigned char > Image3D; typedef DGtal::ImageContainerBySTLVector<DGtal::Z2i::Domain, unsigned char > Image2D; // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are "); general_opt.add_options() ("help,h", "display this message") ("input,i", po::value<std::string>(), "vol file (.vol) , pgm3d (.p3d or .pgm3d) file or sdp (sequence of discrete points)" ) ("grid", "draw slice images using grid mode. " ) ("intergrid", "draw slice images using inter grid mode. " ) ("emptyMode", "remove the default boundingbox display " ) ("thresholdImage", "threshold the image to define binary shape" ) ("thresholdMin,m", po::value<int>()->default_value(0), "threshold min to define binary shape" ) ("thresholdMax,M", po::value<int>()->default_value(255), "threshold max to define binary shape" ) ("displaySDP,s", po::value<std::string>(), "display a set of discrete points (.sdp)" ) ("SDPindex", po::value<std::vector <unsigned int> >()->multitoken(), "specify the sdp index (by default 0,1,2).") ("SDPball", po::value<double>()->default_value(0.5), "use balls to display a set of discrete points (used with displaySDP option)") ("displayMesh", po::value<std::string>(), "display a Mesh given in OFF or OFS format. " ) ("displayDigitalSurface", "display the digital surface instead of display all the set of voxels (used with thresholdImage or displaySDP options)" ) ("colorizeCC", "colorize each Connected Components of the surface displayed by displayDigitalSurface option." ) ("colorSDP,c", po::value<std::vector <int> >()->multitoken(), "set the color discrete points: r g b a " ) ("colorMesh", po::value<std::vector <int> >()->multitoken(), "set the color of Mesh (given from displayMesh option) : r g b a " ) ("scaleX,x", po::value<float>()->default_value(1.0), "set the scale value in the X direction (default 1.0)" ) ("scaleY,y", po::value<float>()->default_value(1.0), "set the scale value in the Y direction (default 1.0)" ) ("scaleZ,z", po::value<float>()->default_value(1.0), "set the scale value in the Z direction (default 1.0)") #ifdef WITH_ITK ("dicomMin", po::value<int>()->default_value(-1000), "set minimum density threshold on Hounsfield scale") ("dicomMax", po::value<int>()->default_value(3000), "set maximum density threshold on Hounsfield scale") #endif ("transparency,t", po::value<uint>()->default_value(255), "transparency") ; bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")||argc<=1) { std::cout << "Usage: " << argv[0] << " [input]\n" << "Displays volume file as a voxel set by using QGLviewer" << general_opt << "\n"; return 0; } if(! vm.count("input")) { trace.error() << " The file name was defined" << endl; return 0; } string inputFilename = vm["input"].as<std::string>(); int thresholdMin = vm["thresholdMin"].as<int>(); int thresholdMax = vm["thresholdMax"].as<int>(); unsigned char transp = vm["transparency"].as<uint>(); QApplication application(argc,argv); float sx = vm["scaleX"].as<float>(); float sy = vm["scaleY"].as<float>(); float sz = vm["scaleZ"].as<float>(); double ballRadius = vm["SDPball"].as<double>(); string extension = inputFilename.substr(inputFilename.find_last_of(".") + 1); if(extension!="vol" && extension != "p3d" && extension != "pgm3D" && extension != "pgm3d" && extension != "sdp" && extension != "pgm" #ifdef WITH_ITK && extension !="dcm" #endif ){ trace.info() << "File extension not recognized: "<< extension << std::endl; return 0; } Viewer3DImage<>::ModeVisu mode; if(vm.count("emptyMode")) mode=Viewer3DImage<>::Empty; else if(vm.count("grid")) mode=Viewer3DImage<>::Grid; else if(vm.count("intergrid")) mode=Viewer3DImage<>::InterGrid; else mode=Viewer3DImage<>::BoundingBox; Viewer3DImage<> viewer(mode); viewer.setWindowTitle("simple Volume Viewer"); viewer.show(); viewer.setGLScale(sx, sy, sz); #ifdef WITH_ITK int dicomMin = vm["dicomMin"].as<int>(); int dicomMax = vm["dicomMax"].as<int>(); typedef DGtal::functors::Rescaling<int ,unsigned char > RescalFCT; Image3D image = extension == "dcm" ? DicomReader< Image3D, RescalFCT >::importDicom( inputFilename, RescalFCT(dicomMin, dicomMax, 0, 255) ) : GenericReader<Image3D>::import( inputFilename ); #else Image3D image = GenericReader<Image3D>::import( inputFilename ); #endif Domain domain = image.domain(); trace.info() << "Image loaded: "<<image<< std::endl; viewer.setVolImage(&image); viewer << Z3i::Point(512, 512, 0); // Used to display 3D surface Z3i::DigitalSet set3d(domain); viewer << Viewer3D<>::updateDisplay; if(vm.count("thresholdImage")){ GradientColorMap<long> gradient( thresholdMin, thresholdMax); gradient.addColor(Color::Blue); gradient.addColor(Color::Green); gradient.addColor(Color::Yellow); gradient.addColor(Color::Red); for(Domain::ConstIterator it = domain.begin(), itend=domain.end(); it!=itend; ++it){ unsigned char val= image( (*it) ); Color c= gradient(val); if(val<=thresholdMax && val >=thresholdMin){ if(!vm.count("displayDigitalSurface")){ viewer << CustomColors3D(Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp), Color((float)(c.red()), (float)(c.green()),(float)(c.blue()), transp)); viewer << *it; } }else{ set3d.insert(*it); } } } if(vm.count("displaySDP")){ if(vm.count("colorSDP")){ std::vector<int> vcol= vm["colorSDP"].as<std::vector<int > >(); if(vcol.size()<4){ trace.error() << "Not enough parameter: color specification should contains four elements: red, green, blue and alpha values." << std::endl; return 0; } Color c(vcol[0], vcol[1], vcol[2], vcol[3]); viewer << CustomColors3D(c, c); } vector<Z3i::Point> vectVoxels; if(vm.count("SDPindex")) { std::vector<unsigned int > vectIndex = vm["SDPindex"].as<std::vector<unsigned int > >(); if(vectIndex.size()!=3){ trace.error() << "you need to specify the three indexes of vertex." << std::endl; return 0; } vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(vm["displaySDP"].as<std::string>(), vectIndex); }else{ vectVoxels = PointListReader<Z3i::Point>::getPointsFromFile(vm["displaySDP"].as<std::string>()); } for(unsigned int i=0;i< vectVoxels.size(); i++){ if(!vm.count("displayDigitalSurface")){ if(vm.count("SDPball")){ viewer.addBall (vectVoxels.at(i), ballRadius); }else{ viewer << vectVoxels.at(i); } }else{ set3d.insert(vectVoxels.at(i)); } } } if(vm.count("displayMesh")){ if(vm.count("colorMesh")){ std::vector<int> vcol= vm["colorMesh"].as<std::vector<int > >(); if(vcol.size()<4){ trace.error() << "Not enough parameter: color specification should contains four elements: red, green, blue and alpha values." << std::endl; return 0; } Color c(vcol[0], vcol[1], vcol[2], vcol[3]); viewer.setFillColor(c); } DGtal::Mesh<Z3i::RealPoint> aMesh(!vm.count("colorMesh")); MeshReader<Z3i::RealPoint>::importOFFFile(vm["displayMesh"].as<std::string>(), aMesh); viewer << aMesh; } if(vm.count("displayDigitalSurface")){ KSpace K; Point low = domain.lowerBound(); low[0]=low[0]-1; low[1]=low[1]-1; low[2]=low[2]-1; Point upp = domain.upperBound(); upp[0]=upp[0]+1; upp[1]=upp[1]+1; upp[2]=upp[2]+1; K.init(low, upp , true); SurfelAdjacency<3> SAdj( true ); vector<vector<SCell> > vectConnectedSCell; trace.info() << "Extracting surface set ... " ; Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, SAdj, set3d, true); trace.info()<< " [done] " <<std::endl; GradientColorMap<long> gradient( 0, vectConnectedSCell.size()); gradient.addColor(DGtal::Color::Red); gradient.addColor(DGtal::Color::Yellow); gradient.addColor(DGtal::Color::Green); gradient.addColor(DGtal::Color::Cyan); gradient.addColor(DGtal::Color::Blue); gradient.addColor(DGtal::Color::Magenta); gradient.addColor(DGtal::Color::Red); viewer << DGtal::SetMode3D(vectConnectedSCell.at(0).at(0).className(), "Basic"); for(unsigned int i= 0; i <vectConnectedSCell.size(); i++){ for(unsigned int j= 0; j <vectConnectedSCell.at(i).size(); j++){ if(vm.count("colorizeCC")){ DGtal::Color c= gradient(i); viewer << CustomColors3D(Color(250, 0,0, transp), Color(c.red(), c.green(), c.blue(), transp)); }else if(vm.count("colorSDP")){ std::vector<int> vcol= vm["colorSDP"].as<std::vector<int > >(); Color c(vcol[0], vcol[1], vcol[2], vcol[3]); viewer << CustomColors3D(c, c); } viewer << vectConnectedSCell.at(i).at(j); } } } viewer << Viewer3D<>::updateDisplay; return application.exec(); }
int main( int argc, char** argv ) { typedef DGtal::ImageContainerBySTLVector< DGtal::Z3i::Domain, unsigned int> Image3D; typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain>, Image3D::Value, DGtal::DefaultFunctor > ImageAdapterExtractor; QApplication application(argc,argv); Viewer3D<> viewer; viewer.setWindowTitle("simpleViewer"); viewer.show(); trace.beginBlock("Testing Viewer with Image Embedder "); Point pcenter( 10, 20, 20 ); Point pcenterImg( 10, 20, 20 ); std::string filename = testPath + "samples/cat10.pgm3d"; Image3D image = DGtal::GenericReader<Image3D>::import(filename); const int IMAGE_PATCH_WIDTH = 80; // Setting the image domain of the resulting image to be displayed in 3D: DGtal::Z2i::Domain domainImage2D (DGtal::Z2i::Point(0,0), DGtal::Z2i::Point(IMAGE_PATCH_WIDTH, IMAGE_PATCH_WIDTH)); DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(image.domain(), pcenterImg, Z3i::RealPoint(1, 1, 1), IMAGE_PATCH_WIDTH); DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder2(image.domain(), pcenterImg, Z3i::RealPoint(1, 0, 0), IMAGE_PATCH_WIDTH); DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder3(image.domain(), pcenterImg, Z3i::RealPoint(0, 1, 0 ), IMAGE_PATCH_WIDTH); DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder4(image.domain(), pcenterImg, Z3i::RealPoint(0, 0, 1 ), IMAGE_PATCH_WIDTH); DGtal::DefaultFunctor idV; ImageAdapterExtractor extractedImage(image, domainImage2D, embedder, idV); ImageAdapterExtractor extractedImage2(image, domainImage2D, embedder2, idV); ImageAdapterExtractor extractedImage3(image, domainImage2D, embedder3, idV); ImageAdapterExtractor extractedImage4(image, domainImage2D, embedder4, idV); viewer << extractedImage; viewer << extractedImage2; viewer << extractedImage3; viewer << extractedImage4; viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(0, embedder(Z2i::RealPoint(0,0),false), embedder(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false), embedder(domainImage2D.upperBound(), false), embedder(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false)); viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(1, embedder2(Z2i::RealPoint(0,0),false), embedder2(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false), embedder2(domainImage2D.upperBound(), false), embedder2(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false)); viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(2, embedder3(Z2i::RealPoint(0,0),false), embedder3(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false), embedder3(domainImage2D.upperBound(), false), embedder3(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false)); viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(3, embedder4(Z2i::RealPoint(0,0),false), embedder4(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false), embedder4(domainImage2D.upperBound(), false), embedder4(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false)); viewer.setFillColor(DGtal::Color(250,20,20,255)); viewer << pcenter; viewer << Viewer3D<>::updateDisplay; bool res = application.exec(); trace.emphase() << ( res ? "Passed." : "Error." ) << endl; trace.endBlock(); return res ? 0 : 1; }
int main( int argc, char** argv ) { typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D; typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char > Image2D; // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("sliceOrientation,s", po::value<unsigned int>()->default_value(2), "specify the slice orientation for which the slice are considered (by default =2 (Z direction))" ) ("input,i", po::value<std::vector <std::string> >()->multitoken(), "input 2D files (.pgm) " ) ("output,o", po::value<std::string>(), "volumetric file (.vol, .longvol .pgm3d) " ); bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")) { std::cout << "Usage: " << argv[0] << " [input-files] [output]\n" << "Convert set of 2D images into volumetric file (pgm3d, vol, longvol) " << general_opt << "\n"; std::cout << "Example:\n" << "slice2vol -i slice1.pgm slice2.pgm slice3.pgm -o vol.p3d \n" << "see vol2slice"<<endl; return 0; } if(! vm.count("input-files")||! vm.count("output")) { trace.error() << " Input and output filename are needed to be defined" << endl; return 0; } std::string outputFileName = vm["output"].as<std::string>(); std::vector<string> vectImage2DNames = vm["input"].as<std::vector<std::string> >(); unsigned int sliceOrientation = vm["sliceOrientation"].as<unsigned int>(); std::vector<Image2D> vectImages2D; // Reading all images for(unsigned int i=0; i< vectImage2DNames.size(); i++){ trace.info() << "Reading image " << i ; Image2D image = GenericReader<Image2D>::import(vectImage2DNames.at(i)); vectImages2D.push_back(image); trace.info() << " [done]" << std::endl; } Image2D::Domain domImage2D = vectImages2D.at(0).domain(); DGtal::functors::Projector<DGtal::Z3i::Space> projIn3Dlower(0); DGtal::functors::Projector<DGtal::Z3i::Space> projIn3Dupper(vectImages2D.size()-1); projIn3Dlower.initAddOneDim(sliceOrientation); projIn3Dupper.initAddOneDim(sliceOrientation); Image3D::Domain domImage3D (projIn3Dlower(vectImages2D.at(0).domain().lowerBound()), projIn3Dupper(vectImages2D.at(0).domain().upperBound())); Image3D imageResult (domImage3D); for( unsigned int i=0; i<vectImages2D.size(); i++){ Image2D sliceImage = vectImages2D.at(i); DGtal::functors::Projector<DGtal::Z3i::Space> projIn3D(i); projIn3D.initAddOneDim(sliceOrientation); for(Image2D::Domain::ConstIterator it = sliceImage.domain().begin(); it!= sliceImage.domain().end(); it++){ Z3i::Point pt =projIn3D(*it); imageResult.setValue(pt, sliceImage(*it)); } } trace.info() << "Exporting 3d image ... " << std::endl ; GenericWriter<Image3D>::exportFile(outputFileName, imageResult); trace.info() << "[done]"; return 0; }
bool testSliceImageFromFunctor() { unsigned int nbok = 0; unsigned int nb = 0; std::string filename = testPath + "samples/cat10.vol"; trace.beginBlock ( "Testing block ..." ); typedef DGtal::ImageContainerBySTLVector<DGtal::Z3i::Domain, unsigned char> Image3D; typedef DGtal::ConstImageAdapter<Image3D, DGtal::Z2i::Domain, DGtal::Projector< DGtal::Z3i::Space>, Image3D::Value, DGtal::DefaultFunctor > MySliceImageAdapter; typedef DGtal::ConstImageAdapter<Image3D, DGtal::Z2i::Domain, DGtal::SliceRotator2D< HyperRectDomain<SpaceND<3, int> >, int>, Image3D::Value, DGtal::DefaultFunctor > MyRotatorSliceImageAdapter; bool res= true; Image3D image = VolReader<Image3D>::importVol( filename ); DGtal::Projector<DGtal::Z2i::Space> projX(0); projX.initRemoveOneDim(0); DGtal::Z2i::Domain domainX(projX(image.domain().lowerBound()), projX(image.domain().upperBound())); DGtal::Projector<DGtal::Z3i::Space> aSliceFunctor(20); aSliceFunctor.initAddOneDim(0); MySliceImageAdapter sliceImageX(image, domainX, aSliceFunctor, DGtal::DefaultFunctor()); res &= PGMWriter<MySliceImageAdapter>::exportPGM("exportedSlice2DDimX.pgm",sliceImageX); DGtal::Projector<DGtal::Z2i::Space> projY(0); projY.initRemoveOneDim(1); DGtal::Z2i::Domain domainY(projY(image.domain().lowerBound()), projY(image.domain().upperBound())); DGtal::Projector<DGtal::Z3i::Space> aSliceFunctor2(20); aSliceFunctor2.initAddOneDim(1); MySliceImageAdapter sliceImageY(image, domainY, aSliceFunctor2, DGtal::DefaultFunctor()); res &= PGMWriter<MySliceImageAdapter>::exportPGM("exportedSlice2DDimY.pgm",sliceImageY); DGtal::Projector<DGtal::Z2i::Space> projZ(0); projZ.initRemoveOneDim(2); DGtal::Z2i::Domain domainZ(projZ(image.domain().lowerBound()), projZ(image.domain().upperBound())); DGtal::Projector<DGtal::Z3i::Space> aSliceFunctor3(20); aSliceFunctor3.initAddOneDim(2); MySliceImageAdapter sliceImageZ(image, domainZ, aSliceFunctor3, DGtal::DefaultFunctor()); res &= PGMWriter<MySliceImageAdapter>::exportPGM("exportedSlice2DDimZ.pgm",sliceImageZ); PointVector<3, int> center(0,0,0); DGtal::SliceRotator2D< HyperRectDomain<SpaceND<3, int> >, int> sliceRot(2, image.domain(), 20, 2, 0.5, center); MyRotatorSliceImageAdapter sliceRotImageZ(image, domainZ, sliceRot, DGtal::DefaultFunctor()); res &= PGMWriter<MyRotatorSliceImageAdapter>::exportPGM("exportedRotSliceZ.pgm",sliceRotImageZ); nbok += res ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "true == true" << std::endl; trace.endBlock(); return nbok == nb; }
int main(int argc, char** argv) { // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("inputFile,i", po::value<std::string>(), "source image used to extract the tangential images." ) ("outputFile,o", po::value<std::string>(), "set output filename (default output)." ) ("center,c", po::value<std::vector <int> >()->multitoken(), "The coordinates of the center to define the seed (default (0,0)). ") ("height", po::value<unsigned int>()->default_value(50), "Height of the extracted image. ") ("distanceImage,d", po::value<double >()->default_value(100.0), "define the distance of the extracted image from the center . ") ("startAngle,s", po::value<double >()->default_value(0), "specify the start angle which will define the image. ") ("endAngle,e", po::value<double >()->default_value(45), "specify the end angle which will define the image. ") ("points,p", po::value<std::vector <int> >()->multitoken(), "The 2D coordinates of the points of the slice image. "); bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")||argc<=1) { std::cout << "Usage: " << argv[0] << " [input-file]\n" << "Extract tangential image from volumetric images. " << general_opt << "\n"; return 0; } if(! (vm.count("inputFile"))) { trace.error() << " No input file was given" << endl; return 0; } if(! (vm.count("outputFile"))) { trace.error() << " No outputFile file was given" << endl; return 0; } string inputFilename = vm["inputFile"].as<std::string>(); string outputFilename = vm["outputFile"].as<std::string>(); Image3D imageVol = DicomReader< Image3D, RescalFCT >::importDicom(inputFilename, RescalFCT(-900, 500, 0, 255)); trace.info() << imageVol.domain(); trace.info()<< "Reading dicom [done]"<<std:: endl; Z3i::Point center(0,0, 0); if(vm.count("center")){ std::vector<int> centerC= vm["center"].as<std::vector <int> >(); if(centerC.size()!=3){ trace.info() << "Incomplete option \"--center\""<< std::endl; return 0; } center[0]= centerC[0]; center[1]= centerC[1]; center[2]= centerC[2]; } // Dimension of the image domain: double distanceImage = vm["distanceImage"].as<double>(); double startAngle = ((vm["startAngle"].as<double>())/180.0)*3.14; double endAngle = ((vm["endAngle"].as<double>())/180)*3.14; if (startAngle>endAngle) endAngle+=6.28; double angleImage = endAngle-startAngle; unsigned int height = vm["height"].as<unsigned int>(); unsigned int width = 2*(unsigned int)(sin(angleImage/2.0)*distanceImage); trace.info() << "Extracted Image Dimension: " << width << " " << height << std::endl; DGtal::Z2i::Domain domainImage2D (Z2i::Point(0, 0), Z2i::Point(width, height)); //domain p1 p2, p3, p4 (counter clockwise) //bottom middle pcb Z3i::RealPoint p1, p2, p3, p4; if(!vm.count("points")){ Z3i::Point pcb(center[0]+(unsigned int) distanceImage*cos(startAngle+angleImage/2.0), center[1]+(unsigned int) distanceImage*sin(startAngle+angleImage/2.0) ,center[2]-height/2 ); Z3i::Point pct(center[0]+(unsigned int) distanceImage*cos(startAngle+angleImage/2.0), center[1]+(unsigned int)distanceImage*sin(startAngle+angleImage/2.0) , center[2]+height/2); p1 = pcb+sin(angleImage/2.0)*distanceImage*(Z3i::RealPoint(-sin(startAngle+angleImage/2.0), cos(startAngle+angleImage/2.0), 0)); p2 = pcb-sin(angleImage/2.0)*distanceImage*(Z3i::RealPoint(-sin(startAngle+angleImage/2.0), cos(startAngle+angleImage/2.0), 0)); p3 = pct-sin(angleImage/2.0)*distanceImage*(Z3i::RealPoint(-sin(startAngle+angleImage/2.0), cos(startAngle+angleImage/2.0), 0)); p4 = pct+sin(angleImage/2.0)*distanceImage*(Z3i::RealPoint(-sin(startAngle+angleImage/2.0), cos(startAngle+angleImage/2.0), 0)); trace.info() << "Points of the 3D domain: " << std::endl; trace.info() << "p1: "<< p1 << std::endl; trace.info() << "p2: "<< p2 << std::endl; trace.info() << "p3: "<< p3 << std::endl; trace.info() << "p4: "<< p4 << std::endl; }else{ std::vector< int> vectCoord = vm["points"].as<std::vector <int> >(); p1[0]=vectCoord[0]; p1[1]=vectCoord[1]; p1[2]=center[2]-height/2; p2[0]=vectCoord[2]; p2[1]=vectCoord[3]; p2[2]=center[2]-height/2; p4[0]=p1[0]; p4[1]=p1[1]; p4[2]=center[2]+height/2; } DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(imageVol.domain(), p1, p2, p4); trace.info() << imageVol.domain(); ImageAdapterExtractor extractedImage(imageVol, domainImage2D, embedder, idV); GenericWriter< ImageAdapterExtractor>::exportFile(outputFilename , extractedImage); }
int main( int argc, char** argv ) { QApplication application(argc,argv); Viewer3D<> viewer; viewer.setWindowTitle("simpleViewer"); viewer.show(); typedef ImageSelector < Z3i::Domain, unsigned char>::Type Image3D; typedef ImageSelector < Z2i::Domain, unsigned char>::Type Image2D; typedef DGtal::ConstImageAdapter<Image3D, Image2D::Domain, DGtal::Projector< Z3i::Space>, Image3D::Value, DGtal::DefaultFunctor > SliceImageAdapter; typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain>, Image3D::Value, DGtal::DefaultFunctor > ImageAdapterExtractor; DGtal::Projector<DGtal::Z2i::Space> invFunctor(2); // Importing a 3D image std::string filename = examplesPath + "samples/lobster.vol"; Image3D image = VolReader<Image3D>::importVol( filename ); DGtal::Z2i::Domain domain(invFunctor(image.domain().lowerBound()), invFunctor(image.domain().upperBound())); DGtal::DefaultFunctor idV; trace.beginBlock ( "Example extract2DImagesFrom3D" ); // Extracting 2D slices ... and visualisation on 3DViewer unsigned int pos=0; for (unsigned int i=0; i<30; i+=5){ DGtal::Projector<DGtal::Z3i::Space> aSliceFunctor(i); aSliceFunctor.initAddOneDim(2); SliceImageAdapter sliceImageZ(image, domain, aSliceFunctor, idV); viewer << sliceImageZ; viewer << DGtal::UpdateImagePosition<Z3i::Space, Z3i::KSpace>(pos, Viewer3D<>::zDirection, i*20, i*20, i*20 ); pos++; } // Visu extraction from points const int IMAGE_PATCH_WIDTH = 40; DGtal::Z3i::Point ptCenter(155, 155, 20); DGtal::Z2i::Domain domainImage2D (DGtal::Z2i::Point(0,0), DGtal::Z2i::Point(IMAGE_PATCH_WIDTH, IMAGE_PATCH_WIDTH)); DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(image.domain(), ptCenter, DGtal::Z3i::RealPoint(1,-1,1), IMAGE_PATCH_WIDTH); ImageAdapterExtractor extractedImage(image, domainImage2D, embedder, idV); viewer << extractedImage; viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(pos, embedder(Z2i::Point(0,0)), embedder(Z2i::Point(IMAGE_PATCH_WIDTH,0)), embedder(domainImage2D.upperBound()), embedder(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH))); viewer << DGtal::Viewer3D<>::updateDisplay; application.exec(); return 0; }
int main( int argc, char** argv ) { typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D; // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("input,i", po::value<std::string>(), "volumetric file (.vol) " ) ("output,o", po::value<std::string>(), "sequence of discrete point file (.sdp) " ) ("exportImageValues,e","option to export also the image value of the voxel in a fourth field.") ("thresholdMin,m", po::value<int>()->default_value(128), "min threshold (default 128)" ) ("thresholdMax,M", po::value<int>()->default_value(255), "max threshold (default 255)" ); bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")||argc<=1) { std::cout << "Usage: " << argv[0] << " [input] [output]\n" << "Convert volumetric file into a digital set of points from a given threshold." << general_opt << "\n"; std::cout << "Example:\n" << "vol2sdp -i ${DGtal}/examples/samples/lobster.vol -o volumeList.p3d \n"; return 0; } if(! vm.count("input") ||! vm.count("output")) { trace.error() << " Input and output filename are needed to be defined" << endl; return 0; } string inputFilename = vm["input"].as<std::string>(); string outputFilename = vm["output"].as<std::string>(); trace.info() << "Reading input file " << inputFilename ; Image3D inputImage = DGtal::VolReader<Image3D>::importVol(inputFilename); trace.info() << " [done] " << std::endl ; std::ofstream outStream; outStream.open(outputFilename.c_str()); int minTh = vm["thresholdMin"].as<int>(); int maxTh = vm["thresholdMax"].as<int>(); trace.info() << "Processing image to output file " << outputFilename ; //Processing all points outStream << "# sdp file generate by vol2sdp with source vol:" << inputFilename << " and threshold min: " << minTh << " max:" << maxTh << std::endl; outStream << "# format: x y z "; if(vm.count("exportImageValues")){ outStream << " image_value"; } outStream << std::endl; for(Image3D::Domain::ConstIterator it=inputImage.domain().begin(); it != inputImage.domain().end(); ++it){ if(inputImage(*it) >= minTh && inputImage(*it) <= maxTh ){ outStream << (*it)[0] << " " << (*it)[1] << " " << (*it)[2]; if(vm.count("exportImageValues")){ outStream << " " << (unsigned int) inputImage(*it); } outStream << std::endl; } } outStream.close(); trace.info() << " [done] " << std::endl ; return 0; }
/* * Kernel event */ KernelEvent::KernelEvent(CommandQueue *parent, Kernel *kernel, cl_uint work_dim, const size_t *global_work_offset, const size_t *global_work_size, const size_t *local_work_size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_int *errcode_ret) : Event(parent, Queued, num_events_in_wait_list, event_wait_list, errcode_ret), p_work_dim(work_dim), p_kernel(kernel), p_timeout_ms(0) { clRetainKernel(desc(p_kernel)); if (*errcode_ret != CL_SUCCESS) return; *errcode_ret = CL_SUCCESS; // Sanity checks if (!kernel) { *errcode_ret = CL_INVALID_KERNEL; return; } // Check that the kernel was built for parent's device. cl_device_id d_device = 0; cl_context k_ctx, q_ctx; size_t max_work_group_size; cl_uint max_dims = 0; *errcode_ret = parent->info(CL_QUEUE_DEVICE, sizeof(cl_device_id), &d_device, 0); if (*errcode_ret != CL_SUCCESS) return; auto device = pobj(d_device); *errcode_ret = parent->info(CL_QUEUE_CONTEXT, sizeof(cl_context), &q_ctx, 0); *errcode_ret |= kernel->info(CL_KERNEL_CONTEXT, sizeof(cl_context), &k_ctx, 0); *errcode_ret |= device->info(CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &max_work_group_size, 0); *errcode_ret |= device->info(CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(size_t), &max_dims, 0); *errcode_ret |= device->info(CL_DEVICE_MAX_WORK_ITEM_SIZES, max_dims * sizeof(size_t), p_max_work_item_sizes, 0); if (*errcode_ret != CL_SUCCESS) return; p_dev_kernel = kernel->deviceDependentKernel(device); if (!p_dev_kernel) { *errcode_ret = CL_INVALID_PROGRAM_EXECUTABLE; return; } // Check that contexts match if (k_ctx != q_ctx) { *errcode_ret = CL_INVALID_CONTEXT; return; } // Check args if (!kernel->argsSpecified()) { *errcode_ret = CL_INVALID_KERNEL_ARGS; return; } // Check dimension if ((work_dim == 0 || work_dim > max_dims) || (max_dims > MAX_WORK_DIMS)) { *errcode_ret = CL_INVALID_WORK_DIMENSION; return; } // Populate work_offset, work_size and local_work_size size_t work_group_size = 1; cl_uint dims[3]; kernel->reqdWorkGroupSize(kernel->deviceDependentModule(device), dims); uint32_t reqd_x = dims[0]; uint32_t reqd_y = dims[1]; uint32_t reqd_z = dims[2]; bool reqd_any = reqd_x > 0 || reqd_y > 0 || reqd_z > 0; if (reqd_any) { // if __attribute__((reqd_work_group_size(X, Y, Z))) is set and local size not specified if (!local_work_size) { *errcode_ret = CL_INVALID_WORK_GROUP_SIZE; return; } // if __attribute__((reqd_work_group_size(X, Y, Z))) doesn't match else { if (( local_work_size[0] != reqd_x) || (work_dim > 1 && local_work_size[1] != reqd_y) || (work_dim > 2 && local_work_size[2] != reqd_z)) { *errcode_ret = CL_INVALID_WORK_GROUP_SIZE; return; } } } // If kernel has zero arguments if (local_work_size && local_work_size[0] == 0) return; cl_uint i; for (i=0; i<work_dim; ++i) { if (global_work_offset) { p_global_work_offset[i] = global_work_offset[i]; } else { p_global_work_offset[i] = 0; } if (!global_work_size || !global_work_size[i]) { *errcode_ret = CL_INVALID_GLOBAL_WORK_SIZE; return; } p_global_work_size[i] = global_work_size[i]; if (!local_work_size) { // Guess the best value according to the device p_local_work_size[i] = p_dev_kernel->guessWorkGroupSize(work_dim, i, global_work_size[i]); } else { // Check divisibility if ((global_work_size[i] % local_work_size[i]) != 0) { *errcode_ret = CL_INVALID_WORK_GROUP_SIZE; return; } // Not too big ? if (local_work_size[i] > p_max_work_item_sizes[i]) { *errcode_ret = CL_INVALID_WORK_ITEM_SIZE; return; } p_local_work_size[i] = local_work_size[i]; work_group_size *= local_work_size[i]; } } // initialize missing dimensions for (; i < max_dims; i++) { p_global_work_offset[i] = 0; p_global_work_size[i] = 1; p_local_work_size[i] = 1; } // Check we don't ask too much to the device if (work_group_size > max_work_group_size) { *errcode_ret = CL_INVALID_WORK_GROUP_SIZE; return; } // Check arguments (buffer alignment, image size, ...) for (unsigned int i=0; i<kernel->numArgs(); ++i) { const Kernel::Arg &a = kernel->arg(i); if (a.kind() == Kernel::Arg::Buffer && a.file() != Kernel::Arg::Local) { MemObject *buffer = *(MemObject **)(a.value(0)); if (!BufferEvent::isSubBufferAligned(buffer, device)) { *errcode_ret = CL_MISALIGNED_SUB_BUFFER_OFFSET; return; } clRetainMemObject(desc(buffer)); p_mem_objects.push_back((MemObject *) buffer); } else if (a.kind() == Kernel::Arg::Image2D) { Image2D *image = *(Image2D **)(a.value(0)); size_t maxWidth, maxHeight; *errcode_ret = device->info(CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &maxWidth, 0); *errcode_ret |= device->info(CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &maxHeight, 0); if (*errcode_ret != CL_SUCCESS) return; if (image->width() > maxWidth || image->height() > maxHeight) { *errcode_ret = CL_INVALID_IMAGE_SIZE; return; } clRetainMemObject(desc(image)); p_mem_objects.push_back((MemObject *) image); } else if (a.kind() == Kernel::Arg::Image3D) { Image3D *image = *(Image3D **)a.value(0); size_t maxWidth, maxHeight, maxDepth; *errcode_ret = device->info(CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &maxWidth, 0); *errcode_ret |= device->info(CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &maxHeight, 0); *errcode_ret |= device->info(CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &maxDepth, 0); if (*errcode_ret != CL_SUCCESS) return; if (image->width() > maxWidth || image->height() > maxHeight || image->depth() > maxDepth) { *errcode_ret = CL_INVALID_IMAGE_SIZE; return; } clRetainMemObject(desc(image)); p_mem_objects.push_back((MemObject *) image); } } // Check if kernel has timeout specified and CommandQueue allows it if (kernel->getTimeout() > 0) { cl_command_queue_properties queue_props; *errcode_ret = parent->info(CL_QUEUE_PROPERTIES, sizeof(cl_command_queue_properties), &queue_props, 0); if (*errcode_ret != CL_SUCCESS) return; if ((queue_props & CL_QUEUE_KERNEL_TIMEOUT_COMPUTE_UNIT_TI) != 0) p_timeout_ms = kernel->getTimeout(); } }
/*! * Name : rayTraceFiller * Description: Used to generate rachis segmentation * Arguments : PROTO_INPUT : protobuf input containing segmented germline * IMAGE_OUTPUT : float image containing intermediate rachis segmentation. This * image needs to be post-processed (thresholding, throw out * unconnected components). * Syntax : ./segpipeline_FREEBSD 0 0 0 0 0 PROTO_INPUT 0 0 rayTraceFiller 32 IMAGE_OUTPUT 0 0 0 0 0 0 0 0 * Notes : This function has a random component, so you won't get the exact same result every time. */ void rayTraceFiller(TextIO* inputText, ImageIO* outputImage, CallbackFunctions *cb) { log(cb, 4, "Calculating rachis segmentation through ray tracing"); // generate full segmentation Protobuf proto(cb); proto.readProto(inputText); Image3D<float> *I = new Image3D<float> (cb); Array1D<float> color(cb); proto.getList("protobuf_index", &color); color + 1; proto.drawSegmentationImage("full", I, &color); // generate points spaced uniformly on a sphere double Jiggle = 0.03 / sqrt(double(NUM_UNIFORM_POINTS_ON_SPHERE)); unsigned int Rounds = 5000; points P("default", NUM_UNIFORM_POINTS_ON_SPHERE, Jiggle, Rounds); Array1D<float> *xUniformP = new Array1D<float> (cb); Array1D<float> *yUniformP = new Array1D<float> (cb); Array1D<float> *zUniformP = new Array1D<float> (cb); P.report(xUniformP, yUniformP, zUniformP); // allocate rayScore. 0 if not yet checked, 1 if collision, 2 if no collision int dimx, dimy, dimz; I->getDimensions(dimx, dimy, dimz); boost::multi_array<unsigned char, 4> *rayScore = new boost::multi_array< unsigned char, 4>( boost::extents[dimx][dimy][dimz][NUM_UNIFORM_POINTS_ON_SPHERE]); // allocate array for progress bar Array1D<float> *progress = new Array1D<float> (cb); progress->resize(NUM_UNIFORM_POINTS_ON_SPHERE); // do ray tracing log(cb, 4, "Starting ray tracing"); #if defined USELIBDISPATCH dispatch_apply(NUM_UNIFORM_POINTS_ON_SPHERE, dispatch_get_global_queue(0,0), ^(size_t ii) { #else for (int ii = 0; ii < NUM_UNIFORM_POINTS_ON_SPHERE; ii++) { #endif int i = (int) ii; // get a discrete line int xP = iround(LENGTH_BRESENHAM_LINE * (*xUniformP)(i)); int yP = iround(LENGTH_BRESENHAM_LINE * (*yUniformP)(i)); int zP = iround(LENGTH_BRESENHAM_LINE * (*zUniformP)(i)); Array1D<int> xLine(cb), yLine(cb), zLine(cb); bresenhamLine(&xLine, &yLine, &zLine, xP, yP, zP); // check if ray hits image boundary for every pixel in the image for (int xc = 0; xc < dimx; xc++) { for (int yc = 0; yc < dimy; yc++) { for (int zc = 0; zc < dimz; zc++) { // only do ray tracing if ray has not passed through point previously. if ((*rayScore)[xc][yc][zc][i] == 0) { // iterate over length of ray for (int r = 0; r < yLine.size(); r++) { int x = xc + xLine(r), y = yc + yLine(r), z = zc + zLine(r); if (x >= 0 & x < dimx & y >= 0 & y < dimy & z >= 0 & z < dimz) { // check if ray in image boundary if ((*I)(x, y, z) > float(BWTHRESH)) { // if collision detected, update collision information for all points on ray for (int rr = 0; rr <= r; rr++) { int xx = xc + xLine(rr), yy = yc + yLine(rr), zz = zc + zLine(rr); (*rayScore)[xx][yy][zz][i] = 1; } break; } // else ray has reach image boundary } else { // update non-collision information on all points on the ray for (int rr = 0; rr < r; rr++) { int xx = xc + xLine(rr), yy = yc + yLine(rr), zz = zc + zLine(rr); (*rayScore)[xx][yy][zz][i] = 2; } break; // break out of iteration over length of the ray } } // end iterate over length of ray } } } } // update progress (*progress)(i) = 1; int progressOutOf100 = (int) (progress->sum() / NUM_UNIFORM_POINTS_ON_SPHERE * 100); cb->progressReport(progressOutOf100); #if defined USELIBDISPATCH }); #else }
int main( int argc, char** argv ) { typedef DGtal::ImageContainerBySTLVector<DGtal::Z3i::Domain, unsigned char > Image3D; QApplication application(argc,argv); typedef Viewer3D<> MyViewer; MyViewer viewer; viewer.show(); std::string inputFilename = examplesPath + "samples/lobster.vol"; Image3D imageVol = VolReader<Image3D>::importVol(inputFilename); //! [ExampleViewer3D2DImagesExtractImages] // Extracting the 2D images from the 3D one and from a given dimension. // First image the teenth Z slice (dim=2) typedef DGtal::ConstImageAdapter<Image3D, DGtal::Z2i::Domain, DGtal::functors::Projector< DGtal::Z3i::Space>, Image3D::Value, DGtal::functors::Identity > MySliceImageAdapter; // Define the functor to recover a 2D domain from the 3D one in the Z direction (2): DGtal::functors::Projector<DGtal::Z2i::Space> transTo2DdomainFunctorZ; transTo2DdomainFunctorZ.initRemoveOneDim(2); DGtal::Z2i::Domain domain2DZ(transTo2DdomainFunctorZ(imageVol.domain().lowerBound()), transTo2DdomainFunctorZ(imageVol.domain().upperBound())); // Define the functor to associate 2D coordinates to the 3D one by giving the direction Z (2) and the slide numnber (10): DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctorZ(10); aSliceFunctorZ.initAddOneDim(2); // We can now obtain the slice image (a ConstImageAdapter): const auto identityFunctor = DGtal::functors::Identity(); MySliceImageAdapter aSliceImageZ(imageVol, domain2DZ, aSliceFunctorZ, identityFunctor ); // Second image the fiftieth Y slice (dim=1) // Define the functor to recover a 2D domain from the 3D one in the Y direction (1): DGtal::functors::Projector<DGtal::Z2i::Space> transTo2DdomainFunctorY; transTo2DdomainFunctorY.initRemoveOneDim(1); DGtal::Z2i::Domain domain2DY(transTo2DdomainFunctorY(imageVol.domain().lowerBound()), transTo2DdomainFunctorY(imageVol.domain().upperBound())); // Define the functor to associate 2D coordinates to the 3D one by giving the direction Y (1) and the slide numnber (50): DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctorY(50); aSliceFunctorY.initAddOneDim(1); // We can now obtain the slice image (a ConstImageAdapter): MySliceImageAdapter aSliceImageY(imageVol, domain2DY, aSliceFunctorY, identityFunctor ); //! [ExampleViewer3D2DImagesExtractImages] //! [ExampleViewer3D2DChangeMode] viewer << SetMode3D(aSliceImageZ.className(), "BoundingBox"); viewer << MyViewer::updateDisplay; //! [ExampleViewer3D2DChangeMode] //! [ExampleViewer3D2DImagesDisplayImages] viewer << aSliceImageZ; viewer << aSliceImageY; //! [ExampleViewer3D2DImagesDisplayImages] viewer << SetMode3D(aSliceImageZ.className(), ""); //! [ExampleViewer3D2DImagesDisplayImagesColor] viewer << AddTextureImage2DWithFunctor<MySliceImageAdapter, hueFct, Z3i::Space, Z3i::KSpace> (aSliceImageZ, hueFct(), Viewer3D<Z3i::Space, Z3i::KSpace>::RGBMode); viewer << AddTextureImage2DWithFunctor<MySliceImageAdapter, hueFct, Z3i::Space, Z3i::KSpace> (aSliceImageY, hueFct(), Viewer3D<Z3i::Space, Z3i::KSpace>::RGBMode); //! [ExampleViewer3D2DImagesDisplayImagesColor] //! [ExampleViewer3D2DModifImages] viewer << DGtal::UpdateImagePosition<Z3i::Space, Z3i::KSpace>(1, MyViewer::yDirection, 0.0, 50.0, 0.0); viewer << DGtal::UpdateImageData<MySliceImageAdapter>(0, aSliceImageZ, 0, 0, 10); viewer << MyViewer::updateDisplay; //! [ExampleViewer3D2DModifImages] //! [ExampleViewer3D2DModifImagesColor] viewer << DGtal::UpdateImagePosition<Z3i::Space, Z3i::KSpace>(3, MyViewer::yDirection, 500.0, 50.0, 0.0); viewer << DGtal::UpdateImageData<MySliceImageAdapter, hueFct>(2, aSliceImageZ, 500, 0, 10, 0.0, MyViewer::zDirection, hueFct()); viewer << MyViewer::updateDisplay; //! [ExampleViewer3D2DModifImagesColor] return application.exec(); trace.endBlock(); return 0; }
int main( int argc, char** argv ) { typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D; typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char> Image2D; typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain>, Image3D::Value, DGtal::functors::Identity > ImageAdapterExtractor; // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("input,i", po::value<std::string>(), "vol file (.vol, .longvol .p3d, .pgm3d and if WITH_ITK is selected: dicom, dcm, mha, mhd). For longvol, dicom, dcm, mha or mhd formats, the input values are linearly scaled between 0 and 255." ) ("output,o", po::value<std::string>(), "sequence of discrete point file (.sdp) ") ("thresholdMin,m", po::value<int>()->default_value(128), "min threshold (default 128)" ) ("thresholdMax,M", po::value<int>()->default_value(255), "max threshold (default 255)" ) ("nx", po::value<double>()->default_value(0), "set the x component of the projection direction." ) ("ny", po::value<double>()->default_value(0), "set the y component of the projection direction." ) ("nz", po::value<double>()->default_value(1), "set the z component of the projection direction." ) ("centerX,x", po::value<unsigned int>()->default_value(0), "choose x center of the projected image." ) ("centerY,y", po::value<unsigned int>()->default_value(0), "choose y center of the projected image." ) ("centerZ,z", po::value<unsigned int>()->default_value(1), "choose z center of the projected image." ) ("width", po::value<unsigned int>()->default_value(100), "set the width of the resulting height Field image." ) ("height", po::value<unsigned int>()->default_value(100), "set the height of the resulting height Field image." ) ("heightFieldMaxScan", po::value<unsigned int>()->default_value(255), "set the maximal scan deep." ) ("setBackgroundLastDepth", "change the default background (black with the last filled intensity).") ("rescaleInputMin", po::value<DGtal::int64_t>()->default_value(0), "min value used to rescale the input intensity (to avoid basic cast into 8 bits image).") ("rescaleInputMax", po::value<DGtal::int64_t>()->default_value(255), "max value used to rescale the input intensity (to avoid basic cast into 8 bits image)."); bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")||argc<=1) { std::cout << "Usage: " << argv[0] << " [input] [output]\n" << "Convert volumetric file into a projected 2D image given from a normal direction N and from a starting point P. The 3D volume is scanned in this normal direction N starting from P with a step 1. If the intensity of the 3d point is inside the given thresholds its 2D gray values are set to the current scan number." << general_opt << "\n"; std::cout << "Example:\n" << "vol2heightfield -i ${DGtal}/examples/samples/lobster.vol -m 60 -M 500 --nx 0 --ny 0.7 --nz -1 -x 150 -y 0 -z 150 --width 300 --height 300 --heightFieldMaxScan 350 -o resultingHeightMap.pgm \n"; return 0; } if(! vm.count("input") ||! vm.count("output")) { trace.error() << " Input and output filename are needed to be defined" << endl; return 0; } string inputFilename = vm["input"].as<std::string>(); string outputFilename = vm["output"].as<std::string>(); DGtal::int64_t rescaleInputMin = vm["rescaleInputMin"].as<DGtal::int64_t>(); DGtal::int64_t rescaleInputMax = vm["rescaleInputMax"].as<DGtal::int64_t>(); trace.info() << "Reading input file " << inputFilename ; typedef DGtal::functors::Rescaling<DGtal::int64_t ,unsigned char > RescalFCT; Image3D inputImage = GenericReader< Image3D >::importWithValueFunctor( inputFilename,RescalFCT(rescaleInputMin, rescaleInputMax, 0, 255) ); trace.info() << " [done] " << std::endl ; std::ofstream outStream; outStream.open(outputFilename.c_str()); int minTh = vm["thresholdMin"].as<int>(); int maxTh = vm["thresholdMax"].as<int>(); trace.info() << "Processing image to output file " << outputFilename << std::endl; unsigned int widthImageScan = vm["height"].as<unsigned int>(); unsigned int heightImageScan = vm["width"].as<unsigned int>(); unsigned int maxScan = vm["heightFieldMaxScan"].as<unsigned int>(); if(maxScan > std::numeric_limits<Image2D::Value>::max()){ maxScan = std::numeric_limits<Image2D::Value>::max(); trace.warning()<< "value --setBackgroundLastDepth outside mox value of image. Set to max value:" << maxScan << std::endl; } unsigned int centerX = vm["centerX"].as<unsigned int>(); unsigned int centerY = vm["centerY"].as<unsigned int>(); unsigned int centerZ = vm["centerZ"].as<unsigned int>(); double nx = vm["nx"].as<double>(); double ny = vm["ny"].as<double>(); double nz = vm["nz"].as<double>(); Image2D::Domain aDomain2D(DGtal::Z2i::Point(0,0), DGtal::Z2i::Point(widthImageScan, heightImageScan)); Z3i::Point ptCenter (centerX, centerY, centerZ); Z3i::RealPoint normalDir (nx, ny, nz); Image2D resultingImage(aDomain2D); for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin(); it != resultingImage.domain().end(); it++){ resultingImage.setValue(*it, 0); } DGtal::functors::Identity idV; unsigned int maxDepthFound = 0; for(unsigned int k=0; k < maxScan; k++){ Z3i::Point c (ptCenter+normalDir*k, DGtal::functors::Round<>()); DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(inputImage.domain(), c, normalDir, widthImageScan); ImageAdapterExtractor extractedImage(inputImage, aDomain2D, embedder, idV); for(Image2D::Domain::ConstIterator it = extractedImage.domain().begin(); it != extractedImage.domain().end(); it++){ if( resultingImage(*it)== 0 && extractedImage(*it) < maxTh && extractedImage(*it) > minTh){ maxDepthFound = k; resultingImage.setValue(*it, maxScan-k); } } } if (vm.count("setBackgroundLastDepth")){ for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin(); it != resultingImage.domain().end(); it++){ if( resultingImage(*it)== 0 ){ resultingImage.setValue(*it, maxScan-maxDepthFound); } } } resultingImage >> outputFilename; trace.info() << " [done] " << std::endl ; return 0; }
int main(int argc, char** argv) { po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("volumeFile,v", po::value<std::string>(), "import volume image (dicom format)" ) ("scaleX,x", po::value<float>()->default_value(1.0), "set the scale value in the X direction (default 1.0)" ) ("scaleY,y", po::value<float>()->default_value(1.0), "set the scale value in the Y direction (default 1.0)" ) ("scaleZ,z", po::value<float>()->default_value(1.0), "set the scale value in the Z direction (default 1.0)") ("centerCoord", po::value<std::vector <unsigned int> >()->multitoken(), "x, y, z coordinate of the center" ); bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")||argc<=1) { std::cout << "Usage: " << argv[0] << " [input-file]\n" << "Display trunk as patches images " << general_opt << "\n"; return 0; } QApplication application(argc,argv); My3DViewer viewer; viewer.setWindowTitle("visu patches"); viewer.show(); float sx = vm["scaleX"].as<float>(); float sy = vm["scaleY"].as<float>(); float sz = vm["scaleZ"].as<float>(); viewer.setGLScale(sx,sy,sz); Image3D imageVol = DicomReader< Image3D, RescalFCT >::importDicom(vm["volumeFile"].as<std::string>(), RescalFCT(-900, 530, 0, 255)); Z2i::RealPoint center (vm["centerCoord"].as<std::vector<unsigned int> >()[0], vm["centerCoord"].as<std::vector<unsigned int> >()[1]); Z3i::Point upper = imageVol.domain().upperBound(); Z3i::Point lower = imageVol.domain().lowerBound(); Z2i::RealPoint center2Dz ((upper[0]-lower[0])/2, (upper[1]-lower[1])/2); DGtal::Mesh<Z3i::RealPoint> meshTrunk(true); DGtal::Mesh<Z3i::RealPoint> meshTrunk2(true); double distanceTranslation= 70; double dir = (350/180.0)*3.142; Z3i::RealPoint translationVect(distanceTranslation*cos(dir), distanceTranslation*sin(dir), 0); meshQuadZCylinder(imageVol, viewer, meshTrunk, center, 0, 170.0, true, 33, 367, 400, 31, 324, 5, 0.5); meshQuadZCylinder(imageVol, viewer, meshTrunk2, center, 0, 170.0, true,33, 367, 400, 324, 31, 5, 0.5, translationVect); embeddMeshInVol(imageVol, viewer, meshTrunk ); embeddMeshInVol(imageVol, viewer, meshTrunk2, translationVect ); viewer << My3DViewer::updateDisplay; return application.exec(); }