【图像处理-图像修复】Criminisi图像修复算法(附matlab代码)

本文详细介绍了Criminisi图像修复模型的工作原理,包括确定优先权的计算、置信度和数据项的表达式,以及通过SSD搜索最优匹配块的过程。提供了Matlab程序代码示例,展示了如何使用该算法进行图像修复。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个愿意伫立在巨人肩膀上的农民......

1、理论

        Criminisi 图像修复模型 可以同时处理像纹理和卡通信息的一种修复方法,其主要思路是先确定破损区域的边界,寻找边界上的像素点,并以边界点为中心像素点设定一个 7 × 7 9 × 9 (默认)或 11 × 11 的区块,利用图片的自相似性在未破损的区域以全局搜索的方式找到与该区块匹配度最高的样本块,使用该样本块对破损区域进行填充,通过迭代直至填充完所有破损区域。 如图 𝐻 表示整个破损图片, Φ 表示未破损区域的已知信息, 表示破损区 域, 𝛿 是破损区域的边界, 𝑝 为边界上的像素点, Ψ 𝑝 是以点 𝑝 为中心的 9 × 9 的区块,n_{p}表示 𝑝 点在破损边界上的法线矢量,\triangledown I'{_{p}^{\perp }} 则是 𝑝 点的等照度线。
         a.优先权的计算
        Criminisi 图像修复模型设计了两项来确定图片修复优先级(即修复顺序),分别是数据项 𝐷 ( 𝑝 ) 和置信度项 𝐶 ( 𝑝 ) 𝐷 ( 𝑝 ) 𝐶 ( 𝑝 ) 的数学表达式如下:
        1. 数据项 𝐷 ( 𝑝 ) 代表图片等照线度的信息,公式如下:
        2. 置信度项 𝐶 ( 𝑝 ) 用来度量像素点 𝑝 的可靠信息量,公式如下:
其中, 𝑝 是破损边缘 𝛿 上的一点,\triangledown I'{_{p}^{\perp }} 𝑝 点处明暗变化的延续方向,n_{p}是垂直于𝑝 点所在的边缘线的向量, 𝛼 是标准化因子,一般取值为 255 Ψ 𝑝 是以 𝑝 为中心的像素块,通常取 9 × 9 个像素为一个区域块,程序初始化时将 𝐶 ( 𝑝 ) 置为零。
        使用这两项去确定点 𝑝 的优先级,定义公式如下:
        b.最优匹配块的搜索
        通过计算得到图像修复的优先级之后,利用图片的自相似性从未破损区域搜索最优的匹配快进行填充,最优匹配块的寻找是通过计算待修复的目标块与样本块之间的最小误差均方准则( SSD )来实现的。在原图中未破损区域用 9 × 9 的块进行搜索,通过 SSD模型寻找一个与目标块的最相似的样本块n_{p}进行填充。表达式如下:
式中n_{p}^{'}是源图像中的匹配块。寻找最佳匹配块的 SSD 模型如下:
式中p^{R}, p^{G}, p^{B} 分别为图 Φ 区域RGB图像的各个通道。q^{R}, q^{G}, q^{B} 为图 中区域 RGB 图像的各个通道。
        c.更新置信度

        Criminisi图像修复模型最重要的两步就是计算优先权值和搜索最优匹配块,利用最优匹配块进行第一次填充后,图像破损区域的边界随之发生改变,因此图片置信度项也要随着迭代更新,更新的具体方法如下:

2、matlab程序(完整代码,可直接运行)

main.m
clc;
clear;
close all;

imagepath =imread( 'hua.bmp');   % 原图像,用于计算PSNR
maskpath =imread('huamask.bmp');   % 破损图像
fillColor=[255,255,0];   % 破损图像中标定的破损区域RGB颜色值
qukuai_size = 5;   % 选择填充区块大小3*3,5*5,7*7,9*9,...
disp('开始图像修复')
disp('......')
tic   % 计时开始点
[Psnr,inpaintedImg] =RGB_Criminisi(imagepath, maskpath, fillColor, qukuai_size);
disp('图像修复结束')
toc   % 计时结束点
Psnr
inpaintedImg=uint8(inpaintedImg);
subplot(1,2,1)
imshow(maskpath);
title('待修复图像');
subplot(1,2,2)
imshow(inpaintedImg);
title('Criminisi算法修复结果');

RGB_Criminisi.m

function [Psnr,inpaintedImg] =RGB_Criminisi(imagepath, maskpath, fillColor, qukuai_size)
img0=imagepath;
fillImg=maskpath;
img = double(fillImg);
fillRegion=img(:,:,1)==fillColor(1)&img(:,:,2)==fillColor(2)&img(:,:,3)==fillColor(3);

origImg = img;
ind = img2ind(img);
%-----------------------------------------------------
sz = [size(img,1) size(img,2)];
z1=size(img,1);
z2=size(img,2);
sourceRegion = ~fillRegion;

% 求等照度线值
[Ix(:,:,3),Iy(:,:,3)] = gradient(img(:,:,3));
[Ix(:,:,2),Iy(:,:,2)] = gradient(img(:,:,2));
[Ix(:,:,1),Iy(:,:,1)] = gradient(img(:,:,1));
Ix = sum(Ix,3)/(3*255); Iy = sum(Iy,3)/(3*255);
temp = Ix; Ix = -Iy; Iy = temp;  % 旋转90度

%------------------------------------------------------------------------
%求得梯度值
[ix(:,:,3),iy(:,:,3)] = gradient(img(:,:,3));
[ix(:,:,2),iy(:,:,2)] = gradient(img(:,:,2));
[ix(:,:,1),iy(:,:,1)] = gradient(img(:,:,1));
ix = sum(ix,3)/(3*255); iy = sum(iy,3)/(3*255);
%------------------------------------------------------------------------

% 初始化置信度项C和数据项D值
C = double(sourceRegion);
D = repmat(-.1,sz);

% 修复(直到所有的破损区域都被修复完成)
while any(fillRegion(:))
  % 寻找边缘
  dR = find(conv2(double(fillRegion),[1,1,1;1,-8,1;1,1,1],'same')>0);
  [Nx,Ny] = gradient(double(~fillRegion));
  N = [Nx(dR(:)) Ny(dR(:))]; 
  N(~isfinite(N))=0; 
  
  % 计算置信度项值
  for k=dR'
    Hp = qukuai_9(sz, k, qukuai_size);
    q = Hp(~(fillRegion(Hp)));
    C(k) = sum(C(q))/numel(Hp);  
  end
  
 % 计算优先权
   D(dR) = abs(Ix(dR).*N(:,1)+Iy(dR).*N(:,2)) /255;
   priorities =C(dR).*D(dR); 
  
  
 % 找到优先权最大的块 Hp
  [~,ndx] = max(priorities(:));
  p = dR(ndx(1));
  %---------------------
 
  [Hp,rows,cols] = qukuai_9(sz,p,qukuai_size);   %9x9块大小
  toFill=fillRegion(Hp);  
  Wpatch=img(rows,cols,:); %得到待修复块
  
  %------------------------------------------------------------------------
  %采用全局搜索,寻找最佳匹配块 
   Hq=whole_match(z1,z2,img,Wpatch,fillColor);
  %------------------------------------------------------------------------
  
  % 更新填充区域
  fillRegion(Hp(toFill)) = false;
  
  % 更新C(p)值和等照度线值
  C(Hp(toFill))  = C(p);
  Ix(Hp(toFill)) = Ix(Hq(toFill));
  Iy(Hp(toFill)) = Iy(Hq(toFill));
  
  %-----------------------------------------------------------------------
  %更新梯度值
  ix(Hp(toFill)) = ix(Hq(toFill));
  iy(Hp(toFill)) = iy(Hq(toFill));
  %----------------------------------------------------------------------
  
  
  % 从Hq复制图像信息到Hp
  ind(Hp(toFill)) = ind(Hq(toFill));
  img(rows,cols,:) = ind2img(ind(rows,cols),origImg);  
 
end

inpaintedImg=img;

A=double(img0);
B=double(inpaintedImg);

Psnr=PSNR(A,B);

qukuai_9.m

function [Hp,rows,cols] = qukuai_9(sz, p, qukuai_size)
x = floor(rem(p,sz(1)));
y = floor(p/sz(1))+1;%得到待修复区域中心点所在的位置
w = floor(qukuai_size/2);%块的半径(9*9大小的块,块的半径为4)
rows = max(1,x-w):min(x+w,sz(1));
cols = max(1,y-w):min(y+w,sz(2));
numhang = length(rows);
numlie = length(cols);
HJ = zeros(numhang,numlie);
LJ = zeros(numhang,numlie);
for ii = 1:numlie
    HJ(:,ii) = rows;%行铺成的矩阵
end
for jj = 1:numhang
    LJ(jj,:) = cols;%列铺成的矩阵
end
Hp = (LJ-1)*sz(1)+HJ;%得到待修复块(在图像中的具体位置)

whole_match.m


%**************************************************************************
%全局搜索,寻找最佳匹配块(彩色图像)
%全局搜索过程中不会出现找不到最佳匹配块的情况
%**************************************************************************


function Block=whole_match(zx,zy,img,Wpatch,fillColor)
%zx,zy为图像的大小

aa=size(Wpatch,1);
bb=size(Wpatch,2);%得到的待修复块的实际大小

sx=zx-aa+1;
sy=zy-bb+1;%确定搜索范围的最大值

all=aa*bb;%一维的大小
min=1.0000e+10;%赋初值

%计算找到的匹配块与待修复块在已知像素点处的距离(只是已知像素点)
for i=1:sx
    for j=1:sy
        Mpatch=img(i:i+aa-1,j:j+bb-1,:);%得到图像中和待修复块同样大小的块(Match patch)
        posunme=Mpatch(:,:,1)==fillColor(1)&Mpatch(:,:,2)==fillColor(2)&Mpatch(:,:,3)==fillColor(3);
        if any(posunme(:))%说明有破损点,不作为待修复块的最佳匹配块
            continue;
        end
        Err=0;
        for gg=1:aa*bb
            %遍历块中的每一个像素点
            pf=Wpatch(gg)==fillColor(1)&Wpatch(gg+all)==fillColor(2)&Wpatch(gg+2*all)==fillColor(3);
            if pf   %说明该位置像素有破损,不参与距离的计算
                continue;
            end
                cha=Wpatch(gg)-Mpatch(gg);Err=Err+cha*cha;
                 cha=Wpatch(gg+all)-Mpatch(gg+all);Err=Err+cha*cha;
                  cha=Wpatch(gg+2*all)-Mpatch(gg+2*all);Err=Err+cha*cha;
        end
        if Err<min
            min=Err;%取使得误差最小的块,并记住它们在图像中的起始位置
            hk=i;
            lk=j;
        end
    end
end
rows=hk:hk+aa-1;
cols=lk:lk+bb-1;%误差最小的块就是最佳匹配块 
Block=form_patch(rows,cols,zx);

form_patch.m

function kuai=form_patch(rows,cols,z)

%知道块在图像中所占的行和列的范围,得到块中每个像素点在图像中的位置(第多少个像素)
%便于引用

numhang=length(rows);
numlie=length(cols);
HJ=zeros(numhang,numlie);
LJ=zeros(numhang,numlie);
for ii=1:numlie
    HJ(:,ii)=rows;%行铺成的矩阵
end
for jj=1:numhang
    LJ(jj,:)=cols;%列铺成的矩阵
end
kuai=(LJ-1)*z+HJ;%得到待修复块(在图像中的具体位置

img2ind.m

%---------------------------------------------------------------------
% 把RGB图像转换为索引图像
%---------------------------------------------------------------------
function ind = img2ind(img)
s=size(img); ind=reshape(1:s(1)*s(2),s(1),s(2));

ind2img.m

%---------------------------------------------------------------------
% 把索引图像转换为RGB图像
%---------------------------------------------------------------------

function img2 = ind2img(ind,img)
for i=3:-1:1, temp=img(:,:,i); img2(:,:,i)=temp(ind); end;

PSNR.m

%----------------------------------------------------------------------
%PSNR值大小
%-------------------------------------------------------------------------
function PSNR=PSNR(u,v)
[m,n]=size(u(:,:,1));
a=0;
for i=1:m
    for j=1:n
         t(i,j,1)=u(i,j,1)-v(i,j,1);
         a=a+t(i,j,1)^2;
    end
end
mse=a/(m*n);
PSNR_R=10*log10(255^2/mse);

b=0;
for i=1:m
    for j=1:n
         t(i,j,2)=u(i,j,2)-v(i,j,2);
         b=b+t(i,j,2)^2;
    end
end
mse=b/(m*n);
PSNR_G=10*log10(255^2/mse);

c=0;
for i=1:m
    for j=1:n
         t(i,j,3)=u(i,j,3)-v(i,j,3);
         c=c+t(i,j,3)^2;
    end
end
mse=c/(m*n);
PSNR_B=10*log10(255^2/mse);

PSNR=(PSNR_R+PSNR_G+PSNR_B)/3;

3、运行结果

5、文献原文及代码文件点击下方连接,可直接跑通

https://download.csdn.net/download/weixin_41809117/88645671?spm=1001.2014.3001.5503icon-default.png?t=N7T8https://download.csdn.net/download/weixin_41809117/88645671?spm=1001.2014.3001.5503

6、参考文献

[1] Criminisi A .Object Removal by Exemplar-based Inpainting (PDF) Jun[J].WI Proc. IEEE Computer Vision and Pattern Recognition, 2003, 2003, 2.

创作不易,请尊重原创,引用请添加原文链接......

评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码韵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值