Sunday, 15 June 2014

Writing ImageJ Plugins

These instructions for getting started writing plugins for ImageJ2 were developed at the Fiji / ImageJ2 Hackathon in Dresden, Germany, December 2011, using the Eclipse IDE version 3.7 and Sun JDK 1.6 on Ubuntu 11.04. It assumes that you have a working installation of ImageJ2, from http://developer.imagej.net/downloads.

Configure your environment

  1. Install JDK 6, needed for the javac compiler, using your system install mechanism or by downloading from http://www.oracle.com/technetwork/java/javase/downloads/index.html
  2. Install Eclipse IDE version 3.7 for Java developers from http://eclipse.org/downloads/, using the appropriate download for your system.
  3. Download imagej-2.0.0-SNAPSHOT-all.jar from http://developer.imagej.net/downloads and save it somewhere handy; I have mine in a directory called JavaLibs.
  4. Run Eclipse and tell it to use JDK 6 as the default JRE for new projects (Window > Preferences > Installed JREs > Add... > Standard VM > Navigate to your JDK install directory
  5. Right click in the Package Explorer > New... > Java Project
  6. Give your project a name, e.g. IJ2-plugins, hit Next
  7. Under the Libraries tab Add External Jars... and navigate to the imagej-2.0.0-SNAPSHOT-all.jar you downloaded in step 3. This gives you access to the IJ2 application programming interface (API). At the time of writing, to get context Javadoc for ImgLib classes you also have to specify the URL of its Javadoc. Click on the triangle to the left of imagej-2.0.0-SNAPSHOT-all.jar, select "Javadoc location:", hit Edit, add the URL:
    http://jenkins.imagej.net/job/ImgLib-daily/javadoc/
    Hit Validate and if everything is OK, hit OK.
  8. Configure Ant to do your build using the javac compiler
    1. Copy this code and paste it into your project in a file called build.xml
      <project name="Plugins for ImageJ2" default="" basedir=".">
      <description>
      ImageJ2 build file
      </description>
      <property name="src" location="src" />
      <property name="build" location="javacbin" />
      <property name="imagej2Plugins" location="/home/mdoube/imagejdev/plugins/" />
      <property name="user.name" value="Michael Doube" />
      <path id="plugin-classpath">
      <fileset dir="/home/mdoube/JavaLibs/">
      <include name="imagej-2.0-SNAPSHOT-all.jar" />
      </fileset>
      <pathelement path="${build.dir}" />
      </path>
      <target name="init">
      <!-- Create the time stamp -->
      <tstamp />
      <!-- Create the build directory structure used by compile -->
      <mkdir dir="${build}" />
      </target>
      <target name="compile" depends="" description="compile the source ">
      <!-- Compile the java code from ${src} into ${build} -->
      <javac includeantruntime="false" srcdir="${src}" destdir="${build}">
      <classpath refid="plugin-classpath"/>
      </javac>
      <echo>
      Building the .jar file.
      </echo>
      </target>
      <target name="compress" depends="" description="generate the distribution">
      <jar jarfile="IJ2Plugins.jar">
      <fileset dir="${build}" includes="**/*.*" />
      <manifest>
      <attribute name="Built-By" value="${user.name}" />
      </manifest>
      </jar>
      <copy file="IJ2Plugins.jar" toDir="${imagej2Plugins}" />
      </target>
      <target name="clean" description="clean up">
      <!-- Delete the ${build} and ${dist} directory trees -->
      <delete dir="${build}" />
      </target>
      </project>
    2. double-click on build.xml and edit it so that the fileset dir="" field contains the ij-app jar and the ImageJ2Plugins location is set to your local ImageJ plugins directory
    3. you can also edit the name of the jar that's generated
    4. now right-click on your project in the Package Explorer > Properties > Builders > New > select Ant Builder > Enter a name for your builder
    5. Main tab, under Buildfile: hit Browse Workspace and locate the build.xml you just made, hit OK
    6. Targets tab, After a “Clean”: Set targets, check init, compile, compress, clean
    7. Targets tab, Auto Build: Set targets, check init, compile, compress, clean

Hello World

Writing your first plugin: HelloWorld

  1. Right-click on the src directory of your new project and New > Class
  2. Give your class a name; e.g., HelloWorld (the convention for classes is to be capitalised like that)
  3. Eclipse initialises a new file and puts a little code into it for you.
    1. Edit the first line so it reads: public class HelloWorld implements RunnablePlugin {
    2. Note the squiggly red line under RunnablePlugin indicating a compile error, move your cursor to it and hit Ctrl+1
    3. Eclipse gives you a bunch of autocorrect options, select the top one, Import 'RunnablePlugin' (imagej.ext.plugin) and hit Enter. Eclipse adds a line of code for you at the top of the file: import imagej.ext.plugin.RunnablePlugin;
    4. Now HelloWorld gets a squiggly line, so Ctrl+1 again and select Add Unimplemented Methods. Eclipse adds a bunch of code, which is the run() method needed because we are implementing the RunnablePlugin interface.
    5. We want HelloWorld to show up in the ImageJ menus, so add an annotation above the public class line: @Plugin(menuPath = "Plugins>Hello World")
    6. Ctrl+1 again on the @Plugin squiggly line to autocorrect the missing import.
    7. You can Ctrl+Space and Eclipse will suggest options for autocompletion.
  4. Let's check ImageJ and see if our plugin is available in the menus.
    1. Run ImageJ
    2. You should now see in ImageJ's Plugins menu an item called Hello World
    3. But it doesn't do anything yet because we haven't added any useful code
  5. Add code to your HelloWorld until it matches HelloWorld.java below, using Ctrl+1 and Ctrl+Space to investigate possibilities in the API
    1. Each time you update your code, Ant rebuilds your jar and copies it to your plugins directory
    2. At the moment, you have to restart ImageJ to test your changes

HelloWorld.java

import imagej.ext.plugin.Parameter;
import imagej.ext.plugin.Plugin;
import imagej.ext.plugin.RunnablePlugin;
import imagej.ui.UIService;

@Plugin(menuPath = "Plugins>Hello World")
public class HelloWorld implements RunnablePlugin {
@Parameter
private UIService uiService;

@Override
public void run() {
uiService.showDialog("Hello world.");
}
}

Monday, 9 June 2014

Interactive Stack Rotation

Here is a screencast how to use the Interactive Stack Rotation plugin:








For a quick overview of keyboard shortcuts, please press the F1 key to be shown this usage:

InteractiveStackRotation.jpg

What are you looking for?


 
ImageJ 1.x
The current, stable version is known simply as "ImageJ"—or sometimes "ImageJ1" or "IJ1" to differentiate it from ImageJ 2.x, which is still in beta.

Read more...

ImageJ 2.x
ImageJ2
ImageJ 2.0.0, referred to as "ImageJ2" or "IJ2" for short, is currently in development. It is a complete rewrite of ImageJ, but includes ImageJ1 with a compatibility layer, so that old-style plugins and macros can run the same as in IJ1.

Read more...
Fiji
Fiji
Fiji is a distribution of ImageJ (both ImageJ1 and ImageJ2!) for the life sciences. It provides a large number of additional plugins to facilitate analysis of life sciences images, particularly microscopy images.

Read more...
Or see the table of ImageJ flavors for a more complete rundown of various ImageJ-related software.

Saturday, 31 May 2014

How to Avoid ConcurrentModificationException when using an Iterator

Java Collection classes are fail-fast which means that if the Collection will be changed while some thread is traversing over it using iterator, the iterator.next() will throw a ConcurrentModificationException.
This situation can come in case of multithreaded as well as single threaded environment.
Lets explore this scenario with the following example :


 
 
From the output stack trace, its clear that the exception is coming when we call iterator next() function. If you are wondering how Iterator checks for the modification, its implementation is present in AbstractList class where an int variable modCount is defined that provides the number of times list size has been changed. This value is used in every next() call to check for any modifications in a function checkForComodification().

Now comment the list part and run the program again.

Output will be:

Map Value:3
Map Value:2
Map Value:4
 
Since we are updating the existing key value in the myMap, its size has not been changed and we are not getting ConcurrentModificationException. Note that the output may differ in your system because HashMap keyset is not ordered like list. If you will uncomment the statement where I am adding a new key-value in the HashMap, it will cause ConcurrentModificationException.

To Avoid ConcurrentModificationException in multi-threaded environment:

1. You can convert the list to an array and then iterate on the array. This approach works well for small or medium size list but if the list is large then it will affect the performance a lot.
2. You can lock the list while iterating by putting it in a synchronized block. This approach is not recommended because it will cease the benefits of multithreading.
3. If you are using JDK1.5 or higher then you can use ConcurrentHashMap and CopyOnWriteArrayList classes. It is the recommended approach.

To Avoid ConcurrentModificationException in single-threaded environment:

You can use the iterator remove() function to remove the object from underlying collection object. But in this case you can remove the same object and not any other object from the list.

 Let us run an example using Concurrent Collection classes:


 

Tuesday, 27 May 2014

How to Column Selection in IDE Eclipse

Eclipse used to need a column mode plugin to be able to select a rectangular selection.

column mode 

Since Eclipse 3.5, you just need to type Alt+Shift+A: see its News and Noteworthy section. (On OS X it's Option-Command-A.)

block (aka column or rectangular) selection mode 

Or activate the 'Editor Presentation' action set ( Window > Customize Perspective menu) to get a tool bar button for toggling the block selection mode.

Thursday, 22 May 2014

Merging two images

Just create a new BufferedImage with transparency, then paint the other two images (with full or semi-transparency) on it. This is how it will look like:
combining images
Sample code (images are called 'image.png' and 'overlay.png'):
File path = ... // base path of the images

// load source images
BufferedImage image = ImageIO.read(new File(path, "image.png"));
BufferedImage overlay = ImageIO.read(new File(path, "overlay.png"));

// create the new image, canvas size is the max. of both image sizes
int w = Math.max(image.getWidth(), overlay.getWidth());
int h = Math.max(image.getHeight(), overlay.getHeight());
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

// paint both images, preserving the alpha channels
Graphics g = combined.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(overlay, 0, 0, null);

// Save as new image
ImageIO.write(combined, "PNG", new File(path, "combined.png"));

Wednesday, 21 May 2014

Version 1.49a 15 May 2014

Version 1.49a  (upgrade)

  • Thanks to Kenneth Sloan, added a "Paint on overlay" option to the built in brush tool's options dialog. Add the built in brush tool to the toolbar by selecting "Brush" from the toolbar's ">>" menu.
  • Thanks to Daniel Pensold, Analyze>Tools>Save XY Coordinatessaves the coordinates and values of pixels inside selections to a .csv file.
  • Thanks to Volker Wirth, added a "Title:" field to the dialog displayed by Edit>Selection>Straighten when the line width is one or when processing a stack.
  • Selections created by the selection brush tool are deleted after they are added to an overlay.
  • Thanks to Jon Harman, Plugins>Install recognizes .zip files.
  • Thanks to Jerome Mutterer, added the makeArrow() macro function (example).
  • Thanks to Federico Luzzati, added the Stack.toggleChannel() macro function (example).
  • Thanks to Norbert Vischer, the showProgress(progress) macro function displays subordinate progress bars as moving dots when 'progress' is negative (macro example, script example).
  • Thanks to Messaoudi Cedric, Edit>Options>Memory & Threadsno longer limits the number of threads to 32.
  • Thanks to Wilhelm Burger, added the IJ.setProperty(String,Object) and IJ.getProperty(String) methods, which are useful for passing data between plugins.
  • Thanks to Stephan Preibisch, added the MultiLineLabel#setText() method (example).
  • Fixed a bug that caused the recording mode to not be saved when quitting ImageJ with the Recorder open.
  • Thanks to Mats Nilsson, fixed a bug that caused the getInfo() macro function and ImagePlus#getStringProperty() method to not work with DICOM tags containing letters.
  • Thanks to Norbert Vischer, fixed a bug the caused the Array.findMaxima() macro function to throw an exception when the array length was one.
  • Fixed a bug that caused images with overlays containing black transparent images to not be correctly saved and restored.
  • Thanks to Jan Brocher, fixed a v1.48 regression that caused changes made in the Image>Overlay>Add to Overlay dialog (displayed when you press alt+b) to not be remembered.
  • Thanks to Kees Straatman, fixed a bug that caused the recorder to incorrectly record the Process>Binary>Convert to Mask command.
  • Thanks to Chris Weisiger, fixed a bug in Image>Stacks>Othogonal Viewsthat caused it to fail with extened StackWindows with custom controls.
  • Thanks to Philippe Carl, fixed a v1.48t regression that caused the Plot#drawNormalizedLine() method to not work with log plots.