CERN / TIGRE

TIGRE: Tomographic Iterative GPU-based Reconstruction Toolbox
BSD 3-Clause "New" or "Revised" License
586 stars 192 forks source link

geometry for curved detector #222

Closed liurenjie666 closed 1 month ago

liurenjie666 commented 3 years ago

Expected Behavior

Are there examples of geometry setting for curved detector panel? I am working on a helical CT project with equiangular detector units, but I only find geometry setting with equidistance detector units. Could you please are there demos for that or how to implement it? Thanks a lot!

AnderBiguri commented 3 years ago

Hi @liurenjie666 , I have bad news! TIGRE does not support curved detectors yet.... Its on my TODO list, but requires a serious amount of work in the source code... If I have time until January I may try to implement it, but I can't promise anything yet, sorry about that.

What others have done in the past is to "flatten" the detector. Its not ideal, but you can imagine a flat detector with more pixels that can be interpolated from your curved detector data. This will introduce slight interpolation errors, but they will be minor, so the results will be practically valid. Of course, not ideal, but its the only option I can offer right now.

liurenjie18 commented 3 years ago

Many thanks to you!!! I will try the interpolation.

AnderBiguri commented 3 years ago

I'll leave this open, TIGRE should either allow for curved detectors, or provide an interpolating function.

AnderBiguri commented 3 years ago

This is work in progress. While a CUDA code for curved detector is not coming anytime soon, an interpolator that flattens detectors will.

listar0810 commented 1 year ago

@AnderBiguri Hi, I wanna to know if the curved detector is supporting now, many thanks!

AnderBiguri commented 1 year ago

hi @listar0810 , I made this: https://github.com/CERN/TIGRE/pull/233 but its untested, as I don't have data that can verify it. If you do, I will be happy to improve that code and merge it to TIGRE.

spencer03172023 commented 1 year ago

hi @listar0810 , I made this: #233 but its untested, as I don't have data that can verify it. If you do, I will be happy to improve that code and merge it to TIGRE.

Hi @AnderBiguri ,

Are you still on wating for the data to verify it? If possible i can provide you the test data. 1) Fully curved-detector 2) Module based curved-detector

AnderBiguri commented 1 year ago

Hi @spencer03172023 Yes, still needing some data to verify the code!

If you have both the recon/original image + sinograms that would really help, yes!

I have not seen module-based curved-detectors. Are they basically picewise flat curved detectors?

stefenmax commented 8 months ago

Hi @AnderBiguri , do you have any news regarding the curved-detector algorithm? I'm wondering if by "curved-detector" you're referring to equal-angular measurements. I've recently attempted to apply your FDK algorithm for reconstructing my equal-angular projection data, yet it appears there's no feature to select between equal angular or equal distance options. It seems to solely support equal distance, although in the Gallery, you mentioned using equal-angular projection data, which is a bit confusing. Also, the image quality I achieved with the FDK reconstruction was not satisfactory. Additionally, I would be happy to share the equal-angular projection data with you in private. Below is the code snippet and the reconstructed image I obtained.(The left is TIGRE generated which the vessel is a little bit deformed).

import numpy as np
import scipy.io as sio
import tigre
import tigre.algorithms as algs

data_path = 'D:/ssh_down/test_code/recons_code/data/female106_phase100_static_proj.mat'
mat = sio.loadmat(data_path)
projections = mat['proj'] 
#TIGRE [T, V, U] [T: Angle V: Dector Hight U: Dector width ]
projections = np.transpose(projections, (2, 1, 0))
projections = projections[:,:,::-1]
# tigre.plotproj(projections, dim="V") # Dim= "V" means plot sinogram

geo = tigre.geometry(mode='cone')

geo.DSD = 950                                          # Distance Source Detector      (mm)
geo.DSO = 540                                          # Distance Source Origin        (mm)
geo.dDetector = np.array([410 / 32, 0.9643345*950 / 835])  
geo.nDetector = np.array([32, 835])                    
geo.sDetector = geo.dDetector * geo.nDetector          
geo.nVoxel = np.array([256, 512, 512])                   
geo.sVoxel = np.array([256, 512, 512])                  
geo.dVoxel = geo.sVoxel / geo.nVoxel                    
geo.offOrigin = np.array((0, 0, 0))
geo.offDetector = np.array((0, 1.5))                     # (z,y)
geo.accuracy=0.5                                        # Accuracy of FWD proj   (vx/sample)  # noqa: E501

start_angle = np.pi
end_angle = start_angle + 2 * np.pi
angles = np.linspace(start_angle, end_angle, 984, dtype=np.float32)

reconstructed_image = algs.fdk(projections, geo, angles)
# tigre.plotimg(reconstructed_image, dim="z")

import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
plt.imshow(reconstructed_image[90,:,::-1], cmap='gray')  
plt.show()

image

AnderBiguri commented 8 months ago

Hi @stefenmax ! Would you mind clarifying what you mean by equal-angular vs equal-distace?

If you mean the difference between a flat detector (equal-distance?) and one that is curved (equal-angular?) then indeed, TIGRE only supports flat detectors, which is essentially the reason why this issue is open :)

That said, I have been working on it a bit, and some other have too. There is a PR with some code that I am unable to test due to lack of data: #233 In that same PR, there is a link to code from someone who did test it themselves with their own data: https://gist.github.com/sjroe/1842e4fd44a6d4a8cb4eb163c4ce0d86

What both my and the linked code do is to "flatten" the detector, i.e. produce a new projection that is flat, but equivalent to the curved one. You could test that and report back, or I am happy to get some data from you and test it myself.

stefenmax commented 8 months ago

I'm not sure, but in your PhD thesis page 93, "RANDO head using 360 equiangular projections". Does that mean RANDO used curved detector? If so I think we are in the same page. By the way I don't know how to set the parameter arclength in the function of flatten_detector.py. I already sent the onedrive link to your gmail, please check and used it in private.

AnderBiguri commented 8 months ago

@stefenmax you are mixing things here. That sentence means they were taken over 360 projections in a circle, and each of those projections is in a flat panel detector. As the sentence goes, it does not clarify if its a flat panel or a curved panel, but given the vast majority of CBCT detectors are flat, its implied.

To be able to convert a curved detector into a flat detector, you need to know its real dimensions in mm. Arclength is a proxy of that. Given a curved detector has pixels that are the same distance to the source, instead of providing the size in mm of the detector, you can provide how much the arc-length of the detector is (2*pi being the max). This is important because pixels can be or arbitrary size in mm, of course.