锡膏高度判断(使用五步相位移法)--matlab

线路问题进行到一半的时候,被分配着去做了锡膏的3D检测算法。趁着两者都有了些许进展,终于是可以来记录一下相关的情况了~

由于解相位算法不是我做的,直接拿了同事的成果,这里就不讲了。主要是这算法也存在着问题,并且有个部分不知道怎么得到的。。。汗

    计算高度的方法总结就是:根据解相位的图,拟合出锡膏周围基准面,再进行计算得到高度。

遇到的问题

1:解出来的相位在边界处,沿x方向在左边界和右边界存在着翘曲的情况,这导致我在后续处理中遇到了一些困难

    解决方法:将处理的图片沿x和y方向在最早需要拓展的像素值上再多拓展了20个点,后续进行计算高度前将之裁掉。

2:图片锡膏周围存在阴影处,解出来的相位基本是近乎水平但是乱序波动的情况。

    解决方法:可以根据灰度判断出阴影的具体位置,根据解相位出来的规律,在左边界存在的阴影所有点都取来作为拟合点、右边界所有点都不取,最后得到一个拟合的基准面。

function  X = Ls1(~)
 

 

% Ref1 = imread('E:\Desktop\3DSPI\pmp\2\4\140_20_0.bmp');
% Ref2 = imread('E:\Desktop\3DSPI\pmp\2\4\140_20_1.bmp');
% Ref3 = imread('E:\Desktop\3DSPI\pmp\2\4\140_20_2.bmp');
% Ref4 = imread('E:\Desktop\3DSPI\pmp\2\4\140_20_3.bmp');
% Ref5 = imread('E:\Desktop\3DSPI\pmp\2\4\140_20_4.bmp');

%边缘全阴影读取
% Ref1 = imread('E:\Desktop\3DSPI\pmp\2\3\130_20_0.bmp');
% Ref2 = imread('E:\Desktop\3DSPI\pmp\2\3\130_20_1.bmp');
% Ref3 = imread('E:\Desktop\3DSPI\pmp\2\3\130_20_2.bmp');
% Ref4 = imread('E:\Desktop\3DSPI\pmp\2\3\130_20_3.bmp');
% Ref5 = imread('E:\Desktop\3DSPI\pmp\2\3\130_20_4.bmp');

Ref1 = imread('E:\Desktop\3DSPI\pmp\3\右边界2\140_20_0.bmp');
Ref2 = imread('E:\Desktop\3DSPI\pmp\3\右边界2\140_20_1.bmp');
Ref3 = imread('E:\Desktop\3DSPI\pmp\3\右边界2\140_20_2.bmp');
Ref4 = imread('E:\Desktop\3DSPI\pmp\3\右边界2\140_20_3.bmp');
Ref5 = imread('E:\Desktop\3DSPI\pmp\3\右边界2\140_20_4.bmp');

% Ref1 = imread('E:\Desktop\3DSPI\metch\3\120_10.bmp');
% Ref2 = imread('E:\Desktop\3DSPI\metch\3\120_11.bmp');
% Ref3 = imread('E:\Desktop\3DSPI\metch\3\120_12.bmp');
% Ref4 = imread('E:\Desktop\3DSPI\metch\3\120_13.bmp');
% Ref5 = imread('E:\Desktop\3DSPI\metch\3\120_14.bmp');

 Test1 = Ref4();
 
 Ref1 = im2double(Ref1);
 Ref2 = im2double(Ref2);
 Ref3 = im2double(Ref3);
 Ref4 = im2double(Ref4);
 Ref5 = im2double(Ref5);

 
%  temp1 = Ref4-Ref2;
%  temp2 = Ref1-Ref3;
 
temp1 = 2*Ref2-2*Ref4;
temp2 = 2*Ref3-Ref1-Ref5;

thetaREF1 = atan2(temp1,temp2); %M自带计算反三角函数

b = thetaREF1;  

lamda=10;%调节参数
[M,N]=size(b);
dx=zeros(M,N);
dy=zeros(M,N);
 

%求包裹相位的相位差
for n=1:N
  for m=1:M-1
         if((b(m+1,n)-b(m,n))>pi)
           dx(m,n)=b(m+1,n)-b(m,n)-2*pi;
         elseif((b(m+1,n)-b(m,n))<-pi)
           dx(m,n)=b(m+1,n)-b(m,n)+2*pi;
         else
           dx(m,n)=b(m+1,n)-b(m,n);
         end
      end
 end
 for n=1:N
     dx(M,n)=0;
 end
 
 for m=1:M
   for n=1:N-1
         if((b(m,n+1)-b(m,n))>pi)
         dy(m,n)=b(m,n+1)-b(m,n)-2*pi;
         elseif((b(m,n+1)-b(m,n))<-pi)
         dy(m,n)=b(m,n+1)-b(m,n)+2*pi;
         else
          dy(m,n)=b(m,n+1)-b(m,n);
         end
     end
 end
 for m=1:M
     dy(m,N)=0;
 end
 
p2=zeros(M,N);
%求相位差
 for m=2:M
     for n=2:N
         p2(m,n)=dx(m,n)-dx(m-1,n)+dy(m,n)-dy(m,n-1);
     end
 end
 p2(1,1)=dx(1,1)+dy(1,1);
 for n=2:N
     p2(1,n)=dx(1,n)+dy(1,n)-dy(1,n-1);
 end
 for m=2:M
     p2(m,1)=dx(m,1)-dx(m-1,1)+dy(m,1);
 end
 

% %DCT变换
 pp=dct2(p2);        %M自带离散余弦变换函数
 
 fi=zeros(M,N);
 for m=1:M
     for n=1:N  
       fi(m,n)=pp(m,n)./((2+16*lamda)*(cos(pi*(m-1)/M)+cos(pi*(n-1)/N))-2*lamda*(cos(2*pi*(m-1)/M)+cos(2*pi*(n-1)/N))-8*lamda*cos(pi*(m-1)/M)*cos(pi*(n-1)/N)-20*lamda-4);
       %fi(m,n) = pp(m,n) ./ (2*(cos(pi*(m-1)/M)+cos(pi*(n-1)/N)-2));
    end
 end
 fi(1,1)=pp(1,1);
 
 y01=idct2(fi);
 
 

y01 = y01();

M = M-20;
N = N-20;
y01 = y01(1:M,1:N);
mesh(y01());title('解包相位');
[M,N]=size(y01);

后续进行曲面拟合的思路如下:在锡膏的周围往外扩散20个像素点的区域,沿x或y方向找取该方向上最直的那条线段或多条线段,判定为可选取拟合点的线,最后找取了很多点进行拟合,得到基准面,再与解相位的面进行相减得到相位差,最后根据标定的系数进行高度的计算。

关键步骤代码:

找取最直的直线,根据二次梯度进行判断:

ys = y01(i,:);
Test1s = Test1(i,:);
%所有点的间距是固定的,那么可以通过y值的差异来标识斜率的不同,当然若间距不固定,就用正常的斜率求法
diffYs = diff(ys);              %M自带函数:数组中(i+1)-i
diff2Ys = diff(diffYs);

根据阈值判断可取的直线起始点 

    k = 0.01;
    diff2Ys( find(abs(diff2Ys < k)) ) = 0;

    zeroIndexs = find(abs(diff2Ys < k));
    flags = ones(1,length(diff2Ys));
    flags( zeroIndexs ) = 0;
    
    %flags里的0值存储的就是斜率相近的点,即二阶导数接近0的点。其他置1.求出每个0值序列,选取要求的那个序列
    diff_flags = diff( flags );
    
    start_0 = find( diff_flags == -1 ) + 1; %1-0为起点,第一二个数为零是start_0会少第一个数1
    end_0 = find( diff_flags == 1 );        %此处会遗漏当最后一个点diff为零时的end点

    %line_num中最大的数的位置代表似直线最长的一段
    line_num = end_0 - start_0;
    
    %line_num最大数坐标映射到start_0和end_0代表曲线的起始和终点
    [m,index] = max(line_num);         %index为位置
    start_line = start_0(index);
    end_line = end_0(index);
%选取拟合点 
   if end_0(index)-start_0(index) > 15
       get_y = randperm(end_0(index)-start_0(index),5) + start_0(index);
       for get_num = 1:5
            standard_pro = [standard_pro;[i get_y(get_num)  ys(get_y(get_num))]];
       end
       
   else
       continue;
   end

 值得一提的是对于阴影区域的高度计算障碍排除:         ,像这样的。

不知道是解相位算法的问题,还是通用的问题:在此处解出来的相位全是混乱波动的。

方法:

    %找到阴影处边界,将梯度加速度置1
    Test1s(find(Test1s<2)) = 0;
    
    shadow_nf = find(Test1s ~=0,1,'first');
    shadow_n = find(Test1s~=0,1,'last');
    diff2Ys(shadow_n + 1: N) = 1;
    diff2Ys(1: shadow_nf - 1) = 1;

最后进行拟合:

%拟合曲面
pro_x=standard_pro(:,1);
pro_y=standard_pro(:,2);
pro_z=standard_pro(:,3);

[X,Y,Z]=griddata(pro_y,pro_x,pro_z,linspace(1,N,N)',linspace(1,M,M),'v4');  %M自带拟合曲面函数

figure;mesh(X,Y,Z);title('profit');


phase_diff = y01(1:M,1:N) - Z;
height = 315* phase_diff;

最后一些结果展示:

存在问题:在阴影与锡膏的交界处,总会产生翘曲或者凹陷导致高度的突增或消失,暂时还未能解决。。。

后续

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值