arcadelab/deepdrr

get_camera3d_from_world() got an unexpected keyword argument 'phi'

lkccu opened this issue · 11 comments

lkccu commented

Hi author @mathiasunberath ,I have encountered a bug when implementing func projector.project_over_carm_range().Here are the errors.Could you please give me a hand? thx.


TypeError Traceback (most recent call last)
Input In [21], in <cell line: 1>()
1 with deepdrr.Projector(
2 volume=volume,
3 carm=carm,
(...)
10
11 ) as projector:
---> 12 images = projector.project_over_carm_range(
13 (-40,40,40),
14 (-45,45,45))
15 for i,image in enumerate(images):
16 plt.imshow(image,cmap ='gray')

File ~/deepdrr/deepdrr/projector/projector.py:813, in Projector.project_over_carm_range(self, phi_range, theta_range, degrees)
811 phis, thetas = utils.generate_uniform_angles(phi_range, theta_range)
812 for phi, theta in zip(phis, thetas):
--> 813 extrinsic = self.device.get_camera3d_from_world(
814 self.device.isocenter,
815 phi=phi,
816 theta=theta,
817 degrees=degrees,
818 )
820 camera_projections.append(
821 geo.CameraProjection(self.camera_intrinsics, extrinsic)
822 )
824 return self.project(*camera_projections)

TypeError: get_camera3d_from_world() got an unexpected keyword argument 'phi'

lkccu commented

Here are the codes.

volume = deepdrr.Volume.from_nifti(path,
                                  materials ='Bone')

camera_intrinsics = deepdrr.geo.CameraIntrinsicTransform.from_sizes(
    sensor_size = 512,
    pixel_size = 0.5,
    source_to_detector_distance = 1118.38
)
center = volume.world_from_ijk @ deepdrr.geo.point(160,160,160)
carm = deepdrr.MobileCArm(isocenter=center,
                          source_to_detector_distance = 689.1,
                         min_alpha = -40,
                         max_alpha = 40,
                         # note that this would collide with the patient. Suggested to limit to +/- 45
                         min_beta = -45,
                         max_beta = 45,
                         pixel_size =0.5,
                         sensor_height =320,
                         sensor_width =320,)

alphas,betas = utils.generate_uniform_angles(
    (-40,40,40),
    (-45,45,45)
)

output_dir = Path("/root/autodl-tmp/drr_result")
output_dir.mkdir(exist_ok = True)
with deepdrr.Projector(
    volume=volume,
    carm=carm,
    step=0.1,  # stepsize along projection ray, measured in voxels
    spectrum="90KV_AL40", # energy spectrum
    photon_count=100000, # number of photons to simulate
    scatter_num=0, # number of scatter events to simulate
    neglog=True, # apply negative log transform to image (convenient for visualization)
    intensity_upper_bound=3, # Good default for windowing
    
) as projector:
    images = projector.project_over_carm_range(
          (-40,40,40),
          (-45,45,45))
    for i,image in enumerate(images):
        plt.imshow(image,cmap ='gray')
        plt.title(f'alpha,beta ={alphas[i],betas[i]}')
        display(Image.fromarray((image * 255).astype(np.uint8)))
print("###               finish               ###")
lkccu commented

And how can I make use of the arg materials,I searched that in issues and I found materials = dict["bone = seg_array"] ,but I am not sure how can I specify the seg_array variable or there is a solution? Thanks
Regards.

@benjamindkilleen you want to take a look at this?

@lkccu The first issue is because project_over_carm_range works with the CArm class and not the MobileCArm class. (This will raise an error in future releases.) I recommend to update the pose of the carm directly with the carm.move_to function, using the alphas,betas you have defined, and calling the projector for each image. (This is what project_over_carm_range does under the hood.

For the latter issue, it would be materials = dict(bone=seg_array), where seg_array is a 3D numpy binary array giving the segmentation of bone. This is syntactically equal to materials = {"bone": seg_array}, which may be more familiar. The materials argument should be the whole dictionary.

lkccu commented

Thank you for that, I mistakes what arg material is doing. So does that mean 'material' is doing seg from an known segmentation nifti data?what should I do to generate a bone-styled DRR image from scratch?
Regards.

lkccu commented

I specify in the volume that "segmentation = True", however I got an terrible result.I wonder whether it is because my data is not that good.Can you give me a hand?Here is the minimum example .
Q%}B1`NWZ1W)@}1K5DKE3Z9
before seg.
image

lkccu commented

Hi author @mathiasunberath, happy CNY!I have encountered the same trouble now.I wonder how can I make use of sample nifti image dataset6_CLINIC_0001_mask_4label_1.nii.gz.I inspected in Slicer and that seg mask looks so great.However,when I tried to load it as a 3-d array and specify arg materials in func Volume.from_nifti, it turned out a dark image.Could you please give me a hand?Thank you very much!The codes are as follows.

seg_array = nib.load('/root/autodl-tmp/datasets/DeepDRR_Data/CTPelvic1K_dataset6_CLINIC_0001/dataset6_CLINIC_0001_mask_4label_1.nii.gz')
print(seg_array.shape)
seg_array = seg_array.get_fdata()
volume = deepdrr.Volume.from_nifti(path,
                                   materials=dict(bone=seg_array))             
volume.supine()
carm = deepdrr.MobileCArm(isocenter=volume.center_in_world, alpha=0, beta=0, degrees=True)

with deepdrr.Projector(
    volume=volume,
    carm=carm,
    step=0.2,  # stepsize along projection ray, measured in voxels
    spectrum="90KV_AL40", # energy spectrum
    photon_count=10000, # number of photons to simulate
    scatter_num=0, # number of catter events to simulate
    collected_energy =False, # apply negative log transform to image (convenient for visualization)
    intensity_upper_bound=2, # Good default for windowing
) as projector:
    for z in range(-500, -100, 50):
        carm.move_to(isocenter_in_world=volume.center_in_world + geo.v(0, 0, z))
        print(f"Projecting at z={z}")
        image = projector.project()
        display(Image.fromarray((image * 255).astype(np.uint8)))
print("######          finish          ######") 
lkccu commented

Hi author!

lkccu commented

Hello,I am wondering what can I do in my func to ensure that the projector is initialized or set it initialized?

projector.initialize(), which is a no-op if already initialized.

lkccu commented

projector.initialize(), which is a no-op if already initialized.
Thank you.I want to initialized the projector in the beginning of code and turn it into a parameter of functions like
drr(projector=projector, rtvec=X) where function drr is generating drr images of the very volume rotating and translating ,carm.What should I do?Please give me a hand.