图像修补中使用有限元方法求解偏微分方程的方法 [英] Using Finite Element Method for Partial Differential Equation Methods in Image Inpainting

查看:44
本文介绍了图像修补中使用有限元方法求解偏微分方程的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个人如何遍历损坏的灰度图像,而不检查未损坏的像素,从而修复其中的所有损坏像素?

任何帮助将不胜感激.

P.S.我有一种算法,可以通过对其周围像素进行插值来修复损坏的像素,但是由于整个过程会花费太长时间,因此无法在整个图像上使用此算法.

这是算法(用伪代码):

  Ek [m,n] = Ik [m − 1,n] + Ik [m +1,n] + Ik [m,n − 1] + Ik [m,n + 1] − 4I[m,n]Ik + 1 [m,n] = Ik [m,n] +αEk [m,n] 

其中误差为Ek,α为系数,Ik为第k次迭代的图像.

解决方案

据我所知,您正在寻找一种迭代2D数组每个像素并在发现损坏"像素.不知道您对损坏"的定义该怎么办,我假设损坏"是指 isnan -不是数字.那么,您的算法就没有意义了(因为您是将NaN平均为校正后的像素值,从而得到一个NaN).因此,我将假定算法只是用最接近的非对角邻域的平均值完全替换像素:

  Ak + 1 [m,n] = 1/4 *(Ak [m − 1,n] + Ak [m +1,n] + Ak [m,n − 1] + Ak [m,n + 1]) 

如果我实际上误解了您,那么您还是希望能够按照我的答案进行工作.

首先:

 %制作一个示例损坏"的数组A = rand(100,100);A(A> 0.9)= NaN.%〜10%损坏 

现在,问题变得更加复杂,因为如果两个相邻的像素以及在阵列的边缘有两个损坏的像素,则该算法将失败.以后我们会担心的.

简单(但不起作用)的方法

您可以使用

查找所有损坏的像素

  nA = isnan(A);%布尔数组,A的大小,其中每个损坏的像素值等于1 

,如果需要,还可以使用

  I = find(nA);%使用线性索引查找上述索引[m,n] = find(nA);%使用下标索引找到索引 

如果您是Matlab的新手,那么这里的有趣读物可能是:"

50%腐败的重建形式

70%的腐败造成重建

蜂巢式方法(我的常用方法)

知道要用Google做什么,因此到达片代码.根据需要进行调整.

How does one traverse through a corrupted grayscale image fixing all the corrupted pixels in it without checking the pixels that are not corrupted?

Any help would be greatly appreciated.

P.S. I have an algorithm that fixes corrupted pixels by interpolating with its surrounding pixels but I cannot use this algorithm on the entire image as it will take too long.

Here is the algorithm (in pseudocode):

Ek[m, n] = Ik[m − 1, n] + Ik[m + 1, n]+ Ik[m, n − 1] + Ik [m, n + 1] − 4I[m, n]
Ik+1[m, n] = Ik[m, n] + α Ek[m, n]

where error is Ek, α is a coeficient and Ik is the image at the kth iteration.

解决方案

As far as I understand your question, you're searching for a way of iterating though each pixel of a 2D array and performing some action whenever you find a "corrupted" pixel. Not knowing what if your definition of "corrupted", I'll assume that by "corrupted" you mean isnan - Not A Number. Your algorithm makes no sense then (because you're averaging NaN into your corrected pixel value which will give you a NaN). I will therefore assume that the algorithm is simply replacing the pixel completely with the average of it's nearest non-diagonal neighbors:

Ak+1[m, n] = 1/4 * ( Ak[m − 1, n] + Ak[m + 1, n]+ Ak[m, n − 1] + Ak [m, n + 1] )

and If I've in fact misunderstood you, you'll hopefully be able to work form my answer anyway.

First of all:

% Make a sample 'corrupted' array
A = rand(100,100);
A(A>0.9) = NaN; % ~10% corrupted

Now, the problem is complicated by the fact that this algorithm fails if there are two corrupted pixels next to one another, as well as at the edges of the array. We will worry about that later.

Simple (but not working) aproach

You can find all the corrupted pixels with

nA = isnan(A); % Boolean array the size of A where each corrupted pixel value is equal to 1

and, if you want to, get their indices with

I = find(nA); % Finds the indices of the above using linear indexing
[m,n] = find(nA); % Finds the indices using subscript indexing

If you're new to Matlab, an interesting reading here might be: "logical arrays", "find" and "linear indexing". We will also need the size of A so lets put that into workspace

sA = size(A);

You then iterate though all the indices and apply the algorithm.

for j = 1:length(I)
    i = I(j); %j'th index
    [m,n] = ind2sub(sA,i); % Change linear indices to subscripts
    A(m,n) = 1/4 * ( A(m−1,n) + A(m+1,n)+ A(m,n−1) + A(m,n+1) );
end

More complicated (and actually working) method

As mentioned, the algorithm has problems when there are edges around, and when there are two or more NaN's around (which you can think of as a tiny little edge). In order to deal with the edge problem we will wrap the border around and make your image into a torus (although a 1 pixel padding would work too). We will then iterate though A replacing the pixels according to the nearest neighbor method. I had to allow for 3 and 2 neighbor replacement to make it work on heavily corrupted images. The code can easily be modified to stop that. Anyway, here is the working example:

A = peaks(100);
A(rand(size(A))>0.3) = NaN; % 70% corrupted image
sA = size(A);

nrep = [1 1 1]; % Initialise as nonzero
imagesc(A); drawnow; % Show what is happening
while any(isnan(A(:)))
    getA = @(m,n) A(mod(m-1,sA(1)-1)+1,mod(n-1,sA(2)-1)+1); % Wrap the image around the edges
    numA = @(m,n) sum(isnan([getA(m+1,n),getA(m-1,n),getA(m,n+1),getA(m,n-1)])); % Number of neighbouring NaNs
    for j = 1:numel(A);
        if isnan(A(j));
            [m,n] = ind2sub(sA,j);
            switch numA(m,n)
                case 0
                    cA = 1/4 * ( getA(m-1,n) + getA(m+1,n) + getA(m,n-1) + getA(m,n+1) );
                    nrep(1) = nrep(1) + 1;
                case 1
                    cA1 = 1/3 * ( getA(m+1,n) + getA(m,n-1) + getA(m,n+1) );
                    cA2 = 1/3 * ( getA(m-1,n) + getA(m,n-1) + getA(m,n+1) );
                    cA3 = 1/3 * ( getA(m-1,n) + getA(m+1,n) + getA(m,n+1) );
                    cA4 = 1/3 * ( getA(m-1,n) + getA(m+1,n) + getA(m,n-1) );
                    cAs = [cA1 cA2 cA3 cA4];
                    ok = ~isnan(cAs); ok = find(ok,1); % find first cA# which is not a NaN
                    cA = cAs(ok);
                    nrep(2) = nrep(2) + 1;
                case 2
                        cA1 = 1/2 * ( getA(m+1,n) + getA(m,n+1) );
                        cA2 = 1/2 * ( getA(m+1,n) + getA(m,n-1) );
                        cA3 = 1/2 * ( getA(m-1,n) + getA(m,n+1) );
                        cA4 = 1/2 * ( getA(m-1,n) + getA(m,n-1) );
                        cA5 = 1/2 * ( getA(m+1,n) + getA(m-1,n) );
                        cA6 = 1/2 * ( getA(m,n+1) + getA(m,n-1) );
                        cAs = [cA1 cA2 cA3 cA4 cA5 cA6];
                        ok = ~isnan(cAs); ok = find(ok,1); % find first cA# which is not a NaN
                        cA = cAs(ok);
                        nrep(3) = nrep(3) + 1;
                case 3
                    continue
                case 4
                    continue
            end
        A(j) = cA; % Replace element
        end
    end
    imagesc(A); drawnow; pause(0.01); % Show what is happening
end

Comment out the lines with the imagesc to suppress plotting the figures (cool as it may look ;) ). The code is somewhat ramshackled and could be improved a lot, but it works pretty well as is:

Original

Reconstruction form 50% corruption

Reconstruction form 70% corruption

Hive-mind method (my go-to method)

Know what to google for and hence arrive at this piece of code. Adapt as needed.

这篇关于图像修补中使用有限元方法求解偏微分方程的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆