def extract_tif_from_hdf(input_path, output_path, key_path, index=(0, -1, 1), axis=0, crop=(0, 0, 0, 0), prefix="img"): """ Extract tif images from a hdf/nxs file. Parameters ---------- input_path : str Path to the hdf/nxs file. output_path : str Output folder. key_path : str Key path to the dataset in the hdf/nxs file. index : tuple of int or int. Indices of extracted images. A tuple corresponds to (start,stop,step). axis : int Axis which the images are extracted. crop : tuple of int, optional Crop the images from the edges, i.e. crop = (crop_top, crop_bottom, crop_left, crop_right). prefix : str, optional Prefix of names of tif files. Returns ------- str Folder path to the tif files. """ data = losa.load_hdf(input_path, key_path) (depth, height, width) = data.shape if isinstance(index, tuple): start, stop, step = index else: start, stop, step = index, index + 1, 1 cr_top, cr_bottom, cr_left, cr_right = crop if axis == 1: if (stop == -1) or (stop > height): stop = height for i in range(start, stop, step): mat = data[cr_top:depth - cr_bottom, i, cr_left:width - cr_right] out_name = "0000" + str(i) losa.save_image( output_path + "/" + prefix + "_" + out_name[-5:] + ".tif", mat) elif axis == 2: if (stop == -1) or (stop > width): stop = width for i in range(start, stop, step): mat = data[cr_top:depth - cr_bottom, cr_left:height - cr_right, i] out_name = "0000" + str(i) losa.save_image( output_path + "/" + prefix + "_" + out_name[-5:] + ".tif", mat) else: if (stop == -1) or (stop > depth): stop = depth for i in range(start, stop, step): mat = data[i, cr_top:height - cr_bottom, cr_left:width - cr_right] out_name = "0000" + str(i) losa.save_image( output_path + "/" + prefix + "_" + out_name[-5:] + ".tif", mat) return output_path
for j in range(num_scan_col): grid_idx = j + row_idx * num_scan_col image_pro = corr.flat_field_correction( data_objects[grid_idx][pro_idx, top:bot, left:right], flat_field[top:bot, left:right], dark_field[top:bot, left:right], ratio=1.0, use_dark=False) image_pro = remo.remove_blob(image_pro, blob_mask) proj_list[grid_idx] = image_pro out1 = "0000" + str(j) out2 = "0000" + str(row_idx) out3 = "0000" + str(pro_idx) name = "row_" + out2[-4:] + "_col_" + out1[-4:] + "_pro_" + out3[ -4:] + ".tif" losa.save_image(output_base1 + "/" + name, image_pro) t_stop = timeit.default_timer() print(" Done row: {0}. Time :{1}".format(row_idx, t_stop - t_start)) print("|-> Find overlap-area and overlap-side between projection-images") # Calculate overlaps between grid-rows ver_overlap_mat = np.zeros((num_scan_row - 1, num_scan_col, 2), dtype=np.int16) col_use = num_scan_col // 2 # Use grid-columns having the sample in their FOV for i in range(num_scan_row - 1): grid_idx = col_use + i * num_scan_col grid_idx1 = col_use + (i + 1) * num_scan_col overlap_area, overlap_side, _ = calc.find_overlap( np.transpose(proj_list[grid_idx]), np.transpose(proj_list[grid_idx1]), overlap_window, norm=True, use_overlap=True)
size=3, gpu=True, block=(16, 16), ncore=None, norm=False, norm_global=True, chunk_size=chunk_size, surf_method="SCS", correct_negative=True, return_shift=True) t1 = timeit.default_timer() print("Time cost for retrieve phase image: {}".format(t1 - t0)) t0 = timeit.default_timer() f_alias2 = ps.get_transmission_dark_field_signal # For convenient use trans, dark = f_alias2(speckle_stack, sample_stack, x_shifts, y_shifts, 7, ncore=None) t1 = timeit.default_timer() print("Time cost for getting transmission + dark-signal: {}".format(t1 - t0)) losa.save_image(output_base + "/x_shifts.tif", x_shifts) losa.save_image(output_base + "/y_shifts.tif", y_shifts) losa.save_image(output_base + "/phase.tif", phase) losa.save_image(output_base + "/trans.tif", trans) losa.save_image(output_base + "/dark.tif", -np.log(dark)) print("Al done !!!")
(center0, overlap, side, _) = calc.find_center_360(sino_360, 100) print( "Center-of-rotation: {0}. Side: {1} (0->'left', 1->'right'). Overlap: {2}". format(center0, side, overlap)) t1 = timeit.default_timer() print("Time cost {}".format(t1 - t0)) # Remove artifacts. They also can be passed to flat_field_correction method above as parameters. # Remove zingers sino_360 = remo.remove_zinger(sino_360, 0.08) # Remove ring artifacts sino_360 = remo.remove_all_stripe(sino_360, 3, 51, 17) # 1st way: Convert the 360-degree sinogram to the 180-degree sinogram. sino_180, center1 = conv.convert_sinogram_360_to_180(sino_360, center0) losa.save_image(output_base + "/reconstruction/sino_180.tif", sino_180) ## Denoising sino_180 = filt.fresnel_filter(sino_180, 250, 1, apply_log=True) # Perform reconstruction img_rec = reco.dfi_reconstruction(sino_180, center1, apply_log=True) ## Using fbp with GPU for faster reconstruction # img_rec = reco.fbp_reconstruction(sino_180, center1, apply_log=True, gpu=True) losa.save_image(output_base + "/reconstruction/recon_image_1.tif", img_rec) # 2nd way: Extending the 360-degree sinogram (by weighting and padding). (sino_ext, center2) = conv.extend_sinogram(sino_360, center0) losa.save_image(output_base + "/reconstruction/sino_360_extened.tif", sino_ext) # Denoising sino_ext = filt.fresnel_filter(sino_ext, 250, 1, apply_log=False) # Perform reconstruction # img_rec = reco.dfi_reconstruction(sino_ext, center2, angles=angles*np.pi/180.0,apply_log=False)
for i, key in enumerate(list_key): # There're datasets with keys containing "data", we only choose a 3D array. if len(list_shape[i])==3: data_key = key break image_key = losa.find_hdf_key(file_path, "image_key")[0][0] # Results are: # data_key = "/entry1/flyScanDetector/data" # image_key = "/entry1/flyScanDetector/image_key" # Load flat-field images, average them, and save the result as a tif image. print("3 -> Load flat-field images, average them, and save the result: ") data = losa.load_hdf(file_path, data_key) # This is an object. No data are loaded to the memory yet. ikey = np.asarray(losa.load_hdf(file_path, image_key)) flat_field = np.mean(np.asarray(data[np.squeeze(np.where(ikey==1.0)), :,:]), axis=0) losa.save_image(output_base + "/flat/flat_field.tif", flat_field) # Load few projection images and save them as tifs. print("4 -> Load projection images in a step of 250 and save to tiff: ") proj_idx = np.squeeze(np.where(ikey == 0)) for i in range(0, len(proj_idx), 250): mat = data[proj_idx[i], :, :] name = "0000" + str(proj_idx[i]) losa.save_image(output_base + "/projection/img_" + name[-5:] + ".tif", mat) print("5 -> Same as 2 but using a built-in function: ") # The above example can be done using the "converter" module as follows: conv.extract_tif_from_hdf(file_path, output_base + "/projection2/", key_path=data_key, index=(proj_idx[0],proj_idx[-1],250), axis=0) # We also can convert a folder of tif images to a hdf file.
# Generate a sinogram with flat-field correction and blob removal. # Angles corresponding to this sinogram also is generated. index = max_index // 2 print("2 -> Generate a circular sinogram from the helical data") (sino_360, angle_sino) = conv.generate_sinogram_helical_scan(index, proj_data, num_proj, pixel_size, y_start, y_stop, pitch, scan_type=scan_type, angles=angles, flat=flat_field, dark=dark_field, mask=blob_mask, crop=(10,0,0,0)) print("3 -> Find the center of rotation, overlap-side, and overlap area between two halves of a 360-degree sinogram") (center0, overlap, side,_) = calc.find_center_360(sino_360, 100) print("Center-of-rotation: {0}. Side: {1} (0->'left', 1->'right'). Overlap: {2}".format(center0, side, overlap)) # Convert the 360-degree sinogram to the 180-degree sinogram. sino_180, center1 = conv.convert_sinogram_360_to_180(sino_360, center0) # Remove partial ring artifacts sino_180 = remo.remove_stripe_based_sorting(sino_180, 15) # Remove zingers sino_180 = remo.remove_zinger(sino_180, 0.08) # Denoising sino_180 = filt.fresnel_filter(sino_180, 250, 1) # Perform recosntruction img_rec = reco.dfi_reconstruction(sino_180, center1, apply_log=True) ## Use gpu for fast reconstruction # img_rec = reco.fbp_reconstruction(sino_180, center1, apply_log=True, gpu=True) losa.save_image(output_base + "/reconstruction/sino_360.tif", sino_360) losa.save_image(output_base + "/reconstruction/sino_180.tif", sino_180) losa.save_image(output_base + "/reconstruction/recon_image.tif", img_rec) print("!!! Done !!!")
def test_save_image(self): file_path = "data/img.tif" losa.save_image(file_path, np.random.rand(64, 64)) self.assertTrue(os.path.isfile(file_path))
def rescale_dataset(input_, output, nbit=16, minmax=None, skip=None, key_path=None): """ Rescale a dataset to 8-bit or 16-bit data-type. The dataset can be a folder of tif files, a hdf file, or a 3D array. Parameters ---------- input_ : str, array_like It can be a folder path to tif files, a hdf file, or 3D array. output : str, None It can be a folder path, a hdf file path, or None (memory consuming). nbit : {8,16} Rescaled data-type: 8-bit or 16-bit. minmax : tuple of float, or None Minimum and maximum values used for rescaling. They are calculated if None is given. skip : int or None Skipping step of reading input used for getting statistical information. key_path : str, optional Key path to the dataset if the input is the hdf file. Returns ------- array_like or None If output is None, returning an 3D array. """ if output is not None: file_base, file_ext = os.path.splitext(output) if file_ext != "": file_base = os.path.dirname(output) if os.path.exists(file_base): raise ValueError("Folder exists!!! Please choose another path!!!") if isinstance(input_, str) and (os.path.splitext(input_)[-1] == ""): list_file = losa.find_file(input_ + "/*.tif*") depth = len(list_file) if depth == 0: raise ValueError("No tif files in the folder: {}".format(input_)) if minmax is None: if skip is None: skip = int(np.ceil(0.15 * depth)) (gmin, gmax) = get_statical_information_dataset(input_, skip=skip)[0:2] else: (gmin, gmax) = minmax if output is not None: file_base, file_ext = os.path.splitext(output) if file_ext != "": if not (file_ext == '.hdf' or file_ext == '.h5' or file_ext == ".nxs"): raise ValueError("File extension must be hdf, h5, or nxs") output = file_base + file_ext (height, width) = np.shape(losa.load_image(list_file[0])) if nbit == 8: data_type = "uint8" else: data_type = "uint16" data_out = losa.open_hdf_stream(output, (depth, height, width), key_path="rescale/data", data_type=data_type, overwrite=False) data_res = [] for i in range(0, depth): mat = rescale(losa.load_image(list_file[i]), nbit=nbit, minmax=(gmin, gmax)) if output is None: data_res.append(mat) else: file_base, file_ext = os.path.splitext(output) if file_ext == "": out_name = "0000" + str(i) losa.save_image(output + "/img_" + out_name[-5:] + ".tif", mat) else: data_out[i] = mat else: if isinstance(input_, str): file_ext = os.path.splitext(input_)[-1] if not (file_ext == '.hdf' or file_ext == '.h5' or file_ext == ".nxs"): raise ValueError( "Can't open this type of file format {}".format(file_ext)) if key_path is None: raise ValueError( "Please provide the key path to the dataset!!!") input_ = losa.load_hdf(input_, key_path) (depth, height, width) = input_.shape if minmax is None: if skip is None: skip = int(np.ceil(0.15 * depth)) (gmin, gmax) = get_statical_information_dataset(input_, skip=skip, key_path=key_path)[0:2] else: (gmin, gmax) = minmax data_res = [] if output is not None: file_base, file_ext = os.path.splitext(output) if file_ext != "": if not (file_ext == '.hdf' or file_ext == '.h5' or file_ext == ".nxs"): raise ValueError("File extension must be hdf, h5, or nxs") output = file_base + file_ext if nbit == 8: data_type = "uint8" else: data_type = "uint16" data_out = losa.open_hdf_stream(output, (depth, height, width), key_path="rescale/data", data_type=data_type, overwrite=False) for i in range(0, depth): mat = rescale(input_[i], nbit=nbit, minmax=(gmin, gmax)) if output is None: data_res.append(mat) else: file_base, file_ext = os.path.splitext(output) if file_ext != "": data_out[i] = mat else: out_name = "0000" + str(i) losa.save_image(output + "/img_" + out_name[-5:] + ".tif", mat) if output is None: return np.asarray(data_res)
slice_index = 500 # Options to remove artfacts opt1 = {"method": "remove_zinger", "para1": 0.08, "para2": 1} opt2 = {"method": "remove_all_stripe", "para1": 3.0, "para2": 51, "para3": 17} list_sino = [] for i in range(num_scan_col): sinogram = corr.flat_field_correction( data_objects[i + row_idx * num_scan_col][:, slice_index, :], flat_field[slice_index], dark_field[slice_index], option1=opt1, option2=opt2) name = "0" + str(i) losa.save_image( output_base + "/reconstruction/sino_360_part_" + name[-2:] + ".tif", sinogram) # Check if there's a part of sample in the sinogram. # check = util.detect_sample(sinogram) # if check: # list_sino.append(sinogram) list_sino.append(sinogram) # Calculate the overlap-sides and overlap-areas between sinograms. print( "2 -> Determine the overlap-side and overlap-area between sinograms and stitch them" ) list_overlap = calc.find_overlap_multiple(list_sino, overlap_window) print(" Results {}".format(list_overlap)) sino_360 = conv.stitch_image_multiple(list_sino, list_overlap, norm=True,
# acquired from a well-aligned tomography system. tilted = -5.0 # Degree # Generate a tilted sinogram and apply the flat-field correction. index = height // 2 # Index of a sinogram. # As there're dark-field images and flat-field images in the raw data, we use # opt=(proj_idx[0], proj_idx[-1], 1) to apply correction only to # projection images sino_tilted = corr.generate_tilted_sinogram(data, index, tilted, opt=(proj_idx[0], proj_idx[-1], 1)) flat_line = corr.generate_tilted_profile_line(flat_field, index, tilted) dark_line = corr.generate_tilted_profile_line(dark_field, index, tilted) sinogram = corr.flat_field_correction(sino_tilted, flat_line, dark_line) losa.save_image(output_base + "/sinogram1/sinogram_mid_tilted.tif", sinogram) # Generate a chunk of tilted sinograms and apply the flat-field correction. start_sino = index stop_sino = start_sino + 20 sinos_tilted = corr.generate_tilted_sinogram_chunk(data, start_sino, stop_sino, tilted, opt=(proj_idx[0], proj_idx[-1], 1)) flat_lines = corr.generate_tilted_profile_chunk(flat_field, start_sino, stop_sino, tilted) dark_lines = corr.generate_tilted_profile_chunk(dark_field, start_sino, stop_sino, tilted) sino_chunk = corr.flat_field_correction(sinos_tilted, flat_lines, dark_lines)
def test_get_image_stack(self): num_stack = 3 for i in range(num_stack): file_path = "data/img_stk_" + str(i) + ".hdf" ifile = h5py.File(file_path, "w") data = np.ones((3, 64, 64)) ifile.create_dataset("entry/data", data=np.float32(data)) ifile.close() list_path = losa.find_file("data/img_stk*") f_alias = losa.get_image_stack img_stack = f_alias(0, list_path, data_key="entry/data", average=False, crop=(0, 0, 0, 0), flat_field=None, dark_field=None, num_use=None, fix_zero_div=False) check1 = True if (img_stack.shape[0] == num_stack) \ and (np.mean(img_stack) == 1.0) else False img_stack = f_alias(4, list_path, data_key="entry/data", average=True, crop=(0, 0, 0, 0), flat_field=None, dark_field=None, num_use=None, fix_zero_div=False) check2 = True if (img_stack.shape[0] == num_stack) \ and (np.mean(img_stack) == 1.0) else False num_img = 4 for i in range(num_stack): folder_path = "data/img_stk_tif_" + str(i) + "/" for j in range(num_img): file_path = folder_path + "/img_" + str(j) + ".tif" losa.save_image(file_path, np.ones((64, 64))) list_path = losa.find_file("data/img_stk_tif*") img_stack = f_alias(0, list_path, data_key=None, average=False, crop=(0, 0, 0, 0), flat_field=None, dark_field=None, num_use=None, fix_zero_div=False) check3 = True if (img_stack.shape[0] == num_stack) \ and (np.mean(img_stack) == 1.0) else False img_stack = f_alias(4, list_path, data_key=None, average=True, crop=(0, 0, 0, 0), flat_field=None, dark_field=None, num_use=None, fix_zero_div=False) check4 = True if (img_stack.shape[0] == num_stack) \ and (np.mean(img_stack) == 1.0) else False img_stack = f_alias(None, list_path[0], data_key=None, average=False, crop=(0, 0, 0, 0), flat_field=None, dark_field=None, num_use=None, fix_zero_div=False) check5 = True if (img_stack.shape[0] == num_img) \ and (np.mean(img_stack) == 1.0) else False self.assertTrue(check1 and check2 and check3 and check4 and check5)
start_sino = i * slice_chunk + offset stop_sino = start_sino + slice_chunk sinograms = corr.flat_field_correction(data[proj_idx[0]:proj_idx[-1], start_sino:stop_sino, :], flat_field[start_sino:stop_sino, :], dark_field[start_sino:stop_sino, :], option1=opt1, option2=opt2, option3=opt3) # Reconstruct a chunk of slices in parallel if using CPU-based method. recon_img = util.apply_method_to_multiple_sinograms( sinograms, "dfi_reconstruction", [center]) # Save the results to tif images for j in range(start_sino, stop_sino): name = "0000" + str(j) losa.save_image(output_base + "/rec_" + name[-5:] + ".tif", recon_img[:, j - start_sino, :]) # # Reconstruct the slices using a GPU-based method # for j in range(start_sino, stop_sino): # recon_img = reco.fbp_reconstruction(sinograms[:, j - start_sino, :], # center, angles=thetas) # name = "0000" + str(j) # losa.save_image(output_base + "/rec_" + name[-5:] + ".tif", recon_img) t_stop = timeit.default_timer() print("Done slice: {0} - {1} . Time {2}".format(start_sino, stop_sino, t_stop - time_start)) if num_rest != 0: for i in range(num_rest): start_sino = num_iter * slice_chunk + offset stop_sino = start_sino + num_rest
f_alias3 = ps.get_transmission_dark_field_signal t0 = timeit.default_timer() for i in range(num_proj): ref_stack, sam_stack = f_alias1(i, list_file, data_key=data_key, image_key=image_key, crop=crop, flat_field=None, dark_field=None, num_use=num_use, fix_zero_div=True) x_shifts, y_shifts, phase = f_alias2(ref_stack, sam_stack, dim=dim, win_size=win_size, margin=margin, method="diff", size=3, gpu=gpu, block=(16, 16), ncore=None, norm=True, norm_global=True, chunk_size=chunk_size, surf_method="SCS", return_shift=True) phase_hdf[i] = phase name = ("0000" + str(i))[-5:] losa.save_image(output_base + "/phase/img_" + name + ".tif", phase) if get_trans_dark_signal: trans, dark = f_alias3(ref_stack, sam_stack, x_shifts, y_shifts, win_size, ncore=None) trans_hdf[i] = trans dark_hdf[i] = dark losa.save_image(output_base + "/transmission/img_" + name + ".tif", trans) losa.save_image(output_base + "/dark/img_" + name + ".tif", dark) t1 = timeit.default_timer() print("Done projection {0}. Time cost: {1} ".format(i, t1 - t0)) t1 = timeit.default_timer() print("\n********************************") print("All done!!!!!!!!! Total time: {}".format(t1 - t0)) print("********************************")
# compared to the projection of the first dataset. # The ROI is pretty large (851 x 851) to detect global shifts. In such case # if using GPU the overhead for getting data from global memory can be high # list_ij2 = [height1//2, width1//2-250] # sam_shifts = f_alias3(ref_stack, sam_stack, sr_shifts, 851, 20, gpu=False, # list_ij=list_ij2) # print("Sample shifts: ") # print(sam_shifts) # Align image stacks (ref_stack_cr, sam_stack_cr) = f_alias4(ref_stack, sam_stack, sr_shifts, sam_shifts) # Check results to make sure for i in range(num_use): name = ("0000" + str(i))[-5:] losa.save_image(output_base + "/aligned/ref/img_" + name + ".tif", ref_stack_cr[i]) losa.save_image(output_base + "/aligned/sam/img_" + name + ".tif", sam_stack_cr[i]) # Taking into account the extra edge for image alignment. extra_edge = int(np.max(np.abs(np.asarray(sr_shifts)))) + int( np.max(np.abs(np.asarray(sam_shifts)))) # Define the ROI area to retrieve phase around the given slice (row) index crop_top1 = slice_idx - 2 * (margin + extra_edge) crop_bot1 = height - (slice_idx + 2 * (margin + extra_edge)) crop_left1 = 0 crop_right1 = 0 crop1 = (crop_top1, crop_bot1, crop_left1, crop_right1) t0 = timeit.default_timer()
sino_phase = phase_hdf[:, i, :] if fluct_correct: sino_phase = filt.double_wedge_filter(sino_phase, center) sino_trans = trans_hdf[:, i, :] sino_dark = dark_hdf[:, i, :] if artifact_rem: sino_phase = rem.remove_all_stripe(sino_phase, 2.0, 51, 17) sino_trans = rem.remove_all_stripe(sino_trans, 2.0, 51, 17) sino_dark = rem.remove_all_stripe(sino_dark, 2.0, 51, 17) # Change to CPU methods (DFI or gridrec) if GPU not available rec_phase = reco.fbp_reconstruction(sino_phase, center, apply_log=False, filter_name="hann") rec_trans = reco.fbp_reconstruction(sino_trans, center, apply_log=True, filter_name="hann") rec_dark = reco.fbp_reconstruction(sino_dark, center, apply_log=True, filter_name="hann") losa.save_image(output_base + "/phase/rec_" + name + ".tif", rec_phase) losa.save_image(output_base + "/transmission/rec_" + name + ".tif", rec_trans) losa.save_image(output_base + "/dark_signal/rec_" + name + ".tif", rec_dark) print("Done slice: {}".format(i)) t1 = timeit.default_timer() print("All done !!!. Time cost {}".format(t1 - t0))
import numpy as np import algotom.io.loadersaver as losa import algotom.util.simulation as sim import algotom.prep.calculation as calc import algotom.prep.removal as rem import algotom.prep.filtering as filt import algotom.rec.reconstruction as reco # Where to save the outputs output_base = "E:/tmp/output/" size = 1024 # Generate a built-in phantom phantom = sim.make_face_phantom(size) losa.save_image(output_base + "/face_phantom.tif", phantom) angles = np.linspace(0.0, 180.0, size) * np.pi / 180.0 # Generate sinogram sinogram = sim.make_sinogram(phantom, angles) losa.save_image(output_base + "/sinogram.tif", sinogram) # Find center of rotation center = calc.find_center_vo(sinogram) # Reconstruct using the DFI method rec_image = reco.dfi_reconstruction(sinogram, center, apply_log=False) losa.save_image(output_base + "/recon_dfi.tif", rec_image) # Reconstruct using the FBP (GPU) method rec_image = reco.fbp_reconstruction(sinogram, center, apply_log=False) losa.save_image(output_base + "/recon_fbp.tif", rec_image) # Convert to X-ray image
def downsample_dataset(input_, output, cell_size, method="mean", key_path=None): """ Downsample a dataset. This can be a folder of tif files, a hdf file, or a 3D array. Parameters ---------- input_ : str, array_like It can be a folder path to tif files, a hdf file, or 3D array. output : str, None It can be a folder path, a hdf file path, or None (memory consuming). cell_size : int or tuple of int Window size along axes used for grouping pixels. method : {"mean", "median", "max", "min"} Downsampling method. key_path : str, optional Key path to the dataset if the input is the hdf file. Returns ------- array_like or None If output is None, returning an 3D array. """ if output is not None: file_base, file_ext = os.path.splitext(output) if file_ext != "": file_base = os.path.dirname(output) if os.path.exists(file_base): raise ValueError("Folder exists!!! Please choose another path!!!") if method == "median": dsp_method = np.median elif method == "max": dsp_method = np.max elif method == "min": dsp_method = np.amin else: dsp_method = np.mean if isinstance(cell_size, int): cell_size = (cell_size, cell_size, cell_size) if isinstance(input_, str) and (os.path.splitext(input_)[-1] == ""): list_file = losa.find_file(input_ + "/*.tif*") depth = len(list_file) if depth == 0: raise ValueError("No tif files in the folder: {}".format(input_)) (height, width) = np.shape(losa.load_image(list_file[0])) depth_dsp = depth // cell_size[0] height_dsp = height // cell_size[1] width_dsp = width // cell_size[2] num = 0 if (depth_dsp != 0) and (height_dsp != 0) and (width_dsp != 0): if output is not None: file_base, file_ext = os.path.splitext(output) if file_ext != "": if not (file_ext == '.hdf' or file_ext == '.h5' or file_ext == ".nxs"): raise ValueError( "File extension must be hdf, h5, or nxs") output = file_base + file_ext data_out = losa.open_hdf_stream( output, (depth_dsp, height_dsp, width_dsp), key_path="downsample/data", overwrite=False) data_dsp = [] for i in range(0, depth, cell_size[0]): if (i + cell_size[0]) > depth: break else: mat = [] for j in range(i, i + cell_size[0]): mat.append(losa.load_image(list_file[j])) mat = np.asarray(mat) mat = mat[:, :height_dsp * cell_size[1], :width_dsp * cell_size[2]] mat = mat.reshape(1, cell_size[0], height_dsp, cell_size[1], width_dsp, cell_size[2]) mat_dsp = dsp_method(dsp_method(dsp_method(mat, axis=-1), axis=1), axis=2) if output is None: data_dsp.append(mat_dsp[0]) else: if file_ext == "": out_name = "0000" + str(num) losa.save_image( output + "/img_" + out_name[-5:] + ".tif", mat_dsp[0]) else: data_out[num] = mat_dsp[0] num += 1 else: raise ValueError("Incorrect cell size {}".format(cell_size)) else: if isinstance(input_, str): file_ext = os.path.splitext(input_)[-1] if not (file_ext == '.hdf' or file_ext == '.h5' or file_ext == ".nxs"): raise ValueError( "Can't open this type of file format {}".format(file_ext)) if key_path is None: raise ValueError( "Please provide the key path to the dataset!!!") input_ = losa.load_hdf(input_, key_path) (depth, height, width) = input_.shape depth_dsp = depth // cell_size[0] height_dsp = height // cell_size[1] width_dsp = width // cell_size[2] if (depth_dsp != 0) and (height_dsp != 0) and (width_dsp != 0): if output is None: input_ = input_[:depth_dsp * cell_size[0], :height_dsp * cell_size[1], :width_dsp * cell_size[2]] input_ = input_.reshape(depth_dsp, cell_size[0], height_dsp, cell_size[1], width_dsp, cell_size[2]) data_dsp = dsp_method(dsp_method(dsp_method(input_, axis=-1), axis=1), axis=2) else: file_base, file_ext = os.path.splitext(output) if file_ext != "": if not (file_ext == '.hdf' or file_ext == '.h5' or file_ext == ".nxs"): raise ValueError( "File extension must be hdf, h5, or nxs") output = file_base + file_ext data_out = losa.open_hdf_stream( output, (depth_dsp, height_dsp, width_dsp), key_path="downsample/data", overwrite=False) num = 0 for i in range(0, depth, cell_size[0]): if (i + cell_size[0]) > depth: break else: mat = input_[i:i + cell_size[0], :height_dsp * cell_size[1], :width_dsp * cell_size[2]] mat = mat.reshape(1, cell_size[0], height_dsp, cell_size[1], width_dsp, cell_size[2]) mat_dsp = dsp_method(dsp_method(dsp_method(mat, axis=-1), axis=1), axis=2) if file_ext != "": data_out[num] = mat_dsp[0] else: out_name = "0000" + str(num) losa.save_image( output + "/img_" + out_name[-5:] + ".tif", mat_dsp[0]) num += 1 else: raise ValueError("Incorrect cell size {}".format(cell_size)) if output is None: return np.asarray(data_dsp)
# Load dark-field images and flat-field images, averaging each result. print("1 -> Load dark-field and flat-field images, average each result") dark_field = np.mean(np.asarray(data[np.squeeze(np.where(ikey==2.0)), :, :]), axis=0) flat_field = np.mean(np.asarray(data[np.squeeze(np.where(ikey==1.0)), :, :]), axis=0) # Perform flat-field correction in the projection space and save the result. # Note that in this data, there're time-stamps at the top-left of images with # binary gray-scale (size ~ 10 x 80). This gives rise to the zero-division # warning. Algotom replaces zeros by the mean value or 1. We also can crop 10 # pixels from the top to avoid this problem. print("2 -> Save few projection images as tifs") proj_idx = np.squeeze(np.where(ikey == 0)) proj_corr = corr.flat_field_correction( data[proj_idx[0], 10:,:], flat_field[10:], dark_field[10:]) losa.save_image(output_base + "/proj_corr/ff_corr_00000.tif", proj_corr) # Perform flat-field correction in the sinogram space and save the result. print("3 -> Generate a sinogram with flat-field correction and save the result") index = height//2 # Index of a sinogram. sinogram = corr.flat_field_correction( data[proj_idx[0]:proj_idx[-1], index,:], flat_field[index, :], dark_field[index, :]) losa.save_image(output_base + "/sinogram/sinogram_mid.tif", sinogram) # Calculate the center-of-rotation by searching around the middle width of # the sinogram (radius=50). print("4 -> Calculate the center-of-rotation") # center = calc.find_center_vo(sinogram, width//2-50, width//2+50) center = calc.find_center_vo(sinogram) print("Center-of-rotation is {}".format(center))
def test_load_image(self): file_path = "data/img.tif" losa.save_image(file_path, np.random.rand(64, 64)) mat = losa.load_image(file_path) self.assertTrue(len(mat.shape) == 2)
# compared to the projection of the first dataset. # The ROI is pretty large (851 x 851) to detect global shifts. In such case # if using GPU the overhead for getting data from global memory can be high # list_ij2 = [height1//2, width1//2-250] # sam_shifts = f_alias3(ref_stack, sam_stack, sr_shifts, 851, 20, gpu=False, # list_ij=list_ij2) # print("Sample shifts: ") # print(sam_shifts) # Align image stacks (ref_stack_cr, sam_stack_cr) = f_alias4(ref_stack, sam_stack, sr_shifts, sam_shifts) # Check results to make sure for i in range(num_use): name = ("0000" + str(i))[-5:] losa.save_image(output_base + "/aligned/ref/img_" + name + ".tif", ref_stack_cr[i]) losa.save_image(output_base + "/aligned/sam/img_" + name + ".tif", sam_stack_cr[i]) # Open hdf stream to save data phase_hdf = losa.open_hdf_stream(output_base + "/phase.hdf", (num_proj, height1, width1), key_path="entry/data") if get_trans_dark_signal: trans_hdf = losa.open_hdf_stream(output_base + "/transmission.hdf", (num_proj, height1, width1), key_path="entry/data") dark_hdf = losa.open_hdf_stream(output_base + "/dark_signal.hdf", (num_proj, height1, width1), key_path="entry/data")
list_idx_nslice = np.reshape(np.arange(total_slice_r), (dsp_slice, cube[0])) dsp_method = np.mean # Use mean for downsampling for idx in np.arange(dsp_slice): slice_start = list_idx_nslice[idx, 0] slice_stop = list_idx_nslice[idx, -1] + 1 slices = locate_slice_chunk(slice_start, slice_stop, list_slices) if len(slices) == 1: data_chunk = list_hdf_object[slices[0][0]][slices[0][1]:slices[0][2] + 1, :height_r, :width_r] else: data_chunk1 = list_hdf_object[slices[0][0]][slices[0][1]:slices[0][2] + 1, :height_r, :width_r] data_chunk2 = list_hdf_object[slices[1][0]][slices[1][1]:slices[1][2] + 1, :height_r, :width_r] data_chunk = np.concatenate((data_chunk1, data_chunk2), axis=0) mat_dsp = data_chunk.reshape(1, cube[0], dsp_height, cube[1], dsp_width, cube[2]) mat_dsp = dsp_method(dsp_method(dsp_method(mat_dsp, axis=-1), axis=1), axis=2) hdf_stream[idx] = mat_dsp if idx % 200 == 0: out_name = "0000" + str(idx) losa.save_image( output_base + "/some_tif_files/dsp_" + out_name[-5:] + ".tif", mat_dsp[0]) time_now = timeit.default_timer() print("Done slices up to {0}. Time cost {1}".format( slice_stop, time_now - time_start)) time_stop = timeit.default_timer() print("All done!!! Total time cost: {}".format(time_stop - time_start))
trans, dark = f_alias3(ref_stack, sam_stack, x_shifts, y_shifts, win_size, ncore=None) sino_trans.append(trans[mid]) sino_dark.append(dark[mid]) t1 = timeit.default_timer() print("Done projection {0}. Time cost: {1} ".format(i, t1 - t0)) print("Done phase retrieval !!!") sino_phase = np.asarray(sino_phase) if get_trans_dark_signal: sino_trans = np.asarray(sino_trans) sino_dark = np.asarray(sino_dark) losa.save_image(output_base + "/sinogram/trans_" + name + ".tif", sino_trans) losa.save_image(output_base + "/sinogram/dark_" + name + ".tif", sino_dark) losa.save_image(output_base + "/sinogram/phase_" + name + ".tif", sino_phase) if get_trans_dark_signal: center = calc.find_center_vo(sino_trans) else: center = calc.find_center_vo(sino_phase) print("Center of rotation {}".format(center)) # Correct the fluctuation of the phase image. sino_phase1 = filt.double_wedge_filter(sino_phase, center) losa.save_image(output_base + "/sinogram/phase_corr.tif", sino_phase1) # Reconstruction rec_phase = reco.fbp_reconstruction(sino_phase,
flat_field[start_sino:stop_sino, left:right], dark_field[start_sino:stop_sino, left:right], option1=opt1, option2=opt2, option3=opt3) for j in range(start_sino, stop_sino): # img_rec = reco.dfi_reconstruction(sinograms[:, j - start_sino, :], center, angles=thetas, apply_log=True) # img_rec = reco.gridrec_reconstruction(sinograms[:, j - start_sino, :], center, angles=thetas, # apply_log=True) img_rec = reco.fbp_reconstruction(sinograms[:, j - start_sino, :], center, angles=thetas, apply_log=True) name = "0000" + str(j) losa.save_image( output_base + "/" + folder_name + "/rec_" + name[-5:] + ".tif", img_rec) t_stop = timeit.default_timer() print("Tomograph {0} -> Done slice: {1} - {2} . Time {3}".format( ii, start_sino, stop_sino, t_stop - time_start)) if num_rest != 0: for i in range(num_rest): start_sino = num_iter * slice_chunk + offset stop_sino = start_sino + num_rest sinograms = corr.flat_field_correction( data[ii * num_proj:(ii + 1) * num_proj, start_sino:stop_sino, left:right], flat_field[start_sino:stop_sino, left:right], dark_field[start_sino:stop_sino, left:right], option1=opt1,
def test_convert_tif_to_hdf(self): losa.save_image("data/tif/image_01.tif", np.random.rand(64, 64)) losa.save_image("data/tif/image_02.tif", np.random.rand(64, 64)) file_path = "data/hdf/data.hdf" con.convert_tif_to_hdf("data/tif/", file_path) self.assertTrue(os.path.isfile(file_path))
print("2 -> Calculate the center-of-rotation...") sinogram = corr.flat_field_correction(data[0:num_proj, mid_slice, left:right], flat_field[mid_slice, left:right], dark_field[mid_slice, left:right]) center = calc.find_center_vo(sinogram) print("Center-of-rotation = {0}".format(center)) for i in range(num_tomo): folder_name = "tomo_" + ("0000" + str(i))[-5:] thetas = np.deg2rad(angles[i * num_proj:(i + 1) * num_proj]) for slice_idx in range(start_slice, stop_slice + 1, step_slice): sinogram = corr.flat_field_correction( data[i * num_proj:(i + 1) * num_proj, slice_idx, left:right], flat_field[slice_idx, left:right], dark_field[slice_idx, left:right]) sinogram = remo.remove_zinger(sinogram, 0.05, 1) sinogram = remo.remove_all_stripe(sinogram, 3.0, 51, 17) sinogram = filt.fresnel_filter(sinogram, 100) # img_rec = reco.dfi_reconstruction(sinogram, center, angles=thetas, apply_log=True) # img_rec = reco.gridrec_reconstruction(sinogram, center, angles=thetas, apply_log=True) img_rec = reco.fbp_reconstruction(sinogram, center, angles=thetas, apply_log=True) file_name = "rec_slice_" + ("0000" + str(slice_idx))[-5:] + ".tif" losa.save_image(output_base + "/" + folder_name + "/" + file_name, img_rec) print("Done tomograph {0}".format(i)) time_stop = timeit.default_timer() print("All done!!! Total time cost: {}".format(time_stop - time_start))
index = 800 print("3 -> Generate a sinogram without distortion correction") sinogram = corr.flat_field_correction(proj_data[:, index, :], flat_field[index], dark_field[index]) sinogram = remo.remove_all_stripe(sinogram, 3.0, 51, 17) sinogram = filt.fresnel_filter(sinogram, 10, 1) t_start = timeit.default_timer() print("4 -> Calculate the center-of-rotation...") center = calc.find_center_vo(sinogram, width // 2 - 50, width // 2 + 50) t_stop = timeit.default_timer() print("Center-of-rotation = {0}. Take {1} second".format( center, t_stop - t_start)) t_start = timeit.default_timer() print("5 -> Perform reconstruction") img_rec = reco.dfi_reconstruction(sinogram, center, apply_log=True) losa.save_image(output_base + "/rec_before_00800.tif", img_rec) t_stop = timeit.default_timer() print("Done reconstruction without distortion correction!!!") # Generate a sinogram with distortion correction and perform reconstruction. print("6 -> Generate a sinogram with distortion correction") sinogram = corr.unwarp_sinogram(proj_data, index, xcenter, ycenter, list_fact) sinogram = corr.flat_field_correction(sinogram, flat_discor[index], dark_discor[index]) sinogram = remo.remove_all_stripe(sinogram, 3.0, 51, 17) sinogram = filt.fresnel_filter(sinogram, 10, 1) t_start = timeit.default_timer() print("7 -> Calculate the center-of-rotation...") # Center-of-rotation can change due to the distortion effect. center = calc.find_center_vo(sinogram, width // 2 - 50, width // 2 + 50) t_stop = timeit.default_timer() print("Center-of-rotation = {0}. Take {1} second".format(