def run(self, ips, imgs, para=None): k = para['diag'] / np.sqrt((np.array(ips.img.shape)**2).sum()) size = tuple((np.array(ips.img.shape) * k).astype(np.int16)) IPy.info('down sample...') news = [] for img in imgs: if k != 0: img = tf.resize(img, size) if para['sigma'] != 0: img = ndimg.gaussian_filter(img, para['sigma']) news.append(img) IPy.info('register...') sr = StackReg(eval('StackReg.%s' % para['trans'])) sr.register_stack(np.array(news), reference=para['ref']) mats = sr._tmats.reshape((sr._tmats.shape[0], -1)) if k != 0: mats[:, [0, 1, 3, 4, 6, 7]] *= k if k != 0: mats[:, [0, 1, 2, 3, 4, 5]] /= k if para['tab']: IPy.show_table(pd.DataFrame( mats, columns=['A%d' % (i + 1) for i in range(mats.shape[1])]), title='%s-Tmats' % ips.title) if para['new'] == 'None': return IPy.info('transform...') for i in range(sr._tmats.shape[0]): tform = tf.ProjectiveTransform(matrix=sr._tmats[i]) img = tf.warp(imgs[i], tform) img -= imgs[i].min() img *= imgs[i].max() - imgs[i].min() if para['new'] == 'Inplace': imgs[i][:] = img if para['new'] == 'New': news[i] = img.astype(ips.img.dtype) self.progress(i, len(imgs)) if para['new'] == 'New': IPy.show_img(news, '%s-reg' % ips.title)
def get_transformation(Tstack, reference): """ Parameters reference: register frame according to 'previous' or 'first' frame ---------- Tstack : uint16 3D array [x,y,t] Returns ------- outStack : uint16 3D array [x,y,t] in time registered slice trans_matrix : calculated transformation matrix """ Tstack = np.transpose(Tstack, (2, 0, 1)) sr = StackReg(StackReg.RIGID_BODY) # trans_matrix= sr.register_stack(Tstack, reference='first') trans_matrix = sr.register_stack(Tstack, reference=reference) outStack = sr.transform_stack(Tstack) outStack = np.uint16(outStack) outStack = np.transpose(outStack, (1, 2, 0)) return outStack, trans_matrix
def reg(stack): sr = StackReg(StackReg.TRANSLATION) t_mats = sr.register_stack(gauss(stack), reference='first', n_frames=1) t_mats[:, 0, -1] = 0 reg_stack = sr.transform_stack(stack, tmats=t_mats) return reg_stack
def align_simple(stack_img, transformation=StackReg.TRANSLATION, reference="previous"): sr = StackReg(transformation) tmats_ = sr.register_stack(stack_img, reference="previous") for i in range(10): out_stk = sr.transform_stack(stack_img, tmats=tmats_) return np.float32(out_stk)
def get_transformation(Tstack): # Tstack=np.transpose(Tstack,(2,0,1)) sr = StackReg(StackReg.RIGID_BODY) trans_matrix = sr.register_stack(Tstack, reference='first') # trans_matrix= sr.register_stack(Tstack, reference='previous') outStack = sr.transform_stack(Tstack) # outStack = np.transpose(outStack,(1,2,0)) outStack = np.uint16(outStack) return outStack, trans_matrix
def process(pth): print(f'\nProcessing {pth}') save_pth = pth / 'reg_stacks' #tmat_pth = pth / 'transformation_matrices' try: save_pth.mkdir() #tmat_pth.mkdir() except FileExistsError: ex('Save File for reg stacks or tmats already exists. Delete and re-run.' ) #tell pystack reg that we will use a translational transformation #there shouldn't be intra-volume rotation or shear (there might be for rod blink) sr = StackReg(StackReg.TRANSLATION) #register to the first slice and output the transfomation matrix without transforming #iterate through the files in the stacks folder files = pth.glob('*.tif') loop_starts = time.time() for i, file in enumerate(files): #start_time = time.time() print(f'Processing: {file}') #Intravolume registration of the fixed volume #load first stack and do a 3d gaussian blur with a sigma=1 #str needed for imread, otherwise only one frame is loaded fixed = io.imread(str(file)) #had gauss(), testing t_mats = sr.register_stack(gauss(fixed), reference='first', n_frames=1) #remove the x shift from all the matrices - horizontal movement isn't relevant here, #the volume should be acquired quickly enough that this isn't a problem. t_mats[:, 0, -1] = 0 fixed = sr.transform_stack(fixed, tmats=t_mats) #Using previous to see if I could get rid of wigge. Didn't seem to work. #t_mats = sr.register_stack(gauss(fixed), reference='previous') #t_mats[:,1,-1] = 0 #fixed = sr.transform_stack(fixed, tmats=t_mats) #save the register fixed volume in the parent directory for reference save_name = save_pth / f'reg_{file.name}' #io.imsave(arr=img_as_uint(fixed), fname=str(save_name)) io.imsave(arr=img_as_float32(fixed), fname=str(save_name)) #get fixed out of memory - may not be worth the time? print(f'Intravolume registration complete. File saved at {save_name}') #end_time = time.time() #print(f'{file} was processed in {(end_time - start_time):.2f}s. \ #\n{((end_time - loop_starts)/60):.2f} minutes have elapsed.') #de;ete emumerate #if i==4: #ex('auto break') end_time = time.time() print(f'Run took {(end_time-loop_starts)/60:.2f} minutes')
def align_stack(stack_img, ref_image_void=True, ref_stack=None, transformation=StackReg.TRANSLATION, reference="previous"): """Image registration flow using pystack reg""" # all the options are in one function sr = StackReg(transformation) if ref_image_void: tmats_ = sr.register_stack(stack_img, reference=reference) else: tmats_ = sr.register_stack(ref_stack, reference=reference) out_ref = sr.transform_stack(ref_stack) out_stk = sr.transform_stack(stack_img, tmats=tmats_) return np.float32(out_stk), tmats_
def dewiggle(stk): print('Wiggles') sr = StackReg(StackReg.TRANSLATION) tmat = sr.register_stack(stk, reference='previous') #clear y shifts #tmat[:,1,-1] = 0 shifts = tmat[:,0,-1] frame_ind = np.arange(len(shifts)) #fit a line to the shifts to remove drift coeff = np.polyfit(frame_ind, shifts,3) drift_line = np.poly1d(coeff) wiggles = shifts-drift_line(frame_ind) tmat[:,0,-1] = wiggles wiggleless = sr.transform_stack(stk, tmats=tmat) return wiggleless
def registration(hstack, bfchannel, nbchannels, file, output_dir): print("This is the bfchannel: " + bfchannel) hstackreg = [] sr = StackReg(StackReg.RIGID_BODY) # register each frame to the previous (already registered) one # this is what the original StackReg ImageJ plugin uses tmats = sr.register_stack(hstack[:,bfchannel,:,:], reference='previous') for channel in range(nbchannels): hstackreg[:,channel,:,:] = sr.transform_stack(hstack[:,channel,:,:]) # tmats contains the transformation matrices -> they can be saved # and loaded at another time np.save(os.path.join(output_dir,file,'tmats.npy'), tmats) return hstackreg
def align_stack_iter( stack, ref_stack_void=True, ref_stack=None, transformation=StackReg.TRANSLATION, method=("previous", "first"), max_iter=2, ): if ref_stack_void: ref_stack = stack for i in range(max_iter): sr = StackReg(transformation) for ii in range(len(method)): print(ii, method[ii]) tmats = sr.register_stack(ref_stack, reference=method[ii]) ref_stack = sr.transform_stack(ref_stack) stack = sr.transform_stack(stack, tmats=tmats) return np.float32(stack)
def get_stackreg_shifts(stack): """ Calculate alignment shifts for image stack using PyStackReg. Args ---------- stack : Hyperspy Signal2D Image stack to align. Returns ---------- sr_shifts : NumPy array Calculated alignment shifts. """ sr = StackReg(StackReg.TRANSLATION) sr_shifts = sr.register_stack(stack.data) sr_shifts = np.array( [sr_shifts[i][:-1, 2][::-1] for i in range(0, len(sr_shifts))]) return sr_shifts
def calculate_shifts_stackreg(stack): """ Calculate shifts using PyStackReg. Args ---------- stack : TomoStack object The image series to be aligned Returns ---------- shifts : NumPy array The X- and Y-shifts to be applied to each image """ sr = StackReg(StackReg.TRANSLATION) shifts = sr.register_stack(stack.data, reference='previous') shifts = -np.array([i[0:2, 2] for i in shifts]) return shifts
def process(pth): print(f'\nProcessing {pth}') save_pth = pth / 'vol_reg_stacks' tmat_pth = pth / 'vol_transformation_matrices' try: save_pth.mkdir() tmat_pth.mkdir() except FileExistsError: ex('Save File for reg stacks or tmats already exists. Delete and re-run.') #Intravolume registration of the fixed volume print('Doing intravolume registration.') #load first stack and do a 3d gaussian blur with a sigma=1 #str needed for imread, otherwise only one frame is loaded fixed = io.imread(str(pth/'stack0.tif')) #had gauss(), testing #tell pystack reg that we will use a translational transformation #there shouldn't be intra-volume rotation or shear (there might be for rod blink) sr = StackReg(StackReg.TRANSLATION) #register to the first slice and output the transfomation matrix without transforming t_mats = sr.register_stack(gauss(fixed), reference='first', n_frames=1) #remove the x shift from all the matrices - horizontal movement isn't relevant here, #the volume should be acquired quickly enough that this isn't a problem. t_mats[:,0,-1] = 0 fixed = sr.transform_stack(fixed, tmats=t_mats) #save the register fixed volume in the parent directory for reference save_name = pth.parent / 'fixed.tif' #io.imsave(arr=img_as_uint(fixed), fname=str(save_name)) io.imsave(arr=fixed.astype('float32'), fname=str(save_name)) #get fixed out of memory - may not be worth the time? del fixed print(f'Intravolume registration complete. File saved at {save_name}') #Volume registration #switch to tmat folder because i dont know how to set the output folder to save #the transformation mats. elastix.Execute() automatically saves #TransformParameters.0.txt in the current directory os.chdir(tmat_pth) #reload fixed image with sitk so it is in the right format fixed = sitk.ReadImage(str(save_name)) #set up for multivolume registration parameterMap = sitk.GetDefaultParameterMap('affine') elastixImageFilter = sitk.ElastixImageFilter() elastixImageFilter.SetFixedImage(fixed) elastixImageFilter.SetParameterMap(parameterMap) #test 11-8-2019 parameterMap['Image Sampler'] = ['Full'] #parameterMap['Metric'] = ['AdvancedMeanSquares'] parameterMap['Optimiser'] = ['FullSearch'] #iterate through the files in the stacks folder files = sorted(list(pth.glob('*.tif')), key=sort_key) loop_starts = time.time() for i,file in enumerate(files): #i=0 #use first stack #register to previous stack if i > 1: fixed = sitk.ReadImage(str(save_name)) elastixImageFilter.SetFixedImage(fixed) start_time = time.time() print(f'Processing: {file}') #load the volume #Do affine registration so that volume can shear to do the intravolume registration #this code is equivalent to the lines below, but allows the export of the #transformation matrices #moving = sitk.ReadImage(file) #reg_volume = sitk.Elastix(fixed, moving, "affine") elastixImageFilter.SetMovingImage(sitk.ReadImage(str(file))) elastixImageFilter.Execute() reg_volume = elastixImageFilter.GetResultImage() #can get the transform parameters, but have no idea how to save them #maybe just through normal python file manipulation? #transformParameterMap = elastixImageFilter.GetTransformParameterMap() #save volume save_name = save_pth / f'reg_{file.name}' sitk.WriteImage(reg_volume, str(save_name)) #transformation was saved on execute, now rename. #tmat_name = tmat_pth / f'tmat_{file.name}' os.rename('TransformParameters.0.txt', f'tmat_{file.stem}.txt') end_time = time.time() print(f'{file} was processed in {(end_time - start_time):.2f}s. \ \n{((end_time - loop_starts)/60):.2f} minutes have elapsed.')
def fix(stk,divisor=1): sr = StackReg(StackReg.TRANSLATION) #Load Stack #Step 1 - Remove Wiggles print('Wiggles') tmat = sr.register_stack(stk, reference='previous') #clear y shifts #tmat[:,1,-1] = 0 shifts = tmat[:,0,-1] frame_ind = np.arange(len(shifts)) #fit a line to the shifts to remove drift coeff = np.polyfit(frame_ind, shifts,3) drift_line = np.poly1d(coeff) wiggles = shifts-drift_line(frame_ind) tmat[:,0,-1] = wiggles #Step 1 - fix curvature along y - NOT GOOD IF BREATHING ARTIFACTS PRESENT print('Curvature Y') #polyfit is too smooth if there are breathing artifacts present - only affect y curvature #temp = sr.register_stack(stk[::divisor,:,::divisor], reference='first', n_frames=1, moving_average=5) #coeffy = np.polyfit(frame_ind[::divisor], temp[:,1,-1],3) #y_line = np.poly1d(coeffy) #tmat[:,1,-1] = y_line(frame_ind) #now just register all frames - bumps should be muted somewhat by using the moving average #can gaussian filter if too bumpy temp = sr.register_stack(stk, reference='first', n_frames=1, moving_average=5) tmat[:,1,-1] = temp[:,1,-1] #use the combined matrix to fix the x-wiggles and the z-y curvature print('Transform') yless_wiggleless = sr.transform_stack(stk, tmats=tmat) #Step 2 - fix curvature along x print('Curvature X') temp_rot = np.rot90(yless_wiggleless, k=-1, axes=(0,2)) temp_stk = np.empty((temp_rot.shape)) #temp_stk[:256]=temp_rot[256:] #temp_stk[256:]=temp_rot[:256] half = int(temp_stk.shape[0]/2) temp_stk[:half]=temp_rot[half:] temp_stk[half:]=temp_rot[:half] #ind = int(256/divisor) #normally 256 is halfway thru 512 ind = int(half/divisor) temp = sr.register_stack(temp_stk[::divisor,:,::divisor], reference='first', n_frames=1, moving_average=5) final_mat = np.empty((temp.shape)) final_mat[:ind] = temp[ind:] final_mat[ind:] = temp[:ind] final_mat[:,0,-1] = 0 coeffx = np.polyfit(frame_ind[::divisor], final_mat[:,1,-1],3) x_line = np.poly1d(coeffx) final_mat_whole = np.zeros((frame_ind.shape[0], 3, 3)) final_mat_whole[:,0,0], final_mat_whole[:,1,1], final_mat_whole[:,2,2] = 1,1,1 final_mat_whole[:,1,-1] = x_line(frame_ind) #finally fix the x-z curvature print('Transform X') fixed = sr.transform_stack(temp_rot, tmats=final_mat_whole) final = np.rot90(fixed, k=1, axes=(0,2)) return final
blrft = np.fft.fftshift(np.fft.fft2(imgs[0])) / np.fft.fftshift( np.fft.fft2(dblimg)) blr = np.fft.ifft2(np.fft.ifftshift(np.abs(blrft))) blr = np.fft.fftshift(np.abs(blr)) r = (imgs[0].shape[0] - 1) // 2 c = (imgs[0].shape[1] - 1) // 2 blur = blr[r - kern // 2:r + kern // 2 + 1, c - kern // 2:c + kern // 2 + 1] blur /= blur.sum() blur = gaussian_filter((kern, kern), 1) # blur = np.ones((kern,kern))/kern**2 # print(blur/blur.sum()) io.imshow(np.uint8(blur * 255)) # Image Regiseration using translation estimation and Affine Matrix Calculation sr = StackReg(StackReg.TRANSLATION) affmats = sr.register_stack(imgs, reference='first') #Interpolation of Median average of LR Images as initial--------------------------------------- init = np.median(imgs, axis=0) init = transform.rescale(init, scale, anti_aliasing=False) io.imshow(np.uint8(init)) #Iterative L1-Norm Minimization for optimization of HR image----------------------------------- X = np.copy(init) invblur = np.flip(blur) k = n_img for i in range(n_iter): ML = np.zeros(X.shape) h, w = X.shape for j in range(k): tmpTmat = np.flip(affmats[j]).T