Image Alignment#

In case of displacement of the detector component, i.e. scintilator, the open beam (background) image can not be used for normalization of the sample (signal) image without alignment.

Here is a simple image position shifting solution.

[1]:
from pathlib import Path

ob_image = Path('background.tiff')
misaligned_image = Path('misaligned_sample.tiff')
[2]:
# load tiff image
from PIL import Image

ob = Image.open(ob_image)
misaligned = Image.open(misaligned_image)
[3]:
import numpy as np

ob_normalized = (ob / np.max(ob) * 255).astype(np.uint8)
misaligned_normalized = (misaligned / np.max(misaligned) * 255).astype(np.uint8)
[4]:
def shift_pixels(image: np.ndarray, shift_x: int = 0, shift_y: int = 0) -> np.ndarray:
    """Shifts the pixels of an image by ``shift_x`` and ``shift_y``.

    Image size will remain the same, shifted pixels will
    be cropped and empty pixels will be filled with zeros.
    """
    rows, cols = image.shape
    empty_image = np.zeros(image.shape, dtype=np.uint8)
    cropping_point = (
        (max(0, -shift_y), min(rows, rows - shift_y)),
        (max(0, -shift_x), min(cols, cols - shift_x)),
    )
    placing_point = (
        (max(0, shift_y), min(rows, rows + shift_y)),
        (max(0, shift_x), min(cols, cols + shift_x)),
    )
    empty_image[
        placing_point[1][0] : placing_point[1][1],
        placing_point[0][0] : placing_point[0][1],
    ] = image[
        cropping_point[1][0] : cropping_point[1][1],
        cropping_point[0][0] : cropping_point[0][1],
    ]
    return empty_image
[5]:
import matplotlib.pyplot as plt

fig, ax = plt.subplots(2, 2, figsize=(15, 10))
im = ax[0, 0].imshow(ob_normalized)
ax[0, 1].imshow(misaligned_normalized, cmap=im.cmap)
ax[1, 0].imshow(misaligned_normalized - (ob_normalized), cmap=im.cmap)
ax[1, 1].imshow(
    shift_pixels(misaligned_normalized, 6, 3) - (ob_normalized), cmap=im.cmap
)

ax[0, 0].set_title('Open Beam (Background)')
ax[0, 1].set_title('Misaligned Sample')
ax[1, 0].set_title('Misaligned Sample - Open Beam')
ax[1, 1].set_title('Shifted Misaligned Sample - Open Beam')

for ax_ in ax:
    plt.colorbar(im, ax=ax_)
    for ax__ in ax_:
        ax__.set_xlabel('pixel numbers')
        ax__.set_ylabel('pixel numbers')
../_images/experiments_image_alignment_5_0.png

Here is the sample image that is included in the misaligned image: f38a8653162b43b1bef1dc2d3901ebc0