学些了closed-form抠图算法,后来又看了KNN matting算法,发现他们很相似,在算法的实现过程中只是改变了L矩阵,原来的是局部线性窗口建立的L矩阵,而现在使用的是KNN这种距离建立的像素,在论文中就是A矩阵,
代码分析:需要用到vlfeat这个库,直接到官网上下,下面程序使用了三分图,而非笔刷
clear all;
run('vlfeat-0.9.16/toolbox/vl_setup');
lambda=1000;
level=2;
factor=1;
im=rgb2hsv(double(imread('F:/matting/input_lowres/plasticbag.png'))/255);
scrib=reshape(double(imread('F:/matting/trimap_lowres/Trimap2/plasticbag.png'))/255,[],1);
[m n d]=size(im);
val=scrib>0.99;
map=(scrib<0.01)+val;
nn=[10;2];
[a b]=ind2sub([m n],1:m*n);
feature=[reshape(cos(im(:,:,1)*2*pi),m*n,1)'*factor;reshape(sin(im(:,:,1)*2*pi),m*n,1)'*factor;reshape(im(:,:,2:3),m*n,2)'/2;[a;b]/sqrt(m*m+n*n)*level+rand(2,m*n)*1e-6];
now=0;
for i=1:size(nn,1)
ind=vl_kdtreequery(vl_kdtreebuild(feature),feature,feature,'NUMNEIGHBORS',nn(i),'MAXNUMCOMPARISONS',nn(i)*2);
a=reshape(repmat(uint32(1:m*n),nn(i),1),[],1);
b=reshape(ind,[],1);
row(now+1:now+m*n*nn(i),:)=[min(a,b) max(a,b)];
feature(5:6,:)=feature(5:6,:)/100;%这里使用nn[10;2]矩阵中的10代表的是每个像素搜索10个最相邻的相邻像素,2代表的是在空间位置x和y都除100后搜索两个最相邻像素
now=now+m*n*nn(i);
end
row=unique(row,'rows');
value=max(1-sum(abs(feature(:,row(:,1))-feature(:,row(:,2))))/6,0);
A=sparse(double(row(:,1)),double(row(:,2)),value,m*n,m*n);
A=A+A';
D=spdiags(sum(A,2),0,n*m,n*m);
M=D-A+lambda*spdiags(map,0,m*n,m*n);
L=ichol(M);
x=pcg(M,lambda*val,[],2000,L,L');
figure,imshow(reshape(x,m,n));
imwrite(reshape(x,m,n),'res.png','png');