Source code for xripl.clean

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Aug  1 13:13:52 2019

Functions for cleaning and regularizing images.

@author: Pawel M. Kozlowski
"""

# python modules
import numpy as np
from skimage.morphology import disk, opening, closing
from skimage.filters import median, gaussian
import matplotlib.pyplot as plt

# custom modules
import xripl.pltDefaults


# listing all functions declared in this file so that sphinx-automodapi
# correctly documents them and doesn't document imported functions.
__all__ = ["cleanArtifacts",
           "flatten",
           "enhanceRadiograph",
           ]


[docs]def cleanArtifacts(image, diskSize=5, plots=False, vmin=0, vmax=1, flip=False): r""" Applies morphological opening to clean bright streaks and spots from radiographs, and then applies a morphological closing to remove dark artifacts. Parameters ---------- image: numpy.ndarray Image containing artifacts to be cleaned. diskSize: int Size of disk to be used as convolving element for removing artifcats. plots: bool Flag for displaying plots of processed images. vmin: float Value between 0 and 1 for setting minimum threshold in plotting image. See matplotlib.pyplot.imshow(). vmax: float Value between 0 and 1 for setting maximum threshold in plotting image. See matplotlib.pyplot.imshow(). flip: bool Flips order of opening and closing operations. When False, opening is applied first, then closing. When True, closing is applied first, then opening. False is used by default for radiographs, and True is used for inverted radiographs """ if flip: imgClosed = closing(image, disk(diskSize)) cleaned = opening(imgClosed, disk(diskSize)) else: imgOpen = opening(image, disk(diskSize)) cleaned = closing(imgOpen, disk(diskSize)) if plots: fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(12, 12), sharex=True, sharey=True) ax = axes.ravel() ax[0].imshow(image, vmin=vmin, vmax=vmax) ax[0].set_title("Original") if flip: ax[1].imshow(imgClosed) ax[1].set_title("Closed") ax[2].imshow(cleaned) ax[2].set_title("Opened") else: ax[1].imshow(imgOpen) ax[1].set_title("Opened") ax[2].imshow(cleaned) ax[2].set_title("Closed") fig.tight_layout() plt.show() return cleaned
[docs]def flatten(image, medianDisk=100, gaussSize=100, plots=False, vmin=0, vmax=1): r""" Produces an approximate image of the background light intensity variations in the image and divides the image by this background to effectively flatten the contrast. Parameters ---------- image: numpy.ndarray Image whose background brightness variation is to be removed via flattening. medianDisk: int Size of disk used in median filtering to smooth out all structures in image other than background light variations. gaussSize: int Size of Gaussian smoothing used on background image produced by median filtering. This smooths out ridges that appear in the median filtered image. plots: bool Flag for displaying plots of processed images. """ # removing background from image denoised = median(image, disk(medianDisk)) # smoothing background gaussed = gaussian(denoised, sigma=gaussSize) # renaming pseudoFlatfield = gaussed # applying pseudo flatfield flat = image / pseudoFlatfield # filtering nan and inf values flat[np.isnan(flat)] = 0 flat[np.isinf(flat)] = 0 # reshaping from flat array to 2D array after filtering out nan values imgShape = np.shape(image) flat = flat.reshape(imgShape) # normalizing flat_norm = flat / np.max(flat) if plots: fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(12, 12), sharex=True, sharey=True) ax = axes.ravel() ax[0].imshow(image, vmin=vmin, vmax=vmax) ax[0].set_title("Original") ax[1].imshow(pseudoFlatfield, vmin=vmin, vmax=vmax) ax[1].set_title("Background") ax[2].imshow(flat_norm, vmin=vmin, vmax=vmax) ax[2].set_title("Flattened") fig.tight_layout() plt.show() return flat_norm
[docs]def enhanceRadiograph(img, medianDisk=5, morphDisk=5, flattenMedian=100, flattenGauss=100, plots=False): r""" Median filter, morphological filter, and pseudo-flatfield the radiographs to prepare it for feature identification. Parameters ---------- img : numpy.ndarray Foreground radiographic image as a 2D numpy array, which is to be cleaned/enhanced. medianDisk : int Radial size of disk in pixels to be used for median filtering the image. Default is radius of 5 pixels. morphDisk : int Radial size of disk in pixels to be used for morphologically filtering the image to clean up artifacts. flattenMedian : int Radial size of disk in pixels to be used for median filtering image as part of over-smoothing process to obtain the pseudo-flatfield. Default is radius of 100 pixels. flattenGauss : int Standard deviation in pixels to be used for Gaussian blurring the image as part of over-smoothing process to obtain the pseudo-flatfield. Default is sigma of 100 pixels. plots : bool Flag for plotting cleaned and flattened images. Default is False. """ # normalizing image intensity to max value img_norm = img / np.max(img) # median filtering to denoise the image denoised = median(img_norm, disk(medianDisk)) denoised_norm = denoised / np.max(denoised) # removing artifacts (e.g. xrfc streaks, hot pixels, etc.) cleaned = cleanArtifacts(image=denoised_norm, diskSize=morphDisk, plots=plots) # Flattening image by dividing out approxiamte background flattened = flatten(image=cleaned, medianDisk=flattenMedian, gaussSize=flattenGauss, plots=plots) # returns median filtered image, morphologically filtered image # and pseudo-flatfielded image as a tuple. return denoised, cleaned, flattened