Skip to main content
CDI Training

Code examples

Here's some examples of CDI code that might be useful.

General utility functions

Common array manipulations
import numpy as npdef fft(arr):
    """Perform a correctly shifted fast Fourier transform"""
    return np.fft.fftshift(np.fft.fftn(np.fft.ifftshift(arr)))


def ifft(arr):
    """Perform a correctly shifted inverse fast Fourier transform"""
    return np.fft.fftshift(np.fft.ifftn(np.fft.ifftshift(arr)))


def comp_log(comp_arr):
    """Take the logarithm of the amplitude of a complex array while keeping the phase intact."""
    amp = np.abs(comp_arr)
    phi = np.angle(comp_arr)
    return np.log(amp+1) * np.exp(1j*phi)


def normalize(arr):
    """Compress the range of an array onto the range (0,1)"""
    return (arr - np.min(arr)) / (np.max(arr) - np.min(arr))


def pad_to_size(arr, N_new):
    """Pad a 2D square array with zeros to a certain output size (bigger than the original)."""
    N = arr.shape[0]
    pad = (N_new - N) // 2
    if 2*pad + N == N_new:
        return np.pad(arr, ((pad, pad), (pad, pad)))
    else 2*pad + N == N_new - 1:
        return np.pad(arr, ((pad, pad+1), (pad, pad+1)))

Plotting
import numpy as npfrom matplotlib import colors

def comp_to_rgb(comp_img):
    """Converts a complex array into an RGB color image (amplitude -> brightness , phase -> color)"""
    amp = normalize(np.abs(comp_img))  # The normalize function is defined above
    phi = normalize(np.angle(comp_img))
    one = np.ones_like(amp)
    hsv = np.dstack((phi, one, amp))
    return colors.hsv_to_rgb(hsv)

Loading and saving images
from skimage import io
import tkinter as tkfrom pathlib import Path
import shutilfrom matplotlib import pyplot as plt
from PIL import Image


def get_file():
    """Opens a GUI dialog to select a single file"""
    root = tk.Tk()
    root.withdraw()
    try:
        return fd.askopenfilename()
    except KeyError:
        return None


def get_save_as(ext):
    """Opens a save-as dialog to save a file with the given extension type"""
    root = tk.Tk()
    root.withdraw()
    try:
        return fd.asksaveasfilename(defaultextension=ext, filetypes=[(ext.lower(), ext.upper())])
    except KeyError:
        return


def load_image(fname=None):
    """Loads an image as a 2D numpy array. Color images will be loaded in grayscale."""
    if fname is None:
        fname = get_file()
    return imread(fname, as_gray=True)


def save_array_as_image(img, fname=None, cmap='plasma'):
    """Saves a 2D array as an image using one of matplotlib's builtin colormap."""
    if fname is None:
        fname = get_save_as('png')
    plt.imsave(fname, img, cmap=cmap)


def save_imstack_as_gif(imstack, fname=None, cmap='plasma'):
    """Saves a 3D array (image stack) as an animated gif. This method is a little janky. If someone knows a
       better way, please share it."""
    if fname is None:
        fname = get_save_as('gif')
    dname = Path(__file__).parent
    temp = dname / 'temp'
    temp.mkdir()
    [plt.imsave(f'{temp}/im_{n:03}.png', im, cmap=cmap, vmin=imstack.amin(), vmax=imstack.amax())
     for n, im in enumerate(imstack)]
    imstack = [Image.open(f'{temp}/im_{n:03}.png') for n, _ in enumerate(imstack)]
    imstack[0].save(fname, save_all=True, append_images=imstack[1:], duration=300, loop=0)
    shutil.rmtree(temp)