Exemplo n.º 1
0
def _twostep_affine(
    vol: np.array,
    mat1: np.array,
    outshape1: Iterable[int],
    mat2: np.array,
    outshape2: Iterable[int],
    order: int = 1,
) -> np.array:
    """performs two affine transforms in succession
    
    Parameters
    ----------
    vol : np.array
        input array
    mat1 : np.array
        first affine matrix
    outshape1 : Iterable[int]
        output shape for first transform
    mat2 : np.array
        second affine matrix
    outshape2 : Interable[int]
        output shape for second matrix
    order : Optional[int], optional
        interpolation order (default is 1 = linear)
    
    Returns:

    np.array:
        transformed volume
    """
    # TODO: deal with "mode" ... maybe pass varargs
    step1 = affine_transform(vol, mat1, output_shape=outshape1, order=order)
    step2 = affine_transform(step1, mat2, output_shape=outshape2, order=order)
    return step2
Exemplo n.º 2
0
def psf_rescale_centre_skew_pad_twostep(
    psf: np.ndarray,
    dz_ratio_galvo_stage: float,
    centre: Collection[float],
    output_shape: Collection[int],
    deskewfactor: Optional[float] = None,
    interpolation: int = 3,
) -> np.ndarray:
    """Rescale, skew and centre a PSF to match the z-spacing and skew of the data
    
    This implementation uses two sequential affine transforms (scale, skew) to 
    achieve this as a single transform might cause interpolation between voxels
    that correspond to different physical spacing.

    Parameters
    ----------
    psf : np.ndarray
        point spread function (volume scan of single bead)
    dz_ratio_galvo_stage : float
        scaling factor along z axis (this accounts for different z scaling between galvo
        and stage)
    centre : Collection[float]
        centre coordinate of bead in volume
    output_shape : Collection[int]
        desired output shape of processed PSF array
    deskewfactor : Optional[float], optional
        if not None (default), will skew the psf for direct deconvolution on the skewed data.
    interpolation : int, optional
        interpolation order

    Returns
    -------
    np.ndarray
        processed PSF
    """
    # Step 1: Scaling to same z step as image data to deconvole
    scale_psf = scale_pixel_z(dz_ratio_galvo_stage)
    scaled_shape = np.array(psf.shape) * np.array(
        (1.0 / dz_ratio_galvo_stage, 1.0, 1.0))
    scaled_shape = scaled_shape.astype(np.int)
    scaled = affine_transform(psf, inv(scale_psf), output_shape=scaled_shape)

    # Step 2: Skewing according to deskewfactor
    # adjust bead centre coordinate to scaled coordinates
    scaled_centre = np.array(centre) * (dz_ratio_galvo_stage, 1.0, 1.0)
    shift = shift_centre(2 * np.array(scaled_centre))
    unshift = unshift_centre(output_shape)

    if deskewfactor:
        skew = inv(deskew_mat(deskewfactor))
    else:
        skew = np.eye(4)  # no skew, identity
    logger.debug(f"deskew factor {deskewfactor}")
    skew_shift = unshift @ skew @ shift
    processed_psf = affine_transform(scaled,
                                     inv(skew_shift),
                                     output_shape=output_shape,
                                     order=interpolation)
    return processed_psf
def psf_rescale_centre_skew_pad(
    psf: np.ndarray,
    dz_ratio_galvo_stage: float,
    centre: Collection[float],
    output_shape: Collection[int],
    deskewfactor: Optional[float] = None,
    interpolation: int = 3,
) -> Tuple[np.ndarray, np.ndarray]:
    """
    TODO: use psf_rescale_centre_skew_pad_twostep instead

    Given a 
    * psf: volume (numpy array)
    * centre: centre coordinate of bead in volume
    * dz_ratio_galvo_stage: scaling factor along z axis (this accounts for different z scaling between galvo
    and stage)
    * output_shape: desired output shape of array
    * deskewfactor: if not None (default), will skew the psf for direct deconvolution on the skewed data.
    
    Returns: tuple (processed_psf, transform_matrix)
    """
    scale_psf = scale_pixel_z(dz_ratio_galvo_stage)
    shift = shift_centre(2 * np.array(centre))
    unshift = unshift_centre(output_shape)
    if deskewfactor:
        skew = inv(deskew_mat(deskewfactor))
    else:
        skew = np.eye(4)  # no skew, identity
    logger.debug(f"deskew factor {deskewfactor}")
    combined_transform = unshift @ skew @ scale_psf @ shift
    processed_psf = affine_transform(
        psf, inv(combined_transform), output_shape=output_shape, order=interpolation
    )
    return processed_psf, combined_transform