曾經想要實作過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,[])