[ITK] SimpleITK optimize memory management for 4d image registration

Cyril Jaudet drcjaudet at gmail.com
Wed Apr 8 12:29:17 EDT 2015


Hi,
a new version of the code using labelstatistic and a better memory
management. idon't suceed to convert image from vtk to itk but the rest is
ok.

Best regards,
Cyril

def CropAndRegister(multi,reference,label):

##################import the image and the node of the
multivolume###############

label=su.PullFromSlicer(label)

multiNode=slicer.util.getNode(multi)

refNode=slicer.util.getNode(reference)

multiImage=multiNode.GetImageData()

N=multiNode.GetNumberOfFrames()

#######"extract image from 4d multivolume to 3d############################

for i in range (N):

im=vtk.vtkImageExtractComponents()

im.SetInputData(multiImage)

im.SetComponents(i)

im.Update()

frame=slicer.modules.volumes.logic().CloneVolume(slicer.mrmlScene,refNode,'frame_'+str(i))

frame.SetAndObserveImageData(im.GetOutput())

del im

del multiNode

del refNode

del multiImage

########## compute the statistic of te image
############################"""""

stats=sitk.LabelStatisticsImageFilter()

stats.Execute(label,label)

Image_size=label.GetSize()

################# crop the image in the ROI
################################"

for i in range(N):

im=su.PullFromSlicer('frame_'+str(i))

im_Crop=sitk.Crop(im,[ stats.GetBoundingBox(1)[0],
stats.GetBoundingBox(1)[2],stats.GetBoundingBox(1)[4]
],[Image_size[0]-1-stats.GetBoundingBox(1)[1],
Image_size[1]-1-stats.GetBoundingBox(1)[3],Image_size[2]-1-stats.GetBoundingBox(1)[5]])


su.PushToSlicer(im_Crop,"frame_crop_"+str(i),1)

del im

del label

##################" register all the image together###################"

im=su.PullFromSlicer('frame_crop_'+str(N-1))

su.PushToSlicer(im,"frame_recal_"+str(N-1),1)

del im

f0=slicer.util.getNode('frame_crop_'+str(N-1))

for f in range(N-1):

f1=slicer.util.getNode('frame_crop_'+str(N-2-f))

parameters = {}

parameters["fixedVolume"] = f0

parameters["movingVolume"] = f1

parameters["useRigid"] = True

#parameters["useScaleSkewVersor3D"]=True

parameters["useAffine"]=True

parameters["useBSpline"]=True

parameters["samplingPercentage"]=0.005

#parameters["initializeTransformMode"] = "useMomentsAlign"

parameters["backgroundFillValue"] = 0

registeredObiNode = slicer.vtkMRMLScalarVolumeNode()

slicer.mrmlScene.AddNode(registeredObiNode)

registeredObiNode.SetName('frame_recal_'+str(N-2-f))

parameters["outputVolume"] = registeredObiNode.GetID()

brainsFit = slicer.modules.brainsfit

cliBrainsFitRigidNode = None

cliBrainsFitRigidNode = slicer.cli.run(brainsFit, None, parameters)

del f1

del f0



2015-03-27 16:46 GMT+01:00 Jaudet Cyril <drcjaudet at gmail.com>:

> Thank You  Bradley. I'll modify the python code and send the new version.
> I think it's take so much memory due to the vtk multi volume and simple
> utk at the same Time.
> Best regards,
> Cyril
>
>
>
> Le 27 mars 2015 à 15:45, Bradley Lowekamp <blowekamp at mail.nih.gov> a
> écrit :
>
> Hello Cyril,
>
>
>
> On Mar 27, 2015, at 10:23 AM, Cyril Jaudet <drcjaudet at gmail.com> wrote:
>
> Thank for you fast reply.
>
> Image size are 512x512x224x22 voxels...
>
>
> OK so your data is 1.2GB? maybe 2.4GB if short? or 4.8 if converted to
> float?
>
>
> 1) This is a good idea but i don't know how to use SimpleITK crop image
> filter with a bounding box as input?
>
>
> The format of the bounding box is defined here:
>
> http://www.itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1LabelStatisticsImageFilter.html#ae117448f17ba708a7364e90bfaaa44af
>
> Should be straight forward enough to convert that info to the parameters
> for CropImageFilter or ExtractImageFilter.
>
>
> 2) You're right but i don't know how delete the image i don't need any
> more.
>
>
> For SimpleITK just use 'del':
>
> https://docs.python.org/2/tutorial/datastructures.html?highlight=del#the-del-statement
>
>
> 3)Indeed the problem come from a mixing of vtk image to go from 4d to 3d,
> simple itk to crop them and vtk to use slicer module to register them.
>
>
> Maybe you could use SimpleITK registration to avoid the pushing to slicer
> and evoking the slicer module, if your registration problem is simple
> enough?
>
>
> Do you have a clue to transform the vtk image in simple itk format? In the
> forum  a convert option suggested was to pass by numpy but i think it's
> really an indirect/ no efficient way.
>
>
> I would think going through numpy would be better than pushing into Slicer
> MRML. But those are currently the two ways to do it. I have been hoping
> some one would implement a more efficient way.
>
>
> Also i would like to keep the convertion to simple itk format before
> calling the slicer module beacause it allow to use another itk filter for
> denoising or change format purpose.
>
> Thank for your help,
> Cyril
>
>
>
>
> 2015-03-27 15:05 GMT+01:00 Bradley Lowekamp <blowekamp at mail.nih.gov>:
>
>> Hello,
>>
>> It's a bit hard to follow the code with how you have formatted. How big
>> are your images?
>>
>> 1) Consider using LabelStatisticImageFilter to compute the bounding box.
>>
>> 2) You have a lot of Slicer, VTK, and SimpleITK code going on here.
>> Frequently with Python code the expense of keeping images on the can build
>> up, so sometimes you need to explicitly "del" them when finished. I don't
>> see too many extras going on here however.
>>
>> 3) I think you need to narrow down the memory problem. You are pushing a
>> lot of images to slicer and not removing them. I am not sure if this is
>> really an SimpleITK usage issue or a Slicer MRML usage issue.
>>
>> Hope that helps,
>> Brad
>>
>> On Mar 27, 2015, at 9:52 AM, Cyril Jaudet <drcjaudet at gmail.com> wrote:
>>
>> Hello itk community,
>>
>> i use a python code to extract, crop, register and export 4d image. This
>> code interact with 3Dslicer.
>> Do you know how optimize the memory management because it use more then
>> 15Gb of memory when running ?
>>
>> Thank you,
>>
>>
>>  ------------------------------
>>
>>
>> *Cyril Jaudet *Medical physicist, phd
>>
>>
>> cyril.jaudet at uzbrussel.be
>>  ------------------------------
>>
>>
>>
>>
>>
>>
>> def CropAndRegister(multi,reference,label):
>>     multiNode=slicer.util.getNode(multi)
>>     refNode=slicer.util.getNode(reference)
>>     multiImage=multiNode.GetImageData()
>>     N=multiNode.GetNumberOfFrames()
>>     for i in range (N):    #extract image
>>         im=vtk.vtkImageExtractComponents()
>>         im.SetInputData(multiImage)
>>         im.SetComponents(i)
>>         im.Update()
>>
>> frame=slicer.modules.volumes.logic().CloneVolume(slicer.mrmlScene,refNode,'frame_'+str(i))
>>         frame.SetAndObserveImageData(im.GetOutput())
>>     label=su.PullFromSlicer(label)
>>     Image_size=label.GetSize()  #get distance between the label map and
>> the image border
>>     xl_min=Image_size[0]
>>     xl_max=0
>>     yl_min=Image_size[1]
>>     yl_max=0
>>     zl_min=Image_size[2]
>>     zl_max=0
>>     for i in range(Image_size[0]):
>>         for j in range(Image_size[1]):
>>             for k in range(Image_size[2]):
>>                 if (label.GetPixel(i,j,k)!=0):
>>                     if( xl_min>i):
>>                         xl_min=i
>>                     if( xl_max<i):
>>                         xl_max=i
>>                     if( yl_min>j):
>>                         yl_min=j
>>                     if( yl_max<j):
>>                         yl_max=j
>>                     if( zl_min>k):
>>                         zl_min=k
>>                     if( zl_max<k):
>>                         zl_max=k
>>     for i in range(N):                  #crop the image
>>         im=su.PullFromSlicer('frame_'+str(i))
>>         im_Crop=sitk.Crop(im,[ xl_min,yl_min,zl_min
>> ],[Image_size[0]-xl_max, Image_size[1]-yl_max, Image_size[2]-zl_max ])
>>         su.PushToSlicer(im_Crop,"frame_crop_"+str(i),1)
>>     im=su.PullFromSlicer('frame_crop_'+str(N-1)) #register
>>     su.PushToSlicer(im,"frame_recal_"+str(N-1),1)
>>     for f in range(N-1):
>>         f0=slicer.util.getNode('frame_crop_'+str(N-1-f))
>>         f1=slicer.util.getNode('frame_crop_'+str(N-2-f))
>>         parameters = {}
>>         parameters["fixedVolume"] = f0
>>         parameters["movingVolume"] = f1
>>         #parameters["useRigid"] = True
>>     parameters["useScaleSkewVersor3D"]=True
>>         parameters["useAffine"]=True
>>     parameters["useBSpline"]=True
>>       parameters["samplingPercentage"]=0.1
>>         #parameters["initializeTransformMode"] = "useMomentsAlign"
>>         parameters["backgroundFillValue"] = 0
>>         registeredObiNode = slicer.vtkMRMLScalarVolumeNode()
>>         slicer.mrmlScene.AddNode(registeredObiNode)
>>
>> registeredObiNode.SetName('frame_recal_'+str(multiNode.GetNumberOfFrames()-2-f))
>>         parameters["outputVolume"] = registeredObiNode.GetID()
>>         brainsFit = slicer.modules.brainsfit
>>         cliBrainsFitRigidNode = None
>>         cliBrainsFitRigidNode = slicer.cli.run(brainsFit, None,
>> parameters)
>> _______________________________________________
>> Community mailing list
>> Community at itk.org
>> http://public.kitware.com/mailman/listinfo/community
>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/community/attachments/20150408/e2385b4f/attachment.html>


More information about the Community mailing list