Skip to content

Commit a61770c

Browse files
authored
Merge pull request #7 from effigies/fix/permute_axes
FIX: Accept images with any axis orientation
2 parents 10b3699 + 1cfd4df commit a61770c

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

quickshear.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,22 @@ def cross(o, a, b):
108108
return np.array(lower).T
109109

110110

111-
def flip_axes(data, flips):
111+
def flip_axes(data, perms, flips):
112112
""" Flip a data array along specified axes
113113
114114
Parameters
115115
----------
116116
data : 3D array
117+
perms : (3,) sequence of ints
118+
Axis permutations to perform
117119
flips : (3,) sequence of bools
118120
Sequence of indicators for whether to flip along each axis
119121
120122
Returns
121123
-------
122124
3D array
123125
"""
126+
data = np.transpose(data, perms)
124127
for axis in np.nonzero(flips)[0]:
125128
data = nb.orientations.flip_axis(data, axis)
126129
return data
@@ -140,13 +143,18 @@ def orient_xPS(img, hemi='R'):
140143
-------
141144
data : 3D array_like
142145
Re-oriented data array
146+
perm : (3,) sequence of ints
147+
Permutation of axes, relative to RAS
143148
flips : (3,) sequence of bools
144149
Sequence of indicators of axes flipped
145150
"""
146151
axes = nb.orientations.aff2axcodes(img.affine)
147-
data = img.get_data()
148-
flips = np.array(axes) != np.array((hemi, 'P', 'S'))
149-
return flip_axes(data, flips), flips
152+
perm = ['RASLPI'.index(axis) % 3 for axis in axes]
153+
inv_perm = np.argsort(perm)
154+
# Flips are in RPS order
155+
flips = np.array(axes)[inv_perm] != np.array((hemi, 'P', 'S'))
156+
# We permute axes then flip, so inverse flips are also permuted
157+
return flip_axes(img.get_data(), inv_perm, flips), perm, flips[perm]
150158

151159

152160
@due.dcite(BibTeX(citation_text), description="Geometric neuroimage defacer",
@@ -168,8 +176,8 @@ def quickshear(anat_img, mask_img, buff=10):
168176
SpatialImage
169177
Nibabel image of defaced anatomical scan
170178
"""
171-
anat, anat_flip = orient_xPS(anat_img)
172-
mask, mask_flip = orient_xPS(mask_img)
179+
anat, anat_perm, anat_flip = orient_xPS(anat_img)
180+
mask, mask_perm, mask_flip = orient_xPS(mask_img)
173181

174182
edgemask = edge_mask(mask)
175183
low = convex_hull(edgemask)
@@ -183,11 +191,12 @@ def quickshear(anat_img, mask_img, buff=10):
183191
for x, y in zip(np.nonzero(ys > 0)[0], ys.astype(int)):
184192
defaced_mask[:, x, :y] = 0
185193

186-
return anat_img.__class__(flip_axes(defaced_mask * anat, anat_flip),
187-
anat_img.affine, anat_img.header.copy())
194+
return anat_img.__class__(
195+
flip_axes(defaced_mask * anat, anat_perm, anat_flip),
196+
anat_img.affine, anat_img.header)
188197

189198

190-
def main(cmd, *argv):
199+
def main():
191200
logger = logging.getLogger(__name__)
192201
logger.setLevel(logging.DEBUG)
193202
ch = logging.StreamHandler()
@@ -207,7 +216,7 @@ def main(cmd, *argv):
207216
help="buffer size (in voxels) between shearing plane "
208217
"and the brain")
209218

210-
opts = parser.parse_args(argv)
219+
opts = parser.parse_args()
211220

212221
anat_img = nb.load(opts.anat_file)
213222
mask_img = nb.load(opts.mask_file)
@@ -223,4 +232,4 @@ def main(cmd, *argv):
223232

224233

225234
if __name__ == '__main__':
226-
sys.exit(main(*sys.argv))
235+
sys.exit(main())

0 commit comments

Comments
 (0)