用于测量和重建的双目内窥镜
Sensors 2018, 18, 2243; doi:10.3390/s18072243
Introduction
探头:3.17mm
CMOS:400*400 pixels,两个
由于两个CMOS的配准直接影响了重建精度,使用了WOS-LBP进行3D测量,使用了两个相机的图像差进行3D重建
Method
双目立体视觉
两个CMOS完全相同且共面,配置如下

其中两个CMOS的中心的距离叫做基线距离\(B\),计算过程用这个更好理解

得到
\[
u_l = f \cdot \frac{X}{Z}\,\,,\,\,u_r = f\cdot \frac{X-B}{Z}\\
v_l=v_r = f\frac{Y}{Z}
\]
令\(u_l-u_r=d\),进而得到
\[
\begin{cases}
X = \frac{Bu_l}{d}\\
Y = \frac{Bv_l}{d}\\
Z = \frac{Bf}{d}
\end{cases}
\]
3D测量
这是为了精准得到视差
为了找到两个镜头中对应的元素,需要进行配准,常见的配准方法有4种
- distribution-based descriptor:统计图像的局部分布特征(方向梯度等)来定位,最准确,对噪音很敏感
- filter-based descriptor:先滤波,再做上面的
- moment-based descriptor:通过矩的统计值进行配对
- binary descriptor:利用像素点的邻域2n个点,(在一张图中)若一个灰度值大于另一个,则将其赋1,否则0,得到nbit代表这个点的二进制字符串,将两张图的所有字符串进行汉明距离匹配,当小于阈值时,认为是一个点
这里用了第四种,因为很快,对噪音不敏感
计算图像的主要方向
为了保证标识符的旋转不变性,需要先提取图像的主要方向
在POI的16*16圆形邻域内,计算每一个点的一阶梯度振幅和方向
首先将图像灰度化,然后就是常规的处理,统计梯度方向最大值作为主要方向
进行WOS-LBP的计算
对于邻域内的每个点\(X_{i,j}\),在其8联通区域内进行如下图的标注

其中\(n_1\)是使得\(\vec{X_{i,j}n_1}\)最接近主要方向的点,然后依次顺时针排列
计算公式如下
\[
\mathsf{WOS-LBP^{m}}(X_{i,j}) =2^0 \mathsf{sign}(n_m-n_{m+4}) + 2^1 \mathsf{sign}(n_{m+2}-n_{m+6})
\]
其中
\[
\mathsf{sign} = \begin{cases}
1,\,\,\, x>T\\
0,\,\,\, o.w.
\end{cases}
\]
\(m=1,2\)
加权体现在突出正交于主要方向的量,最终结果的值域为\(\{0,1,2,3\}\),分别记为0001,0010,0100,1000
这样,每一个\(X_{i,j}\)都会产生一个8bit的二进制字符串
但是这样的分辨率太低,不能准确描述,故改进算法,利用分区域分布的想法
最终算法
以POI为中心,半径为8做一个领域,将这个区域分为5等分,对每一个区域进行下面的操作:
将RGB三种颜色分开,分别计算灰度,计算每一个区域的WOS-LBP
\[
H^m(k) = \sum_{X_{i,j}\in K_l}f\left( \mathsf{WOS-LKP^m(X_{i,j}),k} \right)
\]
其中\(K_l\)是第\(l\)个子区域,\(l=1,2,3,4,5\),\(k=0,1,2,3\)
\[
f(x,y) = \begin{cases}
\exp(-\frac{(i^2+j^2)}{2(1.5\sigma)^2})\,\,,\,\, x=y\\
0\,\,\,\,\,\,\,\,\,\,\,\,\, o.w.
\end{cases}
\]
\(\sigma\)是常数,一般取1.6
这样,对于一个点,会产生\(3\times 5\times 8=120\)维的向量,比目前的算法都少
设这个向量为\(X = \{x_1,x_2,\ldots,x_{120}\}\)
根据
\[
D = \sqrt{\sum_{i=1}^{120}(x_i-y_i)^2}
\]
进行两个POI的配准,当\(D_{\min}\)时,就是配对了
得到了一对配准的点之后,可以算出这个点的3维坐标,多算几个点就能进行3D测量
立体配准
分为四个阶段:cost initialization, cost aggregation, disparity computation and disparity optimization.
需要注意,这里的视差\(d\)是一个范围,需要遍历,每一个\(d\)都能得到一个视差矩阵,在这个矩阵中选择代价最小的。
Cost Initialization
经典Census Transformation(CT)算法使用中心点和邻域的灰度,若中心点大则赋0,得到一个8bits string,利用汉明距离进行配准,但是这个丢失了位置信息
本文使用了高斯滤波器进行空间滤波
设左边的图像是\(p(x,y)\),右边的是\(q(x-d,y)\),\(d\)不是上面好不容易求出来的差距,定义Cost
\[
C_{AD}(p,d) = \sum_{R,G,B}|I^{left}(p)-I^{right}(q)|\\
C_{census}(p,d) = Hamming(CT(p),CT(q))
\]
其中\(I\)是经过高斯滤波的灰度级,二者的结构都是和原图一样大的矩阵,结合两个Cost
\[
C(p,d) = \rho (C_{census},\gamma_1) + \rho(C_{AD},\gamma_2)
\]
其中\(\rho = 1-e^{-\frac{c}{\gamma}}\)
Cross-Based Local Support Region Construction
只有一个点的配准存在准确度的问题,将这个点生长为一个区域
原方法需要看原始文献,大致如下
- 在POI点做一个十字,十字的四条边长由一个集合决定,这个十字上的元素需要满足(也就是如何求出这个集合的元素值)
- 与POI灰度相差小于阈值
- 与POI欧氏距离相差小于阈值
由于这个方法只是用了距离和灰度差两个信息,文章作者觉得不够,又加了一些信息
- 使用Scharr算子(类似于Sobel)计算相邻元素的梯度幅度
- 当距离超出第一个阈值时,选择更小的灰度差阈值防止增长过快
- 使用canny算子计算边界,用更小的距离和灰度阈值对边界处的点进行选择
由此得到了一个十字的范围,然后
- 在竖直轴上遍历,每一个竖直点都会得到一个水平轴
- 不同竖直点的水平轴长度和范围不同
- 遍历结束后的二维图形就是一个LSR
Cost Aggregation
按上面的流程,在两幅图像中各自的到了一个配准区域,通过第一步计算出的\(d\),对两个区域取交集
\[
U_d(p) = \{(x,y)|(x,y)\in U(p) \and (x-d,y)\in U(q)\}
\]
将这个区域内的所有元素\(s\)代入到\(C(p,d)\)的公式中去,取均值得到这个区域的汇总
\[
E(p,d) = \frac{1}{N}\sum_{s\in U_d}C(s,d)
\]
在这个矩阵中选择匹配代价最小的\(s\)的视差\(d\)作为这个点的视差
当然也有别的,比如选择占比最大的
需要注意的是,以上三个过程是对全图进行的,也就是对于\(p(x,y)\)的每一个点,都会得到一个\(U_d\),经过WTA后采取一个最优的\(d\)
Disparity Optimization
对视差图滤波,去除mismatch
分别以左右两张图为参考做一次视差图,如一个点在两张图上的视差相差超过阈值,那么认为这个点的视差无效,需要进行修正;余下的视差有效,保留
对于需要修正的视差,根据上面第二步得到的Cross-Based的区域进行计数,区域像素总数\(N\),区域合法的像素总数\(V\)
\(V
如果没有,向上下扩散找
\(N/3\leq V<2N/3\),区域内所有合法的视差的平均值作为这个点的视差
\(V\geq 2N/3\),用占比最大的视差作为这个点的视差
对于一些由遮挡引起的视差错误,用上面的算法是无法实现去噪的,引入信息熵
\[
E = \sum_{i=0}^{L-1}p_i\log p_i
\]
在p的邻域内计算,当\(E\)小于一个阈值时,认为被遮挡,用下面的算法扩展这个领域
- 将不可靠点中的某一个作为种子
- 对于首次被标记的领域内的点\((x,y)\),当满足灰度相近时标记,作为下一个种子
- 重复2直到所有点被标记,将这些点设为一个区域集合
- 若这个集合小于2000,所有点非法;否则,这些点合法
- 重复第1步直到所有的非法的点
实际上就是摸出一些平滑的小区域,认为这些是遮挡物
这两个方法得到的非法点取并集