Zernike函数拟合曲面--MATLAB实现

利用前36阶zernike函数拟合曲面:

脚本程序

clc;clear;
load unwrap_ph.mat
unwrap_ph=max(max(unwrap_ph))-unwrap_ph;
unwrap_ph=unwrap_ph(:,81:560);
x=linspace(-1,1,size(unwrap_ph,1));
y=linspace(-1,1,size(unwrap_ph,2));
xy=[x;y];
a0=ones(1,36);
unwrap_ph(isnan(unwrap_ph)) = 0;
a=lsqcurvefit('SH',a0,xy,unwrap_ph)
FIT=SH(a,xy);
FIT(FIT==0)=nan;
figure(1)
imagesc(FIT)
colormap('jet')
grid off
shading interp
figure(2)
imagesc(unwrap_ph)
colormap('jet')
grid off
shading interp

zernike函数

function z = zernfun(n,m,r,theta,nflag)
m=m*-1;
if (~any(size(n)==1))||( ~any(size(m)==1))
    error('zernfun:NMvectors','N and M must be vectors.')
end

if length(n)~=length(m)
    error('zernfun:NMlength','N and M must be the same length.')
end

n=n(:);
m=m(:);
if any(mod(n-m,2))
    error('zernfun:NMmultiplesof2', ...
          'All N and M must differ by multiples of 2 (including 0).')
end

if any(m>n)
    error('zernfun:MlessthanN', ...
          'Each M must be less than or equal to its corresponding N.')
end

if any(r>1|r<0)
    error('zernfun:Rlessthan1','All R must be between 0 and 1.')
end

if (~any(size(r)==1))||(~any(size(theta)==1))
    error('zernfun:RTHvector','R and THETA must be vectors.')
end

r=r(:);
theta=theta(:);
length_r=length(r);
if length_r~=length(theta)
    error('zernfun:RTHlength', ...
          'The number of R- and THETA-values must be equal.')
end

% Check normalization:
% --------------------
if nargin==5&&ischar(nflag)
    isnorm=strcmpi(nflag,'norm');
    if ~isnorm
        error('zernfun:normalization','Unrecognized normalization flag.')
    end
else
    isnorm=false;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Compute the Zernike Polynomials
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Determine the required powers of r:
% -----------------------------------
m_abs=abs(m);
rpowers=[];
for j=1:length(n)
    rpowers=[rpowers m_abs(j):2:n(j)];
end
rpowers=unique(rpowers);

% Pre-compute the values of r raised to the required powers,
% and compile them in a matrix:
% -----------------------------
if rpowers(1)==0
    rpowern=arrayfun(@(p)r.^p,rpowers(2:end),'UniformOutput',false);
    rpowern=cat(2,rpowern{:});
    rpowern=[ones(length_r,1) rpowern];
else
    rpowern=arrayfun(@(p)r.^p,rpowers,'UniformOutput',false);
    rpowern=cat(2,rpowern{:});
end

% Compute the values of the polynomials:
% --------------------------------------
y=zeros(length_r,length(n));
for j=1:length(n)
    s=0:(n(j)-m_abs(j))/2;
    pows=n(j):-2:m_abs(j);
    for k=length(s):-1:1
        p=(1-2*mod(s(k),2))* ...
                   prod(2:(n(j)-s(k)))/              ...
                   prod(2:s(k))/                     ...
                   prod(2:((n(j)-m_abs(j))/2-s(k)))/ ...
                   prod(2:((n(j)+m_abs(j))/2-s(k)));
        idx=(pows(k)==rpowers);
        y(:,j)=y(:,j) + p*rpowern(:,idx);
    end
    
    if isnorm
        y(:,j)=y(:,j)*sqrt((1+(m(j)~=0))*(n(j)+1)/pi);
    end
end
% END: Compute the Zernike Polynomials
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Compute the Zernike functions:
% ------------------------------
idx_pos=m>0;
idx_neg=m<0;

z = y;
if any(idx_pos)
    if (m>=0&&rem(n,2)==1)
    z(:,idx_pos)=1-y(:,idx_pos).*sin(theta*m(idx_pos)');
    else
    z(:,idx_pos)=y(:,idx_pos).*sin(theta*m(idx_pos)');
    end
end
if any(idx_neg)
    if (m>=0&&rem(n,2)==1)
    z(:,idx_neg)=1-y(:,idx_neg).*cos(theta*m(idx_neg)');
    else
    z(:,idx_neg)=y(:,idx_neg).*cos(theta*m(idx_neg)');
    end
end
% EOF zernfun

拟合函数

function z=SH(c,data)
x=data(1,:);
y=data(2,:);
[X,Y]=meshgrid(x,y);
[theta,r]=cart2pol(X,Y);
idx=r<=1;
zz=zeros(size(X));
b=c(1:4);
a=c(5:end);
zz(idx)=b(1)*zernfun(0,0,r(idx),theta(idx))+b(2)*zernfun(1,1,r(idx),theta(idx))+b(3)*zernfun(1,-1,r(idx),theta(idx))+b(4)*zernfun(2,0,r(idx),theta(idx))+...
a(1)*zernfun(2,2,r(idx),theta(idx))+a(2)*zernfun(2,-2,r(idx),theta(idx))+a(3)*zernfun(3,1,r(idx),theta(idx))+...
a(4)*zernfun(3,-1,r(idx),theta(idx))+a(5)*zernfun(3,3,r(idx),theta(idx))+a(6)*zernfun(3,-3,r(idx),theta(idx))+...
a(7)*zernfun(4,0,r(idx),theta(idx))+a(8)*zernfun(4,2,r(idx),theta(idx))+a(9)*zernfun(4,-2,r(idx),theta(idx))+...
a(10)*zernfun(4,4,r(idx),theta(idx))+a(11)*zernfun(4,-4,r(idx),theta(idx))+a(12)*zernfun(5,1,r(idx),theta(idx))+...
a(13)*zernfun(5,-1,r(idx),theta(idx))+a(14)*zernfun(5,3,r(idx),theta(idx))+a(15)*zernfun(5,-3,r(idx),theta(idx))+...
a(16)*zernfun(5,5,r(idx),theta(idx))+a(17)*zernfun(5,-5,r(idx),theta(idx))+a(18)*zernfun(6,0,r(idx),theta(idx))+...
a(19)*zernfun(6,2,r(idx),theta(idx))+a(20)*zernfun(6,-2,r(idx),theta(idx))+a(21)*zernfun(6,4,r(idx),theta(idx))+...
a(22)*zernfun(6,-4,r(idx),theta(idx))+a(23)*zernfun(6,6,r(idx),theta(idx))+a(24)*zernfun(6,-6,r(idx),theta(idx))...
+a(25)*zernfun(7,1,r(idx),theta(idx))+a(26)*zernfun(7,-1,r(idx),theta(idx))+a(27)*zernfun(7,3,r(idx),theta(idx))...
+a(28)*zernfun(7,-3,r(idx),theta(idx))+a(29)*zernfun(7,5,r(idx),theta(idx))+a(30)*zernfun(7,-5,r(idx),theta(idx))...
+a(31)*zernfun(7,7,r(idx),theta(idx))+a(32)*zernfun(7,-7,r(idx),theta(idx));
z=zz;

原图


拟合结果

应当注意的是zernike是圆对称函数,也就意味着其拟合的是一个圆,所以原图圆外的数值并未拟合。

猜你喜欢

转载自blog.csdn.net/weixin_41923961/article/details/80370666
今日推荐