模拟哈特曼波前探测器

这是模拟哈特曼波前探测器的另一份代码,这里不需要设置微透镜的参数。

波前 ==> 光点,使用的是 离散一维DFT对应的fft(,),而不是 二维FFT对应的 fft2(),最大的优点是运算速度极快,其原因是 不需要通过双循环分别对 某个子透镜形成光点处理,利用并行运算直接得到整个微透镜的最终形成的光点阵。

也可以参考OOMAO中的哈特曼波前探测的模拟源码,源码见:

GitHub - rconan/OOMAO: Object-Oriented, Matlab & Adaptive Optics

clc;clear all; close all
% function wavePrgted = propagateThrough1(obj,src_in)
%{
for a given wave of size [n, n],   full width at half maximum (FWHM)
nyquistSampling = 1, means 2 pixels per fhwm obtained by setting fftPad = 2,
FHWM 占据两个像素,可通过fftPad = 2 完成设置
fieldStopSize should be set to default 单子透镜分辨率 = n/nLenslet;
        
nyquistSampling = 0.5, means 1 pixels per fhwm obtained by setting fftPad = 1, 
fieldStopSize should be set to default n/nLenslet/nyquistSampling/2

下面用的是 fft(A,) 而不是使用fft(fftshift(A) , ),
fft(),操作使用 有用的信息在四周,而不是中央,故
v((0:nLensletImagePx-1)+centerIndex-halfLength) ...
                    = false; 
半宽高度的范围就是在四周,v设置mask的时候就中心部分的非半宽高度区域内的数据 清除掉 

%}   

nLenslet            = 10;           % 微透镜个数
nLensletImagePx     = 10;           % 单个子透镜分辨率
nLensletsImagePx    = nLenslet * nLensletImagePx;

%% 给出一个湍流波前,必须是弧度单位。 波长为1.215um,==》 rad,乘以系数0.1934

real_coe = [ ...
    -0.0804, 1.5517,-1.7531, 0.7195, 0.3470, 0.1209, 0.0477, 0.4413, 0.0409,-0.0088...
    -0.1640, 0.0846,-0.0254, 0.0734,-0.1656,-0.2289, 0.1348,-0.0130, 0.0624,-0.1272...
    -0.0083, 0.0949, 0.0321, 0.0319, 0.0067,-0.0526,-0.0635,-0.0137,-0.0004, 0.0381...
    -0.0893,-0.0089, 0.0125,-0.0202,-0.0010,-0.0220];

num = numel(real_coe);
Znm = zeros(nLensletsImagePx,nLensletsImagePx,num);       % 初始化像差函数
for i= 1:num
    Znm(:,:,i) = Zernike(i,nLensletsImagePx);% 调用Zernike多项式函数
end
WF = reshape(Znm,[nLensletsImagePx*nLensletsImagePx,num]) * real_coe';
WF = reshape(WF,[nLensletsImagePx,nLensletsImagePx]);     % 系数和对应多项式的线性叠加后的结果

%% 给出一个mask,也就是振幅pupil
x                   = linspace(-1,1,nLensletsImagePx);
[X,Y]               = meshgrid(x,x);
rho                 = sqrt(X.*X + Y.*Y);
rho(rho>1)          = 0;
rho(rho ~=0)        = 1;
mask                = rho * 14.9; % 为啥乘以14.9,我也不清楚哦
val                 = bsxfun( @times , mask , exp(1i*WF) ); % 复振幅

figure(2);
subplot(131);imagesc(WF);colormap(jet);colorbar;title('zernike生成的波前,单位rad')
subplot(132);imshow(val, []);colormap(jet);colorbar;title('振幅.*exp(i * 弧度下的相位)')
subplot(133);imagesc(angle(val));colormap(jet);colorbar;title('angle作用的对象的单位 必须 是弧度')

%% 波前 == > PSF,满足奈奎斯特采样,需要设置像面大小
[nLensletsWavePx,nLensletsWavePxNGuideStar,nWave] ...
                    = size(val);
nLensletsWavePxNGuideStar ... 
                    = nLensletsWavePxNGuideStar*nWave;
val                 = reshape(val,nLensletsWavePx,nLensletsWavePxNGuideStar);
nLensletWavePx      = nLensletsWavePx ./ nLenslet;
nLensletArray       = nLensletsWavePxNGuideStar/nLensletsWavePx;
fftPad              = 2;                        % 采样,nyquistSampling = 1
nOutWavePx          = nLensletWavePx * fftPad;  % 采样前 单个子透镜形成的PSF在像平面坐标区域
evenOdd             = rem(nLensletWavePx,2);
if ~rem(nOutWavePx,2) && evenOdd
    nOutWavePx = nOutWavePx + evenOdd;
end
nOutWavePx          = max(nOutWavePx,nLensletWavePx);
nLensletSquareWavePx ...
                    = nLensletWavePx * nLenslet^2 * nLensletArray;
wavePrgted          = zeros(nOutWavePx,nLensletSquareWavePx);
val                 = val ./ nOutWavePx;

%% get fftPhasor
nOutWavePx      = nLensletWavePx * fftPad;    % Pixel length of the output wave
evenOdd         = rem(nLensletWavePx,2);
if ~rem(nOutWavePx,2) && evenOdd
    nOutWavePx  = nOutWavePx + evenOdd;
end
nOutWavePx      = max(nOutWavePx,nLensletWavePx);

% shift the intensity of half a pixel for even sampling
[u,v]           = ndgrid((0 : (nLensletWavePx-1)) .* (~rem(nLensletWavePx,2)-nOutWavePx)./nOutWavePx);
fftPhasor       = repmat( exp(-1i.*pi.*(u+v)) , nLenslet, nLenslet );
% figure(3);imshow(fftPhasor,[]);colormap(jet);colorbar;
  
if isempty(fftPhasor)
    % Shape the wave per columns of lenslet pixels
    % 为lensletd 每列像素 塑造波形
    val             = reshape(val,nLensletWavePx,nLensletSquareWavePx);
    u               = any(val); % Index of non-zeros columns
    wavePrgted(:,u) = fftshift(fft(val(:,u),nOutWavePx),1);
    % Select the field of view
    v               = [];
    if nOutWavePx   > nLensletImagePx
        centerIndex = ceil((nOutWavePx+1)/2);
        halfLength  = floor(nLensletImagePx/2);
        v           = true(nOutWavePx,1);
        v((0:nLensletImagePx-1)-halfLength+centerIndex) ...
                    = false;
    elseif nOutWavePx<nLensletImagePx
        error('lensletArray:propagateThrough:size','The computed image is smaller than the expected image!')
    end
    wavePrgted(v,:) = [];
    % Back to transpose 2D
    val             = reshape( wavePrgted ,...
                                nLensletsImagePx,nLensletWavePx*nLenslet*nLensletArray).';
    figure(2);imshow((val),[]);colormap(jet);colorbar
    % Shape the wave per rows of lenslet pixels
    val             = reshape(val,nLensletWavePx,nLensletsImagePx*nLenslet*nLensletArray);
    u               = any(val); % Index of non-zeros columns
    wavePrgted      = zeros(nOutWavePx,nLensletsImagePx*nLenslet*nLensletArray);
    wavePrgted(:,u) = fftshift(fft(val(:,u),nOutWavePx),1);
    wavePrgted(v,:) = [];

else
    %% 
    val             = val.*repmat(fftPhasor,1,nLensletArray);
    val             = reshape(val,nLensletWavePx,nLensletSquareWavePx);
    u               = any(val); % Index of non-zeros columns
    wavePrgted(:,u) = fft(val(:,u),nOutWavePx);
    
    v               = []; 
   
    
    if nOutWavePx   > nLensletImagePx
        centerIndex = ceil((nOutWavePx+1)/2) + rem(nLensletWavePx,2);
        halfLength  = floor(nLensletImagePx/2);
        v           = true(nOutWavePx,1);
        v((0:nLensletImagePx-1)+centerIndex-halfLength) ...
                    = false; % fft()操作后 能量集中在四周,此时要把中心区域的数据去除掉(对应半宽高度之外的区域)
    elseif nOutWavePx<nLensletImagePx
        error('lensletArray:propagateThrough:size','The computed image is smaller than the expected image!')
    end
        wavePrgted(v,:) = [];
        % Back to transpose 2D
        val             = reshape( wavePrgted ,...
                                nLensletsImagePx,nLensletWavePx*nLenslet*nLensletArray).';
        % Shape the wave per rows of lenslet pixels
        val             = reshape(val,nLensletWavePx,nLensletsImagePx*nLenslet*nLensletArray);
        u               = any(val); % Index of non-zeros columns
        wavePrgted      = zeros(nOutWavePx,nLensletsImagePx*nLenslet*nLensletArray);
        wavePrgted(:,u) = fft(val(:,u),nOutWavePx);
        wavePrgted(v,:) = []; % fft()操作后 能量集中在四周,此时要把中心区域的数据去除掉(对应半宽高度之外的区域)
end
% Back to transpose 2D
wavePrgted  = reshape(wavePrgted,nLensletsImagePx*nLensletArray,nLensletsImagePx).';
[n,m]       = size(wavePrgted);
wavePrgted  = reshape(wavePrgted,[n,m/nWave,nWave]);
psf         = wavePrgted.*conj(wavePrgted);

figure(4);
subplot(121);imagesc(WF);colormap(jet);colorbar;title('平面波')
subplot(122);imagesc(psf);colormap(jet);colorbar;title('对应的光点阵图像')


左侧是像差,右侧是光点阵。 

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值