Neglecting bad data points; NaN; imresize
8 views (last 30 days)
Show older comments
Hello Everybody,
I'm working with images where each pixel value represents a number of counts. (X-ray scattering data). Some pixels turn out to malfunction, either with zero counts, or with a saturation. To remove these, we normally create a mask (kind of the inverse of "region of interest", to neglect those bad points/pixels.
Usually, I would make this mask as consisting of "ones" and "NaNs", so that when I multiply my data image/matrix by the mask, I get NaNs for all the bad pixels.
Now, I can sum, or make means using "nansum" or "nanmean", because these operations know that the NaNs don't count for the statistics, which is great. This works for more than half of my work!
However, sometimes, I get data with poor statistics, and to overcome this difficulty, I'm using the "imresize" function, which conveniently "bins" the data automatically to smaller images. The problem, is that "imresize" counts NaN, making a whole box as an invalid square.
To exemplify, say pic1 is my original image, mask is my mask, where I want to hide one part of the data, and pic2 is the image with the bad pixels removed. pic3 is the resized image for improved statistics:
if true
% %
%
%
pic1=reshape(1:16,4,4)'
%
mask=ones(size(pic1)); mask(2:3,2)=NaN
%
%Now to apply the mask, I get the good data, with the bad pixels removed.
%
pic2= pic1.*mask
%
%Because pic2 has poor statistics, I want to resize the image to half (or other factors) its %length, to %improve the number of counts, at the cost of loss in spatial resolution:
%
bin=0.5 %0.5, bin factor, it compresses the original matrix to half its size
pic3=imresize(pic2,0.5,'box')
%
%
%
%
%
%
%
end
Unfortunately, I get pic3 =[NaN 5.5000; NaN 13.5000]
instead of pic3=[2.667 5.5000; 12 13.5000]
which would be the result if NaN was neglected.
So, even though I am not counting the bad pixels, which is good, they are propagating in the compression, invalidating some of the good ones.
Do you have any suggestions on how to get around this?
Either using a different strategy in the mask? (replace NaN by something else? zero won't work, as it will affect the statistics)
Maybe there is a symbol I could use to replace for NaN, that the system knows it should not be counted? (again, zero would not work)
Or by using something different than "imresize"?
I could create a loop to manually resize the matrix, and use the "nanmean"… but that would make everything too complicated.
Any suggestion is appreciated!
Thanks!
0 Comments
Accepted Answer
Kelly Kearney
on 11 Apr 2014
Edited: Kelly Kearney
on 11 Apr 2014
Here's a suggestion to replace the imresize call, using histc and accumarray:
fac = 0.5;
dx = 1./fac;
[r,c] = ndgrid(1:size(pic2,1), 1:size(pic2,2));
[n, ibin] = histc(r(:), 0.5:dx:size(pic2,1)+0.5);
[n, jbin] = histc(c(:), 0.5:dx:size(pic2,2)+0.5);
nr = max(ibin);
nc = max(jbin);
idx = sub2ind([nr nc], ibin, jbin);
pic3 = accumarray(idx, pic2(:), [nr*nc 1], @nanmean);
pic3 = reshape(pic3, nr, nc)
Cleaner code than looping, though I'm not sure how it compares performance-wise... The initial setup index stuff would only need to be run once, then the imresize could be replaced by a one-liner:
pic3 = reshape(accumarray(idx, test(:), [nr*nc 1], @nanmean), nr, nc);
More Answers (2)
Image Analyst
on 11 Apr 2014
Unless I misunderstood, I don't see any reason to mess around with nans or reshaping. You have basically salt and pepper noise (either dead pixels at 0 or saturated pixels). A common fix for rthis is the modified median filter. Basically take the median filter. This replaces bad pixels with good values. But only replace the bad pixels, not all of them. So threshold the image to find bad pixels and replace only those like
outputImage(badPixels) = medianFilteredImage(badPixels);
Attached are full demos for both gray scale images and color images.
See Also
Categories
Find more on NaNs in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!