This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于DLP4500结构光三维重构实验中,包裹相位的还原的程序问题,为什么要把相位在(-π,-π/2)和(π/2,π)的相位值给过滤掉,这样岂不是有错误吗?




// Calculate the wrapped phase
phase_value = atan( sqrt(3.0) * (intensity_phase_n120 - intensity_phase_p120) /
(2.0*(intensity_phase_0)-(intensity_phase_n120)-(intensity_phase_p120)) )
/ THREE_PHASE_PI

if((phase_value >= 0.5) || (phase_value <= -0.5)){
// Pixel is invalid
disparity_value = dlp::DisparityMap::INVALID_PIXEL;
}
else{
// Convert the phase to a wrapped pixel value
disparity_value = lroundf(over_sample*(phase_value + 0.5) * ((float)this->resolution_) / this->phase_counts_);//获取所在的像素点处于第几个二值化条纹周期

if(this->use_hybrid_.Get()){
// Get the gray code disparity pixel value
gray_code_disparity.Unsafe_GetPixel(xCol,yRow,&gray_code_disparity_value);

//disparity_vals[(unsigned int)gray_code_disparity_value]++;

if((gray_code_disparity_value != dlp::DisparityMap::INVALID_PIXEL) &&
(gray_code_disparity_value != dlp::DisparityMap::EMPTY_PIXEL)){


// Check that the phase change regions are correct
if(((gray_code_disparity_value+1) % 4) == 0){
// The fourth region of a period should be greater than
// 0.25 and absolutely greater than 0. If it is less than
// zero the phase has been missclassified
if(phase_value < 0) gray_code_disparity_value++;
}
else if(((gray_code_disparity_value+1) % 4) == 1){
// The first region of a period should be less than
// -0.25 and absolutely less than 0. If it is greater than
// zero the phase has been missclassified
if(phase_value > 0) gray_code_disparity_value--;
}

// Adjust the GrayCode disparity value to the phase regions
gray_code_disparity_value = gray_code_disparity_value / 4;

// Add the GrayCode disparity value to unwrap the values
disparity_value += (over_sample*gray_code_disparity_value*this->resolution_/this->phase_counts_);
}
else{
disparity_value = dlp::DisparityMap::INVALID_PIXEL;
}
}
else{
// Non hybrid method not implemented
disparity_value = dlp::DisparityMap::INVALID_PIXEL;
}
}

// Save the calculated pixel value
this->disparity_map_.Unsafe_SetPixel(xCol,yRow,disparity_value);
}
}

three_phase.cpp

  • training.ti.com/introduction-how-structured-light-works

    参考资料: 光栅投影三维精密测量 编辑



    《光栅投影三维精密测量》是2011年科学出版社出版的图书,作者是达飞鹏,盖绍彦。



    书 名光栅投影三维精密测量 作 者达飞鹏,盖绍彦 页 数255 出版社科学出版社 出版时间2011-1-1 版 次1


    目录

    1 基本信息
    2 内容简介
    3 目录




    基本信息

    编辑

    字 数:321000印刷时间:2011-1-1开 本:16开纸 张:胶版纸印 次:1I S B N:9787030300010包 装:平装




    内容简介

    编辑

    光栅投影三维测量技术以现代光学为基础,融光电子学、图像图形处理、计算机控制、机器视觉等技术为一体,是科学技术飞速发展所催生出的现代光学测量方法之一,在工业生产控制与检测、机器人视觉、空间遥感、医学诊断以及社会安全等诸多领域具有广泛的应用前景。达飞鹏、盖绍彦编著的《光栅投影三维精密测量》从构建光栅投影三维精密测量系统的角度,按照所涉及的内容来安排,较系统地介绍了光栅投影三维测量技术的基础理论、方法、关键技术问?及解决方案,并给出了实验论证。

    《光栅投影三维精密测量》可用作从事光学三维测量、机器视觉等领域的科研人员和研究生的参考书。







    一、基本原理:

    正弦条纹打在三维物体上,CCD记录到的条纹由于受到三维物体高度的调制而发生扭曲,扭曲的条纹(deformed fringe)实质上为原始条纹在物体具有高度存在的位置有了附加相位,各点的相位表现为由CCD图像采集获得的被调制的条纹数字图像的灰度值。通过扭曲的条纹和原始条纹比对计算得出相位变化值。又已知投影仪、CCD和物体的具体位置和之间的距离,利用数学关系可求出对应点的高度值,实现3D重建。公式推导如下:(下图来自[1])

    [原理图][原理公式]



    二、四步相移法
    获得正确的相位值并计算出相位差是得到物体真实高度信息并进行3D重建的关键。

    在利用CCD进行数字采集过程中,由于环境等各种因素的影响,以及物体在空间上对光的反射程度和与CCD距离不同,不能够得到理想的均匀而又高对比度的条纹,也就不能得到最真实的相位信息。运用四步相移法处理此问题(此方法参考[1]),过程分析如下:

    四步相移公式1


    式中 R(x,y) 表示所测物体表面的不均匀反射率,A(x,y) 是背景强度,B(x,y)/A(x,y) 表示的是光栅条纹的对比度。∅(x,y) 是相位值。


    考虑到以上引入的多个外部影响因子,利用四步相移法分别记录四次初相不同的正弦条纹和被调制的条纹(每个相差π/2),联立即可得到消去外部因子的真实相位值。表达式如下:


    [四步相移公式2]


    分别为初相等于0、π/2、π 和 3π/2 的条纹表达式,由三角函数变换可分别化成上式。

    联立解得 [四步相移公式3]



    可以看到A、B、R三个外部因子被消去,留下相位的正切值。利用反正切函数即可求出相位分布。

    三、包裹相位处理(相位展开/相位解卷)

    1、 相位包裹的含义:

    [相位包裹图]

    如图所示(图片来自[1]),下图为真实相位值,上图为被包裹的相位。即不在反正切函数(-π,π)的主值区间内的相位值被加上或减去n个2π(n为整数),使其值被调整了主值区间(-π,π)内,称为相位包裹。被包裹的相位(wrapped phase)并不是真正的相位信息,需要进行相位展开,还原出其原始的相位值。

    此处有另一个重点,数学中常用的反正切函数是二象限的反正切函数,值域仅是(-π/2,π/2),而此处我们运用的反正切函数是四象限的反正切函数,值域是(-π,π)。区别如下:
    二象限反正切函数(matlab中函数名为atan)输入参数为正切值,返回正切值仅有两个第一第四两个象限的角度值,即(-π/2,π/2)。而四象限反正切函数(matlab中函数名为atan2)输入参数为y和x,返回正切值包括四个象限,即(-π,π)。
    四象限反正切考虑到正切值的由来是两个量的商,多考虑了x为负时的另一种情况,即可以将值域扩展一倍,延长到(-π,π)。表达式如下:(表达式来自Wikipedia)

    [四象限反正切公式]

    [反正切曲线]


    [圆]






    上图为本人用matlab粗略汇出的四象限反正切函数曲线,各条曲线颜色对应下图圆中角所在的区域。

    2、解卷/相位展开/相位解包裹操作(phase unwrapping)


    上面讲述的相位包裹表现为相位在主值区间内增加到超过主值区间的上限的时候,即超过π时,将发生跳变,也就是说继续增加相位值会跳变到-π。在整体提取的图像中沿着相位增加的方向表现为锯齿波的形状。如下图为没有被物体调制过的条纹沿着条纹的方向横截,被包裹的相位图:

    [相位包裹图]

    相位展开最根本的思想就是找出相位发生跳变的地方,补上被减去的n个2π,使跳变出相位值和周围的值变得连续、平滑。方法很多,请参考[1],文中详细讲解质量法。
    本次使用matlab仿真直接使用了matlab中相位解卷函数unwrap(P,tol,1)。其中P为执行相位解卷的向量或矩阵;tol为相位跳变限度(jump tolerance),即差值大于tol被判定为发生跳变,默认为pi,此处我使用的时候填pi;第三个参数表示进行相位解卷操作的维度,向量只有一个维度,矩阵有两个维度,则1表示行解卷,2表示列解卷。上一张图相位展开完成后相位分布如下图,可以看到不存在跳变(锯齿)。


    [解卷相位图]

    四、傅里叶变换法还原相位

    运用此方法不进行相位解卷便可以获得真实的相位信息。原理如下:(此方法和原理公式来自[2])
    被包裹的相位表示为




    其中φ(x,y)为真实的相位信息,fx和fx标志条纹频率。
    将被包裹的相位表示成复数形式

    二维傅里叶变换

    频移后进行逆傅里叶变换

    求复数表示的相位的相角即可得到真实相位值

    两次傅里叶变换亦可以应用傅里叶变换的频移性质实现:



    此方法就是利用傅里叶变换频移实现滤波操作,滤掉条纹部分的信息。[2]对该方法提高精度的一些办法进行了阐述,具体参考原文。
    此方法虽然可以直接得到相位信息而不需要进行解卷,且精度较高,但是因为没有解卷,若物体高度换算大于2π的相位差,则或出现重建变形,较高部分凹陷下去的情况。