结构光三维重建(四步相移&多频外差法)matlab实现(一)

前言:这里主要梳理自己在理解四步相移法和三频外差法,以及用MATLAB实现条纹图生成,四步相移求相位主值,三频外差相位展开(解包裹)的过程。
废话不多说,一些基本思想概念可以看下面参考文章,里面有详细介绍。这里主要对遇到的问题展开阐述。

多频外差法

由于用周期性变化的黑白条纹编码整幅图像,导致通过相移法获得的相位主值包裹在[-pi,pi]之间,相位不具备唯一性,此时就涉及相位展开,即解包裹的问题。

  1. 通过四步相移法:

  2. 选择三种光栅频率:
    这里参考李中伟博士的博士论文中提到的三种光栅频率。

  3. 进行相位差值运算:
    此节参考文章:https://blog.youkuaiyun.com/weixin_43263382/article/details/123090465
    请添加图片描述在这里插入图片描述
    故:经过公式验证知,两高频率光栅转化为低频率光栅时,相位值等于两频率相位作差。

  4. 相位展开:
    此节参考文章:https://blog.youkuaiyun.com/weixin_43263382/article/details/123090465
    因为T123已经可以覆盖整幅图像所以其中的相位可以认为为绝对相位。下面就是对某一包裹相位进行展开一般最后选择频率最高的进行相位展开,这是因为高频的信噪比比较高,误差较小。
    详细计算公式推导过程如下:
    在这里插入图片描述
    其中由图中,根据平行原理,可以知道,包裹区域相位值是以2nπ的量值增长。根据公式即可展开绝对相位。

  5. 问题展开:
    理论理解内容基本就到此结束,在matlab实现过程中,遇到了三个问题:
    注:问题发现主要是在代码实现过程中遇到的,后面会给出代码,结合代码的话,容易理解。(代码链接在最下面)

请添加图片描述
6. 问题解答:
问题一:λ 12,λ 23,λ 123中的频率代表含义,以及与其图像,像素点值有什么关系?
通过在解决这一问题途中,发现自己原来的条纹图生成周期有问题。比如一幅宽为1110的图像,其正弦条纹频率,宽度为70。
我原文生成的是:每个像素点值以1/70递进;即70为正弦条纹的周期。
但实际上是:正弦条纹频率70,即代表整幅图像出现的正弦条纹条数为70;正弦条纹宽度即有1110/70;
帮助理解的参考文章:https://blog.youkuaiyun.com/qq_33810188/article/details/89921099
如此一来,对于整幅图:
λ 12的频率为1/6即代表整幅图有6条正弦条纹。
λ 23的频率为1/5即代表整幅图有5条正弦条纹。
λ 123的频率为1即代表整幅图有1条正弦条纹。

问题二:作相位差时,θ12,θ23,θ123为什么也要缩放到[0,2pi]?
%将截断相位映射到0~2π
phaseMap(phaseMap<0)=phaseMap(phaseMap<0)+2*pi;

类似这行代码,在代码中,有两处地方出现。
第一次是在经过四步相移法后,由于atan2()函数,原本是0~2pi的相位值,被分成了两部分,因而需要还原。如图,不仅是因为要使用三频外差,才缩放到[0,2pi];而是因为,本来的相位值就是[0,2pi]递增的。

第二次则是在相位作差的时候,可以看到,叠加频率的相位值范围也应该是[0,2pi]递增的。
在这里插入图片描述
单纯经过相减后,可以发现有正值也有负值;而在实际运算中,为什么通过代码:
phaseMap(phaseMap<0)=phaseMap(phaseMap<0)+2*pi;
,即将负值加2pi就能还原到正确值?是我的疑惑点; 之后,通过debug,推了一遍数据值演算结果,找到了答案。
请添加图片描述

问题三:既然θ123是频率为1的绝对相位,为什么不直接作为含有物体信息的相位值使用,还要对θ1或θ2或θ3进行绝对相位展开?
通过查看θ123的数值分布发现,相位值都是在[0,2pi]之内;虽然θ123为绝对相位,但与其要展开的,折叠多个2pi的绝对相位数值分布不同。同时,考虑到对于有物体的条纹图,如果进行多个不同频率相位相减,越是多个频率交错相减,作差次数越多,其结果越混乱,尽管最后能整合为频率为1的绝对相位,但对于物体相位,不具有代表性或实际意义。考虑到这一点,也就觉得θ123是不合适的了。

参考文章:
https://zhuanlan.zhihu.com/p/432343200
https://blog.youkuaiyun.com/weixin_43263382/article/details/123090465?spm=1001.2014.3001.5502
https://blog.youkuaiyun.com/weixin_43263382/article/details/123220055
https://blog.youkuaiyun.com/qq_33810188/article/details/89921099
https://blog.youkuaiyun.com/weixin_40204808/article/details/115376564
https://blog.youkuaiyun.com/qq_27353621/article/details/124235712
https://blog.youkuaiyun.com/qq_33810188/article/details/89921099

下章将附上完整MATLAB代码。
结构光三维重建(四步相移&多频外差法)matlab实现(二)

&lt;think&gt;好的,用户需要四步相移MATLAB代码实现。首先,我得回忆四步相移的基本原理。四步相移通常用于光学测量,比如结构光三维重建,通过四个相位偏移的光栅图案来计算相位信息。每个步骤的相位偏移是0&deg;, 90&deg;, 180&deg;, 270&deg;,也就是0、&pi;/2、&pi;、3&pi;/2弧度。 接下来,我需要确定生成这四个相移图案的方。通常,这些图案是正弦或余弦光栅,可以用公式表示为:$I_n(x,y) = I_0 + I_m \cos(\phi(x,y) + \delta_n)$,其中&delta;n是相位偏移量,n从1到4对应四个步骤。因此,四个图案的公式应该是: I1 = I0 + Im*cos(phi) I2 = I0 + Im*cos(phi + &pi;/2) I3 = I0 + Im*cos(phi + &pi;) I4 = I0 + Im*cos(phi + 3&pi;/2) 不过,可能用户需要的是如何从这四个图案中计算出相位phi。计算相位的公式通常是使用反正切函数,结合四个步骤的强度值。具体来说,phi = arctan2((I4 - I2), (I1 - I3))。这步需要确保公式正确,避免相位缠绕的问题,可能需要后续的解包裹处理。 然后,考虑如何在MATLAB实现这个。首先生成四个相移图案,假设phi是某个初始相位分布,比如二维网格上的相位。例如,可以创建个网格坐标X和Y,然后设置phi = 2*pi*X/width,模拟水平方向的正弦变化。然后根据四个相位偏移生成四个图像矩阵I1到I4。 用户可能需要的是生成这些图案的代码,或者是从已有的四个图案中计算相位的代码。根据问题描述,用户问的是实现四步相移的代码,可能包括生成图案和计算相位两个部分。因此,代码需要包括这两部分。 另外,需要注意MATLAB中的矩阵运算,避免使用循环以提高效率。例如,使用meshgrid生成X和Y坐标,然后计算每个I的矩阵。同时,计算相位时使用atan2函数,正确处理象限问题。 可能还需要考虑示例参数,比如图像尺寸为512x512,I0和Im的取值,比如I0=127.5,Im=127.5,这样强度范围在0到255之间,适合显示为图像。然后,生成四个图案,并显示出来。 最后,相位解包裹可能是个后续步骤,但用户可能只需要基本的相位计算,所以代码中可以包含解包裹的简单示例,或者提到需要进步处理。 需要检查引用中的内容是否有相关部分。查看用户提供的引用,引用[3]提到将单相位循环边缘轮廓从目标空间转换到图像空间灰度级,可能涉及OECF(光电转换函数)的非线性转换。这可能与相移中的强度到相位的转换有关,但用户的问题更偏向于基础实现,所以可能不需要深入这部分,但可以提下非线性转换的可能性,并添加引用标识。 因此,代码部分应包括生成四个相移图案和计算相位的步骤,并在解释中提到相位解包裹和非线性转换的可能性,引用[^3]。同时,确保使用正确的LaTeX格式,比如数学公式用$...$和$$...$$。 可能的问题包括参数设置的影响、相位解包裹方、如何处理噪声等,这些可以作为相关问题列出。&lt;/think&gt;### 四步相移MATLAB实现 四步相移通过四幅相位差为$\pi/2$的光栅图像解算相位分布,常用于结构光三维重建。核心公式为: $$I_n(x,y) = I_0 + I_m \cos[\phi(x,y) + (n-1)\pi/2], \quad n=1,2,3,4$$ 相位解算公式为: $$\phi(x,y) = \arctan\left(\frac{I_4 - I_2}{I_1 - I_3}\right)$$ #### 代码实现 ```matlab % 参数设置 width = 512; % 图像宽度 height = 512; % 图像高度 I0 = 127.5; % 背景光强 Im = 127.5; % 调制幅度 % 生成初始相位分布(示例:水平方向线性相位) [X, Y] = meshgrid(1:width, 1:height); phi = 2*pi*X/width; % 相位范围[0, 2&pi;) % 生成四步相移图案 I1 = I0 + Im * cos(phi); I2 = I0 + Im * cos(phi + pi/2); I3 = I0 + Im * cos(phi + pi); I4 = I0 + Im * cos(phi + 3*pi/2); % 转换为uint8图像(0-255范围) I1 = uint8(I1); I2 = uint8(I2); I3 = uint8(I3); I4 = uint8(I4); % 显示图像 figure; subplot(221); imshow(I1); title(&#39;Phase 0&#39;); subplot(222); imshow(I2); title(&#39;Phase &pi;/2&#39;); subplot(223); imshow(I3); title(&#39;Phase &pi;&#39;); subplot(224); imshow(I4); title(&#39;Phase 3&pi;/2&#39;); % 相位解算 phi_cal = atan2(double(I4-I2), double(I1-I3)); % 使用atan2处理象限 phi_wrapped = mod(phi_cal, 2*pi); % 相位包裹在[0,2&pi;) % 相位解包裹(简单行扫描示例) phi_unwrapped = unwrap(phi_wrapped, [], 2); % 水平方向解包裹 % 显示结果 figure; subplot(121); imshow(phi_wrapped,[]); title(&#39;包裹相位&#39;); subplot(122); imshow(phi_unwrapped,[]); title(&#39;解包裹相位&#39;); ``` #### 关键说明 1. **参数调整**:$I_0$和$I_m$需满足$I_0 + I_m \leq 255$防止像素溢出 2. **相位生成**:示例使用线性相位,实际可替换为任意相位分布 3. **解包裹处理**:`unwrap`函数仅作示例,实际需根据应用场景选择解包裹算法
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值