本人正在学习OCT成像系统的有关知识,会陆陆续续发表一些总结在这个专栏中,希望借助这个机会对自己学到的东西做一个总结。这篇文章主要参考了汪立宏教授的神作《Biomedical Optics: principles and imaging》,Fujimoto的《Optical Coherence Tomography :Technology and Applications》以及几篇综述文章。Matlab代码为汪教授书中源码,我自己按照思路用Python写了一遍。另外,我会在引用块说一些题外话,觉得罗嗦可以忽略不看哈^_^。欢迎大家一起讨论,如果有不对的地方,希望在评论区告知我,十分感谢!
<hr/>背景介绍
OCT是一种具有非侵入性、高分辨率特性的三维成像系统,其在医学领域特别是眼科发挥着极其重要的作用。第一台时域OCT(Time-domain OCT,TD-OCT)由华人David Huang以及他的导师James G. Fujimoto于1991年发明。1997年S. R. Chinn和其导师Jame G. Fujimoto发明了第一台扫频OCT(Optical coherence tomography using a frequency-tunable optical source)。2002年Maciej Wojtkowski和其导师Adolf F. Fercher发明了第一台傅立叶域OCT(Fourier-domain OCT,FD-OCT)。之后OCT的发展主要是围绕傅立叶域OCT展开。 瞻仰一下OCT领域的大佬们
plt.subplot(4,1,3) #spectrum of the rectified interferogram
Frec_1 = np.fft.fft(I_rec)/np.sqrt(N)# order of frequencies: 0,1...(N/2-1),-N/2,-(N/2-1)...-1
Frec_2 =np.fft.fftshift(Frec_1)#shifted order of frequencies: -N/2,-(N/2-1)...-1, 0,1...(N/2-1)
d_freq = 1/(4*lc) #4=2-(-2) frequency bin size = 1/sampling range
freq=d_freq*np.arange(-N/2,N/2) #frequency array
plt.plot(freq*lambda_0, np.abs(Frec_2), 'k')
plt.title("(c) Spectrum of the rectified interferogram")
plt.xlabel(r"Frequency $\mathregular{(1/\lambda_0)}$")
plt.ylabel("Amplitude")
plt.axis([-10,10,0,5.5])
plt.subplot(4,1,4) #envelope
freq_cut = 1/lambda_0/2 #cut-off frequency for filtering
i_cut = int(round(freq_cut/d_freq)) #convert freq_cut to an array index
F_filt = Frec_1.copy() #initialize array
F_filt[i_cut:N-i_cut+1]=0 #filter
I_filt = np.abs(np.fft.ifft(F_filt))*np.sqrt(N) #amplitude of inverse FFT
I_ac_en = np.exp(-16*ln2*((dl/lc)**2))
plt.plot(dl/lc, I_filt/I_filt.max(), 'k',label="Demodulted")
plt.plot(dl[np.arange(0,N,int(N/32))]/lc, I_ac_en[np.arange(0,N,int(N/32))], 'ro',label="original")
plt.title("( d ) Envelopes")
plt.xlabel(r"$\mathregular{\Delta{l}/l_c}$")
plt.ylabel("Signals")
plt.axis([-0.6,0.6,-1,1.2])
plt.legend()
plt.subplots_adjust(hspace=0.6)
plt.show()
# plt.tight_layout(h_pad=2)TD-OCT(Matlab)
% Use SI units throughout
lambda0 = 830E-9; % center wavelength
dlambda = 60E-9; % bandwidth (delta lambda)
c = 3E8; % speed of light
lc=4*log(2)/pi*lambda0^2/dlambda % coherence length
Number_of_periods = 0.5*lc/(lambda0/2) % # of periods in FWHM
figure(1);
N = 2^12; % number of sampling points
dl = lc*linspace(-2,2, N); % array for Delta_l
k0 = 2*pi/lambda0; % propagation constant
subplot(4, 1 , 1 ) % interferogram
Iac = exp(-16*log(2)*(dl/lc).^2) .* cos(2*k0 * dl);
plot(dl/lc, Iac, 'k')
title('(a) Interferogram')
xlabel('\Deltal/l_c')
ylabel('Signal')
axis([-0.6, 0.6, -1, 1])
subplot(4, 1 , 2 ) % rectified interferogram
Irec = abs(Iac);
plot(dl/lc, Irec, 'k')
title('(b) Rectified interferogram')
xlabel('\Deltal/l_c')
ylabel('Signal')
axis([-0.6, 0.6, -1, 1])
subplot(4, 1 , 3 ) % spectrum of the rectified interferogram
Frec1 = fft(Irec)/sqrt(N);
% order of frequencies: 0,1...(N/2-1),-N/2,-(N/2-1)...-1
Frec2 = fftshift(Frec1);
% shifted order of frequencies: -N/2,-(N/2-1)...-1, 0,1...(N/2-1)
dfreq = 1/(4*lc); % freq bin size = 1/sampling range
freq = dfreq*(-N/2:N/2-1); % frequency array
plot(freq*lambda0, abs(Frec2), 'k')
title('(c) Spectrum of the rectified interferogram')
xlabel('Frequency (1/\lambda_0)')
ylabel('Amplitude')
axis([-10, 10, 0, 5])
subplot(4, 1 , 4 ) % envelope
freq_cut = 1/lambda0/2; % cut-off frequency for filtering
i_cut = round(freq_cut/dfreq); % convert freq_cut to an array index
Ffilt = Frec1; % initialize array
Ffilt(i_cut:N-i_cut+1) = 0; % filter
Ifilt = abs(ifft(Ffilt))*sqrt(N); % amplitude of inverse FFT
plot(dl/lc, Ifilt/max(Ifilt), 'k')
Iac_en = exp(-16*log(2)*(dl/lc).^2); % envelope
hold on;
plot(dl(1:N/32:N)/lc, Iac_en(1:N/32:N), 'ko')
hold off;
title ( ' ( d ) Envelopes')
xlabel ( ' \Deltal/l_c ' )
ylabel('Signals')
axis ([ - 0.6 , 0.6, - 1 , 1])
legend('Demodulated','Original')FD-OCT(Python)
"""
Created on Wed Mar 18 20:25:19 2020
@author: Fuwei
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import (AutoMinorLocator, MultipleLocator)
pi = np.pi
ln2 = np.log(2)
lambda_0 = 830e-9 # center wavelength of source
d_lambda = 20e-9 # FWHM wavelength bandwidth of source
ns=1.38 # refractive index of sample
l_s1 = 100e-6 # location of backscatterer 1
l_s2 = 150e-6 # location of backscatterer 2
r_s1 = 0.5 # reflectivity of backscatterer 1
r_s2 = 0.25 # reflectivity of backscatterer 2
k_0=2*pi/lambda_0 # center propagation constant
delta_k=2*pi*d_lambda/lambda_0**2 # FWHM bandwidth of k
sigma_k = delta_k/np.sqrt(2*ln2) # standard deviation of k
N=2**10 # number of sampling points
nsigma = 5 # number of standard deviations to plot on each side of kO
plt.figure(1)
plt.suptitle("FD-OCT Simulation",fontsize=25,fontweight=800)
plt.subplot(4,1,1) # Generate the interferogram
k = k_0 + sigma_k*np.linspace(-nsigma,nsigma, N) # array for k
S_k = np.exp(-(1/2)*((k-k_0)**2)/(sigma_k**2)) # Gaussian source PSD
E_s1 = r_s1*np.exp(2j*k*ns*l_s1) # sample electric field from scatter 1
E_s2 = r_s2*np.exp(2j*k*ns*l_s2) # sample electric field from scatter 2
I_k1 = S_k * np.abs(1 + E_s1 + E_s2)**2 # interferogram (r_R = 1)
plt.plot(k/k_0,I_k1/I_k1.max(), 'k')
plt.title('(a)Interferogram')
plt.xlabel(r'Propagation constant $\mathregular{k/k_0}$')
plt.ylabel('Normalized intensity')
plt.axis([0.9,1.1,0,1.1])
plt.subplot(4,1,2) # Inverse Fourier transform (IFT) of the interferogram
spec1 =np.abs(np.fft.fftshift(np.fft.ifft(I_k1)))/np.sqrt(N)
d_ls_prime = 1/(2*nsigma*sigma_k/(2*pi)) # bin = 1/sampling range
ls_prime = d_ls_prime*np.arange(-N/2,N/2)# frequency array
plt.plot(ls_prime/(2*ns),spec1/spec1.max(), 'k') # scale the frequency
plt.title('(b)IFT of the interferogram')
plt.xlabel(r"Depth $\mathregular{I_s}$ (m)")
plt.ylabel('Relative reflectivity')
plt.gca().xaxis.get_major_formatter().set_powerlimits((0,1))
plt.axis([-2*l_s2,2*l_s2,0,1.1])
plt.subplot(4,1,3); # IFT of the deconvolved interferogram
spec1_norm =np.abs(np.fft.fftshift(np.fft.ifft(I_k1/S_k)) )/np.sqrt(N)
d_ls_prime = 1/(2*nsigma*sigma_k/(2*pi)) # bin size = 1/sampling range
ls_prime = d_ls_prime*np.arange(-N/2,N/2) # frequency array
plt.plot(ls_prime/(2*ns),spec1_norm/spec1_norm.max(), 'k')
plt.title('IFT of the deconvolved interferogram')
plt.xlabel(r'Depth $\mathregular{I_s}$ (m)')
plt.ylabel('Relative reflectivity')
plt.axis([-2*l_s2,2*l_s2,0,1.1])
plt.gca().xaxis.get_major_formatter().set_powerlimits((0,1))
plt.subplot(4,1,4) # IFT of the deconvolved differential interferogram
I_k2 = S_k * np.abs(-1 + E_s1 + E_s2)**2 # interferogram
delta_I_k = I_k1 - I_k2
spec2=np.abs(np.fft.fftshift(np.fft.ifft(delta_I_k/S_k)))/np.sqrt(N)
plt.plot(ls_prime/(2*ns),spec2/spec2.max(), 'k')
plt.title('IFT of the deconvolved differential interferogram')
plt.xlabel("Depth $\mathregular{I_s}$ (m)")
plt.ylabel('Relative reflectivity')
plt.axis([-2*l_s2,2*l_s2,0,1.1])
plt.gca().xaxis.get_major_formatter().set_powerlimits((0,1))
plt.subplots_adjust(hspace=0.6)
plt.show()FD-OCT(Matlab)
% Use SI units throughout
lambda0 = 830E-9; % center wavelength of source
dlambda = 20E-9; % FWHM wavelength bandwidth of source
ns=1.38; % refractive index of sample
ls1 = 100E-6; % location of backscatterer 1
ls2 = 150E-6; % location of backscatterer 2
rs1 = 0.5; % reflectivity of backscatterer 1
rs2 = 0.25; % reflectivity of backscatterer 2
k0=2*pi/lambda0; % center propagation constant
delta_k=2*pi*dlambda/lambda0^2; % FWHM bandwidth of k
sigma_k = delta_k/sqrt(2*log(2)); % standard deviation of k
N=2^10; % number of sampling points
nsigma = 5; % number of standard deviations to plot on each side of kO
subplot(4,1,1); % Generate the interferogram
k = k0 + sigma_k*linspace(-nsigma,nsigma, N); % array for k
S_k = exp(-(1/2)*(k-k0).^2/sigma_k^2); % Gaussian source PSD
E_s1 = rs1*exp(i*2*k*ns*ls1); % sample electric field from scatter 1
E_s2 = rs2*exp(i*2*k*ns*ls2); % sample electric field from scatter 2
I_k1 = S_k .* abs(1 + E_s1 + E_s2).^2; % interferogram (r_R = 1)
plot(k/k0,I_k1/max(I_k1), 'k');
title('Interferogram');
xlabel('Propagation constant k/k_0');
ylabel('Normalized intensity');
axis([0.9 1.1 0 1]);
subplot(4,1,2); % Inverse Fourier transform (IFT) of the interferogram
spec1 =abs(fftshift(ifft(I_k1)))/sqrt(N);
dls_prime = 1/(2*nsigma*sigma_k/(2*pi)); % bin = 1/sampling range
ls_prime = dls_prime*(-N/2:N/2-1); % frequency array
plot(ls_prime/(2*ns),spec1/max(spec1), 'k'); % scale the frequency
title('IFT of the interferogram');
xlabel('Depth I_s (m)');
ylabel('Relative reflectivity');
axis([-2*ls2 2*ls2 0 1]);
subplot(4,1,3); % IFT of the deconvolved interferogram
spec1_norm =abs(fftshift(ifft(I_k1./S_k)) )/sqrt(N);
dls_prime = 1/(2*nsigma*sigma_k/(2*pi)); % bin size = 1/sampling range
ls_prime = dls_prime*(-N/2:N/2-1); % frequency array
plot(ls_prime/(2*ns),spec1_norm/max(spec1_norm), 'k');
title('IFT of the deconvolved interferogram');
xlabel('Depth I_s (m)');
ylabel('Relative reflectivity');
axis([-2*ls2 2*ls2 0 1]);
subplot(4,1,4); % IFT of the deconvolved differential interferogram
I_k2 = S_k .* abs(-1 + E_s1 + E_s2).^2; % interferogram
delta_I_k = I_k1 - I_k2;
spec2=abs(fftshift(ifft(delta_I_k./S_k)))/sqrt(N);
plot(ls_prime/(2*ns),spec2/max(spec2), 'k');
title('IFT of the deconvolved differential interferogram');
xlabel("Depth I_s ( m )");
ylabel('Relative reflectivity') ;
axis([-2*ls2 2*ls2 0 1]);<hr/>推荐书籍