利用前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是圆对称函数,也就意味着其拟合的是一个圆,所以原图圆外的数值并未拟合。