Can I use an Array In Math->Macro... in an IJ macro?

Nested for loops hurt my brain,
so I try to use the Math->Macro… command from within an IJ macro as follows

run("Macro...", "code=[v=myArray[x]]");

to put values from myArray into a new image (a z-stack, this command is in a for loop for z slices).
This doesn’t seem to work as expected, but throws no error message…

The result image scans through its z stack as I run the command but the pixel values aren’t changed.
If i use a trivial function just using eg x*y
it works just fine.

Can anyone tell me if this is possible at all…
or should i just use three nested for loops the “normal” way and forget the Macro… command for now?

I’m trying to reconstruct a 3D image from a 2D radial average image, in an IJ macro, so used an array to hold the 2D image info with which to fill in the 3D image z-Stack.

cheers

Dan

I suppose the variable myArray is just not defined inside the scope of the Macro… command. I agree it should throw an error in this case, but you can try with any name and in fact it doesn’t.


But I’m sure there must be an easier way to achieve what you want using Ops. I’m just not sure if I understand exactly what you need. Could you explain in a bit more detail what is your input array and which output you’d like to have?

As far as I understand, you have a 1D image in your array myArray, and you want to map it to all x,y,z dimensions of your output??

1 Like

Yes that’s right.
The array is used to fill in the 3D Image, using the appropriate transform.

Actually I would like to avoid the intermediate array,
but in IJ macro lang i dont see how you can work on 2 images at the same time, read from one and write into another.
Maybe I miss something basic

Of course if i did it in javascript or python, I could access the image processors directly of both images,
but i was trying to keep my life as simple as possible… maybe that’s not really simpler after all.

Indeed Ops might hold a better answer… i should take a look…

I got it working (except my transform is wrong!)
with nested for loops in IJ macro , but i still don’t like the smell.

cheers

d

Just for completeness: @chalkie666 cross-posted this question on the ImageJ mailing list as well; see this thread.

Post the 2D image and the transform and I will try to create JavaScript code that fills the 3D image. JavaScript is up to 30 times faster than macro code and it is better suited to working with multiple images.

Here is some JavaScript code that transforms a 2D image into a 720x576x256 (101 megapixel) stack in less than one second.

img = IJ.openImage("http://wsr.imagej.net/images/boats.gif");
ip = img.getProcessor();
img2 = makeStack(ip);
img2.show();
IJ.run(img2, "3D Project...", "projection=[Brightest Point] axis=X-Axis slice=1 initial=15 total=0 lower=1 upper=255 opacity=0 surface=100 interior=50");
IJ.run("Enhance Contrast", "saturated=0.35");

function makeStack(ip) {
   var w = ip.getWidth();
   var h = ip.getHeight();
   var d = 256;
   var img2 = IJ.createImage("Stack", "8-bit black", w, h, d);
   var stack, y, x, value, z;
   stack = img2.getStack();
   for (y=0; y<h; y++) {
      for (x=0; x<w; x++) {
         value = ip.get(x,y);
         for (z=0; z<value; z++)
            stack.setVoxel(x, y, z, z);
      }
   }
   return img2;
 }
2 Likes

thanks Wayne! thats really great.
My transform is a bit complicated and ugly, but i think i figured it out…

but you solved my main problem which was a sensible way to do the general idea in a scripting lang where i can easily access both in and out images!

this is much better than making an intermediate array in IJ macro.

cheers
D

1 Like