Exemplo n.º 1
0
def test_array_normalization():
    a = np.asarray([[0, 4], [3, 0]], dtype=np.float32)
    a_ref_area = np.asarray([[0, 4.0 / 7.0], [3.0 / 7.0, 0]], dtype=np.float32)
    a_ref_peak = np.asarray([[0, 1.0], [3.0 / 4.0, 0]], dtype=np.float32)
    a_ref_l2 = np.asarray([[0, 4.0 / 5.0], [3.0 / 5.0, 0]], dtype=np.float32)

    assert np.array_equal(images.normalize(a, by='area'), a_ref_area)
    assert np.array_equal(images.normalize(a, by='peak'), a_ref_peak)
    assert np.array_equal(images.normalize(a, by='l2'), a_ref_l2)

    return
Exemplo n.º 2
0
def test_array_normalization_parsing():

    a = np.asarray([1, 2, 3])

    with raises(ValueError) as cm:
        array = images.normalize(a, "noValidMethod")
    assert ("Specified argument type is not one of the recognized methods: "
             "['area', 'peak', 'l2']") == str(cm.value)

    return
Exemplo n.º 3
0
def get_kernel_hann_rotational(size: int,
                               size_y: Optional[int] = None,
                               normalize: str = 'area') -> ndarray:
    """Get a normalized, rotationally symmetric 2D Hann kernel.

    This kernel is rotationally symmetric and not a tensor product kernel.

    Args:
        size: Size of the kernel in pixels.

        size_y: Size of the kernel in y direction.
            If no value is specified, a quadratic kernel is calculated

        normalize: Normalize the kernel by given method, see
            :func:`plenpy.utilities.images.normalize()` for available types.
            Default: Normalize to sum one.

    Returns:
        A rotationally symmetric Hann kernel of shape (size, size_y).

    """

    if type(size) is not int:
        raise ValueError(f"Specified size {size} is not an integer.")

    # Set kernel size
    size_x = size

    # If no size_y value has been specified, calculate quadratic kernel
    if size_y is None:
        size_y = size_x
    else:
        if type(size_y) is not int:
            raise ValueError(f"Specified size_y {size_y} is not an integer.")

    logger.debug(f"Calculating Hann kernel with shape ({size_x}, {size_y}).")

    distance_x = (size_x - 1) / 2
    distance_y = (size_y - 1) / 2
    distance = min(distance_x, distance_y)

    x_vector = np.arange(-distance_x, distance_x + 1)
    y_vector = np.arange(-distance_y, distance_y + 1)

    x_mesh, y_mesh = np.meshgrid(y_vector, x_vector)
    r = np.hypot(x_mesh, y_mesh)
    del x_mesh, y_mesh

    # Hanning window centralized around x = 0
    kern = 0.5 * (1 - np.cos(np.pi * (r / distance + 1)))
    kern[np.where(r > distance)] = 0.0

    return images.normalize(kern, normalize)
Exemplo n.º 4
0
def get_kernel_hamming(size,
                       size_y: Optional[int] = None,
                       normalize: str = 'area') -> ndarray:
    """Get a normalized 2D Hamming kernel.

    Args:
        size: Size of the kernel in pixels.

        size_y: Size of the kernel in y direction.
            If no value is specified, a quadratic kernel is calculated

        normalize: Normalize the kernel by given method, see
            :func:`plenpy.utilities.images.normalize()` for available types.
            Default: Normalize to sum one.

    Returns:
        A Hamming kernel of shape (size, size_y).
    """

    if type(size) is not int:
        raise ValueError(f"Specified size {size} is not an integer.")

    # Set kernel size
    size_x = size

    # If no size_y value has been specified, calculate quadratic kernel
    if size_y is None:
        size_y = size_x
    else:
        if type(size_y) is not int:
            raise ValueError(f"Specified size_y {size_y} is not an integer.")

    logger.debug(
        f"Calculating Hamming kernel with shape ({size_x}, {size_y}).")

    kern_x = np.hamming(size_x)
    kern_y = np.hamming(size_y)

    # Calculate outer product of the 1D kernels
    kern = np.outer(kern_x, kern_y)

    return images.normalize(kern, normalize)
Exemplo n.º 5
0
def get_kernel_disk(size: int,
                    radius: Optional[float] = None,
                    size_y: Optional[int] = None,
                    radius_y: Optional[int] = None,
                    normalize: str = 'area') -> ndarray:
    """Get a normalized 2D disk kernel.

    Args:
        size: Size of the kernel in pixels.

        radius: Radius of the disk.

        size_y: Size of the kernel in y direction.
            If no value is specified, a quadratic kernel is calculated

        radius_y: Radius of the disk in y-direction.
            If no value is specified, a circular disc is calculated.

        normalize: Normalize the kernel by given method, see
            :func:`plenpy.utilities.images.normalize()` for available types.
            Default: Normalize to sum one.

    Returns:
        A disk kernel of shape (size, size_y) with radii
        (radius, radius_y).

    """
    if type(size) is not int:
        raise ValueError(f"Specified size {size} is not an integer.")

    # Set kernel size
    size_x = size
    radius_x = radius

    # If no size_y value has been specified, calculate quadratic kernel
    if size_y is None:
        size_y = size_x
    else:
        if type(size_y) is not int:
            raise ValueError(f"Specified size_y {size_y} is not an integer.")

    logger.debug(f"Calculating disk kernel with shape ({size_x}, {size_y}).")

    # Set maximal radius if no values are specified
    if radius_x is None and radius_y is None:
        radius_x = min((size - 1) / 2.0, (size_y - 1) / 2.0)
        radius_y = radius_x

    # Check radius value and set to optimal, if not defined
    elif radius_x is None:
        logger.debug(
            "No radius value specified for disk kernel. Setting to maximal.")
        radius_x = (size - 1) / 2.0

    # If no radius_y value has been specified, calculate circular kernel
    elif radius_y is None:
        radius_y = radius_x

    mu_x = (size_x - 1) / 2.0
    mu_y = (size_y - 1) / 2.0

    x, y = np.meshgrid(np.arange(0, size_x, 1), np.arange(0, size_y, 1))

    # Calculate mask, if the radii are not equal, results in an ellipse
    mask = (x - mu_x)**2 / radius_x**2 + (y - mu_y)**2 / radius_y**2 <= 1

    # Initialize kernel with zeros and apple mask.
    kernel = np.zeros((size_x, size_y))
    kernel[mask.T] = 1.0

    return images.normalize(kernel, normalize)
Exemplo n.º 6
0
def get_kernel_kaiser_rotational(size: int,
                                 beta: Optional[float] = None,
                                 size_y: Optional[int] = None,
                                 normalize: str = 'area') -> ndarray:
    """Get a normalized, rotationally symmetric 2D Kaiser kernel.

    This kernel is rotationally symmetric and not a tensor product kernel.
    Since the definition relies on the (recursively defined) modified
    bessel functions, this implementation is much slower than the tensor
    product implementation.

    Args:
        size: Size of the kernel in pixels.

        beta: Shape parameter. Default: 3.5

        size_y: Size of the kernel in y direction.
            If no value is specified, a quadratic kernel is calculated

        normalize: Normalize the kernel by given method, see
            :func:`plenpy.utilities.images.normalize()` for available types.
            Default: Normalize to sum one.

    Returns:
        A rotationally symmetric Kaiser kernel of shape (size, size_y).

    """

    if type(size) is not int:
        raise ValueError(f"Specified size {size} is not an integer.")

    # Default value
    if beta is None:
        beta = 3.5

    # Set kernel size
    size_x = size

    # If no size_y value has been specified, calculate quadratic kernel
    if size_y is None:
        size_y = size_x
    else:
        if type(size_y) is not int:
            raise ValueError(f"Specified size_y {size_y} is not an integer.")

    logger.debug(f"Calculating Kaiser kernel with shape ({size_x}, {size_y}).")

    distance_x = (size_x - 1) / 2
    distance_y = (size_y - 1) / 2
    distance = min(distance_x, distance_y)

    x_vector = np.arange(-distance_x, distance_x + 1)
    y_vector = np.arange(-distance_y, distance_y + 1)

    x_mesh, y_mesh = np.meshgrid(y_vector, x_vector)
    r = np.hypot(x_mesh, y_mesh)
    del x_mesh, y_mesh

    # Kaiser window centralized around x = 0
    kern = iv(1, np.pi * beta * np.sqrt(1 - (r / distance)**2)) / iv(
        1, np.pi * beta)
    kern[np.where(r > distance)] = 0.0

    return images.normalize(kern, normalize)
Exemplo n.º 7
0
def get_kernel_kaiser(size: int,
                      beta: float = 3.5,
                      size_y: Optional[int] = None,
                      beta_y: Optional[float] = None,
                      normalize: str = 'area') -> ndarray:
    """Get a normalized 2D Kaiser kernel.

    Args:
        size: Size of the kernel in pixels.

        beta: Shape parameter. Default: 3.5

        size_y: Size of the kernel in y direction.
            If no value is specified, a quadratic kernel is calculated

        beta_y: Shape parameter in y-direction.
            If no value is specified, a symmetric shape array is calculated

        normalize: Normalize the kernel by given method, see
            :func:`plenpy.utilities.images.normalize()` for available types.
            Default: Normalize to sum one.

    Returns:
        A Kaiser kernel of shape (size, size_y).

    """

    if type(size) is not int:
        raise ValueError(f"Specified size {size} is not an integer.")

    # Set kernel size
    size_x = size

    # If no size_y value has been specified, calculate quadratic kernel
    if size_y is None:
        size_y = size_x
    else:
        if type(size_y) is not int:
            raise ValueError(f"Specified size_y {size_y} is not an integer.")

    logger.debug(f"Calculating Kaiser kernel with shape ({size_x}, {size_y}).")

    # Check beta value and set to optimal, if not defined
    if beta is None:
        logger.debug(
            "No beta value specified for Kaiser kernel. Setting to optimal.")
        beta = 3.5

    beta_x = beta

    # If no beta_y value has been specified, calculate symmetric gauss
    if beta_y is None:
        beta_y = beta_x

    kern_x = np.kaiser(size_x, beta_x)
    kern_y = np.kaiser(size_y, beta_y)

    # Calculate outer product of the 1D kernels
    kern = np.outer(kern_x, kern_y)

    return images.normalize(kern, normalize)
Exemplo n.º 8
0
def get_kernel_gauss(size: int,
                     sigma: Optional[float] = None,
                     size_y: Optional[int] = None,
                     sigma_y: Optional[float] = None,
                     normalize: str = 'area') -> ndarray:
    """Get a normalized 2D Gauss kernel.

    This kernel is not a tensor product kernel, i.e. it is rotationally
    symmetric if the sigma values in x- and y-direction are equal.

    Args:
        size: Size of the kernel in pixels.

        sigma: Standard deviation of the Gauss kernel.
            Default: size/5.0.

        size_y: Size of the kernel in y direction.
            If no value is specified, a quadratic kernel is calculated

        sigma_y: Standard deviation of the Gauss kernel in v-direction.
            If no sigma_y has been specified, a symmetric kernel is calculated.

        normalize: Normalize the kernel by given method, see
            :func:`plenpy.utilities.images.normalize()` for available types.
            Default: Normalize to sum one.

    Returns:
        A gauss kernel of shape (size, size_y) with radii standard deviations
        (sigma, sigma_y).

    """
    if type(size) is not int:
        raise ValueError(f"Specified size {size} is not an integer.")

    # Set kernel size
    size_x = size
    sigma_x = sigma

    # If no size_y value has been specified, calculate quadratic kernel
    if size_y is None:
        size_y = size_x

    else:
        if type(size_y) is not int:
            raise ValueError(f"Specified size_y {size_y} is not an integer.")

    # Set kernel sigma values
    if sigma_x is None and sigma_y is None:
        sigma_x = min(size_x / 5.0, size_y / 5.0)
        sigma_y = sigma_x

    # Check sigma value and set to optimal, if not defined
    elif sigma_x is None:
        logger.debug(
            "No sigma value specified for Gauss kernel. Setting to optimal.")
        sigma_x = size_x / 5.0

    # If no sigma_y value has been specified, calculate symmetric gauss
    elif sigma_y is None:
        sigma_y = sigma_x

    logger.debug(f"Calculating Gauss kernel with shape ({size_x}, {size_y}).")

    # shift kernel zo image center
    mu_x = (size_x - 1) / 2.0
    mu_y = (size_y - 1) / 2.0

    x, y = np.meshgrid(np.arange(0, size_x, 1), np.arange(0, size_y, 1))
    kern = np.exp(-0.5 * (((x - mu_x)**2) / (sigma_x**2) + ((y - mu_y)**2) /
                          (sigma_y**2)))

    return images.normalize(kern.T, normalize)