Tuesday, December 6, 2011

Using images as arrays in script


In my previous posts Using arrays in script... [TOC],  we have seen in Part 1 how to store data in arrays using the built-in function newArray(...)  and in Part 2, the use of Table windows (Results [Link] or any Table window [Link]). Here I'll describe how data storage can be done via images and how this technique is powerful for large arrays.

1- 1D-array

Images are 2D-arrays of pixels where each pixel is defined by its coordinates (x,y, ... and z for stack) and a value (8-bit, 16-bit, 24-bit, or 32-bit). This rather simple definition is exactly what we want for a data storage with a direct access to the contents.
1-2- Array/Image creation
To create such an array, we use the newImage(...) function.

newImage("array","32-bit Black",<length>,1,1);

We have to create a 32-bit (float) image, because in ImageJ, all the numbers used in a script are floating-point numbers, moreover, it's better to choose a black background to initialize the image with the value 0.0 (zero).
The image dimensions are directly related to the amount of data. If all the data are stored in one row, the image dimensions are width=<data length> and height =1.
Note: a vertical image is also possible, it's a matter of personal choice. There is no impact in terms of speed.

To manage multiple arrays in the same script, just put each array in a different image row...

newImage("arrays","32-bit Black",<max(length)>,<arrays number>,1);

The height must be modified to take into account the number of arrays used in the script and the width corresponds to the maximum  length of all the arrays.
For example, three arrays of 4,9, and 7 elements, respectively, can be stored in a 32-bit image of dimension 9 x 3.
1-2- Data access
The functions setPixel(...) and getPixel() are used to write and read the data. 
1-3- Polyhedra example
Using the same example as in my previous posts the script is now ...

+++ IJ snippet +++ +++ End of IJ snippet +++


To see a more sophisticated example, I developed a script using an image as a 1D-array to find prime numbers [Link].

2- 2D-array

An image is genuinely a 2D-array ... thus the getPixel(...) and setPixel(...) functions are just needed to read and write the values in the image/2D-array.

3- Resize an array

That's really simple to extend an array by resizing the image in the X- and/or Y-dimension using the function run("Canvas Size...", ...) available in Image > Adjust > Canvas Size.

+++ IJ snippet +++ +++ End of IJ snippet +++

4- What about strings?

Using images to store strings is not a good approach, because the strings must be converted/encoded in a number (or a series of) and must be decoded to read them.  Maybe a topic for another post...

5- Conclusion

Pros: fast,simple,resizable
Cons: works well with numbers,tricky for strings, needs a good organization.

No comments:

Post a Comment