Image Processing Issue: Fill NaNs in image, which mostly consists of NaNs

僤鯓⒐⒋嵵緔 提交于 2019-12-06 13:41:57

问题


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 cubicfor method. Non of them did the job. nearestdid not do anything, while the rest removed more and more "good" pixels and substituted them by NaNs. 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:


回答1:


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);



回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!