# INPAINTN - Inpaint over missing data in large N-D arrays

Y = INPAINTN(X) replaces the missing data in X by extra/interpolating the non-missing elements. The non finite values (NaN or Inf) in X are considered as missing data. X can be any N-D array.

INPAINTN (no input/output argument) runs the following 3-D example.

## Contents

INPAINTN uses an iterative process based on DCT and IDCT. Y = INPAINTN(X,N) uses N iterations. By default, N = 100. If you estimate that INPAINTN did not totally converge, increase N. For example: Y = INPAINTN(X,1000)

Y = INPAINTN(X,N,Y0) uses Y0 as initial guess. This could be useful if you want to run the process a second time or if you have a GOOD guess of the final result. By default, INPAINTN makes a nearest neighbor interpolation (by using BWDIST) to obtain a rough guess.

## Example #1: Restore a corrupted image

```[X,map] = imread('https://www.biomecardio.com/images/iVFMhome.gif');
X = X(:,1001:2000); % crop the image
n = numel(X); % number of pixels
I = ind2rgb(X,map); % RGB image
figure
imshow(I), title('Original image')
``` Remove 75% of the pixels

```idx = randperm(n);
corruptedI = I;
for k = 0:2, corruptedI(idx(1:n*.75)+k*n) = NaN; end
figure
imshow(corruptedI), title('Corrupted image - 75%')
``` Inpaint the missing RGB pixels

```inpaintedI = corruptedI;
for k = 1:3, inpaintedI(:,:,k) = inpaintn(corruptedI(:,:,k)); end
figure
imshow(inpaintedI), title('Inpainted image')
``` ## Example #2: Recover lost 2-D data

```n = 256;
y0 = peaks(n); % original data
y = y0;
I = randperm(n^2);
y(I(1:n^2*0.5)) = NaN; % lose 1/2 of data
y(40:90,140:190) = NaN; % create a hole
z = inpaintn(y,200); % inpainted data
subplot(2,2,1:2), imagesc(y), axis equal off
title('Corrupted data')
subplot(223), imagesc(z), axis equal off
title('Recovered data ...')
subplot(224), imagesc(y0), axis equal off
title('... compared with original data')
``` ## Example #3: Recover lost 3-D data

```load wind % original 3-D flow
xmin = min(x(:)); xmax = max(x(:));
zmin = min(z(:)); ymax = max(y(:));
%-- wind velocity
vel0 = interp3(sqrt(u.^2+v.^2+w.^2),1,'cubic');
x = interp3(x,1); y = interp3(y,1); z = interp3(z,1);
```

Remove randomly 90% of the data

```I = randperm(numel(vel0));
velNaN = vel0;
velNaN(I(1:round(numel(I)*.9))) = NaN;
```

Restore the data using INPAINTN

```vel = inpaintn(velNaN);
```

Display the results

```subplot(221), imagesc(velNaN(:,:,15)), axis equal off
title('Corrupted plane, z = 15')
subplot(222), imagesc(vel(:,:,15)), axis equal off
title('Reconstructed plane, z = 15')
subplot(223)
hsurfaces = slice(x,y,z,vel0,[xmin,100,xmax],ymax,zmin);
set(hsurfaces,'FaceColor','interp','EdgeColor','none')
hcont = contourslice(x,y,z,vel0,[xmin,100,xmax],ymax,zmin);
set(hcont,'EdgeColor',[.7,.7,.7],'LineWidth',.5)
view(3), daspect([2,2,1]), axis tight
title('Original data compared with...')
subplot(224)
hsurfaces = slice(x,y,z,vel,[xmin,100,xmax],ymax,zmin);
set(hsurfaces,'FaceColor','interp','EdgeColor','none')
hcont = contourslice(x,y,z,vel,[xmin,100,xmax],ymax,zmin);
set(hcont,'EdgeColor',[.7,.7,.7],'LineWidth',.5)
view(3), daspect([2,2,1]), axis tight
title('... reconstructed data')
``` ## References

Please refer to the two following papers:

1. Garcia D. Robust smoothing of gridded data in one and higher dimensions with missing values. Computational Statistics & Data Analysis 2010;54:1167-1178.
2. Wang G, Garcia D et al. A three-dimensional gap filling method for large geophysical datasets: Application to global satellite soil moisture observations. Environ Modell Softw 2012;30:139-142.

```Damien Garcia, Eng., Ph.D.