几个问题:
基本流程?
- Expansion of Known Regions: extrapolates “known foreground" and “known background" regions of the trimap into the “unknown" regions;
- Sample Selection and Matte Computation: tries to identify, for each pixel in the unknown regions, the best pair of foreground and background samples. It also com- putes an alpha matte from the obtained samples;
- Local Smoothing: locally smooths the resulting matte while maintaining its distinct features.
如何计算alpha值?
根据当前点颜色和估计的前景背景对颜色来计算(公式2)
double SharedMatting::comalpha(Scalar c, Scalar f, Scalar b) { double alpha = ((c.val[0] - b.val[0]) * (f.val[0] - b.val[0]) + (c.val[1] - b.val[1]) * (f.val[1] - b.val[1]) + (c.val[2] - b.val[2]) * (f.val[2] - b.val[2])) / ((f.val[0] - b.val[0]) * (f.val[0] - b.val[0]) + (f.val[1] - b.val[1]) * (f.val[1] - b.val[1]) + (f.val[2] - b.val[2]) * (f.val[2] - b.val[2]) + 0.0000001); return min(1.0, max(0.0, alpha)); }
shared体现在哪里?
- 寻找前景背景点对时,每个点只搜索kg次
- 相邻的点共享点对信息
- 极大地削减了搜索空间,降低了计算复杂度
优缺点?
- 基于传统方法的抠图算法,可望移动端实时。目前传统抠像算法中最好的。速度比closed form快。在alphpamatting网站的排名为28,36.4(实时版本)。
- 基于未知区域的前景和背景值总是可以根据邻域像素估计出来这一假设,对于不符合此类假设的情况(比如,前景透明,前景与背景颜色分布严重重叠)效果就会很差。
选择前景(背景)点的标准?
- 色彩空间上的距离在一定范围内
- 空间上的距离在一定范围内
如何选择最佳(前景,背景)点对?
- 色彩相似
- 空间距离接近
- 邻域内色彩失真最小(公式3)
- 属于前景点的概率(到达前景点所需点能量小于到达背景点所需的能量)(公式4、5、6)
- 以上诸多因子幂次相乘(公式7)
公式4中的积分如何实现?
将积分化成加法,在x、y两个方向分别计算
double SharedMatting::energyOfPath(int i1, int j1, int i2, int j2) { double ci = i2 - i1; double cj = j2 - j1; double z = sqrt(ci * ci + cj * cj); double ei = ci / (z + 0.0000001); double ej = cj / (z + 0.0000001); double stepinc = min(1 / (abs(ei) + 1e-10), 1 / (abs(ej) + 1e-10)); double result = 0; Scalar pre = LOAD_RGB_SCALAR(data, i1*step + j1*channels); int ti = i1; int tj = j1; for (double t = 1; ;t += stepinc) { double inci = ei * t; double incj = ej * t; int i = int(i1 + inci + 0.5); int j = int(j1 + incj + 0.5); double z = 1; Scalar cur = LOAD_RGB_SCALAR(data, i*step + j*channels); if (ti - i > 0 && tj - j == 0) { z = ej; } else if(ti - i == 0 && tj - j > 0) { z = ei; } result += ((cur.val[0] - pre.val[0]) * (cur.val[0] - pre.val[0]) + (cur.val[1] - pre.val[1]) * (cur.val[1] - pre.val[1]) + (cur.val[2] - pre.val[2]) * (cur.val[2] - pre.val[2])) * z; pre = cur; ti = i; tj = j; if(abs(ci) >= abs(inci) || abs(cj) >= abs(incj)) break; } return result; }
网友评论