Page MenuHomePhabricator

Philips3D_DCM_Patch2.patch

Authored By
graser
Dec 29 2010, 5:54 PM
Size
18 KB
Referenced Files
None
Subscribers
None

Philips3D_DCM_Patch2.patch

Index: Core/Code/Algorithms/mitkDataNodeFactory.cpp
===================================================================
--- Core/Code/Algorithms/mitkDataNodeFactory.cpp (revision 28567)
+++ Core/Code/Algorithms/mitkDataNodeFactory.cpp (working copy)
@@ -229,6 +229,25 @@
std::locale l( "C" );
std::cin.imbue(l);
+ #if GDCM_MAJOR_VERSION >= 2
+ if ( DicomSeriesReader::IsPhilips3DDicom(this->GetFileName()) )
+ {
+ MITK_INFO << "it is a Philips3D US Dicom file" << std::endl;
+ this->ResizeOutputs(1);
+ DataNode::Pointer node = this->GetOutput(0);
+ mitk::DicomSeriesReader::StringContainer stringvec;
+ stringvec.push_back(this->GetFileName());
+ if (DicomSeriesReader::LoadDicomSeries(stringvec, *node))
+ {
+ node->SetName(this->GetBaseFileName());
+ }
+ setlocale(LC_NUMERIC, previousCLocale);
+ std::cin.imbue(previousCppLocale);
+ return;
+
+ }
+ #endif
+
DicomSeriesReader::UidFileNamesMap names_map = DicomSeriesReader::GetSeries(this->GetDirectory(), this->m_UseSeriesDetails, this->m_SeriesRestrictions);
const unsigned int size = names_map.size();
@@ -244,7 +263,7 @@
const std::string &uid = n_it->first;
DataNode::Pointer node = this->GetOutput(i);
- MITK_INFO << "Reading series #" << i << ": " << uid << std::endl;
+ MITK_INFO << "Readng series #" << i << ": " << uid << std::endl;
if (DicomSeriesReader::LoadDicomSeries(n_it->second, *node))
{
Index: Core/Code/IO/mitkDicomSeriesReader.cpp
===================================================================
--- Core/Code/IO/mitkDicomSeriesReader.cpp (revision 28567)
+++ Core/Code/IO/mitkDicomSeriesReader.cpp (working copy)
@@ -21,6 +21,8 @@
#if GDCM_MAJOR_VERSION >= 2
#include <gdcmAttribute.h>
+ #include <gdcmPixmapReader.h>
+ #include <gdcmStringFilter.h>
#endif
namespace mitk
@@ -108,6 +110,7 @@
return false;
}
+
bool DicomSeriesReader::IsDicom(const std::string &filename)
{
DcmIoType::Pointer io = DcmIoType::New();
@@ -115,6 +118,31 @@
return io->CanReadFile(filename.c_str());
}
+#if GDCM_MAJOR_VERSION >= 2
+bool DicomSeriesReader::IsPhilips3DDicom(const std::string &filename)
+{
+ DcmIoType::Pointer io = DcmIoType::New();
+
+ if (io->CanReadFile(filename.c_str()))
+ {
+ //Look at header Tag 3001,0010 if it is "Philips3D"
+ gdcm::PixmapReader reader;
+ reader.SetFileName(filename.c_str());
+ reader.Read();
+ gdcm::DataSet &data_set = reader.GetFile().GetDataSet();
+ gdcm::StringFilter sf;
+ sf.SetFile(reader.GetFile());
+
+ if (data_set.FindDataElement(gdcm::Tag(0x3001, 0x0010)) &&
+ (sf.ToString(gdcm::Tag(0x3001, 0x0010)) == "Philips3D "))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
DicomSeriesReader::UidFileNamesMap DicomSeriesReader::GetSeries(const std::string &dir, bool additional_criteria, const StringContainer &restrictions)
{
DcmFileNamesGeneratorType::Pointer name_generator = DcmFileNamesGeneratorType::New();
Index: Core/Code/IO/mitkDicomSeriesReader.h
===================================================================
--- Core/Code/IO/mitkDicomSeriesReader.h (revision 28567)
+++ Core/Code/IO/mitkDicomSeriesReader.h (working copy)
@@ -71,6 +71,13 @@
static bool IsDicom(const std::string &filename);
/**
+ * Checks if a specific file is a Philips3D Ultrasound DICOM file.
+ */
+ #if GDCM_MAJOR_VERSION >= 2
+ static bool IsPhilips3DDicom(const std::string &filename);
+ #endif
+
+ /**
* Find all series in a particular directory.
* For each series, an enumeration of the files contained in it is created.
* Optionally, more criteria can be used to distinguish between different series, and series
Index: Core/Code/IO/mitkDicomSeriesReader.txx
===================================================================
--- Core/Code/IO/mitkDicomSeriesReader.txx (revision 28567)
+++ Core/Code/IO/mitkDicomSeriesReader.txx (working copy)
@@ -21,102 +21,272 @@
#include <mitkDicomSeriesReader.h>
#include <itkImageSeriesReader.h>
-
+//#define GDCM_MAJOR_VERSION 3
#if GDCM_MAJOR_VERSION >= 2
- #include <gdcmSorter.h>
- #include <gdcmScanner.h>
+#include <gdcmSorter.h>
+#include <gdcmScanner.h>
+#include <gdcmPixmapReader.h>
+#include <gdcmStringFilter.h>
+#include <gdcmRAWCodec.h>
#endif
namespace mitk
{
-template <typename PixelType>
-void DicomSeriesReader::LoadDicom(const StringContainer &filenames, DataNode &node, UpdateCallBackMethod callback)
-{
- const char* previousCLocale = setlocale(LC_NUMERIC, NULL);
- setlocale(LC_NUMERIC, "C");
- std::locale previousCppLocale( std::cin.getloc() );
- std::locale l( "C" );
- std::cin.imbue(l);
-
- try
+ template <typename PixelType>
+ void DicomSeriesReader::LoadDicom(const StringContainer &filenames, DataNode &node, UpdateCallBackMethod callback)
{
- mitk::Image::Pointer image = mitk::Image::New();
- CallbackCommand *command = callback ? new CallbackCommand(callback) : 0;
+ const char* previousCLocale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
+ std::locale previousCppLocale( std::cin.getloc() );
+ std::locale l( "C" );
+ std::cin.imbue(l);
+ try
+ {
+ mitk::Image::Pointer image = mitk::Image::New();
+ CallbackCommand *command = callback ? new CallbackCommand(callback) : 0;
+
#if GDCM_MAJOR_VERSION >= 2
- /******** Workaround for 4D data ***************/
- gdcm::Sorter sorter;
+ /******** Workaround for Philips 3D+t images ********/
+ if ( DicomSeriesReader::IsPhilips3DDicom(filenames.front().c_str()) )
+ {
+ // It is Philips3D!
+ // Now get PhilipsSpecific Tags
+
+ gdcm::PixmapReader reader;
+ reader.SetFileName(filenames.front().c_str());
+ reader.Read();
+ gdcm::DataSet &data_set = reader.GetFile().GetDataSet();
+ gdcm::StringFilter sf;
+ sf.SetFile(reader.GetFile());
- sorter.SetSortFunction(DicomSeriesReader::GdcmSortFunction);
- sorter.Sort(filenames);
+ gdcm::Attribute<0x0028,0x0011> dimTagX; // coloumns || sagittal
+ gdcm::Attribute<0x3001,0x1001, gdcm::VR::UL, gdcm::VM::VM1> dimTagZ; //I have no idea what is VM1. // (Philips specific) // transversal
+ gdcm::Attribute<0x0028,0x0010> dimTagY; // rows || coronal
+ gdcm::Attribute<0x0028,0x0008> dimTagT;
+ gdcm::Attribute<0x0018,0x602c> spaceTagX;
+ gdcm::Attribute<0x0018,0x602e> spaceTagY;
+ gdcm::Attribute<0x3001,0x1003, gdcm::VR::FD, gdcm::VM::VM1> spaceTagZ; // (Philips specific)
+ gdcm::Attribute<0x0018,0x6024> physicalTagX;
+ gdcm::Attribute<0x0018,0x6026> physicalTagY;
+ gdcm::Attribute<0x3001,0x1002, gdcm::VR::US, gdcm::VM::VM1> physicalTagZ; // (Philips specific)
- gdcm::Tag tag(0x0020,0x1041); //Slice location
- gdcm::Scanner scanner;
+ dimTagX.Set(data_set);
+ dimTagY.Set(data_set);
+ dimTagZ.Set(data_set);
+ dimTagT.Set(data_set);
+ spaceTagX.Set(data_set);
+ spaceTagY.Set(data_set);
+ spaceTagZ.Set(data_set);
+ physicalTagX.Set(data_set);
+ physicalTagY.Set(data_set);
+ physicalTagZ.Set(data_set);
- scanner.AddTag(tag);
- scanner.Scan(sorter.GetFilenames());
+ unsigned int
+ dimX = dimTagX.GetValue(),
+ dimY = dimTagY.GetValue(),
+ dimZ = dimTagZ.GetValue(),
+ dimT = dimTagT.GetValue(),
+ physicalX = physicalTagX.GetValue(),
+ physicalY = physicalTagY.GetValue(),
+ physicalZ = physicalTagZ.GetValue();
- std::list<StringContainer> decomposed_filenames;
- const StringContainer::const_iterator f_end = sorter.GetFilenames().end();
- const char *act_value = scanner.GetValue(sorter.GetFilenames().front().c_str(), tag);
- unsigned int volume_count = 1u;
+ float
+ spaceX = spaceTagX.GetValue(),
+ spaceY = spaceTagY.GetValue(),
+ spaceZ = spaceTagZ.GetValue();
- decomposed_filenames.push_back(StringContainer());
- decomposed_filenames.back().push_back(sorter.GetFilenames().front());
+ // Ok, got all necessary Tags!
+ // Now read Pixeldata (7fe0,0010) X x Y x Z x T Elements
- for (StringContainer::const_iterator f_it = ++sorter.GetFilenames().begin(); f_it != f_end; ++f_it)
- {
- const char *value = scanner.GetValue(f_it->c_str(), tag);
+ const gdcm::Pixmap &pixels = reader.GetPixmap();
+ gdcm::RAWCodec codec;
- if (!strcmp(act_value, value))
+ codec.SetPhotometricInterpretation(gdcm::PhotometricInterpretation::MONOCHROME2);
+ codec.SetPixelFormat(pixels.GetPixelFormat());
+ codec.SetPlanarConfiguration(0);
+
+ gdcm::DataElement out;
+ codec.Decode(data_set.GetDataElement(gdcm::Tag(0x7fe0, 0x0010)), out);
+
+ const gdcm::ByteValue *bv = out.GetByteValue();
+ const char *new_pixels = bv->GetPointer();
+
+ // Create MITK Image + Geometry
+ typedef itk::Image<PixelType, 4> ImageType;
+ typename ImageType::RegionType myRegion;
+ typename ImageType::SizeType mySize;
+ typename ImageType::IndexType myIndex;
+ typename ImageType::SpacingType mySpacing;
+ ImageType::Pointer imageItk = ImageType::New();
+
+ mySpacing[0] = spaceX;
+ mySpacing[1] = spaceY;
+ mySpacing[2] = spaceZ;
+ myIndex[0] = physicalX;
+ myIndex[1] = physicalY;
+ myIndex[2] = physicalZ;
+ mySize[0] = dimX;
+ mySize[1] = dimY;
+ mySize[2] = dimZ;
+ mySize[3] = dimT;
+ myRegion.SetSize( mySize);
+ myRegion.SetIndex( myIndex );
+ imageItk->SetSpacing(mySpacing);
+ imageItk->SetRegions( myRegion);
+ imageItk->Allocate();
+ imageItk->FillBuffer(0);
+
+ typename itk::ImageRegionIterator<ImageType> iterator(imageItk, imageItk->GetLargestPossibleRegion());
+ iterator.GoToBegin();
+ unsigned long pixCount = 0;
+ unsigned long planeSize = dimX*dimY;
+ unsigned long planeCount = 0;
+ unsigned long timeCount = 0;
+ unsigned long numberOfSlices = dimZ;
+
+
+ while (!iterator.IsAtEnd())
+ {
+ unsigned long adressedPixel =
+ pixCount
+ + (numberOfSlices-1-planeCount)*planeSize // add offset to adress the first pixel of current plane
+ + timeCount*numberOfSlices*planeSize; // add time offset
+
+ iterator.Set( new_pixels[ adressedPixel ] );
+ pixCount++;
+ iterator++;
+
+ if (pixCount == planeSize)
+ {
+ pixCount = 0;
+ planeCount++;
+ }
+ if (planeCount == numberOfSlices)
+ {
+ planeCount = 0;
+ timeCount++;
+ }
+ if (timeCount == dimT)
+ {
+ break;
+ }
+ }
+ mitk::CastToMitkImage(imageItk, image);
+
+ /*
+ // this works as well, but then the picture is upside down.. transversal slice[max] should be transversal slice[0] and so on.
+ while (!iterator.IsAtEnd())
+ {
+ iterator.Set( new_pixels[pixCount] );
+ pixCount++;
+ iterator++;
+ }
+ mitk::CastToMitkImage(imageItk, image);
+ */
+
+ }
+ /******** END: Workaround for Phillips 3D+t images ********/
+ else
{
- act_value = value;
+ /******** Workaround for 4D data ***************/
+ gdcm::Sorter sorter;
+
+ sorter.SetSortFunction(DicomSeriesReader::GdcmSortFunction);
+ sorter.Sort(filenames);
+
+ gdcm::Tag tag(0x0020,0x1041); //Slice location
+ gdcm::Scanner scanner;
+
+ scanner.AddTag(tag);
+ scanner.Scan(sorter.GetFilenames());
+
+ std::list<StringContainer> decomposed_filenames;
+ const StringContainer::const_iterator f_end = sorter.GetFilenames().end();
+ const char *act_value = scanner.GetValue(sorter.GetFilenames().front().c_str(), tag);
+ unsigned int volume_count = 1u;
+
decomposed_filenames.push_back(StringContainer());
- ++volume_count;
- }
+ decomposed_filenames.back().push_back(sorter.GetFilenames().front());
- decomposed_filenames.back().push_back(*f_it);
- }
- /******** End: Workaround for 4D data **********/
+ for (StringContainer::const_iterator f_it = ++sorter.GetFilenames().begin(); f_it != f_end; ++f_it)
+ {
+ const char *value = scanner.GetValue(f_it->c_str(), tag);
- if (volume_count > 1)
- {
- typedef itk::Image<PixelType, 4> ImageType;
- typedef itk::ImageSeriesReader<ImageType> ReaderType;
+ if (!strcmp(act_value, value))
+ {
+ act_value = value;
+ decomposed_filenames.push_back(StringContainer());
+ ++volume_count;
+ }
- DcmIoType::Pointer io = DcmIoType::New();
- typename ReaderType::Pointer reader = ReaderType::New();
+ decomposed_filenames.back().push_back(*f_it);
+ }
+ /******** End: Workaround for 4D data **********/
- reader->SetImageIO(io);
- reader->ReverseOrderOff();
+ if (volume_count > 1)
+ {
+ typedef itk::Image<PixelType, 4> ImageType;
+ typedef itk::ImageSeriesReader<ImageType> ReaderType;
- if (command)
- {
- reader->AddObserver(itk::ProgressEvent(), command);
- }
+ DcmIoType::Pointer io = DcmIoType::New();
+ typename ReaderType::Pointer reader = ReaderType::New();
- const std::list<StringContainer>::const_iterator df_end = decomposed_filenames.end();
- unsigned int act_volume = 1u;
+ reader->SetImageIO(io);
+ reader->ReverseOrderOff();
- reader->SetFileNames(decomposed_filenames.front());
- reader->Update();
- image->InitializeByItk(reader->GetOutput(), 1, volume_count);
- image->SetImportVolume(reader->GetOutput()->GetBufferPointer(), 0u);
+ if (command)
+ {
+ reader->AddObserver(itk::ProgressEvent(), command);
+ }
- MITK_DEBUG << "Volume dimension: [" << image->GetDimension(0) << ", " << image->GetDimension(1) << ", " << image->GetDimension(2) << ", " << image->GetDimension(3) << "]";
- MITK_DEBUG << "Volume spacing: [" << image->GetGeometry()->GetSpacing()[0] << ", " << image->GetGeometry()->GetSpacing()[1] << ", " << image->GetGeometry()->GetSpacing()[2] << "]";
+ const std::list<StringContainer>::const_iterator df_end = decomposed_filenames.end();
+ unsigned int act_volume = 1u;
- for (std::list<StringContainer>::iterator df_it = ++decomposed_filenames.begin(); df_it != df_end; ++df_it)
- {
- reader->SetFileNames(*df_it);
- reader->Update();
- image->SetImportVolume(reader->GetOutput()->GetBufferPointer(), act_volume++);
+ reader->SetFileNames(decomposed_filenames.front());
+ reader->Update();
+ image->InitializeByItk(reader->GetOutput(), 1, volume_count);
+ image->SetImportVolume(reader->GetOutput()->GetBufferPointer(), 0u);
+
+ MITK_DEBUG << "Volume dimension: [" << image->GetDimension(0) << ", " << image->GetDimension(1) << ", " << image->GetDimension(2) << ", " << image->GetDimension(3) << "]";
+ MITK_DEBUG << "Volume spacing: [" << image->GetGeometry()->GetSpacing()[0] << ", " << image->GetGeometry()->GetSpacing()[1] << ", " << image->GetGeometry()->GetSpacing()[2] << "]";
+
+ for (std::list<StringContainer>::iterator df_it = ++decomposed_filenames.begin(); df_it != df_end; ++df_it)
+ {
+ reader->SetFileNames(*df_it);
+ reader->Update();
+ image->SetImportVolume(reader->GetOutput()->GetBufferPointer(), act_volume++);
+ }
+ }
+ else
+ {
+ typedef itk::Image<PixelType, 3> ImageType;
+ typedef itk::ImageSeriesReader<ImageType> ReaderType;
+
+ DcmIoType::Pointer io = DcmIoType::New();
+ typename ReaderType::Pointer reader = ReaderType::New();
+
+ reader->SetImageIO(io);
+ reader->ReverseOrderOff();
+
+ if (command)
+ {
+ reader->AddObserver(itk::ProgressEvent(), command);
+ }
+
+ reader->SetFileNames(filenames);
+ reader->Update();
+ image->InitializeByItk(reader->GetOutput());
+ image->SetImportVolume(reader->GetOutput()->GetBufferPointer());
+
+ MITK_DEBUG << "Volume dimension: [" << image->GetDimension(0) << ", " << image->GetDimension(1) << ", " << image->GetDimension(2) << "]";
+ MITK_DEBUG << "Volume spacing: [" << image->GetGeometry()->GetSpacing()[0] << ", " << image->GetGeometry()->GetSpacing()[1] << ", " << image->GetGeometry()->GetSpacing()[2] << "]";
+ }
}
- }
- else
- {
+
+#else
typedef itk::Image<PixelType, 3> ImageType;
typedef itk::ImageSeriesReader<ImageType> ReaderType;
@@ -138,48 +308,24 @@
MITK_DEBUG << "Volume dimension: [" << image->GetDimension(0) << ", " << image->GetDimension(1) << ", " << image->GetDimension(2) << "]";
MITK_DEBUG << "Volume spacing: [" << image->GetGeometry()->GetSpacing()[0] << ", " << image->GetGeometry()->GetSpacing()[1] << ", " << image->GetGeometry()->GetSpacing()[2] << "]";
- }
-#else
- typedef itk::Image<PixelType, 3> ImageType;
- typedef itk::ImageSeriesReader<ImageType> ReaderType;
+#endif
- DcmIoType::Pointer io = DcmIoType::New();
- typename ReaderType::Pointer reader = ReaderType::New();
+ node.SetData(image);
- reader->SetImageIO(io);
- reader->ReverseOrderOff();
+ setlocale(LC_NUMERIC, previousCLocale);
+ std::cin.imbue(previousCppLocale);
- if (command)
+ }
+ catch (std::exception& e)
{
- reader->AddObserver(itk::ProgressEvent(), command);
+ setlocale(LC_NUMERIC, previousCLocale);
+ std::cin.imbue(previousCppLocale);
+
+ throw e;
}
-
- reader->SetFileNames(filenames);
- reader->Update();
- image->InitializeByItk(reader->GetOutput());
- image->SetImportVolume(reader->GetOutput()->GetBufferPointer());
-
- MITK_DEBUG << "Volume dimension: [" << image->GetDimension(0) << ", " << image->GetDimension(1) << ", " << image->GetDimension(2) << "]";
- MITK_DEBUG << "Volume spacing: [" << image->GetGeometry()->GetSpacing()[0] << ", " << image->GetGeometry()->GetSpacing()[1] << ", " << image->GetGeometry()->GetSpacing()[2] << "]";
-
-#endif
-
- node.SetData(image);
-
- setlocale(LC_NUMERIC, previousCLocale);
- std::cin.imbue(previousCppLocale);
-
}
- catch (std::exception& e)
- {
- setlocale(LC_NUMERIC, previousCLocale);
- std::cin.imbue(previousCppLocale);
- throw e;
- }
}
-}
-
#endif

File Metadata

Mime Type
text/plain
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
624
Default Alt Text
Philips3D_DCM_Patch2.patch (18 KB)

Event Timeline

To support Philips3D DCM files 2