Source code for find_center

import numpy as np
from PIL import Image as im
from PIL import ImageOps, ImageChops

[docs]def create_circular_mask(h, w, outer_radius, inner_radius, center=None): """ Create a circular ring mask for specified radii. Authors: Weiqi Yue, Gabriel Ponon, Zhuldyz Ualikhankyzy, Nathaniel K. Tomczak Version: v0_1 (Jul 23 2022) :param h: Height of the mask. :type h: int :param w: Width of the mask. :type w: int :param outer_radius: Outer radius for the mask. :type outer_radius: float :param inner_radius: Inner radius for the mask. :type inner_radius: float :param center: Coordinate tuple of the center of the mask. Uses the middle of the image if None. :type center: tuple, optional :return: The circular mask. :rtype: numpy.ndarray """ if center is None: center = (int(w/2), int(h/2)) Y, X = np.ogrid[:h, :w] dist_from_center = np.sqrt((X - center[0])**2 + (Y - center[1])**2) mask = (dist_from_center <= outer_radius) & (dist_from_center >= inner_radius) return mask
[docs]def define_mask(h=2048, w=2048, inner_radius=40, white_width=8, black_width=10): """ Returns a multi-ring mask that can be used to filter an XRD image. Authors: Weiqi Yue, Gabriel Ponon, Zhuldyz Ualikhankyzy, Nathaniel K. Tomczak Version: v0_1 (Jul 23 2022) :param h: Height of the mask. :type h: int :param w: Width of the mask. :type w: int :param inner_radius: Inner radius of the first ring. :type inner_radius: int, optional :param white_width: Width of the transparent ring portions. :type white_width: int, optional :param black_width: Width of the opaque ring portions. :type black_width: int, optional :return: The multi-ring mask. :rtype: numpy.ndarray """ center = (int(w/2), int(h/2)) result_mask = np.zeros((h, w)) for i in range(0, 50): start = inner_radius + (white_width + black_width) * i end = start + white_width raw_mask = create_circular_mask(w, h, outer_radius=end, inner_radius=start) one_array = np.ones((w, h)) mask = raw_mask * one_array result_mask = np.add(result_mask, mask) return result_mask
[docs]def add_margin(pil_img, top, right, bottom, left, color): """ Add margins around the border of an image. Authors: Weiqi Yue, Gabriel Ponon, Zhuldyz Ualikhankyzy, Nathaniel K. Tomczak Version: v0_1 (Jul 23 2022) :param pil_img: Input PIL image to which margins are added. :type pil_img: PIL.Image :param top: Size of the top margin. :type top: int :param right: Size of the right margin. :type right: int :param bottom: Size of the bottom margin. :type bottom: int :param left: Size of the left margin. :type left: int :param color: Color to overlay for margins. :type color: int or tuple :return: The image with added margins. :rtype: PIL.Image """ width, height = pil_img.size new_width = width + right + left new_height = height + top + bottom result = im.new(pil_img.mode, (new_width, new_height), color) result.paste(pil_img, (left, top)) return result
[docs]def find_center(img, mask=None): """ Apply a mask to the central region of interest on an XRD image and find the coordinates of maximum intensity. Authors: Weiqi Yue, Gabriel Ponon, Zhuldyz Ualikhankyzy, Nathaniel K. Tomczak Version: v0_1 (Jul 23 2022) :param img: Input PIL XRD image to find the ring center. :type img: PIL.Image :param mask: The mask to use. If None, a mask will be generated through the define_mask function. :type mask: numpy.ndarray, optional :return: The coordinates of the maximum intensity. :rtype: tuple """ if mask is None: mask = define_mask() mask = im.fromarray(mask) img_padding = add_margin(img, 300, 300, 300, 300, 0) mask_padding = add_margin(mask, 300, 300, 300, 300, 0) max_i = -99999 cord = np.nan p = 0 for i in range(-20, 20): for j in range(-20, 20): offset_img = np.roll(mask_padding, i, axis=0) offset_img = np.roll(offset_img, j, axis=1) aa = img_padding * offset_img c = aa.sum() if c > max_i: max_i = c cord = [i, j] elif c == max_i: p += 1 final_x = cord[1] + 1024 final_y = cord[0] + 1024 return final_x, final_y