On 9/25/2011 8:40 AM, Jarrod Miller wrote:
Hi folks.
I have a very simple question about threading that I'm sure won't be
difficult for a seasoned piddle twiddler..
I have a 2D matrix which is essentially a greyscale image.
I need to implement a moving window over the image to perform a few
transformations based on surrounding pixel values. For now I'll likely just
be averaging the pixel intensity around each pixel so I can build a
threshold.
At the moment I'm using this code to get my moving window(s), inspired by
the threads page on the wiki: $p->range($p->ndcoords()-15, 31,
'm')->reorder(2,3,0,1); This works fantastic -- except for the part where I
run out of RAM and perl segfaults.
range is very powerful but memory intensive. In your case,
the piddle created is almost 1000X larger than the original.
If perl runs out of memory then it exits. I'm not sure why
you are seeing segfaults.
So I was wondering how I should go about doing this. My current "workaround"
is to use perl loops, and just move the window one slice at a time, adding
and subtracting the columns as I get to them, so I can calculate a
relatively fast average. It works, but I'm very sure this isn't the 'right'
way to do it..
Any help would be greatly appreciated.
Looping over smaller regions/slices is one approach but if
you are using range as above, you'll still see the 1000X
memory increase for the operations.
The simplest approach is to use one of the existing
PDL routines for 2D data. I.e.,
$ pdldoc -a 2d
PDL::Graphics2D Module: An object oriented interface to PDL graphics
PDL::Image2D Module: Miscellaneous 2D image processing functions
applywarp2d Transform a set of points using a 2-D polynomial mapping
bilin2d Bilinearly maps the first piddle in the second. The
interpolated values are actually added to the second piddle which is
supposed to be larger than the first one.
box2d fast 2D boxcar average
cc8compt Connected 8-component labeling of a binary image.
centroid2d Refine a list of object positions in 2D image by centroiding in
a box
conv2d 2D convolution of an array with a kernel (smoothing)
fitwarp2d Find the best-fit 2D polynomial to describe a coordinate
transformation.
hi2d Plot image as 2d histogram (not very good IMHO...)
histogram2d Calculates a 2d histogram.
imag2d Display a 2-D image in a figure window
imagrgb 2D RGB image plot (see also imag2d)
imagrgb3d 2D RGB image plot as an object inside a 3D space
index `index' and `index2d' provide rudimentary index indirection.
index2d `index' and `index2d' provide rudimentary index indirection.
inner2d Inner product over 2 dimensions.
max2d_ind Return value/position of maximum value in 2D image
med2d 2D median-convolution of an array with a kernel (smoothing)
med2df 2D median-convolution of an array in a pxq window (smoothing)
patch2d patch bad pixels out of 2D images using a mask
patchbad2d patch bad pixels out of 2D images containing bad values
polyfill fill the area inside the given polygon with a given colour
polyfillv return the (dataflown) area of an image within a polygon
polyfit Fit discrete data in a least squares sense by polynomials in
one variable. Handles threading correctly--one can pass in a
2D PDL (as `$y') and it will pass back a 2D PDL, the rows of
which are the polynomial regression results (in `$r'
corresponding to the rows of $y.
rescale2d The first piddle is rescaled to the dimensions of the second
(expanding or meaning values as needed) and then added to it
in place. Nothing useful is returned.
rot2d rotate an image by given `angle'
twiddle Enable GUI interaction with a FreeGLUT display window.
warp2d Warp a 2D image given a polynomial describing the *reverse*
mapping.
warp2d_kernel Return the specified kernel, as used by warp2d
whistogram2d Calculates a 2d histogram from weighted data.
conv2d seems appropriate for the current problem.
$ pdldoc conv2d
Module PDL::Image2D
conv2d
Signature: (a(m,n); kern(p,q); [o]b(m,n); int opt)
2D convolution of an array with a kernel (smoothing)
For large kernels, using a FFT routine, such as fftconvolve() in
"PDL::FFT", will be quicker.
$new = conv2d $old, $kernel, {OPTIONS}
$smoothed = conv2d $image, ones(3,3), {Boundary => Reflect}
Boundary - controls what values are assumed for the image when kernel
crosses its edge:
=> Default - periodic boundary conditions
(i.e. wrap around axis)
=> Reflect - reflect at boundary
=> Truncate - truncate at boundary
Unlike the FFT routines, conv2d is able to process bad values.
You can also use PDL::PP code and Inline::Pdlpp to implement
your own window computations directly for the threading engine.
Cheers,
Chris
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl