unexpected axes orientation in volshow()
Matlab documentation recommends using volshow() to display nifti-format images. volshow() does NOT map the indices i,j,k to the x,y,z axes, contrary to the nifti format specification. Have others noticed this? Do you see it as a problem? Could this cause medical scans to display in mirror image from what they should be?
The nifti format specification (nifti1.h, here) says that the indices i,j,k in V(i,j,k) map to x,y,z respectively, by default. (This is called Method 1 in lines 1038-1040 of nifti1.h.) Since I have not specified otherwise, I expect the default method to be used. Furthermore, if I do specify a mapping, using the an affine transform with the identity matrix, i,j,k should map to x,y,z respectively, but they do not. This method is called Method 3 in lines 1101-1103 of the nifti1.h specification. In case you’re wondering, the nifti1.h file also explains at lines 1008-1011 that the first, second,third array indices (i,j,k) should change fastest, medium, slowest respectively, as the array is stored in memory. And that is how Matlab array indices work.
Whether I use Method 1 or 3, index i maps to y and index j maps to x, contrary to expectation.
The code below demonstrates this by making and plotting a 3D scan. The volume V is 99x99x99. It has three lines from the center leading out to the centers of the imax face, the jmax face, and the kmax face. At the max end of each line, there are different size squares, to allow us to tell which is which. The imax face has a small square, the jmax face has a large square, and the kmax face has a medium square. I expect these to be at the +x, +y, and +z axes, respectively, but the large and small are reversed (x-y) from what I expect. This is not just a rotation of the data, it is a reflection, since data expected at +x and +y are flipped. See below.
Other things I’ve tried:
Write the volume to a nifti file, then read it in, then display it. Same result.
Define tform=affinetform3d(eye(4)); and use it: volshow(V,Transformation=tform);. Same result.
I realize that I can use an affine transformation (reflection) S=[0,1,0,0; 1,0,0,0; 0,0,1,0; 0,0,0,1] to make this look like I expected. But I think I shouldn’t have to, or it should be documented.
Since volshow() does not display in Matlab Answers, I have attached a screenshot of the displayed volume that results from the code below.
imax=99; jmax=99; kmax=99; % volume dimensions
V=zeros(imax,jmax,kmax); % allocate array
% draw line from cube center to center of imax face
V(50:imax,50,50)=ones(50,1,1);
% draw line from cube center to center of jmax face
V(50,50:jmax,50)=ones(1,50,1);
% draw line from cube center to center of kmax face
V(50,50,50:kmax)=ones(1,1,50);
% small (9×9) square at center of imax face (imax,jmid,kmid)
V(imax,46:54,46:54)=ones(1,9,9);
% large (21×21) square at center of jmax face (imid, jmax, kmid)
V(40:60,jmax,40:60)=ones(21,1,21);
% medium (15×15) square at center of kmax face (imid, jmid, kmax)
V(43:57,43:57,kmax)=ones(15,15,1);
% Display simulated scan
volshow(V);Matlab documentation recommends using volshow() to display nifti-format images. volshow() does NOT map the indices i,j,k to the x,y,z axes, contrary to the nifti format specification. Have others noticed this? Do you see it as a problem? Could this cause medical scans to display in mirror image from what they should be?
The nifti format specification (nifti1.h, here) says that the indices i,j,k in V(i,j,k) map to x,y,z respectively, by default. (This is called Method 1 in lines 1038-1040 of nifti1.h.) Since I have not specified otherwise, I expect the default method to be used. Furthermore, if I do specify a mapping, using the an affine transform with the identity matrix, i,j,k should map to x,y,z respectively, but they do not. This method is called Method 3 in lines 1101-1103 of the nifti1.h specification. In case you’re wondering, the nifti1.h file also explains at lines 1008-1011 that the first, second,third array indices (i,j,k) should change fastest, medium, slowest respectively, as the array is stored in memory. And that is how Matlab array indices work.
Whether I use Method 1 or 3, index i maps to y and index j maps to x, contrary to expectation.
The code below demonstrates this by making and plotting a 3D scan. The volume V is 99x99x99. It has three lines from the center leading out to the centers of the imax face, the jmax face, and the kmax face. At the max end of each line, there are different size squares, to allow us to tell which is which. The imax face has a small square, the jmax face has a large square, and the kmax face has a medium square. I expect these to be at the +x, +y, and +z axes, respectively, but the large and small are reversed (x-y) from what I expect. This is not just a rotation of the data, it is a reflection, since data expected at +x and +y are flipped. See below.
Other things I’ve tried:
Write the volume to a nifti file, then read it in, then display it. Same result.
Define tform=affinetform3d(eye(4)); and use it: volshow(V,Transformation=tform);. Same result.
I realize that I can use an affine transformation (reflection) S=[0,1,0,0; 1,0,0,0; 0,0,1,0; 0,0,0,1] to make this look like I expected. But I think I shouldn’t have to, or it should be documented.
Since volshow() does not display in Matlab Answers, I have attached a screenshot of the displayed volume that results from the code below.
imax=99; jmax=99; kmax=99; % volume dimensions
V=zeros(imax,jmax,kmax); % allocate array
% draw line from cube center to center of imax face
V(50:imax,50,50)=ones(50,1,1);
% draw line from cube center to center of jmax face
V(50,50:jmax,50)=ones(1,50,1);
% draw line from cube center to center of kmax face
V(50,50,50:kmax)=ones(1,1,50);
% small (9×9) square at center of imax face (imax,jmid,kmid)
V(imax,46:54,46:54)=ones(1,9,9);
% large (21×21) square at center of jmax face (imid, jmax, kmid)
V(40:60,jmax,40:60)=ones(21,1,21);
% medium (15×15) square at center of kmax face (imid, jmid, kmax)
V(43:57,43:57,kmax)=ones(15,15,1);
% Display simulated scan
volshow(V); Matlab documentation recommends using volshow() to display nifti-format images. volshow() does NOT map the indices i,j,k to the x,y,z axes, contrary to the nifti format specification. Have others noticed this? Do you see it as a problem? Could this cause medical scans to display in mirror image from what they should be?
The nifti format specification (nifti1.h, here) says that the indices i,j,k in V(i,j,k) map to x,y,z respectively, by default. (This is called Method 1 in lines 1038-1040 of nifti1.h.) Since I have not specified otherwise, I expect the default method to be used. Furthermore, if I do specify a mapping, using the an affine transform with the identity matrix, i,j,k should map to x,y,z respectively, but they do not. This method is called Method 3 in lines 1101-1103 of the nifti1.h specification. In case you’re wondering, the nifti1.h file also explains at lines 1008-1011 that the first, second,third array indices (i,j,k) should change fastest, medium, slowest respectively, as the array is stored in memory. And that is how Matlab array indices work.
Whether I use Method 1 or 3, index i maps to y and index j maps to x, contrary to expectation.
The code below demonstrates this by making and plotting a 3D scan. The volume V is 99x99x99. It has three lines from the center leading out to the centers of the imax face, the jmax face, and the kmax face. At the max end of each line, there are different size squares, to allow us to tell which is which. The imax face has a small square, the jmax face has a large square, and the kmax face has a medium square. I expect these to be at the +x, +y, and +z axes, respectively, but the large and small are reversed (x-y) from what I expect. This is not just a rotation of the data, it is a reflection, since data expected at +x and +y are flipped. See below.
Other things I’ve tried:
Write the volume to a nifti file, then read it in, then display it. Same result.
Define tform=affinetform3d(eye(4)); and use it: volshow(V,Transformation=tform);. Same result.
I realize that I can use an affine transformation (reflection) S=[0,1,0,0; 1,0,0,0; 0,0,1,0; 0,0,0,1] to make this look like I expected. But I think I shouldn’t have to, or it should be documented.
Since volshow() does not display in Matlab Answers, I have attached a screenshot of the displayed volume that results from the code below.
imax=99; jmax=99; kmax=99; % volume dimensions
V=zeros(imax,jmax,kmax); % allocate array
% draw line from cube center to center of imax face
V(50:imax,50,50)=ones(50,1,1);
% draw line from cube center to center of jmax face
V(50,50:jmax,50)=ones(1,50,1);
% draw line from cube center to center of kmax face
V(50,50,50:kmax)=ones(1,1,50);
% small (9×9) square at center of imax face (imax,jmid,kmid)
V(imax,46:54,46:54)=ones(1,9,9);
% large (21×21) square at center of jmax face (imid, jmax, kmid)
V(40:60,jmax,40:60)=ones(21,1,21);
% medium (15×15) square at center of kmax face (imid, jmid, kmax)
V(43:57,43:57,kmax)=ones(15,15,1);
% Display simulated scan
volshow(V); nifti, volshow, medical image MATLAB Answers — New Questions









