File: visual_test.py

package info (click to toggle)
skimage 0.26.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 32,720 kB
  • sloc: python: 61,600; cpp: 2,592; ansic: 1,591; xml: 1,342; javascript: 1,267; makefile: 135; sh: 16
file content (105 lines) | stat: -rw-r--r-- 2,833 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"""
Script to show the results of the two marching cubes algorithms on different
data.
"""

import time
from contextlib import contextmanager

import numpy as np

from skimage.measure import marching_cubes_classic, marching_cubes_lewiner
from skimage.draw import ellipsoid


def main(select=3, **kwargs):
    """Script main function.

    select: int
        1: Medical data
        2: Blocky data, different every time
        3: Two donuts
        4: Ellipsoid

    """
    import visvis as vv

    # Create test volume
    if select == 1:
        vol = vv.volread('stent')
        isovalue = kwargs.pop('level', 800)
    elif select == 2:
        vol = vv.aVolume(20, 128)
        isovalue = kwargs.pop('level', 0.2)
    elif select == 3:
        with timer('computing donuts'):
            vol = donuts()
        isovalue = kwargs.pop('level', 0.0)
        # Uncommenting the line below will yield different results for
        # classic MC
        # vol *= -1
    elif select == 4:
        vol = ellipsoid(4, 3, 2, levelset=True)
        isovalue = kwargs.pop('level', 0.0)
    else:
        raise ValueError('invalid selection')

    # Get surface meshes
    with timer('finding surface lewiner'):
        vertices1, faces1 = marching_cubes_lewiner(vol, isovalue, **kwargs)[:2]

    with timer('finding surface classic'):
        vertices2, faces2 = marching_cubes_classic(vol, isovalue, **kwargs)

    # Show
    vv.figure(1)
    vv.clf()
    a1 = vv.subplot(121)
    vv.title('Lewiner')
    m1 = vv.mesh(np.fliplr(vertices1), faces1)
    a2 = vv.subplot(122)
    vv.title('Classic')
    m2 = vv.mesh(np.fliplr(vertices2), faces2)
    a1.camera = a2.camera

    # visvis uses right-hand rule, gradient_direction param uses left-hand rule
    m1.cullFaces = m2.cullFaces = 'front'  # None, front or back

    vv.use().Run()


def donuts():
    """Return volume of two donuts based on a formula by Thomas Lewiner."""
    n = 48
    a = 2.5 / n * 8.0
    b = -1.25 * 8.0
    c = 16.0 - 1.85 * 1.85
    d = 64.0

    i = np.arange(n, dtype=int)
    ia_plus_b = i * a + b
    ia_plus_b_square = ia_plus_b**2
    z = ia_plus_b_square[:, np.newaxis, np.newaxis]
    zc = z + c

    y1 = ((ia_plus_b - 2) ** 2)[np.newaxis, :, np.newaxis]
    y2 = ((ia_plus_b + 2) ** 2)[np.newaxis, :, np.newaxis]

    x = ia_plus_b_square[np.newaxis, np.newaxis, :]
    x1 = (x + y1 + zc) ** 2
    x2 = (x + y2 + zc) ** 2

    return ((x1 - d * (x + y1)) * (x2 - d * (z + y2))) + 1025


@contextmanager
def timer(message):
    """Context manager for timing execution speed of body."""
    print(message, end=' ')
    start = time.time()
    yield
    print(f'took {1000 * (time.time() - start):1.0f} ms')


if __name__ == '__main__':
    main()