Page MenuHomePhabricator

DicomSeriesReader_sorting.patch

Authored By
santos
Jan 28 2011, 2:45 PM
Size
5 KB
Referenced Files
None
Subscribers
None

DicomSeriesReader_sorting.patch

Index: mitkDicomSeriesReader.cpp
===================================================================
--- mitkDicomSeriesReader.cpp (revision 29316)
+++ mitkDicomSeriesReader.cpp (working copy)
@@ -360,8 +360,57 @@
}
#if GDCM_MAJOR_VERSION >= 2
+
+DicomSeriesReader::StringContainer DicomSeriesReader::Sort4DSeriesSlices(const StringContainer &unsortedFilenames)
+{
+ gdcm::Sorter sorter;
+
+ sorter.SetSortFunction(DicomSeriesReader::Gdcm4DSortFunction);
+ sorter.Sort(unsortedFilenames);
+ return sorter.GetFilenames();
+}
+
bool DicomSeriesReader::GdcmSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2)
{
+ gdcm::Attribute<0x0020,0x0032> image_pos1; // Image Position (Patient)
+ gdcm::Attribute<0x0020,0x0037> image_orientation1; // Image Orientation (Patient)
+
+ image_pos1.Set(ds1);
+ image_orientation1.Set(ds1);
+
+ gdcm::Attribute<0x0020,0x0032> image_pos2;
+ gdcm::Attribute<0x0020,0x0037> image_orientation2;
+
+ image_pos2.Set(ds2);
+ image_orientation2.Set(ds2);
+
+ if (image_orientation1 != image_orientation2)
+ {
+ MITK_ERROR << "Dicom images have different orientations.";
+ throw std::logic_error("Dicom images have different orientations.");
+ }
+
+ double normal[3];
+
+ normal[0] = image_orientation1[1] * image_orientation1[5] - image_orientation1[2] * image_orientation1[4];
+ normal[1] = image_orientation1[2] * image_orientation1[3] - image_orientation1[0] * image_orientation1[5];
+ normal[2] = image_orientation1[0] * image_orientation1[4] - image_orientation1[1] * image_orientation1[3];
+
+ double
+ dist1 = 0.0,
+ dist2 = 0.0;
+
+ for (unsigned char i = 0u; i < 3u; ++i)
+ {
+ dist1 += normal[i] * image_pos1[i];
+ dist2 += normal[i] * image_pos2[i];
+ }
+
+ return dist1 < dist2;
+}
+
+bool DicomSeriesReader::Gdcm4DSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2)
+{
gdcm::Attribute<0x0008,0x0032> acq_time1; // Acquisition time
gdcm::Attribute<0x0020,0x0032> image_pos1; // Image Position (Patient)
gdcm::Attribute<0x0020,0x0037> image_orientation1; // Image Orientation (Patient)
Index: mitkDicomSeriesReader.h
===================================================================
--- mitkDicomSeriesReader.h (revision 29316)
+++ mitkDicomSeriesReader.h (working copy)
@@ -60,6 +60,7 @@
/**
* Loads a DICOM series composed by the file names enumerated in the file names container.
+ * Loading of 4D datasets will only work if both "sort" and "check_4d" parameters are enabled.
* If a callback method is supplied, it will be called after every progress update with a progress value in [0,1].
*/
static DataNode::Pointer LoadDicomSeries(const StringContainer &filenames, bool sort = true, bool check_4d = true, UpdateCallBackMethod callback = 0);
@@ -122,12 +123,11 @@
*
* \warning This method assumes that input files are similar in basic properties such as slice thicknes, image orientation, pixel spacing, rows, columns.
*
- * It should always be ok to put the result of a call to GetSeries(..) into this method.(..).
+ * It should always be ok to put the result of a call to GetSeries(..) into this method.
*
- * Sorting order is determined by
+ * Images are sorted along a vector normal to the plane of the image (determined from "Image Orientation (Patient)")
+ * by the value of "Image Position (Patient)" projected onto that vector.
*
- * 1. TODO
- * 2.
*/
static StringContainer SortSeriesSlices(const StringContainer &unsortedFilenames);
protected:
@@ -170,11 +170,14 @@
static void LoadDicom(const StringContainer &filenames, DataNode &node, bool sort, bool check_4d, UpdateCallBackMethod callback);
#if GDCM_MAJOR_VERSION >= 2
+ static StringContainer Sort4DSeriesSlices(const StringContainer &unsortedFilenames);
+
/*
* Auxiliary sort function for Gdcm Dicom sorting. It is used for sorting
* 4D Dicom data.
*/
static bool GdcmSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2);
+ static bool Gdcm4DSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2);
#endif
};
Index: mitkDicomSeriesReader.txx
===================================================================
--- mitkDicomSeriesReader.txx (revision 29316)
+++ mitkDicomSeriesReader.txx (working copy)
@@ -56,9 +56,10 @@
unsigned int volume_count = 1u;
StringContainer sorted_filenames = sort
- ? DicomSeriesReader::SortSeriesSlices(filenames)
+ ? (check_4d ? DicomSeriesReader::Sort4DSeriesSlices(filenames)
+ : DicomSeriesReader::SortSeriesSlices(filenames))
: filenames;
- if (check_4d)
+ if (check_4d && sort)
{
gdcm::Tag tag(0x0020,0x0032); //Image position (Patient)
gdcm::Scanner scanner;
@@ -74,9 +75,7 @@
for (StringContainer::const_iterator f_it = ++sorted_filenames.begin(); f_it != f_end; ++f_it)
{
- const char *value = scanner.GetValue(f_it->c_str(), tag);
-
- if (!strcmp(act_value, value))
+ if (!strcmp(act_value, scanner.GetValue(f_it->c_str(), tag)))
{
decomposed_filenames.push_back(StringContainer());
++volume_count;
@@ -84,6 +83,13 @@
decomposed_filenames.back().push_back(*f_it);
}
+
+ const std::list<StringContainer>::const_iterator df_end = decomposed_filenames.end();
+
+ for (std::list<StringContainer>::iterator df_it = decomposed_filenames.begin(); df_it != df_end; ++df_it)
+ {
+ (*df_it) = DicomSeriesReader::SortSeriesSlices(*df_it);
+ }
}
else
{

File Metadata

Mime Type
text/plain
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
628
Default Alt Text
DicomSeriesReader_sorting.patch (5 KB)

Event Timeline

Sorting with Image Poistion priority instead of acquisition time.