arcadelab / deepdrr

Code for "DeepDRR: A Catalyst for Machine Learning in Fluoroscopy-guided Procedures". https://arxiv.org/abs/1803.08606
GNU General Public License v3.0
209 stars 60 forks source link

Project with coronal view #59

Closed junjun1023 closed 3 years ago

junjun1023 commented 3 years ago

Hi, I'm trying to create DRRs with coronal view. I converted dicom to nifti format and create Volume as instructions. However, I tried many different rotations with volume.rotate, the result is not as expectations. And I'm confused why the the size of dicom which is (512, 512) before projection changed after projection?

benjamindkilleen commented 3 years ago

Do you have a minimal code example?

benjamindkilleen commented 3 years ago

(Closing was accidental)

junjun1023 commented 3 years ago

@benjamindkilleen


import dicom2nifti
# convert dicom to nifti
dicom2nifti.convert_directory(path_of_dicom_dir, filepath)

# The code below is from deepdrr_demo.ipynb
volume = Volume.from_nifti(filepath)
carm = deepdrr.MobileCArm(isocenter=volume.center_in_world, alpha=0, beta=0, degrees=True, min_alpha=-40, max_alpha=40, min_beta=0, max_beta=20)

with deepdrr.Projector(
    volume=volume,
    carm=carm,
    step=0.1,  # stepsize along projection ray, measured in voxels
    mode="linear",
    max_block_index=200,
    spectrum="90KV_AL40",
    photon_count=100000,
    add_scatter=False,
    threads=8,
    neglog=True,
) as projector:
    image = projector.project()
    plt.imshow(image, cmap='gray')
    plt.show()

image

junjun1023 commented 3 years ago

I can't tell what projection plane the result is.

benjamindkilleen commented 3 years ago

The latest pre-release includes some convenience functions to handle the rotations, assuming their anatomical coordinate spaces are correct. I believe the following should work.

After positioning the volume faceup or facedown, I suggest rotating the simulated C-arm by changing alpha/beta. This may not be how a cranial X-ray is normally taken, but our convenience functions are designed with intraoperative procedures in mind, so there is more support. You can of course pass in the camera matrix yourself instead of the C-arm object.

import dicom2nifti
# convert dicom to nifti
dicom2nifti.convert_directory(path_of_dicom_dir, filepath)

volume = Volume.from_nifti(filepath)
volume.faceup() # Available in latest pre-release
carm = deepdrr.MobileCArm(volume.center_in_world)
carm.move_to(alpha=0, beta=0, degrees=True) # Can also be done in the with block

# Extra args have reasonable defaults.
with deepdrr.Projector(volume, carm=carm) as projector:
    image = projector.project()
    plt.imshow(image, cmap='gray')
    plt.show()
junjun1023 commented 3 years ago

@benjamindkilleen Thank you for your reply! I'm not familiar with the way to adjust a 3D image and how is C-arm work in the scene. I have tried your sample code, and encountered error isocenter [173.75 14. -7.596878 1. ] is out of bounds. Use world_from_device transform to position the carm in the world. Does it mean that I need to pre-process my 3D image?

The image below is the result I read with pydicom and extract with different axis. 1633004429481

benjamindkilleen commented 3 years ago

Ah, that is my mistake. I have edited the excerpt to omit the isocenter keyword, which does something slightly different.

junjun1023 commented 3 years ago

@benjamindkilleen The result looks quite different from the single slice of AP view above. It seems like a patch of whole lung view. Do you have any suggestion to get the whole PA view like the image of README?

1633012172176

benjamindkilleen commented 3 years ago

@junjun1023 You will have to translate the isocenter (which, by default, is on the principle ray), to be where you want in the anatomy. I assumed that was the center, but you may want to move the camera closer or further away. You can do this by translating the volume or repositioning the C-arm with built-in functions. You can also adjust the camera parameters passed to the C-arm class to change the magnification.

You may find the built-in visualization tools to be useful. The following will open an interactive VTK window with the C-arm and volume shown. This may help understand the geometry setup, so you can tinker with it.

from deepdrr import vis

...

vis.show(volume, carm, full=True)
junjun1023 commented 3 years ago

@benjamindkilleen

Excuse me, is there any way to convert a 3D numpy.array to Volume? I saw that there are some parameters need to pass e.g. material, but I don't know what should be passed. What I want to do is to create subvolumes and project the subvolumes with Projector.

junjun1023 commented 3 years ago

I can get the whole PA view of projection by setting source_to_isocenter_vertical_distance larger than default value. Thank you for helping.

benjamindkilleen commented 3 years ago

That would work. You can do the numpy conversion with the class constructor itself or the from_hu() method.