[ImageJ-devel] Patch Improving Non-uniform Units Handling

Alan Brooks alancbrooks at gmail.com
Wed Jun 25 13:40:19 CDT 2014


ImageJ1 has built-in support for non-uniform x/y/z units via Calibration's
getX/Y/ZUnit() and setX/Y/ZUnit(). At my company, we look a good amount of
"raw" image data that naturally has time as one unit and detectors as the
other unit, so our raw file reader makes use of this functionality. I found
that some parts of ImageJ don't seem to look for X/Y/Z units, instead using
getUnit/s() without checking for non-uniform units.

So, I have put together a patch to improve a couple of key functions. I
based the patch on the 2014.06.23 (1.40c20) snapshot on
https://github.com/imagej/imagej1.git. I don't see any pull requests for
that project, so not sure how the IJ team would want this patch? For now,
it is inline, below. But I'm happy to push it to the correct spot ...
perhaps I should be asking http://wiki.imagej.net/ImageJA for a pull
request?

Thanks,
Alan


>From ad1add8f9dcdfd1ba42436a225a0c41e80353be6 Mon Sep 17 00:00:00 2001
From: Alan Brooks <alancbrooks at gmail.com>
Date: Wed, 25 Jun 2014 12:21:48 -0500
Subject: [PATCH] Show correct non-matching x & y units on surface plot.

---
 ij/plugin/SurfacePlotter.java | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/ij/plugin/SurfacePlotter.java b/ij/plugin/SurfacePlotter.java
index 011754e..9789155 100644
--- a/ij/plugin/SurfacePlotter.java
+++ b/ij/plugin/SurfacePlotter.java
@@ -306,12 +306,15 @@ public class SurfacePlotter implements PlugIn {
  ip2.drawString(s, (int) p1x-18-w, (int) p1y +h/2);

  //x-axis
- s = (double) Math.round(roi.height*cal.pixelHeight*10)/10+"
"+cal.getUnits();
+ boolean unitsMatch = cal.getXUnit().equals(cal.getYUnit());
+ String xunits = unitsMatch ? cal.getUnits() : cal.getYUnit(); // why
swapped?
+ s = (double) Math.round(roi.height*cal.pixelHeight*10)/10+" "+xunits;
  w =  ip2.getFontMetrics().stringWidth(s);
  drawAxis(ip2, (int) p1x, (int) p1y, (int) p2x, (int) p2y, s, 10, -1, 1,
1);

  //y-axis
- s =  (double) Math.round(roi.width*cal.pixelWidth*10)/10+"
"+cal.getUnits();
+ String yunits = unitsMatch ? cal.getUnits() : cal.getXUnit(); // why
swapped?
+ s =  (double) Math.round(roi.width*cal.pixelWidth*10)/10+" "+yunits;
  w =  ip2.getFontMetrics().stringWidth(s);
  //drawAxis(ip2, (int) p2x, (int) p2y, (int) p3x, (int) p3y, s, 10, 1 , 1,
-1);
  drawAxis(ip2, (int) p2x, (int) p2y, (int) p3x, (int) p3y, s, 10, 1, -1,
1);
-- 
1.8.4.msysgit.0

>From 70df4ea5619a010caa8732c764ea2ab897dab448 Mon Sep 17 00:00:00 2001
From: Alan Brooks <alancbrooks at gmail.com>
Date: Wed, 25 Jun 2014 12:20:54 -0500
Subject: [PATCH] Show correct non-matching x & y units when specifying an
ROI
 selection.

---
 ij/plugin/SpecifyROI.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/ij/plugin/SpecifyROI.java b/ij/plugin/SpecifyROI.java
index bb48b24..db71ac3 100644
--- a/ij/plugin/SpecifyROI.java
+++ b/ij/plugin/SpecifyROI.java
@@ -111,8 +111,10 @@ public class SpecifyROI implements PlugIn,
DialogListener {
  gd.addCheckbox("Oval", oval);
  gd.addCheckbox("Constrain square/circle", square);
  gd.addCheckbox("Centered",centered);
+ boolean unitsMatch = cal.getXUnit().equals(cal.getYUnit());
+ String units = unitsMatch ? cal.getUnits() : cal.getXUnit()+" x
"+cal.getYUnit();
  if (cal.scaled())
- gd.addCheckbox("Scaled units ("+cal.getUnits()+")", scaledUnits);
+ gd.addCheckbox("Scaled units ("+units+")", scaledUnits);
  fields = gd.getNumericFields();
  gd.addDialogListener(this);
  gd.showDialog();
-- 
1.8.4.msysgit.0

>From c8717cd7146dae5e54f6b93ba529632f828ce5ef Mon Sep 17 00:00:00 2001
From: Alan Brooks <alancbrooks at gmail.com>
Date: Wed, 25 Jun 2014 12:18:12 -0500
Subject: [PATCH] Update Transformer so that Rotate Right and Rotate Left
 commands preserve non-matching x & y units.

---
 ij/plugin/filter/Transformer.java | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ij/plugin/filter/Transformer.java
b/ij/plugin/filter/Transformer.java
index 26a1e96..5a6aa88 100644
--- a/ij/plugin/filter/Transformer.java
+++ b/ij/plugin/filter/Transformer.java
@@ -62,6 +62,9 @@ public class Transformer implements PlugInFilter {
      double pixelWidth = cal.pixelWidth;
      cal.pixelWidth = cal.pixelHeight;
      cal.pixelHeight = pixelWidth;
+     String xUnit = cal.getXUnit();
+        cal.setXUnit(cal.getYUnit());
+        cal.setYUnit(xUnit);
  return;
  }
  }
-- 
1.8.4.msysgit.0

>From bc4a026a612559b77be7dfc2120886be3529d092 Mon Sep 17 00:00:00 2001
From: Alan Brooks <alancbrooks at gmail.com>
Date: Wed, 25 Jun 2014 12:16:43 -0500
Subject: [PATCH] Improve ImageWindow's subtitle to handle non-matching x & y
 units. Useful when working with raw data files.

---
 ij/gui/ImageWindow.java | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/ij/gui/ImageWindow.java b/ij/gui/ImageWindow.java
index a81ebe3..ee853d9 100644
--- a/ij/gui/ImageWindow.java
+++ b/ij/gui/ImageWindow.java
@@ -301,8 +301,16 @@ public class ImageWindow extends Frame implements
FocusListener, WindowListener,
      int type = imp.getType();
      Calibration cal = imp.getCalibration();
      if (cal.scaled()) {
-     s += IJ.d2s(imp.getWidth()*cal.pixelWidth,2) + "x" +
IJ.d2s(imp.getHeight()*cal.pixelHeight,2)
- + " " + cal.getUnits() + " (" + imp.getWidth() + "x" + imp.getHeight() +
"); ";
+     boolean unitsMatch = cal.getXUnit().equals(cal.getYUnit());
+     if (unitsMatch) {
+     s += IJ.d2s(imp.getWidth()*cal.pixelWidth,2) + "x"
+       + IJ.d2s(imp.getHeight()*cal.pixelHeight,2) + " " + cal.getUnits()
+       + " (" + imp.getWidth() + "x" + imp.getHeight() + "); ";
+  } else {
+     s += IJ.d2s(imp.getWidth()*cal.pixelWidth,2) + cal.getXUnit() + " x "
+       + IJ.d2s(imp.getHeight()*cal.pixelHeight,2) + cal.getYUnit()
+       + " (" + imp.getWidth() + "x" + imp.getHeight() + "); ";
+  }
      } else
      s += imp.getWidth() + "x" + imp.getHeight() + " pixels; ";
  double size =
((double)imp.getWidth()*imp.getHeight()*imp.getStackSize())/1024.0;
-- 
1.8.4.msysgit.0

>From cb0e1dd0f81ca526cc17de90acc13f1569e06584 Mon Sep 17 00:00:00 2001
From: Alan Brooks <alancbrooks at gmail.com>
Date: Wed, 25 Jun 2014 12:07:30 -0500
Subject: [PATCH] Respect X/Y/Z units when showing file information. Useful
for
 displaying details about raw data collect files where x-y-z units are often
 different.

---
 ij/plugin/filter/Info.java | 59
+++++++++++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 29 deletions(-)

diff --git a/ij/plugin/filter/Info.java b/ij/plugin/filter/Info.java
index 9ce1ac2..99fdcf8 100644
--- a/ij/plugin/filter/Info.java
+++ b/ij/plugin/filter/Info.java
@@ -85,36 +85,37 @@ public class Info implements PlugInFilter {
  }

  String getInfo(ImagePlus imp, ImageProcessor ip) {
- String s = new String("\n");
- s += "Title: " + imp.getTitle() + "\n";
- Calibration cal = imp.getCalibration();
-     int stackSize = imp.getStackSize();
-     int channels = imp.getNChannels();
-     int slices = imp.getNSlices();
-     int frames = imp.getNFrames();
- int digits = imp.getBitDepth()==32?4:0;
- int dp, dp2;
- if (cal.scaled()) {
- String unit = cal.getUnit();
- String units = cal.getUnits();
- double pw = imp.getWidth()*cal.pixelWidth;
- double ph = imp.getHeight()*cal.pixelHeight;
-     dp = Tools.getDecimalPlaces(pw, ph);
-     s += "Width:  "+IJ.d2s(pw,dp)+" " + units+" ("+imp.getWidth()+")\n";
-     s += "Height:  "+IJ.d2s(ph,dp)+" " + units+" ("+imp.getHeight()+")\n";
-     if (slices>1) {
- double pd = slices*cal.pixelDepth;
- dp = Tools.getDecimalPlaces(pw, pd);
-     s += "Depth:  "+IJ.d2s(pd,dp)+" " + units+" ("+slices+")\n";
-     }
+            String s = new String("\n");
+            s += "Title: " + imp.getTitle() + "\n";
+            Calibration cal = imp.getCalibration();
+            int stackSize = imp.getStackSize();
+            int channels = imp.getNChannels();
+            int slices = imp.getNSlices();
+            int frames = imp.getNFrames();
+            int digits = imp.getBitDepth()==32?4:0;
+            int dp, dp2;
+            String xunit = cal.getXUnit();
+            String yunit = cal.getYUnit();
+            String zunit = cal.getZUnit();
+            if (cal.scaled()) {
+                double pw = imp.getWidth()*cal.pixelWidth;
+                double ph = imp.getHeight()*cal.pixelHeight;
+                dp = Tools.getDecimalPlaces(pw, ph);
+                s += "Width:  "+IJ.d2s(pw,dp)+" " + xunit +"s
("+imp.getWidth()+")\n";
+                s += "Height:  "+IJ.d2s(ph,dp)+" " + yunit +"s
("+imp.getHeight()+")\n";
+                if (slices>1) {
+                                double pd = slices*cal.pixelDepth;
+                                dp = Tools.getDecimalPlaces(pw, pd);
+                        s += "Depth:  "+IJ.d2s(pd,dp)+" " + zunit +"s
("+slices+")\n";
+                }
      double xResolution = 1.0/cal.pixelWidth;
      double yResolution = 1.0/cal.pixelHeight;
      int places = Tools.getDecimalPlaces(xResolution, yResolution);
      if (xResolution==yResolution)
-     s += "Resolution:  "+IJ.d2s(xResolution,places) + " pixels per
"+unit+"\n";
+     s += "Resolution:  "+IJ.d2s(xResolution,places) + " pixels per
"+xunit+"\n";
      else {
-     s += "X Resolution:  "+IJ.d2s(xResolution,places) + " pixels per
"+unit+"\n";
-     s += "Y Resolution:  "+IJ.d2s(yResolution,places) + " pixels per
"+unit+"\n";
+     s += "X Resolution:  "+IJ.d2s(xResolution,places) + " pixels per
"+xunit+"\n";
+     s += "Y Resolution:  "+IJ.d2s(yResolution,places) + " pixels per
"+yunit+"\n";
      }
     } else {
      s += "Width:  " + imp.getWidth() + " pixels\n";
@@ -122,19 +123,19 @@ public class Info implements PlugInFilter {
      if (stackSize>1)
      s += "Depth:  " + slices + " pixels\n";
     }
-     if (stackSize>1) {
+            if (stackSize>1) {
      dp = Tools.getDecimalPlaces(cal.pixelWidth, cal.pixelDepth);
-     s += "Voxel size:
"+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+"x"+IJ.d2s(cal.pixelDepth,dp)+"
"+cal.getUnit()+"\n";
+     s += "Voxel size:
"+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+"x"+IJ.d2s(cal.pixelDepth,dp)+"
("+xunit+" x "+yunit+" x "+zunit+")\n";
     } else {
      dp = Tools.getDecimalPlaces(cal.pixelWidth, cal.pixelHeight);
-     s += "Pixel size:
"+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+"
"+cal.getUnit()+"\n";
+     s += "Pixel size:
"+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+" ("+xunit+" x
"+yunit+")\n";
     }

     s += "ID: "+imp.getID()+"\n";
     String zOrigin = stackSize>1||cal.zOrigin!=0.0?","+d2s(cal.zOrigin):"";
     s += "Coordinate origin:  " +
d2s(cal.xOrigin)+","+d2s(cal.yOrigin)+zOrigin+"\n";
     int type = imp.getType();
-     switch (type) {
+            switch (type) {
      case ImagePlus.GRAY8:
      s += "Bits per pixel: 8 ";
      String lut = "LUT";
-- 
1.8.4.msysgit.0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://imagej.net/pipermail/imagej-devel/attachments/20140625/5e944ddc/attachment-0001.html>


More information about the ImageJ-devel mailing list