// ------------------------------------------------------------------------ void LoadImage(const std::string &filename, ImageType::Pointer &image) { typedef itk::Image<unsigned short, 4> InImageType; typedef itk::ImageFileReader<InImageType> ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(filename); reader->SetImageIO(itk::NrrdImageIO::New()); reader->Update(); typedef itk::ExtractImageFilter<InImageType, ImageType> ExtractorType; ExtractorType::Pointer extractor = ExtractorType::New(); extractor->SetInput(reader->GetOutput()); InImageType::RegionType exRegion = reader->GetOutput()->GetLargestPossibleRegion(); InImageType::SizeType exSize = exRegion.GetSize(); InImageType::IndexType exIndex = exRegion.GetIndex(); exSize[3] = 0; exIndex[3] = 0; exRegion.SetSize(exSize); exRegion.SetIndex(exIndex); extractor->SetExtractionRegion(exRegion); extractor->SetDirectionCollapseToSubmatrix(); extractor->Update(); image = extractor->GetOutput(); }
int main(int argc, char *argv[]) { if (argc != 2) { cerr << "Usage : " << argv[0] << " configFile" << endl; return 0; } // By default (with no use of MPI) we are alone with id 0 (master) int procNbr = 1; int procId = 0; /******************************************************************************/ #ifdef USE_MPI cout << "Initializing MPI" << endl; MPI_Init(NULL, NULL); MPI_Comm_size(MPI_COMM_WORLD, &procNbr); MPI_Comm_rank(MPI_COMM_WORLD, &procId); #endif /******************************************************************************/ cout << "Configuring code" << endl; ConfigReader config(argv[1]); if (!config.complete()) { cerr << "Bad configuration file" << endl; closeMpiIfUsed(); return 0; } ostringstream streamProcId; streamProcId << procId; string strProcId = streamProcId.str(); /******************************************************************************/ cout << "Reading and thresholding image" << endl; // Read ImageReader::Pointer reader = ImageReader::New(); reader->SetFileName(config.imgPath); reader->Update(); // Set the ROI InImageType::RegionType ROI = reader->GetOutput()->GetLargestPossibleRegion(); InImageType::RegionType::IndexType orig = ROI.GetIndex(); InImageType::RegionType::SizeType size = ROI.GetSize(); int cutDimension = config.cutDim; if (cutDimension < 0 || cutDimension > 2) { if (size[2] > 1) // 3D input image { cutDimension = 2; } else { cutDimension = 1; } } int wholeSize = size[cutDimension]; size[cutDimension] /= procNbr; orig[cutDimension] = procId * size[cutDimension]; if (procId == procNbr - 1) { size[cutDimension] = wholeSize - orig[cutDimension]; } ROI.SetIndex(orig); ROI.SetSize(size); reader->GetOutput()->SetRequestedRegion(ROI); // Threshold ThresholdFilter::Pointer threshold = ThresholdFilter::New(); threshold->SetInput(reader->GetOutput()); threshold->SetLowerThreshold(0); threshold->SetUpperThreshold(config.thresholdValue); threshold->SetInsideValue(pixmsh::FEFactory::PIXEL_BLACK); threshold->SetOutsideValue(pixmsh::FEFactory::PIXEL_WHITE); threshold->GetOutput()->SetRequestedRegion(ROI); threshold->Update(); // Really perform the pre-process /******************************************************************************/ cout << "Creating nodes and elements" << endl; InIterator::RadiusType radius; radius.Fill(1); // 3x3x3 centered region BoundaryConditionType boundaryCondition; boundaryCondition.SetConstant(pixmsh::FEFactory::PIXEL_NONE); InIterator it(radius, threshold->GetOutput(), threshold->GetOutput()->GetRequestedRegion()); it.OverrideBoundaryCondition(&boundaryCondition); ios::openmode flags = ios::out | ios::trunc; if (config.format == CFG_FORMAT_BIN) { flags |= ios::binary; } ofstream nodesFile((config.nodesPath + strProcId).c_str(), flags); ofstream elementsFile((config.elementsPath + strProcId).c_str(), flags); // Creation of the right type factory pixmsh::FEFactory *factory = pixmsh::FEFactory::newFactory(config.elementsType, nodesFile, elementsFile); // No factory constructed if (factory == NULL) { cerr << "Factory can't be constructed" << endl; closeMpiIfUsed(); return 0; } factory->setSize(threshold->GetOutput()->GetLargestPossibleRegion().GetSize()[0], threshold->GetOutput()->GetLargestPossibleRegion().GetSize()[1], threshold->GetOutput()->GetLargestPossibleRegion().GetSize()[2]); factory->setOffset(config.offsetX, config.offsetY, config.offsetZ); factory->setSpacing(config.spacingX, config.spacingY, config.spacingZ); factory->setFlip(config.flipX, config.flipY, config.flipZ); factory->setBinaryOutput(config.format == CFG_FORMAT_BIN ? true : false); factory->setMaterials(config.materials == "both" || config.materials == "black", config.materials == "both" || config.materials == "white"); factory->init(); // Iterate std::vector<pixmsh::FEFactory::PixelValue> values(27); for (it.GoToBegin(); !it.IsAtEnd(); ++it) { for (int i = 0; i < 27; ++i) { values[i] = static_cast<pixmsh::FEFactory::PixelValue>(it.GetPixel(i)); } factory->addPixel(values, it.GetIndex()[0], it.GetIndex()[1], it.GetIndex()[2]); } factory->endOutput(); int nodesNbr = factory->nodesNbr(); int elemNbr = factory->elementsNbr(); #ifdef USE_MPI int nodesNbrTmp = factory->nodesNbr(); int elemNbrTmp = factory->elementsNbr(); MPI_Reduce(&nodesNbrTmp, &nodesNbr, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(&elemNbrTmp, &elemNbr, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); #endif /******************************************************************************/ if (procId == 0) { cout << "Writing final mesh file" << endl; assembleFinalFile(config, procNbr, nodesNbr, elemNbr); } #ifdef USE_MPI // Waiting for writing before deleting files MPI_Barrier(MPI_COMM_WORLD); #endif /******************************************************************************/ cout << "Cleaning working space" << endl; remove((config.nodesPath + strProcId).c_str()); remove((config.elementsPath + strProcId).c_str()); pixmsh::FEFactory::deleteFactory(factory); factory = NULL; /******************************************************************************/ closeMpiIfUsed(); /******************************************************************************/ cout << "Done" << endl; return 0; }