参考论文:https://www.cs.huji.ac.il/~yweiss/Colorization/index.html#recolor
着色是威尔逊·马克尔 (Wilson Markle) 于 1970 年引入的一个术语,用于描述他发明的为黑白电影或电视节目 [Burns] 添加色彩的计算机辅助过程。 该术语现在一般用于描述为单色静止图像和素材添加颜色的任何技术。
然而,着色的一个主要困难在于它是一个昂贵且耗时的过程。 例如,为了给静止图像着色,艺术家通常首先将图像分割成多个区域,然后继续为每个区域分配颜色。 不幸的是,自动分割算法通常无法正确识别模糊或复杂的区域边界,例如对象的头发和面部之间的边界。 因此,艺术家经常面临手动描绘区域之间复杂边界的任务。 电影的着色需要跟踪镜头帧中的区域。 现有的跟踪算法通常无法稳健地跟踪非刚性区域,在此过程中再次需要大量用户干预。
这里的算法基于一个简单的前提,即时空附近具有相似灰度级的像素也应该具有相似的颜色。
论文及matlab代码下载:
https://download.csdn.net/download/bashendixie5/20709511
效果图如下:
?matlab核心代码:
colorize.m
g_name='example.bmp';
c_name='example_marked.bmp';
out_name='example_res.bmp';
%set solver=1 to use a multi-grid solver
%and solver=2 to use an exact matlab "\" solver
solver=2;
gI=double(imread(g_name))/255;
cI=double(imread(c_name))/255;
colorIm=(sum(abs(gI-cI),3)>0.01);
colorIm=double(colorIm);
sgI=rgb2ntsc(gI);
scI=rgb2ntsc(cI);
ntscIm(:,:,1)=sgI(:,:,1);
ntscIm(:,:,2)=scI(:,:,2);
ntscIm(:,:,3)=scI(:,:,3);
max_d=floor(log(min(size(ntscIm,1),size(ntscIm,2)))/log(2)-2);
iu=floor(size(ntscIm,1)/(2^(max_d-1)))*(2^(max_d-1));
ju=floor(size(ntscIm,2)/(2^(max_d-1)))*(2^(max_d-1));
id=1; jd=1;
colorIm=colorIm(id:iu,jd:ju,:);
ntscIm=ntscIm(id:iu,jd:ju,:);
if (solver==1)
nI=getVolColor(colorIm,ntscIm,[],[],[],[],5,1);
nI=ntsc2rgb(nI);
else
nI=getColorExact(colorIm,ntscIm);
end
figure, imshow(nI)
imwrite(nI,out_name)
getColorExact.m
function [nI,snI]=getColorExact(colorIm,ntscIm)
n=size(ntscIm,1); m=size(ntscIm,2);
imgSize=n*m;
nI(:,:,1)=ntscIm(:,:,1);
indsM=reshape([1:imgSize],n,m);
lblInds=find(colorIm);
wd=1;
len=0;
consts_len=0;
col_inds=zeros(imgSize*(2*wd+1)^2,1);
row_inds=zeros(imgSize*(2*wd+1)^2,1);
vals=zeros(imgSize*(2*wd+1)^2,1);
gvals=zeros(1,(2*wd+1)^2);
for j=1:m
for i=1:n
consts_len=consts_len+1;
if (~colorIm(i,j))
tlen=0;
for ii=max(1,i-wd):min(i+wd,n)
for jj=max(1,j-wd):min(j+wd,m)
if (ii~=i)|(jj~=j)
len=len+1; tlen=tlen+1;
row_inds(len)= consts_len;
col_inds(len)=indsM(ii,jj);
gvals(tlen)=ntscIm(ii,jj,1);
end
end
end
t_val=ntscIm(i,j,1);
gvals(tlen+1)=t_val;
c_var=mean((gvals(1:tlen+1)-mean(gvals(1:tlen+1))).^2);
csig=c_var*0.6;
mgv=min((gvals(1:tlen)-t_val).^2);
if (csig<(-mgv/log(0.01)))
csig=-mgv/log(0.01);
end
if (csig<0.000002)
csig=0.000002;
end
gvals(1:tlen)=exp(-(gvals(1:tlen)-t_val).^2/csig);
gvals(1:tlen)=gvals(1:tlen)/sum(gvals(1:tlen));
vals(len-tlen+1:len)=-gvals(1:tlen);
end
len=len+1;
row_inds(len)= consts_len;
col_inds(len)=indsM(i,j);
vals(len)=1;
end
end
vals=vals(1:len);
col_inds=col_inds(1:len);
row_inds=row_inds(1:len);
A=sparse(row_inds,col_inds,vals,consts_len,imgSize);
b=zeros(size(A,1),1);
for t=2:3
curIm=ntscIm(:,:,t);
b(lblInds)=curIm(lblInds);
new_vals=A\b;
nI(:,:,t)=reshape(new_vals,n,m,1);
end
snI=nI;
nI=ntsc2rgb(nI);
|