diff --git a/droplet_growth/register.py b/droplet_growth/register.py index a02f6d65d6dd71c45320c7314ac0d96511dad86e..a064b6d53792e318978adc14dfa790f5a9b2de07 100644 --- a/droplet_growth/register.py +++ b/droplet_growth/register.py @@ -5,6 +5,7 @@ import numpy as np import scipy.ndimage as ndi from droplet_growth import mic from nd2tif.transform import to_8bits +import os grey = np.array([np.arange(256)] * 3, dtype='uint8') red = np.array([np.arange(256), np.zeros((256,)), np.zeros((256,))], dtype='uint8') @@ -24,7 +25,7 @@ META_ALIGNED = {'ImageJ': '1.53c', 'LUTs': [grey, green, blue] } -def align_stack(path, template16, mask2, plot=False, binnings=(1,16,2), suffix='.aligned.tif'): +def align_stack(data_or_path, template16, mask2, plot=False, path=None, binnings=(1,16,2), suffix='.aligned.tif'): ''' stack should contain two channels: bright field and fluorescence. BF will be binned 8 times and registered with template8 (aligned BF). @@ -32,22 +33,29 @@ def align_stack(path, template16, mask2, plot=False, binnings=(1,16,2), suffix=' The output stack is of the same size as mask. The resulting 3-layer stack will be returned and also saved with suffix ".aligned.tif" ''' - - stack = imread(path) - print(path, stack.shape) + if isinstance(data_or_path, str): + path = data_or_path + stack = imread(path) + print(path, stack.shape) + else: + assert data_or_path.ndim == 3 and data_or_path.shape[0] == 2 + assert path is not None + stack = data_or_path bf, tritc = stack[:2] stack_temp_scale = binnings[1] // binnings[0] mask_temp_scale = binnings[1] // binnings[2] stack_mask_scale = binnings[2] // binnings[0] - f_bf = filter_by_fft( - bf[::stack_temp_scale, ::stack_temp_scale], - sigma=40, - fix_horizontal_stripes=True, - fix_vertical_stripes=True, - highpass=True - ) + f_bf = bf[::stack_temp_scale, ::stack_temp_scale] + + # f_bf = filter_by_fft( + # bf[::stack_temp_scale, ::stack_temp_scale], + # sigma=40, + # fix_horizontal_stripes=True, + # fix_vertical_stripes=True, + # highpass=True + # ) tvec8 = get_transform(f_bf, template16, plot=plot) plt.show() tvec = scale_tvec(tvec8, mask_temp_scale) @@ -74,12 +82,12 @@ def align_stack(path, template16, mask2, plot=False, binnings=(1,16,2), suffix=' aligned_stack = np.stack((aligned_bf, aligned_tritc, mask2)).astype('uint16') - imwrite((p:=path.replace('.tif', suffix)), aligned_stack, imagej=True, metadata=META_ALIGNED) + imwrite((p:="".join((*path.split('.')[:-1] , suffix))), aligned_stack, imagej=True, metadata=META_ALIGNED) print(f'Saved aligned stack {p}') return aligned_stack -def align_stack_nd(stack, template16, mask2, plot=False, binnings=(1,16,2), suffix='.aligned.tif'): +def align_stack_nd(stack, template16, mask2, path=None, plot=False, binnings=(1,16,2), suffix='.aligned.tif') -> (np.ndarray, dict): ''' stack should contain two channels: bright field and fluorescence. BF will be binned 8 times and registered with template8 (aligned BF). @@ -92,19 +100,21 @@ def align_stack_nd(stack, template16, mask2, plot=False, binnings=(1,16,2), suff bf, tritc = stack[:2] - print('inputs: \n', *[f'{name}: {im.shape}, {bin}\n' for name, im, bin in zip(['bf', 'tmp', 'mask'], [bf, template16, mask2], binnings )]) + print(f'Aligning {path}: \n', *[f'{name}: {im.shape}, {bin}\n' for name, im, bin in zip(['bf', 'tmp', 'mask'], [bf, template16, mask2], binnings )]) stack_temp_scale = binnings[1] // binnings[0] mask_temp_scale = binnings[1] // binnings[2] stack_mask_scale = binnings[2] // binnings[0] - f_bf = filter_by_fft( - bf[::stack_temp_scale, ::stack_temp_scale], - sigma=40, - fix_horizontal_stripes=True, - fix_vertical_stripes=True, - highpass=True - ) + f_bf = bf[::stack_temp_scale, ::stack_temp_scale] + + #filter_by_fft( + # bf[::stack_temp_scale, ::stack_temp_scale], + # sigma=40, + # fix_horizontal_stripes=True, + # fix_vertical_stripes=True, + # highpass=True + # ) tvec8 = get_transform(f_bf, template16, plot=plot) plt.show() tvec = scale_tvec(tvec8, mask_temp_scale) @@ -131,8 +141,9 @@ def align_stack_nd(stack, template16, mask2, plot=False, binnings=(1,16,2), suff aligned_stack = np.stack((aligned_bf, aligned_tritc, mask2)).astype('uint16') - # imwrite((p:=path.replace('.tif', suffix)), aligned_stack, imagej=True, metadata=META_ALIGNED) - # print(f'Saved aligned stack {p}') + if path is not None: + imwrite((p:="".join((*path.split('.')[:-1] , suffix))), aligned_stack, imagej=True, metadata=META_ALIGNED) + print(f'Saved aligned stack {p}') return aligned_stack, tvec @@ -142,20 +153,22 @@ def align_timelapse(bf, fluo_stack, template16, mask2, plot=False, binnings=(4,1 BF will be binned 8 times and registered with template8 (aligned BF). When the transformation verctor will be applied to the original data and stacked with the mask. The output stack is of the same size as mask. - The resulting 3-layer stack will be returned and also saved with suffix ".aligned.tif" + Return: + (aligned_bf, aligned_fluo, mask) ''' stack_temp_scale = binnings[1] // binnings[0] mask_temp_scale = binnings[1] // binnings[2] mask_bf_scale = binnings[0] // binnings[2] - f_bf = filter_by_fft( - bf[::stack_temp_scale, ::stack_temp_scale], - sigma=40, - fix_horizontal_stripes=True, - fix_vertical_stripes=True, - highpass=True - ) + f_bf = bf[::stack_temp_scale, ::stack_temp_scale] + # f_bf = filter_by_fft( + # bf[::stack_temp_scale, ::stack_temp_scale], + # sigma=40, + # fix_horizontal_stripes=True, + # fix_vertical_stripes=True, + # highpass=True + # ) tvec8 = get_transform(f_bf, template16, plot=plot) plt.show() tvec = scale_tvec(tvec8, stack_temp_scale)