用于测量和重建的双目内窥镜

文章阅读
作者: MingXiao

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点做一个十字,十字的四条边长由一个集合决定,这个十字上的元素需要满足(也就是如何求出这个集合的元素值)
    1. 与POI灰度相差小于阈值
    2. 与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步直到所有的非法的点

实际上就是摸出一些平滑的小区域,认为这些是遮挡物

这两个方法得到的非法点取并集



Comments