7 #include "fwDicomIOFilter/splitter/ImagePositionPatientSplitter.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 "Split instances by finding gaps in image position continuity. This filter assume that " 31 "the instances are <b>already sorted</b> and only gaps between volumes remain.";
63 const ::fwMedData::DicomSeries::sptr& series, const ::fwLog::Logger::sptr& logger)
66 DicomSeriesContainerType result;
71 double previousIndex = 0.;
72 unsigned int instanceNumber = 0;
73 double spacingBetweenSlices = 0.;
74 const double epsilon = 1e-2;
75 ::fwMedData::DicomSeries::sptr currentSeries;
76 for(
const auto& item : series->getDicomContainer())
78 const ::fwMemory::BufferObject::sptr bufferObj = item.second;
79 const size_t buffSize = bufferObj->getSize();
81 char* buffer =
static_cast< char*
>( lock.
getBuffer() );
83 DcmInputBufferStream is;
84 is.setBuffer(buffer, offile_off_t(buffSize));
87 DcmFileFormat fileFormat;
88 fileFormat.transferInit();
89 if (!fileFormat.read(is).good())
91 FW_RAISE(
"Unable to read Dicom file '"<< bufferObj->getStreamInfo().fsFile.string() <<
"' "<<
92 "(slice: '" << item.first <<
"')");
95 fileFormat.loadAllDataIntoMemory();
96 fileFormat.transferEnd();
98 dataset = fileFormat.getDataset();
100 if(!dataset->tagExists(DCM_ImagePositionPatient) || !dataset->tagExists(DCM_ImageOrientationPatient))
102 const std::string msg =
103 "Unable to split the series using ImagePositionPatient and ImageOrientationPatient. " 105 throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
108 fwVec3d imagePosition;
109 for(
unsigned int i = 0; i < 3; ++i)
111 dataset->findAndGetFloat64(DCM_ImagePositionPatient, imagePosition[i], i);
114 fwVec3d imageOrientationU;
115 fwVec3d imageOrientationV;
116 for(
unsigned int i = 0; i < 3; ++i)
118 dataset->findAndGetFloat64(DCM_ImageOrientationPatient, imageOrientationU[i], i);
119 dataset->findAndGetFloat64(DCM_ImageOrientationPatient, imageOrientationV[i], i+3);
123 const fwVec3d zVector = ::fwMath::cross(imageOrientationU, imageOrientationV);
126 const double index = ::fwMath::dot(imagePosition, zVector);
129 const double spacing = index - previousIndex;
130 if(currentSeries && fabs(spacingBetweenSlices) < epsilon)
132 spacingBetweenSlices = spacing;
136 if(!currentSeries || (fabs(spacing - spacingBetweenSlices) > epsilon) )
140 result.push_back(currentSeries);
141 currentSeries->setNumberOfInstances(currentSeries->getDicomContainer().size());
144 currentSeries = ::fwMedData::DicomSeries::New();
145 currentSeries->deepCopy(series);
146 currentSeries->clearDicomContainer();
149 currentSeries->addBinary(instanceNumber++, bufferObj);
150 previousIndex = index;
154 result.push_back(currentSeries);
155 currentSeries->setNumberOfInstances(currentSeries->getDicomContainer().size());
157 if(result.size() > 1)
159 logger->warning(
"Series has been split according to slice positions.");
virtual FWDICOMIOFILTER_API std::string getName() const override
Return the name of the filter.
virtual FWDICOMIOFILTER_API ~ImagePositionPatientSplitter()
Destructor.
fwDicomIOFilter contains filters used to pre-process images before reading.
base class for BufferObject Lock
virtual FWDICOMIOFILTER_API std::string getDescription() const override
Return the description of the filter.
FWDICOMIOFILTER_API ImagePositionPatientSplitter(::fwDicomIOFilter::IFilter::Key key)
Constructor.
virtual FWDICOMIOFILTER_API DicomSeriesContainerType apply(const ::fwMedData::DicomSeries::sptr &series, const ::fwLog::Logger::sptr &logger) const override
Override.
LockBase< T >::BufferType getBuffer() const
Returns BufferObject's buffer pointer.
Filter that uses the ImagePositionPatient tag to split the instances. For this filter to work properl...
Key class used to restrict access to Filter construction. See http://www.drdobbs.com/184402053.
static const std::string s_FILTER_NAME
Filter name.
static const std::string s_FILTER_DESCRIPTION
Filter description.
Base class for Dicom instance splitter.