7 #include "fwDicomIOFilter/sorter/ImagePositionPatientSorter.hpp" 9 #include "fwDicomIOFilter/exceptions/FilterFailure.hpp" 10 #include "fwDicomIOFilter/registry/macros.hpp" 12 #include <fwMath/VectorFunctions.hpp> 14 #include <dcmtk/config/osconfig.h> 15 #include <dcmtk/dcmdata/dcdeftag.h> 16 #include <dcmtk/dcmdata/dcfilefo.h> 17 #include <dcmtk/dcmdata/dcistrmb.h> 18 #include <dcmtk/dcmimgle/dcmimage.h> 19 #include <dcmtk/dcmnet/diutil.h> 30 "Sort instances by computing image position using <i>ImagePositionPatient</i> " 31 "and <i>ImageOrientationPatient</i> tags.";
63 const ::fwMedData::DicomSeries::sptr& series,
64 const ::fwLog::Logger::sptr& logger)
const 66 DicomSeriesContainerType result;
68 typedef std::map< double, ::fwMemory::BufferObject::sptr > SortedDicomMapType;
69 SortedDicomMapType sortedDicom;
74 for(
const auto& item : series->getDicomContainer())
76 const ::fwMemory::BufferObject::sptr bufferObj = item.second;
77 const size_t buffSize = bufferObj->getSize();
79 char* buffer =
static_cast< char*
>( lock.
getBuffer() );
81 DcmInputBufferStream is;
82 is.setBuffer(buffer, offile_off_t(buffSize));
85 DcmFileFormat fileFormat;
86 fileFormat.transferInit();
87 if (!fileFormat.read(is).good())
89 FW_RAISE(
"Unable to read Dicom file '"<< bufferObj->getStreamInfo().fsFile.string() <<
"' "<<
90 "(slice: '" << item.first <<
"')");
93 fileFormat.loadAllDataIntoMemory();
94 fileFormat.transferEnd();
96 dataset = fileFormat.getDataset();
98 if(!dataset->tagExists(DCM_ImagePositionPatient) || !dataset->tagExists(DCM_ImageOrientationPatient))
100 const std::string msg =
101 "Unable to split the series using ImagePositionPatient and ImageOrientationPatient. " 103 throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
106 fwVec3d imagePosition;
107 for(
unsigned int i = 0; i < 3; ++i)
109 dataset->findAndGetFloat64(DCM_ImagePositionPatient, imagePosition[i], i);
112 fwVec3d imageOrientationU;
113 fwVec3d imageOrientationV;
114 for(
unsigned int i = 0; i < 3; ++i)
116 dataset->findAndGetFloat64(DCM_ImageOrientationPatient, imageOrientationU[i], i);
117 dataset->findAndGetFloat64(DCM_ImageOrientationPatient, imageOrientationV[i], i+3);
121 const fwVec3d zVector = ::fwMath::cross(imageOrientationU, imageOrientationV);
124 const double index = ::fwMath::dot(imagePosition, zVector);
126 sortedDicom[index] = bufferObj;
129 if(sortedDicom.size() != series->getDicomContainer().size())
131 const std::string msg =
132 "Unable to sort the series using the ImagePositionPatient tag. Some images have the same " 133 "position meaning this series contains multiple volumes. Try to split the volumes using a different " 135 throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
138 series->clearDicomContainer();
140 for(
const auto& item : sortedDicom)
142 series->addBinary(index++, item.second);
145 result.push_back(series);
147 logger->information(
"The instances have been sorted using the slices positions.");
Filter that uses the ImagepositionPatient tag to sort the instances. The position increases along the...
virtual FWDICOMIOFILTER_API std::string getName() const override
Return the name of the filter.
fwDicomIOFilter contains filters used to pre-process images before reading.
base class for BufferObject Lock
virtual FWDICOMIOFILTER_API ~ImagePositionPatientSorter()
Destructor.
LockBase< T >::BufferType getBuffer() const
Returns BufferObject's buffer pointer.
static const std::string s_FILTER_NAME
Filter name.
Key class used to restrict access to Filter construction. See http://www.drdobbs.com/184402053.
FWDICOMIOFILTER_API ImagePositionPatientSorter(::fwDicomIOFilter::IFilter::Key key)
Constructor.
virtual FWDICOMIOFILTER_API DicomSeriesContainerType apply(const ::fwMedData::DicomSeries::sptr &series, const ::fwLog::Logger::sptr &logger) const override
Override.
Base class for Dicom instance sorter.
static const std::string s_FILTER_DESCRIPTION
Filter description.
virtual FWDICOMIOFILTER_API std::string getDescription() const override
Return the description of the filter.