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