曾经想要实现过Bertalmio图像修复算法,无奈自身实力不够,耗费两天时间也没能实现。昨天博客上有人问到TV模型,这个模型我过去是没听说过的,于是就找来相关论文研究了一下,发现TV模型也可以用来修复图像,于是就有了想实现的想法。用到的偏微分方程技巧和各项异性扩散很像。
先看看效果吧:
原lena:
随手截的噪声图:
合成的需要修复的图:
修复后的图(没有处理边界):
对于从来没有接触过图像修复的我来说,效果真是惊艳了。
下面介绍运算步骤:
和各项异性扩散类似,整个算法也是基于迭代的,迭代公式如下:
其中Io代表当前处理的像素,Ip代表邻域像素,p就可以取news四邻域。H定义如下:
这里的lambda为自定义的平滑系数。wp的定义如下:
这里a同样是自定义。
结合上图在看up散度,将p取e来看ue定义如下:
这里的h就是1了。
如此上述所有公式倒着运算不断迭代就可以了,迭代次数可自定义,或是不断迭代直到某条件成立都是可以的。
matlab代码如下,并不长,变量名和公式名是一一对应的:
close all; clear all; clc; img=double(imread('lena.jpg')); mask=rgb2gray(imread('ma.jpg'))>160; [m n]=size(img); for i=1:m for j=1:n if mask(i,j)==0 img(i,j)=0; end end end imshow(img,[]); %合成的需要修复的图像 lambda=0.2; a=0.5; imgn=img; for l=1:300 %迭代次数 for i=2:m-1 for j=2:n-1 if mask(i,j)==0 %如果当前像素是被污染的像素,则进行处理 Un=sqrt((img(i,j)-img(i-1,j))^2+((img(i-1,j-1)-img(i-1,j+1))/2)^2); Ue=sqrt((img(i,j)-img(i,j+1))^2+((img(i-1,j+1)-img(i+1,j+1))/2)^2); Uw=sqrt((img(i,j)-img(i,j-1))^2+((img(i-1,j-1)-img(i+1,j-1))/2)^2); Us=sqrt((img(i,j)-img(i+1,j))^2+((img(i+1,j-1)-img(i+1,j+1))/2)^2); Wn=1/sqrt(Un^2+a^2); We=1/sqrt(Ue^2+a^2); Ww=1/sqrt(Uw^2+a^2); Ws=1/sqrt(Us^2+a^2); Hon=Wn/((Wn+We+Ww+Ws)+lambda); Hoe=We/((Wn+We+Ww+Ws)+lambda); How=Ww/((Wn+We+Ww+Ws)+lambda); Hos=Ws/((Wn+We+Ww+Ws)+lambda); Hoo=lambda/((Wn+We+Ww+Ws)+lambda); imgn(i,j)=Hon*img(i-1,j)+Hoe*img(i,j+1)+How*img(i,j-1)+Hos*img(i+1,j)+Hoo*img(i,j); end end end img=imgn; end figure; imshow(img,[])