Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
median filtering ignoring NaN

Subject: median filtering ignoring NaN

From: winnie

Date: 20 May, 2009 09:39:02

Message: 1 of 18

Hi all,

I have got a 2D matrix (an image), that I would like to median filter. Usually I'd use medfilt2, but my matrix also contains NaNs. There is no option to ignore NaN in medfilt2, so I am looking for a way of doing this. I have found ndnanfilter on Matlab central as well as moving_average, however both these functions only allow for mean filtering and not median filtering.

Do you have any idea of how I could achieve 2D median filtering ignoring NaNs?
Thanks, Winnie

Subject: median filtering ignoring NaN

From: Image Analyst

Date: 20 May, 2009 10:30:17

Message: 2 of 18

"winnie " <dax42@web.de> wrote in message <gv0j3m$3g9$1@fred.mathworks.com>...
> Hi all,
>
> I have got a 2D matrix (an image), that I would like to median filter. Usually I'd use medfilt2, but my matrix also contains NaNs. There is no option to ignore NaN in medfilt2, so I am looking for a way of doing this. I have found ndnanfilter on Matlab central as well as moving_average, however both these functions only allow for mean filtering and not median filtering.
>
> Do you have any idea of how I could achieve 2D median filtering ignoring NaNs?
> Thanks, Winnie
------------------------------------------------------------------------
How does it handle the nans now? If it doesn't ignore them, then does it consider them high, or low, or generate an error?

Subject: median filtering ignoring NaN

From: Bruno Luong

Date: 20 May, 2009 10:37:01

Message: 3 of 18

"Image Analyst" <imageanalyst@mailinator.com> wrote in message <gv0m3p$bsa$1@fred.mathworks.com>...
> "winnie " <dax42@web.de> wrote in message <gv0j3m$3g9$1@fred.mathworks.com>...

> How does it handle the nans now? If it doesn't ignore them, then does it consider them high, or low, or generate an error?

Probably high

sort([1 nan 2 nan 3])

Bruno

Subject: median filtering ignoring NaN

From: winnie

Date: 20 May, 2009 10:40:20

Message: 4 of 18

>How does it handle the nans now? If it doesn't ignore them, then does it consider them >high, or low, or generate an error?

Hi, at the moment it propagates the NaN, i.e. it sets everything NaN that has at least one NaN in its surround (3x3 per default). In other words, if there is a NaN in the area that is to be median filtered, the median will always be NaN. I hope this makes sense.

Thanks, winnie

Subject: median filtering ignoring NaN

From: winnie

Date: 20 May, 2009 12:04:01

Message: 5 of 18

"winnie " <dax42@web.de> wrote in message <gv0mmk$iaq$1@fred.mathworks.com>...
> >How does it handle the nans now? If it doesn't ignore them, then does it consider them >high, or low, or generate an error?
>
> Hi, at the moment it propagates the NaN, i.e. it sets everything NaN that has at least one NaN in its surround (3x3 per default). In other words, if there is a NaN in the area that is to be median filtered, the median will always be NaN. I hope this makes sense.
>
> Thanks, winnie

Just to clarify, instead of making everything NaN in the surround of a NaN, I would like it to ignore the NaN, so that it is producing the median only of those elements in the surround that are a number. Anyone got any idea how to achieve that?

Thanks, winnie

Subject: median filtering ignoring NaN

From: Bruno Luong

Date: 20 May, 2009 12:23:01

Message: 6 of 18

"winnie " <dax42@web.de> wrote in message <gv0rjh$ncj$1@fred.mathworks.com>...
> "winnie " <dax42@web.de> wrote in message <gv0mmk$iaq$1@fred.mathworks.com>...
> > >How does it handle the nans now? If it doesn't ignore them, then does it consider them >high, or low, or generate an error?
> >
> > Hi, at the moment it propagates the NaN, i.e. it sets everything NaN that has at least one NaN in its surround (3x3 per default). In other words, if there is a NaN in the area that is to be median filtered, the median will always be NaN. I hope this makes sense.
> >
> > Thanks, winnie
>
> Just to clarify, instead of making everything NaN in the surround of a NaN, I would like it to ignore the NaN, so that it is producing the median only of those elements in the surround that are a number. Anyone got any idea how to achieve that?
>
> Thanks, winnie

If the speed is not an issue, I guess you can use SLIDEFUN by supplying the median calculation that discards NaN

http://www.mathworks.com/matlabcentral/fileexchange/12550

Otherwise I can't see other solution than writing a MEX file.

Bruno

Subject: median filtering ignoring NaN

From: Bjorn Gustavsson

Date: 20 May, 2009 13:46:02

Message: 7 of 18

"winnie " <dax42@web.de> wrote in message <gv0rjh$ncj$1@fred.mathworks.com>...
> "winnie " <dax42@web.de> wrote in message <gv0mmk$iaq$1@fred.mathworks.com>...
> > >How does it handle the nans now? If it doesn't ignore them, then does it consider them >high, or low, or generate an error?
> >
> > Hi, at the moment it propagates the NaN, i.e. it sets everything NaN that has at least one NaN in its surround (3x3 per default). In other words, if there is a NaN in the area that is to be median filtered, the median will always be NaN. I hope this makes sense.
> >
> > Thanks, winnie
>
> Just to clarify, instead of making everything NaN in the surround of a NaN, I would like it to ignore the NaN, so that it is producing the median only of those elements in the surround that are a number. Anyone got any idea how to achieve that?
>
I think you could resort to manually treat the regions around your nans, that is to calculate the nan-free median for neighborhoods with nans in them separately and then use medfilt2 for the rest of the image, and finally insert the nanmedianed pixels where they belong. This will of course only work (well?) for cases with few and isolated nans. For those cases I can see this as a (somewhat ugly) wrapper for medfilt2.

HTH,
Bjoern

Subject: median filtering ignoring NaN

From: Bruno Luong

Date: 20 May, 2009 14:22:01

Message: 8 of 18

% This might help:

function M = mediannan(A, sz)

if nargin<2
    sz = 5;
end
if length(sz)==1
    sz = [sz sz];
end

if any(mod(sz,2)==0)
    error('kernel size SZ must be odd)')
end
margin=(sz-1)/2;
AA = nan(size(A)+2*margin);
AA(1+margin(1):end-margin(1),1+margin(2):end-margin(2))=A;
[iB jB]=ndgrid(1:sz(1),1:sz(2));
is=sub2ind(size(AA),iB,jB);
[iA jA]=ndgrid(1:size(A,1),1:size(A,2));
iA=sub2ind(size(AA),iA,jA);
idx=bsxfun(@plus,iA(:).',is(:)-1);

B = sort(AA(idx),1);
j=any(isnan(B),1);
last = zeros(1,size(B,2))+size(B,1);
[trash last(j)]=max(isnan(B(:,j)),[],1);
last(j)=last(j)-1;

M = nan(1,size(B,2));
valid = find(last>0);
mid = (1 + last)/2;
i1 = floor(mid(valid));
i2 = ceil(mid(valid));
i1 = sub2ind(size(B),i1,valid);
i2 = sub2ind(size(B),i2,valid);
M(valid) = 0.5*(B(i1) + B(i2));
M = reshape(M,size(A));

end % medianna

% Test on command line
A=peaks(40);
A(ceil(numel(A)*rand(1,20)))=NaN;

B=mediannan(A,5)

subplot(1,2,1);
imagesc(A);
subplot(1,2,2);
imagesc(B);

% Bruno

Subject: median filtering ignoring NaN

From: dbd

Date: 20 May, 2009 16:45:09

Message: 9 of 18

On May 20, 2:39 am, "winnie " <da...@web.de> wrote:
> Hi all,
>
> I have got a 2D matrix (an image), that I would like to median filter. Us=
ually I'd use medfilt2, but my matrix also contains NaNs. There is no optio=
n to ignore NaN in medfilt2, so I am looking for a way of doing this. I hav=
e found ndnanfilter on Matlab central as well as moving_average, however bo=
th these functions only allow for mean filtering and not median filtering.
>
> Do you have any idea of how I could achieve 2D median filtering ignoring =
NaNs?
> Thanks, Winnie

How about finding the NaNs and replacing them with the median (or even
the mean for speed) of their surrounds, then running medfilt2?

or

Quicker and dirtier, replace all NaNs with a fixed legal value from
the range of the image, running medfilt2 and counting on the
robustness of the median to minimize the impact.

Dale B. Dalrymple

Subject: median filtering ignoring NaN

From: winnie

Date: 21 May, 2009 15:11:01

Message: 10 of 18

Dear Bruno and everyone else who has replied,

I have tried your code and it works nicely, thank you very much!
However, I would like to keep the NaNs and not replace them with the median of their surround, so I have altered the valid assignment in your script to read:

    t = AA(idx);
    valid = find(~isnan(t(ceil(sz(1)*sz(2)/2),:)));

Also, unfortunately my version of Matlab (7.0.1) does not include bsxfun, so instead of that one line I now have:

    rows = length(is(:));
    columns = length(iA(:));
    iA = repmat(iA(:)',rows,1);
    is = repmat(is(:)-1,1,columns);
    idx = iA+is;

It works fine, but I was wondering whether there is a faster/more efficient way to replace bsxfun with.

Thanks again for the help!
Winnie

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <gv13m9$9n7$1@fred.mathworks.com>...
> % This might help:
>
> function M = mediannan(A, sz)
>
> if nargin<2
> sz = 5;
> end
> if length(sz)==1
> sz = [sz sz];
> end
>
> if any(mod(sz,2)==0)
> error('kernel size SZ must be odd)')
> end
> margin=(sz-1)/2;
> AA = nan(size(A)+2*margin);
> AA(1+margin(1):end-margin(1),1+margin(2):end-margin(2))=A;
> [iB jB]=ndgrid(1:sz(1),1:sz(2));
> is=sub2ind(size(AA),iB,jB);
> [iA jA]=ndgrid(1:size(A,1),1:size(A,2));
> iA=sub2ind(size(AA),iA,jA);
> idx=bsxfun(@plus,iA(:).',is(:)-1);
>
> B = sort(AA(idx),1);
> j=any(isnan(B),1);
> last = zeros(1,size(B,2))+size(B,1);
> [trash last(j)]=max(isnan(B(:,j)),[],1);
> last(j)=last(j)-1;
>
> M = nan(1,size(B,2));
> valid = find(last>0);
> mid = (1 + last)/2;
> i1 = floor(mid(valid));
> i2 = ceil(mid(valid));
> i1 = sub2ind(size(B),i1,valid);
> i2 = sub2ind(size(B),i2,valid);
> M(valid) = 0.5*(B(i1) + B(i2));
> M = reshape(M,size(A));
>
> end % medianna
>
> % Test on command line
> A=peaks(40);
> A(ceil(numel(A)*rand(1,20)))=NaN;
>
> B=mediannan(A,5)
>
> subplot(1,2,1);
> imagesc(A);
> subplot(1,2,2);
> imagesc(B);
>
> % Bruno

Subject: median filtering ignoring NaN

From: Bruno Luong

Date: 21 May, 2009 16:06:01

Message: 11 of 18

"winnie " <dax42@web.de> wrote in message <gv3qu5$cdj$1@fred.mathworks.com>...
> Dear Bruno and everyone else who has replied,
>
> I have tried your code and it works nicely, thank you very much!
> However, I would like to keep the NaNs and not replace them with the median of their surround, so I have altered the valid assignment in your script to read:
>
> t = AA(idx);
> valid = find(~isnan(t(ceil(sz(1)*sz(2)/2),:)));

I have a shorter solution to propose to you, see below
>
> Also, unfortunately my version of Matlab (7.0.1) does not include bsxfun, so instead of that one line I now have:
>
> rows = length(is(:));
> columns = length(iA(:));
> iA = repmat(iA(:)',rows,1);
> is = repmat(is(:)-1,1,columns);
> idx = iA+is;

This is fine. Here is the modified code:

function M = mediannan(A, sz)

if nargin<2
    sz = 5;
end
if length(sz)==1
    sz = [sz sz];
end

if any(mod(sz,2)==0)
    error('kernel size SZ must be odd)')
end
margin=(sz-1)/2;
AA = nan(size(A)+2*margin);
AA(1+margin(1):end-margin(1),1+margin(2):end-margin(2))=A;
[iB jB]=ndgrid(1:sz(1),1:sz(2));
is=sub2ind(size(AA),iB,jB);
[iA jA]=ndgrid(1:size(A,1),1:size(A,2));
iA=sub2ind(size(AA),iA,jA);
idx = repmat(iA(:).',numel(is),1) + repmat(is(:)-1,1,numel(iA));

B = sort(AA(idx),1);
j = any(isnan(B),1);
last = zeros(1,size(B,2))+size(B,1);
[trash last(j)]=max(isnan(B(:,j)),[],1);
last(j)=last(j)-1;

M = nan(1,size(B,2));
valid = find(~isnan(A(:).')); % <- Simple check on A
mid = (last(valid)+1)/2;
i1 = sub2ind(size(B),floor(mid),valid);
i2 = sub2ind(size(B),ceil(mid),valid);
M(valid) = 0.5*(B(i1) + B(i2));
M = reshape(M,size(A));

end % medianna
>

Subject: median filtering ignoring NaN

From: winnie

Date: 21 May, 2009 16:53:02

Message: 12 of 18

Dear Bruno,

Thanks a lot for the shorter version, makes sense. May I ask why you are using iA(:).' ? What is the difference to iA(:)'?

Winnie

Subject: median filtering ignoring NaN

From: Bruno Luong

Date: 21 May, 2009 16:59:03

Message: 13 of 18

"winnie " <dax42@web.de> wrote in message <gv40td$28p$1@fred.mathworks.com>...
> Dear Bruno,
>
> Thanks a lot for the shorter version, makes sense. May I ask why you are using iA(:).' ? What is the difference to iA(:)'?

It does not make any difference for real value data. Only there is a difference for complex data. It is just a habit I have as I work often with complex value matrix.

Bruno

Subject: median filtering ignoring NaN

From: DitzaN

Date: 12 Jul, 2010 14:53:26

Message: 14 of 18

Hi,

I have the same problem, but my matrix is huge (960*1280) and I need filter of 5*5.
The code crashed in this line (because of memory problems):
idx = repmat(iA(:).',numel(is),1) + repmat(is(:)-1,1,numel(iA));
Could it be possible to limit the code to work only with points which are problematic with medfilt2:
points which have neighboring NaNs but aren’t totally surrounded by them.

I would appreciate any suggestions!
Ditza

Subject: median filtering ignoring NaN

From: Bruno Luong

Date: 13 Jul, 2010 08:12:06

Message: 15 of 18

Ditza, you lingt give this version a try, the memory requirement is less:

function M = mediannan(A, sz)

if nargin<2
    sz = 5;
end
if length(sz)==1
    sz = [sz sz];
end

if any(mod(sz,2)==0)
    error('kernel size SZ must be odd)')
end
margin=(sz-1)/2;
AA = nan(size(A)+2*margin);
AA(1+margin(1):end-margin(1),1+margin(2):end-margin(2))=A;
[iB jB]=ndgrid(1:sz(1),1:sz(2));
is=sub2ind(size(AA),iB,jB);
[iA jA] = ndgrid(1:size(A,1),1:size(A,2));
iA = sub2ind(size(AA),iA,jA);

iA = uint32(iA(:).');
iS = uint32(is(:)-1);
idx = bsxfun(@plus,iA,iS);
% idx = repmat(iA(:).',numel(is),1) + repmat(is(:)-1,1,numel(iA));

B = sort(AA(idx),1);
clear idx
j = any(isnan(B),1);
last = zeros(1,size(B,2))+size(B,1);
[trash last(j)]=max(isnan(B(:,j)),[],1);
last(j)=last(j)-1;

M = nan(1,size(B,2));
valid = find(~isnan(A(:).')); % <- Simple check on A
mid = (last(valid)+1)/2;
i1 = sub2ind(size(B),floor(mid),valid);
i2 = sub2ind(size(B),ceil(mid),valid);
M(valid) = 0.5*(B(i1) + B(i2));
M = reshape(M,size(A));

end % medianna

% Bruno

Subject: median filtering ignoring NaN

From: DitzaN

Date: 9 Aug, 2010 14:57:03

Message: 16 of 18

Hello Bruno,
Sorry it took me time to respond
It does exactly what I wanted
Thank you,
Ditza

Subject: median filtering ignoring NaN

From: Alex

Date: 17 Jun, 2011 17:55:05

Message: 17 of 18

I don't know if anyone still interested in it, but there is a function in MATLAB nanmedian() that fill filter out NaN.

Subject: median filtering ignoring NaN

From: Matt Kennedy

Date: 26 Jun, 2014 21:37:09

Message: 18 of 18

Here is code which finds the median of just the finite values. Then, it backfills the nan values.

uMed(find(isfinite(u))) = medfilt1(u(isfinite(u)),100);
uMed(find(~isfinite(u))) = nan;


"Alex " <A.Jironkin@warwick.ac.uk> wrote in message <itg4do$28p$1@newscl01ah.mathworks.com>...
> I don't know if anyone still interested in it, but there is a function in MATLAB nanmedian() that fill filter out NaN.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us