Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 邻近像素的高效修复_Matlab_Image Processing_Vectorization - Fatal编程技术网

Matlab 邻近像素的高效修复

Matlab 邻近像素的高效修复,matlab,image-processing,vectorization,Matlab,Image Processing,Vectorization,我正在实现一个简单的算法,用于在“受损”图像上绘制。我有一个预定义的掩码,指定需要固定的区域。我的策略是从遮罩区域的边界开始,用相邻非零像素的中心平均值绘制每个像素,重复直到没有未知像素 function R = inPainting(I, mask) H = [1 2 1; 2 0 2; 1 2 1]; R = I; n = 1; [row,col,~] = find(~mask); %Find zeros in mask (area to be inpainted) unknown = h

我正在实现一个简单的算法,用于在“受损”图像上绘制。我有一个预定义的掩码,指定需要固定的区域。我的策略是从遮罩区域的边界开始,用相邻非零像素的中心平均值绘制每个像素,重复直到没有未知像素

function R = inPainting(I, mask)
H = [1 2 1; 2 0 2; 1 2 1];
R = I;

n = 1;
[row,col,~] = find(~mask); %Find zeros in mask (area to be inpainted)
unknown = horzcat(row, col)';
while size(unknown,2) > 0
    new_unknown = [];
    new_R = R;
    for u = unknown
        r = u(1);
        c = u(2);
        nb = R(max((r-n), 1):min((r+n), end), max((c-n),1):min((c+n),end));
        nz = nb~=0;
        nzs = sum(nz(:));

        if nzs ~= 0 %We have non-zero neighbouring pixels. In-paint with average.
            new_R(r,c) = sum(nb(:)) / nzs;
        else
            new_unknown = horzcat(new_unknown, u);
        end
    end
    unknown = new_unknown;
    R = new_R;
end

这很有效,但效率不高。是否可以使用矩阵运算将这种方法矢量化?有人知道一种更有效的方法来实现这个算法吗?

如果我理解你的问题陈述,你会得到一个掩码,你希望用掩码中每个像素周围的邻域像素的平均值来填充这个掩码中的这些像素。另一个约束是图像的定义使得在相同空间位置属于遮罩的任何像素在此遮罩中为零。从遮罩的边界开始,向遮罩的内部传播信息。鉴于此算法,不幸的是,您无法使用标准过滤技术实现此目的,因为当前时间步长依赖于上一个时间步长

图像过滤机制,如或不能在这里工作,因为这种依赖关系

因此,我能做的就是帮助你加速你的循环中正在发生的事情,希望这能给你总体上的加速。我将向您介绍一个名为的函数。这是来自图像处理工具箱的,如果您可以使用
imfilter
,我们可以使用此函数

im2col
创建一个2D矩阵,使得每列都是一个像素邻域展开成一个向量。它的工作原理是按列主顺序抓取每个像素邻域,因此我们在图像的左上角得到一个像素邻域,然后向下移动一行,再移动另一行,一直移动到最后一行。然后我们移动一列并重复相同的过程。对于我们拥有的每个像素邻域,它被展开成一个向量,输出将是一个
mnxk
矩阵,其中每个像素邻域的邻域大小为
mxn
,并且有
K
邻域

因此,在循环的每次迭代中,我们可以将当前修复图像的像素邻域展开为单个向量,确定哪些像素邻域是非零的,然后确定每个选定像素邻域有多少零值。之后,我们计算这些非零列的平均值,忽略零元素。完成后,我们更新图像并移动到下一个迭代

我们首先需要做的是用一个1像素的边框填充图像,这样我们就能够捕捉到超出图像边框的邻域。也可以使用图像处理工具箱中的

因此,我们可以简单地做到:

function R = inPainting(I, mask)
R = double(I); %// For precision

n = 1;
%// Change - column major indices
unknown = find(~mask); %Find zeros in mask (area to be inpainted)  

%// Until we have searched all unknown pixels
while numel(unknown) ~= 0    
    new_R = R;

    %// Change - take image at current iteration and 
    %// create columns of pixel neighbourhoods
    padR = padarray(new_R, [n n], 'replicate');
    cols = im2col(padR, [2*n+1 2*n+1], 'sliding');  

    %// Change - Access the right pixel neighbourhoods
    %// denoted by unknown       
    nb = cols(:,unknown);

    %// Get total sum of each neighbourhood
    nbSum = sum(nb, 1);

    %// Get total number of non-zero elements per pixel neighbourhood
    nzs = sum(nb ~= 0, 1);

    %// Replace the right pixels in the image with the mean
    new_R(unknown(nzs ~= 0)) = nbSum(nzs ~= 0) ./ nzs(nzs ~= 0);

    %// Find new unknown pixels to look at
    unknown = unknown(nzs == 0);

    %// Update image for next iteration
    R = new_R;
end

%// Cast back to the right type
R = cast(R, class(I));

谢谢,那确实快多了!但是,我只想取非零邻居的平均值。你认为这也可以用imfilter实现吗?@user89161-Ah。好的,我们可以做一些稍微不同的事情。我们不能使用
imfilter
,但我可以做一些稍微不同的事情,这会更快。我将编辑我的帖子。@user89161-问题<代码>R最初未定义,但您可以立即使用它。这不会导致语法错误吗?我说的是
new\u R=R
循环开始时的code>语句。它在任何地方都没有定义,您可以立即开始使用它。非常感谢!您的解决方案速度大约快10倍:)@user89161您应该向上投票并接受。这是一个很好的答案