python - 从 3d 数组中删除图像帧

标签 python image numpy matplotlib dicom

我是一个 Python 新手,想做一些简单的图像处理。本质上,我将拥有动态医学图像 - 一系列不同时间点的 2D 图像,我想将其存储为 3D 阵列。由于扫描技术的性质,在某些成像帧期间可能偶尔会有患者运动,这使得数据无法使用。我想删除这些帧并重铸数组 - 新维度(n-1、256、256)。删除框架后,我想更新图像显示。实现这一目标的最佳方式是什么?这是我目前的框架代码:

import dicom
import numpy as np
import pylab 
from matplotlib.widgets import Slider, Button

ds = dicom.read_file("/home/moadeep/Dropbox/FS1.dcm")
#data = ds.pixel_array
data = np.random.rand(16,256,256)
nframes = data.shape[0]

ax = pylab.subplot(111)
pylab.subplots_adjust(left=0.25, bottom=0.25)

frame = 0
l = pylab.imshow(data[frame,:,:]) #shows 1024x256 imagge, i.e. 0th frame*

axcolor = 'lightgoldenrodyellow'
axframe = pylab.axes([0.35, 0.1, 0.5, 0.03], axisbg=axcolor)

#add slider to scroll image frames
sframe = Slider(axframe, 'Frame', 0, nframes, valinit=0,valfmt='%1d'+'/'+str(nframes))

ax_delete = pylab.axes([0.8,0.025,0.1,0.04], axisbg=axcolor)

#add slider to scroll image frames

#Delete button to delete frame from data set
bDelete = Button(ax_delete, 'Delete')

def update(val):
    frame = np.around(sframe.val)
    pylab.subplot(111)
    pylab.subplots_adjust(left=0.25, bottom=0.25)
    pylab.imshow(data[frame,:,:])

sframe.on_changed(update)

pylab.gray()
pylab.show()

最佳答案

对您的问题的简短回答是使用 numpy.delete。例如

import numpy as np
data = np.arange(1000).reshape((10,10,10))

# Delete the third slice along the first axis 
# (note that you can delete multiple slices at once)
data = np.delete(data, [2], axis=0)

print data.shape

但是,如果您要多次删除单个切片,这是一种糟糕的方法。

较长的答案是避免每次要删除切片时都这样做。

Numpy 数组在内存中必须是连续的。因此,每次都会创建一个新副本(并删除旧副本)。这将相对较慢,并且需要您拥有存储数组所需的两倍的可用内存空间。

在您的情况下,为什么不存储二维数组的 Python 列表?这样你就可以毫无问题地弹出你不想要的切片。如果您之后需要它作为 3D 数组,只需使用 numpy.dstack 来创建它。

当然,如果需要做3D处理,就需要3D数组。因此,另一种方法是存储“坏”指标列表,并在最后使用 numpy.delete 删除它们(注意要删除的项目是一个列表,因此您可以直接传入你的“坏”指标列表)。


附带说明一下,您更新图像的方式会非常慢。

您正在创建大量图像,因此每次都会重新绘制每张图像,并且随着您的继续,更新会变得非常缓慢。

最好设置图像的数据 (im.set_data(next_slice)) 而不是每次都创建一个新图像。

更好的是,使用 blitting,但是对于 matplotlib 中的图像数据,由于 matplotlib 的图像重新缩放速度较慢,因此它不如其他类型的绘图那么有利。

举个简单的例子:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

def main():
    # Set up 3D coordinates from -10 to 10 over a 200x100x100 "open" grid
    x, y, z = np.ogrid[-10:10:200j, -10:10:100j, -10:10:100j]

    # Generate a cube of interesting data
    data= np.sin(x*y*z) / (x*y*z)

    # Visualize it
    viewer = VolumeViewer(data)
    viewer.show()

class VolumeViewer(object):
    def __init__(self, data):
        self.data = data
        self.nframes = self.data.shape[0]

        # Setup the axes.
        self.fig, self.ax = plt.subplots()
        self.slider_ax = self.fig.add_axes([0.2, 0.03, 0.65, 0.03])

        # Make the slider
        self.slider = Slider(self.slider_ax, 'Frame', 1, self.nframes, 
                            valinit=1, valfmt='%1d/{}'.format(self.nframes))
        self.slider.on_changed(self.update)

        # Plot the first slice of the image
        self.im = self.ax.imshow(data[0,:,:])

    def update(self, value):
        frame = int(np.round(value - 1))

        # Update the image data
        dat = self.data[frame,:,:]
        self.im.set_data(dat)

        # Reset the image scaling bounds (this may not be necessary for you)
        self.im.set_clim([dat.min(), dat.max()])

        # Redraw the plot
        self.fig.canvas.draw()

    def show(self):
        plt.show()

if __name__ == '__main__':
    main()

关于python - 从 3d 数组中删除图像帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13440654/

相关文章:

c# - 从剪贴板复制增强型图元文件并将其另存为图像

python - 在 Python 中使用 for 循环垂直翻转图像

swift - 关于线程 1 : Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

python - 有效地将阈值函数应用于 SciPy 稀疏 csr_matrix

python - 在 pandas 中进行几乎不完整的数据透视表操作

python - 如何在发布请求中使用特殊字符(重音符号)

python - 无法成功将 stdout 从 Popen 重定向到临时文件

python - 对 django 模型的对象引用 - 缺少 "object"

python - 更改python中函数的默认参数

python - Numpy 截断?