CERN / TIGRE

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

Question #258

Closed chg0901 closed 3 years ago

chg0901 commented 3 years ago

Expected Behavior

I want to reconstruct a 3D image for the given DCM data.

Actual Behavior

Now I can just run the demo and look at the performance of this library.

Code to reproduce the problem (If applicable)

Specifications

I want to know how to combine these 2D figures (many figures with the same size of 128*128) as a 3D figure. And I want to visualize it and save it. Or could you please show me how to save the 3D figure and check it using other software?

AnderBiguri commented 3 years ago

Hi,

I am not really sure what you are having problem with. Loading data? saving data? in which format do you want your data saved? When you say "figure", you mean "image"? Which "2D figures" are you talking about?

chg0901 commented 3 years ago

I will show you an example image

image Here are two images. and there is a total of 128 images with the size of 128I*128. I don't know to use them.

I hope this is a tutorial that can help us to read the basic CT data with certain formats, and then reconstruct them into a 3D image.

Now I have ".hnd" documents, ".ct" documents and ".dcm" documents. I don't know how to utilize our library to utilize them.

Could you please show me some tutorials with figures and codes to help me understand and use your library?

Thank you!

AnderBiguri commented 3 years ago

Hi,

Those image, taken from TIGRE, are actually 3D images. As visualizing 3D images is not easy, in TIGRE we tend to visualize them in 2D slices, but they are already a 3D image (as you can see from the size(imgFDK) or size(head) functions. They are nto necesarily 128 images of 128x128, they are a single image f size 128x128x128.

Now, medical imaging is a very wide field and there does not exist a generic tutorial to load all hundreds of existing medical formats. I have been trying to add data loaders myself (see demo 21), but this is not tested in all existing machines or data formats, that would be impossible :) However, I am willing to help create data loaders if we can add them to TIGRE (depends if the format is proprietary or not). In demo 21, you can see a dicomDataLoader() function, for DICOM projection data, that has been tested with Phillips scanners only. Note that if its a reconstructed image, then it may not work (as TIGRE is for reconstruction, mostly).

However, I have never seen hnd or ct file extensions myself, so I do not know how to open them. As said, if they are not proprietary and you are allowed to share how they work, I am happy to help writing data loader code.

In general, I suggest you have a look at the demos, if you want to understand how TIGRE works.

Hope this helps

chg0901 commented 3 years ago

Thank you for your answer.

when I try to use my own data, I didn't find how to configure the parameters.

if strcmp(mode,'cone')
    %% Example
    % VARIABLE                                   DESCRIPTION                    UNITS
    %-------------------------------------------------------------------------------------
    % Distances
    geo.DSD = 1536;                             % Distance Source Detector      (mm)
    geo.DSO = 1000;                             % Distance Source Origin        (mm)
    % Detector parameters
    geo.nDetector=nDetector;                    % number of pixels              (px)
    geo.sDetector=[512*0.8;512*0.8];            % total size of the detector    (mm)
    geo.dDetector=geo.sDetector./geo.nDetector;                 % size of each pixel            (mm)

    % Image parameters
    geo.nVoxel=nVoxel;                          % number of voxels              (vx)
    geo.sVoxel=[256;256;256];                   % total size of the image       (mm)
    geo.dVoxel=geo.sVoxel./geo.nVoxel;          % size of each voxel            (mm)
    % Offsets
    geo.offOrigin =[0;0;0];                     % Offset of image from origin   (mm)
    geo.offDetector=[0; 0];                     % Offset of Detector            (mm)

    % Auxiliary
    geo.accuracy=1;
    geo.mode=mode;

I don't know how to set

geo.DSD = 1536;                             % Distance Source Detector      (mm)
geo.DSO = 1000;                             % Distance Source Origin        (mm)
geo.sDetector=[512*0.8;512*0.8];            % total size of the detector    (mm)
geo.sVoxel=[256;256;256];                   % total size of the image       (mm)

in the demo, 256is the size of images geo.DSD = 1536 --> 1536=256x6 geo.sDetector=[512*0.8;512*0.8] --> 512=256x2 but why a 0.8 is used here? geo.sVoxel=[256;256;256]; --->use the size of images

but I don't know to choose the geo.DSO = 1000

these are my guess. But I don't know why you set these configurations

Now my data is 512x512x64, and I will show you an example as shown in these two images below.

I will show you my configuration to combine the parallel and cone mode

    geo.DSD = nDetector(1)*4;                             % Distance Source Detector      (mm)
    geo.DSO = nDetector(1)*2;                             % Distance Source Origin        (mm)
    % Detector parameters
    geo.nDetector=nDetector;                    % number of pixels              (px)
    geo.sDetector=**geo.nDetector**;          % total size of the detector    (mm)
    geo.dDetector=geo.sDetector./geo.nDetector;                 % size of each pixel            (mm)

    % Image parameters
    geo.nVoxel=nVoxel;                          % number of voxels              (vx)
    geo.sVoxel=**nVoxel;%[256;256;256];**                   % total size of the image       (mm)
    geo.dVoxel=geo.sVoxel./geo.nVoxel;          % size of each voxel            (mm)
    % Offsets
    geo.offOrigin =[0;0;0];                     % Offset of image from origin   (mm)
    geo.offDetector=[0; 0];                     % Offset of Detector            (mm)

    % Auxiliary
    geo.accuracy=1;
    geo.mode=mode;

I also have tried the parallel mode, but it worked badly.

could you please tell me how to adjust the codes in the demos? and I think we need a tutorial to tell people how to adjust the configurations for their own data.

These two images show the CT image before and after I use the ASD-POCS algorithm.

21without 21with

chg0901 commented 3 years ago

I use these values in defaultGeometry.m to have the geo struct.

    % Distances
    geo.DSD = 1536*2;                             % Distance Source Detector      (mm)
    geo.DSO = 1000*2;                             % Distance Source Origin        (mm) % Detector parameters
    % Detector parameters
    geo.nDetector=nDetector;                    % number of pixels              (px)
    geo.sDetector=[512*2*0.8;512*2*0.8];          % total size of the detector    (mm)
    geo.dDetector=geo.sDetector./geo.nDetector;                 % size of each pixel            (mm)

    % Image parameters
    geo.nVoxel=nVoxel;                          % number of voxels              (vx)
    geo.sVoxel=[256*2;256*2;64];                   % total size of the image       (mm)
    geo.dVoxel=geo.sVoxel./geo.nVoxel;          % size of each voxel            (mm)
    % Offsets
    geo.offOrigin =[0;0;0];                     % Offset of image from origin   (mm)
    geo.offDetector=[0; 0];                     % Offset of Detector            (mm)

    % Auxiliary
    geo.accuracy=1;
    geo.mode=mode;

in the parse_input() function, I set 'nVoxel' as addParameter(p,'nVoxel', [512;512;64],@(x)(isnumeric(x)&&all(floor(x)==x)&&max(size(x))==3));

and I set the epsilon=0.2 since I find that errL2OSSART(end)is too big (1976.91)

Other parameters are default values.

But the result is still not good. original CT image 64without

the image constructed by the "ASD_POCS algorithm." 64with

I don't know how to adjust the codes to make it clear and remove small black points on the constructed image.

AnderBiguri commented 3 years ago

Hi,

Glad that you managed to get further with the code!

On having a demo to set the geometric parameters:

Each CT scanner has its own geometrical parameters, and some of them have variable geometries. Some manufacturers tell you this information, some don't. Some of the manufacturers that tell you this information only tell you in propetary format that I am not legally allowed to share here, some don't. I can not tell you how to set those for your data, as its not possible for me to know the values of all scanners of all the world. I can not make a demo on how to know the DSO of your real scanner: you either know it, or you don't know it, and I can't help with that! I hope you understand.

Now, on your first example post here, it seems that you have not understood how to define the geometric parameters needed in TIGRE, and instead you are modifying the TIGRE defaultGeometry() function. I recommend you to either read the paper of TIGRE, or read Demo 1. The first demo, is an explanation of what all the parameter are and mean. defaultGeometry() is mentioned there. It is just a function for when you do not know or you do not care about a geometry, and just want something that is "realistic".
I recommend you do not touch that function, and instead you define your own geometry manually as in demo 1, in your main script.


Your second problem: ASD_POCS not being "perfect". Short answer: it is not, no algorithm is perfect. Otherwise there would not be +10 algorithms in TIGRE, I would only have the perfect one :)

Long answer: it heavily depends on our projection data, on your number of angles and the algorithm parameters. If you tell me that the second image comes from 5 projections, I would tell you to write a paper together of how amazing the results are. Or if it comes from only 1 iteration of the algorithm, I would say the same: amazing results, how incredible that 1 iteration has managed to get such a good image. I assume this is not the case, but you have not shared it, so it would be better for me to have a full code to help. In any case, even at good amounts of data, ASD_POCS (and other) algorithms have a problem: they are very very sensitive to algorithm parameters. As you have already seen in Demo 9, the algorithms have many many input parameters, and these tend to be quite hard to find to get the best image. When you find them, you get a really really good reconstruction, but when you don't, you get a really bad one. I have a paper lead by Manasavee Lovithee on just studying the impact of these parameters (we found which ones are more important, but no trick to choose them). One of the main problems tuning these parameters is that they are very very data dependent. So for a particular setup of a scanner, you can find a perfect set of parameters and they will always work, but if you change your image size, the number of projections, or any other data-relevant geometry, the algorithm parameters will need to change to be good.

This is an open question in mathematics. There is no solution I can give you.

chg0901 commented 3 years ago

I also have another question, how to visualize the reconstructed figure in 3D? Now images are just shown in 2D one by one, I hope I can visualize them in 3D.

image

AnderBiguri commented 3 years ago

By using some 3D visualization software, which is much beyond the scope of TIGRE. I know of Simpleware, Fiji, Avizo, VGStudio, Amide, Paraview, etc etc. I am sure Google is of more help than me here.

None of this is a "trivial" task. You may need to play with different ones and try to find the best suited one for you.

chg0901 commented 3 years ago

Maybe my question is not clear enough.

Our output is a 3D figure like 512x512x64, how to save this as a 3D object. is there any API to do it?

AnderBiguri commented 3 years ago

Ah, that is a different question. So its not that you want to visualize it, but you want to save it?

Same answer.... Depends in the format. you want to save it in .mat format? do save("filename.mat",variablename) and thats it. But each different format will have different code to save it. See above for a discussion on different file formats and why its hard to have code for all of them. You need to be specific in what you want if you want specific answers!

maybe dicomWrite from matlab is what you want?


Note that in MATLAB, in TIGRE, you already have a 3D object. You just visualize it by cutting 2D slices, but the input to plotImg() is a 3D matrix already. Maybe that is what is confusing you?

AnderBiguri commented 3 years ago

I will close this for inactivity, but feel free to ask any more questions (maybe the discussions tab is a better place)

chg0901 commented 3 years ago

Thank you for your kind help and good explanation.

Have a good day~

On Thu, Mar 4, 2021 at 9:20 PM Biguri notifications@github.com wrote:

I will close this for inactivity, but feel free to ask any more questions (maybe the discussions https://github.com/CERN/TIGRE/discussions tab is a better place)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CERN/TIGRE/issues/258#issuecomment-790578094, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB636WDQDT5IKNZAAUWPOPDTB53IPANCNFSM4YGQ44AA .