初学相移条纹三维重建,想试试用matlab做一下仿真,结果先被拦在了第一关--------生成正弦条纹图。
我看网上好多教程都是直接用图片计算相位了
所以分享一段代码,仅供初学者参考,个人觉得能够更好的理解。若有不正确之处,还望多多指点,勿怪。
代码如下:
close all;
clc;
clear;
%% ------参数
W = 700;
H = 700;
A = 127.5;
B = 127.5; %127.5+127.5=255
d = 20;%相机-投影的距离
l = 100;%相机到标定板的距离
T = 15; %T=1/f
N=4;%相移次数
[x, y] = meshgrid(1:W, 1:H);
I = cell(2, 4);
%% ---创建一个物体(def)
def=peaks(W);
figure;
mesh(x,y,def);
%% ******(N)步相移条纹图
pha = 2 * pi * x / T;
% pha = linspace(0,N*2*pi,H);
% pha = repmat(pha',1,W); %横向条纹
% pha = linspace(0,N*2*pi,W);
%pha = repmat(pha,H,1); %竖向条纹
%以上两类相位函数都可生成
I1 = A + B * cos(pha + 0 *2* pi / N );%原始条纹
I2 = A + B * cos(pha + 1 *2* pi / N );
I3 = A + B * cos(pha + 2 *2* pi / N );
I4 = A + B * cos(pha + 3 *2* pi / N );
I{1, 1} = I1; % 记录光强
I{1, 2} = I2;
I{1, 3} = I3;
I{1, 4} = I4;
figure; % 弹出窗口
imshow(I1, []); % 图像显示
title('条纹图1');
figure; % 弹出窗口
imshow(I2, []); % 图像显示
title('条纹图2');
figure; % 弹出窗口
imshow(I3, []); % 图像显示
title('条纹图3');
figure; % 弹出窗口
imshow(I4, []); % 图像显示
title('条纹图4');
Ib1 = A + B * cos(pha + 0 *2* pi / N + def);%变形条纹
Ib2 = A + B * cos(pha + 1 *2* pi / N + def);
Ib3 = A + B * cos(pha + 2 *2* pi / N + def);
Ib4 = A + B * cos(pha + 3 *2* pi / N + def);
I{2, 1} = Ib1; % 记录光强
I{2, 2} = Ib2;
I{2, 3} = Ib3;
I{2, 4} = Ib4;
figure; % 弹出窗口
imshow(Ib1, []); % 图像显示
title('变形条纹图1');
figure; % 弹出窗口
imshow(Ib2, []); % 图像显示
title('变形条纹图2');
figure; % 弹出窗口
imshow(Ib3, []); % 图像显示
title('变形条纹图3');
figure; % 弹出窗口
imshow(Ib4, []); % 图像显示
title('变形条纹图4');
%% ———————————计算包裹相位
S=I4-I2;
C=I1-I3;
phar = atan2(C, S); %原条纹
figure;
imshow(phar, []);
title('未变形的包裹相位图');
S1=Ib4-Ib2;
C1=Ib1-Ib3;
phabr = atan2(C1, S1); %原条纹
figure;
imshow(phabr, []);
title('变形的包裹相位图');
%--------变形包裹相位变形曲线
row_data1 = phabr(H/2, :);
figure;
plot(row_data1);
xlabel('列');
ylabel('相位值');
title('变形条纹包裹相位的变化');
%% ————————解包裹(求绝相位)
phax1=unwrap(phar);%原条纹的
phax2=unwrap(phabr);%变形后的
phax=phax2-phax1;
figure;
imshow(phax, []);
title('绝对相位');%绝对相位
figure;
mesh(x, y, phax);
title('三维重建');%def三维
解包裹用的是unwrap,具体参照官网上的解释:
相位解包裹或解包裹是一个过程,通常用于重建信号的原始相位。解包裹算法在每个相位输入中添加适当的2π倍数,以恢复原始相位值,如图所示。详细信息,参见解包裹方法。
计算信号相位的算法通常只输出-π和π之间的相位。例如,这些算法计算sin(2π + 3)的相位为3,因为sin(3) = sin(2π + 3),并且因为实际的相位2π + 3不在-π和π之间。这样的算法将sin(-4π + 3)和sin(16π + 3)的相位也计算为3。
生成的三维形面:
生成的条纹图:
变形后:
包裹相位的曲线:
展开相位:
三维重建:
目前遇到的问题:
①若选择第一种(pha = 2 * pi * x / T;)则会出现,改变T值对绝对的相位的展开有很大的影响,图示T=15时效果最佳(似乎与unwrap的解法有关,我也没有计算验证);
②对三维形的重建时,高度不一致是因为没有还原高度“Z=phax*T*l/d/(2*pi);”