Real-time reconstruction

Hello. I am now using Parker+FDK for CBCT. But right now I’m reconstructing 200 projected images by feeding them into the code, so I have to wait until the image is captured. Now I want to simulate the process of acquisition, and each image is input into the code for reconstruction, so that the process of acquisition and reconstruction is parallel, which can improve the reconstruction efficiency. Is there a demo of this scheme that has been implemented? Or can you tell me some ideas?

You might want to check these threads from RTK’s mailing list
https://www.creatis.insa-lyon.fr/pipermail/rtk-users/2018-February/001225.html
https://www.creatis.insa-lyon.fr/pipermail/rtk-users/2022-September/001875.html

Thank you very much! I see you discussed inline recon when geometry is not obtained. Now we do the geometric correction first, so we have the geometric information for all angles, and in this case we reconstruct. My current idea is: use the full geometry to initialize parker and fdk, then input the projected image one by one, perform parker+fdk, and save the intermediate reconstruction results. filter geometry is not reset during intermediate rebuild. However, the images I made according to this idea are all black, and Error:
Did not get requested region!
Requested:
ImageRegion (0x7ffe23e0fd10)
Dimension: 3
Index: [0, 0, 0]
Size: [512, 512, 512]
Actual:
ImageRegion (0x7ffe23e0fcd0)
Dimension: 3
Index: [0, 0, 0]
Size: [0, 0, 0] is generated.
How do I correct the code?
My code is :slight_smile:

new_projection = self.load_and_correct_projection(projection_array)
geometry = self.addProjection(geometry_info)

self.pss.SetInput(new_projection)
self.pss.SetGeometry(geometry)
self.pss.Update()
pss_output = self.pss.GetOutput()

self.fdk.SetInput(0, self.reconstruction) 
self.fdk.SetInput(1, pss_output)     
self.fdk.Update()
fdk_output = self.fdk.GetOutput()

self.reconstruction = fdk_output

The error message indicates a problem with one of the inputs (possibly the output of pss).
For Parker, you can provide the full geometry, provide as input the full stack but with only the new projection in memory (i.e., one projection in the BufferedRegion with index matching the one in the geometry).
For FDK, we always go over the full stack of projections (see here) so the simplest might be to manually do FDKWeightProjectionFilter, FFTRampImageFilter as suggested above for Parker and then do one FDKBackProjectionImageFilter with a one projection stack and one (corresponding) element in the geometry object.

Thank you for your reply. I found the following code on github. May I ask if I need to implement this part manually and modify the number of projections to 1?

auto frac = (1.0f / 3) / itk::Math::ceil(double(nProj) / m_ProjectionSubsetSize);
  progress->RegisterInternalFilter(m_WeightFilter, frac);
  progress->RegisterInternalFilter(m_RampFilter, frac);
  progress->RegisterInternalFilter(m_BackProjectionFilter, frac);

  for (unsigned int i = 0; i < nProj; i += m_ProjectionSubsetSize)
  {
    // After the first bp update, we need to use its output as input.
    if (i)
    {
      typename TInputImage::Pointer pimg = m_BackProjectionFilter->GetOutput();
      pimg->DisconnectPipeline();
      m_BackProjectionFilter->SetInput(pimg);

      // Change projection subset
      subsetRegion.SetIndex(Dimension - 1, i);
      subsetRegion.SetSize(Dimension - 1, std::min(m_ProjectionSubsetSize, nProj - i));
      m_ExtractFilter->SetExtractionRegion(subsetRegion);

      // This is required to reset the full pipeline
      m_BackProjectionFilter->GetOutput()->UpdateOutputInformation();
      m_BackProjectionFilter->GetOutput()->PropagateRequestedRegion();
    }
    m_BackProjectionFilter->Update();
  }

Yes, it’s the idea. With subsetRegion.SetSize(2,1) if you’re dealing with one projection only. Do you want to give it a try or would you need a Python example?

1 Like

Thank you very much for your reply. I think I’m a beginner, so may need your python demo. My email:2023200830@mail.buct.edu.cn

Hello. So far I have tried it myself and found that the python version is essentially calling C++, which makes it difficult for me to continue. May need your help!

I have created an example for you which will be integrated in the documentation soon:

2 Likes

:wink: