⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdcmfile.cxx

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 CXX
📖 第 1 页 / 共 5 页
字号:
}

/**
 * \brief   Retrieve the number of columns of image.
 * @return  The encountered size when found, 0 by default.
 *          0 means the file is NOT USABLE. The caller will have to check
 */
int File::GetXSize()
{
   const std::string &strSize = GetEntryValue(0x0028,0x0011);
   if ( strSize == GDCM_UNFOUND )
   {
      return 0;
   }
   return atoi( strSize.c_str() );
}

/**
 * \brief   Retrieve the number of lines of image.
 * \warning The defaulted value is 1 as opposed to File::GetXSize()
 * @return  The encountered size when found, 1 by default 
 *          (The ACR-NEMA file contains a Signal, not an Image).
 */
int File::GetYSize()
{
   const std::string &strSize = GetEntryValue(0x0028,0x0010);
   if ( strSize != GDCM_UNFOUND )
   {
      return atoi( strSize.c_str() );
   }
   if ( IsDicomV3() )
   {
      return 0;
   }

   // The Rows (0028,0010) entry was optional for ACR/NEMA.
   // (at least some images didn't have it.)
   // It might hence be a signal (1D image). So we default to 1:
   return 1;
}

/**
 * \brief   Retrieve the number of planes of volume or the number
 *          of frames of a multiframe.
 * \warning When present we consider the "Number of Frames" as the third
 *          dimension. When missing we consider the third dimension as
 *          being the ACR-NEMA "Planes" tag content.
 * @return  The encountered size when found, 1 by default (single image).
 */
int File::GetZSize()
{
   // Both  DicomV3 and ACR/Nema consider the "Number of Frames"
   // as the third dimension.
   const std::string &strSize = GetEntryValue(0x0028,0x0008);
   if ( strSize != GDCM_UNFOUND )
   {
      return atoi( strSize.c_str() );
   }

   // We then consider the "Planes" entry as the third dimension 
   const std::string &strSize2 = GetEntryValue(0x0028,0x0012);
   if ( strSize2 != GDCM_UNFOUND )
   {
      return atoi( strSize2.c_str() );
   }
   return 1;
}
// Special case:
//  ts["1.2.840.10008.5.1.4.1.1.4.1"] = "Enhanced MR Image Storage"; 
bool File::GetSpacing(float &xspacing, float &yspacing, float &zspacing)
{
   xspacing = yspacing = zspacing = 1.0;
   TS *ts = Global::GetTS();
   std::string sopclassuid_used;
   // D 0002|0002 [UI] [Media Storage SOP Class UID]
   const std::string &mediastoragesopclassuid_str = GetEntryValue(0x0002,0x0002);
   const std::string &mediastoragesopclassuid = ts->GetValue(mediastoragesopclassuid_str);
   //D 0008|0016 [UI] [SOP Class UID]
   const std::string &sopclassuid_str = GetEntryValue(0x0008,0x0016);
   const std::string &sopclassuid = ts->GetValue(sopclassuid_str);
   if ( mediastoragesopclassuid == GDCM_UNFOUND && sopclassuid == GDCM_UNFOUND )
     {
     return false;
     }
   else
     {
     if( mediastoragesopclassuid == sopclassuid )
       {
       sopclassuid_used = mediastoragesopclassuid;
       }
     else
       {
       gdcmWarningMacro( "Inconsistant SOP Class UID: "
         << mediastoragesopclassuid << " and " << sopclassuid );
       return false;
       }
     }
   // ok we have now the correc SOP Class UID
   if( sopclassuid_used == "Enhanced MR Image Storage" )
     {
     SeqEntry *PerframeFunctionalGroupsSequence = GetSeqEntry(0x5200,0x9230);
     unsigned int n = PerframeFunctionalGroupsSequence->GetNumberOfSQItems();
     if( !n ) return false;
     SQItem *item1 = PerframeFunctionalGroupsSequence->GetFirstSQItem();
     DocEntry *p = item1->GetDocEntry(0x0028,0x9110);
     if( !p ) return false;
     SeqEntry *seq = dynamic_cast<SeqEntry*>(p);
     unsigned int n1 = seq->GetNumberOfSQItems();
     if( !n1 ) return false;
     SQItem *item2 = seq->GetFirstSQItem();
     // D 0028|0030 [DS] [Pixel Spacing] [0.83333331346511\0.83333331346511 ]
     DocEntry *p2 = item2->GetDocEntry(0x0028,0x0030);
     if( !p2 ) return false;
     ContentEntry *entry = dynamic_cast<ContentEntry *>(p2);
     std::string spacing = entry->GetValue();
     if ( sscanf( spacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2 )
       {
       xspacing = yspacing = 1.;
       return false;
       }
     // D 0018|0050 [DS] [Slice Thickness] [1 ]
     DocEntry *p3 = item2->GetDocEntry(0x0018,0x0050);
     if( !p3 ) return false;
     ContentEntry *entry2 = dynamic_cast<ContentEntry *>(p3);
     std::string thickness = entry2->GetValue();
     if ( sscanf( thickness.c_str(), "%f", &zspacing) != 1 )
       {
       zspacing = 1.;
       return false;
       }
     return true;
     }

  return false;
}

/**
  * \brief gets the info from 0018,1164 : ImagerPixelSpacing
  *                      then 0028,0030 : Pixel Spacing
  *             else 1.0
  * @return X dimension of a pixel
  */
float File::GetXSpacing()
{
   float xspacing = 1.0;
   float yspacing = 1.0;
   float zspacing = 1.0;
   int nbValues;
   if ( GetSpacing(xspacing,yspacing,zspacing) )
     {
     return xspacing;
     }
   // else fallback

   // To follow David Clunie's advice, we first check ImagerPixelSpacing

   const std::string &strImagerPixelSpacing = GetEntryValue(0x0018,0x1164);
   if ( strImagerPixelSpacing != GDCM_UNFOUND )
   {
      if ( ( nbValues = sscanf( strImagerPixelSpacing.c_str(), 
            "%f\\%f", &yspacing, &xspacing)) != 2 )
      {
         // if no values, xspacing is set to 1.0
         if ( nbValues == 0 )
            xspacing = 1.0;
         // if single value is found, xspacing is defaulted to yspacing
         if ( nbValues == 1 )
            xspacing = yspacing;

         if ( xspacing == 0.0 )
            xspacing = 1.0;
      }  
      return xspacing;
   }

   const std::string &strSpacing = GetEntryValue(0x0028,0x0030);

   if ( strSpacing == GDCM_UNFOUND )
   {
      gdcmWarningMacro( "Unfound Pixel Spacing (0028,0030)" );
      return 1.;
   }

   if ( ( nbValues = sscanf( strSpacing.c_str(), 
         "%f \\%f ", &yspacing, &xspacing)) != 2 )
   {
      // if no values, xspacing is set to 1.0
      if ( nbValues == 0 )
         xspacing = 1.0;
      // if single value is found, xspacing is defaulted to yspacing
      if ( nbValues == 1 )
         xspacing = yspacing;

      if ( xspacing == 0.0 )
         xspacing = 1.0;

      return xspacing;
   }

   // to avoid troubles with David Clunie's-like images (at least one)
   if ( xspacing == 0.0 && yspacing == 0.0)
      return 1.0;

   if ( xspacing == 0.0)
   {
      gdcmWarningMacro("gdcmData/CT-MONO2-8-abdo.dcm-like problem");
      // seems to be a bug in the header ...
      nbValues = sscanf( strSpacing.c_str(), "%f \\0\\%f ", &yspacing, &xspacing);
      gdcmAssertMacro( nbValues == 2 );
   }

   return xspacing;
}

/**
  * \brief gets the info from 0018,1164 : ImagerPixelSpacing
  *               then from   0028,0030 : Pixel Spacing                         
  *             else 1.0
  * @return Y dimension of a pixel
  */
float File::GetYSpacing()
{
   float xspacing = 1., yspacing = 1.0, zspacing = 1.;
   int nbValues;
   if ( GetSpacing(xspacing,yspacing,zspacing) )
     {
     return yspacing;
     }
   // else fallback

   // To follow David Clunie's advice, we first check ImagerPixelSpacing
   const std::string &strImagerPixelSpacing = GetEntryValue(0x0018,0x1164);
   if ( strImagerPixelSpacing != GDCM_UNFOUND )
   {
      nbValues = sscanf( strImagerPixelSpacing.c_str(), "%f", &yspacing);
   
   // if sscanf cannot read any float value, it won't affect yspacing
      if ( nbValues == 0 )
            yspacing = 1.0;

      if ( yspacing == 0.0 )
            yspacing = 1.0;

      return yspacing;  
   }

   std::string strSpacing = GetEntryValue(0x0028,0x0030);  
   if ( strSpacing == GDCM_UNFOUND )
   {
      gdcmWarningMacro("Unfound Pixel Spacing (0028,0030)");
      return 1.;
    }

   // if sscanf cannot read any float value, it won't affect yspacing
   nbValues = sscanf( strSpacing.c_str(), "%f", &yspacing);

   // if no values, yspacing is set to 1.0
   if ( nbValues == 0 )
      yspacing = 1.0;

   if ( yspacing == 0.0 )
      yspacing = 1.0;

   return yspacing;
} 

/**
 * \brief gets the info from 0018,0088 : Space Between Slices
 *                 else from 0018,0050 : Slice Thickness
 *                 else 1.0
 *
 * When an element is missing, we suppose slices join together
 * (no overlapping, no interslice gap) but we have no way to check it !
 * For *Dicom* images, ZSpacing *should be* calculated using 
 * XOrigin, YOrigin, ZOrigin (of the top left image corner)
 * of 2 consecutive images, and the Orientation
 * Computing ZSpacing on a single image is not really meaningfull ! 
 * @return Z dimension of a voxel-to be
 */
float File::GetZSpacing()
{
   // There are still a lot of modality we are not dealing with, esp US
   // There are tags like: D 3004|000c [DS]    [Grid Frame Offset Vector] [0.0\2.00000003000000...]
   // or D 0018|1065 [DS] [Frame Time Vector] [0.0\8.000000e+01\8.000000e+01\...
   // That are perfeclty valid to be used
   // Spacing Between Slices : distance between the middle of 2 slices
   // Slices may be :
   //   jointives     (Spacing between Slices = Slice Thickness)
   //   overlapping   (Spacing between Slices < Slice Thickness)
   //   disjointes    (Spacing between Slices > Slice Thickness)
   // Slice Thickness : epaisseur de tissus sur laquelle est acquis le signal
   //   It only concerns the MRI guys, not people wanting to visualize volumes
   //   If Spacing Between Slices is missing, 
   //   we suppose slices joint together

   // --->
   // ---> Warning :
   // --->
   
  //
  // For *Dicom* images, ZSpacing should be calculated using 
  // XOrigin, YOrigin, ZOrigin (of the top left image corner)
  // of 2 consecutive images, and the Orientation
  // 
  // Computing ZSpacing on a single image is not really meaningfull !
  float xspacing = 1.0;
  float yspacing = 1.0;
  float zspacing = 1.0;
  if ( GetSpacing(xspacing,yspacing,zspacing) )
    {
    return zspacing;
    }
 
   const std::string &strSpacingBSlices = GetEntryValue(0x0018,0x0088);

   if ( strSpacingBSlices == GDCM_UNFOUND )
   {
      gdcmWarningMacro("Unfound Spacing Between Slices (0018,0088)");
      const std::string &strSliceThickness = GetEntryValue(0x0018,0x0050);       
      if ( strSliceThickness == GDCM_UNFOUND )
      {
         gdcmWarningMacro("Unfound Slice Thickness (0018,0050)");
         return 1.0;
      }
      else
      {
         // if no 'Spacing Between Slices' is found, 
         // we assume slices join together
         // (no overlapping, no interslice gap)
         // if they don't, we're fucked up
         return (float)atof( strSliceThickness.c_str() );
      }
   }
   //else
   
   float zsp = (float)atof( strSpacingBSlices.c_str());
   if (zsp == 0.0) // last change not to break further computations ...
      zsp = 1.0;
   return zsp;
}

/**
 * \brief gets the info from 0020,0032 : Image Position Patient
 *                 else from 0020,0030 : Image Position (RET)
 *                 else 0.
 * @return up-left image corner X position
 */
float File::GetXOrigin()
{
   float xImPos, yImPos, zImPos;  
   std::string strImPos = GetEntryValue(0x0020,0x0032);

   if ( strImPos == GDCM_UNFOUND )
   {
      gdcmWarningMacro( "Unfound Image Position Patient (0020,0032)");
      strImPos = GetEntryValue(0x0020,0x0030); // For ACR-NEMA images
      if ( strImPos == GDCM_UNFOUND )
      {
         gdcmWarningMacro( "Unfound Image Position (RET) (0020,0030)");
         return 0.0;
      }
   }

   if ( sscanf( strImPos.c_str(), "%f \\%f \\%f ", &xImPos, &yImPos, &zImPos) != 3 )
   {
      return 0.0;
   }

   return xImPos;
}

/**
 * \brief gets the info from 0020,0032 : Image Position Patient
 *                 else from 0020,0030 : Image Position (RET)
 *                 else 0.
 * @return up-left image corner Y position
 */
float File::GetYOrigin()
{
   float xImPos, yImPos, zImPos;
   std::string strImPos = GetEntryValue(0x0020,0x0032);

   if ( strImPos == GDCM_UNFOUND)
   {
      gdcmWarningMacro( "Unfound Image Position Patient (0020,0032)");
      strImPos = GetEntryValue(0x0020,0x0030); // For ACR-NEMA images
      if ( strImPos == GDCM_UNFOUND )
      {
         gdcmWarningMacro( "Unfound Image Position (RET) (0020,0030)");
         return 0.;
      }  
   }

   if ( sscanf( strImPos.c_str(), "%f \\%f \\%f ", &xImPos, &yImPos, &zImPos) != 3 )
   {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -