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.


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

Load an indexed image

[X,map] = imread('');
X = X(:,1001:2000); % crop the image
n = numel(X); % number of pixels
I = ind2rgb(X,map); % RGB image
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
imshow(corruptedI), title('Corrupted image - 75%')

Inpaint the missing RGB pixels

inpaintedI = corruptedI;
for k = 1:3, inpaintedI(:,:,k) = inpaintn(corruptedI(:,:,k)); end
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 volumetric 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')
hsurfaces = slice(x,y,z,vel0,[xmin,100,xmax],ymax,zmin);
hcont = contourslice(x,y,z,vel0,[xmin,100,xmax],ymax,zmin);
view(3), daspect([2,2,1]), axis tight
title('Original data compared with...')
hsurfaces = slice(x,y,z,vel,[xmin,100,xmax],ymax,zmin);
hcont = contourslice(x,y,z,vel,[xmin,100,xmax],ymax,zmin);
view(3), daspect([2,2,1]), axis tight
title('... reconstructed data')


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.

See also


About the author

Damien Garcia, Eng., Ph.D.
INSERM researcher
Creatis, University of Lyon, France

website: BioméCardio