comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: efficient kernel or masking algorithm ?
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: efficient kernel or masking algorithm ? [message #22636] Thu, 30 November 2000 00:00
Struan Gray is currently offline  Struan Gray
Messages: 178
Registered: December 1995
Senior Member
J.D. Smith, jdsmith@astro.cornell.edu writes:

> If you really want the true variance, you're
> probably stuck with for loops,
> preferrably done in C and linked to IDL.

There was a thread back in August called 'Standard Deviation' where we
discussed this a bit. The best i could come up with was to use the SHIFT
function, which for a 3x3 kernal looks like this:

;********************************

function smg_imageSD, image

fimage = float(image)
localmean = smooth(fimage, 3)
sum = (fimage - localmean)^2
sum = temporary(sum) + $
shift((fimage - shift(localmean, 1, 1))^2,-1,-1)
sum = temporary(sum) + $
shift((fimage - shift(localmean, 0, 1))^2, 0,-1)
sum = temporary(sum) + $
shift((fimage - shift(localmean,-1, 1))^2, 1,-1)
sum = temporary(sum) + $
shift((fimage - shift(localmean, 1, 0))^2,-1, 0)
sum = temporary(sum) + $
shift((fimage - shift(localmean,-1, 0))^2, 1, 0)
sum = temporary(sum) + $
shift((fimage - shift(localmean, 1,-1))^2,-1, 1)
sum = temporary(sum) + $
shift((fimage - shift(localmean, 0,-1))^2, 0, 1)
sum = temporary(sum) + $
shift((fimage - shift(localmean,-1,-1))^2, 1, 1)

sum = sqrt(temporary(sum)/8)

dims = size(sum, /dim)
sum[0,*] = 0.0
sum[*,0] = 0.0
sum[dims(0)-1,*] = 0.0
sum[*,dims(1)-1] = 0.0

return, sum
end

;********************************

This handles the edges crudely, but a mixture of padding the original image
and using the right keywords when doing the initial smooth allows more complex
behaviours.

Obviously, it would be possible to generalise the shifting and final sqrt for
other kernal sizes, and to add all sorts of checking for different data types.

It's reasonably fast.


Struan
Re: efficient kernel or masking algorithm ? [message #22642 is a reply to message #22636] Wed, 29 November 2000 00:00 Go to previous message
John-David T. Smith is currently offline  John-David T. Smith
Messages: 384
Registered: January 2000
Senior Member
Richard Tyc wrote:
>
> WOW, I need to look at these equations over about a dozen times to see what
> is going on ?
>
> I have been struggling with the variance of an nxn window of data, INCLUDING
> central pixel
>
> ;mean of the neighboring pixels (including central)
> mean=smooth(arr,n)
> ;square deviation from that mean
> sqdev=(arr-mean)^2
> ;variance of an nxn window of data, INCLUDING central pixel
> var=(smooth(sqdev,n)*n^2-sqdev)/(n^2-1)
>

Almost right. Try:

var=smooth(sqdev,n)*n^2/(n^2-1)

but this still won't yield exactly what you're after, but maybe you're
after the wrong thing ;)

What this computes is a smoothed box variance, not a true box variance,
since the mean you are using changes over the box (instead of
subtracting the mean value at the central pixel from each in the box, we
subtract the box mean value at *that* pixel). Usually, this type of
variance is a more robust estimator, e.g. for excluding outlier pixels,
etc. (in which case you probably should exclude the central pixel after
all to avoid the chicken and egg problem with small box sizes). If you
really want the true variance, you're probably stuck with for loops,
preferrably done in C and linked to IDL.

This reminds me of a few things I've been thinking about IDL recently.
Why shouldn't *all* of these smooth type operations be trivially
feasible in IDL. Certainly, the underlying code required is simple.
Why can't we just say:

a=smooth(b,n,/VARIANCE)

to get a true box variance, or

a=smooth(b,n,/MAX)

to get the box max. Possibilities:
*MEAN (the current default)
*TOTAL (a trivial scaling of mean),
*VARIANCE
*MEDIAN (currently performed by the median function, in a addition to
its normal duties. To see why this is strange, consider that total()
doesn't have an optional "width" to perform neighborhood filtering).
*MIN
*MAX
*MODE
*SKEW
etc.

To be consistent, these should all operate natively on the input data
type (float, byte, long, etc. -- like smooth() and convol() do, but like
median() does not!), and should apply consistent edge conditions
activated by keywords. These seem like simple enough additions, and
would require much reduced chicanery.

While I'm on the gripe train, why shouldn't we be able to consistently
perform operations along any dimension of an array we like with relevant
IDL routines. E.g., we can total along a single dimension. All due
respect to Craig's CMAPPLY function, but some of these things should be
much faster. Resorting to summed logarithms for multiplication is not
entirely dubious, but why shouldn't we be able to say:

col_max=max(array,2,POS=mp)

and have mp be a list of max positions, indexed into the array, and
rapidly computed? While we're at it, why not

col_med=median(array,2,POS=mp)

IDL is an array based language, but it conveniently forgets this fact on
occassion. Certainly there are compatibility difficulties to overcome
to better earn this title, but that shouldn't impede progress.

JD

--
J.D. Smith | WORK: (607) 255-6263
Cornell Dept. of Astronomy | (607) 255-5842
304 Space Sciences Bldg. | FAX: (607) 255-5875
Ithaca, NY 14853 |
Re: efficient kernel or masking algorithm ? [message #22643 is a reply to message #22642] Wed, 29 November 2000 00:00 Go to previous message
Richard Tyc is currently offline  Richard Tyc
Messages: 69
Registered: June 1999
Member
WOW, I need to look at these equations over about a dozen times to see what
is going on ?

I have been struggling with the variance of an nxn window of data, INCLUDING
central pixel

;mean of the neighboring pixels (including central)
mean=smooth(arr,n)
;square deviation from that mean
sqdev=(arr-mean)^2
;variance of an nxn window of data, INCLUDING central pixel
var=(smooth(sqdev,n)*n^2-sqdev)/(n^2-1)

This doesn't seem correct with test samples ? (Only difference is mean and
division by n^2-1 ??)

Thanks JD

Rich


J.D. Smith <jdsmith@astro.cornell.edu> wrote in message
news:3A25758E.A83B10CA@astro.cornell.edu...
>
> Oh my this is a common topic lately. See my recent posts in a thread
> with title "Array Manipulations". Here's the good stuff:
>
> ; the nxn window total
> total=smooth(arr,n)*n^2
> ; the nxn window total not including central pixel
> neighbors=smooth(arr,n)*n^2-arr
> ; the mean of the neighboring pixels (excluding central)
> neighmean=(smooth(arr,n)*n^2-arr)/(n^2-1)
> ; the square deviation from that mean
> sqdev=(arr-neighmean)^2
> ; the variance of an nxn window of data, excluding central pixel
> imvar=(smooth(sqdev,n)*n^2-sqdev)/(n^2-2)
>
> Take a look at the "EDGE*" keywords too, if you care about what happens
> near the borders.
>
> JD
>
> --
> J.D. Smith | WORK: (607) 255-6263
> Cornell Dept. of Astronomy | (607) 255-5842
> 304 Space Sciences Bldg. | FAX: (607) 255-5875
> Ithaca, NY 14853 |
Re: efficient kernel or masking algorithm ? [message #22644 is a reply to message #22642] Wed, 29 November 2000 00:00 Go to previous message
John-David T. Smith is currently offline  John-David T. Smith
Messages: 384
Registered: January 2000
Senior Member
Richard Tyc wrote:
>
> I need to apply a smoothing type kernel across an image, and calculate the
> standard deviation of the pixels masked by this kernel.
>
> ie. lets say I have a 128x128 image. I apply a 3x3 kernel (or simply a
> mask) starting at [0:2,0:2] and use these pixels to find the standard
> deviation for the center pixel [1,1] based on its surrounding pixels, then
> advance the kernel etc deriving a std deviation image essentially.
> I can see myself doing this 'C' like with for loops but does something exist
> for IDL to do it better or more efficiently ?
>
> Rich

Oh my this is a common topic lately. See my recent posts in a thread
with title "Array Manipulations". Here's the good stuff:

; the nxn window total
total=smooth(arr,n)*n^2
; the nxn window total not including central pixel
neighbors=smooth(arr,n)*n^2-arr
; the mean of the neighboring pixels (excluding central)
neighmean=(smooth(arr,n)*n^2-arr)/(n^2-1)
; the square deviation from that mean
sqdev=(arr-neighmean)^2
; the variance of an nxn window of data, excluding central pixel
imvar=(smooth(sqdev,n)*n^2-sqdev)/(n^2-2)

Take a look at the "EDGE*" keywords too, if you care about what happens
near the borders.

JD

--
J.D. Smith | WORK: (607) 255-6263
Cornell Dept. of Astronomy | (607) 255-5842
304 Space Sciences Bldg. | FAX: (607) 255-5875
Ithaca, NY 14853 |
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: Contours driving me mad
Next Topic: How Computers Represent Floats

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Fri Oct 10 08:11:24 PDT 2025

Total time taken to generate the page: 0.24134 seconds