Is vtkDICOMImageReader spacing reading wrong?

I have a DICOM series sliced axially with:

(0020,0037) DS [1\0\0\0\1\0]                            #  12, 6 ImageOrientationPatient
(0028,0010) US 1024                                     #   2, 1 Rows
(0028,0011) US 180                                      #   2, 1 Columns
(0028,0030) DS [.25451123714447\.999946594238281]       #  32, 2 PixelSpacing

The series loads properly in softwares like 3D Slicer or Horos.

However, when loading the image with vtkDICOMImageReader, the column and row spacings are swapped:

vtkSmartPointer<vtkDICOMImageReader> reader =
    vtkSmartPointer<vtkDICOMImageReader>::New();

reader->SetDirectoryName(path.c_str());
reader->Update();
imageData = reader->GetOutput();

vtkDICOMImageReader uses DICOMAppHelper where it gets the spacing like this:

void DICOMAppHelper::PixelSpacingCallback(DICOMParser* parser, doublebyte group, doublebyte element,
  DICOMParser::VRTypes, unsigned char* val, quadbyte)
{
  if (group == 0x0028 && element == 0x0030)
  {
    if (!val ||
      sscanf(reinterpret_cast<char*>(val), "%f\\%f", &this->PixelSpacing[0],
        &this->PixelSpacing[1]) != 2)
    {
      this->PixelSpacing[0] = this->PixelSpacing[1] = 0.0;
    }
  }
  else if (group == 0x0018 && element == 0x0050)
  {
    if (!val)
    {
      this->PixelSpacing[2] = 0.0;
    }
    else
    {
      this->PixelSpacing[2] =
        DICOMFile::ReturnAsFloat(val, parser->GetDICOMFile()->GetPlatformIsBigEndian());
    }
  }
}

But, in the same class this->Dimensions[0] corresponds to the columns and this->Dimensions[1] corresponds to the rows, which is backwards compared to this->PixelSpacing[0] (rows) and this->PixelSpacing[1] (columns).

Am I missing something? Is this a limitation of vtkDICOMImageReader?

Yes, this is a bug. DICOM PixelSpacing is row/column and the DICOMAppHelper class should be switching it to VTK’s column/row ordering. I can push a fix to VTK’s gitlab for review later this week.

Note that vtkDICOMImageReader has many other limitations. It is unable to read compressed images, enhanced images, or images with embedded icons. It also parses sequences (SQ) and unknown (UN) values incorrectly, and doesn’t handle image orientation correctly. The only DICOM files it can read are very simple ones.

Some alternatives to the vtkDICOMImageReader are vtk-dicom (which I wrote, on github), ITK with an ITK->VTK bridge, or (if using Python) to read the file into a numpy array with pydicom and use a numpy->VTK bridge.