I have a dataset / image DD
like the one in this image:

(by the way: is there a way of uploading small data sets here, so that you can actually work with the same data I use, without having to put them in the code?)
Colored pixels in the image represent height/depth ranging from 0 to about 400 meters. Blue pixels are NaN
.
Now what I need to do is to interpolate the pixel values WITHIN the displayed object, but without interpolating the whole image.
I tried using the function inpaint_nans
from the file-exchange, which has helped me quite often and again, it did a decent job:

imagesc(inpaint_nans(DD,4))
However, the runtime is fairly long for large images of ~3000x3000 pixels (and I have a few of them!) and it is not exactly, what I am looking for. Is there a function within the image processing toolbox maybe, that restricts the interpolation to the existing boundaries of my object without taking into account the surrounding NaNs?
I also used interp2
like so:
[xi,yi] = meshgrid(1:size(DD,2),1:size(DD,1));
zi = interp2(xi,yi,DD,xi,yi,'method');
imagesc(zi)
where I tried linear
, nearest
and cubic
for method
. Non of them did the job. nearest
did not do anything, while the rest removed more and more "good" pixels and substituted them by NaN
s. Any help or suggestions would be appreciated!
EDIT: PROCESSING:
I ran a simulation in a different program, that was based on triangular meshs. For each node of the mesh (X,Y), the water depth is written to an ascii file. In the center of the stream, the 2 triangles fit in one pixel (90x90meters), e.g., I get water depth values for the corners of a pixel, not the pixel itself. At surrounding, the simulation works with a larger spacing (as is evident from the regular NaN values within the floodplain). Here, 2 triangles make up a rectangle of 180x180 meters (4 pixels). Because I only get values for the nodes of the triangles again, the calculated water depth value is assigned to every second, not every pixel. Now I thought, the easiest method would be to interpolate between the pixels. Another valid (maybe better) solution, would be to assign the node value (depth) to the surrounding 2 / 4 pixels:

You might try the TriScatteredInterp
function. It works well in my simple test:
% create an image with holes
x = im2double(imread('rice.png'));
x(1:4:end, 1:4:end) = nan;
x(rand(size(x))<.1) = nan;
figure; imshow(x);
% setup the grid to interp from
[m n c] = size(x);
[N M] = meshgrid(1:m, 1:n);
Ni = N;
Mi = M;
Mi(~isnan(x)) = [];
Ni(~isnan(x)) = [];
N(isnan(x)) = [];
M(isnan(x)) = [];
Z = x(~isnan(x));
% do the interp
F = TriScatteredInterp(M', N', Z);
Zi = F(Mi, Ni);
xi = x;
xi(sub2ind(size(x),Mi, Ni)) = Zi;
figure; imshow(xi);
I had similar situation and simple imdilate worked for me. TriScatteredInterp
is quite slow. The post is quite old but maybe following code helpful to somebody:
imgDepth = load('depthImage.mat') % Or imread('depthImage.png')
imgDepth(isnan(imgDepth)) = 0
radius = 10 % Change as per your data
se = strel('disk',radius) % Try different structuring elements as per your need
imgDilated = imdilate(imgDepth,se);
figure,imshow(imgDilated,[]),colormap(jet)
来源:https://stackoverflow.com/questions/16980931/image-processing-issue-fill-nans-in-image-which-mostly-consists-of-nans