Beispiel #1
0
def test_level_4_discarding_level_1():
    # Test that level >= 2 highpasses are identical
    Yl1, Yh1 = dtwavexfm3(ellipsoid, 4, discard_level_1=True)
    Yl2, Yh2 = dtwavexfm3(ellipsoid, 4, discard_level_1=False)

    assert np.abs(Yl1-Yl2).max() < TOLERANCE
    for a, b in zip(Yh1[1:], Yh2[1:]):
        assert np.abs(a-b).max() < TOLERANCE
Beispiel #2
0
def test_level_4_discarding_level_1():
    # Test that level >= 2 highpasses are identical
    Yl1, Yh1 = dtwavexfm3(ellipsoid, 4, discard_level_1=True)
    Yl2, Yh2 = dtwavexfm3(ellipsoid, 4, discard_level_1=False)

    assert np.abs(Yl1 - Yl2).max() < TOLERANCE
    for a, b in zip(Yh1[1:], Yh2[1:]):
        assert np.abs(a - b).max() < TOLERANCE
Beispiel #3
0
def test_integer_perfect_recon():
    # Check that an integer input is correctly coerced into a floating point
    # array and reconstructed
    A = (np.random.random((4,4,4)) * 5).astype(np.int32)
    Yl, Yh = dtwavexfm3(A)
    B = dtwaveifm3(Yl, Yh)
    assert np.max(np.abs(A-B)) < 1e-12
Beispiel #4
0
def test_integer_perfect_recon():
    # Check that an integer input is correctly coerced into a floating point
    # array and reconstructed
    A = (np.random.random((4, 4, 4)) * 5).astype(np.int32)
    Yl, Yh = dtwavexfm3(A)
    B = dtwaveifm3(Yl, Yh)
    assert np.max(np.abs(A - B)) < 1e-12
Beispiel #5
0
def test_simple_level_4_recon_ext_mode_4():
    # Test for perfect reconstruction with 3 levels
    crop_ellipsoid = ellipsoid[:62, :54, :58]
    Yl, Yh = dtwavexfm3(crop_ellipsoid, 4, ext_mode=4)
    ellipsoid_recon = dtwaveifm3(Yl, Yh)
    assert crop_ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(crop_ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #6
0
def test_simple_level_4_recon_ext_mode_4():
    # Test for perfect reconstruction with 3 levels
    crop_ellipsoid = ellipsoid[:62,:54,:58]
    Yl, Yh = dtwavexfm3(crop_ellipsoid, 4, ext_mode=4)
    ellipsoid_recon = dtwaveifm3(Yl, Yh)
    assert crop_ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(crop_ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #7
0
def test_simple_level_4_recon_custom_wavelets():
    # Test for perfect reconstruction with 3 levels
    b = biort('legall')
    q = qshift('qshift_06')
    Yl, Yh = dtwavexfm3(ellipsoid, 4, biort=b, qshift=q)
    ellipsoid_recon = dtwaveifm3(Yl, Yh, biort=b, qshift=q)
    assert ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #8
0
def test_float32_recon():
    # Check that an float32 input is correctly output as float32
    Yl, Yh = dtwavexfm3(ellipsoid.astype(np.float32))
    assert np.issubsctype(Yl.dtype, np.float32)
    assert np.all(list(np.issubsctype(x.dtype, np.complex64) for x in Yh))

    recon = dtwaveifm3(Yl, Yh)
    assert np.issubsctype(recon.dtype, np.float32)
Beispiel #9
0
def test_level_4_recon_discarding_level_1():
    # Test for non-perfect but reasonable reconstruction
    Yl, Yh = dtwavexfm3(ellipsoid, 4, discard_level_1=True)
    ellipsoid_recon = dtwaveifm3(Yl, Yh)
    assert ellipsoid.size == ellipsoid_recon.size

    # Check that we mostly reconstruct correctly
    assert np.median(np.abs(ellipsoid - ellipsoid_recon)[:]) < 1e-3
Beispiel #10
0
def test_float32_recon():
    # Check that an float32 input is correctly output as float32
    Yl, Yh = dtwavexfm3(ellipsoid.astype(np.float32))
    assert np.issubsctype(Yl.dtype, np.float32)
    assert np.all(list(np.issubsctype(x.dtype, np.complex64) for x in Yh))

    recon = dtwaveifm3(Yl, Yh)
    assert np.issubsctype(recon.dtype, np.float32)
Beispiel #11
0
def test_level_4_recon_discarding_level_1():
    # Test for non-perfect but reasonable reconstruction
    Yl, Yh = dtwavexfm3(ellipsoid, 4, discard_level_1=True)
    ellipsoid_recon = dtwaveifm3(Yl, Yh)
    assert ellipsoid.size == ellipsoid_recon.size

    # Check that we mostly reconstruct correctly
    assert np.median(np.abs(ellipsoid - ellipsoid_recon)[:]) < 1e-3
Beispiel #12
0
def test_simple_level_4_recon_custom_wavelets():
    # Test for perfect reconstruction with 3 levels
    b = biort('legall')
    q = qshift('qshift_06')
    Yl, Yh = dtwavexfm3(ellipsoid, 4, biort=b, qshift=q)
    ellipsoid_recon = dtwaveifm3(Yl, Yh, biort=b, qshift=q)
    assert ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #13
0
def test_simple_level_1_recon_haar():
    # Test for perfect reconstruction with 1 level and Haar wavelets

    # Form Haar wavelets
    h0 = np.array((1.0, 1.0))
    g0 = h0
    h0 = h0 / np.sum(h0)
    g0 = g0 / np.sum(g0)
    h1 = g0 * np.cumprod(-np.ones_like(g0))
    g1 = -h0 * np.cumprod(-np.ones_like(h0))

    haar = (h0, g0, h1, g1)

    Yl, Yh = dtwavexfm3(ellipsoid, 1, biort=haar)
    ellipsoid_recon = dtwaveifm3(Yl, Yh, biort=haar)
    assert ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #14
0
def test_simple_level_1_recon_haar():
    # Test for perfect reconstruction with 1 level and Haar wavelets

    # Form Haar wavelets
    h0 = np.array((1.0, 1.0))
    g0 = h0
    h0 = h0 / np.sum(h0)
    g0 = g0 / np.sum(g0)
    h1 = g0 * np.cumprod(-np.ones_like(g0))
    g1 = -h0 * np.cumprod(-np.ones_like(h0))

    haar = (h0, g0, h1, g1)

    Yl, Yh = dtwavexfm3(ellipsoid, 1, biort=haar)
    ellipsoid_recon = dtwaveifm3(Yl, Yh, biort=haar)
    assert ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #15
0
def test_simple_level_4_xfm():
    # Just tests that the transform broadly works and gives expected size output
    Yl, Yh = dtwavexfm3(ellipsoid, 4)
    assert Yl.shape == (GRID_SIZE >> 3, GRID_SIZE >> 3, GRID_SIZE >> 3)
    assert len(Yh) == 4
Beispiel #16
0
def test_simple_level_4_xfm_ext_mode_4():
    # Just tests that the transform broadly works and gives expected size output
    crop_ellipsoid = ellipsoid[:62, :54, :58]
    Yl, Yh = dtwavexfm3(crop_ellipsoid, 4, ext_mode=4)
    assert len(Yh) == 4
Beispiel #17
0
def test_integer_input():
    # Check that an integer input is correctly coerced into a floating point
    # array
    Yl, Yh = dtwavexfm3(np.ones((4, 4, 4), dtype=np.int))
    assert np.any(Yl != 0)
Beispiel #18
0
def test_simple_level_4_xfm():
    # Just tests that the transform broadly works and gives expected size output
    Yl, Yh = dtwavexfm3(ellipsoid, 4)
    assert Yl.shape == (GRID_SIZE>>3,GRID_SIZE>>3,GRID_SIZE>>3)
    assert len(Yh) == 4
def main():
    GRID_SIZE = 128
    SPHERE_RAD = int(0.45 * GRID_SIZE) + 0.5

    # Compute an image of the sphere
    grid = np.arange(-(GRID_SIZE>>1), GRID_SIZE>>1)
    X, Y, Z = np.meshgrid(grid, grid, grid)
    r = np.sqrt(X*X + Y*Y + Z*Z)
    sphere = (0.5 + np.clip(SPHERE_RAD-r, -0.5, 0.5)).astype(np.float32)

    # Specify number of levels and wavelet family to use
    nlevels = 2
    b = biort('near_sym_a')
    q = qshift('qshift_a')

    # Form the DT-CWT of the sphere. We use discard_level_1 since we're
    # uninterested in the inverse transform and this saves us some memory.
    Yl, Yh = dtwavexfm3(sphere, nlevels, b, q, discard_level_1=False)

    # Plot maxima
    figure(figsize=(8,8))

    ax = gcf().add_subplot(1,1,1, projection='3d')
    ax.set_aspect('equal')
    ax.view_init(35, 75)

    # Plot unit sphere +ve octant
    thetas = np.linspace(0, np.pi/2, 10)
    phis = np.linspace(0, np.pi/2, 10)


    tris = []
    rad = 0.99 # so that points plotted latter are not z-clipped
    for t1, t2 in zip(thetas[:-1], thetas[1:]):
        for p1, p2 in zip(phis[:-1], phis[1:]):
            tris.append([
                sphere_to_xyz(rad, t1, p1),
                sphere_to_xyz(rad, t1, p2),
                sphere_to_xyz(rad, t2, p2),
                sphere_to_xyz(rad, t2, p1),
                ])

    sphere = Poly3DCollection(tris, facecolor='w', edgecolor=(0.6,0.6,0.6))
    ax.add_collection3d(sphere)

    locs = []
    scale = 1.1
    for idx in range(Yh[-1].shape[3]):
        Z = Yh[-1][:,:,:,idx]
        C = np.abs(Z)
        max_loc = np.asarray(np.unravel_index(np.argmax(C), C.shape)) - np.asarray(C.shape)*0.5
        max_loc /= np.sqrt(np.sum(max_loc * max_loc))

        # Only record directions in the +ve octant (or those from the -ve quadrant
        # which can be flipped).
        if np.all(np.sign(max_loc) == 1):
            locs.append(max_loc)
            ax.text(max_loc[0] * scale, max_loc[1] * scale, max_loc[2] * scale, str(idx+1))
        elif np.all(np.sign(max_loc) == -1):
            locs.append(-max_loc)
            ax.text(-max_loc[0] * scale, -max_loc[1] * scale, -max_loc[2] * scale, str(idx+1))

            # Plot all directions as a scatter plot
    locs = np.asarray(locs)
    ax.scatter(locs[:,0], locs[:,1], locs[:,2], c=np.arange(locs.shape[0]))

    w = 1.1
    ax.auto_scale_xyz([0, w], [0, w], [0, w])

    legend()
    title('3D DT-CWT subband directions for +ve hemisphere quadrant')
    tight_layout()

    show()
Beispiel #20
0
def test_integer_input():
    # Check that an integer input is correctly coerced into a floating point
    # array
    Yl, Yh = dtwavexfm3(np.ones((4,4,4), dtype=np.int))
    assert np.any(Yl != 0)
Beispiel #21
0
def test_simple_level_4_recon():
    # Test for perfect reconstruction with 3 levels
    Yl, Yh = dtwavexfm3(ellipsoid, 4)
    ellipsoid_recon = dtwaveifm3(Yl, Yh)
    assert ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #22
0
def test_simple_level_4_recon():
    # Test for perfect reconstruction with 3 levels
    Yl, Yh = dtwavexfm3(ellipsoid, 4)
    ellipsoid_recon = dtwaveifm3(Yl, Yh)
    assert ellipsoid.size == ellipsoid_recon.size
    assert np.max(np.abs(ellipsoid - ellipsoid_recon)) < TOLERANCE
Beispiel #23
0
def test_simple_level_4_xfm_ext_mode_8():
    # Just tests that the transform broadly works and gives expected size output
    crop_ellipsoid = ellipsoid[:62,:58,:54]
    Yl, Yh = dtwavexfm3(crop_ellipsoid, 4, ext_mode=8)
    assert len(Yh) == 4
Beispiel #24
0
def main():
    GRID_SIZE = 128
    SPHERE_RAD = int(0.45 * GRID_SIZE) + 0.5

    # Compute an image of the sphere
    grid = np.arange(-(GRID_SIZE >> 1), GRID_SIZE >> 1)
    X, Y, Z = np.meshgrid(grid, grid, grid)
    r = np.sqrt(X * X + Y * Y + Z * Z)
    sphere = (0.5 + np.clip(SPHERE_RAD - r, -0.5, 0.5)).astype(np.float32)

    # Specify number of levels and wavelet family to use
    nlevels = 2
    b = biort('near_sym_a')
    q = qshift('qshift_a')

    # Form the DT-CWT of the sphere. We use discard_level_1 since we're
    # uninterested in the inverse transform and this saves us some memory.
    Yl, Yh = dtwavexfm3(sphere, nlevels, b, q, discard_level_1=False)

    # Plot maxima
    figure(figsize=(8, 8))

    ax = gcf().add_subplot(1, 1, 1, projection='3d')
    ax.set_aspect('equal')
    ax.view_init(35, 75)

    # Plot unit sphere +ve octant
    thetas = np.linspace(0, np.pi / 2, 10)
    phis = np.linspace(0, np.pi / 2, 10)

    tris = []
    rad = 0.99  # so that points plotted latter are not z-clipped
    for t1, t2 in zip(thetas[:-1], thetas[1:]):
        for p1, p2 in zip(phis[:-1], phis[1:]):
            tris.append([
                sphere_to_xyz(rad, t1, p1),
                sphere_to_xyz(rad, t1, p2),
                sphere_to_xyz(rad, t2, p2),
                sphere_to_xyz(rad, t2, p1),
            ])

    sphere = Poly3DCollection(tris, facecolor='w', edgecolor=(0.6, 0.6, 0.6))
    ax.add_collection3d(sphere)

    locs = []
    scale = 1.1
    for idx in range(Yh[-1].shape[3]):
        Z = Yh[-1][:, :, :, idx]
        C = np.abs(Z)
        max_loc = np.asarray(np.unravel_index(
            np.argmax(C), C.shape)) - np.asarray(C.shape) * 0.5
        max_loc /= np.sqrt(np.sum(max_loc * max_loc))

        # Only record directions in the +ve octant (or those from the -ve quadrant
        # which can be flipped).
        if np.all(np.sign(max_loc) == 1):
            locs.append(max_loc)
            ax.text(max_loc[0] * scale, max_loc[1] * scale, max_loc[2] * scale,
                    str(idx + 1))
        elif np.all(np.sign(max_loc) == -1):
            locs.append(-max_loc)
            ax.text(-max_loc[0] * scale, -max_loc[1] * scale,
                    -max_loc[2] * scale, str(idx + 1))

            # Plot all directions as a scatter plot
    locs = np.asarray(locs)
    ax.scatter(locs[:, 0], locs[:, 1], locs[:, 2], c=np.arange(locs.shape[0]))

    w = 1.1
    ax.auto_scale_xyz([0, w], [0, w], [0, w])

    legend()
    title('3D DT-CWT subband directions for +ve hemisphere quadrant')
    tight_layout()

    show()