7 #include "fwGdcmIO/reader/ie/Image.hpp" 9 #include "fwGdcmIO/exception/Failed.hpp" 10 #include "fwGdcmIO/helper/DicomDataReader.hxx" 11 #include "fwGdcmIO/helper/DicomDataTools.hpp" 13 #include <fwData/Image.hpp> 15 #include <fwDataTools/helper/Array.hpp> 17 #include <fwDicomTools/Image.hpp> 19 #include <fwMath/VectorFunctions.hpp> 21 #include <fwMedData/DicomSeries.hpp> 23 #include <boost/algorithm/string/split.hpp> 24 #include <boost/algorithm/string/trim.hpp> 25 #include <boost/assign.hpp> 26 #include <boost/numeric/ublas/io.hpp> 27 #include <boost/numeric/ublas/lu.hpp> 29 #include <gdcmImageApplyLookupTable.h> 30 #include <gdcmImageHelper.h> 31 #include <gdcmImageReader.h> 32 #include <gdcmIPPSorter.h> 33 #include <gdcmPixelFormat.h> 34 #include <gdcmRescaler.h> 35 #include <gdcmUIDGenerator.h> 46 Image::Image(const ::fwMedData::DicomSeries::csptr& dicomSeries,
47 const SPTR(::gdcm::Reader)& reader,
48 const ::fwGdcmIO::container::DicomInstance::sptr& instance,
49 const ::fwData::Image::sptr& image,
50 const ::fwLog::Logger::sptr& logger,
51 ProgressCallback progress,
52 CancelRequestedCallback cancel) :
53 ::
fwGdcmIO::reader::ie::InformationEntity< ::
fwData::Image >(dicomSeries, reader, instance, image,
54 logger, progress, cancel),
55 m_enableBufferRotation(true)
67 double getInstanceZPosition(const ::fwMemory::BufferObject::sptr& bufferObj)
69 ::gdcm::ImageReader reader;
70 const ::fwMemory::BufferManager::StreamInfo streamInfo = bufferObj->getStreamInfo();
71 SPTR(std::istream) is = streamInfo.stream;
72 reader.SetStream(*is);
80 const ::gdcm::DataSet& dataset = reader.GetFile().GetDataSet();
83 if(!dataset.FindDataElement(::gdcm::Tag(0x0020, 0x0032)) || !dataset.FindDataElement(::gdcm::Tag(0x0020, 0x0037)))
85 const std::string msg =
"Unable to compute the spacing between slices of the series.";
86 throw ::fwGdcmIO::exception::Failed(msg);
90 const ::gdcm::Image& gdcmImage = reader.GetImage();
91 const double* gdcmOrigin = gdcmImage.GetOrigin();
92 const fwVec3d imagePosition = {{ gdcmOrigin[0], gdcmOrigin[1], gdcmOrigin[2] }};
95 const double* directionCosines = gdcmImage.GetDirectionCosines();
96 const fwVec3d imageOrientationU = {{
97 std::round(directionCosines[0]),
98 std::round(directionCosines[1]),
99 std::round(directionCosines[2])
101 const fwVec3d imageOrientationV = {{
102 std::round(directionCosines[3]),
103 std::round(directionCosines[4]),
104 std::round(directionCosines[5])
108 const fwVec3d zVector = ::fwMath::cross(imageOrientationU, imageOrientationV);
111 const double index = ::fwMath::dot(imagePosition, zVector);
118 void Image::readImagePlaneModule()
121 SPTR(::gdcm::ImageReader) imageReader = std::static_pointer_cast< ::gdcm::ImageReader >(m_reader);
122 const ::gdcm::Image& gdcmImage = imageReader->GetImage();
125 const double* gdcmOrigin = gdcmImage.GetOrigin();
127 if ( gdcmOrigin != 0 )
129 std::copy( gdcmOrigin, gdcmOrigin+3, origin.begin() );
131 m_object->setOrigin(origin);
135 const unsigned int dimension = gdcmImage.GetNumberOfDimensions();
136 OSLM_TRACE(
"Image's dimension : " << dimension);
139 const double* gdcmSpacing = gdcmImage.GetSpacing();
141 if ( gdcmSpacing != 0 )
143 std::copy( gdcmSpacing, gdcmSpacing+dimension, spacing.begin() );
147 const ::fwMedData::DicomSeries::DicomContainerType dicomContainer = m_dicomSeries->getDicomContainer();
148 if(dicomContainer.size() > 1)
150 auto firstItem = dicomContainer.begin();
151 const auto& lastItem = dicomContainer.rbegin();
154 const double firstIndex = getInstanceZPosition(firstItem->second);
155 const double secondIndex = getInstanceZPosition((++firstItem)->second);
156 const double lastIndex = getInstanceZPosition(lastItem->second);
157 spacing[2] = std::abs(secondIndex - firstIndex);
160 const double epsilon = 1e-2;
161 const double totalZSpacing = std::abs(lastIndex - firstIndex);
162 const double errorGap = std::abs( spacing[2] * static_cast<double>(dicomContainer.size() - 1 ) ) -
164 if(errorGap > epsilon)
166 std::stringstream ss;
167 ss <<
"Computed spacing between slices may not be correct. (Error gap : " << errorGap <<
")";
168 m_logger->warning(ss.str());
174 const ::gdcm::DataSet& dataset = imageReader->GetFile().GetDataSet();
176 if(dataset.FindDataElement(::gdcm::Tag(0x0018, 0x0050)))
178 const std::string& sliceThickness =
179 ::fwGdcmIO::helper::DicomDataReader::getTagValue< 0x0018, 0x0050 >(dataset);
180 spacing[2] = std::stod(sliceThickness);
184 OSLM_TRACE(
"Image's spacing : "<<spacing[0]<<
"x"<<spacing[1]<<
"x"<<spacing[2]);
185 m_object->setSpacing( spacing );
190 void Image::readVOILUTModule()
193 const ::gdcm::DataSet& dataset = m_reader->GetFile().GetDataSet();
196 std::string windowCenter = ::fwGdcmIO::helper::DicomDataReader::getTagValue<0x0028, 0x1050>(dataset);
197 std::vector<std::string> splitedWindowCenters;
198 if ( !windowCenter.empty() )
201 ::boost::split( splitedWindowCenters, windowCenter, ::boost::is_any_of(
"\\" ) );
202 m_object->setWindowCenter( ::boost::lexical_cast< double >(splitedWindowCenters[0]));
204 OSLM_TRACE(
"Image's window center : " << m_object->getWindowCenter());
207 std::string windowWidth = ::fwGdcmIO::helper::DicomDataReader::getTagValue<0x0028, 0x1051>(dataset);
208 std::vector<std::string> splitedWindowWidth;
209 if ( !windowWidth.empty() )
212 ::boost::split( splitedWindowWidth, windowWidth, ::boost::is_any_of(
"\\" ) );
213 m_object->setWindowWidth( ::boost::lexical_cast< double >(splitedWindowWidth[0]));
215 OSLM_TRACE(
"Image's window width : " << m_object->getWindowWidth());
221 std::vector<double> getRescaleInterceptSlopeValue(::gdcm::ImageReader* imageReader)
224 const ::gdcm::DataSet& dataset = imageReader->GetFile().GetDataSet();
227 std::vector< double > rescale = ::gdcm::ImageHelper::GetRescaleInterceptSlopeValue(imageReader->GetFile());
230 if(dataset.FindDataElement(::gdcm::Tag(0x0028, 0x1052)) && dataset.FindDataElement(::gdcm::Tag(0x0028, 0x1053)))
232 rescale[0] = ::fwGdcmIO::helper::DicomDataReader::getTagValue<0x0028, 0x1052, double>(dataset);
233 rescale[1] = ::fwGdcmIO::helper::DicomDataReader::getTagValue<0x0028, 0x1053, double>(dataset);
241 void Image::readImagePixelModule()
244 SPTR(::gdcm::ImageReader) imageReader = std::static_pointer_cast< ::gdcm::ImageReader >(m_reader);
245 const ::gdcm::Image& gdcmImage = imageReader->GetImage();
248 const ::gdcm::DataSet& dataset = m_reader->GetFile().GetDataSet();
251 ::gdcm::PixelFormat pixelFormat = ::gdcm::ImageHelper::GetPixelFormatValue(imageReader->GetFile());
254 std::vector<double> rescale = getRescaleInterceptSlopeValue(imageReader.get());
255 double rescaleIntercept = rescale[0];
256 double rescaleSlope = rescale[1];
258 const unsigned short samplesPerPixel = pixelFormat.GetSamplesPerPixel();
259 const unsigned short bitsAllocated = pixelFormat.GetBitsAllocated();
260 const unsigned short bitsStored = pixelFormat.GetBitsStored();
261 const unsigned short highBit = pixelFormat.GetHighBit();
262 const unsigned short pixelRepresentation = pixelFormat.GetPixelRepresentation();
266 samplesPerPixel, bitsAllocated, bitsStored, highBit, pixelRepresentation, rescaleSlope, rescaleIntercept);
268 m_object->setType(imageType);
271 if(targetPixelFormat == ::gdcm::PixelFormat::UNKNOWN)
273 throw ::fwGdcmIO::exception::Failed(
"Unsupported image pixel format.");
277 const std::string photometricInterpretation =
278 ::fwGdcmIO::helper::DicomDataReader::getTagValue<0x0028, 0x0004>(dataset);
279 const std::string pixelPresentation =
280 ::fwGdcmIO::helper::DicomDataReader::getTagValue<0x0008, 0x9205>(dataset);
282 if(photometricInterpretation ==
"MONOCHROME2")
284 m_object->setNumberOfComponents(1);
286 else if(photometricInterpretation ==
"RGB" || photometricInterpretation ==
"YBR")
288 m_object->setNumberOfComponents(3);
290 else if(photometricInterpretation ==
"ARGB" || photometricInterpretation ==
"CMYK")
292 m_object->setNumberOfComponents(4);
294 else if(photometricInterpretation ==
"PALETTE COLOR" || pixelPresentation ==
"COLOR")
296 m_object->setNumberOfComponents(3);
300 const std::string msg =
"The photometric interpretation \"" + photometricInterpretation
301 +
"\" is not supported.";
302 throw ::fwGdcmIO::exception::Failed(msg);
306 std::vector<unsigned int> dimensions = ::gdcm::ImageHelper::GetDimensionsValue(imageReader->GetFile());
310 const unsigned long frameBufferSize = gdcmImage.GetBufferLength();
311 const unsigned long depth = frameBufferSize / (dimensions[0] * dimensions[1] * (bitsAllocated/8));
312 dimensions[2] =
static_cast<unsigned int>(m_dicomSeries->getDicomContainer().size() * depth);
313 m_object->setSize(::boost::assign::list_of(dimensions[0])(dimensions[1])(dimensions[2]));
315 OSLM_TRACE(
"Image dimensions : [" << dimensions[0] <<
"," <<dimensions[1] <<
"," << dimensions[2] <<
"]");
317 const unsigned long imageBufferSize =
318 dimensions[0] * dimensions[1] * dimensions[2] * (bitsAllocated/8);
319 const unsigned long newImageBufferSize =
320 dimensions[0] * dimensions[1] * dimensions[2] * (targetPixelFormat.GetBitsAllocated()/8);
322 OSLM_TRACE(
"Image buffer size : " << imageBufferSize);
323 OSLM_TRACE(
"New image buffer size : " << newImageBufferSize);
326 bool performRescale = (photometricInterpretation !=
"PALETTE COLOR" && pixelPresentation !=
"COLOR");
327 char* imageBuffer = this->readImageBuffer(dimensions, bitsAllocated, targetPixelFormat.GetBitsAllocated(),
331 if(!(m_cancelRequestedCallback && m_cancelRequestedCallback()) && m_enableBufferRotation)
333 imageBuffer = this->correctImageOrientation(imageBuffer, dimensions,
334 (performRescale) ? targetPixelFormat.GetBitsAllocated() : bitsAllocated);
338 if(!(m_cancelRequestedCallback && m_cancelRequestedCallback()) &&
339 (photometricInterpretation ==
"PALETTE COLOR" || pixelPresentation ==
"COLOR"))
344 char* coloredBuffer = 0;
345 coloredBuffer =
new char[newImageBufferSize*3];
348 gdcmImage.GetLUT().Decode(coloredBuffer, newImageBufferSize*3, imageBuffer, imageBufferSize);
351 delete[] imageBuffer;
352 imageBuffer = coloredBuffer;
356 throw ::fwGdcmIO::exception::Failed(
"There is not enough memory available to open this image.");
361 ::fwData::Array::sptr array = m_object->getDataArray();
363 helper.
setBuffer(imageBuffer,
true, m_object->getType(), m_object->getSize(), m_object->getNumberOfComponents());
369 char* Image::readImageBuffer(
const std::vector<unsigned int>& dimensions,
370 const unsigned short bitsAllocated,
371 const unsigned short newBitsAllocated,
375 SPTR(::gdcm::ImageReader) imageReader = std::static_pointer_cast< ::gdcm::ImageReader >(m_reader);
376 const ::gdcm::Image& gdcmFirstImage = imageReader->GetImage();
379 ::fwMedData::DicomSeries::DicomContainerType dicomContainer = m_dicomSeries->getDicomContainer();
384 const unsigned long frameBufferSize = gdcmFirstImage.GetBufferLength();
385 const unsigned long newFrameBufferSize = frameBufferSize * (newBitsAllocated/bitsAllocated);
386 const unsigned long imageBufferSize = dimensions.at(0) * dimensions.at(1) * dimensions.at(2) *
387 ((performRescale ? newBitsAllocated : bitsAllocated)/8);
392 frameBuffer =
new char[frameBufferSize];
393 imageBuffer =
new char[imageBufferSize];
397 throw ::fwGdcmIO::exception::Failed(
"There is not enough memory available to open this image.");
401 unsigned int frameNumber = 0;
402 for(
const auto& item : dicomContainer)
405 ::gdcm::ImageReader frameReader;
406 const ::fwMemory::BufferObject::sptr bufferObj = item.second;
407 const ::fwMemory::BufferManager::StreamInfo streamInfo = bufferObj->getStreamInfo();
408 const std::string dicomPath = bufferObj->getStreamInfo().fsFile.string();
409 SPTR(std::istream) is = streamInfo.stream;
410 frameReader.SetStream(*is);
412 if ( frameReader.Read() )
414 const ::gdcm::Image& gdcmImage = frameReader.GetImage();
416 if(frameBufferSize != gdcmImage.GetBufferLength())
418 throw ::fwGdcmIO::exception::Failed(
"The frame buffer does not have the expected size : " + dicomPath);
422 if ( !gdcmImage.GetBuffer( frameBuffer ) )
424 throw ::fwGdcmIO::exception::Failed(
"Failed to get a frame buffer");
429 std::stringstream ss;
430 ss <<
"Reading error on frame : " << frameNumber;
431 throw ::fwGdcmIO::exception::Failed(ss.str());
438 std::vector<double> rescale = getRescaleInterceptSlopeValue(&frameReader);
439 double rescaleIntercept = rescale[0];
440 double rescaleSlope = rescale[1];
443 ::gdcm::PixelFormat pixelFormat =
444 ::gdcm::ImageHelper::GetPixelFormatValue(frameReader.GetFile());
445 ::gdcm::PixelFormat::ScalarType scalarType = pixelFormat.GetScalarType();
448 if(targetPixelFormat == ::gdcm::PixelFormat::UNKNOWN)
450 throw ::fwGdcmIO::exception::Failed(
"Unsupported image pixel format.");
454 ::gdcm::Rescaler rescaler;
455 rescaler.SetIntercept(rescaleIntercept);
456 rescaler.SetSlope(rescaleSlope);
457 rescaler.SetPixelFormat(scalarType);
458 rescaler.SetTargetPixelType(targetPixelFormat.GetScalarType());
459 rescaler.SetUseTargetPixelType(
true);
462 rescaler.Rescale(imageBuffer + (frameNumber * newFrameBufferSize), frameBuffer, frameBufferSize);
467 memcpy(imageBuffer + frameNumber * frameBufferSize, frameBuffer, frameBufferSize);
471 const ::gdcm::DataSet& gdcmDatasetRoot = frameReader.GetFile().GetDataSet();
472 const std::string sopInstanceUID = ::fwGdcmIO::helper::DicomDataReader::getTagValue<0x0008, 0x0018>(
474 if(!sopInstanceUID.empty())
476 m_instance->getSOPInstanceUIDContainer().push_back(sopInstanceUID);
480 m_logger->warning(
"A frame with an undefined SOP instance UID has been detected.");
486 unsigned int progress =
487 static_cast<unsigned int>(18 + (frameNumber*100/
static_cast<double>(dicomContainer.size())) * 0.6);
488 m_progressCallback(progress);
490 if(m_cancelRequestedCallback && m_cancelRequestedCallback())
497 delete[] frameBuffer;
504 char* Image::correctImageOrientation(
char* buffer,
505 const std::vector<unsigned int>& dimensions,
506 unsigned short bitsAllocated)
508 char* result = buffer;
511 SPTR(::gdcm::ImageReader) imageReader = std::static_pointer_cast< ::gdcm::ImageReader >(m_reader);
512 const ::gdcm::Image& gdcmImage = imageReader->GetImage();
515 const double* directionCosines = gdcmImage.GetDirectionCosines();
518 fwVec3d imageOrientationU = {{
519 std::round(directionCosines[0]),
520 std::round(directionCosines[1]),
521 std::round(directionCosines[2])
524 if((std::fabs(imageOrientationU[0]) + std::fabs(imageOrientationU[1]) + std::fabs(imageOrientationU[2])) > 1)
526 if(std::fabs(directionCosines[0]) < std::fabs(directionCosines[1]) ||
527 std::fabs(directionCosines[0]) < std::fabs(directionCosines[2]))
529 imageOrientationU[0] = 0;
531 if(std::fabs(directionCosines[1]) < std::fabs(directionCosines[0]) ||
532 std::fabs(directionCosines[1]) < std::fabs(directionCosines[2]))
534 imageOrientationU[1] = 0;
536 if(std::fabs(directionCosines[2]) < std::fabs(directionCosines[0]) ||
537 std::fabs(directionCosines[2]) < std::fabs(directionCosines[1]))
539 imageOrientationU[2] = 0;
541 m_logger->warning(
"Unable to determine clearly the orientation of the image. " 542 "The software may display the image in the wrong direction.");
546 fwVec3d imageOrientationV = {{
547 std::round(directionCosines[3]),
548 std::round(directionCosines[4]),
549 std::round(directionCosines[5])
552 if((std::fabs(imageOrientationV[0]) + std::fabs(imageOrientationV[1]) + std::fabs(imageOrientationV[2])) > 1)
554 if(std::fabs(directionCosines[3]) < std::fabs(directionCosines[4]) ||
555 std::fabs(directionCosines[3]) < std::fabs(directionCosines[5]))
557 imageOrientationV[0] = 0;
559 if(std::fabs(directionCosines[4]) < std::fabs(directionCosines[3]) ||
560 std::fabs(directionCosines[4]) < std::fabs(directionCosines[5]))
562 imageOrientationV[1] = 0;
564 if(std::fabs(directionCosines[5]) < std::fabs(directionCosines[3]) ||
565 std::fabs(directionCosines[5]) < std::fabs(directionCosines[4]))
567 imageOrientationV[2] = 0;
569 m_logger->warning(
"Unable to determine clearly the orientation of the image. " 570 "The software may display the image in the wrong direction.");
574 const fwVec3d imageOrientationW = ::fwMath::cross(imageOrientationU, imageOrientationV);
577 Image::MatrixType matrix(4, 4);
578 matrix(0, 0) = imageOrientationU[0];
579 matrix(1, 0) = imageOrientationU[1];
580 matrix(2, 0) = imageOrientationU[2];
582 matrix(0, 1) = imageOrientationV[0];
583 matrix(1, 1) = imageOrientationV[1];
584 matrix(2, 1) = imageOrientationV[2];
586 matrix(0, 2) = imageOrientationW[0];
587 matrix(1, 2) = imageOrientationW[1];
588 matrix(2, 2) = imageOrientationW[2];
596 Image::MatrixType inverseMatrix = this->computeInverseMatrix(matrix);
597 Image::MatrixType identityMatrix = ::boost::numeric::ublas::identity_matrix< double >(inverseMatrix.size1());
600 if(!::boost::numeric::ublas::detail::expression_type_check(inverseMatrix, identityMatrix))
603 VectorType sizeVector(4);
604 sizeVector(0) = dimensions.at(0);
605 sizeVector(1) = dimensions.at(1);
606 sizeVector(2) = dimensions.at(2);
607 VectorType newSizeVector = ::boost::numeric::ublas::prod(sizeVector, inverseMatrix);
608 const unsigned short newSizeX =
static_cast<unsigned short>(std::fabs(newSizeVector[0]));
609 const unsigned short newSizeY =
static_cast<unsigned short>(std::fabs(newSizeVector[1]));
610 const unsigned short newSizeZ =
static_cast<unsigned short>(std::fabs(newSizeVector[2]));
611 newSizeVector(0) = newSizeX;
612 newSizeVector(1) = newSizeY;
613 newSizeVector(2) = newSizeZ;
616 VectorType oldSizeVector = ::boost::numeric::ublas::prod(newSizeVector, matrix);
619 const unsigned long size = dimensions.at(0) * dimensions.at(1) * dimensions.at(2) * (bitsAllocated/8);
620 char* newBuffer =
new char[size];
623 unsigned short x, y, z, oldx, oldy, oldz;
624 for(z = 0; z < newSizeZ && !(m_cancelRequestedCallback && m_cancelRequestedCallback()); ++z)
626 for(y = 0; y < newSizeY; ++y)
628 for(x = 0; x < newSizeX; ++x)
631 VectorType newPosition(4);
637 VectorType oldPosition = ::boost::numeric::ublas::prod(newPosition, matrix);
638 oldx = (oldSizeVector[0] > 0) ? static_cast<unsigned short>(oldPosition[0])
639 :
static_cast<unsigned short>((dimensions.at(0)-1) + oldPosition[0]);
640 oldy = (oldSizeVector[1] > 0) ? static_cast<unsigned short>(oldPosition[1])
641 :
static_cast<unsigned short>((dimensions.at(1)-1)+ oldPosition[1]);
642 oldz = (oldSizeVector[2] > 0) ? static_cast<unsigned short>(oldPosition[2])
643 :
static_cast<unsigned short>((dimensions.at(2)-1)+ oldPosition[2]);
646 unsigned int positionIndex = (x + (y*newSizeX) + z*(newSizeX*newSizeY)) * (bitsAllocated/8);
647 unsigned int oldPositionIndex =
648 (oldx + (oldy*dimensions.at(0)) + oldz*(dimensions.at(0)*dimensions.at(1))) *
652 memcpy(&newBuffer[positionIndex], &buffer[oldPositionIndex], (bitsAllocated/8));
655 unsigned int progress =
static_cast<unsigned int>(78 + (z*100./newSizeZ) * 0.2);
656 m_progressCallback(progress);
663 m_object->setSize(::boost::assign::list_of(newSizeX)(newSizeY)(newSizeZ));
667 VectorType spacingVector(4);
668 spacingVector(0) = spacing[0];
669 spacingVector(1) = spacing[1];
670 spacingVector(2) = spacing[2];
671 VectorType newSpacingVector = ::boost::numeric::ublas::prod(spacingVector, inverseMatrix);
673 newSpacing[0] = std::fabs(newSpacingVector[0]);
674 newSpacing[1] = std::fabs(newSpacingVector[1]);
675 newSpacing[2] = std::fabs(newSpacingVector[2]);
676 m_object->setSpacing( newSpacing );
680 VectorType originVector(4);
681 originVector(0) = origin[0];
682 originVector(1) = origin[1];
683 originVector(2) = origin[2];
684 VectorType newOriginVector = ::boost::numeric::ublas::prod(originVector, inverseMatrix);
686 newOrigin[0] = newOriginVector[0];
687 newOrigin[1] = newOriginVector[1];
688 newOrigin[2] = newOriginVector[2];
689 m_object->setOrigin( newOrigin );
691 m_logger->warning(
"Image buffer has been rotated in order to match patient orientation: " 692 "image origin could be wrong.");
700 Image::MatrixType Image::computeInverseMatrix(MatrixType matrix)
703 Image::MatrixType output(matrix.size1(), matrix.size2());
704 output.assign(::boost::numeric::ublas::identity_matrix< double >(output.size1()));
707 boost::numeric::ublas::permutation_matrix< std::size_t > perm(matrix.size1());
710 long unsigned int res = boost::numeric::ublas::lu_factorize(matrix, perm);
718 boost::numeric::ublas::lu_substitute(matrix, perm, output);
#define OSLM_TRACE(message)
The namespace fwGdcmIO contains reader, writer and helper for dicom data.
#define SLM_WARN(message)
Implements a failed exception class for fwGdcmIO.
std::vector< double > SpacingType
Image spacing type.
Contains the representation of the data objects used in the framework.
FWGDCMIO_API Image(const std::shared_ptr< const ::fwMedData::DicomSeries > &dicomSeries, const std::shared_ptr< ::gdcm::Reader > &reader, const std::shared_ptr< ::fwGdcmIO::container::DicomInstance > &instance, const ::fwData::Image::sptr &image, const ::fwLog::Logger::sptr &logger=nullptr, ProgressCallback progress=nullptr, CancelRequestedCallback cancel=nullptr)
Constructor.
std::vector< double > OriginType
Image origin type.