Friday, June 24, 2011

JAITools version 1.2.0 and Jiffle version 0.2.0 released

JAITools version 1.2.0 and Jiffle version 0.2.0 are now available. These are the first versions under the new org.jaitools domain and the first to be covered by Simplified BSD licence (aka BSD-2)

If you use Maven as your build tool, see the notes below on upgrading to the new versions.

You can download binaries manually from Maven Central directly at http://repo1.maven.org/maven2/org/jaitools/ or by using the Maven Search interface.

JAITools
Version 1.2.0 is a minor release with a large number of fixes and improvements, better unit test coverage and more comprehensive javadocs. In addition, there are the new image iterator classes SimpleIterator and WindowIterator which were previewed here in earlier posts.

To download the JAITools source code using Subversion:
    svn co http://jaitools.googlecode.com/svn/tags/1.2.0 jaitools-1.2.0
You can browse the API docs at: http://jaitools.org/docs/jaitools/stable/apidocs/

Jiffle
Version 0.2.0 is also a minor release aligned with JAITools 1.2.0.

To download the Jiffle source code using Subversion:
    svn co http://jiffle.googlecode.com/svn/tags/0.2.0 jiffle-1.2.0
You can browse the API docs online at: http://jaitools.org/docs/jiffle/stable/apidocs/The draft Jiffle user guide is here: http://jaitools.org/docs/jiffle/latest/userguide/html/

Upgrading from previous versions
  1. In your source code, edit all JAITools and Jiffle import statements and add the org.prefix. For example:
    import jaitools.imageutils.ROIGeometry;
    becomes...
    import org.jaitools.imageutils.ROIGeometry;
  2. If use you Maven as your build tool, edit your project pom.xml file and change the groupId for all JAITools and Jiffle modules from com.googlecode.jaitools to org.jaitools. For example, the dependency for the jt-utils module will now look like this...
    <dependency>
    <groupId>org.jaitools</groupId>
    <artifactId>jt-utils</artifactId>
    <version>1.2.0</version>
    </dependency>

Coming up next

The wiki on the JAITools Google Code site is sadly out of date, so the next item on the todo list is to replace it with Sphinx-based documentation at jaitools.org.

Meanwhile please try the new versions and give us your feedback via the mailing list or by tweeting to @JAITools.

Share and enjoy.

Tuesday, June 14, 2011

Hyphenectomy

I'm really not sure why I thought JAI-tools was a good name for the project, as opposed to just JAITools. Not only does the dash fail to serve any real purpose in the name, it also guaranteed a clash with package names. And because it seemed more natural for the project's Maven group Id to follow the package names ("jaitools") rather than the project name ("jai-tools") things went from dumb to dumber.

So, the time has come for a radical hyphenectomy (dash removal) consisting of the following changes:
  • A new project web site will be set up at http://jaitools.org. The existing API docs and Jiffle user guide have already been moved from http://jai-tools.org to the new domain.
  • The project's Google Code website is being moved from http://code.google.com/p/jai-tools to http://code.google.com/p/jaitools
  • The root package name and Maven groupId for both JAITools and Jiffle will be org.jaitools
  • This blog will move to http://jaitools.blogspot.com
The new Maven groupId and package names will take effect with the next release: version 1.2.0 for JAITools and version 0.2.0 for Jiffle, both of which are due before the end of this month (June 2011).

Update - 18 June 2011

All project sources have now been moved to the new Google Code site: http://code.google.com/p/jaitools/.

Thursday, June 2, 2011

JAI-tools and Jiffle go free-er

JAI-tools and Jiffle are now covered by the Simplified BSD licence. This applies to the forthcoming JAI-tools version 1.2 release, and immediately to all of the development sources in both projects.

The intention is simple: to encourage use of, and contribution to, both projects as much as possible.

Share and enjoy.

Wednesday, June 1, 2011

Next please ! Image iterators part 2

In the previous article the new SimpleIterator and WritableSimpleIterator classes were introduced. In this article, we'll look at some additional features of those classes and then take a peek at another new class: WindowIterator.

Sometimes size matters. If you are working with massive images it's important to make data access as efficient as possible. This is even more important when working with images over a network. SimpleIterator caters for this with its tile-wise traversal option...


RenderedImage myGreatBigImage = ...
Rectangle iteratorBounds = ...
int outside = 0;

// create an iterator that will visit each tile in turn
SimpleIterator iter = new SimpleIterator(myGreatBigImage, iteratorBounds,
outside, SimpleIterator.Order.TILE_X_Y);

// no special code is required when using the iterator in tile-wise mode
do {
Number sample = iter.getSample();
// do interesting things with data
...
while (iter.next());


With tile-wise traversal, the iterator first divides its bounding rectangle into sub-bounds according to the image's tile structure. When moved with the next() method, as in the above code snippet, the iterator will visit all pixels in a sub-bound before proceeding to the next. This minimizes the need to swap tiles in and out of memory or move them across a network.

You can also use random access in combination with tile-wise traversal as in this example...

SimpleIterator iter = new SimpleIterator(myGreatBigImage, iteratorBounds,
outside, SimpleIterator.Order.TILE_X_Y);

// We first sample a specified position
Number sample = iter.getSample(x, y, band);

// Now if we continue sequentially, the iterator will do tile-wise
// sampling of the image
while (iter.next()) {
sample = iter.getSample(band);
...
}


WindowIterator

Moving window algorithms are common in image processing. Many kernel-based analyses can be implemented as convolutions using JAI's Convolve operator or the more flexible JAI-tools MaskedConvolve operator (see also the JAI-tools KernelFactory class). However, algorithms which are more complex or involve probabilistic sampling of the values in the moving window are better handled by passing the moving window values to the client directly. The new WindowIterator class caters for this.

Consider the Voter Model algorithm in which, over many iterations, the value of each pixel in an image is replaced by a randomly selected value from its neighbourhood. Clint Sprott's excellent website has examples of this algorithm applied to ecological simulation and image reconstruction.

Below is a snippet adapted from a JAI-tools example program showing how WindowIterator can be used with a WritableSimpleIterator to implement the Voter Model algorithm (the complete example is available here).


// A WindowIterator gets values from the source image
Dimension winDim = new Dimension(3, 3);
Point keyElement = new Point(1, 1);
winIter = new WindowIterator(sourceImage, null, winDim, keyElement);
int[][] dataWindow = null;

// A WritableSimpleIterator to set values in the destination image
writeIter = new WritableSimpleIterator(destImage, null, null);

do {
// Get a 3x3 window of values from the source image
dataWindow = winIter.getWindow(dataWindow);

// Call a method which random selects a window position
// other than the key element
Point nbr = getRandomNbr(winDim, keyElement);

// Write the value of the selected neighbour to the
// destination image
writeIter.setSample(dataWindow[nbr.y][nbr.x]);

} while (winIter.next() && writeIter.next());


The bounds of a WindowIterator represent all positions that the data window's key element will traverse. If the bounds are equal to, or extend beyond, the image bounds, then some data window positions can lie outside the image. WindowIterator lets you specify an outside value to be returned for these positions...


// This iterator will return -1 for all cells that lie outside the image
WindowIterator iter = new WindowIterator(image, bounds, winDim, keyElement, -1);


If you're familiar with JAI's BorderExtender classes you'll note that this is equivalent to using a BorderExtenderConstant.

WindowIterator also allows you to set the X and Y step distances. In this example, the step distances are set to the window dimensions to down-sample the source image...

RenderedImage image = ...

Dimension winDim = new Dimension(3, 3);
Point keyElement = new Point(1, 1);
int xstep = 3;
int ystep = 3;

Rectangle iterBounds = new Rectangle(
image.getMinX() + 1, image.getMinY() + 1,
image.getWidth - 2, image.getHeight() - 2);

WindowIterator iter = new WindowIterator(image, iterBounds, winDim, keyElement,
xstep, ystep, 0);

do {
dataWindow = iter.getSample(dataWindow);
// extract desired summary from window and write to
// a destination image
...
} while (iter.next());

Monday, May 30, 2011

Next please ! Easier image iterators

The forthcoming JAI-tools version 1.2 will include several new image iterator classes. Here is a quick preview of two of them: SimpleIterator (read-only access) and WritableSimpleIterator (read-write access).

If you are used to working with the standard JAI RectIter class you probably have nested do-while loops burnt into your frontal cortex from having to write code like this countless times...
RectIter iter = ...
do {
do {
int value = iter.getSample();
// do something with value
} while (!iter.nextPixelDone());
iter.startPixels();
} while (!iter.nextLineDone());

In comparison, SimpleIterator is, well, simpler...
SimpleIterator iter = ...
do {
Number value = iter.getSample();
// do something with value
} while (iter.next());

The next() method takes care of both horizontal and vertical movement, plus it is always safe to call it speculatively. There is also a hasNext() method for convenience.

The comparison is more telling for code where you need to track the location of the image iterator. With RectIter you might write something like this...
RenderedImage image = ...
RectIter iter = ...
int x = image.getMinX();
int y = image.getMinY();
do {
do {
int value = iter.getSample();
x++ ;
// do something with value
} while (!iter.nextPixelDone());
iter.startPixels();
x = image.getMinX();
y++ ;
} while (!iter.nextLineDone());

But with SimpleIterator you can use the getPos() method...
RenderedImage image = ...
SimpleIterator iter = ...
do {
Number value = iter.getSample();
Point pos = iter.getPos();
// do something with value and position
} while (iter.next());

You might have noticed that SimpleIterator.getSample() returns a Number object rather than a primitive value. Unlike JAI's RectIter class, there are no separate getSampleFloat and getSampleDouble methods. Instead, the iterator returns image values that are either Integer, Float or Double class depending on the data type of the source image.

You can also use SimpleIterator as a replacement for JAI's RandomIter class. In fact, a SimpleIterator instance provides both sequential (X then Y) movement across an image via its next() method, plus random positioning with additional getSample methods as shown here...
// get the value of a specific position and band
int value = simpleIter.getSample(x, y, band).intValue();

// now continue from that position to the end of the iterator bounds
while (simpleIter.next()) {
value = simpleIter.getSample().intValue();
}


SimpleIterator also provides more flexible bounds handling. For example, you can set the bounds of the iterator to extend beyond those of the source image. When the iterator is positioned outside the image it will return an outside value which is set via the constructor...
// create an iterator that will return -1 when positioned outside the
// source image bounds
SimpleIterator iter = new SimpleIterator(myImage, iteratorBounds, -1);

This makes it easy to program applications that need to sample within a fixed bounding rectangle, which may or may not be contained within an image's bounds. There is no need to intersect rectangles or monitor positions in your own code.

WritableSimpleIterator provides the same methods as SimpleIterator together with the ability to set values in a writable image, either sequentially or for specified positions.

But wait - there's more ! JAI-tools version 1.2 will also include WindowIterator, to pass a client-defined moving window over an image, and ImageSetIterator, to sample multiple images simultaneously. We'll talk more about these in a subsequent article.

Tuesday, April 5, 2011

JAI-tools version 1.1.1 and Jiffle version 0.1.0 released

The JAI-tools team is pleased to announce the combined release of new versions of JAI-tools and Jiffle. This is the first release since Jiffle moved into a separate project with its own versioning (see previous post).

The new versions are now available from the Maven Central repository and mirror sites.

You can checkout the sources from:
http://jai-tools.googlecode.com/svn/tags/1.1.1
http://jiffle.googlecode.com/svn/tags/0.1.0

To search for particular changes of interest go to the issue tracker for each project.

Thanks to Andrea Aime and Daniele Romagnoli for their work on this release, and also Ian Turton and Manuel Bossant for contributions and bug spotting.

JAI-tools version 1.1.1

This is a minor release which includes bug fixes and improvements, but also some new features. Notable items:
  • ROIGeometry now has more methods implemented and improved performance.
  • Problems with clipping and setting rendering hints have been fixed in the DiskMemImageGraphics class.
  • KernelFactory has been expanded and can now generate many standard kernel types including cosine, Gaussian, Epanechnikov and quartic.
  • Improvements to the utility Swing widgets.
  • A new CompareOp class for comparison of double and float values taking into account absolute or proportional tolerance.

Jiffle version 0.1.0

This is the first release of the Jiffle scripting language under its own version numbering. The new jars are jt-jiffle-language-0.1.0.jar and jt-jiffle-demo-0.1.0.jar.

The main change from the version that was included with JAI-tools 1.1.0 is support for user-defined coordinates. This separates the bounds and resolution of the processing area from those of the source and destination images. It means that within your Jiffle script, you can work with whatever type of coordinates are best suited to your application, e.g. geographic, proportional, or arbitrary cartesian coordinates. When running a script, CoordinateTransform objects are used to convert between user coordinates and pixel positions in each source and destination image.

The separation of processing and image coordinates can be handy even when you are working directly with pixel positions. You can use it to deal with non-overlapping source and destination images, or as a device to sub-sample or over-sample source images.

As well as the new coordinate support, there have been some small extensions to Jiffle's syntax and a general tidy-up of the code base and javadocs.

Share and enjoy.

Tuesday, March 22, 2011

Jiffle leaves home to grow up

Although it's usually the other way around (grow up then leave home) sometimes things don't turn out as planned...

For Jiffle, the scripting language developed as part of JAI-tools, what was originally planned was compatibility with the r.mapcalc raster algebra language used in GRASS GIS, but recently we decided that this was too limiting and it would be better to set Jiffle free and have its development driven purely by our brilliant ideas (plus the moderating influence of user feedback).

Like all great ambitions, this one quickly ran aground on the rocks of practical constraint. Being a module in a Maven-based project, Jiffle had the same version number as all of the other JAI-tools modules, but this didn't fit well with allowing Jiffle's syntax and code-base to be more fluid (ie. lots of changes breaking backwards-compatibility). So it was decided to separate Jiffle out from the JAI-tools project.

Jiffle now has its own site: http://code.google.com/p/jiffle/ and it's been re-versioned to 0.1.x to make it clear to users that substantial changes can be expected. Despite leaving home, Jiffle will retain its close relationship to JAI-tools, with the same project team developing both.

Unfortunately, this has created a certain amount of version chaos. At Maven Central you can find:
  • jt-jiffle-1.1.0.jar (as part of the most recent JAI-tools release)
  • jiffle-1.0.1.jar (from the previous release before the "jt-" prefix was adopted)
  • And soon: jt-jiffle-language-0.1.0.jar (the new jar name being required to avoid future clashes with previous versions)
It's hard to see how we could have made it much more confusing.

Here's what to do:
  • For JAI-tools version 1.1.0, use jt-jiffle-1.1.0
  • With later JAI-tools releases, swap over to the most recent version of jt-jiffle-language
If you you use Maven as your build tool it will cut through much of this confusion for you because the dependency relationship between different versions of JAI-tools and Jiffle will be contained in each project's pom.xml file.

The next post will show off some of the new Jiffle language features to prove that all of this chaos has been worth it :)