From d9004c3f22ee0244e8019cd32aca326dd93acacf Mon Sep 17 00:00:00 2001 From: durm2107 Date: Mon, 25 Jan 2021 14:28:43 -0500 Subject: [PATCH 1/7] concatenate 3d with 4d images into a 4d image --- scilpy/image/operations.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/scilpy/image/operations.py b/scilpy/image/operations.py index 4d1b61b73..76492d4dd 100644 --- a/scilpy/image/operations.py +++ b/scilpy/image/operations.py @@ -502,17 +502,28 @@ def invert(input_list, ref_img): def concat(input_list, ref_img): """ concat: IMGs - Concatenate a list of 3D images into a single 4D image. + Concatenate a list of 3D and 4D images into a single 4D image. """ - _validate_imgs(*input_list, ref_img) - if len(input_list[0].header.get_data_shape()) != 3: - raise ValueError('Concatenate require 3D arrays.') - + + # _validate_imgs(*input_list, ref_img) + if len(input_list[0].header.get_data_shape()) > 4: + raise ValueError('Concatenate require 3D or 4D arrays.') + input_data = [] for img in input_list: + data = img.get_fdata(dtype=np.float64) - input_data.append(data) + + if len(img.header.get_data_shape()) == 4: + data = np.rollaxis(data, 3) + for i in range(0, len(data)): + print(data[i]) + input_data.append(data[i]) + else: + input_data.append(data) + img.uncache() + return np.rollaxis(np.stack(input_data), axis=0, start=4) From 94cd9a581522506adcdf114b2e721d8f41e7effe Mon Sep 17 00:00:00 2001 From: durm2107 Date: Mon, 25 Jan 2021 14:48:19 -0500 Subject: [PATCH 2/7] Removed artifact from tests --- scilpy/image/operations.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scilpy/image/operations.py b/scilpy/image/operations.py index 76492d4dd..b71e934b8 100644 --- a/scilpy/image/operations.py +++ b/scilpy/image/operations.py @@ -517,7 +517,6 @@ def concat(input_list, ref_img): if len(img.header.get_data_shape()) == 4: data = np.rollaxis(data, 3) for i in range(0, len(data)): - print(data[i]) input_data.append(data[i]) else: input_data.append(data) From 072dc4b1dca379b7deb4850db59acea531a727bf Mon Sep 17 00:00:00 2001 From: durm2107 Date: Fri, 5 Feb 2021 13:32:58 -0500 Subject: [PATCH 3/7] Added a test for testing concatenation of a 4D image --- scilpy/io/fetcher.py | 2 +- scripts/tests/test_image_math.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/scilpy/io/fetcher.py b/scilpy/io/fetcher.py index ecf56b412..2c3a2de10 100644 --- a/scilpy/io/fetcher.py +++ b/scilpy/io/fetcher.py @@ -29,7 +29,7 @@ def get_testing_files_dict(): '66e07ada4dd2a192a44705277e0673bb'], 'atlas.zip': ['1waYx4ED3qwzyJqrICjjgGXXBW2v4ZCYJ', - 'af15ab98bc1faf2554fa0abb1891f345'], + 'eb37427054cef5d50ac3d429ff53de47'], 'bst.zip': ['1YprJRnyXk7VRHUkb-bJLs69C1v3tPd1S', 'c0551a28dcefcd7cb53f572b1794b3e8'], diff --git a/scripts/tests/test_image_math.py b/scripts/tests/test_image_math.py index b34d82085..ecbb3f36e 100644 --- a/scripts/tests/test_image_math.py +++ b/scripts/tests/test_image_math.py @@ -57,3 +57,15 @@ def test_execution_concat(script_runner): in_img_1, in_img_2, in_img_3, in_img_4, in_img_5, in_img_6, 'concat_ids.nii.gz') assert ret.success + + +def test_execution_concat_4D(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_img_1 = os.path.join(get_home(), 'atlas', 'ids', '10.nii.gz') + in_img_2 = os.path.join(get_home(), 'atlas', 'ids', '8_10.nii.gz') + in_img_3 = os.path.join(get_home(), 'atlas', 'ids', '12.nii.gz') + in_img_4 = os.path.join(get_home(), 'atlas', 'ids', '8_10.nii.gz') + ret = script_runner.run('scil_image_math.py', 'concatenate', + in_img_1, in_img_2, in_img_3, in_img_4, + 'concat_ids.nii.gz') + assert ret.success From db3030e5ad80921ba6678dcc9a03512a96f8f48b Mon Sep 17 00:00:00 2001 From: durm2107 Date: Thu, 11 Feb 2021 09:17:31 -0500 Subject: [PATCH 4/7] Added test for 4D concatenation --- scilpy/image/operations.py | 6 +++--- scripts/scil_image_math.py | 33 +++++++++++++++++++++++++++++++- scripts/tests/test_image_math.py | 6 +++--- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/scilpy/image/operations.py b/scilpy/image/operations.py index b71e934b8..72726b045 100644 --- a/scilpy/image/operations.py +++ b/scilpy/image/operations.py @@ -54,7 +54,7 @@ def get_image_ops(): """Get a dictionary of all functions relating to image operations""" image_ops = get_array_ops() image_ops.update(OrderedDict([ - ('concatenate', concat), + ('concatenate', concatenate), ('dilation', dilation), ('erosion', erosion), ('closing', closing), @@ -499,9 +499,9 @@ def invert(input_list, ref_img): return output_data -def concat(input_list, ref_img): +def concatenate(input_list, ref_img): """ - concat: IMGs + concatenate: IMGs Concatenate a list of 3D and 4D images into a single 4D image. """ diff --git a/scripts/scil_image_math.py b/scripts/scil_image_math.py index ed51a65b2..7e8d8e775 100755 --- a/scripts/scil_image_math.py +++ b/scripts/scil_image_math.py @@ -101,12 +101,43 @@ def main(): # Find at least one image for reference for input_arg in args.in_images: found_ref = False - if not is_float(input_arg): + if not is_float(input_arg): ref_img = nib.load(input_arg) mask = np.zeros(ref_img.shape) found_ref = True break + # If there's a 4D image, replace the previous 3D image with this one for reference + for input_arg in args.in_images: + if not is_float(input_arg): + ref_img = nib.load(input_arg) + if len(ref_img.shape) == 4: + mask = np.zeros(ref_img.shape) + break + + # itr = 1 + # for input_arg in args.in_images: + # found_ref = False + # if not is_float(input_arg): + # ref_img = nib.load(input_arg) + + # print(args.in_images) + + # if len(ref_img.shape) == 4: + # mask = np.zeros(ref_img.shape) + # found_ref = True + # break + + # if len(args.in_images) == itr: + # mask = np.zeros(ref_img.shape) + # found_ref = True + # break + + # itr = itr + 1 + + + + if not found_ref: raise ValueError('Requires at least one nifti image.') diff --git a/scripts/tests/test_image_math.py b/scripts/tests/test_image_math.py index ecbb3f36e..e29f5c946 100644 --- a/scripts/tests/test_image_math.py +++ b/scripts/tests/test_image_math.py @@ -45,7 +45,7 @@ def test_execution_low_mult(script_runner): assert ret.success -def test_execution_concat(script_runner): +def test_execution_concatenate(script_runner): os.chdir(os.path.expanduser(tmp_dir.name)) in_img_1 = os.path.join(get_home(), 'atlas', 'ids', '10.nii.gz') in_img_2 = os.path.join(get_home(), 'atlas', 'ids', '11.nii.gz') @@ -59,7 +59,7 @@ def test_execution_concat(script_runner): assert ret.success -def test_execution_concat_4D(script_runner): +def test_execution_concatenate_4D(script_runner): os.chdir(os.path.expanduser(tmp_dir.name)) in_img_1 = os.path.join(get_home(), 'atlas', 'ids', '10.nii.gz') in_img_2 = os.path.join(get_home(), 'atlas', 'ids', '8_10.nii.gz') @@ -67,5 +67,5 @@ def test_execution_concat_4D(script_runner): in_img_4 = os.path.join(get_home(), 'atlas', 'ids', '8_10.nii.gz') ret = script_runner.run('scil_image_math.py', 'concatenate', in_img_1, in_img_2, in_img_3, in_img_4, - 'concat_ids.nii.gz') + 'concat_ids_4d.nii.gz') assert ret.success From ac50082170e614492990ce063d1da468c7490140 Mon Sep 17 00:00:00 2001 From: durm2107 Date: Thu, 11 Feb 2021 09:27:25 -0500 Subject: [PATCH 5/7] Test added for 4D images concatenation --- scilpy/image/operations.py | 10 +++++++++- scripts/scil_image_math.py | 25 +------------------------ 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/scilpy/image/operations.py b/scilpy/image/operations.py index 72726b045..060d26e44 100644 --- a/scilpy/image/operations.py +++ b/scilpy/image/operations.py @@ -83,6 +83,14 @@ def _validate_imgs(*imgs): raise ValueError('Not all inputs have the same shape!') +def _validate_imgs_concat(*imgs): + """Make sure that all inputs are images.""" + ref_img = imgs[-1] + for img in imgs: + if isinstance(img, nib.Nifti1Image): + raise ValueError('Inputs are not all images') + + def _validate_length(input_list, length, at_least=False): """Make sure the the input list has the right number of arguments (length).""" @@ -505,7 +513,7 @@ def concatenate(input_list, ref_img): Concatenate a list of 3D and 4D images into a single 4D image. """ - # _validate_imgs(*input_list, ref_img) + _validate_imgs_concat(*input_list, ref_img) if len(input_list[0].header.get_data_shape()) > 4: raise ValueError('Concatenate require 3D or 4D arrays.') diff --git a/scripts/scil_image_math.py b/scripts/scil_image_math.py index 7e8d8e775..ea7ffb206 100755 --- a/scripts/scil_image_math.py +++ b/scripts/scil_image_math.py @@ -113,30 +113,7 @@ def main(): ref_img = nib.load(input_arg) if len(ref_img.shape) == 4: mask = np.zeros(ref_img.shape) - break - - # itr = 1 - # for input_arg in args.in_images: - # found_ref = False - # if not is_float(input_arg): - # ref_img = nib.load(input_arg) - - # print(args.in_images) - - # if len(ref_img.shape) == 4: - # mask = np.zeros(ref_img.shape) - # found_ref = True - # break - - # if len(args.in_images) == itr: - # mask = np.zeros(ref_img.shape) - # found_ref = True - # break - - # itr = itr + 1 - - - + break if not found_ref: raise ValueError('Requires at least one nifti image.') From 231a13a9a75dd2a002b908b24849ca4c38a1bf38 Mon Sep 17 00:00:00 2001 From: durm2107 Date: Thu, 11 Feb 2021 13:52:50 -0500 Subject: [PATCH 6/7] Fix isinstance and mask --- scilpy/image/operations.py | 3 +-- scripts/scil_image_math.py | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/scilpy/image/operations.py b/scilpy/image/operations.py index 060d26e44..b9c3a195e 100644 --- a/scilpy/image/operations.py +++ b/scilpy/image/operations.py @@ -85,9 +85,8 @@ def _validate_imgs(*imgs): def _validate_imgs_concat(*imgs): """Make sure that all inputs are images.""" - ref_img = imgs[-1] for img in imgs: - if isinstance(img, nib.Nifti1Image): + if not isinstance(img, nib.Nifti1Image): raise ValueError('Inputs are not all images') diff --git a/scripts/scil_image_math.py b/scripts/scil_image_math.py index ea7ffb206..e26ca6b12 100755 --- a/scripts/scil_image_math.py +++ b/scripts/scil_image_math.py @@ -101,7 +101,7 @@ def main(): # Find at least one image for reference for input_arg in args.in_images: found_ref = False - if not is_float(input_arg): + if not is_float(input_arg): ref_img = nib.load(input_arg) mask = np.zeros(ref_img.shape) found_ref = True @@ -145,7 +145,10 @@ def main(): if isinstance(img, nib.Nifti1Image): data = img.get_fdata(dtype=np.float64) - mask[data > 0] = 1 + if data.ndim == 4: + mask[np.sum(data, axis=3).astype(bool) > 0] = 1 + else: + mask[data > 0] = 1 img.uncache() input_img.append(img) From 53dbd946030a118ebe227354322508f2720e1d86 Mon Sep 17 00:00:00 2001 From: durm2107 Date: Thu, 11 Feb 2021 14:37:50 -0500 Subject: [PATCH 7/7] Fixed files for pep8 --- scilpy/image/operations.py | 13 +++++++------ scripts/scil_image_math.py | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/scilpy/image/operations.py b/scilpy/image/operations.py index b9c3a195e..37f951696 100644 --- a/scilpy/image/operations.py +++ b/scilpy/image/operations.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- """ -Utility operations provided for scil_image_math.py and scil_connectivity_math.py +Utility operations provided for scil_image_math.py +and scil_connectivity_math.py They basically act as wrappers around numpy to avoid installing MRtrix/FSL to apply simple operations on nibabel images or numpy arrays. """ @@ -511,23 +512,23 @@ def concatenate(input_list, ref_img): concatenate: IMGs Concatenate a list of 3D and 4D images into a single 4D image. """ - + _validate_imgs_concat(*input_list, ref_img) if len(input_list[0].header.get_data_shape()) > 4: raise ValueError('Concatenate require 3D or 4D arrays.') - + input_data = [] for img in input_list: data = img.get_fdata(dtype=np.float64) - + if len(img.header.get_data_shape()) == 4: data = np.rollaxis(data, 3) for i in range(0, len(data)): input_data.append(data[i]) else: - input_data.append(data) - + input_data.append(data) + img.uncache() return np.rollaxis(np.stack(input_data), axis=0, start=4) diff --git a/scripts/scil_image_math.py b/scripts/scil_image_math.py index e26ca6b12..766312bea 100755 --- a/scripts/scil_image_math.py +++ b/scripts/scil_image_math.py @@ -107,13 +107,14 @@ def main(): found_ref = True break - # If there's a 4D image, replace the previous 3D image with this one for reference + # If there's a 4D image, replace the previous 3D image with + # this one for reference for input_arg in args.in_images: if not is_float(input_arg): ref_img = nib.load(input_arg) if len(ref_img.shape) == 4: mask = np.zeros(ref_img.shape) - break + break if not found_ref: raise ValueError('Requires at least one nifti image.')