利用GS,TIE,改进型角谱迭代算法进行相位恢复
角谱传播理论可以翻阅傅里叶光学的书,就能找到定量分析的计算公式,可以分析某个平面的角谱垂直传播到另外一个平面的角谱,得到其振幅与相位信息。下面把一张图的当作一个平面的相位信息,振幅置为恒1,(即相位物体),取d=10,20,30这三个距离根据角谱传播理论计算衍射图,如下:第一张为原图(d=0),2,3,4分别为传播距离d=10,20,30mm处的衍射图。
以上所得图片2-4均只包含了强度信息,没有相位信息,要用以上图片推回图1(相位物体),有两种基本方法:GS和TIE。融合进角谱传播理论,可以得到四种算法,分别是:
1.改进型角谱迭代算法;
2.TIE强度传输方程直接重建;
3.TIE方程所得相位作为角谱迭代算法初始值进行迭代恢复;
4.GS算法所得相位作为角谱迭代算法初始值进行迭代恢复;
使用matlab根据算法思想写代码,得到其恢复的相位效果如下所示:
一开始只想着从网上找到现成的代码来实现自己的目的,后来发现这并不是很可靠。虽然可以找到一些,但是不全,而且大部分不适用。最好的办法是自己先了解了理论知识,知道大概有哪几种方法,然后看相关的论文别人是怎么做的。一般情况下别人都会在论文中写出自己实现的算法思想,但不会给出代码。想要实现,就得根据他的算法自己写代码。在有了理论支撑的基础上,我们可以直接找到能够实现我们目标的计算式或算法流程图,对照每一个量设定变量,一个个写出来,然后进行相关运算,就可以了。
注意:1.第一次写出来总会存在问题,要会步进调式,看看每一步得到的数据有没有异常,异常就得排除和修改。
2.注意处理数据时在必要的时候必须归一化,不然总会出错或者效果不理想。
上面用的图是2021.12.26考研那天在酒店午休时拍的照片,当时考完数学有点丧气,天气很冷,房间已经退了,坐在前台客厅,前台服务员问了我冷不冷,要不要开暖气,瞬间暖到我了。幸而结果是好的,留念。
以上方法参考文献:
1.一种基于角谱理论的改进型相位恢复迭代算法_刘宏展
2.强度传输方程和角谱迭代融合的相位检索算法_程鸿
2022.7.4
本来不打算更新代码,因为是我做毕业设计的部分内容,但由于有网友有需求,且现在毕业了,特地在此更新一下代码。如果对你有帮助的话,还请点赞+收藏哟。
1.改进型角谱迭代算法
%% 自己写的根据角谱迭代法进行相位恢复
clc,clear
close all
%% 参数初始化
lambda=632.8e-6;%波长
d=20;%衍射距离mm
N=256;%像素
PIESIZE=8e-3;%像素大小
L=N*PIESIZE;%长宽
k=2*pi/lambda;%波矢
step=500;%迭代次数
loss=ones(step,1);%MSE
psn=zeros(step,1);%psnr
b=1.1;%修正量
a=0.8;
gk=zeros(N,N);
minloss=1;
%% 读入
A0=im2double(imread('3d=20.tif'));
A=ones(N,N);
phasek=2*pi.*rand(N,N);%给出随机的初始相位
phasek1=phasek;
Ei=A.*exp(1j.*phasek);%初始的角谱面
%figure;
%imshow(angle(Ei));
figure;
%% 频域初始化
[x,y,~]=size(Ei);
fX=[0:fix(x/2),ceil(x/2)-1:-1:1]./L;
fY=[0:fix(y/2),ceil(y/2)-1:-1:1]./L;
[fx,fy]=meshgrid(fX,fY);
%% 角谱传播函数
f=fx.^2+fy.^2;
H=exp(1j*k*d.*sqrt(1-(lambda*lambda).*(f)));
HB=1./H;
tic
%% 开始迭代
for n=1:step
EOO=ifft2((fft2(Ei)).*H);
AOO=abs(EOO).^2;
AOO=AOO./max(max(AOO));
EO=A0.*exp(1j.*angle(EOO));%angle(EOO)是新计算得到的新相位 (像面)
Eii=ifft2((fft2(EO)).*HB);
faik=angle(Eii); %计算得到的新相位 (物面)
faik=faik./max(max(faik));
beitak=(phasek-phasek1);
%abk=(A0-AOO)./pi./2;
if n>1
gk1=gk;
gk=faik-phasek;
rk=sum((gk.*gk1),"all")/(sum((gk1.^2),"all"));%abs
phasek1=phasek;
phasek=faik+beitak*rk;
phasek=phasek./max(max(phasek));
else
gk=faik-phasek;
phasek=faik;
end
Ei=exp(1j*phasek);
loss(n)=immse(A0,AOO);
psn(n)= 10 * log10(1/loss(n));
imshow(faik);
if loss(n)
2.TIE强度传输方程直接求解
clear all;
clc;
close all;
%% TIE强度传输方程进行相位恢复
piesize=8e-3;%像素大小
L= 564*piesize; %相位物体的长
W= 564*piesize; %相位物体的宽 512
lambda=632.8e-6 ;%光源波长
k=2*pi/lambda;
d=20;%衍射距离
I1=im2double(imread('1d=10.tif'));
I2=im2double(imread('1d=20.tif'));
I3=im2double(imread('1d=30.tif'));
diaotaz=10;%衍射图之间的距离
D=(I3-I1)./(2*diaotaz);
[x, y, ~] = size(I2); %size返回行数和列数。r_dim为行数,c_dim为列数,~占位,表示只要行和列的值
fX = [0:fix(x/2),ceil(x/2)-1:-1:1]/L;%fix向下取整,ceil向上取整 %linspace(-x/2,x/2-1,x)/L;
fY = [0:fix(y/2),ceil(y/2)-1:-1:1]/L;%linspace(-y/2,y/2-1,y)/L;%
[fy,fx] = meshgrid(fY,fX);
q=fx.^2+fy.^2;
pesai=ifft2(q).*fft2(k.*D);
H=exp(1j*k*d.*sqrt(1-(lambda*lambda).*(q)));
HB=1./H;
a=ifft2(gradient((gradient(pesai))./I2));
a=a/max(max(a));
m=ifft2(q);
phase=-m.*a;
phase=phase/max(max(phase));
EO=I2.*exp(1j.*phase);
Ei=ifft2((fft2(EO)).*HB);
faik=angle(Ei);
faik=abs(faik);
faik(find(faik==0))=0.01;%去除矩阵中等于0的点
faik=faik/max(max(faik));
% faik=sqrt(faik);
faik=mat2gray(faik);%%利用TIE强度传输方程计算得到的相位信息
figure;
imshow(faik);
imwrite(faik,'d=20tie.tif');
3.TIE方程所得相位作为角谱迭代算法初始值进行迭代恢复
clear all;
clc;
close all;
%% TIE强度传输方程进行相位恢复
piesize=8e-3;%像素大小
L= 564*piesize; %相位物体的长
W= 564*piesize; %相位物体的宽 512
lambda=632.8e-6 ;%光源波长
k=2*pi/lambda;
d=20;%衍射距离
I1=im2double(imread('1d=10.tif'));
I2=im2double(imread('1d=20.tif'));
I3=im2double(imread('1d=30.tif'));
diaotaz=10;%衍射图之间的距离
D=(I3-I1)./(2*diaotaz);
[x, y, ~] = size(I2); %size返回行数和列数。r_dim为行数,c_dim为列数,~占位,表示只要行和列的值
fX = [0:fix(x/2),ceil(x/2)-1:-1:1]/L;%fix向下取整,ceil向上取整 %linspace(-x/2,x/2-1,x)/L;
fY = [0:fix(y/2),ceil(y/2)-1:-1:1]/L;%linspace(-y/2,y/2-1,y)/L;%
[fy,fx] = meshgrid(fY,fX);
q=fx.^2+fy.^2;
pesai=ifft2(q).*fft2(k.*D);
H=exp(1j*k*d.*sqrt(1-(lambda*lambda).*(q)));
HB=1./H;
a=ifft2(gradient((gradient(pesai))./I2));
a=a/max(max(a));
m=ifft2(q);
phase=-m.*a;
phase=phase/max(max(phase));
EO=I2.*exp(1j.*phase);
Ei=ifft2((fft2(EO)).*HB);
faik=angle(Ei);
faik=abs(faik);
faik(find(faik==0))=0.01;%去除矩阵中等于0的点
faik=faik/max(max(faik));
% faik=sqrt(faik);
faik=mat2gray(faik);%%利用TIE强度传输方程计算得到的相位信息
figure;
imshow(faik);
imwrite(faik,'d=20tie.tif');
%% 加速角谱迭代法 开始迭代 tie恢复的相位作为角谱的输入相位迭代
step=300;
loss=ones(step,1);%MSE
psn=zeros(step,1);%psnr
N=564;%
gk=zeros(N,N);
minloss=1;
%% 读入
A0=I2;
%A0=sqrt(A0);
%A0=A0./max(max(A0));
A=ones(N,N);
phasek=2*pi.*rand(N,N);
phasek1=phasek;
Ei=A.*exp(1j.*faik);%初始的物面
figure;
tic
for n=1:step
EOO=ifft2((fft2(Ei)).*H);
AOO=abs(EOO).^2;
AOO=AOO./max(max(AOO));
EO=A0.*exp(1j.*angle(EOO));%新相位 像面
Eii=ifft2((fft2(EO)).*HB);
faik=angle(Eii); %新相位 物面
faik=faik./max(max(faik));
beitak=(phasek-phasek1);
%abk=(A0-AOO)./pi./2;
if n>1
gk1=gk;
gk=faik-phasek;
rk=sum((gk.*gk1),"all")/(sum((gk1.^2),"all"));%abs
phasek1=phasek;
phasek=faik+beitak*rk;
phasek=phasek./max(max(phasek));
else
gk=faik-phasek;
phasek=faik;
end
Ei=exp(1j*phasek);
loss(n)=immse(A0,AOO);
psn(n)= 10 * log10(1/loss(n));
imshow(faik);
if loss(n)
4.GS算法所得相位作为角谱迭代算法初始值进行迭代恢复;
close all;clear all;clc; %
iterative=1000; %设迭代次数为300次吧
imagename='1d=20.tif'; %你想要提取相位的图像名称
phaseimage='1.tif'; %要保存的相位图像名称
figure(1),imshow(imagename);
%空域输入图像的幅度(是已知的,也就是清晰的图像,它的灰度就是幅值)和相位图像(待恢复)
known_abs_spatial=imread(imagename); %作为输入图像的幅度,是已知的
%known_abs_spatial =rgb2gray(known_abs_spatial);%注意要用单通道图像做实验,如果你读取的是彩色图像,那就吧这行取消注释变成灰度图像吧
known_abs_spatial=im2double(known_abs_spatial); %将图像灰度映射到0~1
unknown_phase=known_abs_spatial; %Peppers图像作为输入图像的相位,也即为待恢复的数据,
%要求它和known_abs_spatial大小一致,所以这里直接赋值就好了
unknown_phase=im2double(unknown_phase); %将图像灰度映射到0~1
unknown_phase2=unknown_phase*2*pi; %相位范围映射到0-2*pi
unknown_phase2(unknown_phase2>pi)=unknown_phase2(unknown_phase2>pi)-2*pi;%进一步映射至[-pi,+pi]
[width,length]=size(known_abs_spatial); %获取图像的大小
input=known_abs_spatial.*exp(1i*unknown_phase2); %最终输入图像:幅度*e^(i*相位角度),它是复数图像
known_abs_fourier=abs(fft2(input)); %先将input图像进行傅立叶变换,然后取模,就是傅氏变换后的幅度
%以下开始迭代求相位
phase_estimate=pi*rand(width,length); %这是生成了一副大小为(width*length)的图像
%它的像素值是在[0,pi]范围内随机生成的。
figure(2),imshow(phase_estimate)
%以下开始迭代
for p=1:iterative
signal_estimate_spatial=known_abs_spatial.*exp(1i*phase_estimate); %Step 1 构造estimated signal:还是幅度*e^(i*相位角度)变成复数形式
temp1=fft2(signal_estimate_spatial); %傅立叶变换到频域
temp_ang=angle(temp1); %求相位弧度,它的范围是[-pi,pi]
signal_estimate_fourier=known_abs_fourier.*exp(i*temp_ang); %Step 2 替换傅氏变换后的幅度,产生estimate Fourier transform
temp2=ifft2(signal_estimate_fourier); %Step 3 对Step 2产生的estimate Fourier transform进行傅立叶反变换,又变换到空域了
phase_estimate=angle(temp2); %Step 4:estimated phase
% IS=abs(abs(temp2)-abs(temp1)).^2;
% MSE=sum(IS(:))/256^2%计算均方误差
end
%以上循环就是通过随便预设一个相位图像,在循环中不断调整逼近真实的相位,直到满足条件(也就是我们求的相位和真实相位非常接近的时候)
%不过这里我们只需要设定一个比较大的循环就可以了,基本上都可以满足条件了,这个激光原理就讲过了。
phase_estimate(phase_estimate<0)=phase_estimate(phase_estimate<0)+2*pi; %把estimate_phase从[-pi,+pi],映射到[0,2pi]
retrieved=phase_estimate/(2*pi);%再映射到[0,1]
% IS=abs(abs(temp2)-abs(temp1)).^2;
% MSE1=sum(IS(:))/256^2%计算均方误差
% figure(2);plot(log10(MSE),'LineWidth',1.5);
% xlabel('Iterative number');%迭代的次数
% ylabel('Logarithm of Mean Square Error');%均方误差的对数
figure (3)
imshow(retrieved,[]);title('相位图像')%显示我们提取到的相位图像
a=min(min(retrieved));
retrieved=retrieved/max(max(retrieved));
% imwrite(retrieved,phaseimage)
Uz=known_abs_spatial.*exp(1j.*retrieved);
piesize=8e-3;%像素大小
L= 564*piesize; %相位物体的长
W= 564*piesize; %相位物体的宽 512
lambda=632.8e-6 ;%光源波长
k=2*pi/lambda;
d=20;%衍射距离
[x, y, ~] = size(known_abs_spatial); %size返回行数和列数。r_dim为行数,c_dim为列数,~占位,表示只要行和列的值
fX = [0:fix(x/2),ceil(x/2)-1:-1:1]/L;%fix向下取整,ceil向上取整 %linspace(-x/2,x/2-1,x)/L;
fY = [0:fix(y/2),ceil(y/2)-1:-1:1]/L;%linspace(-y/2,y/2-1,y)/L;%
[fy,fx] = meshgrid(fY,fX);
q=fx.^2+fy.^2;
H=exp(1j*k*d.*sqrt(1-(lambda*lambda).*(q)));
HB=1./H;
Eii=ifft2((fft2(Uz)).*HB);
phase1=angle(Eii);
phase1(find(phase1==0))=0.01;
imshow(phase1,[]);
%% 加速角谱迭代法 开始迭代 GS恢复的相位作为角谱的输入相位迭代
step=1000;
loss=ones(step,1);%MSE
psn=zeros(step,1);%psnr
N=564;%
gk=zeros(N,N);
minloss=1;
%% 读入
A0=known_abs_spatial;
%A0=sqrt(A0);
%A0=A0./max(max(A0));
A=ones(N,N);
phasek=retrieved;
phasek1=phasek;
Ei=A.*exp(1j.*phase1);%初始的物面
figure;
tic
for n=1:step
EOO=ifft2((fft2(Ei)).*H);
AOO=abs(EOO).^2;
AOO=AOO./max(max(AOO));
EO=A0.*exp(1j.*angle(EOO));%新相位 像面
Eii=ifft2((fft2(EO)).*HB);
faik=angle(Eii); %新相位 物面
faik=faik./max(max(faik));
beitak=(phasek-phasek1);
%abk=(A0-AOO)./pi./2;
if n>1
gk1=gk;
gk=faik-phasek;
rk=sum((gk.*gk1),"all")/(sum((gk1.^2),"all"));%abs
phasek1=phasek;
phasek=faik+beitak*rk;
phasek=phasek./max(max(phasek));
else
gk=faik-phasek;
phasek=faik;
end
Ei=exp(1j*phasek);
loss(n)=immse(A0,AOO);
psn(n)= 10 * log10(1/loss(n));
imshow(faik);
if loss(n)