예제 #1
0
def _check_master_pattern_and_get_data(
    master_pattern,
    energy: Union[int,
                  float]) -> Tuple[np.ndarray, np.ndarray, int, int, float]:
    """Check whether the master pattern is suitable for projection, and
    return the northern and southern hemispheres along with their shape.

    Parameters
    ----------
    master_pattern : kikuchipy.signals.EBSDMasterPattern
      Master pattern in the square Lambert projection.
    energy
        Accelerating voltage of the electron beam in kV specifying which
        master pattern energy to use during projection of simulated
        patterns.

    Returns
    -------
    master_north, master_south
        Northern and southern hemispheres of master pattern of data type
        32-bit float.
    npx, npy
        Number of columns and rows of the master pattern.
    scale
        Factor to scale up from the square Lambert projection to the
        master pattern.
    """
    master_pattern._is_suitable_for_projection(raise_if_not=True)
    (
        master_north,
        master_south,
    ) = master_pattern._get_master_pattern_arrays_from_energy(energy=energy)
    npx, npy = master_pattern.axes_manager.signal_shape
    scale = (npx - 1) / 2
    dtype_desired = np.float32
    if master_north.dtype != dtype_desired:
        master_north = rescale_intensity(master_north, dtype_out=dtype_desired)
        master_south = rescale_intensity(master_south, dtype_out=dtype_desired)
    return master_north, master_south, npx, npy, scale
예제 #2
0
def get_rgb_image(
    channels: List[np.ndarray],
    percentiles: Optional[Tuple] = None,
    normalize: bool = True,
    alpha: Optional[np.ndarray] = None,
    dtype_out: Union[np.uint8, np.uint16] = np.uint8,
    **kwargs,
) -> np.ndarray:
    """Return an RGB image from three numpy arrays, with a potential
    alpha channel.

    Parameters
    ----------
    channels
        A list of np.ndarray for the red, green and blue channel,
        respectively.
    normalize
        Whether to normalize the individual `channels` before
        RGB image creation.
    alpha
        Potential alpha channel. If None (default), no alpha channel
        is added to the image.
    percentiles
        Whether to apply contrast stretching with a given percentile
        tuple with percentages, e.g. (0.5, 99.5), after creating the
        RGB image. If None (default), no contrast stretching is
        performed.
    dtype_out
        Output data type, either np.uint16 or np.uint8 (default).
    kwargs :
        Keyword arguments passed to
        :func:`~kikuchipy.generators.virtual_bse_generator.normalize_image`.

    Returns
    -------
    rgb_image : np.ndarray
        RGB image.
    """
    n_channels = 3
    rgb_image = np.zeros(channels[0].shape + (n_channels, ), np.float32)
    for i, channel in enumerate(channels):
        if normalize:
            channel = normalize_image(channel.astype(np.float32),
                                      dtype_out=dtype_out,
                                      **kwargs)
        rgb_image[..., i] = channel

    # Apply alpha channel if desired
    if alpha is not None:
        alpha_min = np.nanmin(alpha)
        rescaled_alpha = (alpha - alpha_min) / (np.nanmax(alpha) - alpha_min)
        for i in range(n_channels):
            rgb_image[..., i] *= rescaled_alpha

    # Rescale to fit data type range
    if percentiles is not None:
        in_range = tuple(np.percentile(rgb_image, q=percentiles))
    else:
        in_range = None
    rgb_image = rescale_intensity(rgb_image,
                                  in_range=in_range,
                                  dtype_out=dtype_out)

    return rgb_image.astype(dtype_out)
예제 #3
0
def _get_patterns_chunk(
    rotations_array: np.ndarray,
    dc: Vector3d,
    master_north: np.ndarray,
    master_south: np.ndarray,
    npx: int,
    npy: int,
    scale: Union[int, float],
    rescale: bool,
    dtype_out: Optional[type] = np.float32,
) -> np.ndarray:
    """Get the EBSD patterns on the detector for each rotation in the
    chunk. Each pattern is found by a bi-quadratic interpolation of the
    master pattern as described in EMsoft.

    Parameters
    ----------
    rotations_array
        Array of rotations of shape (..., 4) for a given chunk in
        quaternions.
    dc
        Direction cosines unit vector between detector and sample.
    master_north
        Northern hemisphere of the master pattern.
    master_south
        Southern hemisphere of the master pattern.
    npx
        Number of pixels in the x-direction on the master pattern.
    npy
        Number of pixels in the y-direction on the master pattern.
    scale
        Factor to scale up from square Lambert projection to the master
        pattern.
    rescale
        Whether to call rescale_intensities() or not.
    dtype_out
        Data type of the returned patterns, by default np.float32.

    Returns
    -------
    numpy.ndarray
        3D or 4D array with simulated patterns.
    """
    rotations = Rotation(rotations_array)
    rotations_shape = rotations_array.shape[:-1]
    simulated = np.empty(shape=rotations_shape + dc.shape, dtype=dtype_out)
    for i in np.ndindex(rotations_shape):
        rotated_dc = rotations[i] * dc
        (
            nii,
            nij,
            niip,
            nijp,
            di,
            dj,
            dim,
            djm,
        ) = _get_lambert_interpolation_parameters(
            rotated_direction_cosines=rotated_dc, npx=npx, npy=npy, scale=scale,
        )
        pattern = np.where(
            rotated_dc.z >= 0,
            (
                master_north[nii, nij] * dim * djm
                + master_north[niip, nij] * di * djm
                + master_north[nii, nijp] * dim * dj
                + master_north[niip, nijp] * di * dj
            ),
            (
                master_south[nii, nij] * dim * djm
                + master_south[niip, nij] * di * djm
                + master_south[nii, nijp] * dim * dj
                + master_south[niip, nijp] * di * dj
            ),
        )
        if rescale:
            pattern = rescale_intensity(pattern, dtype_out=dtype_out)
        simulated[i] = pattern
    return simulated