如何在python中进行alpha matting
如何在python中进行alpha matting 更具体地说,如何提取图像的alpha通道,给定将像素标记为如何在python中进行alpha matting,python,image-processing,Python,Image Processing,如何在python中进行alpha matting 更具体地说,如何提取图像的alpha通道,给定将像素标记为 100%前景(白色) 100%背景(黑色) 或未知(灰色) 输入图像 输入trimap 使用alpha matting库 这里有两种选择,都是基于Levin和Lischinski的论文 背后的数学 根据图像I计算矩阵L,该矩阵描述了相邻像素的相似程度: 使用约束矩阵D和向量b求解线性系统的α值,以固定已知的α值: python实现 将numpy导入为np 进口nump
- 100%前景(白色)
- 100%背景(黑色)
- 或未知(灰色)
I
计算矩阵L
,该矩阵描述了相邻像素的相似程度:D
和向量b
求解线性系统的α值,以固定已知的α值:将numpy导入为np
进口numpy.linalg
导入scipy.sparse
导入scipy.sparse.linalg
从PIL导入图像
来自numba import njit
def main():
#在此处配置路径
image\u path=“cat\u image.png”
trimap\u path=“cat\u trimap.png”
alpha_path=“cat_alpha.png”
cutout\u path=“cat\u cutout.png”
#加载并转换到[0,1]范围
image=np.array(image.open(image\u path.convert(“RGB”))/255.0
trimap=np.array(Image.open(trimap\u path).convert(“L”)/255.0
#做垫子拉普拉斯
i、 j,v=闭合形式拉普拉斯(图)
h、 w=trimap.shape
L=scipy.sparse.csr_矩阵((v,(i,j)),shape=(w*h,w*h))
#建立线性系统
A、 b=制造系统(L,trimap)
#求解稀疏线性系统
打印(“求解线性系统…”)
alpha=scipy.sparse.linalg.spsolve(A,b)。重塑(h,w)
#堆栈rgb和alpha
剪切=np.连接([image,alpha[:,:,np.newaxis]],axis=2)
#剪辑并转换为PIL的uint8
cutout=np.clip(cutout*255,0255).astype(np.uint8)
alpha=np.clip(alpha*255,0255).aType(np.uint8)
#保存并显示
Image.fromarray(alpha).save(alpha\u路径)
Image.fromarray(剪切).save(剪切路径)
Image.fromarray(alpha.show())
Image.fromarray(cutout.show())
@njit
def闭合形式拉普拉斯(图,ε=1e-7,r=1):
h、 w=图像.形状[:2]
窗面积=(2*r+1)**2
n\u VAL=(w-2*r)*(h-2*r)*窗口面积**2
k=0
#坐标形式的拉普拉斯消光数据
i=np.empty(n_vals,dtype=np.int32)
j=np.empty(n_vals,dtype=np.int32)
v=np.empty(n_vals,dtype=np.float64)
#对于图像的每个像素
对于范围内的y(r,h-r):
对于范围内的x(r,w-r):
#在3x3窗口中收集当前像素的邻居
n=图像[y-r:y+r+1,x-r:x+r+1]
u=np.零(3)
对于范围(3)内的p:
u[p]=n[:,:,p].平均值()
c=n-u
#计算颜色通道上的协方差矩阵
cov=np.零((3,3))
对于范围(3)内的p:
对于范围(3)内的q:
cov[p,q]=np.均值(c[:,:,p]*c[:,:,q])
#计算窗口的逆协方差
inv_cov=np.linalg.inv(cov+ε/窗面积*np.eye(3))
#对于3x3窗口中的每对((xi,yi),(xj,yj))
对于范围(2*r+1)内的dyi:
对于范围(2*r+1)内的dxi:
对于范围(2*r+1)内的dyj:
对于范围(2*r+1)内的dxj:
i[k]=(x+dxi-r)+(y+dyi-r)*w
j[k]=(x+dxj-r)+(y+dyj-r)*w
温度=c[dyi,dxi].dot(inv_cov).dot(c[dyj,dxj])
v[k]=(如果(i[k]==j[k]),则为1.0,否则为0.0)-(1+温度)/窗口面积
k+=1
打印(“生成消光拉普拉斯算子”,y-r+1,“/”,h-2*r)
返回i,j,v
def制造系统(L、trimap、约束系数=100.0):
#将trimap拆分为前景、背景、已知和未知遮罩
is_fg=(trimap>0.9).flatten()
is_bg=(trimap<0.1).flatten()
is_known=is_fg | is_bg
是否未知=~是否已知
#约束已知alpha值的对角矩阵
d=已知。aType(np.float64)
D=scipy.sparse.diags(D)
#结合约束和图拉普拉斯算子
A=约束系数*D+L
#已知alpha值的约束值
b=约束系数*为类型(np.64)
返回A,b
如果名称=“\uuuuu main\uuuuuuuu”:
main()
输出阿尔法
输出断路器
你能回答自己的问题吗?这真的属于这里吗?@ErikXIII有一个非常类似的问题,但公认的答案并不是关于学术上所谓的alpha matting。此外,作者不再活跃。我看不出@ErikXIII这样做有什么问题。甚至“更糟”。一旦允许,他应该接受自己的答案。@John一个人怎么能生成trimap呢?