├── CT Reconstruction using Fourier Filtered Backprojection.pdf ├── FFB.m ├── LICENSE ├── README.md ├── fan_beam_compare.m ├── img ├── read ├── sample1.PNG ├── sample2.PNG ├── sample3.PNG ├── sample4.jpg ├── sample5.JPG ├── sample6.JPG ├── sample7.JPG ├── sample8.JPG └── sample9.JPG ├── main.m ├── own_radon.m ├── sample1.PNG ├── sample2.PNG └── sample3.PNG /CT Reconstruction using Fourier Filtered Backprojection.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/CT Reconstruction using Fourier Filtered Backprojection.pdf -------------------------------------------------------------------------------- /FFB.m: -------------------------------------------------------------------------------- 1 | %{ Implementation of the Fourier Filtered Backprojection method 2 | 3 | %@param phantom_img 4 | %the original image 5 | %@param filter_type 6 | %string, can either be none, ramlak, shepplogan, hamming, or lowpasscosine 7 | %@param dtheta 8 | %interval betwen projection angles, in degrees 9 | %@param coe_transform 10 | %a coefficient adjusting the size of the Fourier Transform 11 | %@param cut_off 12 | %the cut off ratio for the filters, values larger than width*cut_off are set to zeroes 13 | %@param interpolation 14 | %interpolation method, can either be linear or nearest 15 | %} 16 | 17 | function final_img = FFB(phantom_img, filter_type, dtheta, coe_transform, cut_off, interpolation) 18 | P = phantom_img; %Load the phantom 19 | 20 | [n_row, n_column] = size(P); 21 | theta = 0:dtheta:(180-dtheta); % Set the projection angle 22 | 23 | [R,xp] = radon(P,theta); %Perform radon transorm, Xp is a vector containing 24 | %the radial coordinates corresponding to each row of R 25 | 26 | [num_detectors ,num_angles] = size(R); 27 | xp_offset = abs(min(xp)) +1; 28 | 29 | width = 2^nextpow2(num_detectors)*(2^coe_transform); %Get power of 2 for FFT 30 | %at least large enough to fit a column of R 31 | proj_fft = fft(R, width); 32 | 33 | ram_lak = 2*[0:(width/2-1), width/2:-1:1]'/width; %Apply the filter specified 34 | if (strcmp(filter_type,'none')==1) 35 | filter = ones(width, 1); 36 | elseif(strcmp(filter_type,'ramlak')==1) %Ram-Lak 37 | filter = ram_lak; 38 | elseif(strcmp(filter_type,'shepplogan')==1) %Shepp-Logan 39 | Sinc = abs(sinc(2*(0:width-1)/(2*width))); 40 | temp = [Sinc(1:(width/2)), Sinc(width/2:-1:1)]; 41 | filter = ram_lak .* temp'; 42 | elseif(strcmp(filter_type,'hamming')==1) %hamming 43 | Hamming = 0.54 - 0.46*cos(2*pi*(0:width-1)/width); 44 | temp = [Hamming(width/2:width) Hamming(1:width/2-1)]; 45 | filter = ram_lak .* temp'; 46 | elseif(strcmp(filter_type,'lowpasscosine')==1) %Lowpass Cosine 47 | Cosine = abs(cos(2*pi*(0:width-1)/(2*width))); 48 | filter = ram_lak .* Cosine'; 49 | end 50 | 51 | filter(width*cut_off:end)=0; %Apply the threshold according to the cut-off ratio specified 52 | 53 | for w = 1:num_angles 54 | filtered(:, w) = proj_fft(:, w).*filter; 55 | end 56 | 57 | inverse_f = real(ifft(filtered)); %Inverse Fourier Transform 58 | 59 | final_img = zeros(n_row, n_column); 60 | 61 | if (strcmp(interpolation,'linear')==1) %Use linear interpolation method to calculate the values of the reconstruction image 62 | 63 | for iprog=1:num_angles 64 | G = inverse_f(:, iprog); 65 | rad = theta(iprog)*pi/180; 66 | 67 | for x=1:n_column 68 | for y=1:n_row 69 | t = (x-(n_column/2))*cos(rad) - (y-(n_row)/2)*sin(rad) + xp_offset; 70 | 71 | if (ceil(t) == floor(t)) 72 | g1 = G(ceil(t)); 73 | g2=0; 74 | else 75 | g1 = G(ceil(t)) * (t-floor(t)); 76 | g2 = G(floor(t)) * (ceil(t) -t); 77 | end 78 | 79 | final_img(y,x) = final_img(y,x) +g1 +g2; 80 | end 81 | end 82 | end 83 | 84 | 85 | 86 | elseif(strcmp(interpolation,'nearest')==1) %Use nearest neighbor interpolation method to calculate the values of the reconstruction image 87 | for iprog=1:num_angles 88 | G = inverse_f(:, iprog); 89 | rad = theta(iprog)*pi/180; 90 | 91 | for x=1:n_column 92 | for y=1:n_row 93 | t = (x-(n_column/2))*cos(rad) - (y-(n_row)/2)*sin(rad) + xp_offset; 94 | 95 | if (t-floor(t))<(ceil(t) -t) 96 | g = G(floor(t)); 97 | else 98 | g = G(ceil(t)); 99 | end 100 | 101 | final_img(y,x) = final_img(y,x) +g; 102 | end 103 | end 104 | end 105 | end 106 | 107 | final_img = (pi/num_angles)*final_img; 108 | 109 | return 110 | end 111 | 112 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 zachlyu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CT Reconstruction using Fourier Filtered Backprojection 2 | 3 | 4 | ## Overview 5 | 6 | Tomography is a technique to investigate the structure and composition of an object 7 | non-invasively, along spatial and temporal dimensions using photonic radiation, acoustic or 8 | electromagnetic waves, such as X-rays and gamma rays. Initially, the tomographic system 9 | acquires a set of partial measurements by scanning. These measurements are then used for 10 | tomographic projection and reconstruction of optimal tomographic images. 11 | 12 | The purpose of this report is to use Fourier Filtered Backprojection on a Shepp-Logan phantom 13 | image generated in MATLAB. After construction of the image, it is transformed into the radon 14 | and frequency domains. Next, nine filters are applied on the image, followed by a 15 | one-dimensional fast inverse fourier transform and backprojection. After reconstruction, the 16 | effects of sampling, missing projection, filtering, noise and other artifacts on the image are 17 | analyzed and discussed briefly. 18 | 19 | 20 | ## Files 21 | 22 | Overview of the files 23 | 24 | * [FFB.m](https://github.com/bijiuni/CT_reconstruction/blob/master/FFB.m) - Implementation of the Fourier Filtered Backprojection method 25 | * [main.m](https://github.com/bijiuni/CT_reconstruction/blob/master/main.m) - The main program to perform the reconstruction 26 | * [fan_beam_compare.m](https://github.com/bijiuni/CT_reconstruction/blob/master/fan_beam_compare.m) - Compare the performance of pencil-beam and fan-beam 27 | * [own_radon.m](https://github.com/bijiuni/CT_reconstruction/blob/master/own_radon.m) - Realizing radon transform without using built-in fuction 28 | 29 | 30 | ## Explanations 31 | 32 | 33 | ### FFB function 34 | ``` 35 | function final_img = FFB(phantom_img, filter_type, dtheta, coe_transform, cut_off, interpolation) 36 | ``` 37 | 38 | 39 | The function has six parameters. It takes in the original phantom, perform radon transform, and output the reconstructed image 40 | 41 | ``` 42 | %{ Implementation of the Fourier Filtered Backprojection method 43 | 44 | %@param phantom_img 45 | %the original image 46 | %@param filter_type 47 | %string, can either be none, ramlak, shepplogan, hamming, or lowpasscosine 48 | %@param dtheta 49 | %interval betwen projection angles, in degrees 50 | %@param coe_transform 51 | %a coefficient adjusting the size of the Fourier Transform 52 | %@param cut_off 53 | %the cut off ratio for the filters, values larger than width*cut_off are set to zeroes 54 | %@param interpolation 55 | %interpolation method, can either be linear or nearest 56 | %} 57 | ``` 58 | 59 | ### own_radon 60 | 61 | Realizing radon transform without using built-in fuction 62 | 63 | ``` 64 | function processed_img = own_radon(img, theta) 65 | ``` 66 | 67 | ### main 68 | 69 | * Create a phantom image 70 | * Calling the FFB function with specific parameters 71 | * Calculate the SSIM and MSE of the reconstruction to evaluate the process 72 | * Plot the result for analysis 73 | 74 | 75 | ## Sample results 76 | 77 | **For detailed results please refer the [Report](https://github.com/bijiuni/CT_reconstruction/blob/master/CT%20Reconstruction%20using%20Fourier%20Filtered%20Backprojection.pdf)** 78 | 79 | 80 | ### Effect of Sampling 81 | 82 | When the sampling interval decreases, the SSIM value increases and the MSE value decreases. 83 | This is intuitively true as for a single point, more projection means that the sum of 84 | backprojection is closer to the complete integral. 85 | ![Result sample 4](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample4.jpg) 86 | 87 | ### Effect of filters 88 | 89 | From the graph, it can be deduced that the image with the Bartlett-Hanning filter has the lowest MSE and highest 90 | SSIM, showing it has the best image quality. On the other hand, the Barlett filtered image has the 91 | lowest SSIM while the MSE is comparable to the other values, thus, having the worst image 92 | quality. 93 | ![Result sample 5](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample5.JPG) 94 | ![Result sample 2](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample2.PNG) 95 | 96 | 97 | ### Noise Propagation 98 | 99 | When noise is added to left-half or right-half of the radon 100 | transform, the influence seems to be 101 | universal, or at least distributed evenly in the whole picture. The noise added to one half of the 102 | radon transform exists in half of the projections, since R has a shape of (number of detectors, 103 | number of angles). The noise in the final reconstruction is distributed evenly. This is because any 104 | projection selected affects all the point reconstruction in the process of backprojection. 105 | 106 | 107 | The reconstruction shows distinct features in the upper-half and 108 | lower-half parts when we add noise to the upper half or lower half of the radon transform. We 109 | are essentially adding noise to one half of the detectors’ data. For a certain point in an image, most of its 110 | projection will be detected by one half of the detectors only. 111 | 112 | ![Result sample 7](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample7.JPG) 113 | 114 | ### Effect of missing projection 115 | 116 | For the SSIM, it can be seen that the value drop 117 | dramatically when the no. of missing projection increase from 1 to 25, and start flattening after 118 | that. This indicate that the image quality compared to the original phantom will decrease at first 119 | and no longer decrease when the no. of missing projection is large. However, in terms of the 120 | MSE, the value surprisingly drops when the no. of missing projection increases, which is 121 | contradict to the real case. It could be possibly due to the scaling factor that used for every 122 | reconstruction. This scaling factor is strongly related to the number of projection we used. When 123 | there are missing projection, the decrease in projection is unconventional in real cases, which do 124 | not take into account by the reconstruction. And because MSE is strongly depends on the 125 | intensity scaling, therefore the abnormal results happened. This can also be shown that the SSIM 126 | is a better evaluation than MSE here. 127 | 128 | ![Result sample 8](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample8.JPG) 129 | 130 | ### Effect of missing detectors 131 | 132 | The results show that the image quality drop in the similar way as the 133 | effect of missing projection do. From quantify statistics, the SSIM of the image drop rapidly on 134 | first two sets of no. of missing detector and start flattening afterwards. On the other hand, the 135 | value of MSE increase rapidly from 1 to 50 missing detectors and start to slow down afterward. 136 | 137 | ![Result sample 3](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample3.PNG) 138 | 139 | 140 | ### Effect of Gaussian noise in radon domain 141 | 142 | Gaussian noise has a normal distribution in the time domain, and white noise is a random signal 143 | having equal intensity at different frequencies. Therefore, Gaussian white noise should be the 144 | most popular noise in the detection process if there are no big defects in the detector. 145 | Different degree of Gaussian noise was added in the Radon space to analog the noise generated 146 | in the detection process. Sampling interval of 0.1 degree and the ramlak filter (coefficient of 147 | transform=5, cut off frequency=0.5) were used reconstruct all images under the same conditions. 148 | The results are shown below. 149 | 150 | ![Result sample 6](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample6.JPG) 151 | 152 | ### Fan-beam and Pencil-beam 153 | 154 | In order to ensure that our project has practical meaning, we compared the projections of the 155 | phantom using pencil-beam and fan-beam respectively. The two sets of projection data was 156 | obtained by using MATLAB radon and fanbeam functions. Two angles of 45 degrees and 90 157 | degrees were sampled and values in radon domain for different detectors were plotted as below. 158 | We can see that the two projections are close to each other in terms of values and shape. 159 | 160 | ![Result sample 9](https://github.com/bijiuni/CT_reconstruction/blob/master/img/sample9.JPG) 161 | 162 | 163 | ## Authors 164 | 165 | * **Zach Lyu** 166 | 167 | ## Acknowledgments 168 | 169 | * Prof Ed. Wu for supervising the project 170 | * Other group mates: Chui Mei Yee; Dey Poonam Aditi; Fung Chun Hin. 171 | -------------------------------------------------------------------------------- /fan_beam_compare.m: -------------------------------------------------------------------------------- 1 | %{ Compare the performance of pencil-beam and fan-beam CT reconstruction 2 | 3 | % This is a simple program with no function defined 4 | %} 5 | 6 | % Calculate pencil-beam and fan-beam result for a single column 7 | I = phantom(256); D = 200; dtheta = 1; [Farc,FposArcDeg,Fangles] = fanbeam(I,D,'FanSensorGeometry','arc','FanRotationIncrement',dtheta); 8 | 9 | FposArc = D*tan(FposArcDeg*pi/180); 10 | 11 | [R,Rpos]=radon(I,Fangles); 12 | 13 | % Plot the result and compare the performance 14 | figure idx = find(Fangles==90); plot(Rpos,R(:,idx),FposArc,Farc(:,idx)) legend('Radon','Arc') 15 | -------------------------------------------------------------------------------- /img/read: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /img/sample1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample1.PNG -------------------------------------------------------------------------------- /img/sample2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample2.PNG -------------------------------------------------------------------------------- /img/sample3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample3.PNG -------------------------------------------------------------------------------- /img/sample4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample4.jpg -------------------------------------------------------------------------------- /img/sample5.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample5.JPG -------------------------------------------------------------------------------- /img/sample6.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample6.JPG -------------------------------------------------------------------------------- /img/sample7.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample7.JPG -------------------------------------------------------------------------------- /img/sample8.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample8.JPG -------------------------------------------------------------------------------- /img/sample9.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/img/sample9.JPG -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | P = phantom(256); 2 | 3 | reconstruction = FFB(P, 'lowpasscosine', 0.01, 8, 1, 'linear'); 4 | 5 | 6 | 7 | [global_sim, local_sim] = ssim(reconstruction, P); 8 | 9 | %figure, imshow(local_sim,[]) 10 | X = ['SSIM VALUE: ',num2str(global_sim)]; 11 | disp(X); 12 | 13 | err = immse(reconstruction, P); 14 | fprintf('\n The mean-squared error is %0.4f\n', err); 15 | 16 | subplot(1,2,1), imshow(P); 17 | title('original phantom'); 18 | subplot(1,2,2), imshow(reconstruction); 19 | title('reconstruction'); 20 | -------------------------------------------------------------------------------- /own_radon.m: -------------------------------------------------------------------------------- 1 | % Realizing radon transform without using built-in fuction 2 | % param img 3 | % the original image to be radon transformed 4 | % param theta 5 | % the interval of the projection angles 6 | 7 | function processed_img = own_radon(img, theta) 8 | 9 | [n_row, n_column] = size(img); Dia = sqrt(n_row + n_column); row_Pad = ceil(Dia - n_row) + 2; col_Pad = ceil(Dia - n_column) + 2; pad = zeros(n_row+row_Pad, n_column+col_Pad); pad(ceil(row_Pad/2):(ceil(row_Pad/2)+n_row-1), ... ceil(col_Pad/2):(ceil(col_Pad/2)+n_column-1)) = img; 10 | 11 | angle = length(theta); processed_img = zeros(size(pad,2), angle); for i = 1:angle tic tmpimg = imrotate(pad, 90-theta(i), 'bilinear', 'crop'); processed_img(:,i) = (sum(tmpimg))'; theta(i) toc end 12 | -------------------------------------------------------------------------------- /sample1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/sample1.PNG -------------------------------------------------------------------------------- /sample2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/sample2.PNG -------------------------------------------------------------------------------- /sample3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bijiuni/CT_reconstruction/fb38d144d06504033485a5a75eed5c63d060cb87/sample3.PNG --------------------------------------------------------------------------------