用 Matlab 实现 GS 算法设计计算全息图

1 全息术以及计算全息

  • 什么是全息术
    全息是利用干涉和衍射原理记录并再现物体光波波前的一种技术,也称为全息术、全息照相、全息照相技术。全息术利用干涉和衍射原理,把物光波以干涉条纹的形式记录下来,在一定条件下使其衍射再现,成与原物体相似的三维图像。全息照相把物光波的强度分布和位相分布都完整的记录下来,即是记录了物体的全部信息(而普通照相只能记录物光波的强度分布)。
    全息术由丹尼斯·盖伯于1948年提出,随后用实验证实这一想法,并制成世界上第一张全息图。盖伯本来是为提高电子显微镜的分辨率而提出的设想,虽然未能用电子波证实其原理,但用可见光证实了。

用 Matlab 实现 GS 算法设计计算全息图_第1张图片

  • 全息术的发展历程
阶段 特征 优缺点 主要成就
第一阶段 汞灯记录,同轴全息 缺点:无相干光源,衍射像无法分离 提出全息术
第二阶段 激光记录,激光再现 优点:相干光源 缺点:图像无色彩 离轴全息
第三阶段 激光记录,白光再现 优点:相干光源,有色彩 像全息,彩虹全息,模压全息
第四阶段 白光记录,白光再现 优点:条件放宽,更加实用 研究阶段
  • 计算全息
    计算全息术是全息术的一个重要分支。六十年代初全息术开始发展后不久,计算全息术即随之出现。它与一般全息术(光学全息)的区别主要在于:全息记录与再现过程的一部分由计算机取代。根据所取代部分的不同,又可分为计算机产生的全息图和全息图的计算机再现两种,通常都简称为计算全息。

2 GS算法

  • 什么是GS算法
    如图所示,光源经过衍射元件 A,叠加 A 的相位 φ,经过傅里叶变换,得到右侧上半部分的模糊笑脸图案,我们的目的要使得到的图案接近右下笑脸,GS算法的目的就是计算出我们要叠加的相位 φ。要实现这一目的,我们去除经傅里叶变换得到图像的振幅,以目标图像振幅代替,进行逆傅里叶变换得到相位 φ,以此循环,最终得到想要的位相图 φ。

用 Matlab 实现 GS 算法设计计算全息图_第2张图片

  • GS算法流程
    具体步骤如下:选择初始复振幅分布 g 0 ( x , y ) = ∣ f ( x , y ) ∣ e x p [ j θ ( x , y ) ] g_{0}(x,y)=\left | f(x,y) \right |exp\left [ j\theta (x,y) \right ] g0(x,y)=f(x,y)exp[jθ(x,y)],其中 ∣ f ( x , y ) ∣ \left | f(x,y) \right | f(x,y),为所预设衍射图案振幅分布, θ ( x , y ) \theta (x,y) θ(x,y) [ 0 ∼ 2 π ] \left [ 0\sim 2\pi \right ] [02π]范围随机分布函数。在第 N 次迭代时,对分布 g j ( x , y ) g_{j}(x,y) gj(x,y)进行逆傅里叶变换,令振幅部分为单位1,由此得到新分布函数。之后再进行傅里叶变换,得到 g j ‾ ( x , y ) \overline{g_{j}}(x,y) gj(x,y),令 ∣ g j + 1 ‾ ( x , y ) ∣ = ∣ f ( x , y ) ∣ \left | \overline{g_{j+1}}(x,y) \right |=\left | f(x,y) \right | gj+1(x,y)=f(x,y),由此得到经过一次迭代后的值,同时将其作为下一次迭代的初始分布。
    重复上述迭代过程,直到迭代精度达到事先设定的迭代退出条件:迭代的结果达到设定的精度或者达到最大迭代次数,最后得到的位相分布 G j ( ξ , η ) ‾ \overline{G_{j}(\xi ,\eta )} Gj(ξ,η),即所设计的衍射元件位相分布。

用 Matlab 实现 GS 算法设计计算全息图_第3张图片
用 Matlab 实现 GS 算法设计计算全息图_第4张图片

  • GS算法的改进
    GS算法编程简单,但其收敛速度与精确度对初始条件的选取比较敏感,且容易陷入局部最优问题。因此,Fienup 等在GS算法的基础上提出了一种改进算法,这种算法对重建的光场分布 g j ‾ ( x , y ) \overline{g_{j}}(x,y) gj(x,y)进行处理时增加了反馈过程,从而达到快速收敛目的。
    在第 j 次迭代时,定义 g j ‾ ( x , y ) ′ {\overline{g_{j}}(x,y)}' gj(x,y)为目标分布函数 ∣ f ( x , y ) ∣ \left | f(x,y) \right | f(x,y)与实际重建光分布 g j ‾ ( x , y ) \overline{g_{j}}(x,y) gj(x,y)的差值,即 g j ‾ ( x , y ) ′ = ∣ f ( x , y ) ∣ − g j ‾ ( x , y ) {\overline{g_{j}}(x,y)}'=\left | f(x,y) \right |-\overline{g_{j}}(x,y) gj(x,y)=f(x,y)gj(x,y),然后引入反馈参量 k ∈ [ 0 , 1 ] k\in \left [ 0,1 \right ] k[0,1],将下一次迭代的初始振幅分布设为 ∣ f ( x , y ) ∣ + g j ‾ ( x , y ) ′ k \left | f(x,y) \right |+{\overline{g_{j}}(x,y)}'k f(x,y)+gj(x,y)k
    这样做的优点是在第 j 次迭代过程中,无论重建光场分布与预设分布误差如何,都能使最终重建光场分布快速收敛于预设值。

3 Matlab程序设计

3.1 位相型全息图

  • 实验用图

用 Matlab 实现 GS 算法设计计算全息图_第5张图片

  • 程序代码
%第一步:抽样
image0 = imread('Hepburn.jpg');
%转为灰度图(若已为灰度图则忽略)
%image0 = rgb2gray(image0);
image0 = im2double(image0);
[M,N] = size(image0);

%输出原图
figure;
subplot(2,2,1);
imshow(image0);
title('原图')

%加入随机位相信息
PI = 3.14159;
image1 = image0;
phase = 2i*PI*rand(M,N);
image1 = image1.*exp(phase);

%输出随机位相图
subplot(2,2,2);
imshow(image1);
title('随机位相图');

%第二步:计算编码
%第一次逆傅里叶变换
image2 = ifft2(ifftshift(image1));

%迭代过程
for t=1:1:1000
    %迭代判据
    imgangle = angle(image2);                       %取位相
    image = exp(1i*imgangle);
    image = fftshift(fft2(image));                  %还原
    imgabs = abs(image)/max(max(abs(image)));
    sim = corrcoef(image0,imgabs);                  %取相关系数
    if sim(1,2) >= 0.9995
        %满足条件,跳出循环
        break
    else
        %开始迭代
        %单位振幅
        imgangle = angle(image2);
        image2 = exp(1i*imgangle);

        %正傅里叶变换
        image3 = fftshift(fft2(image2));

        %赋反馈振幅
        imgabs = abs(image3)/max(max(abs(image3)));
        imgangle = angle(image3);
        image3 = exp(1i*imgangle);
        image3 = image3.*(image0+rand(1,1)*(image0-imgabs));

        %逆傅里叶变换
        image2 = ifft2(ifftshift(image3));
        
    end
end

%第三步:输出位相全息图
%取位相
imgangle = angle(image2);                       
image4 = exp(1i*imgangle);

%还原
image4 = fftshift(fft2(image4));                          
imgabs = abs(image4)/max(max(abs(image4)));

%存储位相全息图
imgangle = (imgangle+PI)/(2*PI);
imwrite(imgangle,'Hepburn.jpg')

%输出位相全息图
subplot(2,2,3);
imshow(imgangle);
title('位相全息图')

%输出还原图
subplot(2,2,4);
imshow(imgabs);
title('还原图')
  • 过程输出图

用 Matlab 实现 GS 算法设计计算全息图_第6张图片

3.2 振幅型全息图

  • 实验用图

用 Matlab 实现 GS 算法设计计算全息图_第7张图片

  • 程序代码
%第一步:抽样
image0 = imread('Ironman.jpg');
%转为灰度图(若已为灰度图则忽略)
image0 = rgb2gray(image0);
image0 = im2double(image0);
[M,N] = size(image0);

%输出原图
figure;
subplot(2,2,1);
imshow(image0);
title('原图')

%加入随机位相信息
PI = 3.14159;
image1 = image0;
phase = 2i*PI*rand(M,N);
image1 = image1.*exp(phase);

%输出随机位相图
subplot(2,2,2);
imshow(image1);
title('随机位相图');

%第二步:计算编码
%第一次逆傅里叶变换
image2 = ifft2(ifftshift(image1));

%迭代过程
for t=1:1:1000
    %迭代判据
    imgangle = angle(image2);                       %取位相
    image = exp(1i*imgangle);
    image = fftshift(fft2(image));                  %还原
    imgabs = abs(image)/max(max(abs(image)));
    sim = corrcoef(image0,imgabs);                  %取相关系数
    if sim(1,2) >= 0.9995
        %满足条件,跳出循环
        break
    else
        %开始迭代
        %单位振幅
        imgangle = angle(image2);
        image2 = exp(1i*imgangle);

        %正傅里叶变换
        image3 = fftshift(fft2(image2));

        %赋反馈振幅
        imgabs = abs(image3)/max(max(abs(image3)));
        imgangle = angle(image3);
        image3 = exp(1i*imgangle);
        image3 = image3.*(image0+rand(1,1)*(image0-imgabs));

        %逆傅里叶变换
        image2 = ifft2(ifftshift(image3));
        
    end
end

%第三步:输出振幅全息图
%取实部
imgreal = real(image2);                       
image = mat2gray(imgreal);

%还原
image4 = fftshift(fft2(imgreal));                          
imgabs = abs(image4)/max(max(abs(image4)));

%输出位相全息图
subplot(2,2,3);
imshow(image);
title('振幅全息图')

%输出还原图
subplot(2,2,4);
imshow(imgabs);
title('还原图')

%保存振幅全息图
imwrite(image,'Ironman.bmp')
  • 过程输出图

用 Matlab 实现 GS 算法设计计算全息图_第8张图片

你可能感兴趣的:(Matlab,GS算法,计算全息,Matlab)