Replace NaN values in a matrix with values of x positions after it

조회 수: 4 (최근 30일)
Tooba Shelkh
Tooba Shelkh 2020년 5월 10일
답변: Image Analyst 2020년 5월 10일
Suppose I have a matrix (actually grayscale images with think streaks of NaNs):
[ 3 4 4 2 4 6 8 6 3 2
4 5 NaN NaN 2 3 4 2 1 2
2 NaN NaN NaN 3 2 4 3 1 2
3 NaN NaN NaN 3 4 2 5 3 2
4 NaN NaN NaN 2 4 1 3 2 5
4 5 NaN NaN 2 3 4 2 1 2
2 NaN NaN NaN 3 2 4 3 1 2
3 2 NaN NaN NaN 4 2 5 3 2
4 3 2 NaN NaN NaN 4 1 3 2
4 3 2 3 NaN NaN 2 1 3 2
]
I want to replace all NaNs with 'x' values after it, for example for x=3 the second and third row woud be like:
4 5 3 4 2 3 4 2 1 2,
2 3 2 4 3 2 4 3 1 2,
I actually want to fill the NaNs with the background color smoothly so that the NaN lines are not visible clearly.
I have tried using the Matlab functions like fillmissing and fillgaps, and a function inpaint_nans() from matlab file_exchange, but they all leave a clear line that is prominent over the background.
Attached is the real image, where nans have been replaced by zeros.
Any ideas would be appreciated.
Thanks.
  댓글 수: 2
Walter Roberson
Walter Roberson 2020년 5월 10일
What do you want to have happen if there are more than x NaNs in a row, or if one of the values x later is itself nan?
Guillaume
Guillaume 2020년 5월 10일
Note that the isub2 matrix attached cannot contain NaNs as it's of type uint8. Only matrices of type single or double can contain NaN.

댓글을 달려면 로그인하십시오.

답변 (3개)

Guillaume
Guillaume 2020년 5월 10일
편집: Guillaume 2020년 5월 10일
regionfill seems to be the function you're after. So:
newimage = regionfill(yourimage, isnan(yourimage));
  댓글 수: 2
Walter Roberson
Walter Roberson 2020년 5월 10일
No, the user wishes to fill any given NaN value with a copy of the column x further on, and regionfill() is not going to do that.
Guillaume
Guillaume 2020년 5월 10일
"I actually want to fill the NaNs with the background color smoothly so that the NaN lines are not visible clearly."
Sounds to me like the user wants to fill the background so that it's continuous with the surrounding region, which is exactly what regionfill is going to do. The actual filling algorithm doesn't matter much.
If regionfill doesn't do the deeds, then I would try inpaintCoherent. Both of these are designed to fill missing pixels with a background so that the filled region doesn't stand out.

댓글을 달려면 로그인하십시오.


Walter Roberson
Walter Roberson 2020년 5월 10일
편집: Walter Roberson 2020년 5월 10일
for c = size(isub2,2) - x: -1 : 1
mask = isnan(isub2(:,c));
isub2(mask,c) = isub2(mask,c+x);
end
This code can handle streams of nans that are longer than x, and can handle the possibility that the position x further on might also be nan: it starts at the right hand side and moves leftward, so those nans would already have been filled in.
The one thing it cannot handle is the possibility of nan in the last x columns, as there is nothing x further columns on to copy. I can think of an easy and not unreasonable modification that would handle nan in the last x columns except in the last column; the last column just doesn't have anything further on to copy from.

Image Analyst
Image Analyst 2020년 5월 10일
You could try to anti-alias it by doing a weighted sum of the original plus a blurred version of the nan image:
m = [ 3 4 4 2 4 6 8 6 3 2
4 5 NaN NaN 2 3 4 2 1 2
2 NaN NaN NaN 3 2 4 3 1 2
3 NaN NaN NaN 3 4 2 5 3 2
4 NaN NaN NaN 2 4 1 3 2 5
4 5 NaN NaN 2 3 4 2 1 2
2 NaN NaN NaN 3 2 4 3 1 2
3 2 NaN NaN NaN 4 2 5 3 2
4 3 2 NaN NaN NaN 4 1 3 2
4 3 2 3 NaN NaN 2 1 3 2
]
subplot(2, 2, 1);
imshow(m, [], 'InitialMagnification', 800);
title('Original Matrix');
impixelinfo
% Define x image.
x = 2;
xImage = x * ones(size(m));
nanLocations = 2 * isnan(m)
subplot(2, 2, 2);
imshow(nanLocations, []);
title('Nan Locations');
impixelinfo
% Blur nanLocations to get percentages.
windowWidth = 3;
kernel = ones(windowWidth) / windowWidth^2;
blurred = conv2(nanLocations, kernel, 'same')
% Normalize
blurred = blurred / max(blurred(:));
subplot(2, 2, 3);
imshow(blurred, [], 'InitialMagnification', 800);
title('Blurred');
impixelinfo
% Make nans zero so we can make weighted sum
m(isnan(m)) = 0;
% Do weighted sum
output = m .* (1 - blurred) + xImage .* blurred;
subplot(2, 2, 4);
imshow(output, [], 'InitialMagnification', 800);
title('Output');
impixelinfo

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by