Login  Register

Re: Calculating atan2 on pixels from two input images in a macro

Posted by Kurt Thorn on May 15, 2014; 9:26pm
URL: http://imagej.273.s1.nabble.com/Calculating-atan2-on-pixels-from-two-input-images-in-a-macro-tp5007758p5007762.html

On 5/15/2014 1:21 PM, Brian Northan wrote:

> Hi Adam
>
> You could go to one of the scripting languages, jython, jruby, beanshell...
> depends what you are comfortable with.
>
> I find most of the work is in googling the API functions anyway, figuring
> out how to get access to the images and buffers you need.   Something like
> the below beanshell may work (obviously where it says "clown.jpg" you
> replace with the name of your images).
>
>   ip1=WindowManager.getImage("clown.jpg (red)").getProcessor();
> ip2=WindowManager.getImage("clown.jpg (green)").getProcessor();
>
> width = ip1.getWidth();
> height = ip1.getHeight();
>
> out = NewImage.createFloatImage("out", width, height, 1, 0);
> out_ip=out.getProcessor();
>
> ip1Buffer=ip1.getPixels();
> ip2Buffer=ip2.getPixels();
> outBuffer=out_ip.getPixels();
>
> for (x=0;x<width;x++)
> {
>      for (y =0;y<height;y++)
>      {
>          p1=ip1Buffer[x+y*width];
>          p2=ip2Buffer[x+y*width];
>
>          value=java.lang.Math.atan2((double)p1, (double)p2);
>
>          outBuffer[x+y*width]=(float)value;
>      }
> }

In writing some Java code for Micro-manager, I found a 5-10x speed up by
replacing a nested loop like this one by a single loop, where you just
loop over the whole 1D array:

          int length = oldPixels.length;
          for (int index = 0; index < length; index++){
             newPixels[index] = (byte) ( (float) oldPixels[index]
                 * flatFieldImage_[index]);
          }


Code from
https://valelab.ucsf.edu/svn/micromanager2/trunk/plugins/MultiChannelShading/src/org/micromanager/multichannelshading/BFProcessor.java

Kurt

>
> out.show();
>
>
> On Thu, May 15, 2014 at 4:09 PM, George Patterson <[hidden email]>wrote:
>
>> Hi Adam,
>> There is likely a more elegant solution to your question, but until it's
>> posted a way to speed up your macro is to put the pixels values for each
>> image into arrays and then index them based on the image dimensions.  It's
>> one of the work arounds suggested for the macro language limitation to 1D
>> arrays.
>> Using the arrays avoids switching between the three images.  It will still
>> be limited in speed compared to a plugin and may require a lot of memory
>> for the arrays (dependent on your image size).  But it will be faster than
>> switching between the images and it might get you by until a better
>> solution is posted.
>> I've pasted an edited version of your code below.
>> Best,
>> George
>>
>>
>> selectImage(U);
>> w = getWidth();
>> h = getHeight();
>>
>> UArray=newArray(w*h);
>> QArray=newArray(w*h);
>>
>> selectImage(U);
>> for (y=0; y<h; y++) {
>> for (x=0; x<w; x++) {
>> UArray[x+(h*y)]=getPixel(x, y);
>> }
>> }
>>
>> selectImage(Q);
>> for (y=0; y<h; y++) {
>> for (x=0; x<w; x++) {
>> QArray[x+(h*y)]=getPixel(x, y);
>> }
>> }
>>
>> newImage("Ψ", "32-bit", w, h, 1);
>> for (y=0; y<h; y++) {
>> for (x=0; x<w; x++) {
>> setPixel(x, y, 0.5*atan2(UArray[x+(h*y)],QArray[x+(h*y)]));
>> }
>> }
>> updateDisplay();
>>
>>
>> On Thu, May 15, 2014 at 2:46 PM, [hidden email] <[hidden email]
>>> wrote:
>>> Hello all,
>>>
>>> *My Question:*
>>> Is there a way of creating a new image (in a reasonable amount of time)
>>> from
>>> the atan2 value calculated from the pixel values of two input images, in
>> an
>>> imageJ macro? Can this be done within a macro or will this require a
>> script
>>> or plugin?
>>>
>>> *Background on what I'm doing and what I've attempted:*
>>> I have been writing a macro to calculate intensity (/I/), degree of
>> linear
>>> polarization (/p/), and angle of polarization (Ψ) from a set of four
>>> photographs taken with a polarizing filter at different angles (0, 45,
>> 90,
>>> 135) ( addition info on polarimetry measurements
>>> <
>>>
>> https://casper.berkeley.edu/astrobaki/index.php/Polarization#Stokes_Q__U:_linear_polarization
>>> ). I have created the macro work on multiple sets of such images.
>>>
>>> I am able to calculate /I/ & /p/ without to much trouble using the image
>>> calculator and the process>math functions. I have hit a roadblock with
>>> calculating Ψ though. The formula to calculate Ψ is:
>>>
>>>      Ψ = 0.5*atan(/U///Q/)
>>>
>>>      U & Q are stokes parameters calculated from intensity values from the
>>> images (see link above)
>>>
>>> Unfortunately atan have different values depending on the sign of the two
>>> inputs, so I cannot simply divide U by Q and take the atan of the value
>>> like
>>> this:
>>>
>>>      imageCalculator("Divide create 32-bit", "U","Q");
>>>      selectWindow("Result of U");
>>>      run("Macro...", "code=v=0.5*atan(v)");
>>>
>>> The atan2 function takes the different values into account but requires
>> two
>>> inputs and must be iterated over each pixel. I've tried the code below
>> but
>>> it is incredibly slow.
>>>
>>>          selectImage(U);
>>>          w = getWidth();
>>>          h = getHeight();
>>>          newImage("Ψ", "32-bit", w, h, 1)
>>>          for (y=0; y<h; y++) {
>>>                  for (x=0; x<w; x++) {
>>>                          selectImage(U)
>>>                          Upixel=getPixel(x, y);
>>>                          selectImage(Q)
>>>                          Qpixel=getPixel(x, y);
>>>                          setPixel(x, y, 0.5*atan2(Upixel, Qpixel))
>>>                          }
>>>                  }
>>>          updateDisplay();
>>>
>>> Fiji has the Image Expression Parser which does exactly what I want
>>> (0.5*atan2(A,B)), but at least I haven't figured out a way to pass
>>> arguments
>>> to the Parser from a macro.
>>>
>>> I know this is possible to calculate within a plugin, but I have yet to
>>> find
>>> one that I can incorporate into my macro. Any idea how to calculate this
>> in
>>> my macro would be appreciated. Would this particular task be better
>> suited
>>> to a script or plugin? I can post my code thus far if it would be
>> helpful.
>>> Thanks,
>>> Adam Blake
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> --
>>> View this message in context:
>>>
>> http://imagej.1557.x6.nabble.com/Calculating-atan2-on-pixels-from-two-input-images-in-a-macro-tp5007758.html
>>> Sent from the ImageJ mailing list archive at Nabble.com.
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
>


--
Kurt Thorn
Director, Nikon Imaging Center
http://nic.ucsf.edu/blog/

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html