; docformat = 'rst' ;+ ; Computes the local moments for an array with a given window size. ; ; :Examples: ; Try the main-level example program at the end of this file:: ; ; IDL> .run mg_local_moment ; ; :Returns: ; array of the same size as `image` input parameter, type will be float or ; double depending on the type of `image` and if the `DOUBLE` keyword is ; set ; ; :Params: ; image : in, required, type=numeric array ; original image; will be converted to float or double ; width : in, required, type=integer ; size of window ; ; :Keywords: ; double : in, optional, type=boolean ; set to do computations as doubles ; sdev : out, optional, type=float/double array ; set to a named variable to get local standard deviation ; variance : out, optional, type=float/double array ; set to a named variable to get local variance ; skewness : out, optional, type=float/double array ; set to a named variable to get local skewness ; kurtosis : out, optional, type=float/double array ; set to a named variable to get local kurtosis ; edge_mirror : in, optional, type=boolean ; set to compute edge values by mirroring ; edge_truncate : in, optional, type=boolean ; set to compute edge values by repeating ; edge_wrap : in, optional, type=boolean ; set to compute edge values by padding array with zeros ; edge_zero : in, optional, type=boolean ; set to compute edge values by wrapping ; nan : in, optional, type=boolean ; set to treat NaN as missing data ; ; :Requires: ; IDL 8.1 ;- function mg_local_moment, image, width, double=double, $ sdev=sdev, variance=variance, skewness=skewness, $ kurtosis=kurtosis, $ edge_mirror=edge_mirror, $ edge_truncate=edge_truncate, $ edge_wrap=edge_wrap, $ edge_zero=edge_zero, $ nan=nan compile_opt strictarr on_error, 2 ; sanity checking on arguments if (n_params() ne 2) then message, 'incorrect number of arguments' ; convert to double precision if DOUBLE keyword is set _image = keyword_set(double) ? double(image) : image ; kernel is array of 1's with the same number of dimensions as `image`, but ; size in each dimension of `width` dims = replicate(width, size(image, /n_dimensions)) one = fix(1, type=keyword_set(double) ? 5L : size(image, /type)) kernel = make_array(dimension=dims, value=one) n = product(dims, /preserve_type) ; mean local_mean = convol(_image, kernel, $ edge_mirror=edge_mirror, edge_truncate=edge_truncate, $ edge_wrap=edge_wrap, edge_zero=edge_zero, nan=nan) / n ; variance or standard deviation if (arg_present(sdev) $ || arg_present(variance) $ || arg_present(skewness) $ || arg_present(kurtosis)) then begin squared = convol(_image^2, kernel, $ edge_mirror=edge_mirror, edge_truncate=edge_truncate, $ edge_wrap=edge_wrap, edge_zero=edge_zero, nan=nan) variance = (squared - n * local_mean^2) / (n - 1.0) sdev = sqrt(variance) endif ; skewness if (arg_present(skewness) || arg_present(kurtosis)) then begin cubed = convol(_image^3, kernel, $ edge_mirror=edge_mirror, edge_truncate=edge_truncate, $ edge_wrap=edge_wrap, edge_zero=edge_zero, nan=nan) skewness = (cubed / n - 3.0 * local_mean * squared / n + 2.0 * local_mean^3) / sdev ^ 3 endif ; kurtosis if (arg_present(kurtosis)) then begin fourth = convol(_image^4, kernel, $ edge_mirror=edge_mirror, edge_truncate=edge_truncate, $ edge_wrap=edge_wrap, edge_zero=edge_zero, nan=nan) kurtosis = (fourth / n - 4.0 * local_mean * cubed / n + 6.0 * local_mean^2 * squared / n - 3.0 * local_mean^4) / variance^2 - 3.0 endif return, local_mean end ; main-level example program print, '1-dimensional example: mg_local_moment(findgen(10), 3)' print, mg_local_moment(findgen(10), 3) print print, '2-dimensional example: mg_local_moment(findgen(5, 5), 3)' print, mg_local_moment(findgen(5, 5), 3) print print, '3-dimensional example: mg_local_moment(findgen(4, 4, 4), 3)' print, mg_local_moment(findgen(4, 4, 4), 3) end