深度滤波器推导
测量不确定性
图像IrI_rIr与IkI_kIk对应的相机中心分别为Cr,CkC_r,C_kCr,Ck。二者的转换关系为Tk,rT_{k,r}Tk,r,并且平移距离为ttt, 估计场景中的3d点为rPrPrP.假设匹配误差为一个像素,得到的误差距离为τk2=(∥rP∥−∥rP+∥)2\tau_k^2=(\|rP\|-\|rP^{+}\|)^2τk2=(∥rP∥−∥rP+∥)2。
因此有:
a=rP−t
a = rP - t
a=rP−t
角度
α=arccos(f⋅t∥t∥)
\alpha = \arccos (\frac{f \cdot t}{\|t\|})
α=arccos(∥t∥f⋅t)
β=arccos(−a⋅t∥a∥⋅∥t∥) \beta = \arccos (-\frac{a \cdot t}{\|a\| \cdot \|t\|}) β=arccos(−∥a∥⋅∥t∥a⋅t)
β+=β+2tan−1(12f) \beta^{+}=\beta + 2 \tan^{-1}(\frac{1}{2f}) β+=β+2tan−1(2f1)
γ=π−α−β+ \gamma=\pi - \alpha - \beta^{+} γ=π−α−β+
因此得到,
∥rP+∥=∥t∥sinβ+sinγ
\|rP^{+}\|=\|t\| \frac{\sin \beta^{+}}{ \sin \gamma}
∥rP+∥=∥t∥sinγsinβ+
最终得到测量不确定度为
τk2=(∥rP∥−∥rP+∥)2 \tau_k^2=(\|rP\|-\|rP^{+}\|)^2 τk2=(∥rP∥−∥rP+∥)2
代码分析
基本就是一条条公式对应过来
double DepthFilter::computeTau(
const SE3& T_ref_cur,
const Vector3d& f,
const double z,
const double px_error_angle)
{
Vector3d t(T_ref_cur.translation());
Vector3d a = f*z-t;
double t_norm = t.norm();
double a_norm = a.norm();
double alpha = acos(f.dot(t)/t_norm); // dot product
double beta = acos(a.dot(-t)/(t_norm*a_norm)); // dot product
double beta_plus = beta + px_error_angle;
double gamma_plus = PI-alpha-beta_plus; // triangle angles sum to PI
double z_plus = t_norm*sin(beta_plus)/sin(gamma_plus); // law of sines
return (z_plus - z); // tau
}
深度滤波器
采用高斯分布与均匀分布叠加的概率密度函数表达深度信息的分布。
- 好处:提高算法对于错误匹配的鲁棒性
- 坏处:公式推导过程复杂,实现计算量稍大
包含四个参数分别为高斯分布的μ,σ2\mu,\sigma^2μ,σ2与均匀分布的a,ba,ba,b。
p(x∣Z,π)=πN(x∣μ,σ2)+(1−π)U(x∣a,b) p(x|Z,\pi)=\pi N(x|\mu,\sigma^2) + (1-\pi)U(x|a,b) p(x∣Z,π)=πN(x∣μ,σ2)+(1−π)U(x∣a,b)
迭代更新过程
已知:
上一次的概率分布 ak,bk,μk,σka_k, b_k, \mu_k, \sigma_kak,bk,μk,σk
当前的测量值 x,τx, \taux,τ
求解更新后的概率分布 ak+1,bk+1,μk+1,σk+1a_{k+1}, b_{k+1}, \mu_{k+1}, \sigma_{k+1}ak+1,bk+1,μk+1,σk+1
计算过程
1s2=1σk2+1τ2 \frac{1}{s^2}=\frac{1}{\sigma_k^2} + \frac{1}{\tau^2} s21=σk21+τ21
m=s2(μkσ2k+xτ2) m = s^2 (\frac{\mu_k}{\sigma_2^k} + \frac{x}{\tau^2}) m=s2(σ2kμk+τ2x)
C1=akak+bk⋅N(x∣μt,τ2+σt2) C_1 = \frac{a_k}{a_k+b_k} \cdot N(x|\mu_t, \tau^2+\sigma_t^2) C1=ak+bkak⋅N(x∣μt,τ2+σt2)
C2=bkak+bk⋅U(x)
C_2 = \frac{b_k}{a_k+b_k} \cdot U(x)
C2=ak+bkbk⋅U(x)
这里的N(x∣μt,τ2+σt2)N(x|\mu_t, \tau^2+\sigma_t^2)N(x∣μt,τ2+σt2)代表高斯分布N(μt,τ2+σt2)N(\mu_t, \tau^2+\sigma_t^2)N(μt,τ2+σt2)在xxx位置的概率分布,同理U(x)U(x)U(x)为均匀分布在x位置处的概率。
C1′=C1C1+C2,C2′=C2C1+C2 C_1^{'}=\frac{C_1}{C_1+C_2}, C_2^{'}=\frac{C_2}{C_1+C_2} C1′=C1+C2C1,C2′=C1+C2C2
更新概率分布
μk+1=C1′m+C2′μk
\mu_{k+1}=C_1^{'}m + C_2^{'} \mu_k
μk+1=C1′m+C2′μk
σk+12=C1′(s2+m2)+C2′(τ2+σt2) \sigma_{k+1}^2 = C^{'}_1 (s^2 + m^2) + C_2^{'}(\tau^2+\sigma_t^2) σk+12=C1′(s2+m2)+C2′(τ2+σt2)
更新均匀分布
f=C1′ak+1ak+bk+1+C2′akak+bk+1
f = C_1^{'}\frac{a_k+1}{a_k+b_k+1} + C_2^{'}\frac{a_k}{a_k+b_k+1}
f=C1′ak+bk+1ak+1+C2′ak+bk+1ak
e=C1′(ak+1)(ak+2)(ak+bk+1)(ak+bk+2)+C2′ak(ak+1)(ak+bk+1)(ak+bk+2) e = C_1^{'}\frac{(a_k+1)(a_k+2)}{(a_k+b_k+1)(a_k+b_k+2)} + C_2^{'}\frac{a_k(a_k+1)}{(a_k+b_k+1)(a_k+b_k+2)} e=C1′(ak+bk+1)(ak+bk+2)(ak+1)(ak+2)+C2′(ak+bk+1)(ak+bk+2)ak(ak+1)
ak+1=e−ff−ef a_{k+1} = \frac{e-f}{f - \frac{e}{f}} ak+1=f−fee−f
bk+1=1−ffak+1 b_{k+1} = \frac{1-f}{f} a_{k+1} bk+1=f1−fak+1
代码分析
基本能和上面的公式对应起来
void DepthFilter::updateSeed(const float x, const float tau2, Seed* seed)
{
float norm_scale = sqrt(seed->sigma2 + tau2);
if(std::isnan(norm_scale))
return;
boost::math::normal_distribution<float> nd(seed->mu, norm_scale);
float s2 = 1./(1./seed->sigma2 + 1./tau2);
float m = s2*(seed->mu/seed->sigma2 + x/tau2);
float C1 = seed->a/(seed->a+seed->b) * boost::math::pdf(nd, x);
float C2 = seed->b/(seed->a+seed->b) * 1./seed->z_range;
float normalization_constant = C1 + C2;
C1 /= normalization_constant;
C2 /= normalization_constant;
float f = C1*(seed->a+1.)/(seed->a+seed->b+1.) + C2*seed->a/(seed->a+seed->b+1.);
float e = C1*(seed->a+1.)*(seed->a+2.)/((seed->a+seed->b+1.)*(seed->a+seed->b+2.))
+ C2*seed->a*(seed->a+1.0f)/((seed->a+seed->b+1.0f)*(seed->a+seed->b+2.0f));
// update parameters
float mu_new = C1*m+C2*seed->mu;
seed->sigma2 = C1*(s2 + m*m) + C2*(seed->sigma2 + seed->mu*seed->mu) - mu_new*mu_new;
seed->mu = mu_new;
seed->a = (e-f)/(f-e/f);
seed->b = seed->a*(1.0f-f)/f;
}
理论推导
深度滤波器的公式实现较为简单,但是具体的理论推导较为繁琐,因此放在最后没有特别高的需求的可以直接用上面的结论和代码,而不需要过分深究推导过程。
推导过程分为两步
- 证明分布后验分布的近似表达形式,即
p(x∣Z,π)=πN(x∣μ,σ2)+(1−π)U(x∣a,b)≈N(Z∣μ,σ2)Beta(π∣a,b) p(x|Z,\pi)=\pi N(x|\mu,\sigma^2) + (1-\pi)U(x|a,b) \approx N(Z|\mu, \sigma^2) Beta(\pi|a,b) p(x∣Z,π)=πN(x∣μ,σ2)+(1−π)U(x∣a,b)≈N(Z∣μ,σ2)Beta(π∣a,b) - 推导迭代公式
(πN(x∣Z,τ2)+(1−π)U(x))N(Z∣μ,σ2)Beta(π∣a,b)→N(Z∣μ′,σ′2)Beta(π∣a′,b′) (\pi N(x|Z, \tau^2) + (1-\pi)U(x)) N(Z|\mu, \sigma^2) Beta(\pi|a,b) \to N(Z|\mu^{'}, \sigma^{'2}) Beta(\pi|a^{'},b^{'}) (πN(x∣Z,τ2)+(1−π)U(x))N(Z∣μ,σ2)Beta(π∣a,b)→N(Z∣μ′,σ′2)Beta(π∣a′,b′)
后验分布的参数近似
参数更新公式
已知:
- 当前分布 N(Z∣μ,σ2)Beta(π∣a,b)N(Z|\mu, \sigma^2) Beta(\pi|a,b)N(Z∣μ,σ2)Beta(π∣a,b)
- 新测量值 x,τ2x, \tau^2x,τ2
Beta(π∣a,b)=Γ(a+b)Γ(a)Γ(b)πa−1(1−π)b−1
Beta(\pi|a,b) = \frac{\Gamma(a+b)}{\Gamma(a) \Gamma(b)} \pi^{a-1} (1-\pi)^{b-1}
Beta(π∣a,b)=Γ(a)Γ(b)Γ(a+b)πa−1(1−π)b−1
E(Beta(X))=aa+bE(Beta(X2))=a(a+1)(a+b+1)(a+b)
E(Beta(X)) = \frac{a}{a+b} \qquad E(Beta(X^2)) = \frac{a(a+1)}{(a+b+1)(a+b)}
E(Beta(X))=a+baE(Beta(X2))=(a+b+1)(a+b)a(a+1)
其中Γ(n)\Gamma(n)Γ(n)为gamma函数[1],存在如下性质
Γ(n+1)=nΓ(n)
\Gamma(n+1) = n \Gamma(n)
Γ(n+1)=nΓ(n)
因此得到性质如下
Beta(π∣a,b+1)=Γ(a+b+1)Γ(a)Γ(b+1)πa−1(1−π)b=a+baΓ(a+b)Γ(a)Γ(b)πa−1(1−π)b−1π=a+baπBeta(π∣a,b)
Beta(\pi|a,b+1) = \frac{\Gamma(a+b+1)}{\Gamma(a) \Gamma(b+1)} \pi^{a-1} (1-\pi)^{b} \\ = \frac{a+b}{a} \frac{\Gamma(a+b)}{\Gamma(a) \Gamma(b)} \pi^{a-1} (1-\pi)^{b-1} \pi \\ = \frac{a+b}{a} \pi Beta(\pi|a,b)
Beta(π∣a,b+1)=Γ(a)Γ(b+1)Γ(a+b+1)πa−1(1−π)b=aa+bΓ(a)Γ(b)Γ(a+b)πa−1(1−π)b−1π=aa+bπBeta(π∣a,b)
Beta(π∣a+1,b)=Γ(a+b+1)Γ(a+1)Γ(b)πa(1−π)b−1=a+bbΓ(a+b)Γ(a)Γ(b)πa−1(1−π)b−1(1−π)=a+bb(1−π)Beta(π∣a,b) Beta(\pi|a+1,b) = \frac{\Gamma(a+b+1)}{\Gamma(a+1) \Gamma(b)} \pi^{a} (1-\pi)^{b-1} \\ = \frac{a+b}{b} \frac{\Gamma(a+b)}{\Gamma(a) \Gamma(b)} \pi^{a-1} (1-\pi)^{b-1} (1-\pi) \\ = \frac{a+b}{b} (1-\pi) Beta(\pi|a,b) Beta(π∣a+1,b)=Γ(a+1)Γ(b)Γ(a+b+1)πa(1−π)b−1=ba+bΓ(a)Γ(b)Γ(a+b)πa−1(1−π)b−1(1−π)=ba+b(1−π)Beta(π∣a,b)
此外,推导过程中用到高斯分布乘积的性质如下[2]:
设有高斯分布N(x∣Z,τ2)N(x|Z,\tau^2)N(x∣Z,τ2)及N(Z∣μ,σ2)N(Z|\mu, \sigma^2)N(Z∣μ,σ2),则
N(x∣Z,τ2)N(Z∣μ,σ2)=N(x∣μ,τ2+σ2)N(Z∣m,s2)
N(x|Z,\tau^2) N(Z|\mu, \sigma^2) = N(x|\mu, \tau^2+\sigma^2) N(Z|m,s^2)
N(x∣Z,τ2)N(Z∣μ,σ2)=N(x∣μ,τ2+σ2)N(Z∣m,s2)
其中,
1s2=1σ2+1τ2m=s2(μσ2+xτ2)
\frac{1}{s^2} = \frac{1}{\sigma^2} + \frac{1}{\tau^2} \\
m = s^2 (\frac{\mu}{\sigma^2} + \frac{x}{\tau^2})
s21=σ21+τ21m=s2(σ2μ+τ2x)
得到后验分布为:
(πN(x∣Z,τ2)+(1−π)U(x))N(Z∣μ,σ2)Beta(π∣a,b)πN(x∣Z,τ2)N(Z∣μ,σ2)Beta(π∣a,b)+(1−π)U(x)N(Z∣μ,σ2)Beta(π∣a,b)aa+bN(x∣μ,σ2+τ2)N(Z∣m,s2)Beta(π∣a+1,b)+ba+bU(x)N(Z∣μ,σ2)Beta(π∣a,b+1) (\pi N(x|Z, \tau^2) + (1-\pi)U(x)) N(Z|\mu, \sigma^2) Beta(\pi|a,b) \\ \pi N(x|Z, \tau^2) N(Z|\mu, \sigma^2) Beta(\pi|a,b) + (1-\pi)U(x) N(Z|\mu, \sigma^2) Beta(\pi|a,b) \\ \frac{a}{a+b} N(x|\mu, \sigma^2 + \tau^2) N(Z|m,s^2) Beta(\pi|a+1,b) + \frac{b}{a+b} U(x) N(Z|\mu, \sigma^2) Beta(\pi|a,b+1) (πN(x∣Z,τ2)+(1−π)U(x))N(Z∣μ,σ2)Beta(π∣a,b)πN(x∣Z,τ2)N(Z∣μ,σ2)Beta(π∣a,b)+(1−π)U(x)N(Z∣μ,σ2)Beta(π∣a,b)a+baN(x∣μ,σ2+τ2)N(Z∣m,s2)Beta(π∣a+1,b)+a+bbU(x)N(Z∣μ,σ2)Beta(π∣a,b+1)
将常量替换成单一变量
C1=aa+bN(x∣μ,σ2+τ2)C2=ba+bU(x)
C_1 = \frac{a}{a+b} N(x|\mu, \sigma^2 + \tau^2) \\
C_2 = \frac{b}{a+b} U(x)
C1=a+baN(x∣μ,σ2+τ2)C2=a+bbU(x)
得到如下分布
C1N(Z∣m,s2)Beta(π∣a+1,b)+C2N(Z∣μ,σ2)Beta(π∣a,b+1)
C_1 N(Z|m,s^2) Beta(\pi|a+1,b) + C_2 N(Z|\mu, \sigma^2) Beta(\pi|a,b+1)
C1N(Z∣m,s2)Beta(π∣a+1,b)+C2N(Z∣μ,σ2)Beta(π∣a,b+1)
计算对变量ZZZ求一阶矩和二阶矩
μ′=E(Z)=C1m+C2μ \mu^{'} = E(Z) = C_1 m + C_2 \mu μ′=E(Z)=C1m+C2μ
σ′2+μ′2=C1(m2+s2)+C2(μ2+σ2)
\sigma^{'2} + \mu^{'2} = C_1 (m^2 + s^2) + C_2 (\mu^2 + \sigma^2)
σ′2+μ′2=C1(m2+s2)+C2(μ2+σ2)
计算对变量π\piπ求一阶矩和二阶矩
a′a′+b′=C1a+1a+b+1+C2aa+b+1
\frac{a^{'}}{a^{'} + b^{'}} = C_1 \frac{a+1}{a+b+1} + C_2 \frac{a}{a+b+1}
a′+b′a′=C1a+b+1a+1+C2a+b+1a
a′(a′+1)(a′+b′+1)(a′+b′)=C1(a+1)(a+2)(a+b+2)(a+b+1)+C2a(a+1)(a+b+2)(a+b+1)
\frac{a^{'}(a^{'}+1)}{(a^{'}+b^{'}+1)(a^{'}+b^{'})} = C_1 \frac{(a+1)(a+2)}{(a+b+2)(a+b+1)} + C_2 \frac{a(a+1)}{(a+b+2)(a+b+1)}
(a′+b′+1)(a′+b′)a′(a′+1)=C1(a+b+2)(a+b+1)(a+1)(a+2)+C2(a+b+2)(a+b+1)a(a+1)
最后化简即得到更新公式。
参考资料
[1] Gamma 函数 https://zh.m.wikipedia.org/wiki/%CE%93%E5%87%BD%E6%95%B0
[2] 高斯分布的乘积推导 https://www.zhihu.com/question/46458824