LSSTApplications  18.1.0
LSSTDataManagementBasePackage
MaskedImage Locators

(Return to Images)

(You might be interested to compare this example with the discussion of Image locators; apart from an include file and a typedef, the only difference is the use of ImageT::Pixel(y, 0x1, 10) as the assigned pixel value instead of y).

Iterators provide access to an image, pixel by pixel. You often want access to neighbouring pixels (e.g. computing a gradient, or smoothing). Let's consider the problem of smoothing with a

1 2 1
2 4 2
1 2 1

kernel (the code's in maskedImage2.cc):

Start by including MaskedImage.h, defining a namespace for clarity:

#include "lsst/geom.h"
namespace image = lsst::afw::image;
typedef image::MaskedImage<int> ImageT;
int main() {
Declare a MaskedImage
ImageT in(lsst::geom::Extent2I(10, 6));
Set the image (but not the mask or variance) to a ramp
for (int y = 0; y != in.getHeight(); ++y) {
for (ImageT::xy_locator ptr = in.xy_at(0, y), end = in.xy_at(in.getWidth(), y); ptr != end;
++ptr.x()) {
*ptr = ImageT::Pixel(y, 0x1, 10);
}
}

That didn't gain us much, did it? The code's a little messier than using x_iterator. But now we can add code to calculate the smoothed image. First make an output image, and copy the input pixels:

(we didn't need to copy all of them, just the ones around the edge that we won't smooth, but this is an easy way to do it).

Now do the smoothing:

(N.b. you don't really want to do this; not only is this kernel separable into 1 2 1 in first the x then the y directions, but lsst::afw::math can do convolutions for you).

Here's a faster way to do the same thing (the use of an Image::Ptr is just for variety)

The xy_loc::cached_location_t variables remember relative positions.

We can rewrite this to move setting nw, se etc. out of the loop:

You may have noticed that that kernel isn't normalised. We could change the coefficients, but that'd slow things down for integer images (such as the one here); but we can normalise after the fact by making an Image that shares pixels with the central part of out2 and manipulating it via overloaded operator/=

N.b. you can use the iterator embedded in the locator directly if you really want to, e.g.

Note that this isn't quite the same x_iterator as before, due to the need to make the x_iterator move the underlying xy_locator.

Finally write some output files and close out main():