备注:该代码框架从https://blog.csdn.net/u011630458/article/details/78323136的global-matting笔记总结而来,感谢羽凌寒对global-matting代码框架的梳理。
输入:1、src
2、mask(0为背景,128未知区域,255为前景)
输出:alpha-matte
# 根据前后景图像与周围未知区域的颜色、强度相关性,对图像掩码mask做一定程度的前后景扩散,然后腐蚀。
1、expansionOfKnownRegions
2、找mask的前景和unknown区域的边界位置,存入:fore_Boundary ;找mask背景和未知区域边界位置,存入:back_Boundary
# generate global-samples set
3、随机生成:fore_Boundary.size + back_Boundary.size个坐标点,如果该坐标位置mask像素值为255或者0,
则将该点坐标对应放入fore_Boundary或者back_Boundary。
4、根据fore_Boundary和back_Boundary中存放的坐标点的对应src图像信息强度从小到大对坐标点进行排序。
5、对于mask未知区域中的每个点:
计算每个未知区域点和fore_Boundary、back_Boundary的最小坐标距离平方差。
并随机生成(rand()%fore_Boundary.size(), rand()%back_Boundary.size())全部存入到samples中。
# samples中数据存储格式:[y, x, d, fi, bj, alpha, cost]
6、建立数组二维coords,存入src图像坐标从(0,0)到(h,w)存入。
7、循环10次:
将coords存的坐标数据随机打乱从排。
# propagation ...
for i in range(coords.size()):
取出mask[coords[i].x, coords[i].y]数据
if(mask != 128)
continue;
else
取出src该点像素与samples该点参数(s1)。
以(coords[i].x, coords[i].y)为中心的3x3矩形遍历(索引用[p][q]表示): # shared-info
if(mask[p][q]==128)
取出该点samples值(s2)
取出src(fore_Boundary[s2.fi]);src(back_Boundary[s2.bj]);
计算alpha,并根据该alpha求出cost值
if(s1.cost==[]||s1.cost>cost)
更新当前s1中的fi,bj,cost和alpha值
# random search...
for j in range(coords.size()):
if mask[coords[j].x, coords[i].y] ==128
I = src[coords[j].x, coords[i].y]
for p in range(k):
F_index = rand()%fore_Boundary.size()
B_index = rand()%back_Boundary.size()
F = src(fore_Boundary[F_index])
B = src(back_Boundary[B_index])
计算出alpha,并根据该alpha求出cost值
if(s1.cost==[]||s1.cost>cost)
更新当前s1中的fi, bj, cost和alpha值
8、for y in range(mask.rows):
for x in range(mask.cols):
if(mask[y][x]==128)
mask[y][x] = 255*samples[y][x].alpha