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

📄 texture_synth.m

📁 this is a very very very nice code
💻 M
字号:
%In is the input image, mask is the region to be synthesized, and prm is a
%parameter file. prm has three components, the similarity threshold,
%thresh, which defines how similar a sample must be to be considered a
%candidate for synthesization. W is a parameter that defines the size of
%the neighborhood to compare between a target region and a candidate.
%Larger values of W will allow to maintain large-scale textures, while
%small values of W will maintain small-scale textures. Sigma is the size of
%the gaussian kernel used when comparing neighborhoods, and skip is a value
%used to define how densely to sample the input image. To have a good guess
%for the value of skip computed automatically, simply define the value of
%skip to be 0.
%
%Note that mask is a binary image, where 0's represent the region to be
%synthesized. Within the algorithm though the reverse is true, 1's
%represent the regions to be synthesized, so the mask is inverted at the
%beginning of the algorithm. This is to make the algorithm follow the same
%convention used in the inpainting algorithm
function out = texture_synth(in, mask, prm)
if sum(class(prm) == 'struct') < 6
    prm = struct('thresh', 150, 'W', 17, 'sigma', 6, 'skip', 4);
end

%If you are unsure of what value of skip to use, plug in 0, and this will
%compute a reasonably good value for you
if prm.skip <= 0
    prm.skip = floor(sqrt(size(in,1)*size(in,2)/650))-2;
end

%Make sure we have just a single-channel image...
if size(in,3) > 1
    in = in(:,:,1);
end
in = double(in);

%I wrote this code originally using the inverted form of the mask, ie, ones
%specify where to inpaint, and 0's everywhere else. So I simply invert the
%mask to make to get this effect.
mask = ~mask;

%Create the full parameter file
param = struct('thresh', prm.thresh, 'W', prm.W, 'wh', 0, 'gauss', 0, 'sigma', prm.sigma, 'patches', 0, 'skip', prm.skip, 'fast', 1);
param.wh = (param.W-1)/2;

%Define the gaussian kernel
gauss = zeros(param.W, param.W);
sigs = param.sigma ^ 2;
wh = param.wh + 1;
for i = 1:param.W
    for j = 1:param.W
        gauss(i,j) = exp(-((i-wh)^2 + (j-wh)^2) / (2*sigs)) / sqrt(2*3.1415*sigs);
    end
end
gauss = gauss / sum(gauss(:));
param.gauss = gauss;

out = in;
M = size(out, 1);
N = size(out, 2);
wh = param.wh;
skip = param.skip;

%Sample the input image, these will be considered later for candidate regions
nm = 0;
for y = wh+1:skip:M-wh
    for x = wh+1:skip:N-wh
        if sum(sum(mask(y-wh:y+wh, x-wh:x+wh))) == 0
            nm = nm + 1;
            region = out(y-wh:y+wh, x-wh:x+wh);
            patches(nm, :) = region(:)';
        end
    end
end
param.patches = patches;
disp([num2str(size(patches,1)), ' sample patches collected'])

%For every pixel to by synthesized, starting from the border of the mask
%and eroding towards the center...
pix_set = get_pix_set(~mask);
for K = 1:size(pix_set,1)
    y = pix_set(K,1);
    x = pix_set(K,2);
    if ~(y < wh+1 | x < wh+1 | y > size(mask,1)-wh | x > size(mask,2)-wh) %Cant handle borders
        %Define the local mask of synthesized and unsynthesized pixels
        loc_mask = ~mask(y-wh:y+wh, x-wh:x+wh);
        %Gather the pixels into a target patch
        target = out(y-wh:y+wh, x-wh:x+wh);
        %Get a matching patch and fill the current pixel with the current pixel in that matching patch
        out(y, x) = get_match(target, loc_mask, param);
        mask(y, x) = 0;
    end
end

⌨️ 快捷键说明

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