[Rtk-users] Help with CudaForwardProjectionImageFilter
Rahman, Obaid
rahmano at ornl.gov
Thu Apr 25 02:59:39 CEST 2024
Hello all,
I am getting “out of memory” error when I run CudaForwardProjectionImageFilter.
Please refer to the attached screenshot.
These are the array sizes with which I get the error:
Projection size: (slice/row, view, column)=(1456,145,1840)
Recon size: (z, y, x)=(1264, 1356, 1356)
When I increase the voxel size to twice i.e. Recon size: (z, y, x)=(632, 678, 678), it works fine.
Maybe I’m not being very efficient with the memory?
If anyone has suggestion to make it more memory efficient, please let me know.
Thanks.
Best,
Obaid
Here’s what I’m doing:
def rtk_projection(recon_arrar, proj_params, miscalib, vol_params, return_itk=False, return_RVC=True):
'''
inputs:
recon_arrar: image numpy array (ZXY format is expected)
proj_params: projection parameter dictionary
miscalib: miscalibation parameter dictionary
vol_params: image volume parameter dictionary
return_itk: True if itk image is expected, False if a numpy array is expected
output:
itk image (c,r,v format internally) or image numpy array (r,v,c format) of projection data
'''
ImageType = itk.Image[itk.F,3]; CudaImageType = itk.CudaImage[itk.F,3]
# Convert the recon to itk format
###########################################################################
# proj_data is in (z,x,y); rtk requires numpy array in (x,z,y)
recon_arrar = np.transpose(recon_arrar, [1,0,2]).astype('float32') # now in (x,z,y)
recon_shape = recon_arrar.shape
recon_arrar = itk.GetImageFromArray(recon_arrar) # internally img has format (y,z,x)
# Center the image around 0 which is the default center of rotation
recon_arrar.SetOrigin([-0.5*(recon_arrar.GetLargestPossibleRegion().GetSize()[0]-1)*recon_arrar.GetSpacing()[0],
-0.5*(recon_arrar.GetLargestPossibleRegion().GetSize()[1]-1)*recon_arrar.GetSpacing()[1],
-0.5*(recon_arrar.GetLargestPossibleRegion().GetSize()[2]-1)*recon_arrar.GetSpacing()[2]])
# Graft the projections to an itk::CudaImage
###########################################################################
vol_xy = float(vol_params['vox_xy']); vol_z = float(vol_params['vox_z'])
rtk_recon = CudaImageType.New()# img will have format crv
rtk_recon.SetPixelContainer(recon_arrar.GetPixelContainer()) # img has format crv
rtk_recon.SetLargestPossibleRegion(recon_arrar.GetLargestPossibleRegion())
rtk_recon.SetBufferedRegion(recon_arrar.GetBufferedRegion())
rtk_recon.SetRequestedRegion(recon_arrar.GetRequestedRegion())
rtk_recon.SetSpacing([vol_xy, vol_z, vol_xy]) # spacing for xzy
rtk_recon.SetOrigin([-0.5*(recon_shape[2]-1)*vol_xy, # origin for x direction
-0.5*(recon_shape[1]-1)*vol_z, # origin for z direction
-0.5*(recon_shape[0]-1)*vol_xy]) # origin for y direction
# print('GPU recon:', rtk_recon)
del recon_arrar
###########################################################################
# Defines the RTK geometry object
geometry = rtk.ThreeDCircularProjectionGeometry.New()
for i in range(len(proj_params['angles'])):
angle_deg = proj_params['angles'][i]*180/np.pi # angle in degree
geometry.AddProjection(proj_params['cone_params']['src_orig'],
proj_params['cone_params']['src_orig']+proj_params['cone_params']['orig_det'],
angle_deg, miscalib['delta_u'], miscalib['delta_v'])
# define some parameters (to make code more readable)
det_pix_x = proj_params['cone_params']['pix_x'] # row direction pixel size
det_pix_y = proj_params['cone_params']['pix_y'] # channel direction pixel size
proj_shape = [int(proj_params['dims'][0]), int(proj_params['dims'][1]), int(proj_params['dims'][2])] # r,v,c
###########################################################################
# define a zero projection (GPU)
constantImageSource = rtk.ConstantImageSource[CudaImageType].New()
constantImageSource.SetSpacing( [det_pix_y, det_pix_x, 1.] ) # c,r,v
constantImageSource.SetSize( [proj_shape[2], proj_shape[0], proj_shape[1]] ) # c,r,v
constantImageSource.SetOrigin([ -0.5*(proj_shape[2]-1)*det_pix_y, # origin for channel direction
-0.5*(proj_shape[0]-1)*det_pix_x, # origin for row direction
-0.5*(proj_shape[1]-1)*1]) # origin for view direction (will be ignored anyway)
constantImageSource.SetConstant(0.)
###########################################################################
# forward project the recon to fill out the zero projection image
ForwardProj = rtk.CudaForwardProjectionImageFilter[CudaImageType].New()
ForwardProj.SetGeometry( geometry )
ForwardProj.SetInput(0, constantImageSource.GetOutput()) # projection image
ForwardProj.SetInput(1, cpu2gpu(rtk_recon)) # recon volume
ForwardProj.SetStepSize(float(vol_params['vox_xy'])/4) # step size along the ray (default is 1mm)
ForwardProj.Update()
###########################################################################
# graft the projection to CPU / extract the array
rtk_reprojection = gpu2cpu(ForwardProj.GetOutput()) # array inside the image has c,r,v format
if return_itk:
return rtk_reprojection # array inside the image has c,r,v format
else:
rtk_reprojection = itk.GetArrayViewFromImage(rtk_reprojection) # now v,r,c format
if return_RVC:
rtk_reprojection = np.transpose(rtk_reprojection, [1,0,2]) # r,v,c format to match Astra projection
return rtk_reprojection # numpy array (r,v,c)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.creatis.insa-lyon.fr/pipermail/rtk-users/attachments/20240425/a18acb74/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Screenshot 2024-04-24 at 8.34.20?PM.png
Type: image/png
Size: 175206 bytes
Desc: not available
URL: <http://www.creatis.insa-lyon.fr/pipermail/rtk-users/attachments/20240425/a18acb74/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 1611 bytes
Desc: not available
URL: <http://www.creatis.insa-lyon.fr/pipermail/rtk-users/attachments/20240425/a18acb74/attachment-0001.p7s>
More information about the Rtk-users
mailing list