Python plot - stacked image slices

前端 未结 3 751
北海茫月
北海茫月 2020-12-01 22:19

I have a series of basic 2D images (3 for simplicity for now) and these are related to each other, analogous to frames from a movie:

Within python how may I stack the

相关标签:
3条回答
  • 2020-12-01 22:55

    Here is a completely silly way to accomplish using matplotlib and shear transformations (you probably need to tweak the transform matrix some more so the stacked images look correct):

    import numpy as np
    import matplotlib.pyplot as plt
    
    from scipy.ndimage.interpolation import affine_transform
    
    
    nimages = 4
    img_height, img_width = 512, 512
    bg_val = -1 # Some flag value indicating the background.
    
    # Random test images.
    rs = np.random.RandomState(123)
    img = rs.randn(img_height, img_width)*0.1
    images = [img+(i+1) for i in range(nimages)]
    
    stacked_height = 2*img_height
    stacked_width  = img_width + (nimages-1)*img_width/2
    stacked = np.full((stacked_height, stacked_width), bg_val)
    
    # Affine transform matrix.
    T = np.array([[1,-1],
                  [0, 1]])
    
    for i in range(nimages):
        # The first image will be right most and on the "bottom" of the stack.
        o = (nimages-i-1) * img_width/2
        out = affine_transform(images[i], T, offset=[o,-o],
                               output_shape=stacked.shape, cval=bg_val)
        stacked[out != bg_val] = out[out != bg_val]
    
    plt.imshow(stacked, cmap=plt.cm.viridis)
    plt.show()
    

    0 讨论(0)
  • 2020-12-01 23:04

    As far as I know, matplotlib has no 3D equivalent to imshow that would allow you to draw a 2D array as a plane within 3D axes. However, mayavi seems to have exactly the function you're looking for.

    0 讨论(0)
  • 2020-12-01 23:06

    You can't do this with imshow, but you can with contourf, if that will work for you. It's a bit of a kludge though:

    enter image description here

    from mpl_toolkits.mplot3d import Axes3D
    import numpy as np
    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    
    x = np.linspace(0, 1, 100)
    X, Y = np.meshgrid(x, x)
    Z = np.sin(X)*np.sin(Y)
    
    levels = np.linspace(-1, 1, 40)
    
    ax.contourf(X, Y, .1*np.sin(3*X)*np.sin(5*Y), zdir='z', levels=.1*levels)
    ax.contourf(X, Y, 3+.1*np.sin(5*X)*np.sin(8*Y), zdir='z', levels=3+.1*levels)
    ax.contourf(X, Y, 7+.1*np.sin(7*X)*np.sin(3*Y), zdir='z', levels=7+.1*levels)
    
    ax.legend()
    ax.set_xlim3d(0, 1)
    ax.set_ylim3d(0, 1)
    ax.set_zlim3d(0, 10)
    
    plt.show()
    

    The docs of what's implemented in 3D are here.

    As ali_m suggested, if this won't work for you, if you can imagine it you can do it with VTk/MayaVi.

    0 讨论(0)
提交回复
热议问题