<div dir="ltr"><div>Hi Matthew,</div><div><br></div><div>I've written a patch that includes your fix:</div><a href="https://gitlab.kitware.com/vtk/vtk/merge_requests/181">https://gitlab.kitware.com/vtk/vtk/merge_requests/181</a><br><div><br></div><div>Hopefully we'll get this merged soon.</div><div><br></div><div> - David</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 6, 2015 at 2:10 PM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Matthew,<div><br></div><div>I have confirmed that when qfac=-1, the z-offset in the qform and sform</div><div>differ when they should be exactly the same.  It is a very good thing that</div><div>you found this problem.  I'll get to work on verifying your fix.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div> - David</div></font></span><div><div class="h5"><div><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 6, 2015 at 9:25 AM, mbrown <span dir="ltr"><<a href="mailto:mbrown2@ualberta.ca" target="_blank">mbrown2@ualberta.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Is the following behaviour a bug in vtkNIFTImageReader ?<br>
<br>
If you load SPM8's EPI.nii MNI template file using vtkNIFTIImageReader, it<br>
produces different q-form and s-form matrices. Note that the EPI.nii file<br>
obeys radiological convention (i.e. left-right flipped, qfac=-1 and<br>
left-handed s-form matrix), and vtkNIFTIImageReader flips the slice order<br>
and changes the q-form and s-form matrices as described in<br>
vtkNIFTIImageReader.cxx. To reproduce, in Python 2.7.3, running on Ubuntu<br>
12.04, using vtk 6.2.0, do this:<br>
<br>
import vtk<br>
file_path = '<path/to/SPM8>/templates/EPI.nii'<br>
r = vtk.vtkNIFTIImageReader()<br>
r.SetFileName(file_path)<br>
r.Update()<br>
print(r.GetNIFTIHeader()) # original header values<br>
print(r.GetQFormMatrix()) # q-form matrix, with modifications by<br>
vtkNIFTIImageReader<br>
print(r.GetSFormMatrix()) # s-form matrix, with modifications by<br>
vtkNIFTIImageReader<br>
<br>
The last three lines produce ...<br>
<br>
original NIFTI header values (unnecessary fields not shown):<br>
Dim: 3 91 109 91 1 1 1 1<br>
PixDim: -1 2 2 2 0 0 0 0<br>
QFormCode: 4<br>
SFormCode: 4<br>
QuaternB: 0<br>
QuaternC: 1<br>
QuaternD: 0<br>
QoffsetX: 90<br>
QoffsetY: -126<br>
QoffsetZ: -72<br>
SRowX: -2 0 0  90<br>
SRowY:  0 2 0 -126<br>
SRowZ:  0 0 2 -72<br>
<br>
q-form matrix<br>
-1  0  0   90<br>
 0 -1  0 -126<br>
 0  0 -1  108<br>
 0  0  0  1<br>
<br>
s-form matrix<br>
-1  0  0   90<br>
 0 -1  0 -126<br>
 0  0 -1 -252<br>
 0  0  0  1<br>
<br>
I.e. the z-offset number in the fourth column is different between the<br>
q-form and s-form matrices. I tracked down the cause. In<br>
vtkNIFTIImageReader.cxx (accessed from<br>
<a href="https://github.com/Kitware/VTK/blob/master/IO/Image/vtkNIFTIImageReader.cxx" target="_blank">https://github.com/Kitware/VTK/blob/master/IO/Image/vtkNIFTIImageReader.cxx</a><br>
on 2015-05-06):<br>
<br>
lines 974-976, where it adjusts the q-form matrix when qfac<0:<br>
      mmat[3] -= rmat[0][2]*hdr2->pixdim[3]*(hdr2->dim[3] - 1);<br>
      mmat[7] -= rmat[1][2]*hdr2->pixdim[3]*(hdr2->dim[3] - 1);<br>
      mmat[11] -= rmat[2][2]*hdr2->pixdim[3]*(hdr2->dim[3] - 1);<br>
<br>
versus lines 1031-1033, where it adjusts the s-form matrix when qfac<0:<br>
      mmat[3] -= hdr2->srow_x[2]*(hdr2->dim[3] - 1);<br>
      mmat[7] -= hdr2->srow_y[2]*(hdr2->dim[3] - 1);<br>
      mmat[11] -= hdr2->srow_z[2]*(hdr2->dim[3] - 1);<br>
<br>
Importantly, the rmat matrix (computed on line 926) used in lines 974-976 is<br>
positive definite whereas the matrix defined by srow_x,y,z and used in lines<br>
1031-1033 has negative determinant, in the case of SPM8's EPI.nii file. This<br>
means that rmat[2,2]=-1 and line 976 adds 180 to mmat[11] taking it from -72<br>
to 108 in the case of EPI.nii. In contrast, srow_z[2]=2, and line 1033<br>
subtracts 180 from mmat[11] taking it from -72 to -252.<br>
<br>
Is this difference in behaviour intentional? If so, why?<br>
<br>
Other tests suggest that the q-form code is correct and the s-form code is<br>
incorrect. A possible fix would be to replace lines 1031-1033 with:<br>
      mmat[3] += hdr2->srow_x[2]*(hdr2->dim[3] - 1);<br>
      mmat[7] += hdr2->srow_y[2]*(hdr2->dim[3] - 1);<br>
      mmat[11] += hdr2->srow_z[2]*(hdr2->dim[3] - 1);<br>
<br>
What do you think? Thanks.<br>
Matt<br>
<br>
----------<br>
Matthew Brown, PhD<br>
Department of Psychiatry, University of Alberta<br>
Edmonton, Canada<br></blockquote></div></div></div></div></div></div>
</blockquote></div><br></div>