【结构光三维重建】基于格雷码的相位展开方法(含代码)

之前一直在做关于格雷码+相移的相位展开方法,根据一些相应的论文,能够对该法进行一些较为详细的阐述,并融合一些自己的理解,文章中如有不妥之处,敬请指教。

整个文章分为以下几部分:
1、格雷码+相移法基本原理
2、格雷码条纹生成
3、格雷码条纹解码
4、确保相移正确展开的措施(补码)。


1、格雷码+相移法基本原理

格雷码+相移法是将相移技术和二元编码光栅相结合的时间相位展开方法。其中相移法是计算相位的主值,格雷码解码后作为相位展开的级次,此时投影相位就能唯一的展开。该方法中使用格雷码来提供级次具有抗环境噪声干扰强,相比二进制码明暗交界处变换更少(明暗交界处容易判断二值出错),高位条纹更宽(条纹越宽越不容易模糊)等优点,能够有效提供出正确的展开级次。

格雷码+相移的方法比条纹降级法的好处在于,降级法必须要从1频条纹进行投影,一级一级展开后单频的噪声对最终的归一化相位噪声影响最大,而投影格雷码的环境噪声远小于二值化阈值,具有较强的抑制噪声的能力,对最终的归一化相位噪声影响几乎为0,那么相对的重建效果要好的多。

那么如何选择正确的格雷码位数、相移周期及步数呢,这些参数的选择直接决定了最终归一化相位精度、获得一幅相位的速率(总图片张数);一般的,格雷码的位数与相移的条纹周期之间选择存在着一个规则(假设投影仪的横向分辨率是1024个像素,如果选择6位格雷码pow(2,6)=64级次,那么意味着相移条纹也要选择64根条纹的图像,相移条纹周期是16Pixel);该规则表示相移周期与格雷码位数必须统一,那么此时决定格雷码位数的就是所需的包裹相位精度(由相移步数与周期决定),但是格雷码的位数也不能选择过高,否则极易受噪声影响,后续解码错误,影响重建效果。那么最佳的相位精度条纹编码请参考详细描述

以下是格雷码+相移的相位展开过程:
相位展开

2、格雷码条纹生成

格雷码是一个数列集合,每个数都使用二进制来表示,并且任两个数之间只有一个位不同,N位元表示   2 N   \ 2^N\,  2N个数列,每个数列有N位二进制数。

一、按格雷码特殊方式生成

以4位的格雷码条纹为准,格雷码的生成是有规律的,我们发现格雷码条纹的每位元是严格的左右对称的,除第一行外,其他都是以0110进行循环的:
格雷码编码
那么,按照此规律,格雷码的生成代码可写成:

CamW = 1024; //像素分辨率
Nbit = 6;  //所要生成的位数
I = zeros(CamW, Nbit); //从1到Nbit的格雷码存储空间
bit = [0 1 1 0];
for i = 3:Nbit 
    bit  = [bit bit]; 
end
for i = 1:Nbit
    for j = 1:2^i
        beg = 1 + CamW/(2^i)*(j-1);       
        I(beg:beg-1+CamW/(2^i), i) = bit(j);
    end
end

上述代码表示先把Nbit的格雷码循环生成,然后再把01放到指定的位置上。
该方法简单且好理解,充分利用了格雷码条纹的规律。

3、格雷码条纹解码

格雷码条纹主要是将被调制过的信息解码出来,经过二值化(根据灰度阈值,判断明暗变化条纹的01)、依次异或(使用该格雷码与次一级的格雷码进行异或操作,数值保留在当前格雷码位置)、数值展开等操作;
解码操作
之后在按照二值进行数值的展开。

4、确保相移正确展开的措施(补码)

传统的用于相位展开的二元光栅是根据格雷码的编码设计的,编码图像中的某一点最多只会出现在一副编码图的黑白交界处,虽然最多只会导致一位错码,然而用于相位展开将引入2pi的相位误差

该处提出的补码光栅也是按照格雷码的编码原则实现的,是在原先编码光栅最后一副光栅的基础上再增加一倍码字,其解决思路是两种编码出现误码的位置不同,在相位展开时根据截断相位的不同,利用编码的互补性,采用不同的解码方式来恢复真实相位。

不失一般性, 为便于说明令相移光栅的周期数为 8, 互补型二元光栅的编码方式如图所示, k1 是对前三幅编码光栅所产生的码字进行的编码, k2 是对四幅编码光栅所产生的码字进行的编码。由图可得, 在 k1 可能出现误码的位置( 椭圆处), 在 k2 中不会出现误码。
两种编码图案
上述补码表述来自"基于互补型光栅编码的相位展开"论文中所述;

下面附上解格雷码+补码的C++代码,有需要可以参考。

float *pha = new float[IMAGE_HEIGHT*IMAGE_WIDTH];	
int Gcode;
int Bcode[7];
int *NLevel = new int[IMAGE_HEIGHT*IMAGE_WIDTH];
int *NLevel2 = new int[IMAGE_HEIGHT*IMAGE_WIDTH];

for(int i=0; i<IMAGE_WIDTH*IMAGE_HEIGHT; i++)
{
    for(int n=0; n<7; n++)
    {
        if(Img[n][i] > I[i])
           Gcode = 1;
        else
           Gcode = 0;
        if(n == 0)   
           Bcode[n] = Gcode;
        else
           Bcode[n] = Bcode[n - 1]!=Gcode;        
    }
    NLevel[i] = Bcode[0] * 32 + Bcode[1] * 16 + Bcode[2] * 8 + Bcode[3] * 4 + Bcode[4] * 2 + Bcode[5];
    NLevel2[i] = NLevel[i] + Bcode[6];
    if(pha[i] <= pi/2)
      Phase[i] = pha[i] + NLevel2[i]*2*pi;
    else if(pha[i] >= 3*pi/2)
      Phase[i] = pha[i] + (NLevel2[i] - 1)*2*pi;
    else
      Phase[i] = pha[i] + NLevel[i]*2*pi;  
}
  • 6
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
格雷码结构三维重建是一种使用格雷码编码的方法来进行三维物体重建的技术。在这种方法中,通过投影仪将预先设计好的格雷码模式投射到被测物体上,然后使用相机捕捉被投影的格雷码图案。通过分析相机捕捉到的格雷码图案与预先设定的编码模式之间的差异,可以推断出物体表面的深度信息。根据这些深度信息,可以重建出物体的三维形状。 格雷码结构三维重建的过程相对简单,但要得到高精度、高稳定性和高效率的三维重建效果,还需要进行一些优化。由于格雷码是一种离散型编码,编码精度是整数级的像素,所以在实际应用中,通常需要与其他编码方式结合使用,比如使用格雷码来标示相移的周期数,以提高重建精度。 然而,尽管格雷码在精度需求不是特别高的情况下具有稳定性高和抗反效果好的特点,但在一些情况下仍存在一些限制。例如,对于需要较高精度的应用场景,格雷码的编码精度可能无法满足要求。此外,在景深范围较大的情况下,相位容易出现模糊,而黑白条纹的格雷码适应的景深范围相对较大。 因此,在使用格雷码进行三维重建时,需要根据具体应用场景和精度要求来选择合适的编码方式,并进行相应的优化。同时,还可以从三维重建方式本身出发,考虑使用双目重建模型,通过准确解码和极线对应关系来提高重建精度。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值