光源标定是进行光度立体三维重建的第一步,本文将介绍两种光源标定方法——基于金属球反射的标定以及基于“SFM”思想的标定

1.基于金属球反射的标定

标定光源的一种方法是使用金属球,在排到的金属球的照片上面的最亮的点指明了光源的方向

来源于http://pages.cs.wisc.edu/~csverma/CS766_09/Stereo/stereo.html的示意图:

然而,这幅示意图的几何向量标注具有一定的误导性,我将其换个角度表示以便展开光源方向的推导:

其中,反射方向R是固定的(因为它一直正对着观察者):
R=[0,0,1]T\ \mathbf{R}=[0,0,1]^T R=[0,0,1]T
我们取Px,Py\ P_x,P_y Px​,Py​为最亮点在图像中的像素坐标位置,Cx,Cy\ C_x, C_y Cx​,Cy​为金属球在图像中的中心点(可以由mask图像确定),由此我们可以求出法线向量N=[Nx,Ny.Nz]T\ \mathbf{N}=[N_x,N_y.N_z]^T N=[Nx​,Ny​.Nz​]T:
Nx=Px−Cx\ N_x=P_x-C_x Nx​=Px​−Cx​ Ny=Py−Cy\ N_y=P_y-C_y Ny​=Py​−Cy​ Nz=(R2−Nx2−Ny2)\ N_z = \sqrt{(R^2-N_x^2-N_y^2)} Nz​=(R2−Nx2​−Ny2​)​
N_z中的R是球的半径

求得法线向量后,我们可以知道:
R+L=N=2S\ \mathbf{R}+\mathbf{L}=\mathbf{N}=2\mathbf{S} R+L=N=2S L=2S−R\ \mathbf{L}=2\mathbf{S}-\mathbf{R} L=2S−R
我们现在转移到求S,因为S是R在N上的投影(向量投影计算可参考这里),因此可以得到:
S=(R⋅N)∣N∣2N=(R⋅N)N\ \mathbf{S}=\frac{(\mathbf{R}·\mathbf{N})}{|\mathbf{N}|^2}\mathbf{N}=(\mathbf{R}·\mathbf{N})\mathbf{N} S=∣N∣2(R⋅N)​N=(R⋅N)N
带入L的表达式,可得:
L=2(N⋅R)R−R\ \mathbf{L}=2(\mathbf{N·\mathbf{R}})\mathbf{R}-\mathbf{R} L=2(N⋅R)R−R
我们便可以利用上式求解光源方向

2.基于“SFM”的光源标定

论文标题:Light Structure from Pin Motion: Geometric Point Light Source Calibration(ECCV2018 / IJCV2020)

2.0 SFM简单回顾

SFM(structure from motion)目的是从图像特征点的对应同时恢复3D结构(3D点的位置)和姿态(相机的外参数)
设Pw\ P_w Pw​是世界坐标系的一个点,Pc\ P_c Pc​是Pw\ P_w Pw​在相机坐标系中的位置,则有Pc=[Rt]Pw\ P_c=[R \quad t]P_w Pc​=[Rt]Pw​,该点在成像平面的齐次坐标为p=[μ,v,1]T\ p=[\mu,v,1]^T p=[μ,v,1]T,其在归一化平面的坐标为x=[Xc/Zc,Yc/Zc,1]\ x=[X_c/Z_c,Y_c/Z_c,1] x=[Xc​/Zc​,Yc​/Zc​,1],有p=Kx,x=K−1p\ p=Kx,x=K^{-1}p p=Kx,x=K−1p,则通过对极几何约束,我们可以获得同一个特征点在两幅图像(相机在两个姿态)下坐标的对应关系:
对于本质矩阵
E=[t]×R\ E=[t]_\times R E=[t]×​R
和基础矩阵
F=K−TEK−1\ F=K^{-T}EK^{-1} F=K−TEK−1
本质矩阵表征了点在两个姿态下归一化平面坐标的对应关系:
x2TEx1=0\ x_2^TEx_1=0 x2T​Ex1​=0
基础矩阵表征了点在两个姿态下齐次像素坐标的对应关系:
p2TFp1=0\ p_2^TFp_1=0 p2T​Fp1​=0
考虑E\ E E的尺度等价性,我们可以使用八点法来求解基础矩阵E\ E E

在求出E\ E E后,可以通过SVD分解求出R和t\ R和t R和t

如果场景中的特征点都落在同一平面上,则可以通过单应矩阵H\ H H来进行运动估计,单应矩阵描述了两个平面间的映射关系,对于图像I1,I2\ I_1,I_2 I1​,I2​中匹配好的落在同一个平面上的特征点p1,p2\ p_1,p_2 p1​,p2​,其对应关系为:
p2=K(R−tnTd)K−1p1=Hp1\ p_2=K(R-\frac{tn^T}{d})K^{-1}p_1=Hp_1 p2​=K(R−dtnT​)K−1p1​=Hp1​

单应矩阵可以通过4对匹配特征点算出(特征点不能三点共线)

在估计出相机运动后,可以通过三角测量估计出地图点的深度。

2.1 方法介绍

在第一节所介绍的用金属球进行标定的方法中,存在以下的弊端:
1.需要拥有相对精确的球体
2.需要注释出每个图像的高亮中心
3.需要标出图像中球的轮廓(mask)
4.小的标注误差会导致光源位置大的偏差

因此作者提出一种新的方法来进行光源的标定:作者通过在标定板上插上带有一定大小头部的针,通过在固定相机下改变标定板的姿态,从而获得当前光源的位置信息:


论文提出方法的流程图:

2.1.1阴影的形成模型

假设阴影接收平面π固定于世界坐标系的x-y平面

一个近点光源在世界坐标系的位置为:
l=[lx,ly,lz]T∈R3\ \mathbf{l}=[l_x,l_y,l_z]^T \in \mathbb{R}^3 l=[lx​,ly​,lz​]T∈R3
假设阴影制造物(caster),即针头的位置为c∈R3\ \mathbf{c} \in \mathbb{R}^3 c∈R3,它产生的阴影在π平面上位置为s∈R2\ \mathbf{s} \in \mathbb{R}^2 s∈R2,在世界坐标系中位置是s‾=[sT,0]T\ \overline{\mathbf{s}}=[\mathbf{s}^T,0]^T s=[sT,0]T,因为l,c,s‾\ \mathbf{l},\mathbf{c},\overline{\mathbf{s}} l,c,s在同一直线上,因此由其中两个点组成的任意两直线是平行的,因此可以得出:



代入(1)式得:

将叉积展开得到:

从中可以求出sx和sy:

我们将s写为齐次坐标,并使用缩放因子γ\ \gamma γ,得到:

继续整理得:

将等号右边改写为矩阵相乘的形式得:

我们称L\ \mathbf{L} L为光矩阵,我们将其分解可以得到其内参和外参:

以上是关于近点光源的,对于远点光源,光线是平行的,因此光向量应该指光源的方向,而不是光源点的位置,因此(1)变为:

同理我们可以整理为:

我们发现对于远点光源,光矩阵(3,3)的位置是0,这个光矩阵类似于在相机矩阵中的正交投影

我们希望将近点光源和远点光源的光矩阵统一起来,在齐次坐标中,相差一个常数的缩放是等价的,因此我们把两个光矩阵都除以lz\ l_z lz​,得到:

可以发现,当光源无限远时,近点光源光矩阵变为远点光源光矩阵,因此我们使用下式作为统一的阴影投影等式:

这也是为什么论文名为Light Structure from Pin Motion的原因,论文中恢复光源方向的思想是跟SFM类似的,点光源和针孔相机可以被相似的数学模型所描述,其相似的对应关系为:
1.点光源=针孔相机
2.阴影接收面=图像平面(成像面)
3.阴影caster=场景点
4.光矩阵L=相机投影矩阵P=KT=K[R∣t]\ P=KT=K[R|t] P=KT=K[R∣t]

Light Structure from Pin Motion与SFM的对比:

2.1.2 阴影对应中的对极几何

回顾SFM,相机运动的求解是基于对极几何约束的,那么,在Light Structure from Pin Motion中,也应该找出阴影对应的对极几何约束。

作者移动光源,同时casters和阴影接收面是静止的,在其中分析阴影的对应关系,这类似于SFM中移动的相机与静置的场景点。

阴影的对极几何关系图:

caster是静置且位置未知的,对于由光源l1\ l_1 l1​投影得到的阴影s\ s s,caster可以在线段l1s\ l_1s l1​s上的任意位置,当光源位置移动到l2\ l_2 l2​时,一系列阴影的可能位置形成一条线,这相当于相机对极几何中的极线。

我们现在希望构造出阴影对极几何中的基础矩阵F\ F F

记c\ c c是caster的位置,l1≠l2\ l_1 \neq l_2 l1​​=l2​是在标定目标坐标系下的光的位置,Li是li\ L_i是l_i Li​是li​的光矩阵,L1+=(L1TL1)−1L1T是L1\ L_1^+=(L_1^TL_1)^{-1}L_1^T是L_1 L1+​=(L1T​L1​)−1L1T​是L1​的伪逆,∅L1∈null(L1)\ \empty_{L_1} \in null(L_1) ∅L1​​∈null(L1​)是L1\ L_1 L1​一维零空间下的非零向量,η\ \eta η是一个缩放常量,我们可以得到:


对上式左乘s~2T[L2∅L1]×\ \tilde{s}_2^T[L_2 \empty_{L_1}]_\times s~2T​[L2​∅L1​​]×​,得到:

由此我们得到了表征阴影对应的基础矩阵,对于Li\ L_i Li​
我们得到零空间向量∅L1\ \empty_{L_1} ∅L1​​

将其代入(5)式得到基础矩阵:

这个矩阵是反对称的,对于阴影s1~=[u,v,1]T,s2=[u′,v′,1]~\ \tilde{s_1}=[u,v,1]^T, \tilde{{s_2}=[u',v',1]} s1​~​=[u,v,1]T,s2​=[u′,v′,1]~​,阴影的对极约束为:

因此我们可以解齐次线性方程组来求解在一个缩放因子下成立的系数f:

这实际上相当于估计只进行纯平移而不进行相对旋转的相机的常规的本质矩阵,由式(2)可以看出,旋转矩阵为单位阵

2.2 模型求解

论文提出的方法中,通过在固定点光源下从固定视点(相机位置固定)对标定目标进行多次观察,同时改变标定目标的姿态,自动实现点光源标定。阴影caster相对于校准目标的3D位置是未知的,这使得它特别容易建立目标,而问题仍然是易于处理的。

2.2.1 通过光束平差法标定光源方向

目标:通过观察投影自未知caster的阴影求出(4)中的l\ l l。一次观察不足以提供充分的信息,因为我们让阴影接收面经历多个姿态{[Ri∣ti]}\ \{[R_i|t_i]\} {[Ri​∣ti​]}

在第i个姿态中,光源在接收面坐标系中的位置li\ l_i li​与在世界坐标系中的位置l\ l l的关系为:

光矩阵Li\ L_i Li​为:

作者不仅使用多个姿态,更使用多个casters{cj}\ \{c_j\} {cj​}来提高校准精度,因此对于姿态i和caster j,我们得到阴影sij\ s_{ij} sij​,此时(4)变为:

假设目标姿态{[Ri∣ti]}\ \{[R_i|t_i]\} {[Ri​∣ti​]}已知,我们目标是估计光源在世界坐标系中的位置l\ l l以及caster在标定目标坐标系中的位置cj\ c_j cj​,我们通过最小化重投影误差构建一个最小二乘问题:

可以使用LM算法来求解这个非线性最小二乘问题,为了鲁棒的估计使用随机抽样一致性(RANSAC)算法:我们不断选取一个随机的观测集,估计(l,cj,λij)\ (l,c_j,\lambda_{ij}) (l,cj​,λij​),选择有最小残差的一个

2.2.2 Bundle Adjustment的初始化

(1)近点光源
类似于式(1),我们可以写出:



代入得到:

其中,

我们可以重写上式为:

扩展叉积得到:

我们将它整理一下,得到:

其矩阵形式为:

这个方程包含一个观测结果,即姿态i和caster j的结合,但是我们需要堆砌多个观测下的方程。为了简化步骤,我们先将(18)分为几个子矩阵:

让Np,Nc\ N_p,N_c Np​,Nc​为目标姿态和casters的数量,可以得到整个系统的方程为:

因为所有的观测共享l=[lx,ly,lz]T\ l=[l_x,l_y,l_z]^T l=[lx​,ly​,lz​]T,每个θj\ \theta_j θj​有12个未知数,因此我们有3+12Nc\ 3+12N_c 3+12Nc​个未知数

为了防止外点的影响,我们通过L1最小化来鲁棒求解:

为了求解此式,我们要满足:

因此,不管casters有多少,5个姿态下的观测足以求解方程

解出θ∗\ \theta^* θ∗后,我们忽视二阶变量如lxcj,x\ l_xc_{j,x} lx​cj,x​,使用cj∗,l∗\ c_j^*,l^* cj∗​,l∗来初始化(17)

(2)远点光源
对于远点光源,矩阵A的秩为3+12Nc−1\ 3+12N_c-1 3+12Nc​−1,因此,不幸的是,我们不能使用(18)来处理远光,但我们可以自动检测这种情况,切换到对远光的方程,求解,并切换回(17)的BA。因此,用户不必为他们的场景选择一个光照模型。

我们通过构造近点光源的矩阵A,然后检测A的奇异值,如果最大和最小的奇异值之比大于4e+4,我们转换到远光求解

对于远光,类似于(3),我们使用li=RiTl\ l_i=R_i^Tl li​=RiT​l重写为:

类似得,我们将其整理得:

设置l=[lx,ly,1]T\ l=[l_x,l_y,1]^T l=[lx​,ly​,1]T(2自由度)得到:

整理得:

将其改写为矩阵形式,得:

其子矩阵的形式为:

多次观测的方程堆叠和求解类似于(19)(20),为了求解这个线性方程组,我们要满足:

因此只需要4个姿态下的观测,因为对于远光的方程组求解得到的是光的方向(direction),但光束平差法需要光的位置(position),因此我们需要它们的一个转换。我们从其中一个casters开始,将光源不断移动到很远的地方:

c是世界坐标系下任意的caster的位置,k是大常数(10e+10),hc是caster的高度

2.2.3 阴影对应

在(17)(18)(21)中,我们需要得到在不同图像Ii\ \mathbf{I}_i Ii​中同一个caster j产生阴影sij\ s_{ij} sij​的对应。形式上,阴影对应搜索意味着我们需要找到与图像之间对应阴影匹配的置换

设S\ S S为阴影{si~}\ \{\tilde{s_i}\} {si​~​},S′\ S' S′为阴影{si′~}\ \{\tilde{s'_i}\} {si′​~​},将其水平叠加成矩阵,对于基础矩阵,我们寻找:

也就是说,S′\ S' S′的每一列都是一个阴影向量,我们将置换矩阵P′\ P' P′右乘,以对各个阴影向量进行排列,只有S′和S\ S'和S S′和S的每一列对应的阴影向量是在两幅图像中一一对应时,基础矩阵的对极约束等式才为0

不同于传统的图像特征匹配,我们不能使用特征描述符来缩小搜索范围,因为我们希望阴影非常小(为了让阴影的中心可以精确定位),所以不能改变caster的形状以使其阴影与其他caster的阴影有明显区别

作者通过检测多幅图像对应的一致性以获得阴影对应

对应一致性检验
作者建立了两个图像池:已经建立了阴影对应的图像——确定池(established pool) 以及对应未知的图像——未知池(unknown pool)

确定池用一张随机的,未知的图像进行初始化,目的是将尽可能多的图像从未知池移动到确定池中

工作分为两个阶段,在第一个阶段中,在确定池随机选取图像Ie\ I_e Ie​,在未知池选取k张图像Ii1,...Iik\ I_{i_1},...I_{i_k} Ii1​​,...Iik​​

假设

是一个二值函数,其为真的条件是:当且仅当对于图像Ia,Ib\ I_a,I_b Ia​,Ib​,Ia\ I_a Ia​中的阴影si\ s_i si​和Ib\ I_b Ib​中的阴影sj\ s_j sj​获得匹配,使得式(22)最小化

然后,如果:

成立(即,从确定池抽取的图像开始,与未知池的第一张图像匹配,然后未知池的第一张与第二张图像进行匹配,以此类推,通过第一张(确定池图像)到最后一张(未知池的最后一张图像)能沿着图像链一直对应下去),我们就将未知池的图像Ii1,...Iik\ I_{i_1},...I_{i_k} Ii1​​,...Iik​​移动到确定池,为了使约束严格,作者在文章中选择k=3,一旦有一半的图像转移到了确定池,我们就转到第二个阶段

在第二个阶段中,假设确定池中所有的图像都是一致对应的。因此,如果我们考虑一个未知图像和一个caster,那么所有已确定的图像中对应于那个特定caster的所有阴影都应该匹配未知图像中的相同阴影,这适用于所有的阴影caster。我们随机选取一幅未知图像,验证这一准则,如果超过一半的已确定图像与未知图像的对应关系一致,将其移动到确定池,否则将其丢弃,当未知池为空时,第二阶段结束

阴影检测
作者使用模板匹配方法进行阴影检测

作者生成了由一条线和一个圆组成的阴影合成图像作为模板。为了处理变化的射影变换,生成的模板具有12个旋转角度,每个角度都有3个大小的模板(也就是有36个模板)。作者将输入图像二值化后再进行模板匹配。进一步,作者使用针头头部的颜色(红色)来区分头部和头部阴影

2.3 实际操作(代码)

论文的github仓库:https://github.com/hiroaki-santo/light-structure-from-pin-motion

(1)相机标定
论文的代码中是使用Arcuo码进行标记的,因此我们首先要制作Arcuo标定板:

import cv2
from cv2 import aruco
import numpy as npdic = aruco.getPredefinedDictionary(aruco.DICT_6X6_1000)
board = aruco.GridBoard_create(5, 7, 100, 10, dic)
img = np.zeros((600, 800))
img = aruco.drawPlanarBoard(board, (600, 800), img, 10, 1)
cv2.imshow("board", img)
cv2.waitKey(0)

打印得到的Aruco标定板:

我在测试时使用的是手机摄像头,通过不同角度拍摄屏幕上显示的标定板,获得了14张图片来进行标定:

标定得到的数据:

上面是手机相机的内参矩阵,下面是5个失真系数

代码里的detect_markers.py可以检测aruco标记:


剩下的阴影检测,实际光源标定的步骤在代码的README文档里也有操作指导,这里就不展开了。

我组建了一个光度立体技术的交流群,有兴趣的朋友可以一起来讨论一下!

Photometric Stereo 光度立体三维重建(四)——光源标定相关推荐

  1. Photometric Stereo光度立体三维重建(五)——基于深度学习的PS方法

    本文将会介绍几种具有代表性的将深度学习与Photometric Stereo进行结合来进行三维重建的方法 一.开山之作 DPSN 论文:Deep Photometric Stereo Network ...

  2. Photometric Stereo 光度立体三维重建(一)——介绍

    在计算机视觉的三维重建中,基于几何的方法有: SFM立体视觉 结构光 我们在这篇文章中介绍的是基于光度立体视觉的三维重建方法: 基于几何的三维重建方法中可以恢复粗略的三维形状,而光度法的特点是可以对物 ...

  3. Photometric Stereo 光度立体三维重建(三)——由法向量恢复深度

    本文分为三部分,第一部分是使用最小二乘法求解物体表面法向量,第二部分是利用求解得到的法向量求出物体表面的深度(物体表面的高度场),第三部分是将求出的高度场写成obj文件后使用MeshLab显示 1. ...

  4. 如何获取物体表面的法向量?好好谈谈光度立体法

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:AI算法与图像处理 这种逼真的效果,一个很重要的原因是获 ...

  5. 光度立体(Photometric Stereo)领域中的GBR问题

    1999年P. N. Belhumeur等人在<The Bas-Relief Ambiguity>中首次对GBR问题进行了阐述,所谓"bas-reliefs",是指当从 ...

  6. 双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python

    双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python 目录 双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python 1.项目结构 2. Environment 3.双 ...

  7. 光度立体(一)- 基于先验信息的快速表面法向量求解

    基于先验信息的快速表面法向量求解 一.光度立体法简介 二.经典光度立体法求解法向量 三.基于先验信息快速求解法向量 一.光度立体法简介 光度立体法(Photometric Stereo)是一种使用多个 ...

  8. halcon:光度立体法

    下文是对于halcon:光度立体法的一些浅薄理解. 主要用于测试产品表面的凹坑,深一点的划伤等等 光度立体法是通过二维图片提取三维模型,一般使用4张图. 下面先看一下测试原图和测试结果 原图: 结果图 ...

  9. Halcon 光度立体法应用(二)——皮革表面缺陷检测

    Halcon 光度立体法应用--皮革表面缺陷检测 如果想深刻.系列的了解光度立体法,建议根据博客顺序观看.在这个例程中将会介绍通过光度立体法生成的图像适用场景. 总体代码注释说明 * 此例程介绍的是利 ...

  10. 3D视觉检测的未来:光度立体技术

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 利用3D表面定向,特别是它对反射光的影响,工业应用的光度立体产生对 ...

最新文章

  1. Java 方法重载 方法重写
  2. How to add and configure jetty server in maven pom.xml
  3. 《openssl 编程》之大数
  4. 舞台现场直播技术实践
  5. 微软同步框架入门开篇(附SnapShot快照Demo)
  6. android base64encoder 不存在
  7. 打印三角形之细节讲解
  8. JEECG-V3 版本相关文档开放通知
  9. Linux安装中文字体_宋体
  10. LeetCode 410. 分割数组的最大值
  11. kociemba算法c语言,Python kociemba包_程序模块 - PyPI - Python中文网
  12. 【剖析 | SOFARPC 框架】系列之 SOFARPC 注解支持剖析
  13. Unity MMO游戏架构设计之角色设计一
  14. 高德地图使用鼠标工具(mouseTool)画覆盖物折线(mouseTool.polyline),光标使用十字架(crosshair)类型,不断出现closehand小手图标干扰
  15. 经验:如何快速地写出格雷码
  16. JS基础--强制类型转换(易错点,自用)
  17. Linux应用基础与实训小结
  18. 来认识一下Ning!
  19. 国医大师王绵之:汤药煎服经验谈
  20. ES6字符串新增方法

热门文章

  1. 使用protues仿真stm32教程
  2. protues仿真之数码管消影问题
  3. java核心技术卷2 第9版 pdf,Java核心技术 卷II 高级特性(原书第9版) PDF
  4. 打印机服务器没有响应 请检查设置,打印机服务无法启动的解决办法
  5. 生成可编辑的pdf(可java代码动态赋值)
  6. java adt eclipse_Eclipse安装ADT插件
  7. 马士兵oracle视频教程笔记
  8. IE缓存文件提取器 视频,音频,图片一网打尽
  9. 如何在iPhone上安装Skype?
  10. 计算机毕业论文数据挖掘,数据挖掘论文范文