My company's systems often acquire image data using a linear
one-dimensional detector, building up an image over time by scanning. The raw data files that come from this process naturally have time as one axis and pixel as the other axis. In our raw file reader for ImageJ, I have found it useful to preserve these units when reading the raw data by using the setX/YUnits() methods in Calibration. This allows our teams to analyze the raw time axis for sampling and/or noise artifacts and the raw pixel axis for any problems related to individual detectors. A problem with the current ImageJ handling of non-uniform x, y, and z units is that even though the units are set, many of the supporting functions just use getUnit() which returns getXUnit() even when getY/ZUnit() might differ. For example, the Image->Show Info function display the x-units for all dimensions when displaying XResolution and YResolution. Is there interest in fixing this? I developed a start at some patches that improve the non-uniform handling and submitted them to the imagej-dev mailing list last week ( http://imagej.net/pipermail/imagej-devel/2014-June/002140.html), but didn't hear back as of yet. Perhaps there is a better way to submit ImageJ1 patches and report bugs? Or maybe it is better to have a discussion first before sending out a patch. Although I have been developing plugins and using ImageJ for years, this is my first attempt to engage with the community. I admit I am confused about the proper path for that, perhaps because much of the community's work seems to be focused on ImageJ2 development at the moment. Cheers, Alan -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Alan,
> Is there interest in fixing this? The ImageJ2 team is definitely interested in making support for non-linear calibration and units better in ImageJ2. And actually, the data structures are already in place on the ImgLib2 side of things. > I developed a start at some patches that improve the non-uniform > handling and submitted them to the imagej-dev mailing list last week ( > http://imagej.net/pipermail/imagej-devel/2014-June/002140.html), > but didn't hear back as of yet. Changes to ImageJ1 are at Wayne Rasband's discretion, as he is ImageJ1's sole developer. Historically, he has taken patch submissions and reworked them to his liking before merging them. For ImageJ2 code changes, we prefer Pull Requests on GitHub, and public discussion on the ImageJ and imagej-devel mailing lists. > Perhaps there is a better way to submit ImageJ1 patches and report > bugs? For ImageJ1, sending a patch to imagej-devel, or as a PR on GitHub, or to Wayne via private mail, all work. The important part is that Wayne receive the patch, since he is the only one with the authority to merge it. Note that Wayne typically replies via private mail, especially for long back-and-forth threads, so current status is often opaque to the rest of the community. > Or maybe it is better to have a discussion first before sending out a > patch. Having a public discussion is almost always worthwhile; otherwise, you are a working in a vacuum and not receiving any feedback on your development directions. In this particular case, I would caution against hacking on ImageJ1's calibration logic too much. Firstly, it needs to remain backwards compatible with existing macros and plugins. And secondly, anything which makes ImageJ1's calibration logic more complex at this point will also make ImageJ2's job of backwards compatibility more complex -- and we have enough on our hands already, there. I would rather see developers start migrating to the ImageJ2 data structures when they need things like nonlinear calibration, so that ImageJ1 does not have to worry about that problem at all, and we can all move forward together as a community. > Although I have been developing plugins and using ImageJ for years, > this is my first attempt to engage with the community. I admit I am > confused about the proper path for that, perhaps because much of the > community's work seems to be focused on ImageJ2 development at the > moment. Hopefully the above clarifies things a bit. If you have further questions, please feel free to ask! And if you want to benefit the community along these lines, I encourage you to edit the Community section of the ImageJ wiki's FAQ to add a question about community contributions, so that others will not have to ask on the mailing list next time! http://wiki.imagej.net/FAQ#Community Regards, Curtis On Mon, Jun 30, 2014 at 10:04 AM, Alan Brooks <[hidden email]> wrote: > My company's systems often acquire image data using a linear > one-dimensional detector, building up an image over time by scanning. The > raw data files that come from this process naturally have time as one axis > and pixel as the other axis. In our raw file reader for ImageJ, I have > found it useful to preserve these units when reading the raw data by using > the setX/YUnits() methods in Calibration. This allows our teams to analyze > the raw time axis for sampling and/or noise artifacts and the raw pixel > axis for any problems related to individual detectors. > > A problem with the current ImageJ handling of non-uniform x, y, and z units > is that even though the units are set, many of the supporting functions > just use getUnit() which returns getXUnit() even when getY/ZUnit() might > differ. For example, the Image->Show Info function display the x-units for > all dimensions when displaying XResolution and YResolution. > > Is there interest in fixing this? > > I developed a start at some patches that improve the non-uniform handling > and submitted them to the imagej-dev mailing list last week ( > http://imagej.net/pipermail/imagej-devel/2014-June/002140.html), but > didn't > hear back as of yet. > > Perhaps there is a better way to submit ImageJ1 patches and report bugs? Or > maybe it is better to have a discussion first before sending out a patch. > Although I have been developing plugins and using ImageJ for years, this is > my first attempt to engage with the community. I admit I am confused about > the proper path for that, perhaps because much of the community's work > seems to be focused on ImageJ2 development at the moment. > > Cheers, > Alan > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Alan Brooks
On Jun 30, 2014, at 11:04 AM, Alan Brooks wrote:
> My company's systems often acquire image data using a linear > one-dimensional detector, building up an image over time by scanning. The > raw data files that come from this process naturally have time as one axis > and pixel as the other axis. In our raw file reader for ImageJ, I have > found it useful to preserve these units when reading the raw data by using > the setX/YUnits() methods in Calibration. This allows our teams to analyze > the raw time axis for sampling and/or noise artifacts and the raw pixel > axis for any problems related to individual detectors. > > A problem with the current ImageJ handling of non-uniform x, y, and z units > is that even though the units are set, many of the supporting functions > just use getUnit() which returns getXUnit() even when getY/ZUnit() might > differ. For example, the Image->Show Info function display the x-units for > all dimensions when displaying XResolution and YResolution. > > Is there interest in fixing this? The latest ImageJ daily build (1.49d4) displays non-uniform x and y units in image subtitles. The image subtitle is the text in image windows displayed above the image and below the title bar. As an example, the following JavaScript creates a stack with this subtitle: "1/256; 25.6 xunit x 51.2 yunit (256x256); 8-bit; 16MB" The next daily build (1.49d5) will add support for non-uniform units to the Image>Show Info command. -wayne imp = IJ.createImage("Untitled", "8-bit black", 256, 256, 256); cal = imp.getCalibration(); cal.pixelWidth = 0.1; cal.pixelHeight = 0.2; cal.pixelDepth = 0.3; cal.setXUnit("xunit"); cal.setYUnit("yunit"); cal.setZUnit("zunit"); imp.show(); win = imp.getWindow(); print(win.createSubtitle()); > I developed a start at some patches that improve the non-uniform handling > and submitted them to the imagej-dev mailing list last week ( > http://imagej.net/pipermail/imagej-devel/2014-June/002140.html), but didn't > hear back as of yet. > > Perhaps there is a better way to submit ImageJ1 patches and report bugs? Or > maybe it is better to have a discussion first before sending out a patch. > Although I have been developing plugins and using ImageJ for years, this is > my first attempt to engage with the community. I admit I am confused about > the proper path for that, perhaps because much of the community's work > seems to be focused on ImageJ2 development at the moment. > > Cheers, > Alan > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by ctrueden
Hi Curtis,
Thanks for the very helpful response. I would caution against hacking on ImageJ1's > calibration logic too much. Firstly, it needs to remain backwards > compatible with existing macros and plugins. And secondly, anything which > makes ImageJ1's calibration logic more complex at this point will also make > ImageJ2's job of backwards compatibility more complex -- and we have enough > on our hands already, there. I would rather see developers start migrating > to the ImageJ2 data structures when they need things like nonlinear > calibration, so that ImageJ1 does not have to worry about that problem at > all, and we can all move forward together as a community. > I can understand the concern about changing the behavior of the calibration and agree that waiting for IJ2 would be better. The changes I proposed were more about the UI being consistent about accurately showing the state calibration units using the existing API for storing & accessing calibration metadata. I think that these changes are relatively safe since its about the UI being true to the data model. > I encourage you to edit the Community section of the ImageJ > wiki's FAQ to add a question about community contributions, so that others > will not have to ask on the mailing list next time! > http://wiki.imagej.net/FAQ#Community I made an attempt at documenting this on the FAQ as a new question <http://wiki.imagej.net/Frequently_Asked_Questions#How_do_I_contribute_a_bug_fix.2C_a_patch.2C_or_propose_an_idea_for_a_change_to_the_community.3F>. Take a look and see if I got it approximately right. Regards, Alan -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Rasband, Wayne (NIH/NIMH) [E]
Hi Wayne,
The latest ImageJ daily build (1.49d4) displays non-uniform x and y units > in image subtitles. The image subtitle is the text in image windows > displayed above the image and below the title bar. As an example, the > following JavaScript creates a stack with this subtitle: > > "1/256; 25.6 xunit x 51.2 yunit (256x256); 8-bit; 16MB" > I tried build 1.49d4 on my data and the subtitle is working correctly for me. > The next daily build (1.49d5) will add support for non-uniform units to > the Image>Show Info command. I will give this a try too. Will you also be looking at Transformer.java to swap the units when rotating by 90 degrees? (This was part of my patch also. Curious because the rotation was actually my initial motivation for doing this patch.) Alan -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Alan Brooks
Hi Alan,
> I made an attempt at documenting this on the FAQ as a new question Wow, what a fabulous writeup! Thank you so much! It is always great when a detail oriented, technically minded person such as yourself contributes to the project. Cheers, Curtis On Mon, Jun 30, 2014 at 4:18 PM, Alan Brooks <[hidden email]> wrote: > Hi Curtis, > > Thanks for the very helpful response. > > I would caution against hacking on ImageJ1's > > calibration logic too much. Firstly, it needs to remain backwards > > compatible with existing macros and plugins. And secondly, anything which > > makes ImageJ1's calibration logic more complex at this point will also > make > > ImageJ2's job of backwards compatibility more complex -- and we have > enough > > on our hands already, there. I would rather see developers start > migrating > > to the ImageJ2 data structures when they need things like nonlinear > > calibration, so that ImageJ1 does not have to worry about that problem at > > all, and we can all move forward together as a community. > > > > I can understand the concern about changing the behavior of the calibration > and agree that waiting for IJ2 would be better. The changes I proposed were > more about the UI being consistent about accurately showing the state > calibration units using the existing API for storing & accessing > calibration metadata. I think that these changes are relatively safe since > its about the UI being true to the data model. > > > > > I encourage you to edit the Community section of the ImageJ > > wiki's FAQ to add a question about community contributions, so that > others > > will not have to ask on the mailing list next time! > > http://wiki.imagej.net/FAQ#Community > > > I made an attempt at documenting this on the FAQ as a new question > < > http://wiki.imagej.net/Frequently_Asked_Questions#How_do_I_contribute_a_bug_fix.2C_a_patch.2C_or_propose_an_idea_for_a_change_to_the_community.3F > >. > Take a look and see if I got it approximately right. > > Regards, > Alan > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Alan Brooks
On Jun 30, 2014, at 5:24 PM, Alan Brooks wrote:
> Hi Wayne, > > The latest ImageJ daily build (1.49d4) displays non-uniform x and y units >> in image subtitles. The image subtitle is the text in image windows >> displayed above the image and below the title bar. As an example, the >> following JavaScript creates a stack with this subtitle: >> >> "1/256; 25.6 xunit x 51.2 yunit (256x256); 8-bit; 16MB" >> > I tried build 1.49d4 on my data and the subtitle is working correctly for > me. > >> The next daily build (1.49d5) will add support for non-uniform units to >> the Image>Show Info command. > > I will give this a try too. > > Will you also be looking at Transformer.java to swap the units when > rotating by 90 degrees? (This was part of my patch also. Curious because > the rotation was actually my initial motivation for doing this patch.) The "Rotate Right", "Rotate Left" and "Show Info" commands in latest ImageJ daily build (1.49d5) support non-uniform units. -wayne -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
>> The "Rotate Right", "Rotate Left" and "Show Info" commands in latest ImageJ
>> daily build (1.49d5) support non-uniform units. > > This is generally working for me on my data. However it seems to pick the > number of decimal points to display in an inconsistent manner. > > On a data set with time in the x-dimension, pixels in the y-dimension, and > electronic integrator in the z-dimension, I get the following Image>Show > Info.. when opening the file: > > Width: 65.83 sec (11350) > Height: 1504.00 dexel (1504) > Depth: 2.00 integrator (2) > X Resolution: 172.4138 pixels per sec > Y Resolution: 1.0000 pixels per dexel > Voxel size: 0.0058x1.0000x1.0000 (sec x dexel x integrator) > > but it changes to the following after rotating by 90 degrees: > > Width: 1504 dexel (1504) > Height: 66 sec (11350) > Depth: 2 integrator (2) > X Resolution: 1 pixels per dexel > Y Resolution: 172 pixels per sec > Voxel size: 1x0x1 (dexel x sec x integrator) > > Perhaps there is a problem with Tools.getDecimalPlaces(double n1, double > n2)? I couldn't see it upon inspection. I looked at this problem further and found that the two-input Tools.getDecimalPlaces() didn't behave as expected if one the units is a round number with other units as decimals. I developed a minor patch for this, included inline below. Also, I realized that it makes more sense for non-uniform units to treat each number separately when computing significant digits for display in ImageWindow's subtitle and in the Info command. I developed a potential patch that does this, inline below. If you create a sample image with this javascript: imp = IJ.createImage("Untitled", "8-bit black", 500, 200, 10); cal = imp.getCalibration(); cal.pixelWidth = 0.0058; cal.pixelHeight = 1.0; cal.pixelDepth = 12.3; cal.setXUnit("sec"); cal.setYUnit("dexel"); cal.setZUnit("mm"); imp.show(); win = imp.getWindow(); print(win.createSubtitle()); The current IJ daily (1.49d6) shows: 1/10; 2.9 sec x 200.0 dexel (500x200); 8-bit; 977K My patch shows: 1/10; 2.9 sec x 200 dexel (500x200); 8-bit; 977K Similarly, IJ daily shows the following Info: Width: 2.9 sec (500) Height: 200.0 sec (200) Depth: 123.0 sec (10) X Resolution: 172.4138 pixels per sec Y Resolution: 1.0000 pixels per sec Voxel size: 0.0058x1.0000x12.3000 sec My patch shows: Width: 2.9 sec (500) Height: 200 dexel (200) Depth: 123 mm (10) X Resolution: 172.4138 pixels per sec Y Resolution: 1 pixels per dexel Voxel size: 0.0058x1x12.3 (sec x dexel x mm) The patch against 1.49d6 follows ----------------------------- From dc43859d9abe52403751492f1f3325516ea74ad8 Mon Sep 17 00:00:00 2001 From: Alan Brooks <[hidden email]> Date: Wed, 2 Jul 2014 11:34:02 -0500 Subject: [PATCH] For two-input getDecimalPlaces with either input almost an integer, let the other input determine the format. --- ij/util/Tools.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ij/util/Tools.java b/ij/util/Tools.java index c99c11b..9874402 100644 --- a/ij/util/Tools.java +++ b/ij/util/Tools.java @@ -147,7 +147,11 @@ import java.util.Comparator; return 0; int digits = getDecimalPlaces(n1); int digits2 = getDecimalPlaces(n2); - if (digits<=0 || digits2<=0) + if (digits==0) + return digits2; + if (digits2==0) + return digits; + if (digits<0 || digits2<0) return digits; if (digits2>digits) digits = digits2; -- 1.8.4.msysgit.0 From 8f4a5a8caf6881b7967cb802306b8e15b1ef94bb Mon Sep 17 00:00:00 2001 From: Alan Brooks <[hidden email]> Date: Wed, 2 Jul 2014 11:32:20 -0500 Subject: [PATCH] Separate the handling of display digits to account for non-uniform units of much different scales. --- ij/gui/ImageWindow.java | 12 +++++++----- ij/plugin/filter/Info.java | 31 +++++++++++++++++-------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/ij/gui/ImageWindow.java b/ij/gui/ImageWindow.java index d9b47af..e972509 100644 --- a/ij/gui/ImageWindow.java +++ b/ij/gui/ImageWindow.java @@ -304,14 +304,16 @@ public class ImageWindow extends Frame implements FocusListener, WindowListener, boolean unitsMatch = cal.getXUnit().equals(cal.getYUnit()); double cwidth = imp.getWidth()*cal.pixelWidth; double cheight = imp.getHeight()*cal.pixelHeight; - int digits = Tools.getDecimalPlaces(cwidth, cheight); - if (digits>2) digits=2; + int digitsw = Tools.getDecimalPlaces(cwidth); + if (digitsw>2) digitsw=2; + int digitsh = Tools.getDecimalPlaces(cheight); + if (digitsh>2) digitsh=2; if (unitsMatch) { - s += IJ.d2s(cwidth,digits) + "x" + IJ.d2s(cheight,digits) + s += IJ.d2s(cwidth,digitsw) + "x" + IJ.d2s(cheight,digitsh) + " " + cal.getUnits() + " (" + imp.getWidth() + "x" + imp.getHeight() + "); "; } else { - s += IJ.d2s(cwidth,digits) + " " + cal.getXUnit() + " x " - + IJ.d2s(cheight,digits) + " " + cal.getYUnit() + s += IJ.d2s(cwidth,digitsw) + " " + cal.getXUnit() + " x " + + IJ.d2s(cheight,digitsh) + " " + cal.getYUnit() + " (" + imp.getWidth() + "x" + imp.getHeight() + "); "; } } else diff --git a/ij/plugin/filter/Info.java b/ij/plugin/filter/Info.java index e6d193a..070db3a 100644 --- a/ij/plugin/filter/Info.java +++ b/ij/plugin/filter/Info.java @@ -93,7 +93,7 @@ public class Info implements PlugInFilter { int slices = imp.getNSlices(); int frames = imp.getNFrames(); int digits = imp.getBitDepth()==32?4:0; - int dp, dp2; + int dpw, dph, dpd; boolean nonUniformUnits = !cal.getXUnit().equals(cal.getYUnit()); String xunit = cal.getXUnit(); String yunit = cal.getYUnit(); @@ -109,22 +109,24 @@ public class Info implements PlugInFilter { } double pw = imp.getWidth()*cal.pixelWidth; double ph = imp.getHeight()*cal.pixelHeight; - dp = Tools.getDecimalPlaces(pw, ph); - s += "Width: "+IJ.d2s(pw,dp)+" " + xunits+" ("+imp.getWidth()+")\n"; - s += "Height: "+IJ.d2s(ph,dp)+" " + yunits+" ("+imp.getHeight()+")\n"; + dpw = Tools.getDecimalPlaces(pw); + dph = Tools.getDecimalPlaces(ph); + s += "Width: "+IJ.d2s(pw,dpw)+" " + xunits+" ("+imp.getWidth()+")\n"; + s += "Height: "+IJ.d2s(ph,dph)+" " + yunits+" ("+imp.getHeight()+")\n"; if (slices>1) { double pd = slices*cal.pixelDepth; - dp = Tools.getDecimalPlaces(pw, pd); - s += "Depth: "+IJ.d2s(pd,dp)+" " + zunits+" ("+slices+")\n"; + dpd = Tools.getDecimalPlaces(pd); + s += "Depth: "+IJ.d2s(pd,dpd)+" " + zunits+" ("+slices+")\n"; } double xResolution = 1.0/cal.pixelWidth; double yResolution = 1.0/cal.pixelHeight; - int places = Tools.getDecimalPlaces(xResolution, yResolution); + int placesx = Tools.getDecimalPlaces(xResolution); + int placesy = Tools.getDecimalPlaces(yResolution); if (xResolution==yResolution) - s += "Resolution: "+IJ.d2s(xResolution,places) + " pixels per "+xunit+"\n"; + s += "Resolution: "+IJ.d2s(xResolution,placesx) + " pixels per "+xunit+"\n"; else { - s += "X Resolution: "+IJ.d2s(xResolution,places) + " pixels per "+xunit+"\n"; - s += "Y Resolution: "+IJ.d2s(yResolution,places) + " pixels per "+yunit+"\n"; + s += "X Resolution: "+IJ.d2s(xResolution,placesx) + " pixels per "+xunit+"\n"; + s += "Y Resolution: "+IJ.d2s(yResolution,placesy) + " pixels per "+yunit+"\n"; } } else { s += "Width: " + imp.getWidth() + " pixels\n"; @@ -132,18 +134,19 @@ public class Info implements PlugInFilter { if (stackSize>1) s += "Depth: " + slices + " pixels\n"; } + dpw = Tools.getDecimalPlaces(cal.pixelWidth); + dph = Tools.getDecimalPlaces(cal.pixelHeight); if (stackSize>1) { String vunit = cal.getUnit()+"^3"; if (nonUniformUnits) vunit = "("+xunit+" x "+yunit+" x "+zunit+")"; - 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)+" "+vunit+"\n"; + dpd = Tools.getDecimalPlaces(cal.pixelDepth); + s += "Voxel size: "+IJ.d2s(cal.pixelWidth,dpw)+"x"+IJ.d2s(cal.pixelHeight,dph)+"x"+IJ.d2s(cal.pixelDepth,dpd)+" "+vunit+"\n"; } else { String punit = cal.getUnit()+"^2"; if (nonUniformUnits) punit = "("+xunit+" x "+yunit+")"; - dp = Tools.getDecimalPlaces(cal.pixelWidth, cal.pixelHeight); - s += "Pixel size: "+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+" "+punit+"\n"; + s += "Pixel size: "+IJ.d2s(cal.pixelWidth,dpw)+"x"+IJ.d2s(cal.pixelHeight,dph)+" "+punit+"\n"; } s += "ID: "+imp.getID()+"\n"; -- 1.8.4.msysgit.0 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |