Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
                                     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 !!!")
Ejemplo n.º 4
0
(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 !!!")
Ejemplo n.º 7
0
 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))
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
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()
Ejemplo n.º 15
0
    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))
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
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))
Ejemplo n.º 19
0
 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)
Ejemplo n.º 20
0
    # 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")
Ejemplo n.º 21
0
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))
Ejemplo n.º 22
0
        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,
Ejemplo n.º 23
0
            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,
Ejemplo n.º 24
0
 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))
Ejemplo n.º 26
0
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(