void NrrdPlugin::readSlice(int idx[3], int sz[3], int nbytes, uchar *slice) { typedef itk::Image<T, 3> ImageType; typedef itk::ImageFileReader<ImageType> ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(m_fileName[0].toAscii().data()); typedef itk::NrrdImageIO NrrdIOType; NrrdIOType::Pointer nrrdIO = NrrdIOType::New(); reader->SetImageIO(nrrdIO); typedef itk::RegionOfInterestImageFilter<ImageType,ImageType> RegionExtractor; ImageType::RegionType region; ImageType::SizeType size; ImageType::IndexType index; index[2] = idx[2]; index[1] = idx[1]; index[0] = idx[0]; size[2] = sz[2]; size[1] = sz[1]; size[0] = sz[0]; region.SetIndex(index); region.SetSize(size); // Extract the relevant sub-region. RegionExtractor::Pointer extractor = RegionExtractor::New(); extractor->SetInput(reader->GetOutput()); extractor->SetRegionOfInterest(region); extractor->Update(); ImageType *dimg = extractor->GetOutput(); char *tdata = (char*)(dimg->GetBufferPointer()); memcpy(slice, tdata, nbytes); }
//#################### PRIVATE METHODS #################### void DICOMVolumeLoader::execute_impl() try { typedef itk::GDCMImageIO ImageIO; typedef itk::Image<int,2> Image2D; typedef itk::Image<int,3> Image3D; typedef itk::JoinSeriesImageFilter<Image2D,Image3D> Joiner; typedef itk::ImageFileReader<Image2D> Reader; typedef itk::RegionOfInterestImageFilter<Image2D,Image2D> RegionExtractor; // Set up the desired region for each of the slices. Image2D::RegionType region; itk::Index<2> index = {{m_volumeChoice.minX, m_volumeChoice.minY}}; itk::Size<2> size = {{m_volumeChoice.maxX + 1 - m_volumeChoice.minX, m_volumeChoice.maxY + 1 - m_volumeChoice.minY}}; region.SetIndex(index); region.SetSize(size); std::vector<std::string> imageFilenames = m_dicomdir->image_filenames(m_volumeChoice.patientKey, m_volumeChoice.studyKey, m_volumeChoice.seriesKey); std::vector<Image2D::Pointer> images(imageFilenames.size()); for(int i=m_volumeChoice.minZ; i<=m_volumeChoice.maxZ; ++i) { std::string imageFilename = m_volumeChoice.filePrefix + imageFilenames[i]; if(!is_aborted()) { set_progress(i - m_volumeChoice.minZ); set_status("Loading image " + imageFilename + "..."); } else return; // Load the image. Reader::Pointer reader = Reader::New(); reader->SetFileName(imageFilename); ImageIO::Pointer gdcmImageIO = ImageIO::New(); reader->SetImageIO(gdcmImageIO); reader->Update(); // Extract the relevant sub-region. RegionExtractor::Pointer extractor = RegionExtractor::New(); extractor->SetInput(reader->GetOutput()); extractor->SetRegionOfInterest(region); extractor->Update(); // Store the image. images[i] = extractor->GetOutput(); images[i]->SetMetaDataDictionary(reader->GetMetaDataDictionary()); } // Get the window centre and width if they haven't been explicitly specified by the user. if(m_volumeChoice.windowSettings.unspecified()) { std::string windowCentreStr = read_header_field(images[m_volumeChoice.minZ], "0028|1050"); std::string windowWidthStr = read_header_field(images[m_volumeChoice.minZ], "0028|1051"); std::string validChars = "-0123456789"; windowCentreStr = windowCentreStr.substr(0, windowCentreStr.find_first_not_of(validChars)); windowWidthStr = windowWidthStr.substr(0, windowWidthStr.find_first_not_of(validChars)); double windowCentre = lexical_cast<double>(windowCentreStr); double windowWidth = lexical_cast<double>(windowWidthStr); m_volumeChoice.windowSettings = WindowSettings(windowCentre, windowWidth); } // Make the images into a volume. Joiner::Pointer joiner = Joiner::New(); double minSliceLocation = 0; try { minSliceLocation = lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ], "0020|1041")); } catch(bad_lexical_cast&) { throw Exception("The SliceLocation value for the slice was not of the appropriate type"); } joiner->SetOrigin(minSliceLocation); double sliceThickness = 0; if(m_volumeChoice.minZ + 1 <= m_volumeChoice.maxZ) { try { double nextSliceLocation = lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ+1], "0020|1041")); sliceThickness = fabs(nextSliceLocation - minSliceLocation); } catch(bad_lexical_cast&) {} } if(sliceThickness == 0) { try { sliceThickness = lexical_cast<double>(read_header_field(images[m_volumeChoice.minZ], "0018|0050")); } catch(bad_lexical_cast&) { throw Exception("The SliceThickness value for the slice was not of the appropriate type"); } } joiner->SetSpacing(sliceThickness); for(int i=m_volumeChoice.minZ; i<=m_volumeChoice.maxZ; ++i) joiner->PushBackInput(images[i]); joiner->Update(); Image3D::Pointer volumeImage = joiner->GetOutput(); // Determine the modality of the images. DICOMVolume::Modality modality = DICOMVolume::UNSUPPORTED_MODALITY; std::string modalityString = read_header_field(images[m_volumeChoice.minZ], "0008|0060"); if(modalityString == "CT") modality = DICOMVolume::CT; else if(modalityString == "MR") modality = DICOMVolume::MR; if(modality == DICOMVolume::UNSUPPORTED_MODALITY) { throw Exception("Cannot currently handle modalities other than CT and MR - sorry!"); } m_volume.reset(new DICOMVolume(volumeImage, modality)); } catch(std::exception& e) { abort(); set_status(e.what()); }