⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 structure_inpaint.m

📁 this is a very very very nice code
💻 M
字号:
%Inpaints the inpute image according to the mask, which is a binary image
%where 0 represents the regions to be inpainted. Parameters can be defined
%by param, or pass param=0 to use default values. An example of param can
%be seen below. T is the number of iterations, num_fill is the number of
%inpainting iterations to perform each T, and num_anis is the number of
%anisotropic diffusions to perform. num_initial is the number of initial
%"bleeding" iterations performed before inpainting to get a rough initial
%result. Delta is the update rate, and you typically want this value to be small
function out = structure_inpaint(in, mask, param)
if sum(class(param) == 'struct') < 6
    param = struct('T', 1000, 'num_fill', 15, 'num_anis', 2, 'num_initial', 300, 'delta', .1);
end
in = double(in);
out = in;

%We want the laplacian mask to be slightly larger than the input mask, in
%order for anisotropic diffusion to work
SE = strel('arbitrary',ones(3,3));
LapMask = imerode(mask,SE);

%Collect all the pixels to be inpainted and/or diffused
diff_set = get_pix_set(LapMask);
pix_set = get_pix_set(mask);

%Perform some initial diffusion. This just fills in the region to be
%inpainted with some color from the surrounding region. It serves as a good
%"first guess" to the inpainting result
for K = 1:param.num_initial
    out = out + param.delta.*comp_laplacian(out,diff_set,1);
end

for i = 1:param.T
    if mod(i,50) == 0
        disp([i, param.T])   %Update the user with the progress
    end
    
    %This is because normally you want intensities to be in the range [0,1]
    %but I choose to work in the range [0,255]. Thus I need to divide the
    %final result by 255 to keep it in the correct range.
    inpaint_delta = param.delta / 255;

    %Fill the region num_fill times
    for j = 1:param.num_fill
        %Compute gradients and the laplacian
        [Iy, Ix] = comp_backgrad(out,pix_set,2);
        [Iyb, Ixb] = comp_backgrad(out,pix_set,1);
        L = comp_laplacian(out,diff_set,1);
        nrm = get_norm(Iy,Ix,pix_set);
        
        %For every pixel to be inpainted...
        for k = 1:size(pix_set,1)
            y = pix_set(k,1);
            x = pix_set(k,2);
            if nrm(y,x) > 0
                %All the equations from the image inpainting paper
                dL = [L(y-1,x) - L(y+1,x), L(y,x+1) - L(y,x-1)];
                N = [Ix(y,x), -Iy(y,x)];
                beta = dL * N' / nrm(y,x);

                if beta > 0
                    Ixbm = min(0, Ixb(y,x));
                    IxfM = max(0, Ixb(y,x+1));
                    Iybm = min(0, Iyb(y,x));
                    IyfM = max(0, Iyb(y-1,x));
                    magI = sqrt(Ixbm^2 + IxfM^2 + Iybm^2 + IyfM^2);
                else
                    IxbM = max(0, Ixb(y,x));
                    Ixfm = min(0, Ixb(y,x+1));
                    IybM = max(0, Iyb(y,x));
                    Iyfm = min(0, Iyb(y-1,x));
                    magI = sqrt(IxbM^2 + Ixfm^2 + IybM^2 + Iyfm^2);
                end
                
                out(y,x) = out(y,x) + inpaint_delta * beta * magI;
            end
        end
    end
    
    %Do some anisotropic diffusion, the method used can be found in the report
    for j = 1:param.num_anis
        [Iy, Ix] = comp_backgrad(out,diff_set,2);
        Iyy = comp_laplacian(out,diff_set,2);
        Ixx = comp_laplacian(out,diff_set,3);
        Ixy = comp_laplacian(out,diff_set,4);
        Ix2 = Ix.^2;
        Iy2 = Iy.^2;
        norm2 = Ix2 + Iy2;
        for K = 1:size(diff_set,1)
            y = diff_set(K,1);
            x = diff_set(K,2);
            if norm2(y,x) > 0
                diff = (Ixx(y,x)*Iy2(y,x) - 2*Ixy(y,x)*Ix(y,x)*Iy(y,x) + Iyy(y,x)*Ix2(y,x)) / norm2(y,x);
                out(y,x) = out(y,x) + param.delta * diff;
            end
        end
    end
    
end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -