3

私はPythonの新規ユーザーであり、簡単な画像処理を行いたいと思っています。基本的に、動的な医用画像を作成します。これは、3D配列として保存したいさまざまな時点での一連の2D画像です。スキャン技術の性質上、特定のイメージングフレーム中に患者の動きが時折発生し、データが使用できなくなる可能性があります。そのようなフレームを削除して、配列を再キャストしたいと思います-新しい次元(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()
4

1 に答える 1

4

あなたの質問に対する簡単な答えはusenumpy.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配列は、メモリ内で連続している必要があります。したがって、これにより毎回新しいコピーが作成されます(古いコピーが削除されます)。これは比較的遅く、アレイを格納するために必要な2倍の空きメモリスペースが必要です。

あなたの場合、2D配列のPythonリストを保存してみませんか?そうすれば、問題なく、不要なスライスをポップできます。後で3D配列として必要な場合は、を使用numpy.dstackして作成します。

もちろん、3D処理を行う必要がある場合は、3D配列が必要になります。したがって、別のアプローチは、「不良」指標のリストを保存し、最後にを使用してそれらを削除することnumpy.deleteです(削除される項目はリストであるため、「不良」指標のリストを渡すだけで済みます)。


ちなみに、画像を更新する方法は非常に遅くなります。

たくさんの画像を作成しているので、それぞれが毎回再描画され、続行すると更新が非常に遅くなります。

im.set_data(next_slice)毎回新しい画像を作成するのではなく 、画像のデータ()を設定することをお勧めします。

さらに良いことに、ブリッティングを使用しますが、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()
于 2012-11-18T17:56:01.957 に答える