#!/usr/bin/env python # coding: utf-8 # This notebook is part of the `kikuchipy` documentation https://kikuchipy.org. # Links to the documentation won't work from the notebook. # # Virtual backscatter electron imaging # ## Interactive plotting # # Angle resolved backscatter electron (BSE) imaging can be performed interactively # with the method # [plot_virtual_bse_intensity()](reference.rst#kikuchipy.signals.EBSD.plot_virtual_bse_intensity), # adopted from [pyxem](https://github.com/pyxem/pyxem), by integrating the # intensities within a part, e.g. a (10 x 10) pixel rectangular region of interest # (ROI), of the stack of EBSD patterns. Let's first import necessary libraries # and a 13 MB Nickel EBSD data set # In[ ]: # exchange inline for qt5 for interactive plotting from the pyqt package get_ipython().run_line_magic('matplotlib', 'inline') import tempfile import hyperspy.api as hs import matplotlib.pyplot as plt plt.rcParams["font.size"] = 12 import numpy as np import kikuchipy as kp s = kp.data.nickel_ebsd_large(allow_download=True) # External download s # In[ ]: roi = hs.roi.RectangularROI(left=0, top=0, right=10, bottom=10) roi # In[ ]: s.plot_virtual_bse_intensity(roi) # Below is an animation showing the output three output windows of the above # method: navigator to the left (the navigator image created from *all* # intensities on the detector, not just within an ROI), detector in the middle # with the adjustable ROI, and the virtual BSE image generated from the # intensities within the ROI to the right. # # Note that the position of the ROI on the detector is updated during the # interactive plotting. See # [HyperSpy's ROI user guide](http://hyperspy.org/hyperspy-doc/current/user_guide/interactive_operations_ROIs.html#region-of-interest-roi) # for more detailed use of ROIs. # # The virtual image, created from integrating the intensities within the ROI, can # then be written to an image file using # [get_virtual_bse_intensity()](reference.rst#kikuchipy.signals.EBSD.get_virtual_bse_intensity) # In[ ]: vbse = s.get_virtual_bse_intensity(roi) vbse # In[ ]: temp_dir = tempfile.mkdtemp() plt.imsave(temp_dir + "vbse1.png", arr=vbse.data) # A [VirtualBSEImage](reference.rst#kikuchipy.signals.VirtualBSEImage) instance is # returned. # ## Generate many virtual images # # Sometimes we want to get many images from parts of the detector, e.g. like what # is demonstrated in the # [xcdskd project](https://xcdskd.readthedocs.io/en/latest/bse_imaging.html) with # the angle resolved virtual backscatter electron array (arbse/vbse array). # Instead of keeping track of multiple # [hyperspy.roi.BaseInteractiveROI](http://hyperspy.org/hyperspy-doc/current/api/hyperspy.roi.html#hyperspy.roi.BaseInteractiveROI) # objects, we can create a detector grid of a certain shape, e.g. (5, 5), and # obtain gray scale images, or combine multiple grid tiles in red, green and # channels to obtain RGB images. # # First, we initialize a virtual BSE image generator, # [kikuchipy.generators.VirtualBSEGenerator](reference.rst#kikuchipy.generators.VirtualBSEGenerator), # with an [EBSD](reference.rst#kikuchipy.signals.EBSD) signal, in this case the # raw EBSD patterns without any background correction or other processing # In[ ]: vbse_gen = kp.generators.VirtualBSEGenerator(s) vbse_gen # We can set and plot the detector grid on one of the EBSD patterns, also coloring # one or more of the grid tiles red, green and blue, as is done in # Nolze et al. (2017), by calling # [VirtualBSEGenerator.plot_grid()](reference.rst#kikuchipy.generators.VirtualBSEGenerator.plot_grid) # In[ ]: vbse_gen.grid_shape # In[ ]: vbse_gen.grid_shape = (10, 10) red = [(7, 1), (8, 1), (8, 2), (9, 1), (9, 2)] green = [(8, 4), (8, 5), (9, 4), (9, 5)] blue = [(7, 8), (8, 7), (8, 8), (9, 7), (9, 8)] p = vbse_gen.plot_grid( rgb_channels=[red, green, blue], visible_indices=True, # Default pattern_idx=(10, 20), # Default is (0, 0) ) p # As shown above, whether to show the grid tile indices or not is controlled with # the `visible_indices` argument, and which signal pattern to superimpose the grid # upon is controlled with the `pattern_idx` parameter. # To obtain an RGB image from the detector grid tiles shown above, we use # [get_rgb_image()](reference.rst#kikuchipy.generators.VirtualBSEGenerator.get_rgb_image) # (see the docstring for all available parameters) # In[ ]: vbse_rgb_img = vbse_gen.get_rgb_image(r=red, g=green, b=blue) vbse_rgb_img # In[ ]: vbse_rgb_img.plot(title="", axes_off=True) # An RGB image formed from coloring three grey scale virtual BSE images red, # green and blue. # To obtain one grey scale virtual BSE image from each grid tile, we use # [get_images_from_grid()](reference.rst#kikuchipy.generators.VirtualBSEGenerator.get_images_from_grid) # In[ ]: vbse_gen.grid_shape = (3, 3) vbse_imgs = vbse_gen.get_images_from_grid() vbse_imgs # In[ ]: vbse_imgs.plot() # In[ ]: fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(20, 20)) for idx in np.ndindex(vbse_imgs.axes_manager.navigation_shape[::-1]): ax[idx].imshow(vbse_imgs.inav[idx].data, cmap="gray") ax[idx].axis("off") fig.tight_layout(w_pad=0.5, h_pad=-24) # It might be desirable to normalize, rescale or stretch the intensities in the # images, as shown e.g. in Fig. 9 in # Wright et al. (2015). This can be # done with # [VirtualBSEImage.normalize_intensity()](reference.rst#kikuchipy.signals.VirtualBSEImage.normalize_intensity) # or # [VirtualBSEImage.rescale_intensity()](reference.rst#kikuchipy.signals.VirtualBSEImage.rescale_intensity). # Let's rescale the intensities in each image to the range [0, 1], while also # excluding the intensities outside the lower and upper 0.5% percentile, per image # In[ ]: vbse_imgs.data.dtype # In[ ]: vbse_imgs2 = vbse_imgs.deepcopy() vbse_imgs2.rescale_intensity(out_range=(0, 1), percentiles=(0.5, 99.5)) # In[ ]: print(vbse_imgs.data.min(), vbse_imgs.data.max()) print(vbse_imgs2.data.min(), vbse_imgs2.data.max()) # In[ ]: fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(20, 20)) for idx in np.ndindex(vbse_imgs2.axes_manager.navigation_shape[::-1]): ax[idx].imshow(vbse_imgs2.inav[idx].data, cmap="gray") ax[idx].axis("off") fig.tight_layout(w_pad=0.5, h_pad=-24) # To obtain a rectangular ROI from the grid, we can use # [VirtualBSEGenerator.roi_from_grid()](reference.rst#kikuchipy.generators.VirtualBSEGenerator.roi_from_grid) # In[ ]: roi2 = vbse_gen.roi_from_grid((3, 3)) # (Row, column) roi2 # In[ ]: import os os.rmdir(temp_dir)