@kokerf
2018-04-25T14:53:40.000000Z
字数 4638
阅读 1540
开源SLAM笔记
在论文中,作者给出光度模型如下:
这里的为相机的响应函数(response function),为(归一化的)渐晕函数(vignette),是辐照度图像(irradiance image),是我们从相机获取的图像。在论文中,使用的是非参数化(non-parametric)的求解方式,也就是说我们不是求出函数的表达式,而是得到一个映射表。
在标定相机响应函数的时候,作者是将相机固定,逐渐变换相机曝光时间,对一个静止的场景进行采集。也就是说,在这个过程中,相机的辐照度图像是不变的。由于相机的渐晕是相机固有的属性,在标定相机响应函数的时候,把相机的光度模型转换成:
这里。在求响应函数的时候,为了方便起见,作者求的是响应函数的反函数:,给定一个图像,其对应的曝光时间为,假设在上有一个零均值的高斯噪声,则模型有如下形式:
通过最大似然估计,我们近似给出如下最小二乘的形式:
第一个求和是对所有(不同曝光时间的)图像,第二个求和是对图像平面上所有的像素点。对上式最小化,通过轮流最小化求解和得到:
先看的求解,由于论文中使用的是非参数方式,对应于一个大小为256的表格(一维数组),对于固定的值,也是常量。因此在求时,相当于对式子中的一个变量求偏导,并令式子为:
for(int i=0;i<n;i++)//! 遍历 i (图像){for(int k=0;k<w*h;k++)//! 遍历 x (像素点){int b = dataVec[i][k];if(b == 255) continue;GNum[b]++;//! 所有像素值为b的像素点个数|omega_k|GSum[b]+= E[k] * exposureVec[i];//! 累计的ti*B'(x)}}for(int i=0;i<256;i++){G[i] = GSum[i] / GNum[i];if(!std::isfinite(G[i]) && i > 1) G[i] = G[i-1] + (G[i-1]-G[i-2]);}
对于同理,由于是只对某一位置像素点求,因此可以把每一个分开,求得其对应的最优。转换得到
则分别对每一个求偏导,也就是对中的求偏导,可得:
整理之后就可以得到式。对应的代码为:
for(int i=0;i<n;i++)//! 遍历 i (图像){for(int k=0;k<w*h;k++)//! 遍历 k(像素点){int b = dataVec[i][k];if(b == 255) continue;ENum[k] += exposureVec[i]*exposureVec[i];ESum[k] += (G[b]) * exposureVec[i];}}for(int i=0;i<w*h;i++){E[i] = ESum[i] / ENum[i];if(E[i] < 0) E[i] = 0;}
在求响应函数的时候,对像素值为的点都是认为过曝光的,因此都剔除了。则就没法正常计算得到,因此论文中通过使用相邻的函数值推断得到。并且为了除去尺度的多义性,令,并把其他值按照该尺度进行缩放。对应代码:
// rescale such that maximum response is 255 (fairly arbitrary choice).double rescaleFactor=255.0 / G[255];for(int i=0;i<w*h;i++){E[i] *= rescaleFactor;if(i<256) G[i] *= rescaleFactor;}
由于论文使用的是打表(非参数化)的形式,因此在计算的时候,我们需要保证每一个都应该可以计算,也就是说采集的图像上的像素值要尽可能覆盖的所有范围。实际操作的时候,作者是从曝光时间从ms逐渐提升到ms,采集1000张图像,覆盖120种不同曝光时间,以保证响应函数计算的准确。
同样,对渐晕标定也使用非参数化的形式,使用一个渐晕映射表。标定过程是对这一块白墙进行图像的采集,假设白墙是理想的朗伯反射面(Lambertian Suface),也就是指在固定照明下,从任意视角上观察都有相同亮度的平面。
论文中,作者通过AR Marker获取相机相对平面的位姿。定义从3D空间到图像平面的映射。同样假设在上有高斯白噪声,通过最大似然,得到如下的误差方程:
通过交替最小化和,给出:
去除曝光时间的影响,可以转化为:
这里。
和相机响应函数标定一样,这里是稠密的打表的形式,因此,需要尽可能多的数据,才可以较好地恢复出渐晕的映射表。