Image Reconstruction: Backprojection & Fourier

Backprojection

This section demonstrates a basic backprojection algorithm for image reconstruction.

Steps:

  • Determine the dimensions of the sinogram:
[numOfParallelProjections, numOfAngularProjections] = size(sinogram);
  • Initialize a matrix for the backprojected image (BPI):
BPI = zeros(numOfParallelProjections);
d = numOfParallelProjections * sind(45);
c = d * 2;
dim_pad = ceil((c - numOfParallelProjections) / 2);
  • Calculate the padded image dimensions:
padded_dim = numOfParallelProjections + 2 * dim_pad;
  • Iterate through each projection angle:
for i = 1:numOfAngularProjections
    % Replicate the attenuation profile to create an image.
    Sin_im = repmat(sinogram(:,i), 1, padded_dim);

    % Pad the image to make it square.
    Pad_im = padarray(Sin_im, dim_pad, 0, 'both');

    % Rotate the image clockwise.
    Rot_im = imrotate(Pad_im, -thetas(i), 'bilinear', 'crop');

    % Crop the image to its original size.
    Rot_im_crop = Rot_im(dim_pad + (1:numOfParallelProjections), dim_pad + (1:numOfParallelProjections));

    % Accumulate the rotated and cropped image.
    BPI = Rot_im_crop + BPI;

    imagesc(BPI, "XData", 0:50:150, "YData", 0:20:180)
    colormap('bone')
    drawnow
end

Direct Fourier Reconstruction

This section implements the Direct Fourier Reconstruction method.

  • Define the oversampling ratio:
oversampling_ratio = 2;
  • Compute the 1D Discrete Fourier Transform (DFT) of the sinogram:
[DFT_sinogram, omega_s] = compute1DFT(sinogram);
  • Convert from polar to Cartesian coordinates:
[Cartesian_sinogram, omega_xy] = polar_to_rectA(thetas, omega_s, DFT_sinogram, numOfAngularProjections * oversampling_ratio);
  • Perform the 2D inverse Fourier transform:
[Interpolated_sinogram, axis_xy] = inverse_Fourier_2DA(Cartesian_sinogram, omega_xy);
IM_DFR = Interpolated_sinogram;
  • Crop and rotate the reconstructed image:
Reconstructed_image = real(IM_DFR);
Reconstructed_image_crop = Reconstructed_image(round((length(Reconstructed_image) - numOfAngularProjections) / 2) : round((length(Reconstructed_image) - numOfAngularProjections) / 2) + numOfAngularProjections - 1, round((length(Reconstructed_image) - numOfAngularProjections) / 2) : round((length(Reconstructed_image) - numOfAngularProjections) / 2) + numOfAngularProjections - 1);
Reconstructed_image_final = rot90(Reconstructed_image_crop, -1);
imagesc(Reconstructed_image_final, "XData", 0:50:150, "YData", 0:20:180)
colormap('bone')

Filtered Backprojection

This section details the Filtered Backprojection (FBP) algorithm.

  • Calculate filter coefficients:
filter_FBP = zeros(1, 2 * numOfParallelProjections + 1);
c = 1;
for k = -(numOfParallelProjections + 1):(numOfParallelProjections + 1)
    if k == 0
        filter_FBP(c) = 1/4;
    elseif mod(k, 2) ~= 0
        filter_FBP(c) = (-1) / (pi^2 * (k)^2);
    elseif mod(k, 2) == 0
        filter_FBP(c) = 0;
    end
    c = c + 1;
end
filter_FBP_spec = abs(fft(filter_FBP));
  • Iterate through each projection angle and apply the filter:
for i = 1:numOfAngularProjections
    % Filter the attenuation profile.
    filteredProfile = conv(sinogram(:, i), filter_FBP, 'same');
    Sin_im = repmat(filteredProfile, 1, padded_dim);
    Pad_im = padarray(Sin_im, dim_pad, 0, 'both');

    % Rotate the image clockwise.
    Rot_im = imrotate(Pad_im, -thetas(i), 'bilinear', 'crop');

    % Crop the image to its original size.
    Rot_im_crop = Rot_im(dim_pad + (1:numOfParallelProjections), dim_pad + (1:numOfParallelProjections));

    % Sum the rotated and cropped image.
    BPI = BPI + Rot_im_crop;

    colormap('bone')
    imagesc(BPI, "XData", 0:50:150, "YData", 0:20:180)
end