Hanjie's Blog

一只有理想的羊驼

  • 型号:Thinkpad T460p
  • 显卡:GeForce 940MX
  • 系统:Ubuntu 16.04.4 LTS
  • 内核:4.13.0-45-generic

为SLAM系统开发配置环境,使用ZED MINI CAMERA。

Ubuntu 16.04

1
2
3
4
5
6
7
8
9
uname -r
4.13.0-36-generic

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.4 LTS
Release: 16.04
Codename: xenial
换源
1
2
sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup
sudo gedit /etc/apt/sources.list

填入:

1
2
3
4
5
6
7
8
9
10
deb http://mirrors.163.com/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ xenial-backports main restricted universe multiverse

终端:

1
2
sudo apt-get update
sudo apt-get upgrade
1
sudo apt-get install build-essential vim
安装NVIDIA驱动
1
2
3
4
5
sudo apt-get remove --purge nvidia*
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys FCAE110B1118213C
sudo apt-get update
sudo apt-get install nvidia-396

重启电脑,终端执行:

1
2
3
ls /dev/nvidia*

/dev/nvidia0 /dev/nvidiactl /dev/nvidia-modeset /dev/nvidia-uvm
1
2
3
4
cat /proc/driver/nvidia/version

NVRM version: NVIDIA UNIX x86_64 Kernel Module 396.24 Thu Apr 26 00:10:09 PDT 2018
GCC version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)

安装CUDA 9.1

官网下载CUDA cuda_9.1.85_387.26_linux.run。

1
2
chmod +x cuda_9.1.85_387.26_linux.run
sudo sh ./cuda_9.1.85_387.26_linux.run

只安装CUDA 9.1 Toolkit。

重启,配置环境:

1
sudo gedit ~/.bashrc

添加:

1
2
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

刷新:

1
source /etc/profile

重启:

1
2
3
4
5
6
nvcc -V

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Nov__3_21:07:56_CDT_2017
Cuda compilation tools, release 9.1, V9.1.85
Building Samples (optional)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
cd /NVIDIA_CUDA-9.1_Samples/1_Utilities/deviceQuery
make
./deviceQuery

CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 1 CUDA Capable device(s)

Device 0: "GeForce 940MX"
CUDA Driver Version / Runtime Version 9.2 / 9.1
CUDA Capability Major/Minor version number: 5.0
Total amount of global memory: 2004 MBytes (2101870592 bytes)
( 3) Multiprocessors, (128) CUDA Cores/MP: 384 CUDA Cores
GPU Max Clock rate: 1242 MHz (1.24 GHz)
Memory Clock rate: 1001 Mhz
Memory Bus Width: 64-bit
L2 Cache Size: 1048576 bytes
Maximum Texture Dimension Size (x,y,z) 1D=(65536), 2D=(65536, 65536), 3D=(4096, 4096, 4096)
Maximum Layered 1D Texture Size, (num) layers 1D=(16384), 2048 layers
Maximum Layered 2D Texture Size, (num) layers 2D=(16384, 16384), 2048 layers
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 49152 bytes
Total number of registers available per block: 65536
Warp size: 32
Maximum number of threads per multiprocessor: 2048
Maximum number of threads per block: 1024
Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535)
Maximum memory pitch: 2147483647 bytes
Texture alignment: 512 bytes
Concurrent copy and kernel execution: Yes with 1 copy engine(s)
Run time limit on kernels: Yes
Integrated GPU sharing Host Memory: No
Support host page-locked memory mapping: Yes
Alignment requirement for Surfaces: Yes
Device has ECC support: Disabled
Device supports Unified Addressing (UVA): Yes
Supports Cooperative Kernel Launch: No
Supports MultiDevice Co-op Kernel Launch: No
Device PCI Domain ID / Bus ID / location ID: 0 / 2 / 0
Compute Mode:
< Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 9.2, CUDA Runtime Version = 9.1, NumDevs = 1
Result = PASS

安装OpenCV 3.4.0

官网下载sources。

1
2
3
4
5
6
7
8
9
10
sudo apt-get install build-essential git cmake git yasm libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev python-dev python-numpy python-tk libtbb2 libtbb-dev libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev libdc1394-22-dev libswscale-dev libopenexr-dev libeigen2-dev libeigen3-dev libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common texlive-latex-extra libv4l-dev

mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_EXAMPLES=OFF -D BUILD_DOCS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_TESTS=OFF -D WITH_GTK_2_X=ON -D WITH_QT=ON -D WITH_OPENGL=ON ..
make -j8
sudo make install

sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

安装ROS Kinetic (optional)

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116

sudo apt-get update
sudo apt-get install ros-kinetic-desktop-full

sudo rosdep init
rosdep update

echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
source ~/.bashrc

sudo apt-get install python-rosinstall

echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc之后,系统的opencv版本会变成Kinetic自带的3.3版本,所以必要时不要添加此句。

安装ZED SDK

官网下载ZED_SDK_Linux_Ubuntu16_v2.4.0.run。

1
2
chmod +x ZED_SDK_Linux_Ubuntu16_v2.4.0.run
./ZED_SDK_Linux_Ubuntu16_v2.4.0.run

输入 q 退出 license agreement。

To accept the license simply press Tab key until the 'O.k.' is highlighted when installing the ttf-mscorefonts-installer

测试:

1
/usr/local/zed/tools/ZED\ Explorer

zed camera test

为了测试新的双目SLAM系统,需要带有ground truth,depth信息的dataset。但寻找后发现这类dataset不多,于是尝试搭建AirSim仿真平台,希望能自己生成一些具有深度的双目数据。

系统环境:

  • 型号:Thinkpad T460p
  • 显卡:GeForce 940MX
  • 系统:Ubuntu 16.04.4 LTS
  • 内核:4.13.0-36-generic
  • CUDA: 9.1

显卡驱动

太新或太久的驱动都不行1,我尝试过使用396,但是场景会一片白,更换为384版本:

1
2
3
4
5
sudo apt-get remove --purge nvidia*
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys FCAE110B1118213C
sudo apt-get update
sudo apt-get install nvidia-384

Install and Build2

根据这里注册Epic Games帐号,并且关联github账号。

We use the same compiler that Unreal Engine uses, Clang 5.0, and stdlib, libc++.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sudo apt-get install build-essential mono-mcs mono-devel mono-xbuild mono-dmcs mono-reference-assemblies-4.0 libmono-system-data-datasetextensions4.0-cil libmono-system-web-extensions4.0-cil libmono-system-management4.0-cil libmono-system-xml-linq4.0-cil cmake dos2unix clang-5.0 libfreetype6-dev libgtk-3-dev libmono-microsoft-build-tasks-v4.0-4.0-cil xdg-user-dirs

sudo ln -s /usr/bin/clang-5.0 /usr/bin/clang
sudo ln -s /usr/bin/clang++-5.0 /usr/bin/clang++

clang -v
clang version 5.0.0-3~16.04.1 (tags/RELEASE_500/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.0.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
Found CUDA installation: /usr/local/cuda, version unknown

安装UnrealEngine

1
2
3
4
5
6
# go to the folder where you clone GitHub projects
git clone -b 4.18 https://github.com/EpicGames/UnrealEngine.git
cd UnrealEngine
./Setup.sh
./GenerateProjectFiles.sh
make

安装AirSim.git

1
2
3
4
5
# go to the folder where you clone GitHub projects
git clone https://github.com/Microsoft/AirSim.git
cd AirSim
./setup.sh
./build.sh

如果遇到mono-devel : Depends: libmono-cil-dev (= 3.2.8+dfsg-4ubuntu1.1) but it is not going to be installed 错误,将源换成mirrors.163.com的就可以了。

Built-in Blocks Environment3

为了测试安装结果,运行自带的Blocks Environment作测试。

RunUnrealEngine/Engine/Binaries/Linux/UE4Editor, Click on Projects tab, Browse button and then navigate to AirSim/Unreal/Environments/Blocks/Blocks.uproject

If you get prompted for incompatible version and conversion, select In-place conversion which is usually under "More" options. If you get prompted for missing modules, make sure to select No so you don't exit.

Press the Play button in Unreal Editor and you will see something like in below(use F1 to see help on keys).

Blocks Environment

"Computer Vision" Mode4

You can use AirSim in so-called "Computer Vision" mode. In this mode, physics engine is disabled and there is no vehicle, just cameras. You can move around using keyboard (use F1 to see help on keys). You can press Record button to continuously generate images. Or you can call APIs to move cameras around and take images.

To active this mode, edit settings.json that you can find in your Documentsfolder (or ~/Documents/AirSim on Linux) and make sure following values exist at root level(更多settings.json设置参考5):

1
2
3
4
{
"SettingsVersion": 1.2,
"SimMode": "ComputerVision"
}

设置好后,按Play button,效果如下。

Computer Vision

AirSim APIs6

1
2
sudo pip install msgpack-rpc-python
sudo pip install airs

在设置好Computer Vision Mode情况下,按下Play键运行仿真,然后打开一个终端(主要不要在IDE中运行,有可能会出现termios.error: (25, 'Inappropriate ioctl for device')错误),输入:

1
2
cd AirSim/PythonClient/
python cv_mode.py

会输出:

1
2
3
4
5
6
7
8
Connected!
Client Ver:1 (Min Req: 1), Server Ver:1 (Min Req: 1)

Press any key to set camera-0 gamble to 15-degree pitch
Press any key to get camera parameters
<instance> { u'fob': 90.0,
u'pose': <instance> { u'orientation':
...

Create Your Own Unreal Environment

以Modular Neighborhood Pack7为例。New Project > C++ > Basic Code,将项目名改为Neighborhood,注意设置no Starter Content。将包含Modular Neighborhood Pack数据的文件夹放置到Neighborhood项目文件夹的Content文件夹内。

Edit > Project Settings > Maps & Modes > Editor Startup Map设置为Demp_Map8

关掉,重启项目,等待场景打开后,Blueprints > Open level Blueprint,右击MatineeActor  Event BeginPlay,选择Break Link(s),然后关掉窗口。

If the environment comes with MatineeActor, delete it to avoid any startup demo sequences. There might be other ways to remove it as well, for example, click on Blueprints button, then Level Blueprint and then look at Begin Play event in Event Graph. You might want to disconnect any connections that may be starting "matinee"9.

Own Unreal Environment

From the File menu select New C++ class, leave default None on the type of class, click Next, leave default name MyClass, and click Create Class.

1
rsync -a --delete AirSim/Unreal/Plugins path/to/Project

Save Current,关闭软件。使用文本编辑器打开项目文件Neighborhood.uproject,编辑为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"FileVersion": 3,
"EngineAssociation": "4.18",
"Category": "Samples",
"Description": "",
"Modules": [
{
"Name": "LandscapeMountains",
"Type": "Runtime",
"LoadingPhase": "Default",
"AdditionalDependencies": [
"AirSim"
]
}
],
"TargetPlatforms": [
"MacNoEditor",
"WindowsNoEditor"
],
"Plugins": [
{
"Name": "AirSim",
"Enabled": true
}
]
}

重新运行Neighborhood.uproject,在World Settings > Game Mode中选择AirSimGameMode

gamemode

在Multi rotor模式下10,按play键运行场景,然后打开一个终端,输入:

1
2
cd AirSim/PythonClient/
python hello_drone.py

会输出:

1
2
3
4
5
6
7
Connected!
Client Ver:1 (Min Req: 1), Server Ver:1 (Min Req: 1)

state: <instance> { u'collision': <instance> { u'has_collided': False,
u'impact_point': <instance> { u'x_val': 0.0,

...
hello_drone

运行结束后,在\tmp\airsim_drone文件夹中,会有一些输出数据。

dronw_test_0
dronw_test_2
dronw_test_3.greene

  1. https://blog.csdn.net/CSDNhuaong/article/details/79147365↩︎

  2. https://github.com/Microsoft/AirSim/blob/master/docs/build_linux.md↩︎

  3. https://github.com/Microsoft/AirSim/blob/master/docs/unreal_blocks.md↩︎

  4. https://github.com/Microsoft/AirSim/blob/master/docs/image_apis.md#computer-vision-mode-1↩︎

  5. https://github.com/Microsoft/AirSim/blob/master/docs/settings.md#simmode↩︎

  6. https://github.com/Microsoft/AirSim/blob/master/docs/image_apis.md#computer-vision-mode-1↩︎

  7. https://www.unrealengine.com/marketplace/modular-neighborhood-pack↩︎

  8. https://github.com/1508189250/AirSim/blob/master/docs/build.md↩︎

  9. https://github.com/1508189250/AirSim/blob/master/docs/build.md↩︎

  10. https://github.com/Microsoft/AirSim/blob/master/docs/settings.md#simmode↩︎

罗汉杰,CVTE中央研究院
Slide

Introduction

我们生活在三维的空间中,然而,传统的摄像机和图像传感器只能获取二维的图像,缺乏深度的信息,这对感知和了解真实的物体造成了极大的限制。而最近几十年,随着高清,高速图像传感器和计算能力的不断发展,三维表面成像技术在研究,工程和商业上取得了显著的成果。特别是结构光三维表面成像技术,已经运用到各个地方中,从MEMS组件的表面测量到大面积平面厚度测量(2.5m×0.45m)1。结构光的显著的优点是能够通过非接触的方式,建立高分辨率,全幅的物体三维模型,合适于运用在对成像面积,精度有一定要求的应用中。

一般的3D影像技术中,可以用一个坐标系为\(\text{(x,y,z)}\)的空间中描述三维物体的属性。而3D表面成像技术,是专门用来测量物体表面的。测量的结果可以用一个以\(\lbrace z=h(x,y),x=1,2,...,L,y=1,2,...,M \rbrace\)为形式的矩阵来描述。\((x,y)\)为笛卡尔坐标系中的点坐标,\(z\)为该点的高度。

本文主要讲述构光三维表面成像技术,特别是相位测量轮廓术(Phase measuring profilometry, PMP)的原理和实现方式。

Structured-light 3D Surface Imaging System

下图2描述了一个经典的结构光三维表面成像系统。它包括一个投影模块(Projector),图像获取模块(Camera)和处理模块(Computer)。通过对目标物体表面主动投影一个有一定结构的二维纹理图像(如图所示的黑白光栅图),获取其随着物体表面高度变化而变形的二维纹理图,然后利用处理模块根据算法计算出物体表面三维几何结构。

structuredlight1

结构光三维成像技术根据实现方式的不同能分为很多类。根据拍摄次数的不同能分为多次拍摄(multiple-shot)和单次拍摄(single-shot)两个大类3。如果物体保持静止,并且应用对于获取时间没有严格要求的情况下,多次拍摄的方法一般能产生更可靠和更准确的结果。然而,如果物体是运动的话,则可以利用单次拍摄的方法获取物体在某个时间点的三维表面图像。本文中,我们主要讨论多次拍摄技术中的相位测量轮廓术(phase-measuring profilometry,PMP,也称作Fringe projection profilometry。Phase shift method 属于PMP的一种)。

structuredlight2

相对于Binary code和Gray code等编码结构光法,PMP不需要复杂的编码,并且算法可以根据每一个像素点的信息计算出高度数值,从而实现全幅高精度测量。在相位法中,通常包含以下步骤4

  1. 投影一个结构纹理图像(通常是一个正弦光栅图案)到待测物体表面。
  2. 记录被物体高度所相位调制的光栅图像。
  3. 利用光栅分析技术提取相位。
  4. 使用合适的相位展开算法,获得与物体高度等比例变化的连续相位分布。
  5. 标定系统,将展开了的相位分布映射到真实世界的三维坐标系中。

在每一个步骤中,都存在多种的变体。而根据相位提取方法的不同,相位法可以分为Phase shift profilometry (PSP,也称作Phase stepping profilometry),Fourier transform profilometry (FTP),Wavelet transform profilometry (WTP),Spatial filtering profilometry (SFP)等几个大类。本文主要讨论PMP中的Phase shift profilometry。

Phase Measuring Profilometry

Model

PMP方法的光学几何结构如下图5所示。投影模块产生的正弦光栅图像投影到放在参考平面(Reference plane)的物体表面上,所折射的光被图像获取模块(Camera)捕获。由于所投影的正弦图在列方向都是以相同模式改变的,所以物体的轮廓能够通过每一行的计算结果组建起来。

structuredlight3

在上图的例子中,我们假设O点为光轴跟参考平面的交点,O点被用作坐标原点并且相位为0。投影到参考平面上的正弦光栅图周期为\(p_{o}\),原始正弦光栅图周期为\(p\)\(p=p_{o}\cdot\cos\alpha\)。Camera中的传感器接收到在物体表面D点反射的光线;如果没有物体的话,传感器中的同一位置将会接收到在参考平面上的C点所反射的光线。相应地,物体表面D点折射的光线,跟没有物体的情况下水平面上G点折射的光线相同。所以投影图像在D点的相位相跟在G点的相位相等,有:

\[\begin{align} \phi_{D}=\phi_{G} \end{align}\]

\(\phi_{C}=2\pi OC/p_{o}\)为投影图像在C点的相位值。点D跟点C的相位差为:

\[\begin{align} \Delta\phi_{CD} &= \phi_{C}-\phi_{D}=\phi_{C}-\phi_{G} \label{eq:2.2} \newline &= 2\pi OC/p_{o}-2\pi OG/p_{o}=2\pi CG/p_{o} \notag \end{align}\]

根据几何关系,有:

\[\begin{align} CG=OD(\tan\alpha+\tan\beta)\label{eq:2.3} \end{align}\]

根据公式\(\ref{eq:2.2}\)\(\ref{eq:2.3}\),有:

\[\begin{align} OD=\frac{\Delta\phi_{CD}\cdot p_{o}}{2\pi(\tan\alpha+\tan\beta)}\label{eq:2.4} \end{align}\]

OD即为物体在点O的高。上式的一般式为:

\[\begin{align} h(x,y)=\frac{[\phi_{o}(x,y)-\phi_{r}(x,y)]\cdot p_{o}}{2\pi(\tan\alpha+\tan\beta)}\label{eq:2.13} \end{align}\]

\(\phi_{o}(x,y)\)为在点\((x,y)\)中的相位,\(\phi_{r}(x,y)\)为在相应点中参考平面上的相位。在实际系统中,由于\(\beta\)的值接近于\(0^{\circ}\),所以公式\(\ref{eq:2.13}\)也可以写成以下近似公式6

\[\begin{align} h(x,y)\approx\frac{[\phi_{o}(x,y)-\phi_{r}(x,y)]\cdot p_{o}}{2\pi\tan\alpha}\label{eq:2.5} \end{align}\]

从公式\(\ref{eq:2.5}\)可以看出,物体的高度信息可以通过提取投影在物体上的正弦图像相位值和投影在相应位置的水平面上的相位值计算所得。下一小节将介绍如何使用相移法(Phase shift profilometry)进行相位提取。

Phase Shift Profilometry

当在光照稳定,Camera是线性的情况下,所拍摄的图像中某点\((x,y)\)的光照强度\(I(x,y)\)能够表达为以下公式7

\[\begin{align} I(x,y)=B(x,y)+C(x,y)\cos\phi(x,y)\label{eq:2.6} \end{align}\]

\(B(x,y)\)为背景光强,\(C(x,y)\)为正弦光栅的幅度值,\(\phi(x,y)\)为受物体高度调制后的相位值。\(I(x,y)\)可以通过Camera获得,为了消掉公式中的\(B(x,y)\)\(C(x,y)\)而得到\(\phi(x,y)\),我们使用一种称作相移法的相位提取算法。在相移法中,相位将移动\(k(k\geq3)\)次,每次移动相等的值\(\theta_{k}\)\(\theta_{k}<2\pi\)。则公式\(\ref{eq:2.6}\)可以写成:

\[\begin{align} I_{k}(x,y) &= B(x,y)+C(x,y)\cos[\phi(x,y)+\theta_{k}] \label{eq:2.7} \newline &= B(x,y)+C(x,y)[\cos\phi(x,y)\cos{\theta_{k}}+\sin\phi(x,y)\sin\theta_{k}] \notag \end{align}\]

一般我们获取4张图片8。令\(\theta_{k}=(k-1)\pi/2\)\(k=\lbrace 1,2,3,4 \rbrace\),代入公式\(\ref{eq:2.7}\),可以得到:

\[\begin{align} B(x,y) & =\frac{1}{4}[I_{1}(x,y)+I_{2}(x,y)+I_{3}(x,y)+I_{4}(x,y)]\label{eq:2.8}\newline \cos\phi(x,y) & =\frac{I_{1}(x,y)-I_{3}(x,y)}{2C(x,y)}\label{eq:2.9}\newline \sin\phi(x,y) & =\frac{I_{4}(x,y)-I_{2}(x,y)}{2C(x,y)}\label{eq:2.10} \end{align}\]

从公式\(\ref{eq:2.9}\)\(\ref{eq:2.10}\)可以得到:

\[\begin{align} \tan\phi(x,y)=\frac{I_{4}(x,y)-I_{2}(x,y)}{I_{1}(x,y)-I_{3}(x,y)}\label{eq:2.11} \end{align}\]

因此我们得到相位值:

\[\begin{align} \phi(x,y)=\arctan\left(\frac{I_{4}(x,y)-I_{2}(x,y)}{I_{1}(x,y)-I_{3}(x,y)}\right) , \phi(x,y)\in[-\pi,\pi)\label{eq:2.12} \end{align}\]

然后物体表面高度可以根据公式\(\ref{eq:2.5}\)得出。

相移法由于利用多幅图像的光强信息计算得每一点的相位,具有一定的抗噪能力。但在采样的过程中,要求物体保持静止,所以不适合于动态测量。下图显示当\(k=4\)时,使用相移法将4张不同相位的正弦光栅图像投影到物体表面时的照片。可以看出,投影的光栅图像每次移动四分之一个周期。

structuredlight4

Phase Unwrapping

我们通过公式\(\ref{eq:2.12}\)计算获得相位值\(\phi(x,y)\)。然后在反正切计算中,所得的结果总是在\([−π, π)\)之间,而真正的相位即绝对相位应该是连续的,所以我们在相位展开时,需要作相应处理。

假定\(\phi^{wrap}\)表示被包裹的相位值,那么对相邻的两个相位\(\phi _1^{wrap}\)\(\phi _2^{wrap}\)进行展开运算\(U(\phi _2^{wrap}, \phi _1^{wrap})\)

\[\begin{align} U(\phi _2^{wrap}, \phi _1^{wrap}) = \phi _2^{wrap} - 2\pi R[(\phi _2^{wrap} - \phi _1^{wrap}) / 2\pi]\label{eq:2.14} \end{align}\]

\(R(\cdot)\)表示四舍五入到最接近的整数。所以,对于\(\phi _s^{wrap}\)的相位展开操作为:

\[\begin{align} \phi _{s}^{unwrap} = \sum _{t = 1}^s U( \phi _{t}^{wrap} , \phi _{t-1}^{wrap}) \label{eq:2.15} \end{align}\]

我们这里仅仅介绍了一种简单的相位展开操作,它对于相位展开时的路径十分敏感,错误的路径会导致错误的展开结果(如下图所示)。

structuredlight5

Appendix

Generation of Sinusoidal Pattern

相位测量轮廓术需要将具有不同相位的正弦光栅图案投影到物体表面上。传统方法采用两束激光,利用干涉原理生成正弦光栅图,相位的移动利用压电晶体实现9。然而激光干涉产生的斑点噪音会影响光栅图像的光强分布。另一方面,由于压电晶体的非线性属性,使得相位移动的产生误差。也有一些相位移动是通过步进电机位移平台实现的10。但系统的精度也难免受到平台移动时的震动而影响。

液晶投影仪能够利用个人电脑控制投影的图像。通过投影软件生成正弦光栅图像,它提供了一种高效的结构光投影方案。我们假设液晶投影仪的分辨率为\(R\times C\)。对于生成的正弦光栅图中的每一列\(c\)\(c=0,1,2,...,C-1\),有:

\[\begin{align} F_{n}(r,c) & =\lbrace 1+\sin\lbrace \frac{2\pi}{p}[r+(k-1)\delta] \rbrace \rbrace \cdot127.5\newline r & =0,1,2,...,R-1 \notag \label{eq:3.1} \end{align}\]

\(F_{n}(r,c)\)是相移\(k\)步后的光栅图中\((r,c)\)位置的像素值,在我们的例子中,\(k=\lbrace 1,2,3,4 \rbrace\)\(p\)是以像素为单位的光栅周期;\(\delta\)为相位移动增量。当\(|k|=4\)时,相位的增量为\(\pi/2\),所以相应地,\(\delta=p/4\)。下图显示了使用软件生成的正弦光栅图,每一张图都比上一张图往右移动了四分之一个周期。

structuredlight6

  1. S. S. Gorthi and P. Rastogi, “Fringe projection techniques: whither we are?,” Optics and Lasers in Engineering, vol. 48, no. IMAC-REVIEW-2009-001, pp. 133–140, 2010.↩︎

  2. S. S. Gorthi and P. Rastogi, “Fringe projection techniques: whither we are?,” Optics and Lasers in Engineering, vol. 48, no. IMAC-REVIEW-2009-001, pp. 133–140, 2010.↩︎

  3. J. Geng, “Structured-light 3d surface imaging: a tutorial,” Advances in Optics and Photonics, vol. 3, no. 2, pp. 128–160, 2011.↩︎

  4. S. S. Gorthi and P. Rastogi, “Fringe projection techniques: whither we are?,” Optics and Lasers in Engineering, vol. 48, no. IMAC-REVIEW-2009-001, pp. 133–140, 2010.↩︎

  5. F.Deng,W.F.Sze,J.Deng,K.S.Fung,W.Leung,andE.Y.Lam,“Regularizedmultiframe phase-shifting algorithm for three-dimensional profilometry,” Applied optics, vol. 51, no. 1, pp. 33–42, 2012.↩︎

  6. V. Srinivasan, H. Liu, and M. Halioua, “Automated phase-measuring profilometry of 3-d diffuse objects,” Applied optics, vol. 23, no. 18, pp. 3105–3108, 1984.↩︎

  7. V. Srinivasan, H. Liu, and M. Halioua, “Automated phase-measuring profilometry of 3-d diffuse objects,” Applied optics, vol. 23, no. 18, pp. 3105–3108, 1984.↩︎

  8. F.Deng,W.F.Sze,J.Deng,K.S.Fung,W.Leung,andE.Y.Lam,“Regularizedmultiframe phase-shifting algorithm for three-dimensional profilometry,” Applied optics, vol. 51, no. 1, pp. 33–42, 2012.↩︎

  9. Yen, H.N., Tsai, D.M. and Yang, J.Y., 2006. Full-field 3-D measurement of solder pastes using LCD-based phase shifting techniques. IEEE Transactions on Electronics Packaging Manufacturing, 29(1), pp.50-57.↩︎

  10. Xian, T. and Su, X., 2001. Area modulation grating for sinusoidal structure illumination on phase-measuring profilometry. Applied Optics, 40(8), pp.1201-1206.↩︎

0%