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

本文详细阐述了格雷码+相移法的基本原理,包括格雷码条纹的生成、解码过程以及如何确保相移正确展开的补码措施。这种方法通过结合格雷码的抗噪声优势和相移技术,提高了相位展开的精度和稳定性。文章还探讨了参数选择的重要性,如格雷码位数、相移周期和步数,以达到最佳的相位精度和运算效率。此外,提出了补码光栅的概念,以减少相位展开中的误码率,从而改善相位重建效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

整个文章分为以下几部分:
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;  
}
格雷码三维重建是一种基于编码结构光技术的三维测量方法,其中使用了格雷码序列对物体表面进行投影,并通过解码获得物面上每个点的空间坐标。下面是一个简单的MATLAB代码框架用于生成格雷码图案、获取图像并计算深度信息: ```matlab % 参数设置 numBits = 8; % 格雷码位数 width = 640; height = 480; % 创建白图与黑图作为起始帧 whiteImg = ones(height,width) * uint8(255); blackImg = zeros(height,width,'uint8'); % 初始化相机及采集设备 (此处省略具体初始化过程) camObj = initializeCamera(); % 开始拍摄黑白参考图像 imBlackRef = snapshot(camObj); imWhiteRef = snapshot(camObj); % 计算反射率图像(归一化处理) reflectanceIm = double(imWhiteRef - imBlackRef)./(imWhiteRef + imBlackRef+eps); % 构建水平方向上的格雷码条纹图像 for i=1:numBits code = dec2bin(graycode(numBits), numBits); projPattern(:,:,i)= reshape(str2num(code(i,:)),[ones(1,numel(code)-1), height, width]); end % 投影所有构建好的模式并通过摄像机捕获对应返回值... for i = 1:length(projPatterns) projectImageToScene(projPatterns(:,:,i)); capImages{i} = snapShotFromCam(); end % 解码步骤... 对每一张捕捉到的画面分析其亮暗变化情况, % 并按照规则转换成二进制数字串进而还原出该位置上实际存在的像素序号。 % 深度计算部分 ... 利用了三角法原理求得距离Z轴远近的关系式。 ``` 注意上述代码只是一个简化的示例流程描述,在真实的应用场景下还需要考虑诸如畸变校正等更多因素。而且由于涉及到硬件控制如光源投射装置和工业相机的操作命令,这部分内容无法直接给出完整实现。 此外,为了方便理解整个程序的工作机制,建议先学习一下有关双目视觉以及编码结构光的知识基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值