7 #include "fwDicomIOFilter/modifier/SliceThicknessModifier.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 "Compute and modify slice thickness using <i>ImagePositionPatient</i> " 31 "and <i>ImageOrientationPatient</i> tags of the two first instances.";
63 const ::fwMedData::DicomSeries::sptr& series,
64 const ::fwLog::Logger::sptr& logger)
const 66 DicomSeriesContainerType result;
68 if(series->getDicomContainer().size() < 2)
70 SLM_WARN(
"SliceThicknessModifier is being applied on a series containing only one slice.");
71 result.push_back(series);
76 auto firstItem = series->getDicomContainer().begin();
78 const ::fwMemory::BufferObject::sptr& firstBufferObj = firstItem->second;
79 const ::fwMemory::BufferObject::sptr& secondBufferObj = (++firstItem)->second;
84 const double sliceThickness = std::abs(secondIndex - firstIndex);
88 const double epsilon = 1e-2;
92 if(std::abs(sliceThickness - currentSliceThickness) > epsilon)
94 series->addComputedTagValue(
"SliceThickness", std::to_string(sliceThickness));
97 result.push_back(series);
105 DcmFileFormat fileFormat;
108 const size_t buffSize = bufferObj->getSize();
110 char* buffer =
static_cast< char*
>( lock.
getBuffer() );
112 DcmInputBufferStream is;
113 is.setBuffer(buffer, offile_off_t(buffSize));
116 fileFormat.transferInit();
117 if (!fileFormat.read(is).good())
119 FW_RAISE(
"Unable to read Dicom file '"<< bufferObj->getStreamInfo().fsFile.string() <<
"'");
122 fileFormat.loadAllDataIntoMemory();
123 fileFormat.transferEnd();
125 dataset = fileFormat.getDataset();
127 if(!dataset->tagExists(DCM_ImagePositionPatient) || !dataset->tagExists(DCM_ImageOrientationPatient))
129 const std::string msg =
"Unable to compute the SliceThickness of the series.";
130 throw ::fwDicomIOFilter::exceptions::FilterFailure(msg);
133 fwVec3d imagePosition;
134 for(
unsigned int i = 0; i < 3; ++i)
136 dataset->findAndGetFloat64(DCM_ImagePositionPatient, imagePosition[i], i);
139 fwVec3d imageOrientationU;
140 fwVec3d imageOrientationV;
141 for(
unsigned int i = 0; i < 3; ++i)
143 dataset->findAndGetFloat64(DCM_ImageOrientationPatient, imageOrientationU[i], i);
144 dataset->findAndGetFloat64(DCM_ImageOrientationPatient, imageOrientationV[i], i+3);
148 const fwVec3d zVector = ::fwMath::cross(imageOrientationU, imageOrientationV);
151 const double index = ::fwMath::dot(imagePosition, zVector);
160 DcmFileFormat fileFormat;
164 const size_t buffSize = bufferObj->getSize();
166 char* buffer =
static_cast< char*
>( lock.
getBuffer() );
168 DcmInputBufferStream is;
169 is.setBuffer(buffer, offile_off_t(buffSize));
172 fileFormat.transferInit();
173 if (!fileFormat.read(is).good())
175 FW_RAISE(
"Unable to read Dicom file '"<< bufferObj->getStreamInfo().fsFile.string() <<
"'");
178 fileFormat.loadAllDataIntoMemory();
179 fileFormat.transferEnd();
181 dataset = fileFormat.getDataset();
183 double sliceThickness = 0.;
184 dataset->findAndGetFloat64(DCM_SliceThickness, sliceThickness);
186 return sliceThickness;
static const std::string s_FILTER_NAME
Filter name.
virtual FWDICOMIOFILTER_API double getSliceThickness(const ::fwMemory::BufferObject::sptr &bufferObj) const
Get the SliceThickness value from an instance.
Base class for Dicom instance modifier.
static const std::string s_FILTER_DESCRIPTION
Filter description.
fwDicomIOFilter contains filters used to pre-process images before reading.
base class for BufferObject Lock
#define SLM_WARN(message)
LockBase< T >::BufferType getBuffer() const
Returns BufferObject's buffer pointer.
Key class used to restrict access to Filter construction. See http://www.drdobbs.com/184402053.
virtual FWDICOMIOFILTER_API std::string getDescription() const override
Return the description of the filter.
virtual FWDICOMIOFILTER_API double getInstanceZPosition(const ::fwMemory::BufferObject::sptr &bufferObj) const
Compute the Z coordinate of the slice according to the ImagePositionPatient and ImageOrientationPatie...
virtual FWDICOMIOFILTER_API ~SliceThicknessModifier()
Destructor.
FWDICOMIOFILTER_API SliceThicknessModifier(::fwDicomIOFilter::IFilter::Key key)
Constructor.
virtual FWDICOMIOFILTER_API DicomSeriesContainerType apply(const ::fwMedData::DicomSeries::sptr &series, const ::fwLog::Logger::sptr &logger) const override
Override.
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.