def preprocess(inputfile, outputfile, order=0, df=None): img = nib.load(inputfile) data = img.get_data() affine = img.affine zoom = img.header.get_zooms()[:3] data, affine = reslice(data, affine, zoom, (1., 1., 1.), order) data = np.squeeze(data) data = np.pad(data, [(0, 256 - len_) for len_ in data.shape], "constant") if order == 0: if df is not None: for target, raw in zip(df["preprocessed"], df["raw"]): data[np.where(data == raw)] = target data = np.int32(data) assert data.ndim == 3, data.ndim else: data_sub = data - gaussian_filter(data, sigma=1) img = sitk.GetImageFromArray(np.copy(data_sub)) img = sitk.AdaptiveHistogramEqualization(img) data_clahe = sitk.GetArrayFromImage(img)[:, :, :, None] data = np.concatenate((data_clahe, data[:, :, :, None]), 3) data = (data - np.mean(data, (0, 1, 2))) / np.std(data, (0, 1, 2)) assert data.ndim == 4, data.ndim assert np.allclose(np.mean(data, (0, 1, 2)), 0.), np.mean(data, (0, 1, 2)) assert np.allclose(np.std(data, (0, 1, 2)), 1.), np.std(data, (0, 1, 2)) data = np.float32(data) img = nib.Nifti1Image(data, affine) nib.save(img, outputfile)
def preprocess_img(inputfile, output_preprocessed, zooms=[1, 1, 1]): img = nib.load(inputfile) data = img.get_data() affine = img.affine #The last value of header.get_zooms() is the time between scans in milliseconds; this is the equivalent of voxel size on the time axis. zoom = img.header.get_zooms()[:3] data, affine = reslice(data, affine, zoom, zooms, 1) data = np.squeeze(data) #填充256*256*256的图像,在后部进行填2 data[data < 0] = 0 data = np.pad(data, [(0, 218 - len_) for len_ in data.shape], "constant") data_sub = data - gaussian_filter(data, sigma=1) img = sitk.GetImageFromArray(np.copy(data_sub)) img = sitk.AdaptiveHistogramEqualization(img) data_clahe = sitk.GetArrayFromImage(img)[:, :, :, None] data = np.concatenate((data_clahe, data[:, :, :, None]), 3) data = (data - np.mean(data, (0, 1, 2))) / np.std(data, (0, 1, 2)) assert data.ndim == 4, data.ndim #assert np.allclose(np.mean(data, (0, 1, 2)), 0.), np.mean(data, (0, 1, 2)) #assert np.allclose(np.std(data, (0, 1, 2)), 1.), np.std(data, (0, 1, 2)) data = np.float32(data) img = nib.Nifti1Image(data, affine) nib.save(img, output_preprocessed)
def preprocess_img(inputfile, output_preprocessed, zooms, args): img = nib.load(inputfile) data = img.get_fdata() affine = img.affine zoom = img.header.get_zooms()[:3] data, affine = reslice(data, affine, zoom, zooms, 1) data = np.squeeze(data) data = np.pad(data, [((256 - len_) // 2, (256 - len_) // 2) for len_ in data.shape], "constant") data_sub = data - gaussian_filter(data, sigma=1) img = sitk.GetImageFromArray(np.copy(data_sub)) img = sitk.AdaptiveHistogramEqualization(img) data_clahe = sitk.GetArrayFromImage(img)[:, :, :, None] data = np.concatenate((data_clahe, data[:, :, :, None]), 3) data = (data - np.mean(data, (0, 1, 2))) / np.std(data, (0, 1, 2)) assert data.ndim == 4, data.ndim assert np.allclose(np.mean(data, (0, 1, 2)), 0.), np.mean(data, (0, 1, 2)) assert np.allclose(np.std(data, (0, 1, 2)), 1.), np.std(data, (0, 1, 2)) data = np.float32(data) img = nib.Nifti1Image(data, affine) nib.save( img, os.path.join(args.input_directory, "processed", output_preprocessed))
def preprocess(inputfile, outputfile, order=0, df=None, input_key=None, output_key=None): # import pdb; pdb.set_trace() img = nib.load(inputfile) data = img.get_data() affine = img.affine zoom = img.header.get_zooms()[:3] data, affine = reslice(data, affine, zoom, (1., 1., 1.), order) data = np.squeeze(data) data = np.pad(data, [(0, 256 - len_) for len_ in data.shape], "constant") if order == 0: if df is not None: tmp = np.zeros_like(data) for target, source in zip(df[output_key], df[input_key]): tmp[np.where(data == source)] = target data = tmp data = np.int32(data) assert data.ndim == 3, data.ndim else: data_sub = data - gaussian_filter(data, sigma=1) img = sitk.GetImageFromArray(np.copy(data_sub)) img = sitk.AdaptiveHistogramEqualization(img) data_clahe = sitk.GetArrayFromImage(img)[:, :, :, None] data = np.concatenate((data_clahe, data[:, :, :, None]), 3) data = (data - np.mean(data, (0, 1, 2))) / np.std(data, (0, 1, 2)) assert data.ndim == 4, data.ndim assert np.allclose(np.mean(data, (0, 1, 2)), 0.), np.mean(data, (0, 1, 2)) assert np.allclose(np.std(data, (0, 1, 2)), 1.), np.std(data, (0, 1, 2)) data = np.float32(data) img = nib.Nifti1Image(data, affine) nib.save(img, outputfile) print("{} Done!".format(inputfile))
def histogram_equalization(in_fname, out_fname): perm = (2, 1, 0) data, affine, _ = read_vol(in_fname) data = np.transpose(data, perm) img = sitk.GetImageFromArray(np.copy(data)) img = sitk.AdaptiveHistogramEqualization(img) data_clahe = sitk.GetArrayFromImage(img) data = np.transpose(data_clahe, perm) return write_vol(data, affine, out_fname)
def histogram_equalize(image, radius=(1, 1, 1), alpha=0.6, beta=0.3): if isinstance(image, (np.ndarray)): image = sitk.GetImageFromArray(image) filter = sitk.AdaptiveHistogramEqualizationImageFilter() heq = sitk.AdaptiveHistogramEqualization(image, radius, alpha=alpha, beta=beta) # mean = sitk.Mean(heq,(1,1)) return sitk.GetArrayFromImage(heq)
def GenerateSitkImage(pixel_array, Normalize=True, ktrans_mode=False, verbose=False): pixel_array_ = np.array(pixel_array) Spacing = np.array(pixel_array.attrs.get('Spacing')) Origin = np.array(pixel_array.attrs.get('Origin')) Direction = np.array(pixel_array.attrs.get('Direction')) if ktrans_mode: pixel_array_ = (pixel_array_ - np.mean(pixel_array_)) / np.std(pixel_array_) pixel_array_d = pixel_array_.copy() pixel_array_[pixel_array_d > 3.] = 3. pixel_array_ = np.log2(np.log2(pixel_array_ + 1) + 1) ''' This code fix the slice order of ktrans. MRI usually looks from Upside to downside ''' simg = np.zeros(pixel_array_.shape) counter = 0 for i in range(simg.shape[0] - 1, -1, -1): #print(i) simg[counter] = pixel_array_[i] counter = counter + 1 pixel_array_ = simg if verbose: for i in range(pixel_array_.shape[0]): plt.imshow(pixel_array_[i]) plt.show() img = sitk.GetImageFromArray(pixel_array_.astype(float)) img.SetDirection(Direction) img.SetOrigin(Origin) img.SetSpacing(Spacing) if Normalize: img = sitk.AdaptiveHistogramEqualization(img) rescale = sitk.RescaleIntensityImageFilter() img = rescale.Execute(img) elif ktrans_mode: rescale = sitk.RescaleIntensityImageFilter() img = rescale.Execute(img) return img
def apply_normalize(self, image: ScalarImage) -> None: image_sitk = image.as_sitk() if self.target is None: # if target is not present, perform global histogram equalization image_sitk_arr = sitk.GetArrayFromImage(image_sitk) target_arr = np.linspace( -1.0, 1.0, np.array(image_sitk_arr.shape).prod(), dtype=image_sitk_arr.dtype, ) target_sitk = sitk.GetImageFromArray( target_arr.reshape(image_sitk_arr.shape)) elif os.path.exists(self.target): target_sitk = sitk.ReadImage(self.target, image_sitk.GetPixelID()) if self.target == "adaptive": normalized_img = sitk.AdaptiveHistogramEqualization(image_sitk) else: normalized_img = sitk.HistogramMatching(image_sitk, target_sitk, self.num_hist_level, self.num_match_points) image.from_sitk(normalized_img)
def itkImageEnhancement(path, my_method): # Define function itkImageEnhancement # Call SimpleITK to read the image img = sitk.ReadImage(path) result = [] # img = sitk.HistogramMatching(img1, img2) # 直方图匹配 Histogram Matching # 函数参数不一样,使用*args 出现error 尚未解决 if my_method == 'GSD': # chose the method of enhancement # save the file named result in the same path result = sitk.GrayscaleDilate(img) # Tell the user function worked successfully print('Gray Scale Dilate') elif my_method == 'AHE': result = sitk.AdaptiveHistogramEqualization(img) print('Adaptive Histogram Equalization') elif my_method == 'LS': result = sitk.LaplacianSharpening(img) print('Laplace Sharpening') else: print('Error') # Return an error return result
def main(): t_start_overall = time.time() parser = argparse.ArgumentParser( description= 'Register a brain in the BOSS and upload it back in a new experiment.') parser.add_argument('--collection', help='Name of collection to upload tif stack to', type=str) parser.add_argument('--experiment', help='Name of experiment to upload tif stack to', type=str) parser.add_argument( '--channel', help= 'Name of channel to upload tif stack to. Default is new channel will be created unless otherwise specified. See --new_channel', type=str) parser.add_argument( '--image_orientation', help= 'Orientation of brain image. 3-letter orientation of brain. For example can be PIR: Posterior, Inferior, Right.', type=str) parser.add_argument( '--outdir', help= 'set the directory in which you want to save the intermediates. default is ./{collection}_{experiment}_{channel}_reg', type=str, default=None) parser.add_argument( '--resume', help= 'If steps of the registration completed, pick up from where you left off', action='store_true') parser.add_argument( '--config', help= 'Path to configuration file with Boss API token. Default: ~/.intern/intern.cfg', default=os.path.expanduser('~/.intern/intern.cfg')) args = parser.parse_args() # conversion factor from mm to um mm_to_um = 1000.0 # download image rmt = BossRemote(cfg_file_or_dict=args.config) # resolution level from 0-6 resolution_image = 3 # resolution in microns resolution_atlas = 50 # atlas orientation known orientation_atlas = 'pir' # ensure outdir is default value if None if args.outdir is None: outdir = '{}_{}_{}_reg/'.format(args.collection, args.experiment, args.channel) ndreg.dirMake(outdir) else: outdir = args.outdir # downloading image if not args.resume or not os.path.isfile(outdir + '{}_{}_{}um.img'.format( args.experiment, args.channel, resolution_atlas)): print('downloading experiment: {}, channel: {}...'.format( args.experiment, args.channel)) t1 = time.time() img = ndreg.download_image(rmt, args.collection, args.experiment, args.channel) print("time to download image at res {} um: {} seconds".format( img.GetSpacing()[0] * mm_to_um, time.time() - t1)) # download atlas print('downloading atlas...') t1 = time.time() atlas = ndreg.download_ara(rmt, resolution_atlas, type='average') print("time to download atlas at {} um: {} seconds".format( resolution_atlas, time.time() - t1)) # resample image to match atlas spacing print('downsampling image...') t1 = time.time() # downsample_factor = 3 # img_ds = downsample(img, res=downsample_factor) img = ndreg.imgResample(img, [resolution_atlas / mm_to_um] * 3) print("time to downsample image: {} seconds".format(time.time() - t1)) # save sitk.WriteImage( img, outdir + '{}_{}_{}um.img'.format( args.experiment, args.channel, resolution_atlas)) else: img = ndreg.imgRead(outdir + '{}_{}_{}um.img'.format( args.experiment, args.channel, resolution_atlas)) atlas = ndreg.download_ara(rmt, resolution_atlas, type='average') if not args.resume or not os.path.isfile( outdir + '{}_{}_bias_corrected.img'.format(args.experiment, args.channel)): # do the bias correction print("creating mask and correcting bias field in target...") t1 = time.time() mask_dilation_radius = 10 # voxels mask = sitk.BinaryDilate( preprocessor.create_mask(img, use_triangle=True), mask_dilation_radius) img_bc, bias = preprocessor.correct_bias_field( img, scale=0.25, spline_order=4, mask=mask, num_control_pts=[5, 5, 5], niters=[500, 500, 500, 500]) print("time to bias correct image: {} seconds".format(time.time() - t1)) # save bias corrected image sitk.WriteImage( img_bc, outdir + '{}_{}_bias_corrected.img'.format(args.experiment, args.channel)) else: img_bc = ndreg.imgRead( outdir + '{}_{}_bias_corrected.img'.format(args.experiment, args.channel)) # reorient the image to match atlas print("image size: {}, image orientation: {}".format( img_bc.GetSize(), args.image_orientation)) print("atlas size: {}, atlas orientation: {}".format( atlas.GetSize(), orientation_atlas)) img_bc = ndreg.imgReorient(img_bc, args.image_orientation, orientation_atlas) print("normalizing atlas and target...") t1 = time.time() atlas_n = sitk.Normalize(atlas) img_bc_n = sitk.Normalize(img_bc) print("time taken to normalize atlas and target: {} seconds".format( time.time() - t1)) # affine registration print("performing affine registration...") t1 = time.time() final_transform = registerer.register_affine(atlas_n, img_bc_n, learning_rate=1e-1, grad_tol=4e-6, use_mi=False, iters=50, shrink_factors=[4, 2, 1], sigmas=[0.4, 0.2, 0.1], verbose=False) atlas_affine = registerer.resample(atlas, final_transform, img_bc, default_value=ndreg.imgPercentile( atlas, 0.01)) target_affine = registerer.resample(img_bc, final_transform.GetInverse(), atlas, default_value=ndreg.imgPercentile( img_bc, 0.01)) print("time taken for affine registration: {} seconds".format(time.time() - t1)) # save affine registered image sitk.WriteImage(atlas_affine, outdir + 'atlas_to_{}_affine.img'.format(args.experiment)) sitk.WriteImage(target_affine, outdir + '{}_to_atlas_affine.img'.format(args.experiment)) # whiten the images print("whitening images...") t1 = time.time() atlas_affine_w = sitk.AdaptiveHistogramEqualization(atlas_affine, [10, 10, 10], alpha=0.25, beta=0.25) img_bc_w = sitk.AdaptiveHistogramEqualization(img_bc, [10, 10, 10], alpha=0.25, beta=0.25) print('time to whiten atlas and target: {}'.format(time.time() - t1)) # lddmm code print("beginning LDDMM parameter sweep") t1 = time.time() e = 5e-3 s = 0.1 atlas_lddmm, field, inv_field = registerer.register_lddmm( affine_img=sitk.Normalize(atlas_affine_w), target_img=sitk.Normalize(img_bc_w), alpha_list=[0.05], scale_list=[0.0625, 0.125, 0.25, 0.5, 1.0], epsilon_list=e, sigma=s, min_epsilon_list=e * 1e-6, use_mi=False, iterations=50, verbose=True, out_dir=outdir + 'lddmm') print("time taken for LDDMM: {} seconds".format(time.time() - t1)) end_time = time.time() print( "Overall time taken through all steps: {} seconds ({} minutes)".format( end_time - t_start_overall, (end_time - t_start_overall) / 60.0))
def register_brain(atlas, img, spacing=None, outdir=None): """Register 3D mouse brain to the Allen Reference atlas using affine and deformable registration. Parameters: ---------- atlas : {SimpleITK.SimpleITK.Image} Allen reference atlas or other atlas to register data to. img : {SimpleITK.SimpleITK.Image} Input observed 3D mouse brain volume outdir : {str}, optional Path to output directory to store intermediates. (the default is None, which will store all outputs in './') Returns ------- SimpleITK.SimpleITK.Image The atlas deformed to fit the input image. """ if spacing is None: spacing = atlas.GetSpacing() if outdir is None: outdir = './' whitening_radius = [ int(i) for i in np.array([0.5, 0.5, 0.5]) / np.array(atlas.GetSpacing()) ] # mm # resample both images to `spacing` atlas_ds = preprocessor.imgResample(atlas, spacing) img_ds = preprocessor.imgResample(img, spacing) final_transform = register_affine(sitk.Normalize(atlas_ds), sitk.Normalize(img_ds), learning_rate=1e-1, grad_tol=4e-6, iters=50, shrink_factors=[4, 2, 1], sigmas=[0.4, 0.2, 0.1], verbose=False) # save the affine transformation to outdir # make the dir if it doesn't exist util.dir_make(outdir) sitk.WriteTransform(final_transform, outdir + 'atlas_to_observed_affine.txt') atlas_affine = resample(atlas_ds, final_transform, img_ds, default_value=util.img_percentile(atlas, 0.01)) # whiten both images only before lddmm atlas_affine_w = sitk.AdaptiveHistogramEqualization(atlas_affine, whitening_radius, alpha=0.25, beta=0.25) img_w = sitk.AdaptiveHistogramEqualization(img_ds, whitening_radius, alpha=0.25, beta=0.25) # then run lddmm e = 5e-3 s = 0.1 atlas_lddmm, field, inv_field = register_lddmm( sitk.Normalize(atlas_affine_w), sitk.Normalize(img_w), alpha_list=[0.05], scale_list=[0.0625, 0.125, 0.25, 0.5, 1.0], epsilon_list=e, sigma=s, min_epsilon_list=e * 1e-6, use_mi=False, iterations=50, verbose=True, out_dir=outdir + 'lddmm') field_up = preprocessor.imgResample(field, atlas.GetSpacing()) atlas_affine_up = imgApplyAffine(atlas, final_transform) atlas_lddmm_up = imgApplyField(atlas_affine_up, field_up) return atlas_lddmm_up
def whiten(image, radius=[10, 10, 10], alpha=0.3, beta=0.3): return sitk.AdaptiveHistogramEqualization(image, radius, alpha, beta)